From b0d56ee1cb80e3b3b6af5bf738b0233b36fc9483 Mon Sep 17 00:00:00 2001 From: Harshdeep Dhatt Date: Fri, 18 Dec 2015 15:13:06 -0700 Subject: [PATCH] msm: kgsl: Make snapshot resilient to a non-existent ib1base During snapshot, we may encounter an invalid IB1 base which is not found in the current rb. In that case, dump the entire ringbuffer from start to end and all the IBs in it to get a more complete picture of the failure. Change-Id: I4393c7de6f8f4890870fa6e2b5e69073dce922b7 Signed-off-by: Harshdeep Dhatt --- drivers/gpu/msm/adreno_snapshot.c | 54 +++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c index ab12399ba236..85387889b5ce 100644 --- a/drivers/gpu/msm/adreno_snapshot.c +++ b/drivers/gpu/msm/adreno_snapshot.c @@ -244,6 +244,48 @@ static inline bool iommu_is_setstate_addr(struct kgsl_device *device, size); } +static void dump_all_ibs(struct kgsl_device *device, + struct adreno_ringbuffer *rb, + struct kgsl_snapshot *snapshot) +{ + int index = 0; + unsigned int *rbptr; + struct adreno_device *adreno_dev = ADRENO_DEVICE(device); + + rbptr = rb->buffer_desc.hostptr; + + for (index = 0; index < KGSL_RB_DWORDS;) { + + if (adreno_cmd_is_ib(adreno_dev, rbptr[index])) { + uint64_t ibaddr; + uint64_t ibsize; + + if (ADRENO_LEGACY_PM4(adreno_dev)) { + ibaddr = rbptr[index + 1]; + ibsize = rbptr[index + 2]; + index += 3; + } else { + ibaddr = rbptr[index + 2]; + ibaddr = ibaddr << 32 | rbptr[index + 1]; + ibsize = rbptr[index + 3]; + index += 4; + } + + /* Don't parse known global IBs */ + if (iommu_is_setstate_addr(device, ibaddr, ibsize)) + continue; + + if (kgsl_gpuaddr_in_memdesc(&adreno_dev->pwron_fixup, + ibaddr, ibsize)) + continue; + + parse_ib(device, snapshot, snapshot->process, ibaddr, + ibsize); + } else + index = index + 1; + } +} + /** * snapshot_rb_ibs() - Dump rb data and capture the IB's in the RB as well * @rb: The RB to dump @@ -295,6 +337,18 @@ static void snapshot_rb_ibs(struct adreno_ringbuffer *rb, break; } while (index != rb->wptr); + /* + * If the ib1 was not found, for example, if ib1base was restored + * incorrectly after preemption, then simply dump the entire + * ringbuffer along with all the IBs in the ringbuffer. + */ + + if (index == rb->wptr) { + memcpy(data, rb->buffer_desc.hostptr, KGSL_RB_SIZE); + dump_all_ibs(device, rb, snapshot); + return; + } + /* * index points at the last submitted IB. We can only trust that the * memory between the context switch and the hanging IB is valid, so