From 8abd7613b7ecf0f511a8fcd27adb1ea9043bb431 Mon Sep 17 00:00:00 2001 From: Deepak Kumar Date: Tue, 16 Feb 2021 14:44:00 +0530 Subject: [PATCH] msm: kgsl: Add snapshot memory region in minidump only once As snapshot can be recollected and snapshot size can vary on each recollection if we add snapshot region in minidump during each recollection then we need to remove it and add it again to ensure proper snapshot size is captured in minidump. To avoid this add snapshot region to minidump once and with complete snapshot memory size. Also, take care of removing it during close to ensure minidump doesn't try to access already freed memory region. Change-Id: I5eded015c0544a03eec835da57b6aaf64defc139 Signed-off-by: Deepak Kumar --- drivers/gpu/msm/kgsl_device.h | 3 ++- drivers/gpu/msm/kgsl_snapshot.c | 18 ++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h index 4cd2f5e3e5a1..8c797739b1fb 100644 --- a/drivers/gpu/msm/kgsl_device.h +++ b/drivers/gpu/msm/kgsl_device.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2002,2007-2021, The Linux Foundation. All rights reserved. */ #ifndef __KGSL_DEVICE_H #define __KGSL_DEVICE_H @@ -261,6 +261,7 @@ struct kgsl_device { struct { void *ptr; u32 size; + bool in_minidump; } snapshot_memory; struct kgsl_snapshot *snapshot; diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c index 40809f909ffe..f61d4b69070a 100644 --- a/drivers/gpu/msm/kgsl_snapshot.c +++ b/drivers/gpu/msm/kgsl_snapshot.c @@ -35,16 +35,18 @@ static void add_to_minidump(struct kgsl_device *device) struct md_region md_entry; int ret; - if (!msm_minidump_enabled()) + if (!msm_minidump_enabled() || device->snapshot_memory.in_minidump) return; scnprintf(md_entry.name, sizeof(md_entry.name), "GPU_SNAPSHOT"); md_entry.virt_addr = (u64)(device->snapshot_memory.ptr); md_entry.phys_addr = __pa(device->snapshot_memory.ptr); - md_entry.size = device->snapshot->size; + md_entry.size = device->snapshot_memory.size; ret = msm_minidump_add_region(&md_entry); if (ret < 0) dev_err(device->dev, "Failed to register snapshot with minidump: %d\n", ret); + else + device->snapshot_memory.in_minidump = true; } static void obj_itr_init(struct snapshot_obj_itr *itr, u8 *buf, @@ -1165,6 +1167,7 @@ void kgsl_device_snapshot_probe(struct kgsl_device *device, u32 size) return; } + device->snapshot_memory.in_minidump = false; device->snapshot = NULL; device->snapshot_faultcount = 0; device->force_panic = false; @@ -1195,6 +1198,17 @@ void kgsl_device_snapshot_probe(struct kgsl_device *device, u32 size) */ void kgsl_device_snapshot_close(struct kgsl_device *device) { + if (msm_minidump_enabled() && device->snapshot_memory.in_minidump) { + struct md_region md_entry; + + scnprintf(md_entry.name, sizeof(md_entry.name), "GPU_SNAPSHOT"); + md_entry.virt_addr = (u64)(device->snapshot_memory.ptr); + md_entry.phys_addr = __pa(device->snapshot_memory.ptr); + md_entry.size = device->snapshot_memory.size; + if (msm_minidump_remove_region(&md_entry) < 0) + dev_err(device->dev, "Failed to remove snapshot with minidump\n"); + } + sysfs_remove_bin_file(&device->snapshot_kobj, &snapshot_attr); sysfs_remove_files(&device->snapshot_kobj, snapshot_attrs);