On Monday 11 May 2015 08:07:51 Tina Ruchandani wrote:
struct timeval uses a 32-bit seconds representation which will overflow in the year 2038 and beyond. This patch replaces the usage of struct timeval with ktime_t which is a 64-bit timestamp and is year 2038 safe. This patch is part of a larger attempt to remove all instances of 32-bit timekeeping variables (timeval, timespec, time_t) which are not year 2038 safe, from the kernel. The patch is a work-in-progress - correctness of the following changes is unclear: (a) Usage of timeval_usec_diff - The function seems to subtract usec values without caring about the difference of the seconds field. There may be an implicit assumption in the original code that the time delta is always of the order of microseconds.
Right, in particular, it does handle the seconds field overflowing once, but it breaks when the difference is larger than one second.
The patch replaces the usage of timeval_usec_diff with ktime_to_us(ktime_sub()) which computes the real timestamp difference, not just the difference in the usec field.
As in the other patches, ktime_us_delta() would look nicer, but it's equally correct.
- Sleep until gettimeofday() > waketime + add_usec
- This needs to be as precise as possible, but as the delay is
- usually between 2ms and 32ms, it is done using a scheduled msleep
- followed by usleep (normally a busy-wait loop) for the remainder
*/ -void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec) +void dvb_frontend_sleep_until(ktime_t waketime, u32 add_usec) {
- struct timeval lasttime;
- ktime_t lasttime; s32 delta, newdelta;
- timeval_usec_add(waketime, add_usec);
- ktime_add_us(waketime, add_usec);
- do_gettimeofday(&lasttime);
- delta = timeval_usec_diff(lasttime, *waketime);
- lasttime = ktime_get_real();
- delta = ktime_to_us(ktime_sub(lasttime, waketime)); if (delta > 2500) { msleep((delta - 1500) / 1000);
do_gettimeofday(&lasttime);
newdelta = timeval_usec_diff(lasttime, *waketime);
lasttime = ktime_get_real();
delta = (newdelta > delta) ? 0 : newdelta; }newdelta = ktime_to_us(ktime_sub(lasttime, waketime));
There is a bug you introduced: The original function added add_usec to the value pointed to by waketime. Changing this from a pointer to a scalar argument means that the value is only updated in the dvb_frontend_sleep_until() function, but not inside of the caller.
In order to preserve the behavior, you have to leave waketime as a pointer.
Arnd