timer updates for 2.6.40
Linus,
Please pull the latest timers-fixes-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git timers-fixes-for-linus
Thanks,
tglx
------------------>
Eric Dumazet (1):
posix-timers: RCU conversion
include/linux/posix-timers.h | 1 + kernel/posix-timers.c | 25 ++++++++++++++----------- 2 files changed, 15 insertions(+), 11 deletions(-)
include/linux/posix-timers.h +1 -0
@@ -82,6 +82,7 @@ struct k_itimer {unsigned long expires; } mmtimer;struct alarm alarmtimer; +struct rcu_head rcu; } it; };
kernel/posix-timers.c +14 -11
@@ -491,6 +491,13 @@ static struct k_itimer * alloc_posix_timer(void)return tmr; } +static void k_itimer_rcu_free (struct rcu_head *head) +{ + struct k_itimer *tmr = container_of(head, struct k_itimer, it.rcu); + +kmem_cache_free (posix_timers_cache, tmr); +} +#define IT_ID_SET 1#define IT_ID_NOT_SET 0static void release_posix_timer (struct k_itimer *tmr,int it_id_set)
@@ -503,7 +510,7 @@ static void release_posix_timer(struct k_itimer *tmr, int it_id_set) }put_pid (tmr->it_pid);sigqueue_free (tmr->sigq); -kmem_cache_free (posix_timers_cache, tmr); +call_rcu (&tmr->it.rcu, k_itimer_rcu_free); }static struct k_clock *clockid_to_kclock (const clockid_t id)
@@ -631,22 +638,18 @@ out:static struct k_itimer *__lock_timer (timer_t timer_id,unsigned long *flags) {struct k_itimer *timr; -/* -* Watch out here. We do a irqsave on the idr_lock and pass the -* flags part over to the timer lock. Must not let interrupts in -* while we are moving the lock. -*/ -spin_lock_irqsave (&idr_lock, *flags); + +rcu_read_lock (); timr =idr_find (&posix_timers_id, (int )timer_id);if (timr) { -spin_lock (&timr->it_lock); +spin_lock_irqsave (&timr->it_lock, *flags);if (timr->it_signal == current->signal) { -spin_unlock (&idr_lock); +rcu_read_unlock ();return timr; } -spin_unlock (&timr->it_lock); +spin_unlock_irqrestore (&timr->it_lock, *flags); } -spin_unlock_irqrestore (&idr_lock, *flags); +rcu_read_unlock ();return NULL ; }