Messages in this thread Patch in this message | | | Date | Mon, 19 Aug 2019 16:31:44 +0200 | From | Thomas Gleixner <> | Subject | [patch 03/44] posix-timer: Use a callback for cancel synchronization |
| |
Cleanup timer_wait_running() by using a kclock callback. Get's rid of the ifdeffery and the odd conditionals. Should have thought about this right away.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- kernel/time/alarmtimer.c | 14 ++++++++++++++ kernel/time/posix-timers.c | 32 ++++++++++++-------------------- kernel/time/posix-timers.h | 1 + 3 files changed, 27 insertions(+), 20 deletions(-)
--- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -606,6 +606,19 @@ static int alarm_timer_try_to_cancel(str } /** + * alarm_timer_wait_running - Posix timer callback to wait for a timer + * @timr: Pointer to the posixtimer data struct + * + * Called from the core code when timer cancel detected that the callback + * is running. @timr is unlocked and rcu read lock is held to prevent it + * from being freed. + */ +static void alarm_timer_wait_running(struct k_itimer *timr) +{ + hrtimer_cancel_wait_running(&timr->it.alarm.alarmtimer.timer); +} + +/** * alarm_timer_arm - Posix timer callback to arm a timer * @timr: Pointer to the posixtimer data struct * @expires: The new expiry time @@ -834,6 +847,7 @@ const struct k_clock alarm_clock = { .timer_forward = alarm_timer_forward, .timer_remaining = alarm_timer_remaining, .timer_try_to_cancel = alarm_timer_try_to_cancel, + .timer_wait_running = alarm_timer_wait_running, .nsleep = alarm_timer_nsleep, }; #endif /* CONFIG_POSIX_TIMERS */ --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -805,7 +805,11 @@ static int common_hrtimer_try_to_cancel( return hrtimer_try_to_cancel(&timr->it.real.timer); } -#ifdef CONFIG_PREEMPT_RT +static void common_timer_wait_running(struct k_itimer *timer) +{ + hrtimer_cancel_wait_running(&timer->it.real.timer); +} + static struct k_itimer *timer_wait_running(struct k_itimer *timer, unsigned long *flags) { @@ -816,29 +820,13 @@ static struct k_itimer *timer_wait_runni rcu_read_lock(); unlock_timer(timer, *flags); - if (kc->timer_arm == common_hrtimer_arm) - hrtimer_cancel_wait_running(&timer->it.real.timer); - else if (kc == &alarm_clock) - hrtimer_cancel_wait_running(&timer->it.alarm.alarmtimer.timer); - else - WARN_ON_ONCE(1); - rcu_read_unlock(); - - /* Relock the timer. It might be not longer hashed. */ - return lock_timer(timer_id, flags); -} -#else -static struct k_itimer *timer_wait_running(struct k_itimer *timer, - unsigned long *flags) -{ - timer_t timer_id = READ_ONCE(timer->it_id); + if (!WARN_ON_ONCE(kc->timer_wait_running)) + kc->timer_wait_running(timer); - unlock_timer(timer, *flags); - cpu_relax(); + rcu_read_unlock(); /* Relock the timer. It might be not longer hashed. */ return lock_timer(timer_id, flags); } -#endif /* Set a POSIX.1b interval timer. */ int common_timer_set(struct k_itimer *timr, int flags, @@ -1279,6 +1267,7 @@ static const struct k_clock clock_realti .timer_forward = common_hrtimer_forward, .timer_remaining = common_hrtimer_remaining, .timer_try_to_cancel = common_hrtimer_try_to_cancel, + .timer_wait_running = common_timer_wait_running, .timer_arm = common_hrtimer_arm, }; @@ -1294,6 +1283,7 @@ static const struct k_clock clock_monoto .timer_forward = common_hrtimer_forward, .timer_remaining = common_hrtimer_remaining, .timer_try_to_cancel = common_hrtimer_try_to_cancel, + .timer_wait_running = common_timer_wait_running, .timer_arm = common_hrtimer_arm, }; @@ -1324,6 +1314,7 @@ static const struct k_clock clock_tai = .timer_forward = common_hrtimer_forward, .timer_remaining = common_hrtimer_remaining, .timer_try_to_cancel = common_hrtimer_try_to_cancel, + .timer_wait_running = common_timer_wait_running, .timer_arm = common_hrtimer_arm, }; @@ -1339,6 +1330,7 @@ static const struct k_clock clock_bootti .timer_forward = common_hrtimer_forward, .timer_remaining = common_hrtimer_remaining, .timer_try_to_cancel = common_hrtimer_try_to_cancel, + .timer_wait_running = common_timer_wait_running, .timer_arm = common_hrtimer_arm, }; --- a/kernel/time/posix-timers.h +++ b/kernel/time/posix-timers.h @@ -24,6 +24,7 @@ struct k_clock { int (*timer_try_to_cancel)(struct k_itimer *timr); void (*timer_arm)(struct k_itimer *timr, ktime_t expires, bool absolute, bool sigev_none); + void (*timer_wait_running)(struct k_itimer *timr); }; extern const struct k_clock clock_posix_cpu;
| |