| .. | .. |
|---|
| 463 | 463 | |
|---|
| 464 | 464 | static void k_itimer_rcu_free(struct rcu_head *head) |
|---|
| 465 | 465 | { |
|---|
| 466 | | - struct k_itimer *tmr = container_of(head, struct k_itimer, it.rcu); |
|---|
| 466 | + struct k_itimer *tmr = container_of(head, struct k_itimer, rcu); |
|---|
| 467 | 467 | |
|---|
| 468 | 468 | kmem_cache_free(posix_timers_cache, tmr); |
|---|
| 469 | 469 | } |
|---|
| .. | .. |
|---|
| 480 | 480 | } |
|---|
| 481 | 481 | put_pid(tmr->it_pid); |
|---|
| 482 | 482 | sigqueue_free(tmr->sigq); |
|---|
| 483 | | - call_rcu(&tmr->it.rcu, k_itimer_rcu_free); |
|---|
| 483 | + call_rcu(&tmr->rcu, k_itimer_rcu_free); |
|---|
| 484 | 484 | } |
|---|
| 485 | 485 | |
|---|
| 486 | 486 | static int common_timer_create(struct k_itimer *new_timer) |
|---|
| .. | .. |
|---|
| 826 | 826 | return hrtimer_try_to_cancel(&timr->it.real.timer); |
|---|
| 827 | 827 | } |
|---|
| 828 | 828 | |
|---|
| 829 | +static void timer_wait_for_callback(const struct k_clock *kc, struct k_itimer *timer) |
|---|
| 830 | +{ |
|---|
| 831 | + if (kc->timer_arm == common_hrtimer_arm) |
|---|
| 832 | + hrtimer_grab_expiry_lock(&timer->it.real.timer); |
|---|
| 833 | + else if (kc == &alarm_clock) |
|---|
| 834 | + hrtimer_grab_expiry_lock(&timer->it.alarm.alarmtimer.timer); |
|---|
| 835 | + else |
|---|
| 836 | + /* posix-cpu-timers */ |
|---|
| 837 | + cpu_timers_grab_expiry_lock(timer); |
|---|
| 838 | +} |
|---|
| 839 | + |
|---|
| 829 | 840 | /* Set a POSIX.1b interval timer. */ |
|---|
| 830 | 841 | int common_timer_set(struct k_itimer *timr, int flags, |
|---|
| 831 | 842 | struct itimerspec64 *new_setting, |
|---|
| .. | .. |
|---|
| 891 | 902 | else |
|---|
| 892 | 903 | error = kc->timer_set(timr, flags, new_spec64, old_spec64); |
|---|
| 893 | 904 | |
|---|
| 894 | | - unlock_timer(timr, flag); |
|---|
| 895 | 905 | if (error == TIMER_RETRY) { |
|---|
| 906 | + rcu_read_lock(); |
|---|
| 907 | + unlock_timer(timr, flag); |
|---|
| 908 | + timer_wait_for_callback(kc, timr); |
|---|
| 909 | + rcu_read_unlock(); |
|---|
| 896 | 910 | old_spec64 = NULL; // We already got the old time... |
|---|
| 897 | 911 | goto retry; |
|---|
| 898 | 912 | } |
|---|
| 913 | + unlock_timer(timr, flag); |
|---|
| 899 | 914 | |
|---|
| 900 | 915 | return error; |
|---|
| 901 | 916 | } |
|---|
| .. | .. |
|---|
| 957 | 972 | return 0; |
|---|
| 958 | 973 | } |
|---|
| 959 | 974 | |
|---|
| 960 | | -static inline int timer_delete_hook(struct k_itimer *timer) |
|---|
| 975 | +static int timer_delete_hook(struct k_itimer *timer) |
|---|
| 961 | 976 | { |
|---|
| 962 | 977 | const struct k_clock *kc = timer->kclock; |
|---|
| 978 | + int ret; |
|---|
| 963 | 979 | |
|---|
| 964 | 980 | if (WARN_ON_ONCE(!kc || !kc->timer_del)) |
|---|
| 965 | 981 | return -EINVAL; |
|---|
| 966 | | - return kc->timer_del(timer); |
|---|
| 982 | + ret = kc->timer_del(timer); |
|---|
| 983 | + if (ret == TIMER_RETRY) { |
|---|
| 984 | + rcu_read_lock(); |
|---|
| 985 | + spin_unlock_irq(&timer->it_lock); |
|---|
| 986 | + timer_wait_for_callback(kc, timer); |
|---|
| 987 | + rcu_read_unlock(); |
|---|
| 988 | + } |
|---|
| 989 | + return ret; |
|---|
| 967 | 990 | } |
|---|
| 968 | 991 | |
|---|
| 969 | 992 | /* Delete a POSIX.1b interval timer. */ |
|---|
| .. | .. |
|---|
| 977 | 1000 | if (!timer) |
|---|
| 978 | 1001 | return -EINVAL; |
|---|
| 979 | 1002 | |
|---|
| 980 | | - if (timer_delete_hook(timer) == TIMER_RETRY) { |
|---|
| 981 | | - unlock_timer(timer, flags); |
|---|
| 1003 | + if (timer_delete_hook(timer) == TIMER_RETRY) |
|---|
| 982 | 1004 | goto retry_delete; |
|---|
| 983 | | - } |
|---|
| 984 | 1005 | |
|---|
| 985 | 1006 | spin_lock(¤t->sighand->siglock); |
|---|
| 986 | 1007 | list_del(&timer->list); |
|---|
| .. | .. |
|---|
| 1006 | 1027 | retry_delete: |
|---|
| 1007 | 1028 | spin_lock_irqsave(&timer->it_lock, flags); |
|---|
| 1008 | 1029 | |
|---|
| 1009 | | - if (timer_delete_hook(timer) == TIMER_RETRY) { |
|---|
| 1010 | | - unlock_timer(timer, flags); |
|---|
| 1030 | + if (timer_delete_hook(timer) == TIMER_RETRY) |
|---|
| 1011 | 1031 | goto retry_delete; |
|---|
| 1012 | | - } |
|---|
| 1032 | + |
|---|
| 1013 | 1033 | list_del(&timer->list); |
|---|
| 1014 | 1034 | /* |
|---|
| 1015 | 1035 | * This keeps any tasks waiting on the spin lock from thinking |
|---|