Merge branch 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
time: catch xtime_nsec underflows and fix them
posix-cpu-timers: fix clock_gettime with CLOCK_PROCESS_CPUTIME_ID

+23 -1
+1 -1
kernel/posix-cpu-timers.c
··· 311 311 struct task_cputime cputime; 312 312 313 313 thread_group_cputime(p, &cputime); 314 - switch (which_clock) { 314 + switch (CPUCLOCK_WHICH(which_clock)) { 315 315 default: 316 316 return -EINVAL; 317 317 case CPUCLOCK_PROF:
+22
kernel/time/timekeeping.c
··· 518 518 /* correct the clock when NTP error is too big */ 519 519 clocksource_adjust(offset); 520 520 521 + /* 522 + * Since in the loop above, we accumulate any amount of time 523 + * in xtime_nsec over a second into xtime.tv_sec, its possible for 524 + * xtime_nsec to be fairly small after the loop. Further, if we're 525 + * slightly speeding the clocksource up in clocksource_adjust(), 526 + * its possible the required corrective factor to xtime_nsec could 527 + * cause it to underflow. 528 + * 529 + * Now, we cannot simply roll the accumulated second back, since 530 + * the NTP subsystem has been notified via second_overflow. So 531 + * instead we push xtime_nsec forward by the amount we underflowed, 532 + * and add that amount into the error. 533 + * 534 + * We'll correct this error next time through this function, when 535 + * xtime_nsec is not as small. 536 + */ 537 + if (unlikely((s64)clock->xtime_nsec < 0)) { 538 + s64 neg = -(s64)clock->xtime_nsec; 539 + clock->xtime_nsec = 0; 540 + clock->error += neg << (NTP_SCALE_SHIFT - clock->shift); 541 + } 542 + 521 543 /* store full nanoseconds into xtime after rounding it up and 522 544 * add the remainder to the error difference. 523 545 */