From 274824c561775f03052c54637fd16ee30dce25f5 Mon Sep 17 00:00:00 2001 From: Pankaj Gupta Date: Thu, 6 May 2021 13:33:53 +0530 Subject: [PATCH] msm: kgsl: Fix snapshot collection for ib1 Sometimes IB1_BASE from register does not match with IB1 of the ring buffer, this may happen while doing save restore of IB during preemption. In such case, to dump IB1 in snapshot, check for overlap between IB1_BASE and IB1 from the ring buffer and dump IB1 in snapshot as per ring buffer's IB1 base and size. Change-Id: Ic3af8678a11f20f447fcbcbd3ec209283619b96a Signed-off-by: Pankaj Gupta --- drivers/gpu/msm/adreno_snapshot.c | 42 +++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c index 1b08ec8b018f..2da41adafdf7 100644 --- a/drivers/gpu/msm/adreno_snapshot.c +++ b/drivers/gpu/msm/adreno_snapshot.c @@ -183,7 +183,17 @@ void adreno_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; } @@ -287,16 +297,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); @@ -884,8 +907,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;