diff options
| author | Oleg Nesterov <oleg@tv-sign.ru> | 2008-12-01 17:18:15 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-12-12 11:00:34 -0500 |
| commit | 899921025b406a71a8aeb2d7855658ea0cf0ed23 (patch) | |
| tree | 6faf12eb15231b6a430d0e1e11a4f6fcc581874e | |
| parent | 27af4245b6ce99e08c6a7c38825383bf51119cc9 (diff) | |
posix-timers: check ->it_signal instead of ->it_pid to validate the timer
Impact: clean up, speed up
->it_pid (was ->it_process) has also a special meaning: if it is NULL,
the timer is under deletion or it wasn't initialized yet. We can check
->it_signal != NULL instead, this way we can
- simplify sys_timer_create() a bit
- remove yet another check from lock_timer()
- move put_pid(->it_pid) into release_posix_timer() which
runs outside of ->it_lock
Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
| -rw-r--r-- | kernel/posix-timers.c | 17 |
1 files changed, 7 insertions, 10 deletions
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index 42a39afd694a..aa922bbb6403 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c | |||
| @@ -464,6 +464,7 @@ static void release_posix_timer(struct k_itimer *tmr, int it_id_set) | |||
| 464 | idr_remove(&posix_timers_id, tmr->it_id); | 464 | idr_remove(&posix_timers_id, tmr->it_id); |
| 465 | spin_unlock_irqrestore(&idr_lock, flags); | 465 | spin_unlock_irqrestore(&idr_lock, flags); |
| 466 | } | 466 | } |
| 467 | put_pid(tmr->it_pid); | ||
| 467 | sigqueue_free(tmr->sigq); | 468 | sigqueue_free(tmr->sigq); |
| 468 | kmem_cache_free(posix_timers_cache, tmr); | 469 | kmem_cache_free(posix_timers_cache, tmr); |
| 469 | } | 470 | } |
| @@ -477,7 +478,6 @@ sys_timer_create(const clockid_t which_clock, | |||
| 477 | { | 478 | { |
| 478 | struct k_itimer *new_timer; | 479 | struct k_itimer *new_timer; |
| 479 | int error, new_timer_id; | 480 | int error, new_timer_id; |
| 480 | struct pid *it_pid; | ||
| 481 | sigevent_t event; | 481 | sigevent_t event; |
| 482 | int it_id_set = IT_ID_NOT_SET; | 482 | int it_id_set = IT_ID_NOT_SET; |
| 483 | 483 | ||
| @@ -531,9 +531,9 @@ sys_timer_create(const clockid_t which_clock, | |||
| 531 | goto out; | 531 | goto out; |
| 532 | } | 532 | } |
| 533 | rcu_read_lock(); | 533 | rcu_read_lock(); |
| 534 | it_pid = get_pid(good_sigevent(&event)); | 534 | new_timer->it_pid = get_pid(good_sigevent(&event)); |
| 535 | rcu_read_unlock(); | 535 | rcu_read_unlock(); |
| 536 | if (!it_pid) { | 536 | if (!new_timer->it_pid) { |
| 537 | error = -EINVAL; | 537 | error = -EINVAL; |
| 538 | goto out; | 538 | goto out; |
| 539 | } | 539 | } |
| @@ -541,7 +541,7 @@ sys_timer_create(const clockid_t which_clock, | |||
| 541 | event.sigev_notify = SIGEV_SIGNAL; | 541 | event.sigev_notify = SIGEV_SIGNAL; |
| 542 | event.sigev_signo = SIGALRM; | 542 | event.sigev_signo = SIGALRM; |
| 543 | event.sigev_value.sival_int = new_timer->it_id; | 543 | event.sigev_value.sival_int = new_timer->it_id; |
| 544 | it_pid = get_pid(task_tgid(current)); | 544 | new_timer->it_pid = get_pid(task_tgid(current)); |
| 545 | } | 545 | } |
| 546 | 546 | ||
| 547 | new_timer->it_sigev_notify = event.sigev_notify; | 547 | new_timer->it_sigev_notify = event.sigev_notify; |
| @@ -551,7 +551,6 @@ sys_timer_create(const clockid_t which_clock, | |||
| 551 | new_timer->sigq->info.si_code = SI_TIMER; | 551 | new_timer->sigq->info.si_code = SI_TIMER; |
| 552 | 552 | ||
| 553 | spin_lock_irq(¤t->sighand->siglock); | 553 | spin_lock_irq(¤t->sighand->siglock); |
| 554 | new_timer->it_pid = it_pid; | ||
| 555 | new_timer->it_signal = current->signal; | 554 | new_timer->it_signal = current->signal; |
| 556 | list_add(&new_timer->list, ¤t->signal->posix_timers); | 555 | list_add(&new_timer->list, ¤t->signal->posix_timers); |
| 557 | spin_unlock_irq(¤t->sighand->siglock); | 556 | spin_unlock_irq(¤t->sighand->siglock); |
| @@ -587,7 +586,7 @@ static struct k_itimer *lock_timer(timer_t timer_id, unsigned long *flags) | |||
| 587 | timr = idr_find(&posix_timers_id, (int)timer_id); | 586 | timr = idr_find(&posix_timers_id, (int)timer_id); |
| 588 | if (timr) { | 587 | if (timr) { |
| 589 | spin_lock(&timr->it_lock); | 588 | spin_lock(&timr->it_lock); |
| 590 | if (timr->it_pid && timr->it_signal == current->signal) { | 589 | if (timr->it_signal == current->signal) { |
| 591 | spin_unlock(&idr_lock); | 590 | spin_unlock(&idr_lock); |
| 592 | return timr; | 591 | return timr; |
| 593 | } | 592 | } |
| @@ -834,8 +833,7 @@ retry_delete: | |||
| 834 | * This keeps any tasks waiting on the spin lock from thinking | 833 | * This keeps any tasks waiting on the spin lock from thinking |
| 835 | * they got something (see the lock code above). | 834 | * they got something (see the lock code above). |
| 836 | */ | 835 | */ |
| 837 | put_pid(timer->it_pid); | 836 | timer->it_signal = NULL; |
| 838 | timer->it_pid = NULL; | ||
| 839 | 837 | ||
| 840 | unlock_timer(timer, flags); | 838 | unlock_timer(timer, flags); |
| 841 | release_posix_timer(timer, IT_ID_SET); | 839 | release_posix_timer(timer, IT_ID_SET); |
| @@ -861,8 +859,7 @@ retry_delete: | |||
| 861 | * This keeps any tasks waiting on the spin lock from thinking | 859 | * This keeps any tasks waiting on the spin lock from thinking |
| 862 | * they got something (see the lock code above). | 860 | * they got something (see the lock code above). |
| 863 | */ | 861 | */ |
| 864 | put_pid(timer->it_pid); | 862 | timer->it_signal = NULL; |
| 865 | timer->it_pid = NULL; | ||
| 866 | 863 | ||
| 867 | unlock_timer(timer, flags); | 864 | unlock_timer(timer, flags); |
| 868 | release_posix_timer(timer, IT_ID_SET); | 865 | release_posix_timer(timer, IT_ID_SET); |
