[Intel-gfx] [PATCH] drm/i915/guc: Set init value for cached work queue head
Yu Dai
yu.dai at intel.com
Wed Feb 10 20:31:07 UTC 2016
On 02/10/2016 09:30 AM, Tvrtko Ursulin wrote:
> Hi,
>
> On 10/02/16 00:05, yu.dai at intel.com wrote:
> > From: Alex Dai <yu.dai at intel.com>
> >
> > The cached work queue header pointer is set to last byte of work
> > queue buffer. It will make sure the whole work queue buffer is
> > available after coming back from reset or init.
> >
> > Do not hold kmap_atomic mapping before going to sleep when work
> > queue is full.
>
> Could you please split this into two patches? They are two completely
> separate issues and it is customary to do so.
>
> For the kmap_atomic issue you can also reference
> https://bugs.freedesktop.org/show_bug.cgi?id=93847 in the commit message.
Yes, will do.
> > Signed-off-by: Alex Dai <yu.dai at intel.com>
> > ---
> > drivers/gpu/drm/i915/i915_guc_submission.c | 10 +++++-----
> > 1 file changed, 5 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
> > index d7543ef..41f4a96 100644
> > --- a/drivers/gpu/drm/i915/i915_guc_submission.c
> > +++ b/drivers/gpu/drm/i915/i915_guc_submission.c
> > @@ -486,11 +486,11 @@ int i915_guc_wq_check_space(struct i915_guc_client *gc)
> > if (CIRC_SPACE(gc->wq_tail, gc->wq_head, gc->wq_size) >= size)
> > return 0;
> >
> > - base = kmap_atomic(i915_gem_object_get_page(gc->client_obj, 0));
> > - desc = base + gc->proc_desc_offset;
> > -
> > while (timeout_counter-- > 0) {
> > + base = kmap_atomic(i915_gem_object_get_page(gc->client_obj, 0));
> > + desc = base + gc->proc_desc_offset;
> > gc->wq_head = desc->head;
> > + kunmap_atomic(base);
> >
> > if (CIRC_SPACE(gc->wq_tail, gc->wq_head, gc->wq_size) >= size) {
> > ret = 0;
> > @@ -501,8 +501,6 @@ int i915_guc_wq_check_space(struct i915_guc_client *gc)
> > usleep_range(1000, 2000);
> > };
> >
> > - kunmap_atomic(base);
> > -
> > return ret;
> > }
>
> This part is OK to extinguish this fire. But in general you could also
> consider caching the kmap in the client since it looks to me that object
> is persistently pinned for its lifetime. So kmap_atomic just complicates
> things.
Yes this object must be pinned for its lifetime as it is used by GuC
internally too. I will think about a way to cache it.
> > @@ -730,6 +728,8 @@ static struct i915_guc_client *guc_client_alloc(struct drm_device *dev,
> > client->client_obj = obj;
> > client->wq_offset = GUC_DB_SIZE;
> > client->wq_size = GUC_WQ_SIZE;
> > + client->wq_head = GUC_WQ_SIZE - 1;
> > + client->wq_tail = 0;
> >
> > client->doorbell_offset = select_doorbell_cacheline(guc);
> >
> >
>
> This one I can't really figure out without I suppose knowing more about
> the code design. How come it was OK when it was zero (apart after reset)?
>
> The value is otherwise only updated from the GuC shared page and a
> driver does not appear to modify it. Perhaps just a better commit
> message to explain things?
The way this kernel CIRC_xx works is it leaves one byte free and treat
head == tail case as empty. So, there won't be a problem if this head
happens to be 0. If it comes with some random number between [1,
sizeof(WQ item)], there will be a SW dead looping in driver.
And, I will split this patch into two ones.
Thanks,
Alex
More information about the Intel-gfx
mailing list