[PATCH 15/16] drm/radeon: implement ring commit tracking

Jerome Glisse j.glisse at gmail.com
Mon Jul 9 08:36:10 PDT 2012


On Mon, Jul 9, 2012 at 6:42 AM, Christian König <deathsimple at vodafone.de> wrote:
> Signed-off-by: Christian König <deathsimple at vodafone.de>

Bit too complex to my taste, what about attached patch, it's lot
simpler. (Haven't tested
the patch but it should work)

Cheers,
Jerome

> ---
>  drivers/gpu/drm/radeon/radeon.h      |    3 +++
>  drivers/gpu/drm/radeon/radeon_ring.c |   39 ++++++++++++++++++++++++++++++++--
>  2 files changed, 40 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
> index fef4257..9c11be8 100644
> --- a/drivers/gpu/drm/radeon/radeon.h
> +++ b/drivers/gpu/drm/radeon/radeon.h
> @@ -637,6 +637,9 @@ struct radeon_ring {
>         u32                     ptr_reg_shift;
>         u32                     ptr_reg_mask;
>         u32                     nop;
> +       unsigned                *track_back;
> +       unsigned                track_ptr;
> +       unsigned                track_mask;
>  };
>
>  /*
> diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
> index d9b2e45..994c98c 100644
> --- a/drivers/gpu/drm/radeon/radeon_ring.c
> +++ b/drivers/gpu/drm/radeon/radeon_ring.c
> @@ -276,6 +276,8 @@ void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring)
>         DRM_MEMORYBARRIER();
>         WREG32(ring->wptr_reg, (ring->wptr << ring->ptr_reg_shift) & ring->ptr_reg_mask);
>         (void)RREG32(ring->wptr_reg);
> +       ring->track_back[ring->track_ptr++] = ring->wptr_old;
> +       ring->track_ptr &= ring->track_mask;
>  }
>
>  void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *ring)
> @@ -362,6 +364,27 @@ bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *rin
>         return false;
>  }
>
> +static unsigned radeon_ring_first_valid_commit(struct radeon_ring *ring)
> +{
> +       unsigned i, c, result = ring->track_ptr;
> +       i = ring->track_ptr - 1;
> +       while (i != ring->track_ptr) {
> +               i &= ring->track_mask;
> +               c = ring->track_back[i];
> +
> +               if (ring->wptr >= ring->rptr) {
> +                       if (c < ring->rptr || c >= ring->wptr)
> +                               break;
> +               } else {
> +                       if (c < ring->rptr && c >= ring->wptr)
> +                               break;
> +               }
> +
> +               result = i--;
> +       }
> +       return result;
> +}
> +
>  int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring,
>                      unsigned ring_size, unsigned align,
>                      unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg,
> @@ -403,6 +426,10 @@ int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring,
>                         dev_err(rdev->dev, "(%d) ring map failed\n", r);
>                         return r;
>                 }
> +               ring->track_back = kmalloc(ring_size / align, GFP_KERNEL);
> +               memset(ring->track_back, 0, ring_size / align);
> +               ring->track_ptr = 0;
> +               ring->track_mask = ((ring->ring_size / 4) / align) - 1;
>         }
>         ring->ptr_mask = (ring->ring_size / 4) - 1;
>         ring->ring_free_dw = ring->ring_size / 4;
> @@ -422,6 +449,7 @@ void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *ring)
>         ring->ready = false;
>         ring->ring = NULL;
>         ring->ring_obj = NULL;
> +       kfree(ring->track_back);
>         mutex_unlock(&rdev->ring_lock);
>
>         if (ring_obj) {
> @@ -447,7 +475,7 @@ static int radeon_debugfs_ring_info(struct seq_file *m, void *data)
>         struct radeon_device *rdev = dev->dev_private;
>         int ridx = *(int*)node->info_ent->data;
>         struct radeon_ring *ring = &rdev->ring[ridx];
> -       unsigned count, i, j;
> +       unsigned count, i, j, commit;
>
>         radeon_ring_free_size(rdev, ring);
>         count = (ring->ring_size / 4) - ring->ring_free_dw;
> @@ -457,9 +485,16 @@ static int radeon_debugfs_ring_info(struct seq_file *m, void *data)
>         seq_printf(m, "driver's copy of the rptr: 0x%08x\n", ring->rptr);
>         seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw);
>         seq_printf(m, "%u dwords in ring\n", count);
> +       commit = radeon_ring_first_valid_commit(ring);
>         i = ring->rptr;
>         for (j = 0; j <= count; j++) {
> -               seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]);
> +               seq_printf(m, "r[%04x]=0x%08x", i, ring->ring[i]);
> +               if (commit != ring->track_ptr && ring->track_back[commit] == i) {
> +                       seq_printf(m, " <-");
> +                       ++commit;
> +                       commit &= ring->track_mask;
> +               }
> +               seq_printf(m, "\n");
>                 i = (i + 1) & ring->ptr_mask;
>         }
>         return 0;
> --
> 1.7.9.5
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-drm-radeon-record-what-is-next-valid-wptr-for-each-r.patch
Type: application/octet-stream
Size: 7152 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20120709/f0d368f6/attachment.obj>


More information about the dri-devel mailing list