Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

accel/ivpu: Add coredump support

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>

authored by

Karol Wachowski and committed by
Jacek Lawrynowicz
bade0340 990b1e3d

+74 -14
+1
drivers/accel/ivpu/Kconfig
··· 8 8 select FW_LOADER 9 9 select DRM_GEM_SHMEM_HELPER 10 10 select GENERIC_ALLOCATOR 11 + select WANT_DEV_COREDUMP 11 12 help 12 13 Choose this option if you have a system with an 14th generation 13 14 Intel CPU (Meteor Lake) or newer. Intel NPU (formerly called Intel VPU)
+1
drivers/accel/ivpu/Makefile
··· 19 19 ivpu_sysfs.o 20 20 21 21 intel_vpu-$(CONFIG_DEBUG_FS) += ivpu_debugfs.o 22 + intel_vpu-$(CONFIG_DEV_COREDUMP) += ivpu_coredump.o 22 23 23 24 obj-$(CONFIG_DRM_ACCEL_IVPU) += intel_vpu.o
+39
drivers/accel/ivpu/ivpu_coredump.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (C) 2020-2024 Intel Corporation 4 + */ 5 + 6 + #include <linux/devcoredump.h> 7 + #include <linux/firmware.h> 8 + 9 + #include "ivpu_coredump.h" 10 + #include "ivpu_fw.h" 11 + #include "ivpu_gem.h" 12 + #include "vpu_boot_api.h" 13 + 14 + #define CRASH_DUMP_HEADER "Intel NPU crash dump" 15 + #define CRASH_DUMP_HEADERS_SIZE SZ_4K 16 + 17 + void ivpu_dev_coredump(struct ivpu_device *vdev) 18 + { 19 + struct drm_print_iterator pi = {}; 20 + struct drm_printer p; 21 + size_t coredump_size; 22 + char *coredump; 23 + 24 + coredump_size = CRASH_DUMP_HEADERS_SIZE + FW_VERSION_HEADER_SIZE + 25 + ivpu_bo_size(vdev->fw->mem_log_crit) + ivpu_bo_size(vdev->fw->mem_log_verb); 26 + coredump = vmalloc(coredump_size); 27 + if (!coredump) 28 + return; 29 + 30 + pi.data = coredump; 31 + pi.remain = coredump_size; 32 + p = drm_coredump_printer(&pi); 33 + 34 + drm_printf(&p, "%s\n", CRASH_DUMP_HEADER); 35 + drm_printf(&p, "FW version: %s\n", vdev->fw->version); 36 + ivpu_fw_log_print(vdev, false, &p); 37 + 38 + dev_coredumpv(vdev->drm.dev, coredump, pi.offset, GFP_KERNEL); 39 + }
+25
drivers/accel/ivpu/ivpu_coredump.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright (C) 2020-2024 Intel Corporation 4 + */ 5 + 6 + #ifndef __IVPU_COREDUMP_H__ 7 + #define __IVPU_COREDUMP_H__ 8 + 9 + #include <drm/drm_print.h> 10 + 11 + #include "ivpu_drv.h" 12 + #include "ivpu_fw_log.h" 13 + 14 + #ifdef CONFIG_DEV_COREDUMP 15 + void ivpu_dev_coredump(struct ivpu_device *vdev); 16 + #else 17 + static inline void ivpu_dev_coredump(struct ivpu_device *vdev) 18 + { 19 + struct drm_printer p = drm_info_printer(vdev->drm.dev); 20 + 21 + ivpu_fw_log_print(vdev, false, &p); 22 + } 23 + #endif 24 + 25 + #endif /* __IVPU_COREDUMP_H__ */
+3 -2
drivers/accel/ivpu/ivpu_drv.c
··· 14 14 #include <drm/drm_ioctl.h> 15 15 #include <drm/drm_prime.h> 16 16 17 - #include "vpu_boot_api.h" 17 + #include "ivpu_coredump.h" 18 18 #include "ivpu_debugfs.h" 19 19 #include "ivpu_drv.h" 20 20 #include "ivpu_fw.h" ··· 29 29 #include "ivpu_ms.h" 30 30 #include "ivpu_pm.h" 31 31 #include "ivpu_sysfs.h" 32 + #include "vpu_boot_api.h" 32 33 33 34 #ifndef DRIVER_VERSION_STR 34 35 #define DRIVER_VERSION_STR __stringify(DRM_IVPU_DRIVER_MAJOR) "." \ ··· 383 382 ivpu_err(vdev, "Failed to boot the firmware: %d\n", ret); 384 383 ivpu_hw_diagnose_failure(vdev); 385 384 ivpu_mmu_evtq_dump(vdev); 386 - ivpu_fw_log_dump(vdev); 385 + ivpu_dev_coredump(vdev); 387 386 return ret; 388 387 } 389 388
-8
drivers/accel/ivpu/ivpu_fw_log.h
··· 8 8 9 9 #include <linux/types.h> 10 10 11 - #include <drm/drm_print.h> 12 - 13 11 #include "ivpu_drv.h" 14 12 15 13 #define IVPU_FW_LOG_DEFAULT 0 ··· 27 29 void ivpu_fw_log_mark_read(struct ivpu_device *vdev); 28 30 void ivpu_fw_log_reset(struct ivpu_device *vdev); 29 31 30 - static inline void ivpu_fw_log_dump(struct ivpu_device *vdev) 31 - { 32 - struct drm_printer p = drm_info_printer(vdev->drm.dev); 33 - 34 - ivpu_fw_log_print(vdev, false, &p); 35 - } 36 32 37 33 #endif /* __IVPU_FW_LOG_H__ */
+5 -4
drivers/accel/ivpu/ivpu_pm.c
··· 9 9 #include <linux/pm_runtime.h> 10 10 #include <linux/reboot.h> 11 11 12 - #include "vpu_boot_api.h" 12 + #include "ivpu_coredump.h" 13 13 #include "ivpu_drv.h" 14 - #include "ivpu_hw.h" 15 14 #include "ivpu_fw.h" 16 15 #include "ivpu_fw_log.h" 16 + #include "ivpu_hw.h" 17 17 #include "ivpu_ipc.h" 18 18 #include "ivpu_job.h" 19 19 #include "ivpu_jsm_msg.h" 20 20 #include "ivpu_mmu.h" 21 21 #include "ivpu_ms.h" 22 22 #include "ivpu_pm.h" 23 + #include "vpu_boot_api.h" 23 24 24 25 static bool ivpu_disable_recovery; 25 26 module_param_named_unsafe(disable_recovery, ivpu_disable_recovery, bool, 0644); ··· 125 124 if (ret) 126 125 ivpu_err(vdev, "Failed to resume NPU: %d\n", ret); 127 126 128 - ivpu_fw_log_dump(vdev); 127 + ivpu_dev_coredump(vdev); 129 128 130 129 atomic_inc(&vdev->pm->reset_counter); 131 130 atomic_set(&vdev->pm->reset_pending, 1); ··· 264 263 if (!is_idle || ret_d0i3) { 265 264 ivpu_err(vdev, "Forcing cold boot due to previous errors\n"); 266 265 atomic_inc(&vdev->pm->reset_counter); 267 - ivpu_fw_log_dump(vdev); 266 + ivpu_dev_coredump(vdev); 268 267 ivpu_pm_prepare_cold_boot(vdev); 269 268 } else { 270 269 ivpu_pm_prepare_warm_boot(vdev);