diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_device.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 64 | 
1 files changed, 64 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index c56b04e9ce9a..620afd75dae7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -32,6 +32,8 @@  #include <linux/slab.h>  #include <linux/iommu.h>  #include <linux/pci.h> +#include <linux/devcoredump.h> +#include <generated/utsrelease.h>  #include <drm/drm_atomic_helper.h>  #include <drm/drm_probe_helper.h> @@ -4680,6 +4682,59 @@ static int amdgpu_reset_reg_dumps(struct amdgpu_device *adev)  	return 0;  } +#ifdef CONFIG_DEV_COREDUMP +static ssize_t amdgpu_devcoredump_read(char *buffer, loff_t offset, +		size_t count, void *data, size_t datalen) +{ +	struct drm_printer p; +	struct amdgpu_device *adev = data; +	struct drm_print_iterator iter; +	int i; + +	iter.data = buffer; +	iter.offset = 0; +	iter.start = offset; +	iter.remain = count; + +	p = drm_coredump_printer(&iter); + +	drm_printf(&p, "**** AMDGPU Device Coredump ****\n"); +	drm_printf(&p, "kernel: " UTS_RELEASE "\n"); +	drm_printf(&p, "module: " KBUILD_MODNAME "\n"); +	drm_printf(&p, "time: %lld.%09ld\n", adev->reset_time.tv_sec, adev->reset_time.tv_nsec); +	if (adev->reset_task_info.pid) +		drm_printf(&p, "process_name: %s PID: %d\n", +			   adev->reset_task_info.process_name, +			   adev->reset_task_info.pid); + +	if (adev->reset_vram_lost) +		drm_printf(&p, "VRAM is lost due to GPU reset!\n"); +	if (adev->num_regs) { +		drm_printf(&p, "AMDGPU register dumps:\nOffset:     Value:\n"); + +		for (i = 0; i < adev->num_regs; i++) +			drm_printf(&p, "0x%08x: 0x%08x\n", +				   adev->reset_dump_reg_list[i], +				   adev->reset_dump_reg_value[i]); +	} + +	return count - iter.remain; +} + +static void amdgpu_devcoredump_free(void *data) +{ +} + +static void amdgpu_reset_capture_coredumpm(struct amdgpu_device *adev) +{ +	struct drm_device *dev = adev_to_drm(adev); + +	ktime_get_ts64(&adev->reset_time); +	dev_coredumpm(dev->dev, THIS_MODULE, adev, 0, GFP_KERNEL, +		      amdgpu_devcoredump_read, amdgpu_devcoredump_free); +} +#endif +  int amdgpu_do_asic_reset(struct list_head *device_list_handle,  			 struct amdgpu_reset_context *reset_context)  { @@ -4764,6 +4819,15 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,  					goto out;  				vram_lost = amdgpu_device_check_vram_lost(tmp_adev); +#ifdef CONFIG_DEV_COREDUMP +				tmp_adev->reset_vram_lost = vram_lost; +				memset(&tmp_adev->reset_task_info, 0, +						sizeof(tmp_adev->reset_task_info)); +				if (reset_context->job && reset_context->job->vm) +					tmp_adev->reset_task_info = +						reset_context->job->vm->task_info; +				amdgpu_reset_capture_coredumpm(tmp_adev); +#endif  				if (vram_lost) {  					DRM_INFO("VRAM is lost due to GPU reset!\n");  					amdgpu_inc_vram_lost(tmp_adev);  | 
