summaryrefslogtreecommitdiffstats
path: root/kernel/time/alarmtimer.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/time/alarmtimer.c')
-rw-r--r--kernel/time/alarmtimer.c381
1 files changed, 161 insertions, 220 deletions
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index ee2f4202d82a..c991cf212c6d 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -27,6 +27,9 @@
27#include <linux/posix-timers.h> 27#include <linux/posix-timers.h>
28#include <linux/workqueue.h> 28#include <linux/workqueue.h>
29#include <linux/freezer.h> 29#include <linux/freezer.h>
30#include <linux/compat.h>
31
32#include "posix-timers.h"
30 33
31#define CREATE_TRACE_POINTS 34#define CREATE_TRACE_POINTS
32#include <trace/events/alarmtimer.h> 35#include <trace/events/alarmtimer.h>
@@ -45,11 +48,13 @@ static struct alarm_base {
45 clockid_t base_clockid; 48 clockid_t base_clockid;
46} alarm_bases[ALARM_NUMTYPE]; 49} alarm_bases[ALARM_NUMTYPE];
47 50
51#if defined(CONFIG_POSIX_TIMERS) || defined(CONFIG_RTC_CLASS)
48/* freezer information to handle clock_nanosleep triggered wakeups */ 52/* freezer information to handle clock_nanosleep triggered wakeups */
49static enum alarmtimer_type freezer_alarmtype; 53static enum alarmtimer_type freezer_alarmtype;
50static ktime_t freezer_expires; 54static ktime_t freezer_expires;
51static ktime_t freezer_delta; 55static ktime_t freezer_delta;
52static DEFINE_SPINLOCK(freezer_delta_lock); 56static DEFINE_SPINLOCK(freezer_delta_lock);
57#endif
53 58
54static struct wakeup_source *ws; 59static struct wakeup_source *ws;
55 60
@@ -307,38 +312,6 @@ static int alarmtimer_resume(struct device *dev)
307} 312}
308#endif 313#endif
309 314
310static void alarmtimer_freezerset(ktime_t absexp, enum alarmtimer_type type)
311{
312 struct alarm_base *base;
313 unsigned long flags;
314 ktime_t delta;
315
316 switch(type) {
317 case ALARM_REALTIME:
318 base = &alarm_bases[ALARM_REALTIME];
319 type = ALARM_REALTIME_FREEZER;
320 break;
321 case ALARM_BOOTTIME:
322 base = &alarm_bases[ALARM_BOOTTIME];
323 type = ALARM_BOOTTIME_FREEZER;
324 break;
325 default:
326 WARN_ONCE(1, "Invalid alarm type: %d\n", type);
327 return;
328 }
329
330 delta = ktime_sub(absexp, base->gettime());
331
332 spin_lock_irqsave(&freezer_delta_lock, flags);
333 if (!freezer_delta || (delta < freezer_delta)) {
334 freezer_delta = delta;
335 freezer_expires = absexp;
336 freezer_alarmtype = type;
337 }
338 spin_unlock_irqrestore(&freezer_delta_lock, flags);
339}
340
341
342/** 315/**
343 * alarm_init - Initialize an alarm structure 316 * alarm_init - Initialize an alarm structure
344 * @alarm: ptr to alarm to be initialized 317 * @alarm: ptr to alarm to be initialized
@@ -488,6 +461,38 @@ u64 alarm_forward_now(struct alarm *alarm, ktime_t interval)
488} 461}
489EXPORT_SYMBOL_GPL(alarm_forward_now); 462EXPORT_SYMBOL_GPL(alarm_forward_now);
490 463
464#ifdef CONFIG_POSIX_TIMERS
465
466static void alarmtimer_freezerset(ktime_t absexp, enum alarmtimer_type type)
467{
468 struct alarm_base *base;
469 unsigned long flags;
470 ktime_t delta;
471
472 switch(type) {
473 case ALARM_REALTIME:
474 base = &alarm_bases[ALARM_REALTIME];
475 type = ALARM_REALTIME_FREEZER;
476 break;
477 case ALARM_BOOTTIME:
478 base = &alarm_bases[ALARM_BOOTTIME];
479 type = ALARM_BOOTTIME_FREEZER;
480 break;
481 default:
482 WARN_ONCE(1, "Invalid alarm type: %d\n", type);
483 return;
484 }
485
486 delta = ktime_sub(absexp, base->gettime());
487
488 spin_lock_irqsave(&freezer_delta_lock, flags);
489 if (!freezer_delta || (delta < freezer_delta)) {
490 freezer_delta = delta;
491 freezer_expires = absexp;
492 freezer_alarmtype = type;
493 }
494 spin_unlock_irqrestore(&freezer_delta_lock, flags);
495}
491 496
492/** 497/**
493 * clock2alarm - helper that converts from clockid to alarmtypes 498 * clock2alarm - helper that converts from clockid to alarmtypes
@@ -511,22 +516,26 @@ static enum alarmtimer_type clock2alarm(clockid_t clockid)
511static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm, 516static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm,
512 ktime_t now) 517 ktime_t now)
513{ 518{
514 unsigned long flags;
515 struct k_itimer *ptr = container_of(alarm, struct k_itimer, 519 struct k_itimer *ptr = container_of(alarm, struct k_itimer,
516 it.alarm.alarmtimer); 520 it.alarm.alarmtimer);
517 enum alarmtimer_restart result = ALARMTIMER_NORESTART; 521 enum alarmtimer_restart result = ALARMTIMER_NORESTART;
522 unsigned long flags;
523 int si_private = 0;
518 524
519 spin_lock_irqsave(&ptr->it_lock, flags); 525 spin_lock_irqsave(&ptr->it_lock, flags);
520 if ((ptr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) {
521 if (IS_ENABLED(CONFIG_POSIX_TIMERS) &&
522 posix_timer_event(ptr, 0) != 0)
523 ptr->it_overrun++;
524 }
525 526
526 /* Re-add periodic timers */ 527 ptr->it_active = 0;
527 if (ptr->it.alarm.interval) { 528 if (ptr->it_interval)
528 ptr->it_overrun += alarm_forward(alarm, now, 529 si_private = ++ptr->it_requeue_pending;
529 ptr->it.alarm.interval); 530
531 if (posix_timer_event(ptr, si_private) && ptr->it_interval) {
532 /*
533 * Handle ignored signals and rearm the timer. This will go
534 * away once we handle ignored signals proper.
535 */
536 ptr->it_overrun += alarm_forward_now(alarm, ptr->it_interval);
537 ++ptr->it_requeue_pending;
538 ptr->it_active = 1;
530 result = ALARMTIMER_RESTART; 539 result = ALARMTIMER_RESTART;
531 } 540 }
532 spin_unlock_irqrestore(&ptr->it_lock, flags); 541 spin_unlock_irqrestore(&ptr->it_lock, flags);
@@ -535,6 +544,72 @@ static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm,
535} 544}
536 545
537/** 546/**
547 * alarm_timer_rearm - Posix timer callback for rearming timer
548 * @timr: Pointer to the posixtimer data struct
549 */
550static void alarm_timer_rearm(struct k_itimer *timr)
551{
552 struct alarm *alarm = &timr->it.alarm.alarmtimer;
553
554 timr->it_overrun += alarm_forward_now(alarm, timr->it_interval);
555 alarm_start(alarm, alarm->node.expires);
556}
557
558/**
559 * alarm_timer_forward - Posix timer callback for forwarding timer
560 * @timr: Pointer to the posixtimer data struct
561 * @now: Current time to forward the timer against
562 */
563static int alarm_timer_forward(struct k_itimer *timr, ktime_t now)
564{
565 struct alarm *alarm = &timr->it.alarm.alarmtimer;
566
567 return (int) alarm_forward(alarm, timr->it_interval, now);
568}
569
570/**
571 * alarm_timer_remaining - Posix timer callback to retrieve remaining time
572 * @timr: Pointer to the posixtimer data struct
573 * @now: Current time to calculate against
574 */
575static ktime_t alarm_timer_remaining(struct k_itimer *timr, ktime_t now)
576{
577 struct alarm *alarm = &timr->it.alarm.alarmtimer;
578
579 return ktime_sub(now, alarm->node.expires);
580}
581
582/**
583 * alarm_timer_try_to_cancel - Posix timer callback to cancel a timer
584 * @timr: Pointer to the posixtimer data struct
585 */
586static int alarm_timer_try_to_cancel(struct k_itimer *timr)
587{
588 return alarm_try_to_cancel(&timr->it.alarm.alarmtimer);
589}
590
591/**
592 * alarm_timer_arm - Posix timer callback to arm a timer
593 * @timr: Pointer to the posixtimer data struct
594 * @expires: The new expiry time
595 * @absolute: Expiry value is absolute time
596 * @sigev_none: Posix timer does not deliver signals
597 */
598static void alarm_timer_arm(struct k_itimer *timr, ktime_t expires,
599 bool absolute, bool sigev_none)
600{
601 struct alarm *alarm = &timr->it.alarm.alarmtimer;
602 struct alarm_base *base = &alarm_bases[alarm->type];
603
604 if (!absolute)
605 expires = ktime_add_safe(expires, base->gettime());
606 if (sigev_none)
607 alarm->node.expires = expires;
608 else
609 alarm_start(&timr->it.alarm.alarmtimer, expires);
610}
611
612/**
538 * alarm_clock_getres - posix getres interface 613 * alarm_clock_getres - posix getres interface
539 * @which_clock: clockid 614 * @which_clock: clockid
540 * @tp: timespec to fill 615 * @tp: timespec to fill
@@ -591,97 +666,6 @@ static int alarm_timer_create(struct k_itimer *new_timer)
591} 666}
592 667
593/** 668/**
594 * alarm_timer_get - posix timer_get interface
595 * @new_timer: k_itimer pointer
596 * @cur_setting: itimerspec data to fill
597 *
598 * Copies out the current itimerspec data
599 */
600static void alarm_timer_get(struct k_itimer *timr,
601 struct itimerspec64 *cur_setting)
602{
603 ktime_t relative_expiry_time =
604 alarm_expires_remaining(&(timr->it.alarm.alarmtimer));
605
606 if (ktime_to_ns(relative_expiry_time) > 0) {
607 cur_setting->it_value = ktime_to_timespec64(relative_expiry_time);
608 } else {
609 cur_setting->it_value.tv_sec = 0;
610 cur_setting->it_value.tv_nsec = 0;
611 }
612
613 cur_setting->it_interval = ktime_to_timespec64(timr->it.alarm.interval);
614}
615
616/**
617 * alarm_timer_del - posix timer_del interface
618 * @timr: k_itimer pointer to be deleted
619 *
620 * Cancels any programmed alarms for the given timer.
621 */
622static int alarm_timer_del(struct k_itimer *timr)
623{
624 if (!rtcdev)
625 return -ENOTSUPP;
626
627 if (alarm_try_to_cancel(&timr->it.alarm.alarmtimer) < 0)
628 return TIMER_RETRY;
629
630 return 0;
631}
632
633/**
634 * alarm_timer_set - posix timer_set interface
635 * @timr: k_itimer pointer to be deleted
636 * @flags: timer flags
637 * @new_setting: itimerspec to be used
638 * @old_setting: itimerspec being replaced
639 *
640 * Sets the timer to new_setting, and starts the timer.
641 */
642static int alarm_timer_set(struct k_itimer *timr, int flags,
643 struct itimerspec64 *new_setting,
644 struct itimerspec64 *old_setting)
645{
646 ktime_t exp;
647
648 if (!rtcdev)
649 return -ENOTSUPP;
650
651 if (flags & ~TIMER_ABSTIME)
652 return -EINVAL;
653
654 if (old_setting)
655 alarm_timer_get(timr, old_setting);
656
657 /* If the timer was already set, cancel it */
658 if (alarm_try_to_cancel(&timr->it.alarm.alarmtimer) < 0)
659 return TIMER_RETRY;
660
661 /* start the timer */
662 timr->it.alarm.interval = timespec64_to_ktime(new_setting->it_interval);
663
664 /*
665 * Rate limit to the tick as a hot fix to prevent DOS. Will be
666 * mopped up later.
667 */
668 if (timr->it.alarm.interval < TICK_NSEC)
669 timr->it.alarm.interval = TICK_NSEC;
670
671 exp = timespec64_to_ktime(new_setting->it_value);
672 /* Convert (if necessary) to absolute time */
673 if (flags != TIMER_ABSTIME) {
674 ktime_t now;
675
676 now = alarm_bases[timr->it.alarm.alarmtimer.type].gettime();
677 exp = ktime_add_safe(now, exp);
678 }
679
680 alarm_start(&timr->it.alarm.alarmtimer, exp);
681 return 0;
682}
683
684/**
685 * alarmtimer_nsleep_wakeup - Wakeup function for alarm_timer_nsleep 669 * alarmtimer_nsleep_wakeup - Wakeup function for alarm_timer_nsleep
686 * @alarm: ptr to alarm that fired 670 * @alarm: ptr to alarm that fired
687 * 671 *
@@ -705,8 +689,10 @@ static enum alarmtimer_restart alarmtimer_nsleep_wakeup(struct alarm *alarm,
705 * 689 *
706 * Sets the alarm timer and sleeps until it is fired or interrupted. 690 * Sets the alarm timer and sleeps until it is fired or interrupted.
707 */ 691 */
708static int alarmtimer_do_nsleep(struct alarm *alarm, ktime_t absexp) 692static int alarmtimer_do_nsleep(struct alarm *alarm, ktime_t absexp,
693 enum alarmtimer_type type)
709{ 694{
695 struct restart_block *restart;
710 alarm->data = (void *)current; 696 alarm->data = (void *)current;
711 do { 697 do {
712 set_current_state(TASK_INTERRUPTIBLE); 698 set_current_state(TASK_INTERRUPTIBLE);
@@ -719,36 +705,25 @@ static int alarmtimer_do_nsleep(struct alarm *alarm, ktime_t absexp)
719 705
720 __set_current_state(TASK_RUNNING); 706 __set_current_state(TASK_RUNNING);
721 707
722 return (alarm->data == NULL); 708 if (!alarm->data)
723}
724
725
726/**
727 * update_rmtp - Update remaining timespec value
728 * @exp: expiration time
729 * @type: timer type
730 * @rmtp: user pointer to remaining timepsec value
731 *
732 * Helper function that fills in rmtp value with time between
733 * now and the exp value
734 */
735static int update_rmtp(ktime_t exp, enum alarmtimer_type type,
736 struct timespec __user *rmtp)
737{
738 struct timespec rmt;
739 ktime_t rem;
740
741 rem = ktime_sub(exp, alarm_bases[type].gettime());
742
743 if (rem <= 0)
744 return 0; 709 return 0;
745 rmt = ktime_to_timespec(rem);
746 710
747 if (copy_to_user(rmtp, &rmt, sizeof(*rmtp))) 711 if (freezing(current))
748 return -EFAULT; 712 alarmtimer_freezerset(absexp, type);
713 restart = &current->restart_block;
714 if (restart->nanosleep.type != TT_NONE) {
715 struct timespec rmt;
716 ktime_t rem;
717
718 rem = ktime_sub(absexp, alarm_bases[type].gettime());
749 719
750 return 1; 720 if (rem <= 0)
721 return 0;
722 rmt = ktime_to_timespec(rem);
751 723
724 return nanosleep_copyout(restart, &rmt);
725 }
726 return -ERESTART_RESTARTBLOCK;
752} 727}
753 728
754/** 729/**
@@ -760,32 +735,12 @@ static int update_rmtp(ktime_t exp, enum alarmtimer_type type,
760static long __sched alarm_timer_nsleep_restart(struct restart_block *restart) 735static long __sched alarm_timer_nsleep_restart(struct restart_block *restart)
761{ 736{
762 enum alarmtimer_type type = restart->nanosleep.clockid; 737 enum alarmtimer_type type = restart->nanosleep.clockid;
763 ktime_t exp; 738 ktime_t exp = restart->nanosleep.expires;
764 struct timespec __user *rmtp;
765 struct alarm alarm; 739 struct alarm alarm;
766 int ret = 0;
767 740
768 exp = restart->nanosleep.expires;
769 alarm_init(&alarm, type, alarmtimer_nsleep_wakeup); 741 alarm_init(&alarm, type, alarmtimer_nsleep_wakeup);
770 742
771 if (alarmtimer_do_nsleep(&alarm, exp)) 743 return alarmtimer_do_nsleep(&alarm, exp, type);
772 goto out;
773
774 if (freezing(current))
775 alarmtimer_freezerset(exp, type);
776
777 rmtp = restart->nanosleep.rmtp;
778 if (rmtp) {
779 ret = update_rmtp(exp, type, rmtp);
780 if (ret <= 0)
781 goto out;
782 }
783
784
785 /* The other values in restart are already filled in */
786 ret = -ERESTART_RESTARTBLOCK;
787out:
788 return ret;
789} 744}
790 745
791/** 746/**
@@ -798,11 +753,10 @@ out:
798 * Handles clock_nanosleep calls against _ALARM clockids 753 * Handles clock_nanosleep calls against _ALARM clockids
799 */ 754 */
800static int alarm_timer_nsleep(const clockid_t which_clock, int flags, 755static int alarm_timer_nsleep(const clockid_t which_clock, int flags,
801 struct timespec64 *tsreq, 756 const struct timespec64 *tsreq)
802 struct timespec __user *rmtp)
803{ 757{
804 enum alarmtimer_type type = clock2alarm(which_clock); 758 enum alarmtimer_type type = clock2alarm(which_clock);
805 struct restart_block *restart; 759 struct restart_block *restart = &current->restart_block;
806 struct alarm alarm; 760 struct alarm alarm;
807 ktime_t exp; 761 ktime_t exp;
808 int ret = 0; 762 int ret = 0;
@@ -825,35 +779,36 @@ static int alarm_timer_nsleep(const clockid_t which_clock, int flags,
825 exp = ktime_add(now, exp); 779 exp = ktime_add(now, exp);
826 } 780 }
827 781
828 if (alarmtimer_do_nsleep(&alarm, exp)) 782 ret = alarmtimer_do_nsleep(&alarm, exp, type);
829 goto out; 783 if (ret != -ERESTART_RESTARTBLOCK)
830 784 return ret;
831 if (freezing(current))
832 alarmtimer_freezerset(exp, type);
833 785
834 /* abs timers don't set remaining time or restart */ 786 /* abs timers don't set remaining time or restart */
835 if (flags == TIMER_ABSTIME) { 787 if (flags == TIMER_ABSTIME)
836 ret = -ERESTARTNOHAND; 788 return -ERESTARTNOHAND;
837 goto out;
838 }
839 789
840 if (rmtp) {
841 ret = update_rmtp(exp, type, rmtp);
842 if (ret <= 0)
843 goto out;
844 }
845
846 restart = &current->restart_block;
847 restart->fn = alarm_timer_nsleep_restart; 790 restart->fn = alarm_timer_nsleep_restart;
848 restart->nanosleep.clockid = type; 791 restart->nanosleep.clockid = type;
849 restart->nanosleep.expires = exp; 792 restart->nanosleep.expires = exp;
850 restart->nanosleep.rmtp = rmtp;
851 ret = -ERESTART_RESTARTBLOCK;
852
853out:
854 return ret; 793 return ret;
855} 794}
856 795
796const struct k_clock alarm_clock = {
797 .clock_getres = alarm_clock_getres,
798 .clock_get = alarm_clock_get,
799 .timer_create = alarm_timer_create,
800 .timer_set = common_timer_set,
801 .timer_del = common_timer_del,
802 .timer_get = common_timer_get,
803 .timer_arm = alarm_timer_arm,
804 .timer_rearm = alarm_timer_rearm,
805 .timer_forward = alarm_timer_forward,
806 .timer_remaining = alarm_timer_remaining,
807 .timer_try_to_cancel = alarm_timer_try_to_cancel,
808 .nsleep = alarm_timer_nsleep,
809};
810#endif /* CONFIG_POSIX_TIMERS */
811
857 812
858/* Suspend hook structures */ 813/* Suspend hook structures */
859static const struct dev_pm_ops alarmtimer_pm_ops = { 814static const struct dev_pm_ops alarmtimer_pm_ops = {
@@ -879,23 +834,9 @@ static int __init alarmtimer_init(void)
879 struct platform_device *pdev; 834 struct platform_device *pdev;
880 int error = 0; 835 int error = 0;
881 int i; 836 int i;
882 struct k_clock alarm_clock = {
883 .clock_getres = alarm_clock_getres,
884 .clock_get = alarm_clock_get,
885 .timer_create = alarm_timer_create,
886 .timer_set = alarm_timer_set,
887 .timer_del = alarm_timer_del,
888 .timer_get = alarm_timer_get,
889 .nsleep = alarm_timer_nsleep,
890 };
891 837
892 alarmtimer_rtc_timer_init(); 838 alarmtimer_rtc_timer_init();
893 839
894 if (IS_ENABLED(CONFIG_POSIX_TIMERS)) {
895 posix_timers_register_clock(CLOCK_REALTIME_ALARM, &alarm_clock);
896 posix_timers_register_clock(CLOCK_BOOTTIME_ALARM, &alarm_clock);
897 }
898
899 /* Initialize alarm bases */ 840 /* Initialize alarm bases */
900 alarm_bases[ALARM_REALTIME].base_clockid = CLOCK_REALTIME; 841 alarm_bases[ALARM_REALTIME].base_clockid = CLOCK_REALTIME;
901 alarm_bases[ALARM_REALTIME].gettime = &ktime_get_real; 842 alarm_bases[ALARM_REALTIME].gettime = &ktime_get_real;