On 2021-02-23 4:10 p.m., Jonathan Kim wrote:
Add IH function to allow caller to process ring entries until the
checkpoint write pointer.
Suggested-by: Felix Kuehling <felix.kuehling@xxxxxxx>
Signed-off-by: Jonathan Kim <jonathan.kim@xxxxxxx>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 46 +++++++++++++++++++++++++-
drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 2 ++
2 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
index dc852af4f3b7..cae50af9559d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
@@ -22,7 +22,7 @@
*/
#include <linux/dma-mapping.h>
-
+#include <linux/processor.h>
#include "amdgpu.h"
#include "amdgpu_ih.h"
@@ -160,6 +160,50 @@ void amdgpu_ih_ring_write(struct amdgpu_ih_ring *ih, const uint32_t *iv,
}
}
+/**
+ * amdgpu_ih_wait_on_checkpoint_process - wait to process IVs up to checkpoint
+ *
+ * @adev: amdgpu_device pointer
+ * @ih: ih ring to process
+ *
+ * Used to ensure ring has processed IVs up to the checkpoint write pointer.
+ */
+int amdgpu_ih_wait_on_checkpoint_process(struct amdgpu_device *adev,
+ struct amdgpu_ih_ring *ih)
+{
+ u32 prev_rptr, cur_rptr, checkpoint_wptr;
+
+ if (!ih->enabled || adev->shutdown)
+ return -ENODEV;
+
+ cur_rptr = READ_ONCE(ih->rptr);
+ /* Order read of current rptr with checktpoint wptr. */
+ mb();
+ checkpoint_wptr = amdgpu_ih_get_wptr(adev, ih);
+
Isn't rmb() enough in this case ? If I understand correctly you just
want to confirm that
you are not reading stale checkpoint_wptr while reading fresh cur_rptr.
Andrey
+ /* allow rptr to wrap around */
+ if (cur_rptr > checkpoint_wptr) {
+ spin_begin();
+ do {
+ spin_cpu_relax();
+ prev_rptr = cur_rptr;
+ cur_rptr = READ_ONCE(ih->rptr);
+ } while (cur_rptr >= prev_rptr);
+ spin_end();
+ }
+
+ /* wait for rptr to catch up to or pass checkpoint. */
+ spin_begin();
+ do {
+ spin_cpu_relax();
+ prev_rptr = cur_rptr;
+ cur_rptr = READ_ONCE(ih->rptr);
+ } while (cur_rptr >= prev_rptr && cur_rptr < checkpoint_wptr);
+ spin_end();
+
+ return 0;
+}
+
/**
* amdgpu_ih_process - interrupt handler
*
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
index 6ed4a85fc7c3..6817f0a812d2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
@@ -87,6 +87,8 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih);
void amdgpu_ih_ring_write(struct amdgpu_ih_ring *ih, const uint32_t *iv,
unsigned int num_dw);
+int amdgpu_ih_wait_on_checkpoint_process(struct amdgpu_device *adev,
+ struct amdgpu_ih_ring *ih);
int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih);
void amdgpu_ih_decode_iv_helper(struct amdgpu_device *adev,
struct amdgpu_ih_ring *ih,
_______________________________________________
amd-gfx mailing list
amd-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/amd-gfx