All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Wilson <chris@chris-wilson.co.uk>
To: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH 2/3] drm/i915: Allow userspace to specify ringsize on construction
Date: Mon, 18 Nov 2019 11:28:29 +0000	[thread overview]
Message-ID: <157407650904.24372.7396047058720514369@skylake-alporthouse-com> (raw)
In-Reply-To: <14059150.4o38dXUsEa@jkrzyszt-desk.ger.corp.intel.com>

Quoting Janusz Krzysztofik (2019-11-18 11:14:12)
> Hi Chris,
> 
> Only some minor comments from me, mostly out of my curiosity.
> 
> On Friday, November 15, 2019 5:05:45 PM CET Chris Wilson wrote:
> > No good reason why we must always use a static ringsize, so let
> > userspace select one during construction.
> > 
> > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> > Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> > ---
> > +static int __apply_ringsize(struct intel_context *ce, void *sz)
> > +{
> > +     int err;
> > +
> > +     err = i915_active_wait(&ce->active);
> > +     if (err < 0)
> > +             return err;
> > +
> > +     if (intel_context_lock_pinned(ce))
> > +             return -EINTR;
> > +
> > +     if (intel_context_is_pinned(ce)) {
> > +             err = -EBUSY; /* In active use, come back later! */
> > +             goto unlock;
> > +     }
> > +
> > +     if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
> > +             struct intel_ring *ring;
> > +
> > +             /* Replace the existing ringbuffer */
> > +             ring = intel_engine_create_ring(ce->engine,
> > +                                             (unsigned long)sz);
> > +             if (IS_ERR(ring)) {
> > +                     err = PTR_ERR(ring);
> > +                     goto unlock;
> > +             }
> > +
> > +             intel_ring_put(ce->ring);
> > +             ce->ring = ring;
> > +
> > +             /* Context image will be updated on next pin */
> > +     } else {
> > +             ce->ring = sz;
> > +     }
> > +
> > +unlock:
> > +     intel_context_unlock_pinned(ce);
> > +     return err;
> > +}
> 
> I'm wondering if this function (and __get_ringsize() below as well), with its 
> dependency on intel_context internals, especially on that dual meaning of 
> ce->ring which depends on (ce->flags & CONTEXT_ALLOC_BIT), would better fit 
> into drivers/gpu/drm/i915/gt/intel_context.c.

Possibly, but at the same time it's currently only implementing a
feature of the GEM context.

I hear you, I'm just resisting, mainly because I don't want to have to
think of a good name :)

intel_context_param.c
intel_context_ring.c

I might be able to find friends for either.

> > +static int set_ringsize(struct i915_gem_context *ctx,
> > +                     struct drm_i915_gem_context_param *args)
> > +{
> > +     if (!HAS_LOGICAL_RING_CONTEXTS(ctx->i915))
> > +             return -ENODEV;
> > +
> > +     if (args->size)
> > +             return -EINVAL;
> > +
> > +     if (!IS_ALIGNED(args->value, I915_GTT_PAGE_SIZE))
> > +             return -EINVAL;
> > +
> > +     if (args->value < I915_GTT_PAGE_SIZE)
> > +             return -EINVAL;
> > +
> > +     if (args->value > 128 * I915_GTT_PAGE_SIZE)
> > +             return -EINVAL;
> > +
> > +     return context_apply_all(ctx,
> > +                              __apply_ringsize,
> > +                              __intel_context_ring_size(args->value));
> > +}
> > +
> > +static int __get_ringsize(struct intel_context *ce, void *arg)
> > +{
> > +     int num_pages;
> > +
> > +     if (intel_context_lock_pinned(ce))
> > +             return -EINTR;
> > +
> > +     if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags))
> > +             num_pages = ce->ring->size / I915_GTT_PAGE_SIZE;
> > +     else
> > +             num_pages = (uintptr_t)ce->ring / I915_GTT_PAGE_SIZE;
> > +
> > +     intel_context_unlock_pinned(ce);
> > +     return num_pages; /* stop on first engine */
> 
> Location of this comment seems not perfect to me as it is not quite obvious 
> how that works without examining how this function is used, but having spent a 
> while looking around, I'm not able to suggest a better place.

Yeah, the comment is for the intent of returning the positive, so
there's definitely a case for explaining the unusual pattern here.

The calling loop is just a standard if (err) return err; propagation so
that hardly merits a long winded explanation.

> > +static int get_ringsize(struct i915_gem_context *ctx,
> > +                     struct drm_i915_gem_context_param *args)
> > +{
> > +     int num_pages;
> > +
> > +     if (!HAS_LOGICAL_RING_CONTEXTS(ctx->i915))
> > +             return -ENODEV;
> > +
> > +     if (args->size)
> > +             return -EINVAL;
> > +
> > +     num_pages = context_apply_all(ctx, __get_ringsize, NULL);
> > +     if (num_pages < 0)
> > +             return num_pages;
> > +
> > +     args->value = (u64)num_pages * I915_GTT_PAGE_SIZE;
> 
> Do you convert to num_pages inside __get_ringsize() then back to size in bytes 
> to avoid an overflow?  Or any other reason?  Something that may be useful in 
> the future?

Just being prudent in making sure we have sufficient bits across all the
type-narrowing.

> > @@ -2003,6 +2113,19 @@ static int clone_engines(struct i915_gem_context *dst,
> >                       __free_engines(clone, n);
> >                       goto err_unlock;
> >               }
> > +
> > +             /* Copy across the preferred ringsize */
> > +             clone->engines[n]->ring = e->engines[n]->ring;
> > +             if (test_bit(CONTEXT_ALLOC_BIT, &e->engines[n]->flags)) {
> > +                     if (intel_context_lock_pinned(e->engines[n])) {
> > +                             __free_engines(clone, n + 1);
> > +                             goto err_unlock;
> > +                     }
> > +
> > +                     clone->engines[n]->ring =
> > +                             __intel_context_ring_size(e->engines[n]->ring->size);
> > +                     intel_context_unlock_pinned(e->engines[n]);
> > +             }
> 
> Another candidate for a helper located in 
> drivers/gpu/drm/i915/gt/intel_context.c?

This is much less of a candidate for potential reuse as I feel it is very
peculiar to the GEM->engines[], and not a fit for ugpu. At least as
currently written; an intel_context_get_ring_size() to go along with
intel_context_set_ring_size(), maybe.

> > diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> > index 5400d7e057f1..ae7cd681b075 100644
> > --- a/include/uapi/drm/i915_drm.h
> > +++ b/include/uapi/drm/i915_drm.h
> > @@ -1587,6 +1587,25 @@ struct drm_i915_gem_context_param {
> >   * By default, new contexts allow persistence.
> >   */
> >  #define I915_CONTEXT_PARAM_PERSISTENCE       0xb
> > +
> > +/*
> > + * I915_CONTEXT_PARAM_RINGSIZE:
> > + *
> > + * Sets the size of the CS ringbuffer to use for logical ring contexts. This
> > + * applies a limit of how many batches can be queued to HW before the caller
> > + * is blocked due to lack of space for more commands.
> > + *
> > + * Only reliably possible to be set prior to first use, i.e. during
> > + * construction. At any later point, the current execution must be flushed as
> > + * the ring can only be changed while the context is idle.
> > + *
> > + * Only applies to the current set of engine and lost when those engines
> > + * are replaced by a new mapping (see I915_CONTEXT_PARAM_ENGINES).
> > + *
> > + * Must be between 4 - 512 KiB, in intervals of page size [4 KiB].
> > + * Default is 16 KiB.
> > + */
> > +#define I915_CONTEXT_PARAM_RINGSIZE  0xc
> 
> I know it looked like that already before, but having other documented flags 
> separated by blank lines from each other, Is there any reason for not putting 
> another blank line after the last one?
> 
> >  /* Must be kept compact -- no holes and well documented */

You mean before the /* Must be... */? My intent is to make it conflict
and force people to take notice of the instruction.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

WARNING: multiple messages have this Message-ID (diff)
From: Chris Wilson <chris@chris-wilson.co.uk>
To: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH 2/3] drm/i915: Allow userspace to specify ringsize on construction
Date: Mon, 18 Nov 2019 11:28:29 +0000	[thread overview]
Message-ID: <157407650904.24372.7396047058720514369@skylake-alporthouse-com> (raw)
Message-ID: <20191118112829.OrjRSA0aqSvn0z0rOMh2FQQaq4xXM8dKyxrllxOE1nM@z> (raw)
In-Reply-To: <14059150.4o38dXUsEa@jkrzyszt-desk.ger.corp.intel.com>

Quoting Janusz Krzysztofik (2019-11-18 11:14:12)
> Hi Chris,
> 
> Only some minor comments from me, mostly out of my curiosity.
> 
> On Friday, November 15, 2019 5:05:45 PM CET Chris Wilson wrote:
> > No good reason why we must always use a static ringsize, so let
> > userspace select one during construction.
> > 
> > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> > Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> > ---
> > +static int __apply_ringsize(struct intel_context *ce, void *sz)
> > +{
> > +     int err;
> > +
> > +     err = i915_active_wait(&ce->active);
> > +     if (err < 0)
> > +             return err;
> > +
> > +     if (intel_context_lock_pinned(ce))
> > +             return -EINTR;
> > +
> > +     if (intel_context_is_pinned(ce)) {
> > +             err = -EBUSY; /* In active use, come back later! */
> > +             goto unlock;
> > +     }
> > +
> > +     if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
> > +             struct intel_ring *ring;
> > +
> > +             /* Replace the existing ringbuffer */
> > +             ring = intel_engine_create_ring(ce->engine,
> > +                                             (unsigned long)sz);
> > +             if (IS_ERR(ring)) {
> > +                     err = PTR_ERR(ring);
> > +                     goto unlock;
> > +             }
> > +
> > +             intel_ring_put(ce->ring);
> > +             ce->ring = ring;
> > +
> > +             /* Context image will be updated on next pin */
> > +     } else {
> > +             ce->ring = sz;
> > +     }
> > +
> > +unlock:
> > +     intel_context_unlock_pinned(ce);
> > +     return err;
> > +}
> 
> I'm wondering if this function (and __get_ringsize() below as well), with its 
> dependency on intel_context internals, especially on that dual meaning of 
> ce->ring which depends on (ce->flags & CONTEXT_ALLOC_BIT), would better fit 
> into drivers/gpu/drm/i915/gt/intel_context.c.

Possibly, but at the same time it's currently only implementing a
feature of the GEM context.

I hear you, I'm just resisting, mainly because I don't want to have to
think of a good name :)

intel_context_param.c
intel_context_ring.c

I might be able to find friends for either.

> > +static int set_ringsize(struct i915_gem_context *ctx,
> > +                     struct drm_i915_gem_context_param *args)
> > +{
> > +     if (!HAS_LOGICAL_RING_CONTEXTS(ctx->i915))
> > +             return -ENODEV;
> > +
> > +     if (args->size)
> > +             return -EINVAL;
> > +
> > +     if (!IS_ALIGNED(args->value, I915_GTT_PAGE_SIZE))
> > +             return -EINVAL;
> > +
> > +     if (args->value < I915_GTT_PAGE_SIZE)
> > +             return -EINVAL;
> > +
> > +     if (args->value > 128 * I915_GTT_PAGE_SIZE)
> > +             return -EINVAL;
> > +
> > +     return context_apply_all(ctx,
> > +                              __apply_ringsize,
> > +                              __intel_context_ring_size(args->value));
> > +}
> > +
> > +static int __get_ringsize(struct intel_context *ce, void *arg)
> > +{
> > +     int num_pages;
> > +
> > +     if (intel_context_lock_pinned(ce))
> > +             return -EINTR;
> > +
> > +     if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags))
> > +             num_pages = ce->ring->size / I915_GTT_PAGE_SIZE;
> > +     else
> > +             num_pages = (uintptr_t)ce->ring / I915_GTT_PAGE_SIZE;
> > +
> > +     intel_context_unlock_pinned(ce);
> > +     return num_pages; /* stop on first engine */
> 
> Location of this comment seems not perfect to me as it is not quite obvious 
> how that works without examining how this function is used, but having spent a 
> while looking around, I'm not able to suggest a better place.

Yeah, the comment is for the intent of returning the positive, so
there's definitely a case for explaining the unusual pattern here.

The calling loop is just a standard if (err) return err; propagation so
that hardly merits a long winded explanation.

> > +static int get_ringsize(struct i915_gem_context *ctx,
> > +                     struct drm_i915_gem_context_param *args)
> > +{
> > +     int num_pages;
> > +
> > +     if (!HAS_LOGICAL_RING_CONTEXTS(ctx->i915))
> > +             return -ENODEV;
> > +
> > +     if (args->size)
> > +             return -EINVAL;
> > +
> > +     num_pages = context_apply_all(ctx, __get_ringsize, NULL);
> > +     if (num_pages < 0)
> > +             return num_pages;
> > +
> > +     args->value = (u64)num_pages * I915_GTT_PAGE_SIZE;
> 
> Do you convert to num_pages inside __get_ringsize() then back to size in bytes 
> to avoid an overflow?  Or any other reason?  Something that may be useful in 
> the future?

Just being prudent in making sure we have sufficient bits across all the
type-narrowing.

> > @@ -2003,6 +2113,19 @@ static int clone_engines(struct i915_gem_context *dst,
> >                       __free_engines(clone, n);
> >                       goto err_unlock;
> >               }
> > +
> > +             /* Copy across the preferred ringsize */
> > +             clone->engines[n]->ring = e->engines[n]->ring;
> > +             if (test_bit(CONTEXT_ALLOC_BIT, &e->engines[n]->flags)) {
> > +                     if (intel_context_lock_pinned(e->engines[n])) {
> > +                             __free_engines(clone, n + 1);
> > +                             goto err_unlock;
> > +                     }
> > +
> > +                     clone->engines[n]->ring =
> > +                             __intel_context_ring_size(e->engines[n]->ring->size);
> > +                     intel_context_unlock_pinned(e->engines[n]);
> > +             }
> 
> Another candidate for a helper located in 
> drivers/gpu/drm/i915/gt/intel_context.c?

This is much less of a candidate for potential reuse as I feel it is very
peculiar to the GEM->engines[], and not a fit for ugpu. At least as
currently written; an intel_context_get_ring_size() to go along with
intel_context_set_ring_size(), maybe.

> > diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> > index 5400d7e057f1..ae7cd681b075 100644
> > --- a/include/uapi/drm/i915_drm.h
> > +++ b/include/uapi/drm/i915_drm.h
> > @@ -1587,6 +1587,25 @@ struct drm_i915_gem_context_param {
> >   * By default, new contexts allow persistence.
> >   */
> >  #define I915_CONTEXT_PARAM_PERSISTENCE       0xb
> > +
> > +/*
> > + * I915_CONTEXT_PARAM_RINGSIZE:
> > + *
> > + * Sets the size of the CS ringbuffer to use for logical ring contexts. This
> > + * applies a limit of how many batches can be queued to HW before the caller
> > + * is blocked due to lack of space for more commands.
> > + *
> > + * Only reliably possible to be set prior to first use, i.e. during
> > + * construction. At any later point, the current execution must be flushed as
> > + * the ring can only be changed while the context is idle.
> > + *
> > + * Only applies to the current set of engine and lost when those engines
> > + * are replaced by a new mapping (see I915_CONTEXT_PARAM_ENGINES).
> > + *
> > + * Must be between 4 - 512 KiB, in intervals of page size [4 KiB].
> > + * Default is 16 KiB.
> > + */
> > +#define I915_CONTEXT_PARAM_RINGSIZE  0xc
> 
> I know it looked like that already before, but having other documented flags 
> separated by blank lines from each other, Is there any reason for not putting 
> another blank line after the last one?
> 
> >  /* Must be kept compact -- no holes and well documented */

You mean before the /* Must be... */? My intent is to make it conflict
and force people to take notice of the instruction.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2019-11-18 11:28 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-15 16:05 [PATCH 1/3] drm/i915: Flush idle barriers when waiting Chris Wilson
2019-11-15 16:05 ` [Intel-gfx] " Chris Wilson
2019-11-15 16:05 ` [PATCH 2/3] drm/i915: Allow userspace to specify ringsize on construction Chris Wilson
2019-11-15 16:05   ` [Intel-gfx] " Chris Wilson
2019-11-18 11:14   ` Janusz Krzysztofik
2019-11-18 11:14     ` [Intel-gfx] " Janusz Krzysztofik
2019-11-18 11:28     ` Chris Wilson [this message]
2019-11-18 11:28       ` Chris Wilson
2019-11-25 10:05   ` Chris Wilson
2019-11-25 10:05     ` [Intel-gfx] " Chris Wilson
2019-11-15 16:05 ` [PATCH 3/3] drm/i915/gem: Honour O_NONBLOCK before throttling execbuf submissions Chris Wilson
2019-11-15 16:05   ` [Intel-gfx] " Chris Wilson
2019-11-15 20:56 ` ✓ Fi.CI.BAT: success for series starting with [1/3] drm/i915: Flush idle barriers when waiting Patchwork
2019-11-15 20:56   ` [Intel-gfx] " Patchwork
2019-11-17  9:27 ` ✗ Fi.CI.IGT: failure " Patchwork
2019-11-17  9:27   ` [Intel-gfx] " Patchwork
2019-11-25 12:18 ` ✗ Fi.CI.BUILD: failure for series starting with [1/3] drm/i915: Flush idle barriers when waiting (rev2) Patchwork
2019-11-25 12:18   ` [Intel-gfx] " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=157407650904.24372.7396047058720514369@skylake-alporthouse-com \
    --to=chris@chris-wilson.co.uk \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=janusz.krzysztofik@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.