[Intel-gfx] [PATCH v2 2/3] drm/i915: Wrap a timer into a i915_sw_fence

Chris Wilson chris at chris-wilson.co.uk
Wed Oct 11 12:34:03 UTC 2017


Quoting Tvrtko Ursulin (2017-10-11 13:20:25)
> 
> On 10/10/2017 22:38, Chris Wilson wrote:
> > For some selftests, we want to issue requests but delay them going to
> > hardware. Furthermore, we don't want those requests to block
> > indefinitely (or else we may hang the driver and block testing) so we
> > want to employ a timeout. So naturally we want a fence that is
> > automatically signaled by a timer.
> > 
> > v2: Add kselftests.
> > 
> > Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> > ---
> >   drivers/gpu/drm/i915/i915_sw_fence.c           | 64 ++++++++++++++++++++++++++
> >   drivers/gpu/drm/i915/i915_sw_fence.h           |  3 ++
> >   drivers/gpu/drm/i915/selftests/i915_sw_fence.c | 43 +++++++++++++++++
> >   3 files changed, 110 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c
> > index 808ea4d5b962..388424a95ac9 100644
> > --- a/drivers/gpu/drm/i915/i915_sw_fence.c
> > +++ b/drivers/gpu/drm/i915/i915_sw_fence.c
> > @@ -506,6 +506,70 @@ int i915_sw_fence_await_reservation(struct i915_sw_fence *fence,
> >       return ret;
> >   }
> >   
> > +struct timer_fence {
> 
> timed fence?
> 
> > +     struct i915_sw_fence base;
> > +     struct timer_list timer;
> > +     struct kref ref;
> > +};
> > +
> > +static void timer_fence_wake(unsigned long data)
> > +{
> > +     struct timer_fence *tf = (struct timer_fence *)data;
> > +
> > +     i915_sw_fence_complete(&tf->base);
> > +}
> > +
> > +static void i915_sw_fence_timer_free(struct kref *ref)
> > +{
> > +     struct timer_fence *tf = container_of(ref, typeof(*tf), ref);
> > +
> > +     kfree(tf);
> > +}
> > +
> > +static void i915_sw_fence_timer_put(struct i915_sw_fence *fence)
> > +{
> > +     struct timer_fence *tf = container_of(fence, typeof(*tf), base);
> > +
> > +     kref_put(&tf->ref, i915_sw_fence_timer_free);
> > +}
> > +
> > +static int __i915_sw_fence_call
> > +timer_fence_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
> > +{
> > +     if (state == FENCE_FREE)
> > +             i915_sw_fence_timer_put(fence);
> > +
> > +     return NOTIFY_DONE;
> > +}
> > +
> > +struct i915_sw_fence *i915_sw_fence_create_timer(long timeout, gfp_t gfp)
> 
> Depending on the outcome of the public vs test private question (see 
> below), you might want to rename timeout to expired to signify it is in 
> absolute jiffies. And also add kernel doc if it will be public.

timed_fence + expires are good suggestions.

> > +{
> > +     struct timer_fence *tf;
> > +
> > +     tf = kmalloc(sizeof(*tf), gfp);
> > +     if (!tf)
> > +             return ERR_PTR(-ENOMEM);
> > +
> > +     i915_sw_fence_init(&tf->base, timer_fence_notify);
> > +     kref_init(&tf->ref);
> > +
> > +     setup_timer(&tf->timer, timer_fence_wake, (unsigned long)tf);
> > +     mod_timer(&tf->timer, timeout);
> > +
> > +     kref_get(&tf->ref);
> > +     return &tf->base;
> > +}
> > +
> > +void i915_sw_fence_timer_flush(struct i915_sw_fence *fence)
> > +{
> > +     struct timer_fence *tf = container_of(fence, typeof(*tf), base);
> > +
> > +     if (del_timer_sync(&tf->timer))
> > +             i915_sw_fence_complete(&tf->base);
> > +
> > +     i915_sw_fence_timer_put(fence);
> 
> A bit unusual that flush destroys an object? Should i915_sw_fence_fini 
> just be made work on these to come close to OO design it partially tries 
> to do?

I repeated the pattern "flush; put" everytime so I decided to hide the ref
and just have the second API point consume the fence.

Flush is the right semantic for the first action on the fence, but not a
great name for the combined operation.

I did consider doing i915_sw_fence_init_timer() and timed_fence_fini()
but wasn't as keen on exporting the struct. Though really if we follow
the selftests/ direction, that isn't an issue.
 
> I reckon there are some private functions it uses so it has to live in 
> i915_sw_fence.c or it could be moved under selftests completely?

We can push it into selftests so that it's only built then.
 
> Quick glance - only i915_sw_fence_complete it seems? Could you use 
> i915_sw_fence_commit instead? No idea what the interaction with debug 
> objects there would mean.

Originally kfence exposed both the await / complete semantics. And also
provided a kfence wrapper for a timer. Since then that timer was
absorbed into the external fence wrapper, and I'm not keen on exporting
await / complete functions and choose to export the timer instead.
(Mostly because we already have the timer interaction inside
i915_sw_fence.c so it felt a reasonable extension of that.)
-Chris


More information about the Intel-gfx mailing list