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 /kernel/posix-timers.c | |
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>
Diffstat (limited to 'kernel/posix-timers.c')
-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); |