[PATCH] drm/etnaviv: correct timeout calculation
Lucas Stach
l.stach at pengutronix.de
Fri Mar 9 11:52:40 UTC 2018
Hi Russell,
Am Freitag, den 09.03.2018, 11:44 +0000 schrieb Russell King - ARM Linux:
> Hi Lucas,
>
> Please retain my authorship of my patch, which was sent on 23 Oct 2017.
> The patch you have below is 100% identical to that which I sent.
I'll gladly do so if you provide me a proper Signed-off-by for this
patch, which was missing from your 23 Oct 2017 submission.
> You should also point out, as per the follow-on discussion, that using
> clock_gettime() on 32-bit systems will not work once the time it
> reports wraps - so something like the comment I suggested in a follow
> up patch:
>
> + * Etnaviv timeouts are specified wrt CLOCK_MONOTONIC, not jiffies.
> + * We need to calculate the timeout in terms of number of jiffies
> + * between the specified timeout and the current CLOCK_MONOTONIC time.
> + * Note: clock_gettime() is 32-bit on 32-bit arch. Using 64-bit
> + * timespec math here just means that when a wrap occurs, the
> + * specified timeout goes into the past and we can't request a
> + * timeout in the future: IOW, the code breaks.
>
> would be sensible either in the commit message or the code.
I'll add it to the commit message, as I think the discussion with Arnd
established that this is a very theoretical risk, not likely to be hit
in practice.
Regards,
Lucas
> On Fri, Mar 09, 2018 at 12:21:49PM +0100, Lucas Stach wrote:
> > The old way did clamp the jiffy conversion and thus caused the timeouts
> > to become negative after some time. Also it didn't work with userspace
> > which actually fills the upper 32bits of the 64bit timestamp value.
> >
> > Fix this by using the solution developed and tested by Russell.
> >
> > > > Suggested-by: Russell King <linux at armlinux.org.uk>
> > > > Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> > ---
> > drivers/gpu/drm/etnaviv/etnaviv_drv.h | 25 +++++++++++++++++--------
> > 1 file changed, 17 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
> > index ddb17ee565e9..17a43da98fb9 100644
> > --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h
> > +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
> > @@ -26,6 +26,7 @@
> > #include <linux/pm_runtime.h>
> > #include <linux/slab.h>
> > #include <linux/list.h>
> > +#include <linux/time64.h>
> > #include <linux/types.h>
> > #include <linux/sizes.h>
> >
> > @@ -132,19 +133,27 @@ static inline bool fence_after_eq(u32 a, u32 b)
> > > > return (s32)(a - b) >= 0;
> > }
> >
> > +/*
> > + * Etnaviv timeouts are specified wrt CLOCK_MONOTONIC, not jiffies.
> > + * We need to calculate the timeout in terms of number of jiffies
> > + * between the specified timeout and the current CLOCK_MONOTONIC time.
> > + */
> > static inline unsigned long etnaviv_timeout_to_jiffies(
> > > > const struct timespec *timeout)
> > {
> > > > - unsigned long timeout_jiffies = timespec_to_jiffies(timeout);
> > > > - unsigned long start_jiffies = jiffies;
> > > > - unsigned long remaining_jiffies;
> > > > + struct timespec64 ts, to;
> > +
> > > > + to = timespec_to_timespec64(*timeout);
> > +
> > > > + ktime_get_ts64(&ts);
> > +
> > > > + /* timeouts before "now" have already expired */
> > > > + if (timespec64_compare(&to, &ts) <= 0)
> > > > + return 0;
> >
> > > > - if (time_after(start_jiffies, timeout_jiffies))
> > > > - remaining_jiffies = 0;
> > > > - else
> > > > - remaining_jiffies = timeout_jiffies - start_jiffies;
> > > > + ts = timespec64_sub(to, ts);
> >
> > > > - return remaining_jiffies;
> > > > + return timespec64_to_jiffies(&ts);
> > }
> >
> > #endif /* __ETNAVIV_DRV_H__ */
> > --
> > 2.16.1
> >
>
>
More information about the etnaviv
mailing list