Skip to content

Commit feb864e

Browse files
edumazetKAGA-KOKO
authored andcommitted
posix-timers: Make signal_struct:: Next_posix_timer_id an atomic_t
The global hash_lock protecting the posix timer hash table can be heavily contended especially when there is an extensive linear search for a timer ID. Timer IDs are handed out by monotonically increasing next_posix_timer_id and then validating that there is no timer with the same ID in the hash table. Both operations happen with the global hash lock held. To reduce the hash lock contention the hash will be reworked to a scaled hash with per bucket locks, which requires to handle the ID counter lockless. Prepare for this by making next_posix_timer_id an atomic_t, which can be used lockless with atomic_inc_return(). [ tglx: Adopted from Eric's series, massaged change log and simplified it ] Signed-off-by: Eric Dumazet <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Reviewed-by: Frederic Weisbecker <[email protected]> Acked-by: Frederic Weisbecker <[email protected]> Link: https://lore.kernel.org/all/[email protected] Link: https://lore.kernel.org/all/[email protected]
1 parent 538d710 commit feb864e

File tree

2 files changed

+6
-10
lines changed

2 files changed

+6
-10
lines changed

include/linux/sched/signal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ struct signal_struct {
136136
#ifdef CONFIG_POSIX_TIMERS
137137

138138
/* POSIX.1b Interval Timers */
139-
unsigned int next_posix_timer_id;
139+
atomic_t next_posix_timer_id;
140140
struct hlist_head posix_timers;
141141
struct hlist_head ignored_posix_timers;
142142

kernel/time/posix-timers.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,21 +119,17 @@ static bool posix_timer_hashed(struct hlist_head *head, struct signal_struct *si
119119
static int posix_timer_add(struct k_itimer *timer)
120120
{
121121
struct signal_struct *sig = current->signal;
122-
struct hlist_head *head;
123-
unsigned int cnt, id;
124122

125123
/*
126124
* FIXME: Replace this by a per signal struct xarray once there is
127125
* a plan to handle the resulting CRIU regression gracefully.
128126
*/
129-
for (cnt = 0; cnt <= INT_MAX; cnt++) {
130-
spin_lock(&hash_lock);
131-
id = sig->next_posix_timer_id;
132-
133-
/* Write the next ID back. Clamp it to the positive space */
134-
sig->next_posix_timer_id = (id + 1) & INT_MAX;
127+
for (unsigned int cnt = 0; cnt <= INT_MAX; cnt++) {
128+
/* Get the next timer ID and clamp it to positive space */
129+
unsigned int id = atomic_fetch_inc(&sig->next_posix_timer_id) & INT_MAX;
130+
struct hlist_head *head = &posix_timers_hashtable[hash(sig, id)];
135131

136-
head = &posix_timers_hashtable[hash(sig, id)];
132+
spin_lock(&hash_lock);
137133
if (!posix_timer_hashed(head, sig, id)) {
138134
/*
139135
* Set the timer ID and the signal pointer to make

0 commit comments

Comments
 (0)