accel/ivpu: Add coredump support

[ Upstream commit bade0340526827d03d9c293450c0422beba77f04 ]

Use coredump (if available) to collect FW logs in case of a FW crash.
This makes dmesg more readable and allows to collect more log data.

Signed-off-by: Karol Wachowski <karol.wachowski@intel.com>
Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-8-jacek.lawrynowicz@linux.intel.com
Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
Stable-dep-of: 41a2d8286c90 ("accel/ivpu: Fix error handling in recovery/reset")
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Karol Wachowski
2024-09-30 21:52:58 +02:00
committed by Greg Kroah-Hartman
parent d3f80d98f2
commit 509662f532
7 changed files with 74 additions and 14 deletions
+1
View File
@@ -8,6 +8,7 @@ config DRM_ACCEL_IVPU
select FW_LOADER
select DRM_GEM_SHMEM_HELPER
select GENERIC_ALLOCATOR
select WANT_DEV_COREDUMP
help
Choose this option if you have a system with an 14th generation
Intel CPU (Meteor Lake) or newer. Intel NPU (formerly called Intel VPU)
+1
View File
@@ -19,5 +19,6 @@ intel_vpu-y := \
ivpu_sysfs.o
intel_vpu-$(CONFIG_DEBUG_FS) += ivpu_debugfs.o
intel_vpu-$(CONFIG_DEV_COREDUMP) += ivpu_coredump.o
obj-$(CONFIG_DRM_ACCEL_IVPU) += intel_vpu.o
+39
View File
@@ -0,0 +1,39 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2020-2024 Intel Corporation
*/
#include <linux/devcoredump.h>
#include <linux/firmware.h>
#include "ivpu_coredump.h"
#include "ivpu_fw.h"
#include "ivpu_gem.h"
#include "vpu_boot_api.h"
#define CRASH_DUMP_HEADER "Intel NPU crash dump"
#define CRASH_DUMP_HEADERS_SIZE SZ_4K
void ivpu_dev_coredump(struct ivpu_device *vdev)
{
struct drm_print_iterator pi = {};
struct drm_printer p;
size_t coredump_size;
char *coredump;
coredump_size = CRASH_DUMP_HEADERS_SIZE + FW_VERSION_HEADER_SIZE +
ivpu_bo_size(vdev->fw->mem_log_crit) + ivpu_bo_size(vdev->fw->mem_log_verb);
coredump = vmalloc(coredump_size);
if (!coredump)
return;
pi.data = coredump;
pi.remain = coredump_size;
p = drm_coredump_printer(&pi);
drm_printf(&p, "%s\n", CRASH_DUMP_HEADER);
drm_printf(&p, "FW version: %s\n", vdev->fw->version);
ivpu_fw_log_print(vdev, false, &p);
dev_coredumpv(vdev->drm.dev, coredump, pi.offset, GFP_KERNEL);
}
+25
View File
@@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2020-2024 Intel Corporation
*/
#ifndef __IVPU_COREDUMP_H__
#define __IVPU_COREDUMP_H__
#include <drm/drm_print.h>
#include "ivpu_drv.h"
#include "ivpu_fw_log.h"
#ifdef CONFIG_DEV_COREDUMP
void ivpu_dev_coredump(struct ivpu_device *vdev);
#else
static inline void ivpu_dev_coredump(struct ivpu_device *vdev)
{
struct drm_printer p = drm_info_printer(vdev->drm.dev);
ivpu_fw_log_print(vdev, false, &p);
}
#endif
#endif /* __IVPU_COREDUMP_H__ */
+3 -2
View File
@@ -14,7 +14,7 @@
#include <drm/drm_ioctl.h>
#include <drm/drm_prime.h>
#include "vpu_boot_api.h"
#include "ivpu_coredump.h"
#include "ivpu_debugfs.h"
#include "ivpu_drv.h"
#include "ivpu_fw.h"
@@ -29,6 +29,7 @@
#include "ivpu_ms.h"
#include "ivpu_pm.h"
#include "ivpu_sysfs.h"
#include "vpu_boot_api.h"
#ifndef DRIVER_VERSION_STR
#define DRIVER_VERSION_STR __stringify(DRM_IVPU_DRIVER_MAJOR) "." \
@@ -382,7 +383,7 @@ int ivpu_boot(struct ivpu_device *vdev)
ivpu_err(vdev, "Failed to boot the firmware: %d\n", ret);
ivpu_hw_diagnose_failure(vdev);
ivpu_mmu_evtq_dump(vdev);
ivpu_fw_log_dump(vdev);
ivpu_dev_coredump(vdev);
return ret;
}
-8
View File
@@ -8,8 +8,6 @@
#include <linux/types.h>
#include <drm/drm_print.h>
#include "ivpu_drv.h"
#define IVPU_FW_LOG_DEFAULT 0
@@ -28,11 +26,5 @@ extern unsigned int ivpu_log_level;
void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_printer *p);
void ivpu_fw_log_clear(struct ivpu_device *vdev);
static inline void ivpu_fw_log_dump(struct ivpu_device *vdev)
{
struct drm_printer p = drm_info_printer(vdev->drm.dev);
ivpu_fw_log_print(vdev, false, &p);
}
#endif /* __IVPU_FW_LOG_H__ */
+5 -4
View File
@@ -9,17 +9,18 @@
#include <linux/pm_runtime.h>
#include <linux/reboot.h>
#include "vpu_boot_api.h"
#include "ivpu_coredump.h"
#include "ivpu_drv.h"
#include "ivpu_hw.h"
#include "ivpu_fw.h"
#include "ivpu_fw_log.h"
#include "ivpu_hw.h"
#include "ivpu_ipc.h"
#include "ivpu_job.h"
#include "ivpu_jsm_msg.h"
#include "ivpu_mmu.h"
#include "ivpu_ms.h"
#include "ivpu_pm.h"
#include "vpu_boot_api.h"
static bool ivpu_disable_recovery;
module_param_named_unsafe(disable_recovery, ivpu_disable_recovery, bool, 0644);
@@ -123,7 +124,7 @@ static void ivpu_pm_recovery_work(struct work_struct *work)
if (ret)
ivpu_err(vdev, "Failed to resume NPU: %d\n", ret);
ivpu_fw_log_dump(vdev);
ivpu_dev_coredump(vdev);
atomic_inc(&vdev->pm->reset_counter);
atomic_set(&vdev->pm->reset_pending, 1);
@@ -262,7 +263,7 @@ int ivpu_pm_runtime_suspend_cb(struct device *dev)
if (!is_idle || ret_d0i3) {
ivpu_err(vdev, "Forcing cold boot due to previous errors\n");
atomic_inc(&vdev->pm->reset_counter);
ivpu_fw_log_dump(vdev);
ivpu_dev_coredump(vdev);
ivpu_pm_prepare_cold_boot(vdev);
} else {
ivpu_pm_prepare_warm_boot(vdev);