Skip to content

Commit 50f53b2

Browse files
committed
posix-timers: Simplify lock/unlock_timer()
Since the integration of sigqueue into the timer struct, lock_timer() is only used in task context. So taking the lock with irqsave() is not longer required. Convert it to use spin_[un]lock_irq(). Signed-off-by: Thomas Gleixner <[email protected]> Reviewed-by: Frederic Weisbecker <[email protected]> Link: https://lore.kernel.org/all/[email protected]
1 parent a31a300 commit 50f53b2

File tree

1 file changed

+29
-41
lines changed

1 file changed

+29
-41
lines changed

kernel/time/posix-timers.c

Lines changed: 29 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,19 @@ static const struct k_clock clock_realtime, clock_monotonic;
5353
#error "SIGEV_THREAD_ID must not share bit with other SIGEV values!"
5454
#endif
5555

56-
static struct k_itimer *__lock_timer(timer_t timer_id, unsigned long *flags);
56+
static struct k_itimer *__lock_timer(timer_t timer_id);
5757

58-
#define lock_timer(tid, flags) \
59-
({ struct k_itimer *__timr; \
60-
__cond_lock(&__timr->it_lock, __timr = __lock_timer(tid, flags)); \
61-
__timr; \
58+
#define lock_timer(tid) \
59+
({ struct k_itimer *__timr; \
60+
__cond_lock(&__timr->it_lock, __timr = __lock_timer(tid)); \
61+
__timr; \
6262
})
6363

64+
static inline void unlock_timer(struct k_itimer *timr)
65+
{
66+
spin_unlock_irq(&timr->it_lock);
67+
}
68+
6469
static int hash(struct signal_struct *sig, unsigned int nr)
6570
{
6671
return hash_32(hash32_ptr(sig) ^ nr, HASH_BITS(posix_timers_hashtable));
@@ -144,11 +149,6 @@ static int posix_timer_add(struct k_itimer *timer)
144149
return -EAGAIN;
145150
}
146151

147-
static inline void unlock_timer(struct k_itimer *timr, unsigned long flags)
148-
{
149-
spin_unlock_irqrestore(&timr->it_lock, flags);
150-
}
151-
152152
static int posix_get_realtime_timespec(clockid_t which_clock, struct timespec64 *tp)
153153
{
154154
ktime_get_real_ts64(tp);
@@ -538,7 +538,7 @@ COMPAT_SYSCALL_DEFINE3(timer_create, clockid_t, which_clock,
538538
}
539539
#endif
540540

541-
static struct k_itimer *__lock_timer(timer_t timer_id, unsigned long *flags)
541+
static struct k_itimer *__lock_timer(timer_t timer_id)
542542
{
543543
struct k_itimer *timr;
544544

@@ -580,14 +580,14 @@ static struct k_itimer *__lock_timer(timer_t timer_id, unsigned long *flags)
580580
guard(rcu)();
581581
timr = posix_timer_by_id(timer_id);
582582
if (timr) {
583-
spin_lock_irqsave(&timr->it_lock, *flags);
583+
spin_lock_irq(&timr->it_lock);
584584
/*
585585
* Validate under timr::it_lock that timr::it_signal is
586586
* still valid. Pairs with #1 above.
587587
*/
588588
if (timr->it_signal == current->signal)
589589
return timr;
590-
spin_unlock_irqrestore(&timr->it_lock, *flags);
590+
spin_unlock_irq(&timr->it_lock);
591591
}
592592
return NULL;
593593
}
@@ -680,17 +680,16 @@ void common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)
680680
static int do_timer_gettime(timer_t timer_id, struct itimerspec64 *setting)
681681
{
682682
struct k_itimer *timr;
683-
unsigned long flags;
684683
int ret = 0;
685684

686-
timr = lock_timer(timer_id, &flags);
685+
timr = lock_timer(timer_id);
687686
if (!timr)
688687
return -EINVAL;
689688

690689
memset(setting, 0, sizeof(*setting));
691690
timr->kclock->timer_get(timr, setting);
692691

693-
unlock_timer(timr, flags);
692+
unlock_timer(timr);
694693
return ret;
695694
}
696695

@@ -746,15 +745,14 @@ SYSCALL_DEFINE2(timer_gettime32, timer_t, timer_id,
746745
SYSCALL_DEFINE1(timer_getoverrun, timer_t, timer_id)
747746
{
748747
struct k_itimer *timr;
749-
unsigned long flags;
750748
int overrun;
751749

752-
timr = lock_timer(timer_id, &flags);
750+
timr = lock_timer(timer_id);
753751
if (!timr)
754752
return -EINVAL;
755753

756754
overrun = timer_overrun_to_int(timr);
757-
unlock_timer(timr, flags);
755+
unlock_timer(timr);
758756

759757
return overrun;
760758
}
@@ -813,14 +811,13 @@ static void common_timer_wait_running(struct k_itimer *timer)
813811
* when the task which tries to delete or disarm the timer has preempted
814812
* the task which runs the expiry in task work context.
815813
*/
816-
static struct k_itimer *timer_wait_running(struct k_itimer *timer,
817-
unsigned long *flags)
814+
static struct k_itimer *timer_wait_running(struct k_itimer *timer)
818815
{
819816
timer_t timer_id = READ_ONCE(timer->it_id);
820817

821818
/* Prevent kfree(timer) after dropping the lock */
822819
scoped_guard (rcu) {
823-
unlock_timer(timer, *flags);
820+
unlock_timer(timer);
824821
/*
825822
* kc->timer_wait_running() might drop RCU lock. So @timer
826823
* cannot be touched anymore after the function returns!
@@ -829,7 +826,7 @@ static struct k_itimer *timer_wait_running(struct k_itimer *timer,
829826
}
830827

831828
/* Relock the timer. It might be not longer hashed. */
832-
return lock_timer(timer_id, flags);
829+
return lock_timer(timer_id);
833830
}
834831

835832
/*
@@ -889,7 +886,6 @@ static int do_timer_settime(timer_t timer_id, int tmr_flags,
889886
struct itimerspec64 *old_spec64)
890887
{
891888
struct k_itimer *timr;
892-
unsigned long flags;
893889
int error;
894890

895891
if (!timespec64_valid(&new_spec64->it_interval) ||
@@ -899,7 +895,7 @@ static int do_timer_settime(timer_t timer_id, int tmr_flags,
899895
if (old_spec64)
900896
memset(old_spec64, 0, sizeof(*old_spec64));
901897

902-
timr = lock_timer(timer_id, &flags);
898+
timr = lock_timer(timer_id);
903899
retry:
904900
if (!timr)
905901
return -EINVAL;
@@ -916,10 +912,10 @@ static int do_timer_settime(timer_t timer_id, int tmr_flags,
916912
// We already got the old time...
917913
old_spec64 = NULL;
918914
/* Unlocks and relocks the timer if it still exists */
919-
timr = timer_wait_running(timr, &flags);
915+
timr = timer_wait_running(timr);
920916
goto retry;
921917
}
922-
unlock_timer(timr, flags);
918+
unlock_timer(timr);
923919

924920
return error;
925921
}
@@ -995,10 +991,7 @@ static inline void posix_timer_cleanup_ignored(struct k_itimer *tmr)
995991
/* Delete a POSIX.1b interval timer. */
996992
SYSCALL_DEFINE1(timer_delete, timer_t, timer_id)
997993
{
998-
struct k_itimer *timer;
999-
unsigned long flags;
1000-
1001-
timer = lock_timer(timer_id, &flags);
994+
struct k_itimer *timer = lock_timer(timer_id);
1002995

1003996
retry_delete:
1004997
if (!timer)
@@ -1009,7 +1002,7 @@ SYSCALL_DEFINE1(timer_delete, timer_t, timer_id)
10091002

10101003
if (unlikely(timer->kclock->timer_del(timer) == TIMER_RETRY)) {
10111004
/* Unlocks and relocks the timer if it still exists */
1012-
timer = timer_wait_running(timer, &flags);
1005+
timer = timer_wait_running(timer);
10131006
goto retry_delete;
10141007
}
10151008

@@ -1028,7 +1021,7 @@ SYSCALL_DEFINE1(timer_delete, timer_t, timer_id)
10281021
WRITE_ONCE(timer->it_signal, NULL);
10291022
}
10301023

1031-
unlock_timer(timer, flags);
1024+
unlock_timer(timer);
10321025
posix_timer_unhash_and_free(timer);
10331026
return 0;
10341027
}
@@ -1039,12 +1032,7 @@ SYSCALL_DEFINE1(timer_delete, timer_t, timer_id)
10391032
*/
10401033
static void itimer_delete(struct k_itimer *timer)
10411034
{
1042-
unsigned long flags;
1043-
1044-
/*
1045-
* irqsave is required to make timer_wait_running() work.
1046-
*/
1047-
spin_lock_irqsave(&timer->it_lock, flags);
1035+
spin_lock_irq(&timer->it_lock);
10481036

10491037
retry_delete:
10501038
/*
@@ -1065,7 +1053,7 @@ static void itimer_delete(struct k_itimer *timer)
10651053
* do_exit() only for the last thread of the thread group.
10661054
* So no other task can access and delete that timer.
10671055
*/
1068-
if (WARN_ON_ONCE(timer_wait_running(timer, &flags) != timer))
1056+
if (WARN_ON_ONCE(timer_wait_running(timer) != timer))
10691057
return;
10701058

10711059
goto retry_delete;
@@ -1082,7 +1070,7 @@ static void itimer_delete(struct k_itimer *timer)
10821070
*/
10831071
WRITE_ONCE(timer->it_signal, NULL);
10841072

1085-
spin_unlock_irqrestore(&timer->it_lock, flags);
1073+
spin_unlock_irq(&timer->it_lock);
10861074
posix_timer_unhash_and_free(timer);
10871075
}
10881076

0 commit comments

Comments
 (0)