diff options
Diffstat (limited to 'kernel/posix-timers.c')
| -rw-r--r-- | kernel/posix-timers.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index 10349d5f2ec3..6edbb2c55c22 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c | |||
| @@ -552,24 +552,22 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock, | |||
| 552 | return -EAGAIN; | 552 | return -EAGAIN; |
| 553 | 553 | ||
| 554 | spin_lock_init(&new_timer->it_lock); | 554 | spin_lock_init(&new_timer->it_lock); |
| 555 | retry: | 555 | |
| 556 | if (unlikely(!idr_pre_get(&posix_timers_id, GFP_KERNEL))) { | 556 | idr_preload(GFP_KERNEL); |
| 557 | error = -EAGAIN; | ||
| 558 | goto out; | ||
| 559 | } | ||
| 560 | spin_lock_irq(&idr_lock); | 557 | spin_lock_irq(&idr_lock); |
| 561 | error = idr_get_new(&posix_timers_id, new_timer, &new_timer_id); | 558 | error = idr_alloc(&posix_timers_id, new_timer, 0, 0, GFP_NOWAIT); |
| 562 | spin_unlock_irq(&idr_lock); | 559 | spin_unlock_irq(&idr_lock); |
| 563 | if (error) { | 560 | idr_preload_end(); |
| 564 | if (error == -EAGAIN) | 561 | if (error < 0) { |
| 565 | goto retry; | ||
| 566 | /* | 562 | /* |
| 567 | * Weird looking, but we return EAGAIN if the IDR is | 563 | * Weird looking, but we return EAGAIN if the IDR is |
| 568 | * full (proper POSIX return value for this) | 564 | * full (proper POSIX return value for this) |
| 569 | */ | 565 | */ |
| 570 | error = -EAGAIN; | 566 | if (error == -ENOSPC) |
| 567 | error = -EAGAIN; | ||
| 571 | goto out; | 568 | goto out; |
| 572 | } | 569 | } |
| 570 | new_timer_id = error; | ||
| 573 | 571 | ||
| 574 | it_id_set = IT_ID_SET; | 572 | it_id_set = IT_ID_SET; |
| 575 | new_timer->it_id = (timer_t) new_timer_id; | 573 | new_timer->it_id = (timer_t) new_timer_id; |
| @@ -639,6 +637,13 @@ static struct k_itimer *__lock_timer(timer_t timer_id, unsigned long *flags) | |||
| 639 | { | 637 | { |
| 640 | struct k_itimer *timr; | 638 | struct k_itimer *timr; |
| 641 | 639 | ||
| 640 | /* | ||
| 641 | * timer_t could be any type >= int and we want to make sure any | ||
| 642 | * @timer_id outside positive int range fails lookup. | ||
| 643 | */ | ||
| 644 | if ((unsigned long long)timer_id > INT_MAX) | ||
| 645 | return NULL; | ||
| 646 | |||
| 642 | rcu_read_lock(); | 647 | rcu_read_lock(); |
| 643 | timr = idr_find(&posix_timers_id, (int)timer_id); | 648 | timr = idr_find(&posix_timers_id, (int)timer_id); |
| 644 | if (timr) { | 649 | if (timr) { |
