diff options
| author | David Howells <dhowells@redhat.com> | 2017-11-13 10:36:33 -0500 |
|---|---|---|
| committer | David Howells <dhowells@redhat.com> | 2017-11-13 10:36:33 -0500 |
| commit | 81445e63e67a1e98b1c2575fa2b406d4289d2754 (patch) | |
| tree | 2d121d1873b3e8ec7b71086c4db2f5cb207a46ec /kernel | |
| parent | ede372dcae15d3ba1d3d52ac45be7a27ce31be28 (diff) | |
| parent | b24591e2fcf852ad7ad2ccf745c8220bf378d312 (diff) | |
Merge remote-tracking branch 'tip/timers/core' into afs-next
These AFS patches need the timer_reduce() patch from timers/core.
Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/irq/spurious.c | 2 | ||||
| -rw-r--r-- | kernel/kthread.c | 10 | ||||
| -rw-r--r-- | kernel/rcu/rcutorture.c | 4 | ||||
| -rw-r--r-- | kernel/rcu/tree_plugin.h | 9 | ||||
| -rw-r--r-- | kernel/time/Kconfig | 2 | ||||
| -rw-r--r-- | kernel/time/clockevents.c | 21 | ||||
| -rw-r--r-- | kernel/time/ntp.c | 227 | ||||
| -rw-r--r-- | kernel/time/ntp_internal.h | 1 | ||||
| -rw-r--r-- | kernel/time/posix-stubs.c | 20 | ||||
| -rw-r--r-- | kernel/time/tick-oneshot.c | 1 | ||||
| -rw-r--r-- | kernel/time/time.c | 71 | ||||
| -rw-r--r-- | kernel/time/timekeeping.c | 182 | ||||
| -rw-r--r-- | kernel/time/timekeeping.h | 2 | ||||
| -rw-r--r-- | kernel/time/timer.c | 82 | ||||
| -rw-r--r-- | kernel/workqueue.c | 29 |
15 files changed, 396 insertions, 267 deletions
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c index 987d7bca4864..1215229d1c12 100644 --- a/kernel/irq/spurious.c +++ b/kernel/irq/spurious.c | |||
| @@ -21,7 +21,7 @@ static int irqfixup __read_mostly; | |||
| 21 | 21 | ||
| 22 | #define POLL_SPURIOUS_IRQ_INTERVAL (HZ/10) | 22 | #define POLL_SPURIOUS_IRQ_INTERVAL (HZ/10) |
| 23 | static void poll_spurious_irqs(unsigned long dummy); | 23 | static void poll_spurious_irqs(unsigned long dummy); |
| 24 | static DEFINE_TIMER(poll_spurious_irq_timer, poll_spurious_irqs, 0, 0); | 24 | static DEFINE_TIMER(poll_spurious_irq_timer, poll_spurious_irqs); |
| 25 | static int irq_poll_cpu; | 25 | static int irq_poll_cpu; |
| 26 | static atomic_t irq_poll_active; | 26 | static atomic_t irq_poll_active; |
| 27 | 27 | ||
diff --git a/kernel/kthread.c b/kernel/kthread.c index 1c19edf82427..ba3992c8c375 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c | |||
| @@ -798,15 +798,14 @@ EXPORT_SYMBOL_GPL(kthread_queue_work); | |||
| 798 | /** | 798 | /** |
| 799 | * kthread_delayed_work_timer_fn - callback that queues the associated kthread | 799 | * kthread_delayed_work_timer_fn - callback that queues the associated kthread |
| 800 | * delayed work when the timer expires. | 800 | * delayed work when the timer expires. |
| 801 | * @__data: pointer to the data associated with the timer | 801 | * @t: pointer to the expired timer |
| 802 | * | 802 | * |
| 803 | * The format of the function is defined by struct timer_list. | 803 | * The format of the function is defined by struct timer_list. |
| 804 | * It should have been called from irqsafe timer with irq already off. | 804 | * It should have been called from irqsafe timer with irq already off. |
| 805 | */ | 805 | */ |
| 806 | void kthread_delayed_work_timer_fn(unsigned long __data) | 806 | void kthread_delayed_work_timer_fn(struct timer_list *t) |
| 807 | { | 807 | { |
| 808 | struct kthread_delayed_work *dwork = | 808 | struct kthread_delayed_work *dwork = from_timer(dwork, t, timer); |
| 809 | (struct kthread_delayed_work *)__data; | ||
| 810 | struct kthread_work *work = &dwork->work; | 809 | struct kthread_work *work = &dwork->work; |
| 811 | struct kthread_worker *worker = work->worker; | 810 | struct kthread_worker *worker = work->worker; |
| 812 | 811 | ||
| @@ -837,8 +836,7 @@ void __kthread_queue_delayed_work(struct kthread_worker *worker, | |||
| 837 | struct timer_list *timer = &dwork->timer; | 836 | struct timer_list *timer = &dwork->timer; |
| 838 | struct kthread_work *work = &dwork->work; | 837 | struct kthread_work *work = &dwork->work; |
| 839 | 838 | ||
| 840 | WARN_ON_ONCE(timer->function != kthread_delayed_work_timer_fn || | 839 | WARN_ON_ONCE(timer->function != (TIMER_FUNC_TYPE)kthread_delayed_work_timer_fn); |
| 841 | timer->data != (unsigned long)dwork); | ||
| 842 | 840 | ||
| 843 | /* | 841 | /* |
| 844 | * If @delay is 0, queue @dwork->work immediately. This is for | 842 | * If @delay is 0, queue @dwork->work immediately. This is for |
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 45f2ffbc1e78..96a3cdaeed91 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c | |||
| @@ -1076,7 +1076,7 @@ static void rcu_torture_timer_cb(struct rcu_head *rhp) | |||
| 1076 | * counter in the element should never be greater than 1, otherwise, the | 1076 | * counter in the element should never be greater than 1, otherwise, the |
| 1077 | * RCU implementation is broken. | 1077 | * RCU implementation is broken. |
| 1078 | */ | 1078 | */ |
| 1079 | static void rcu_torture_timer(unsigned long unused) | 1079 | static void rcu_torture_timer(struct timer_list *unused) |
| 1080 | { | 1080 | { |
| 1081 | int idx; | 1081 | int idx; |
| 1082 | unsigned long started; | 1082 | unsigned long started; |
| @@ -1163,7 +1163,7 @@ rcu_torture_reader(void *arg) | |||
| 1163 | VERBOSE_TOROUT_STRING("rcu_torture_reader task started"); | 1163 | VERBOSE_TOROUT_STRING("rcu_torture_reader task started"); |
| 1164 | set_user_nice(current, MAX_NICE); | 1164 | set_user_nice(current, MAX_NICE); |
| 1165 | if (irqreader && cur_ops->irq_capable) | 1165 | if (irqreader && cur_ops->irq_capable) |
| 1166 | setup_timer_on_stack(&t, rcu_torture_timer, 0); | 1166 | timer_setup_on_stack(&t, rcu_torture_timer, 0); |
| 1167 | 1167 | ||
| 1168 | do { | 1168 | do { |
| 1169 | if (irqreader && cur_ops->irq_capable) { | 1169 | if (irqreader && cur_ops->irq_capable) { |
diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h index e012b9be777e..e85946d9843b 100644 --- a/kernel/rcu/tree_plugin.h +++ b/kernel/rcu/tree_plugin.h | |||
| @@ -2261,9 +2261,11 @@ static void do_nocb_deferred_wakeup_common(struct rcu_data *rdp) | |||
| 2261 | } | 2261 | } |
| 2262 | 2262 | ||
| 2263 | /* Do a deferred wakeup of rcu_nocb_kthread() from a timer handler. */ | 2263 | /* Do a deferred wakeup of rcu_nocb_kthread() from a timer handler. */ |
| 2264 | static void do_nocb_deferred_wakeup_timer(unsigned long x) | 2264 | static void do_nocb_deferred_wakeup_timer(struct timer_list *t) |
| 2265 | { | 2265 | { |
| 2266 | do_nocb_deferred_wakeup_common((struct rcu_data *)x); | 2266 | struct rcu_data *rdp = from_timer(rdp, t, nocb_timer); |
| 2267 | |||
| 2268 | do_nocb_deferred_wakeup_common(rdp); | ||
| 2267 | } | 2269 | } |
| 2268 | 2270 | ||
| 2269 | /* | 2271 | /* |
| @@ -2327,8 +2329,7 @@ static void __init rcu_boot_init_nocb_percpu_data(struct rcu_data *rdp) | |||
| 2327 | init_swait_queue_head(&rdp->nocb_wq); | 2329 | init_swait_queue_head(&rdp->nocb_wq); |
| 2328 | rdp->nocb_follower_tail = &rdp->nocb_follower_head; | 2330 | rdp->nocb_follower_tail = &rdp->nocb_follower_head; |
| 2329 | raw_spin_lock_init(&rdp->nocb_lock); | 2331 | raw_spin_lock_init(&rdp->nocb_lock); |
| 2330 | setup_timer(&rdp->nocb_timer, do_nocb_deferred_wakeup_timer, | 2332 | timer_setup(&rdp->nocb_timer, do_nocb_deferred_wakeup_timer, 0); |
| 2331 | (unsigned long)rdp); | ||
| 2332 | } | 2333 | } |
| 2333 | 2334 | ||
| 2334 | /* | 2335 | /* |
diff --git a/kernel/time/Kconfig b/kernel/time/Kconfig index ac09bc29eb08..d689a9557e17 100644 --- a/kernel/time/Kconfig +++ b/kernel/time/Kconfig | |||
| @@ -56,7 +56,7 @@ menu "Timers subsystem" | |||
| 56 | 56 | ||
| 57 | # Core internal switch. Selected by NO_HZ_COMMON / HIGH_RES_TIMERS. This is | 57 | # Core internal switch. Selected by NO_HZ_COMMON / HIGH_RES_TIMERS. This is |
| 58 | # only related to the tick functionality. Oneshot clockevent devices | 58 | # only related to the tick functionality. Oneshot clockevent devices |
| 59 | # are supported independ of this. | 59 | # are supported independent of this. |
| 60 | config TICK_ONESHOT | 60 | config TICK_ONESHOT |
| 61 | bool | 61 | bool |
| 62 | 62 | ||
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 4237e0744e26..16c027e9cc73 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c | |||
| @@ -280,17 +280,22 @@ static int clockevents_program_min_delta(struct clock_event_device *dev) | |||
| 280 | static int clockevents_program_min_delta(struct clock_event_device *dev) | 280 | static int clockevents_program_min_delta(struct clock_event_device *dev) |
| 281 | { | 281 | { |
| 282 | unsigned long long clc; | 282 | unsigned long long clc; |
| 283 | int64_t delta; | 283 | int64_t delta = 0; |
| 284 | int i; | ||
| 284 | 285 | ||
| 285 | delta = dev->min_delta_ns; | 286 | for (i = 0; i < 10; i++) { |
| 286 | dev->next_event = ktime_add_ns(ktime_get(), delta); | 287 | delta += dev->min_delta_ns; |
| 288 | dev->next_event = ktime_add_ns(ktime_get(), delta); | ||
| 287 | 289 | ||
| 288 | if (clockevent_state_shutdown(dev)) | 290 | if (clockevent_state_shutdown(dev)) |
| 289 | return 0; | 291 | return 0; |
| 290 | 292 | ||
| 291 | dev->retries++; | 293 | dev->retries++; |
| 292 | clc = ((unsigned long long) delta * dev->mult) >> dev->shift; | 294 | clc = ((unsigned long long) delta * dev->mult) >> dev->shift; |
| 293 | return dev->set_next_event((unsigned long) clc, dev); | 295 | if (dev->set_next_event((unsigned long) clc, dev) == 0) |
| 296 | return 0; | ||
| 297 | } | ||
| 298 | return -ETIME; | ||
| 294 | } | 299 | } |
| 295 | 300 | ||
| 296 | #endif /* CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST */ | 301 | #endif /* CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST */ |
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 99e03bec68e4..8d70da1b9a0d 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c | |||
| @@ -493,6 +493,67 @@ out: | |||
| 493 | return leap; | 493 | return leap; |
| 494 | } | 494 | } |
| 495 | 495 | ||
| 496 | static void sync_hw_clock(struct work_struct *work); | ||
| 497 | static DECLARE_DELAYED_WORK(sync_work, sync_hw_clock); | ||
| 498 | |||
| 499 | static void sched_sync_hw_clock(struct timespec64 now, | ||
| 500 | unsigned long target_nsec, bool fail) | ||
| 501 | |||
| 502 | { | ||
| 503 | struct timespec64 next; | ||
| 504 | |||
| 505 | getnstimeofday64(&next); | ||
| 506 | if (!fail) | ||
| 507 | next.tv_sec = 659; | ||
| 508 | else { | ||
| 509 | /* | ||
| 510 | * Try again as soon as possible. Delaying long periods | ||
| 511 | * decreases the accuracy of the work queue timer. Due to this | ||
| 512 | * the algorithm is very likely to require a short-sleep retry | ||
| 513 | * after the above long sleep to synchronize ts_nsec. | ||
| 514 | */ | ||
| 515 | next.tv_sec = 0; | ||
| 516 | } | ||
| 517 | |||
| 518 | /* Compute the needed delay that will get to tv_nsec == target_nsec */ | ||
| 519 | next.tv_nsec = target_nsec - next.tv_nsec; | ||
| 520 | if (next.tv_nsec <= 0) | ||
| 521 | next.tv_nsec += NSEC_PER_SEC; | ||
| 522 | if (next.tv_nsec >= NSEC_PER_SEC) { | ||
| 523 | next.tv_sec++; | ||
| 524 | next.tv_nsec -= NSEC_PER_SEC; | ||
| 525 | } | ||
| 526 | |||
| 527 | queue_delayed_work(system_power_efficient_wq, &sync_work, | ||
| 528 | timespec64_to_jiffies(&next)); | ||
| 529 | } | ||
| 530 | |||
| 531 | static void sync_rtc_clock(void) | ||
| 532 | { | ||
| 533 | unsigned long target_nsec; | ||
| 534 | struct timespec64 adjust, now; | ||
| 535 | int rc; | ||
| 536 | |||
| 537 | if (!IS_ENABLED(CONFIG_RTC_SYSTOHC)) | ||
| 538 | return; | ||
| 539 | |||
| 540 | getnstimeofday64(&now); | ||
| 541 | |||
| 542 | adjust = now; | ||
| 543 | if (persistent_clock_is_local) | ||
| 544 | adjust.tv_sec -= (sys_tz.tz_minuteswest * 60); | ||
| 545 | |||
| 546 | /* | ||
| 547 | * The current RTC in use will provide the target_nsec it wants to be | ||
| 548 | * called at, and does rtc_tv_nsec_ok internally. | ||
| 549 | */ | ||
| 550 | rc = rtc_set_ntp_time(adjust, &target_nsec); | ||
| 551 | if (rc == -ENODEV) | ||
| 552 | return; | ||
| 553 | |||
| 554 | sched_sync_hw_clock(now, target_nsec, rc); | ||
| 555 | } | ||
| 556 | |||
| 496 | #ifdef CONFIG_GENERIC_CMOS_UPDATE | 557 | #ifdef CONFIG_GENERIC_CMOS_UPDATE |
| 497 | int __weak update_persistent_clock(struct timespec now) | 558 | int __weak update_persistent_clock(struct timespec now) |
| 498 | { | 559 | { |
| @@ -508,76 +569,75 @@ int __weak update_persistent_clock64(struct timespec64 now64) | |||
| 508 | } | 569 | } |
| 509 | #endif | 570 | #endif |
| 510 | 571 | ||
| 511 | #if defined(CONFIG_GENERIC_CMOS_UPDATE) || defined(CONFIG_RTC_SYSTOHC) | 572 | static bool sync_cmos_clock(void) |
| 512 | static void sync_cmos_clock(struct work_struct *work); | ||
| 513 | |||
| 514 | static DECLARE_DELAYED_WORK(sync_cmos_work, sync_cmos_clock); | ||
| 515 | |||
| 516 | static void sync_cmos_clock(struct work_struct *work) | ||
| 517 | { | 573 | { |
| 574 | static bool no_cmos; | ||
| 518 | struct timespec64 now; | 575 | struct timespec64 now; |
| 519 | struct timespec64 next; | 576 | struct timespec64 adjust; |
| 520 | int fail = 1; | 577 | int rc = -EPROTO; |
| 578 | long target_nsec = NSEC_PER_SEC / 2; | ||
| 579 | |||
| 580 | if (!IS_ENABLED(CONFIG_GENERIC_CMOS_UPDATE)) | ||
| 581 | return false; | ||
| 582 | |||
| 583 | if (no_cmos) | ||
| 584 | return false; | ||
| 521 | 585 | ||
| 522 | /* | 586 | /* |
| 523 | * If we have an externally synchronized Linux clock, then update | 587 | * Historically update_persistent_clock64() has followed x86 |
| 524 | * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be | 588 | * semantics, which match the MC146818A/etc RTC. This RTC will store |
| 525 | * called as close as possible to 500 ms before the new second starts. | 589 | * 'adjust' and then in .5s it will advance once second. |
| 526 | * This code is run on a timer. If the clock is set, that timer | 590 | * |
| 527 | * may not expire at the correct time. Thus, we adjust... | 591 | * Architectures are strongly encouraged to use rtclib and not |
| 528 | * We want the clock to be within a couple of ticks from the target. | 592 | * implement this legacy API. |
| 529 | */ | 593 | */ |
| 530 | if (!ntp_synced()) { | ||
| 531 | /* | ||
| 532 | * Not synced, exit, do not restart a timer (if one is | ||
| 533 | * running, let it run out). | ||
| 534 | */ | ||
| 535 | return; | ||
| 536 | } | ||
| 537 | |||
| 538 | getnstimeofday64(&now); | 594 | getnstimeofday64(&now); |
| 539 | if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec * 5) { | 595 | if (rtc_tv_nsec_ok(-1 * target_nsec, &adjust, &now)) { |
| 540 | struct timespec64 adjust = now; | ||
| 541 | |||
| 542 | fail = -ENODEV; | ||
| 543 | if (persistent_clock_is_local) | 596 | if (persistent_clock_is_local) |
| 544 | adjust.tv_sec -= (sys_tz.tz_minuteswest * 60); | 597 | adjust.tv_sec -= (sys_tz.tz_minuteswest * 60); |
| 545 | #ifdef CONFIG_GENERIC_CMOS_UPDATE | 598 | rc = update_persistent_clock64(adjust); |
| 546 | fail = update_persistent_clock64(adjust); | 599 | /* |
| 547 | #endif | 600 | * The machine does not support update_persistent_clock64 even |
| 548 | 601 | * though it defines CONFIG_GENERIC_CMOS_UPDATE. | |
| 549 | #ifdef CONFIG_RTC_SYSTOHC | 602 | */ |
| 550 | if (fail == -ENODEV) | 603 | if (rc == -ENODEV) { |
| 551 | fail = rtc_set_ntp_time(adjust); | 604 | no_cmos = true; |
| 552 | #endif | 605 | return false; |
| 606 | } | ||
| 553 | } | 607 | } |
| 554 | 608 | ||
| 555 | next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec - (TICK_NSEC / 2); | 609 | sched_sync_hw_clock(now, target_nsec, rc); |
| 556 | if (next.tv_nsec <= 0) | 610 | return true; |
| 557 | next.tv_nsec += NSEC_PER_SEC; | 611 | } |
| 558 | 612 | ||
| 559 | if (!fail || fail == -ENODEV) | 613 | /* |
| 560 | next.tv_sec = 659; | 614 | * If we have an externally synchronized Linux clock, then update RTC clock |
| 561 | else | 615 | * accordingly every ~11 minutes. Generally RTCs can only store second |
| 562 | next.tv_sec = 0; | 616 | * precision, but many RTCs will adjust the phase of their second tick to |
| 617 | * match the moment of update. This infrastructure arranges to call to the RTC | ||
| 618 | * set at the correct moment to phase synchronize the RTC second tick over | ||
| 619 | * with the kernel clock. | ||
| 620 | */ | ||
| 621 | static void sync_hw_clock(struct work_struct *work) | ||
| 622 | { | ||
| 623 | if (!ntp_synced()) | ||
| 624 | return; | ||
| 563 | 625 | ||
| 564 | if (next.tv_nsec >= NSEC_PER_SEC) { | 626 | if (sync_cmos_clock()) |
| 565 | next.tv_sec++; | 627 | return; |
| 566 | next.tv_nsec -= NSEC_PER_SEC; | 628 | |
| 567 | } | 629 | sync_rtc_clock(); |
| 568 | queue_delayed_work(system_power_efficient_wq, | ||
| 569 | &sync_cmos_work, timespec64_to_jiffies(&next)); | ||
| 570 | } | 630 | } |
| 571 | 631 | ||
| 572 | void ntp_notify_cmos_timer(void) | 632 | void ntp_notify_cmos_timer(void) |
| 573 | { | 633 | { |
| 574 | queue_delayed_work(system_power_efficient_wq, &sync_cmos_work, 0); | 634 | if (!ntp_synced()) |
| 575 | } | 635 | return; |
| 576 | |||
| 577 | #else | ||
| 578 | void ntp_notify_cmos_timer(void) { } | ||
| 579 | #endif | ||
| 580 | 636 | ||
| 637 | if (IS_ENABLED(CONFIG_GENERIC_CMOS_UPDATE) || | ||
| 638 | IS_ENABLED(CONFIG_RTC_SYSTOHC)) | ||
| 639 | queue_delayed_work(system_power_efficient_wq, &sync_work, 0); | ||
| 640 | } | ||
| 581 | 641 | ||
| 582 | /* | 642 | /* |
| 583 | * Propagate a new txc->status value into the NTP state: | 643 | * Propagate a new txc->status value into the NTP state: |
| @@ -654,67 +714,6 @@ static inline void process_adjtimex_modes(struct timex *txc, | |||
| 654 | } | 714 | } |
| 655 | 715 | ||
| 656 | 716 | ||
| 657 | |||
| 658 | /** | ||
| 659 | * ntp_validate_timex - Ensures the timex is ok for use in do_adjtimex | ||
| 660 | */ | ||
| 661 | int ntp_validate_timex(struct timex *txc) | ||
| 662 | { | ||
| 663 | if (txc->modes & ADJ_ADJTIME) { | ||
| 664 | /* singleshot must not be used with any other mode bits */ | ||
| 665 | if (!(txc->modes & ADJ_OFFSET_SINGLESHOT)) | ||
| 666 | return -EINVAL; | ||
| 667 | if (!(txc->modes & ADJ_OFFSET_READONLY) && | ||
| 668 | !capable(CAP_SYS_TIME)) | ||
| 669 | return -EPERM; | ||
| 670 | } else { | ||
| 671 | /* In order to modify anything, you gotta be super-user! */ | ||
| 672 | if (txc->modes && !capable(CAP_SYS_TIME)) | ||
| 673 | return -EPERM; | ||
| 674 | /* | ||
| 675 | * if the quartz is off by more than 10% then | ||
| 676 | * something is VERY wrong! | ||
| 677 | */ | ||
| 678 | if (txc->modes & ADJ_TICK && | ||
| 679 | (txc->tick < 900000/USER_HZ || | ||
| 680 | txc->tick > 1100000/USER_HZ)) | ||
| 681 | return -EINVAL; | ||
| 682 | } | ||
| 683 | |||
| 684 | if (txc->modes & ADJ_SETOFFSET) { | ||
| 685 | /* In order to inject time, you gotta be super-user! */ | ||
| 686 | if (!capable(CAP_SYS_TIME)) | ||
| 687 | return -EPERM; | ||
| 688 | |||
| 689 | if (txc->modes & ADJ_NANO) { | ||
| 690 | struct timespec ts; | ||
| 691 | |||
| 692 | ts.tv_sec = txc->time.tv_sec; | ||
| 693 | ts.tv_nsec = txc->time.tv_usec; | ||
| 694 | if (!timespec_inject_offset_valid(&ts)) | ||
| 695 | return -EINVAL; | ||
| 696 | |||
| 697 | } else { | ||
| 698 | if (!timeval_inject_offset_valid(&txc->time)) | ||
| 699 | return -EINVAL; | ||
| 700 | } | ||
| 701 | } | ||
| 702 | |||
| 703 | /* | ||
| 704 | * Check for potential multiplication overflows that can | ||
| 705 | * only happen on 64-bit systems: | ||
| 706 | */ | ||
| 707 | if ((txc->modes & ADJ_FREQUENCY) && (BITS_PER_LONG == 64)) { | ||
| 708 | if (LLONG_MIN / PPM_SCALE > txc->freq) | ||
| 709 | return -EINVAL; | ||
| 710 | if (LLONG_MAX / PPM_SCALE < txc->freq) | ||
| 711 | return -EINVAL; | ||
| 712 | } | ||
| 713 | |||
| 714 | return 0; | ||
| 715 | } | ||
| 716 | |||
| 717 | |||
| 718 | /* | 717 | /* |
| 719 | * adjtimex mainly allows reading (and writing, if superuser) of | 718 | * adjtimex mainly allows reading (and writing, if superuser) of |
| 720 | * kernel time-keeping variables. used by xntpd. | 719 | * kernel time-keeping variables. used by xntpd. |
diff --git a/kernel/time/ntp_internal.h b/kernel/time/ntp_internal.h index 0a53e6ea47b1..909bd1f1bfb1 100644 --- a/kernel/time/ntp_internal.h +++ b/kernel/time/ntp_internal.h | |||
| @@ -8,7 +8,6 @@ extern void ntp_clear(void); | |||
| 8 | extern u64 ntp_tick_length(void); | 8 | extern u64 ntp_tick_length(void); |
| 9 | extern ktime_t ntp_get_next_leap(void); | 9 | extern ktime_t ntp_get_next_leap(void); |
| 10 | extern int second_overflow(time64_t secs); | 10 | extern int second_overflow(time64_t secs); |
| 11 | extern int ntp_validate_timex(struct timex *); | ||
| 12 | extern int __do_adjtimex(struct timex *, struct timespec64 *, s32 *); | 11 | extern int __do_adjtimex(struct timex *, struct timespec64 *, s32 *); |
| 13 | extern void __hardpps(const struct timespec64 *, const struct timespec64 *); | 12 | extern void __hardpps(const struct timespec64 *, const struct timespec64 *); |
| 14 | #endif /* _LINUX_NTP_INTERNAL_H */ | 13 | #endif /* _LINUX_NTP_INTERNAL_H */ |
diff --git a/kernel/time/posix-stubs.c b/kernel/time/posix-stubs.c index 06f34feb635e..b258bee13b02 100644 --- a/kernel/time/posix-stubs.c +++ b/kernel/time/posix-stubs.c | |||
| @@ -117,8 +117,7 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, | |||
| 117 | const struct timespec __user *, rqtp, | 117 | const struct timespec __user *, rqtp, |
| 118 | struct timespec __user *, rmtp) | 118 | struct timespec __user *, rmtp) |
| 119 | { | 119 | { |
| 120 | struct timespec64 t64; | 120 | struct timespec64 t; |
| 121 | struct timespec t; | ||
| 122 | 121 | ||
| 123 | switch (which_clock) { | 122 | switch (which_clock) { |
| 124 | case CLOCK_REALTIME: | 123 | case CLOCK_REALTIME: |
| @@ -129,16 +128,15 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, | |||
| 129 | return -EINVAL; | 128 | return -EINVAL; |
| 130 | } | 129 | } |
| 131 | 130 | ||
| 132 | if (copy_from_user(&t, rqtp, sizeof (struct timespec))) | 131 | if (get_timespec64(&t, rqtp)) |
| 133 | return -EFAULT; | 132 | return -EFAULT; |
| 134 | t64 = timespec_to_timespec64(t); | 133 | if (!timespec64_valid(&t)) |
| 135 | if (!timespec64_valid(&t64)) | ||
| 136 | return -EINVAL; | 134 | return -EINVAL; |
| 137 | if (flags & TIMER_ABSTIME) | 135 | if (flags & TIMER_ABSTIME) |
| 138 | rmtp = NULL; | 136 | rmtp = NULL; |
| 139 | current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; | 137 | current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; |
| 140 | current->restart_block.nanosleep.rmtp = rmtp; | 138 | current->restart_block.nanosleep.rmtp = rmtp; |
| 141 | return hrtimer_nanosleep(&t64, flags & TIMER_ABSTIME ? | 139 | return hrtimer_nanosleep(&t, flags & TIMER_ABSTIME ? |
| 142 | HRTIMER_MODE_ABS : HRTIMER_MODE_REL, | 140 | HRTIMER_MODE_ABS : HRTIMER_MODE_REL, |
| 143 | which_clock); | 141 | which_clock); |
| 144 | } | 142 | } |
| @@ -203,8 +201,7 @@ COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags, | |||
| 203 | struct compat_timespec __user *, rqtp, | 201 | struct compat_timespec __user *, rqtp, |
| 204 | struct compat_timespec __user *, rmtp) | 202 | struct compat_timespec __user *, rmtp) |
| 205 | { | 203 | { |
| 206 | struct timespec64 t64; | 204 | struct timespec64 t; |
| 207 | struct timespec t; | ||
| 208 | 205 | ||
| 209 | switch (which_clock) { | 206 | switch (which_clock) { |
| 210 | case CLOCK_REALTIME: | 207 | case CLOCK_REALTIME: |
| @@ -215,16 +212,15 @@ COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags, | |||
| 215 | return -EINVAL; | 212 | return -EINVAL; |
| 216 | } | 213 | } |
| 217 | 214 | ||
| 218 | if (compat_get_timespec(&t, rqtp)) | 215 | if (compat_get_timespec64(&t, rqtp)) |
| 219 | return -EFAULT; | 216 | return -EFAULT; |
| 220 | t64 = timespec_to_timespec64(t); | 217 | if (!timespec64_valid(&t)) |
| 221 | if (!timespec64_valid(&t64)) | ||
| 222 | return -EINVAL; | 218 | return -EINVAL; |
| 223 | if (flags & TIMER_ABSTIME) | 219 | if (flags & TIMER_ABSTIME) |
| 224 | rmtp = NULL; | 220 | rmtp = NULL; |
| 225 | current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; | 221 | current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; |
| 226 | current->restart_block.nanosleep.compat_rmtp = rmtp; | 222 | current->restart_block.nanosleep.compat_rmtp = rmtp; |
| 227 | return hrtimer_nanosleep(&t64, flags & TIMER_ABSTIME ? | 223 | return hrtimer_nanosleep(&t, flags & TIMER_ABSTIME ? |
| 228 | HRTIMER_MODE_ABS : HRTIMER_MODE_REL, | 224 | HRTIMER_MODE_ABS : HRTIMER_MODE_REL, |
| 229 | which_clock); | 225 | which_clock); |
| 230 | } | 226 | } |
diff --git a/kernel/time/tick-oneshot.c b/kernel/time/tick-oneshot.c index 6b009c207671..c1f518e7aa80 100644 --- a/kernel/time/tick-oneshot.c +++ b/kernel/time/tick-oneshot.c | |||
| @@ -33,6 +33,7 @@ int tick_program_event(ktime_t expires, int force) | |||
| 33 | * We don't need the clock event device any more, stop it. | 33 | * We don't need the clock event device any more, stop it. |
| 34 | */ | 34 | */ |
| 35 | clockevents_switch_state(dev, CLOCK_EVT_STATE_ONESHOT_STOPPED); | 35 | clockevents_switch_state(dev, CLOCK_EVT_STATE_ONESHOT_STOPPED); |
| 36 | dev->next_event = KTIME_MAX; | ||
| 36 | return 0; | 37 | return 0; |
| 37 | } | 38 | } |
| 38 | 39 | ||
diff --git a/kernel/time/time.c b/kernel/time/time.c index 44a8c1402133..bd4e6c7dd689 100644 --- a/kernel/time/time.c +++ b/kernel/time/time.c | |||
| @@ -82,7 +82,7 @@ SYSCALL_DEFINE1(time, time_t __user *, tloc) | |||
| 82 | 82 | ||
| 83 | SYSCALL_DEFINE1(stime, time_t __user *, tptr) | 83 | SYSCALL_DEFINE1(stime, time_t __user *, tptr) |
| 84 | { | 84 | { |
| 85 | struct timespec tv; | 85 | struct timespec64 tv; |
| 86 | int err; | 86 | int err; |
| 87 | 87 | ||
| 88 | if (get_user(tv.tv_sec, tptr)) | 88 | if (get_user(tv.tv_sec, tptr)) |
| @@ -90,11 +90,11 @@ SYSCALL_DEFINE1(stime, time_t __user *, tptr) | |||
| 90 | 90 | ||
| 91 | tv.tv_nsec = 0; | 91 | tv.tv_nsec = 0; |
| 92 | 92 | ||
| 93 | err = security_settime(&tv, NULL); | 93 | err = security_settime64(&tv, NULL); |
| 94 | if (err) | 94 | if (err) |
| 95 | return err; | 95 | return err; |
| 96 | 96 | ||
| 97 | do_settimeofday(&tv); | 97 | do_settimeofday64(&tv); |
| 98 | return 0; | 98 | return 0; |
| 99 | } | 99 | } |
| 100 | 100 | ||
| @@ -122,7 +122,7 @@ COMPAT_SYSCALL_DEFINE1(time, compat_time_t __user *, tloc) | |||
| 122 | 122 | ||
| 123 | COMPAT_SYSCALL_DEFINE1(stime, compat_time_t __user *, tptr) | 123 | COMPAT_SYSCALL_DEFINE1(stime, compat_time_t __user *, tptr) |
| 124 | { | 124 | { |
| 125 | struct timespec tv; | 125 | struct timespec64 tv; |
| 126 | int err; | 126 | int err; |
| 127 | 127 | ||
| 128 | if (get_user(tv.tv_sec, tptr)) | 128 | if (get_user(tv.tv_sec, tptr)) |
| @@ -130,11 +130,11 @@ COMPAT_SYSCALL_DEFINE1(stime, compat_time_t __user *, tptr) | |||
| 130 | 130 | ||
| 131 | tv.tv_nsec = 0; | 131 | tv.tv_nsec = 0; |
| 132 | 132 | ||
| 133 | err = security_settime(&tv, NULL); | 133 | err = security_settime64(&tv, NULL); |
| 134 | if (err) | 134 | if (err) |
| 135 | return err; | 135 | return err; |
| 136 | 136 | ||
| 137 | do_settimeofday(&tv); | 137 | do_settimeofday64(&tv); |
| 138 | return 0; | 138 | return 0; |
| 139 | } | 139 | } |
| 140 | 140 | ||
| @@ -158,40 +158,6 @@ SYSCALL_DEFINE2(gettimeofday, struct timeval __user *, tv, | |||
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | /* | 160 | /* |
| 161 | * Indicates if there is an offset between the system clock and the hardware | ||
| 162 | * clock/persistent clock/rtc. | ||
| 163 | */ | ||
| 164 | int persistent_clock_is_local; | ||
| 165 | |||
| 166 | /* | ||
| 167 | * Adjust the time obtained from the CMOS to be UTC time instead of | ||
| 168 | * local time. | ||
| 169 | * | ||
| 170 | * This is ugly, but preferable to the alternatives. Otherwise we | ||
| 171 | * would either need to write a program to do it in /etc/rc (and risk | ||
| 172 | * confusion if the program gets run more than once; it would also be | ||
| 173 | * hard to make the program warp the clock precisely n hours) or | ||
| 174 | * compile in the timezone information into the kernel. Bad, bad.... | ||
| 175 | * | ||
| 176 | * - TYT, 1992-01-01 | ||
| 177 | * | ||
| 178 | * The best thing to do is to keep the CMOS clock in universal time (UTC) | ||
| 179 | * as real UNIX machines always do it. This avoids all headaches about | ||
| 180 | * daylight saving times and warping kernel clocks. | ||
| 181 | */ | ||
| 182 | static inline void warp_clock(void) | ||
| 183 | { | ||
| 184 | if (sys_tz.tz_minuteswest != 0) { | ||
| 185 | struct timespec adjust; | ||
| 186 | |||
| 187 | persistent_clock_is_local = 1; | ||
| 188 | adjust.tv_sec = sys_tz.tz_minuteswest * 60; | ||
| 189 | adjust.tv_nsec = 0; | ||
| 190 | timekeeping_inject_offset(&adjust); | ||
| 191 | } | ||
| 192 | } | ||
| 193 | |||
| 194 | /* | ||
| 195 | * In case for some reason the CMOS clock has not already been running | 161 | * In case for some reason the CMOS clock has not already been running |
| 196 | * in UTC, but in some local time: The first time we set the timezone, | 162 | * in UTC, but in some local time: The first time we set the timezone, |
| 197 | * we will warp the clock so that it is ticking UTC time instead of | 163 | * we will warp the clock so that it is ticking UTC time instead of |
| @@ -224,7 +190,7 @@ int do_sys_settimeofday64(const struct timespec64 *tv, const struct timezone *tz | |||
| 224 | if (firsttime) { | 190 | if (firsttime) { |
| 225 | firsttime = 0; | 191 | firsttime = 0; |
| 226 | if (!tv) | 192 | if (!tv) |
| 227 | warp_clock(); | 193 | timekeeping_warp_clock(); |
| 228 | } | 194 | } |
| 229 | } | 195 | } |
| 230 | if (tv) | 196 | if (tv) |
| @@ -441,6 +407,7 @@ time64_t mktime64(const unsigned int year0, const unsigned int mon0, | |||
| 441 | } | 407 | } |
| 442 | EXPORT_SYMBOL(mktime64); | 408 | EXPORT_SYMBOL(mktime64); |
| 443 | 409 | ||
| 410 | #if __BITS_PER_LONG == 32 | ||
| 444 | /** | 411 | /** |
| 445 | * set_normalized_timespec - set timespec sec and nsec parts and normalize | 412 | * set_normalized_timespec - set timespec sec and nsec parts and normalize |
| 446 | * | 413 | * |
| @@ -501,6 +468,7 @@ struct timespec ns_to_timespec(const s64 nsec) | |||
| 501 | return ts; | 468 | return ts; |
| 502 | } | 469 | } |
| 503 | EXPORT_SYMBOL(ns_to_timespec); | 470 | EXPORT_SYMBOL(ns_to_timespec); |
| 471 | #endif | ||
| 504 | 472 | ||
| 505 | /** | 473 | /** |
| 506 | * ns_to_timeval - Convert nanoseconds to timeval | 474 | * ns_to_timeval - Convert nanoseconds to timeval |
| @@ -520,7 +488,6 @@ struct timeval ns_to_timeval(const s64 nsec) | |||
| 520 | } | 488 | } |
| 521 | EXPORT_SYMBOL(ns_to_timeval); | 489 | EXPORT_SYMBOL(ns_to_timeval); |
| 522 | 490 | ||
| 523 | #if BITS_PER_LONG == 32 | ||
| 524 | /** | 491 | /** |
| 525 | * set_normalized_timespec - set timespec sec and nsec parts and normalize | 492 | * set_normalized_timespec - set timespec sec and nsec parts and normalize |
| 526 | * | 493 | * |
| @@ -581,7 +548,7 @@ struct timespec64 ns_to_timespec64(const s64 nsec) | |||
| 581 | return ts; | 548 | return ts; |
| 582 | } | 549 | } |
| 583 | EXPORT_SYMBOL(ns_to_timespec64); | 550 | EXPORT_SYMBOL(ns_to_timespec64); |
| 584 | #endif | 551 | |
| 585 | /** | 552 | /** |
| 586 | * msecs_to_jiffies: - convert milliseconds to jiffies | 553 | * msecs_to_jiffies: - convert milliseconds to jiffies |
| 587 | * @m: time in milliseconds | 554 | * @m: time in milliseconds |
| @@ -853,24 +820,6 @@ unsigned long nsecs_to_jiffies(u64 n) | |||
| 853 | EXPORT_SYMBOL_GPL(nsecs_to_jiffies); | 820 | EXPORT_SYMBOL_GPL(nsecs_to_jiffies); |
| 854 | 821 | ||
| 855 | /* | 822 | /* |
| 856 | * Add two timespec values and do a safety check for overflow. | ||
| 857 | * It's assumed that both values are valid (>= 0) | ||
| 858 | */ | ||
| 859 | struct timespec timespec_add_safe(const struct timespec lhs, | ||
| 860 | const struct timespec rhs) | ||
| 861 | { | ||
| 862 | struct timespec res; | ||
| 863 | |||
| 864 | set_normalized_timespec(&res, lhs.tv_sec + rhs.tv_sec, | ||
| 865 | lhs.tv_nsec + rhs.tv_nsec); | ||
| 866 | |||
| 867 | if (res.tv_sec < lhs.tv_sec || res.tv_sec < rhs.tv_sec) | ||
| 868 | res.tv_sec = TIME_T_MAX; | ||
| 869 | |||
| 870 | return res; | ||
| 871 | } | ||
| 872 | |||
| 873 | /* | ||
| 874 | * Add two timespec64 values and do a safety check for overflow. | 823 | * Add two timespec64 values and do a safety check for overflow. |
| 875 | * It's assumed that both values are valid (>= 0). | 824 | * It's assumed that both values are valid (>= 0). |
| 876 | * And, each timespec64 is in normalized form. | 825 | * And, each timespec64 is in normalized form. |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 2cafb49aa65e..198afa78bf69 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
| @@ -60,8 +60,27 @@ struct tk_fast { | |||
| 60 | struct tk_read_base base[2]; | 60 | struct tk_read_base base[2]; |
| 61 | }; | 61 | }; |
| 62 | 62 | ||
| 63 | static struct tk_fast tk_fast_mono ____cacheline_aligned; | 63 | /* Suspend-time cycles value for halted fast timekeeper. */ |
| 64 | static struct tk_fast tk_fast_raw ____cacheline_aligned; | 64 | static u64 cycles_at_suspend; |
| 65 | |||
| 66 | static u64 dummy_clock_read(struct clocksource *cs) | ||
| 67 | { | ||
| 68 | return cycles_at_suspend; | ||
| 69 | } | ||
| 70 | |||
| 71 | static struct clocksource dummy_clock = { | ||
| 72 | .read = dummy_clock_read, | ||
| 73 | }; | ||
| 74 | |||
| 75 | static struct tk_fast tk_fast_mono ____cacheline_aligned = { | ||
| 76 | .base[0] = { .clock = &dummy_clock, }, | ||
| 77 | .base[1] = { .clock = &dummy_clock, }, | ||
| 78 | }; | ||
| 79 | |||
| 80 | static struct tk_fast tk_fast_raw ____cacheline_aligned = { | ||
| 81 | .base[0] = { .clock = &dummy_clock, }, | ||
| 82 | .base[1] = { .clock = &dummy_clock, }, | ||
| 83 | }; | ||
| 65 | 84 | ||
| 66 | /* flag for if timekeeping is suspended */ | 85 | /* flag for if timekeeping is suspended */ |
| 67 | int __read_mostly timekeeping_suspended; | 86 | int __read_mostly timekeeping_suspended; |
| @@ -477,17 +496,39 @@ u64 notrace ktime_get_boot_fast_ns(void) | |||
| 477 | } | 496 | } |
| 478 | EXPORT_SYMBOL_GPL(ktime_get_boot_fast_ns); | 497 | EXPORT_SYMBOL_GPL(ktime_get_boot_fast_ns); |
| 479 | 498 | ||
| 480 | /* Suspend-time cycles value for halted fast timekeeper. */ | ||
| 481 | static u64 cycles_at_suspend; | ||
| 482 | 499 | ||
| 483 | static u64 dummy_clock_read(struct clocksource *cs) | 500 | /* |
| 501 | * See comment for __ktime_get_fast_ns() vs. timestamp ordering | ||
| 502 | */ | ||
| 503 | static __always_inline u64 __ktime_get_real_fast_ns(struct tk_fast *tkf) | ||
| 484 | { | 504 | { |
| 485 | return cycles_at_suspend; | 505 | struct tk_read_base *tkr; |
| 506 | unsigned int seq; | ||
| 507 | u64 now; | ||
| 508 | |||
| 509 | do { | ||
| 510 | seq = raw_read_seqcount_latch(&tkf->seq); | ||
| 511 | tkr = tkf->base + (seq & 0x01); | ||
| 512 | now = ktime_to_ns(tkr->base_real); | ||
| 513 | |||
| 514 | now += timekeeping_delta_to_ns(tkr, | ||
| 515 | clocksource_delta( | ||
| 516 | tk_clock_read(tkr), | ||
| 517 | tkr->cycle_last, | ||
| 518 | tkr->mask)); | ||
| 519 | } while (read_seqcount_retry(&tkf->seq, seq)); | ||
| 520 | |||
| 521 | return now; | ||
| 486 | } | 522 | } |
| 487 | 523 | ||
| 488 | static struct clocksource dummy_clock = { | 524 | /** |
| 489 | .read = dummy_clock_read, | 525 | * ktime_get_real_fast_ns: - NMI safe and fast access to clock realtime. |
| 490 | }; | 526 | */ |
| 527 | u64 ktime_get_real_fast_ns(void) | ||
| 528 | { | ||
| 529 | return __ktime_get_real_fast_ns(&tk_fast_mono); | ||
| 530 | } | ||
| 531 | EXPORT_SYMBOL_GPL(ktime_get_real_fast_ns); | ||
| 491 | 532 | ||
| 492 | /** | 533 | /** |
| 493 | * halt_fast_timekeeper - Prevent fast timekeeper from accessing clocksource. | 534 | * halt_fast_timekeeper - Prevent fast timekeeper from accessing clocksource. |
| @@ -507,6 +548,7 @@ static void halt_fast_timekeeper(struct timekeeper *tk) | |||
| 507 | memcpy(&tkr_dummy, tkr, sizeof(tkr_dummy)); | 548 | memcpy(&tkr_dummy, tkr, sizeof(tkr_dummy)); |
| 508 | cycles_at_suspend = tk_clock_read(tkr); | 549 | cycles_at_suspend = tk_clock_read(tkr); |
| 509 | tkr_dummy.clock = &dummy_clock; | 550 | tkr_dummy.clock = &dummy_clock; |
| 551 | tkr_dummy.base_real = tkr->base + tk->offs_real; | ||
| 510 | update_fast_timekeeper(&tkr_dummy, &tk_fast_mono); | 552 | update_fast_timekeeper(&tkr_dummy, &tk_fast_mono); |
| 511 | 553 | ||
| 512 | tkr = &tk->tkr_raw; | 554 | tkr = &tk->tkr_raw; |
| @@ -654,6 +696,7 @@ static void timekeeping_update(struct timekeeper *tk, unsigned int action) | |||
| 654 | update_vsyscall(tk); | 696 | update_vsyscall(tk); |
| 655 | update_pvclock_gtod(tk, action & TK_CLOCK_WAS_SET); | 697 | update_pvclock_gtod(tk, action & TK_CLOCK_WAS_SET); |
| 656 | 698 | ||
| 699 | tk->tkr_mono.base_real = tk->tkr_mono.base + tk->offs_real; | ||
| 657 | update_fast_timekeeper(&tk->tkr_mono, &tk_fast_mono); | 700 | update_fast_timekeeper(&tk->tkr_mono, &tk_fast_mono); |
| 658 | update_fast_timekeeper(&tk->tkr_raw, &tk_fast_raw); | 701 | update_fast_timekeeper(&tk->tkr_raw, &tk_fast_raw); |
| 659 | 702 | ||
| @@ -1264,33 +1307,31 @@ EXPORT_SYMBOL(do_settimeofday64); | |||
| 1264 | * | 1307 | * |
| 1265 | * Adds or subtracts an offset value from the current time. | 1308 | * Adds or subtracts an offset value from the current time. |
| 1266 | */ | 1309 | */ |
| 1267 | int timekeeping_inject_offset(struct timespec *ts) | 1310 | static int timekeeping_inject_offset(struct timespec64 *ts) |
| 1268 | { | 1311 | { |
| 1269 | struct timekeeper *tk = &tk_core.timekeeper; | 1312 | struct timekeeper *tk = &tk_core.timekeeper; |
| 1270 | unsigned long flags; | 1313 | unsigned long flags; |
| 1271 | struct timespec64 ts64, tmp; | 1314 | struct timespec64 tmp; |
| 1272 | int ret = 0; | 1315 | int ret = 0; |
| 1273 | 1316 | ||
| 1274 | if (!timespec_inject_offset_valid(ts)) | 1317 | if (ts->tv_nsec < 0 || ts->tv_nsec >= NSEC_PER_SEC) |
| 1275 | return -EINVAL; | 1318 | return -EINVAL; |
| 1276 | 1319 | ||
| 1277 | ts64 = timespec_to_timespec64(*ts); | ||
| 1278 | |||
| 1279 | raw_spin_lock_irqsave(&timekeeper_lock, flags); | 1320 | raw_spin_lock_irqsave(&timekeeper_lock, flags); |
| 1280 | write_seqcount_begin(&tk_core.seq); | 1321 | write_seqcount_begin(&tk_core.seq); |
| 1281 | 1322 | ||
| 1282 | timekeeping_forward_now(tk); | 1323 | timekeeping_forward_now(tk); |
| 1283 | 1324 | ||
| 1284 | /* Make sure the proposed value is valid */ | 1325 | /* Make sure the proposed value is valid */ |
| 1285 | tmp = timespec64_add(tk_xtime(tk), ts64); | 1326 | tmp = timespec64_add(tk_xtime(tk), *ts); |
| 1286 | if (timespec64_compare(&tk->wall_to_monotonic, &ts64) > 0 || | 1327 | if (timespec64_compare(&tk->wall_to_monotonic, ts) > 0 || |
| 1287 | !timespec64_valid_strict(&tmp)) { | 1328 | !timespec64_valid_strict(&tmp)) { |
| 1288 | ret = -EINVAL; | 1329 | ret = -EINVAL; |
| 1289 | goto error; | 1330 | goto error; |
| 1290 | } | 1331 | } |
| 1291 | 1332 | ||
| 1292 | tk_xtime_add(tk, &ts64); | 1333 | tk_xtime_add(tk, ts); |
| 1293 | tk_set_wall_to_mono(tk, timespec64_sub(tk->wall_to_monotonic, ts64)); | 1334 | tk_set_wall_to_mono(tk, timespec64_sub(tk->wall_to_monotonic, *ts)); |
| 1294 | 1335 | ||
| 1295 | error: /* even if we error out, we forwarded the time, so call update */ | 1336 | error: /* even if we error out, we forwarded the time, so call update */ |
| 1296 | timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET); | 1337 | timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET); |
| @@ -1303,7 +1344,40 @@ error: /* even if we error out, we forwarded the time, so call update */ | |||
| 1303 | 1344 | ||
| 1304 | return ret; | 1345 | return ret; |
| 1305 | } | 1346 | } |
| 1306 | EXPORT_SYMBOL(timekeeping_inject_offset); | 1347 | |
| 1348 | /* | ||
| 1349 | * Indicates if there is an offset between the system clock and the hardware | ||
| 1350 | * clock/persistent clock/rtc. | ||
| 1351 | */ | ||
| 1352 | int persistent_clock_is_local; | ||
| 1353 | |||
| 1354 | /* | ||
| 1355 | * Adjust the time obtained from the CMOS to be UTC time instead of | ||
| 1356 | * local time. | ||
| 1357 | * | ||
| 1358 | * This is ugly, but preferable to the alternatives. Otherwise we | ||
| 1359 | * would either need to write a program to do it in /etc/rc (and risk | ||
| 1360 | * confusion if the program gets run more than once; it would also be | ||
| 1361 | * hard to make the program warp the clock precisely n hours) or | ||
| 1362 | * compile in the timezone information into the kernel. Bad, bad.... | ||
| 1363 | * | ||
| 1364 | * - TYT, 1992-01-01 | ||
| 1365 | * | ||
| 1366 | * The best thing to do is to keep the CMOS clock in universal time (UTC) | ||
| 1367 | * as real UNIX machines always do it. This avoids all headaches about | ||
| 1368 | * daylight saving times and warping kernel clocks. | ||
| 1369 | */ | ||
| 1370 | void timekeeping_warp_clock(void) | ||
| 1371 | { | ||
| 1372 | if (sys_tz.tz_minuteswest != 0) { | ||
| 1373 | struct timespec64 adjust; | ||
| 1374 | |||
| 1375 | persistent_clock_is_local = 1; | ||
| 1376 | adjust.tv_sec = sys_tz.tz_minuteswest * 60; | ||
| 1377 | adjust.tv_nsec = 0; | ||
| 1378 | timekeeping_inject_offset(&adjust); | ||
| 1379 | } | ||
| 1380 | } | ||
| 1307 | 1381 | ||
| 1308 | /** | 1382 | /** |
| 1309 | * __timekeeping_set_tai_offset - Sets the TAI offset from UTC and monotonic | 1383 | * __timekeeping_set_tai_offset - Sets the TAI offset from UTC and monotonic |
| @@ -2248,6 +2322,72 @@ ktime_t ktime_get_update_offsets_now(unsigned int *cwsseq, ktime_t *offs_real, | |||
| 2248 | } | 2322 | } |
| 2249 | 2323 | ||
| 2250 | /** | 2324 | /** |
| 2325 | * timekeeping_validate_timex - Ensures the timex is ok for use in do_adjtimex | ||
| 2326 | */ | ||
| 2327 | static int timekeeping_validate_timex(struct timex *txc) | ||
| 2328 | { | ||
| 2329 | if (txc->modes & ADJ_ADJTIME) { | ||
| 2330 | /* singleshot must not be used with any other mode bits */ | ||
| 2331 | if (!(txc->modes & ADJ_OFFSET_SINGLESHOT)) | ||
| 2332 | return -EINVAL; | ||
| 2333 | if (!(txc->modes & ADJ_OFFSET_READONLY) && | ||
| 2334 | !capable(CAP_SYS_TIME)) | ||
| 2335 | return -EPERM; | ||
| 2336 | } else { | ||
| 2337 | /* In order to modify anything, you gotta be super-user! */ | ||
| 2338 | if (txc->modes && !capable(CAP_SYS_TIME)) | ||
| 2339 | return -EPERM; | ||
| 2340 | /* | ||
| 2341 | * if the quartz is off by more than 10% then | ||
| 2342 | * something is VERY wrong! | ||
| 2343 | */ | ||
| 2344 | if (txc->modes & ADJ_TICK && | ||
| 2345 | (txc->tick < 900000/USER_HZ || | ||
| 2346 | txc->tick > 1100000/USER_HZ)) | ||
| 2347 | return -EINVAL; | ||
| 2348 | } | ||
| 2349 | |||
| 2350 | if (txc->modes & ADJ_SETOFFSET) { | ||
| 2351 | /* In order to inject time, you gotta be super-user! */ | ||
| 2352 | if (!capable(CAP_SYS_TIME)) | ||
| 2353 | return -EPERM; | ||
| 2354 | |||
| 2355 | /* | ||
| 2356 | * Validate if a timespec/timeval used to inject a time | ||
| 2357 | * offset is valid. Offsets can be postive or negative, so | ||
| 2358 | * we don't check tv_sec. The value of the timeval/timespec | ||
| 2359 | * is the sum of its fields,but *NOTE*: | ||
| 2360 | * The field tv_usec/tv_nsec must always be non-negative and | ||
| 2361 | * we can't have more nanoseconds/microseconds than a second. | ||
| 2362 | */ | ||
| 2363 | if (txc->time.tv_usec < 0) | ||
| 2364 | return -EINVAL; | ||
| 2365 | |||
| 2366 | if (txc->modes & ADJ_NANO) { | ||
| 2367 | if (txc->time.tv_usec >= NSEC_PER_SEC) | ||
| 2368 | return -EINVAL; | ||
| 2369 | } else { | ||
| 2370 | if (txc->time.tv_usec >= USEC_PER_SEC) | ||
| 2371 | return -EINVAL; | ||
| 2372 | } | ||
| 2373 | } | ||
| 2374 | |||
| 2375 | /* | ||
| 2376 | * Check for potential multiplication overflows that can | ||
| 2377 | * only happen on 64-bit systems: | ||
| 2378 | */ | ||
| 2379 | if ((txc->modes & ADJ_FREQUENCY) && (BITS_PER_LONG == 64)) { | ||
| 2380 | if (LLONG_MIN / PPM_SCALE > txc->freq) | ||
| 2381 | return -EINVAL; | ||
| 2382 | if (LLONG_MAX / PPM_SCALE < txc->freq) | ||
| 2383 | return -EINVAL; | ||
| 2384 | } | ||
| 2385 | |||
| 2386 | return 0; | ||
| 2387 | } | ||
| 2388 | |||
| 2389 | |||
| 2390 | /** | ||
| 2251 | * do_adjtimex() - Accessor function to NTP __do_adjtimex function | 2391 | * do_adjtimex() - Accessor function to NTP __do_adjtimex function |
| 2252 | */ | 2392 | */ |
| 2253 | int do_adjtimex(struct timex *txc) | 2393 | int do_adjtimex(struct timex *txc) |
| @@ -2259,12 +2399,12 @@ int do_adjtimex(struct timex *txc) | |||
| 2259 | int ret; | 2399 | int ret; |
| 2260 | 2400 | ||
| 2261 | /* Validate the data before disabling interrupts */ | 2401 | /* Validate the data before disabling interrupts */ |
| 2262 | ret = ntp_validate_timex(txc); | 2402 | ret = timekeeping_validate_timex(txc); |
| 2263 | if (ret) | 2403 | if (ret) |
| 2264 | return ret; | 2404 | return ret; |
| 2265 | 2405 | ||
| 2266 | if (txc->modes & ADJ_SETOFFSET) { | 2406 | if (txc->modes & ADJ_SETOFFSET) { |
| 2267 | struct timespec delta; | 2407 | struct timespec64 delta; |
| 2268 | delta.tv_sec = txc->time.tv_sec; | 2408 | delta.tv_sec = txc->time.tv_sec; |
| 2269 | delta.tv_nsec = txc->time.tv_usec; | 2409 | delta.tv_nsec = txc->time.tv_usec; |
| 2270 | if (!(txc->modes & ADJ_NANO)) | 2410 | if (!(txc->modes & ADJ_NANO)) |
diff --git a/kernel/time/timekeeping.h b/kernel/time/timekeeping.h index c9f9af339914..7a9b4eb7a1d5 100644 --- a/kernel/time/timekeeping.h +++ b/kernel/time/timekeeping.h | |||
| @@ -11,7 +11,7 @@ extern ktime_t ktime_get_update_offsets_now(unsigned int *cwsseq, | |||
| 11 | 11 | ||
| 12 | extern int timekeeping_valid_for_hres(void); | 12 | extern int timekeeping_valid_for_hres(void); |
| 13 | extern u64 timekeeping_max_deferment(void); | 13 | extern u64 timekeeping_max_deferment(void); |
| 14 | extern int timekeeping_inject_offset(struct timespec *ts); | 14 | extern void timekeeping_warp_clock(void); |
| 15 | extern int timekeeping_suspend(void); | 15 | extern int timekeeping_suspend(void); |
| 16 | extern void timekeeping_resume(void); | 16 | extern void timekeeping_resume(void); |
| 17 | 17 | ||
diff --git a/kernel/time/timer.c b/kernel/time/timer.c index f2674a056c26..af0b8bae4502 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c | |||
| @@ -610,7 +610,7 @@ static bool timer_fixup_init(void *addr, enum debug_obj_state state) | |||
| 610 | } | 610 | } |
| 611 | 611 | ||
| 612 | /* Stub timer callback for improperly used timers. */ | 612 | /* Stub timer callback for improperly used timers. */ |
| 613 | static void stub_timer(unsigned long data) | 613 | static void stub_timer(struct timer_list *unused) |
| 614 | { | 614 | { |
| 615 | WARN_ON(1); | 615 | WARN_ON(1); |
| 616 | } | 616 | } |
| @@ -626,7 +626,7 @@ static bool timer_fixup_activate(void *addr, enum debug_obj_state state) | |||
| 626 | 626 | ||
| 627 | switch (state) { | 627 | switch (state) { |
| 628 | case ODEBUG_STATE_NOTAVAILABLE: | 628 | case ODEBUG_STATE_NOTAVAILABLE: |
| 629 | setup_timer(timer, stub_timer, 0); | 629 | timer_setup(timer, stub_timer, 0); |
| 630 | return true; | 630 | return true; |
| 631 | 631 | ||
| 632 | case ODEBUG_STATE_ACTIVE: | 632 | case ODEBUG_STATE_ACTIVE: |
| @@ -665,7 +665,7 @@ static bool timer_fixup_assert_init(void *addr, enum debug_obj_state state) | |||
| 665 | 665 | ||
| 666 | switch (state) { | 666 | switch (state) { |
| 667 | case ODEBUG_STATE_NOTAVAILABLE: | 667 | case ODEBUG_STATE_NOTAVAILABLE: |
| 668 | setup_timer(timer, stub_timer, 0); | 668 | timer_setup(timer, stub_timer, 0); |
| 669 | return true; | 669 | return true; |
| 670 | default: | 670 | default: |
| 671 | return false; | 671 | return false; |
| @@ -929,8 +929,11 @@ static struct timer_base *lock_timer_base(struct timer_list *timer, | |||
| 929 | } | 929 | } |
| 930 | } | 930 | } |
| 931 | 931 | ||
| 932 | #define MOD_TIMER_PENDING_ONLY 0x01 | ||
| 933 | #define MOD_TIMER_REDUCE 0x02 | ||
| 934 | |||
| 932 | static inline int | 935 | static inline int |
| 933 | __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only) | 936 | __mod_timer(struct timer_list *timer, unsigned long expires, unsigned int options) |
| 934 | { | 937 | { |
| 935 | struct timer_base *base, *new_base; | 938 | struct timer_base *base, *new_base; |
| 936 | unsigned int idx = UINT_MAX; | 939 | unsigned int idx = UINT_MAX; |
| @@ -950,7 +953,11 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only) | |||
| 950 | * larger granularity than you would get from adding a new | 953 | * larger granularity than you would get from adding a new |
| 951 | * timer with this expiry. | 954 | * timer with this expiry. |
| 952 | */ | 955 | */ |
| 953 | if (timer->expires == expires) | 956 | long diff = timer->expires - expires; |
| 957 | |||
| 958 | if (!diff) | ||
| 959 | return 1; | ||
| 960 | if (options & MOD_TIMER_REDUCE && diff <= 0) | ||
| 954 | return 1; | 961 | return 1; |
| 955 | 962 | ||
| 956 | /* | 963 | /* |
| @@ -962,6 +969,12 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only) | |||
| 962 | base = lock_timer_base(timer, &flags); | 969 | base = lock_timer_base(timer, &flags); |
| 963 | forward_timer_base(base); | 970 | forward_timer_base(base); |
| 964 | 971 | ||
| 972 | if (timer_pending(timer) && (options & MOD_TIMER_REDUCE) && | ||
| 973 | time_before_eq(timer->expires, expires)) { | ||
| 974 | ret = 1; | ||
| 975 | goto out_unlock; | ||
| 976 | } | ||
| 977 | |||
| 965 | clk = base->clk; | 978 | clk = base->clk; |
| 966 | idx = calc_wheel_index(expires, clk); | 979 | idx = calc_wheel_index(expires, clk); |
| 967 | 980 | ||
| @@ -971,7 +984,10 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only) | |||
| 971 | * subsequent call will exit in the expires check above. | 984 | * subsequent call will exit in the expires check above. |
| 972 | */ | 985 | */ |
| 973 | if (idx == timer_get_idx(timer)) { | 986 | if (idx == timer_get_idx(timer)) { |
| 974 | timer->expires = expires; | 987 | if (!(options & MOD_TIMER_REDUCE)) |
| 988 | timer->expires = expires; | ||
| 989 | else if (time_after(timer->expires, expires)) | ||
| 990 | timer->expires = expires; | ||
| 975 | ret = 1; | 991 | ret = 1; |
| 976 | goto out_unlock; | 992 | goto out_unlock; |
| 977 | } | 993 | } |
| @@ -981,7 +997,7 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only) | |||
| 981 | } | 997 | } |
| 982 | 998 | ||
| 983 | ret = detach_if_pending(timer, base, false); | 999 | ret = detach_if_pending(timer, base, false); |
| 984 | if (!ret && pending_only) | 1000 | if (!ret && (options & MOD_TIMER_PENDING_ONLY)) |
| 985 | goto out_unlock; | 1001 | goto out_unlock; |
| 986 | 1002 | ||
| 987 | debug_activate(timer, expires); | 1003 | debug_activate(timer, expires); |
| @@ -1042,7 +1058,7 @@ out_unlock: | |||
| 1042 | */ | 1058 | */ |
| 1043 | int mod_timer_pending(struct timer_list *timer, unsigned long expires) | 1059 | int mod_timer_pending(struct timer_list *timer, unsigned long expires) |
| 1044 | { | 1060 | { |
| 1045 | return __mod_timer(timer, expires, true); | 1061 | return __mod_timer(timer, expires, MOD_TIMER_PENDING_ONLY); |
| 1046 | } | 1062 | } |
| 1047 | EXPORT_SYMBOL(mod_timer_pending); | 1063 | EXPORT_SYMBOL(mod_timer_pending); |
| 1048 | 1064 | ||
| @@ -1068,11 +1084,26 @@ EXPORT_SYMBOL(mod_timer_pending); | |||
| 1068 | */ | 1084 | */ |
| 1069 | int mod_timer(struct timer_list *timer, unsigned long expires) | 1085 | int mod_timer(struct timer_list *timer, unsigned long expires) |
| 1070 | { | 1086 | { |
| 1071 | return __mod_timer(timer, expires, false); | 1087 | return __mod_timer(timer, expires, 0); |
| 1072 | } | 1088 | } |
| 1073 | EXPORT_SYMBOL(mod_timer); | 1089 | EXPORT_SYMBOL(mod_timer); |
| 1074 | 1090 | ||
| 1075 | /** | 1091 | /** |
| 1092 | * timer_reduce - Modify a timer's timeout if it would reduce the timeout | ||
| 1093 | * @timer: The timer to be modified | ||
| 1094 | * @expires: New timeout in jiffies | ||
| 1095 | * | ||
| 1096 | * timer_reduce() is very similar to mod_timer(), except that it will only | ||
| 1097 | * modify a running timer if that would reduce the expiration time (it will | ||
| 1098 | * start a timer that isn't running). | ||
| 1099 | */ | ||
| 1100 | int timer_reduce(struct timer_list *timer, unsigned long expires) | ||
| 1101 | { | ||
| 1102 | return __mod_timer(timer, expires, MOD_TIMER_REDUCE); | ||
| 1103 | } | ||
| 1104 | EXPORT_SYMBOL(timer_reduce); | ||
| 1105 | |||
| 1106 | /** | ||
| 1076 | * add_timer - start a timer | 1107 | * add_timer - start a timer |
| 1077 | * @timer: the timer to be added | 1108 | * @timer: the timer to be added |
| 1078 | * | 1109 | * |
| @@ -1560,8 +1591,11 @@ static int collect_expired_timers(struct timer_base *base, | |||
| 1560 | * jiffies, otherwise forward to the next expiry time: | 1591 | * jiffies, otherwise forward to the next expiry time: |
| 1561 | */ | 1592 | */ |
| 1562 | if (time_after(next, jiffies)) { | 1593 | if (time_after(next, jiffies)) { |
| 1563 | /* The call site will increment clock! */ | 1594 | /* |
| 1564 | base->clk = jiffies - 1; | 1595 | * The call site will increment base->clk and then |
| 1596 | * terminate the expiry loop immediately. | ||
| 1597 | */ | ||
| 1598 | base->clk = jiffies; | ||
| 1565 | return 0; | 1599 | return 0; |
| 1566 | } | 1600 | } |
| 1567 | base->clk = next; | 1601 | base->clk = next; |
| @@ -1668,9 +1702,20 @@ void run_local_timers(void) | |||
| 1668 | raise_softirq(TIMER_SOFTIRQ); | 1702 | raise_softirq(TIMER_SOFTIRQ); |
| 1669 | } | 1703 | } |
| 1670 | 1704 | ||
| 1671 | static void process_timeout(unsigned long __data) | 1705 | /* |
| 1706 | * Since schedule_timeout()'s timer is defined on the stack, it must store | ||
| 1707 | * the target task on the stack as well. | ||
| 1708 | */ | ||
| 1709 | struct process_timer { | ||
| 1710 | struct timer_list timer; | ||
| 1711 | struct task_struct *task; | ||
| 1712 | }; | ||
| 1713 | |||
| 1714 | static void process_timeout(struct timer_list *t) | ||
| 1672 | { | 1715 | { |
| 1673 | wake_up_process((struct task_struct *)__data); | 1716 | struct process_timer *timeout = from_timer(timeout, t, timer); |
| 1717 | |||
| 1718 | wake_up_process(timeout->task); | ||
| 1674 | } | 1719 | } |
| 1675 | 1720 | ||
| 1676 | /** | 1721 | /** |
| @@ -1704,7 +1749,7 @@ static void process_timeout(unsigned long __data) | |||
| 1704 | */ | 1749 | */ |
| 1705 | signed long __sched schedule_timeout(signed long timeout) | 1750 | signed long __sched schedule_timeout(signed long timeout) |
| 1706 | { | 1751 | { |
| 1707 | struct timer_list timer; | 1752 | struct process_timer timer; |
| 1708 | unsigned long expire; | 1753 | unsigned long expire; |
| 1709 | 1754 | ||
| 1710 | switch (timeout) | 1755 | switch (timeout) |
| @@ -1738,13 +1783,14 @@ signed long __sched schedule_timeout(signed long timeout) | |||
| 1738 | 1783 | ||
| 1739 | expire = timeout + jiffies; | 1784 | expire = timeout + jiffies; |
| 1740 | 1785 | ||
| 1741 | setup_timer_on_stack(&timer, process_timeout, (unsigned long)current); | 1786 | timer.task = current; |
| 1742 | __mod_timer(&timer, expire, false); | 1787 | timer_setup_on_stack(&timer.timer, process_timeout, 0); |
| 1788 | __mod_timer(&timer.timer, expire, 0); | ||
| 1743 | schedule(); | 1789 | schedule(); |
| 1744 | del_singleshot_timer_sync(&timer); | 1790 | del_singleshot_timer_sync(&timer.timer); |
| 1745 | 1791 | ||
| 1746 | /* Remove the timer from the object tracker */ | 1792 | /* Remove the timer from the object tracker */ |
| 1747 | destroy_timer_on_stack(&timer); | 1793 | destroy_timer_on_stack(&timer.timer); |
| 1748 | 1794 | ||
| 1749 | timeout = expire - jiffies; | 1795 | timeout = expire - jiffies; |
| 1750 | 1796 | ||
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index a2dccfe1acec..3b67c0a0df16 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
| @@ -1493,9 +1493,9 @@ bool queue_work_on(int cpu, struct workqueue_struct *wq, | |||
| 1493 | } | 1493 | } |
| 1494 | EXPORT_SYMBOL(queue_work_on); | 1494 | EXPORT_SYMBOL(queue_work_on); |
| 1495 | 1495 | ||
| 1496 | void delayed_work_timer_fn(unsigned long __data) | 1496 | void delayed_work_timer_fn(struct timer_list *t) |
| 1497 | { | 1497 | { |
| 1498 | struct delayed_work *dwork = (struct delayed_work *)__data; | 1498 | struct delayed_work *dwork = from_timer(dwork, t, timer); |
| 1499 | 1499 | ||
| 1500 | /* should have been called from irqsafe timer with irq already off */ | 1500 | /* should have been called from irqsafe timer with irq already off */ |
| 1501 | __queue_work(dwork->cpu, dwork->wq, &dwork->work); | 1501 | __queue_work(dwork->cpu, dwork->wq, &dwork->work); |
| @@ -1509,8 +1509,7 @@ static void __queue_delayed_work(int cpu, struct workqueue_struct *wq, | |||
| 1509 | struct work_struct *work = &dwork->work; | 1509 | struct work_struct *work = &dwork->work; |
| 1510 | 1510 | ||
| 1511 | WARN_ON_ONCE(!wq); | 1511 | WARN_ON_ONCE(!wq); |
| 1512 | WARN_ON_ONCE(timer->function != delayed_work_timer_fn || | 1512 | WARN_ON_ONCE(timer->function != (TIMER_FUNC_TYPE)delayed_work_timer_fn); |
| 1513 | timer->data != (unsigned long)dwork); | ||
| 1514 | WARN_ON_ONCE(timer_pending(timer)); | 1513 | WARN_ON_ONCE(timer_pending(timer)); |
| 1515 | WARN_ON_ONCE(!list_empty(&work->entry)); | 1514 | WARN_ON_ONCE(!list_empty(&work->entry)); |
| 1516 | 1515 | ||
| @@ -1833,9 +1832,9 @@ static void destroy_worker(struct worker *worker) | |||
| 1833 | wake_up_process(worker->task); | 1832 | wake_up_process(worker->task); |
| 1834 | } | 1833 | } |
| 1835 | 1834 | ||
| 1836 | static void idle_worker_timeout(unsigned long __pool) | 1835 | static void idle_worker_timeout(struct timer_list *t) |
| 1837 | { | 1836 | { |
| 1838 | struct worker_pool *pool = (void *)__pool; | 1837 | struct worker_pool *pool = from_timer(pool, t, idle_timer); |
| 1839 | 1838 | ||
| 1840 | spin_lock_irq(&pool->lock); | 1839 | spin_lock_irq(&pool->lock); |
| 1841 | 1840 | ||
| @@ -1881,9 +1880,9 @@ static void send_mayday(struct work_struct *work) | |||
| 1881 | } | 1880 | } |
| 1882 | } | 1881 | } |
| 1883 | 1882 | ||
| 1884 | static void pool_mayday_timeout(unsigned long __pool) | 1883 | static void pool_mayday_timeout(struct timer_list *t) |
| 1885 | { | 1884 | { |
| 1886 | struct worker_pool *pool = (void *)__pool; | 1885 | struct worker_pool *pool = from_timer(pool, t, mayday_timer); |
| 1887 | struct work_struct *work; | 1886 | struct work_struct *work; |
| 1888 | 1887 | ||
| 1889 | spin_lock_irq(&pool->lock); | 1888 | spin_lock_irq(&pool->lock); |
| @@ -3236,11 +3235,9 @@ static int init_worker_pool(struct worker_pool *pool) | |||
| 3236 | INIT_LIST_HEAD(&pool->idle_list); | 3235 | INIT_LIST_HEAD(&pool->idle_list); |
| 3237 | hash_init(pool->busy_hash); | 3236 | hash_init(pool->busy_hash); |
| 3238 | 3237 | ||
| 3239 | setup_deferrable_timer(&pool->idle_timer, idle_worker_timeout, | 3238 | timer_setup(&pool->idle_timer, idle_worker_timeout, TIMER_DEFERRABLE); |
| 3240 | (unsigned long)pool); | ||
| 3241 | 3239 | ||
| 3242 | setup_timer(&pool->mayday_timer, pool_mayday_timeout, | 3240 | timer_setup(&pool->mayday_timer, pool_mayday_timeout, 0); |
| 3243 | (unsigned long)pool); | ||
| 3244 | 3241 | ||
| 3245 | mutex_init(&pool->attach_mutex); | 3242 | mutex_init(&pool->attach_mutex); |
| 3246 | INIT_LIST_HEAD(&pool->workers); | 3243 | INIT_LIST_HEAD(&pool->workers); |
| @@ -5383,11 +5380,8 @@ static void workqueue_sysfs_unregister(struct workqueue_struct *wq) { } | |||
| 5383 | */ | 5380 | */ |
| 5384 | #ifdef CONFIG_WQ_WATCHDOG | 5381 | #ifdef CONFIG_WQ_WATCHDOG |
| 5385 | 5382 | ||
| 5386 | static void wq_watchdog_timer_fn(unsigned long data); | ||
| 5387 | |||
| 5388 | static unsigned long wq_watchdog_thresh = 30; | 5383 | static unsigned long wq_watchdog_thresh = 30; |
| 5389 | static struct timer_list wq_watchdog_timer = | 5384 | static struct timer_list wq_watchdog_timer; |
| 5390 | TIMER_DEFERRED_INITIALIZER(wq_watchdog_timer_fn, 0, 0); | ||
| 5391 | 5385 | ||
| 5392 | static unsigned long wq_watchdog_touched = INITIAL_JIFFIES; | 5386 | static unsigned long wq_watchdog_touched = INITIAL_JIFFIES; |
| 5393 | static DEFINE_PER_CPU(unsigned long, wq_watchdog_touched_cpu) = INITIAL_JIFFIES; | 5387 | static DEFINE_PER_CPU(unsigned long, wq_watchdog_touched_cpu) = INITIAL_JIFFIES; |
| @@ -5401,7 +5395,7 @@ static void wq_watchdog_reset_touched(void) | |||
| 5401 | per_cpu(wq_watchdog_touched_cpu, cpu) = jiffies; | 5395 | per_cpu(wq_watchdog_touched_cpu, cpu) = jiffies; |
| 5402 | } | 5396 | } |
| 5403 | 5397 | ||
| 5404 | static void wq_watchdog_timer_fn(unsigned long data) | 5398 | static void wq_watchdog_timer_fn(struct timer_list *unused) |
| 5405 | { | 5399 | { |
| 5406 | unsigned long thresh = READ_ONCE(wq_watchdog_thresh) * HZ; | 5400 | unsigned long thresh = READ_ONCE(wq_watchdog_thresh) * HZ; |
| 5407 | bool lockup_detected = false; | 5401 | bool lockup_detected = false; |
| @@ -5503,6 +5497,7 @@ module_param_cb(watchdog_thresh, &wq_watchdog_thresh_ops, &wq_watchdog_thresh, | |||
| 5503 | 5497 | ||
| 5504 | static void wq_watchdog_init(void) | 5498 | static void wq_watchdog_init(void) |
| 5505 | { | 5499 | { |
| 5500 | timer_setup(&wq_watchdog_timer, wq_watchdog_timer_fn, TIMER_DEFERRABLE); | ||
| 5506 | wq_watchdog_set_thresh(wq_watchdog_thresh); | 5501 | wq_watchdog_set_thresh(wq_watchdog_thresh); |
| 5507 | } | 5502 | } |
| 5508 | 5503 | ||
