From 6e294b6fdf4d378c8e201d5897d2698f176138f4 Mon Sep 17 00:00:00 2001 From: Harshdeep Dhatt Date: Tue, 8 Sep 2020 14:28:42 -0600 Subject: [PATCH 1/4] msm: kgsl: Add kernel profile buffer to snapshot This helps establish submission order of submissions across ringbuffers as well as help establish how long the recent submissions took on the GPU. Change-Id: I181d1b49c23b37888106370609dc086ccb3439ae Signed-off-by: Harshdeep Dhatt --- drivers/gpu/msm/adreno_a6xx_hwsched.c | 6 ++++++ drivers/gpu/msm/adreno_snapshot.c | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/drivers/gpu/msm/adreno_a6xx_hwsched.c b/drivers/gpu/msm/adreno_a6xx_hwsched.c index 6e1d85a156b9..b47d40acef61 100644 --- a/drivers/gpu/msm/adreno_a6xx_hwsched.c +++ b/drivers/gpu/msm/adreno_a6xx_hwsched.c @@ -120,6 +120,12 @@ void a6xx_hwsched_snapshot(struct adreno_device *adreno_dev, snapshot, adreno_snapshot_global, entry->gpu_md); + if (entry->desc.mem_kind == MEMKIND_PROFILE) + kgsl_snapshot_add_section(device, + KGSL_SNAPSHOT_SECTION_GPU_OBJECT_V2, + snapshot, adreno_snapshot_global, + entry->gpu_md); + if (entry->desc.mem_kind == MEMKIND_CSW_SMMU_INFO) kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_GPU_OBJECT_V2, diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c index 1f0874a539dc..6d534a38ba3d 100644 --- a/drivers/gpu/msm/adreno_snapshot.c +++ b/drivers/gpu/msm/adreno_snapshot.c @@ -854,6 +854,10 @@ void adreno_snapshot(struct kgsl_device *device, struct kgsl_snapshot *snapshot, snapshot, adreno_snapshot_global, adreno_dev->pwron_fixup); + kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_GPU_OBJECT_V2, + snapshot, adreno_snapshot_global, + adreno_dev->profile_buffer); + if (kgsl_mmu_get_mmutype(device) == KGSL_MMU_TYPE_IOMMU) adreno_snapshot_iommu(device, snapshot); From 01e5e2f57e74f4c154621f22e31120161c7619d8 Mon Sep 17 00:00:00 2001 From: Harshdeep Dhatt Date: Fri, 4 Sep 2020 16:09:05 -0600 Subject: [PATCH 2/4] msm: kgsl: Remove dev_err() from fenced write loop dev_err() can take milliseconds to finish which can allow GMU to come out of IFPC and go back to IFPC before kgsl gets a chance to update the fenced register. Change-Id: Ic1846188213da571c23d52b8a78eb2162a8adc7b Signed-off-by: Harshdeep Dhatt --- drivers/gpu/msm/adreno.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index fcc21dbf8ced..8aeabbcb5966 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -3062,26 +3062,32 @@ int adreno_gmu_fenced_write(struct adreno_device *adreno_dev, * was successful */ if (!(status & fence_mask)) - return 0; + break; + /* Wait a small amount of time before trying again */ udelay(GMU_CORE_WAKEUP_DELAY_US); /* Try to write the fenced register again */ adreno_writereg(adreno_dev, offset, val); + } - if (i == GMU_CORE_SHORT_WAKEUP_RETRY_LIMIT) - dev_err(adreno_dev->dev.dev, - "Waited %d usecs to write fenced register 0x%x. Continuing to wait...\n", - (GMU_CORE_SHORT_WAKEUP_RETRY_LIMIT * - GMU_CORE_WAKEUP_DELAY_US), - reg_offset); + if (i < GMU_CORE_SHORT_WAKEUP_RETRY_LIMIT) + return 0; + + if (i == GMU_CORE_LONG_WAKEUP_RETRY_LIMIT) { + dev_err(adreno_dev->dev.dev, + "Timed out waiting %d usecs to write fenced register 0x%x\n", + i * GMU_CORE_WAKEUP_DELAY_US, + reg_offset); + return -ETIMEDOUT; } dev_err(adreno_dev->dev.dev, - "Timed out waiting %d usecs to write fenced register 0x%x\n", - GMU_CORE_LONG_WAKEUP_RETRY_LIMIT * GMU_CORE_WAKEUP_DELAY_US, + "Waited %d usecs to write fenced register 0x%x\n", + i * GMU_CORE_WAKEUP_DELAY_US, reg_offset); - return -ETIMEDOUT; + + return 0; } bool adreno_is_cx_dbgc_register(struct kgsl_device *device, From 8833b6fd82c41cb1dd8c1f8a97e77b9f462c4edc Mon Sep 17 00:00:00 2001 From: Harshdeep Dhatt Date: Thu, 3 Sep 2020 21:05:00 -0600 Subject: [PATCH 3/4] msm: kgsl: Update internal timestamp when preemption is toggled Say preemption is enabled and a context is bound to ringbuffer-1. It's internal timestamp say is 0x4000. Now if we disable preemption, all the contexts are bound to ringbuffer-0. Now, say the context is going away. The context destroy path will check timestamp 0x4000 which is from the stale ringbuffer, against ringbuffer-0, and its very likely that ringbuffer-0's timestamp is less than 0x4000 which will cause a false context-detach fault. Fix this by updating the context's internal timestamp to the last retired timestamp on the new ringbuffer. Also, toggle preemption only if ringbuffers are completely drained. Change-Id: I674978593b11df3998765017c270c3f0dde6c0a5 Signed-off-by: Harshdeep Dhatt --- drivers/gpu/msm/adreno_sysfs.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/msm/adreno_sysfs.c b/drivers/gpu/msm/adreno_sysfs.c index c9bd4c7f1cbf..be8ef6db3d74 100644 --- a/drivers/gpu/msm/adreno_sysfs.c +++ b/drivers/gpu/msm/adreno_sysfs.c @@ -144,16 +144,38 @@ static void change_preemption(struct adreno_device *adreno_dev, void *priv) struct kgsl_device *device = KGSL_DEVICE(adreno_dev); struct kgsl_context *context; struct adreno_context *drawctxt; - int id; + struct adreno_ringbuffer *rb; + int id, i, ret; + + /* Make sure all ringbuffers are finished */ + FOR_EACH_RINGBUFFER(adreno_dev, rb, i) { + ret = adreno_ringbuffer_waittimestamp(rb, rb->timestamp, + 2 * 1000); + if (ret) { + dev_err(device->dev, + "Cannot disable preemption because couldn't idle ringbuffer[%d] ret: %d\n", + rb->id, ret); + return; + } + } change_bit(ADRENO_DEVICE_PREEMPTION, &adreno_dev->priv); - adreno_dev->cur_rb = &(adreno_dev->ringbuffers[0]); + adreno_dev->cur_rb = &adreno_dev->ringbuffers[0]; + adreno_dev->next_rb = NULL; + adreno_dev->prev_rb = NULL; /* Update the ringbuffer for each draw context */ write_lock(&device->context_lock); idr_for_each_entry(&device->context_idr, context, id) { drawctxt = ADRENO_CONTEXT(context); drawctxt->rb = adreno_ctx_get_rb(adreno_dev, drawctxt); + + /* + * Make sure context destroy checks against the correct + * ringbuffer's timestamp. + */ + adreno_rb_readtimestamp(adreno_dev, drawctxt->rb, + KGSL_TIMESTAMP_RETIRED, &drawctxt->internal_timestamp); } write_unlock(&device->context_lock); } From d1ee0bf97522bfac15abad6fc596dd9146eae628 Mon Sep 17 00:00:00 2001 From: Harshdeep Dhatt Date: Tue, 8 Sep 2020 16:52:32 -0600 Subject: [PATCH 4/4] msm: kgsl: Re-define maximum number of cmds for hwscheduling HFI messages are only SZ_1K bytes. From this, derive HWSCHED_MAX_NUMIBS as the number of maximum IBs that can be in a single submission in hwscheduling. Change-Id: Id6d5cd2c8130479bc83f731ddd564af8c552e531 Signed-off-by: Harshdeep Dhatt --- drivers/gpu/msm/adreno_a6xx_hwsched_hfi.h | 5 +++++ drivers/gpu/msm/adreno_hwsched.c | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/drivers/gpu/msm/adreno_a6xx_hwsched_hfi.h b/drivers/gpu/msm/adreno_a6xx_hwsched_hfi.h index 70635b60f6ff..435134f4b36f 100644 --- a/drivers/gpu/msm/adreno_a6xx_hwsched_hfi.h +++ b/drivers/gpu/msm/adreno_a6xx_hwsched_hfi.h @@ -6,6 +6,11 @@ #ifndef _ADRENO_A6XX_HWSCHED_HFI_H_ #define _ADRENO_A6XX_HWSCHED_HFI_H_ +/* Maximum number of IBs in a submission */ +#define HWSCHED_MAX_NUMIBS \ + ((HFI_MAX_MSG_SIZE - offsetof(struct hfi_issue_cmd_cmd, ibs)) \ + / sizeof(struct hfi_issue_ib)) + enum mem_kind { /** @MEMKIND_GENERIC: Used for requesting generic memory */ MEMKIND_GENERIC = 0, diff --git a/drivers/gpu/msm/adreno_hwsched.c b/drivers/gpu/msm/adreno_hwsched.c index 3fa6ac3cf260..402fe2a02bec 100644 --- a/drivers/gpu/msm/adreno_hwsched.c +++ b/drivers/gpu/msm/adreno_hwsched.c @@ -836,6 +836,23 @@ int adreno_hwsched_queue_cmds(struct kgsl_device_private *dev_priv, if (!count) return -EINVAL; + for (i = 0; i < count; i++) { + struct kgsl_drawobj_cmd *cmdobj; + struct kgsl_memobj_node *ib; + u32 numibs = 0; + + if (drawobj[i]->type != CMDOBJ_TYPE) + continue; + + cmdobj = CMDOBJ(drawobj[i]); + + list_for_each_entry(ib, &cmdobj->cmdlist, node) + numibs++; + + if (numibs > HWSCHED_MAX_NUMIBS) + return -EINVAL; + } + ret = _check_context_state(&drawctxt->base); if (ret) return ret;