Hi Krzysztof,

[...]

> Can a request that's not already on the GPU be passed into _unsubmit()
> again? Otherwise setting running_since to 0 is not needed, because it's
> gonna get overwritten in _submit() anyway.
Nice catch.

> 
> >     if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &request->fence.flags))
> >             i915_request_cancel_breadcrumb(request);
> >  
> > diff --git a/drivers/gpu/drm/i915/i915_request.h 
> > b/drivers/gpu/drm/i915/i915_request.h
> > index b09135301f39..48b619ca6bf4 100644
> > --- a/drivers/gpu/drm/i915/i915_request.h
> > +++ b/drivers/gpu/drm/i915/i915_request.h
> > @@ -325,6 +325,9 @@ struct i915_request {
> >     struct i915_request_watchdog {
> >             struct llist_node link;
> >             struct hrtimer timer;
> > +           ktime_t running_since;
> > +           ktime_t preempted_at;
> > +           ktime_t total_run_time;
> >     } watchdog;
> >  
> 
> The preempted_at variable is currently not needed, as it's only ever
> written to and never read from in this patch.
> 
> The running_since = 0 trick in _unsubmit() used to filter out the
> requests that have been passed to it but haven't actually advanced seems
> a bit hacky at first glance, assuming it's needed. It does make sense
> if you know that running_since > 0 if the request is active and = 0
> otherwise after reading the code a bit, but it's not readily apparent
> to me.
> 
> Something like the following would be clearer to me, however please do
> judge yourself and check with others whether it is actually more readable.
> 
> You could keep track of the most recent time of being given GPU time
> (running_since) and the most recent preemption (preempted_at). If
> running_since > preempted_at, that means the request has actually
> advanced, since it has been _submit()ed after the most recent _unsubmit().
> Conversely, if preempted_at > running_since, then _unsubmit() has been
> called after the most recent _submit(), so the request couldn't have been
> active.
> 
> So something along these lines:
> 
> in _submit() (I'm omitting the struct stuff for brevity)
> 
>       running_since = ktime_get();
> 
> in _unsubmit()
> 
>       /* "if the most recent submit was after the most recent preemption" */
>       if (running_since > preempted_at) { /* possibly >= instead? */
>               preempted_at = ktime_get();
> 
>               total_run_time = ktime_add(total_run_time,
>                                          ktime_sub(preempted_at, 
> running_since));
>                                          /* the block of time between
>                                           * activation and preemption
>                                           */
>       }
> 
> This along with renaming the variables to something like (running_at,
> preempted_at) / (running_since, preempted_since) for symmetry.
Huh, I quite like this approach. More stuff appears implicit,
but after giving it more thought, I think it looks cleaner and
equally readable.

I'll experiment with this and see if the results acquired
empirically are the same.

However, this is a major change to the logic of handling
preemption, so I'll wait for some more voices from the
community before making this a fully fledged patch.

Thanks for looking at this!

-- 
Best Regards,
Krzysztof

Reply via email to