Re: [Y2038] [PATCH v3] Staging: media: Replace timeval with ktime_t

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, May 13, 2015 at 2:10 PM, Mauro Carvalho Chehab
<mchehab@xxxxxxxxxxxxxxx> wrote:
> Em Wed, 13 May 2015 21:53:07 +0200
> Arnd Bergmann <arnd@xxxxxxxx> escreveu:
>
>> On Wednesday 13 May 2015 10:04:48 John Stultz wrote:
>> > On Wed, May 13, 2015 at 9:57 AM, Ksenija Stanojevic
>> > <ksenija.stanojevic@xxxxxxxxx> wrote:
>> > > 'struct timeval last_tv' is used to get the time of last signal change
>> > > and 'struct timeval last_intr_tv' is used to get the time of last UART
>> > > interrupt.
>> > > 32-bit systems using 'struct timeval' will break in the year 2038, so we
>> > > have to replace that code with more appropriate types.
>> > > Here struct timeval is replaced with ktime_t.
>> > >
>> > > Signed-off-by: Ksenija Stanojevic <ksenija.stanojevic@xxxxxxxxx>
>>
>> An additional comment: as drivers/staging/media refers to a whole subsystem
>> with mutually independent drivers, the subject line should mention 'lirc',
>> either in addition to, or instead of 'media'.
>>
>> > > -static long delta(struct timeval *tv1, struct timeval *tv2)
>> > > +static inline long delta(ktime_t t1, ktime_t t2)
>> > >  {
>> > > -       unsigned long deltv;
>> > > -
>> > > -       deltv = tv2->tv_sec - tv1->tv_sec;
>> > > -       if (deltv > 15)
>> > > -               deltv = 0xFFFFFF;
>> > > -       else
>> > > -               deltv = deltv*1000000 +
>> > > -                       tv2->tv_usec -
>> > > -                       tv1->tv_usec;
>> > > -       return deltv;
>> > > +       /* return the delta in 32bit usecs, but cap to UINTMAX in case the
>> > > +        * delta is greater then 32bits */
>> > > +       return (long) min((unsigned int) ktime_us_delta(t1, t2), UINT_MAX);
>> > >  }
>> >
>> > This probably needs some close review from the media folks. Thinking
>> > about it more, I'm really not certain the 15sec cap was to avoid a
>> > 32bit overflow or if there's some other subtle undocumented reason.
>>
>> The new code is clearly wrong, as the cast to 'unsigned int' already truncates
>> the value to at most UINT_MAX, and the min() does not have any effect.
>>
>> The correct way to write what was intended here is
>>
>>       return min_t(long long, ktime_us_delta(t1, t2), UINT_MAX);
>>
>> which will truncate delta to an unsigned integer. The return type of the
>> delta() function would need to be changed to 'unsigned long' as well to
>> make this work.
>>
>> However, I think you are right that we should probably not change the
>> behavior, unless someone who understands the purpose better can say
>> what it really should be.
>
> Inside the remote controller code, we have measurements for pulse/space
> encodings on a IR transmission. The duration of a pulse or space is
> generally in the other of microseconds. On the standard protocols, the
> maximum duration is on NEC protocol, where a pulse of 9 ms is sent at
> the beginning:
>         http://www.sbprojects.com/knowledge/ir/nec.php
>
> It should be noticed that bigger time intervals can be used to indicate
> key repeat. Again, in the NEC protocol, the space between key repeats
> are 110 ms.
>
> So, everything above 110 ms is actually an infinite time.
>
> As the Kernel implementation was built to be generic enough, we consider
> (u32)-1 (e. g. about 4 seconds) as the maximum possible time.

So that's ~4 seconds of nanoseconds, but since we're talking usecs,
UINT_MAX is something like 70-some minutes.


> This is due to the fact that some IR protocols use u32 for the pulse/space
> time shifts. So, any duration bigger than that could actually be
> rounded to (u32)-1.

Sure. The part that confused me is that the delta function is checking
if the second delta is larger then 15 seconds, and I couldn't quite
understand the significance of that check. If it really is just to
make sure the timeval -> usec conversion doesn't overflow, then that's
easy enough to solve. But if the 15 second check has some other
meaning, we'd want to understand before changing this.

> That's said, I really don't see the need of "fixing" it on the y2038
> patchset. All that it is needed is to warrant that the time difference
> will be positive.
>
> I would, instead, remove the delta function, and replace:
>
>         do_gettimeofday(&curr_tv);
>         deltv = delta(&last_tv, &curr_tv);
>
> (and other equivalent parts)
>
> By an equivalent logic that would be reading the timestamp from a
> high precision clock.
>
> That's said, I suspect that this driver is broken, as I doubt that
> do_gettimeofday() gets enough precision needed for IR decoding. Also,
> as this returns a non-monotonic timestamp, it will break if one adjusts
> the clock while IR keys are being pressed.

Yep. Moving to ktime_get should help since it uses the monotonic clock.

thanks
-john
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux