Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-hrt

* git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-hrt:
hrtimer: catch expired CLOCK_REALTIME timers early
hrtimer: check relative timeouts for overflow

+40 -22
+2
include/linux/ktime.h
··· 310 310 return ktime_sub_ns(kt, usec * 1000); 311 311 } 312 312 313 + extern ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs); 314 + 313 315 /* 314 316 * The resolution of the clocks. The resolution value is returned in 315 317 * the clock_getres() system call to give application programmers an
+1 -1
kernel/futex.c
··· 2116 2116 2117 2117 t = timespec_to_ktime(ts); 2118 2118 if (cmd == FUTEX_WAIT) 2119 - t = ktime_add(ktime_get(), t); 2119 + t = ktime_add_safe(ktime_get(), t); 2120 2120 tp = &t; 2121 2121 } 2122 2122 /*
+1 -1
kernel/futex_compat.c
··· 176 176 177 177 t = timespec_to_ktime(ts); 178 178 if (cmd == FUTEX_WAIT) 179 - t = ktime_add(ktime_get(), t); 179 + t = ktime_add_safe(ktime_get(), t); 180 180 tp = &t; 181 181 } 182 182 if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE)
+31 -17
kernel/hrtimer.c
··· 326 326 #endif /* BITS_PER_LONG >= 64 */ 327 327 328 328 /* 329 + * Add two ktime values and do a safety check for overflow: 330 + */ 331 + ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs) 332 + { 333 + ktime_t res = ktime_add(lhs, rhs); 334 + 335 + /* 336 + * We use KTIME_SEC_MAX here, the maximum timeout which we can 337 + * return to user space in a timespec: 338 + */ 339 + if (res.tv64 < 0 || res.tv64 < lhs.tv64 || res.tv64 < rhs.tv64) 340 + res = ktime_set(KTIME_SEC_MAX, 0); 341 + 342 + return res; 343 + } 344 + 345 + /* 329 346 * Check, whether the timer is on the callback pending list 330 347 */ 331 348 static inline int hrtimer_cb_pending(const struct hrtimer *timer) ··· 442 425 ktime_t expires = ktime_sub(timer->expires, base->offset); 443 426 int res; 444 427 428 + WARN_ON_ONCE(timer->expires.tv64 < 0); 429 + 445 430 /* 446 431 * When the callback is running, we do not reprogram the clock event 447 432 * device. The timer callback is either running on a different CPU or ··· 453 434 */ 454 435 if (hrtimer_callback_running(timer)) 455 436 return 0; 437 + 438 + /* 439 + * CLOCK_REALTIME timer might be requested with an absolute 440 + * expiry time which is less than base->offset. Nothing wrong 441 + * about that, just avoid to call into the tick code, which 442 + * has now objections against negative expiry values. 443 + */ 444 + if (expires.tv64 < 0) 445 + return -ETIME; 456 446 457 447 if (expires.tv64 >= expires_next->tv64) 458 448 return 0; ··· 710 682 */ 711 683 orun++; 712 684 } 713 - timer->expires = ktime_add(timer->expires, interval); 714 - /* 715 - * Make sure, that the result did not wrap with a very large 716 - * interval. 717 - */ 718 - if (timer->expires.tv64 < 0) 719 - timer->expires = ktime_set(KTIME_SEC_MAX, 0); 685 + timer->expires = ktime_add_safe(timer->expires, interval); 720 686 721 687 return orun; 722 688 } ··· 861 839 new_base = switch_hrtimer_base(timer, base); 862 840 863 841 if (mode == HRTIMER_MODE_REL) { 864 - tim = ktime_add(tim, new_base->get_time()); 842 + tim = ktime_add_safe(tim, new_base->get_time()); 865 843 /* 866 844 * CONFIG_TIME_LOW_RES is a temporary way for architectures 867 845 * to signal that they simply return xtime in ··· 870 848 * timeouts. This will go away with the GTOD framework. 871 849 */ 872 850 #ifdef CONFIG_TIME_LOW_RES 873 - tim = ktime_add(tim, base->resolution); 851 + tim = ktime_add_safe(tim, base->resolution); 874 852 #endif 875 - /* 876 - * Careful here: User space might have asked for a 877 - * very long sleep, so the add above might result in a 878 - * negative number, which enqueues the timer in front 879 - * of the queue. 880 - */ 881 - if (tim.tv64 < 0) 882 - tim.tv64 = KTIME_MAX; 883 853 } 884 854 timer->expires = tim; 885 855
+5 -3
kernel/posix-timers.c
··· 767 767 /* SIGEV_NONE timers are not queued ! See common_timer_get */ 768 768 if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) { 769 769 /* Setup correct expiry time for relative timers */ 770 - if (mode == HRTIMER_MODE_REL) 771 - timer->expires = ktime_add(timer->expires, 772 - timer->base->get_time()); 770 + if (mode == HRTIMER_MODE_REL) { 771 + timer->expires = 772 + ktime_add_safe(timer->expires, 773 + timer->base->get_time()); 774 + } 773 775 return 0; 774 776 } 775 777