diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c index 780e89d58899..8529084eaaf0 100644 --- a/drivers/gpu/msm/adreno_snapshot.c +++ b/drivers/gpu/msm/adreno_snapshot.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ #include @@ -195,7 +195,17 @@ static inline void parse_ib(struct kgsl_device *device, * then push it into the static blob otherwise put it in the dynamic * list */ - if (gpuaddr == snapshot->ib1base) { + if (kgsl_addr_range_overlap(gpuaddr, dwords, + snapshot->ib1base, snapshot->ib1size)) { + /* + * During restore after preemption, ib1base in the register + * can be updated by CP. In such scenarios, to dump complete + * IB1 in snapshot, we should consider ib1base from ringbuffer. + */ + if (gpuaddr != snapshot->ib1base) { + snapshot->ib1base = gpuaddr; + snapshot->ib1size = dwords; + } kgsl_snapshot_push_object(device, process, gpuaddr, dwords); return; } @@ -309,16 +319,29 @@ static void snapshot_rb_ibs(struct kgsl_device *device, } if (adreno_cmd_is_ib(adreno_dev, rbptr[index])) { - if (ADRENO_LEGACY_PM4(adreno_dev)) { - if (rbptr[index + 1] == snapshot->ib1base) - break; - } else { - uint64_t ibaddr; + uint64_t ibaddr; + uint64_t ibsize; + if (ADRENO_LEGACY_PM4(adreno_dev)) { + ibaddr = rbptr[index + 1]; + ibsize = rbptr[index + 2]; + } else { ibaddr = rbptr[index + 2]; ibaddr = ibaddr << 32 | rbptr[index + 1]; - if (ibaddr == snapshot->ib1base) - break; + ibsize = rbptr[index + 3]; + } + + if (kgsl_addr_range_overlap(ibaddr, ibsize, + snapshot->ib1base, snapshot->ib1size)) { + /* + * During restore after preemption, ib1base in + * the register can be updated by CP. In such + * scenario, to dump complete IB1 in snapshot, + * we should consider ib1base from ringbuffer. + */ + snapshot->ib1base = ibaddr; + snapshot->ib1size = ibsize; + break; } } } while (index != rb->wptr); @@ -916,8 +939,7 @@ void adreno_snapshot(struct kgsl_device *device, struct kgsl_snapshot *snapshot, * figure how often this really happens. */ - if (-ENOENT == find_object(snapshot->ib1base, snapshot->process) && - snapshot->ib1size) { + if (-ENOENT == find_object(snapshot->ib1base, snapshot->process)) { struct kgsl_mem_entry *entry; u64 ibsize;