diff options
| author | Waiman Long <longman@redhat.com> | 2019-05-28 12:03:45 -0400 |
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2019-05-28 14:12:00 -0400 |
| commit | 5ca584d935c32906d114924dc0e1dbfcbb13fdb2 (patch) | |
| tree | 3798f09c5d4d3a4142f01a784d1a76e05d371fa2 /kernel/futex.c | |
| parent | c0090c4c85c27d1fa3d785c935501b7207cd2869 (diff) | |
futex: Consolidate duplicated timer setup code
Add a new futex_setup_timer() helper function to consolidate all the
hrtimer_sleeper setup code.
Signed-off-by: Waiman Long <longman@redhat.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Darren Hart <dvhart@infradead.org>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Link: https://lkml.kernel.org/r/20190528160345.24017-1-longman@redhat.com
Diffstat (limited to 'kernel/futex.c')
| -rw-r--r-- | kernel/futex.c | 69 |
1 files changed, 39 insertions, 30 deletions
diff --git a/kernel/futex.c b/kernel/futex.c index 2268b97d5439..49bf20a8c512 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
| @@ -484,6 +484,37 @@ enum futex_access { | |||
| 484 | }; | 484 | }; |
| 485 | 485 | ||
| 486 | /** | 486 | /** |
| 487 | * futex_setup_timer - set up the sleeping hrtimer. | ||
| 488 | * @time: ptr to the given timeout value | ||
| 489 | * @timeout: the hrtimer_sleeper structure to be set up | ||
| 490 | * @flags: futex flags | ||
| 491 | * @range_ns: optional range in ns | ||
| 492 | * | ||
| 493 | * Return: Initialized hrtimer_sleeper structure or NULL if no timeout | ||
| 494 | * value given | ||
| 495 | */ | ||
| 496 | static inline struct hrtimer_sleeper * | ||
| 497 | futex_setup_timer(ktime_t *time, struct hrtimer_sleeper *timeout, | ||
| 498 | int flags, u64 range_ns) | ||
| 499 | { | ||
| 500 | if (!time) | ||
| 501 | return NULL; | ||
| 502 | |||
| 503 | hrtimer_init_on_stack(&timeout->timer, (flags & FLAGS_CLOCKRT) ? | ||
| 504 | CLOCK_REALTIME : CLOCK_MONOTONIC, | ||
| 505 | HRTIMER_MODE_ABS); | ||
| 506 | hrtimer_init_sleeper(timeout, current); | ||
| 507 | |||
| 508 | /* | ||
| 509 | * If range_ns is 0, calling hrtimer_set_expires_range_ns() is | ||
| 510 | * effectively the same as calling hrtimer_set_expires(). | ||
| 511 | */ | ||
| 512 | hrtimer_set_expires_range_ns(&timeout->timer, *time, range_ns); | ||
| 513 | |||
| 514 | return timeout; | ||
| 515 | } | ||
| 516 | |||
| 517 | /** | ||
| 487 | * get_futex_key() - Get parameters which are the keys for a futex | 518 | * get_futex_key() - Get parameters which are the keys for a futex |
| 488 | * @uaddr: virtual address of the futex | 519 | * @uaddr: virtual address of the futex |
| 489 | * @fshared: 0 for a PROCESS_PRIVATE futex, 1 for PROCESS_SHARED | 520 | * @fshared: 0 for a PROCESS_PRIVATE futex, 1 for PROCESS_SHARED |
| @@ -2692,7 +2723,7 @@ out: | |||
| 2692 | static int futex_wait(u32 __user *uaddr, unsigned int flags, u32 val, | 2723 | static int futex_wait(u32 __user *uaddr, unsigned int flags, u32 val, |
| 2693 | ktime_t *abs_time, u32 bitset) | 2724 | ktime_t *abs_time, u32 bitset) |
| 2694 | { | 2725 | { |
| 2695 | struct hrtimer_sleeper timeout, *to = NULL; | 2726 | struct hrtimer_sleeper timeout, *to; |
| 2696 | struct restart_block *restart; | 2727 | struct restart_block *restart; |
| 2697 | struct futex_hash_bucket *hb; | 2728 | struct futex_hash_bucket *hb; |
| 2698 | struct futex_q q = futex_q_init; | 2729 | struct futex_q q = futex_q_init; |
| @@ -2702,17 +2733,8 @@ static int futex_wait(u32 __user *uaddr, unsigned int flags, u32 val, | |||
| 2702 | return -EINVAL; | 2733 | return -EINVAL; |
| 2703 | q.bitset = bitset; | 2734 | q.bitset = bitset; |
| 2704 | 2735 | ||
| 2705 | if (abs_time) { | 2736 | to = futex_setup_timer(abs_time, &timeout, flags, |
| 2706 | to = &timeout; | 2737 | current->timer_slack_ns); |
| 2707 | |||
| 2708 | hrtimer_init_on_stack(&to->timer, (flags & FLAGS_CLOCKRT) ? | ||
| 2709 | CLOCK_REALTIME : CLOCK_MONOTONIC, | ||
| 2710 | HRTIMER_MODE_ABS); | ||
| 2711 | hrtimer_init_sleeper(to, current); | ||
| 2712 | hrtimer_set_expires_range_ns(&to->timer, *abs_time, | ||
| 2713 | current->timer_slack_ns); | ||
| 2714 | } | ||
| 2715 | |||
| 2716 | retry: | 2738 | retry: |
| 2717 | /* | 2739 | /* |
| 2718 | * Prepare to wait on uaddr. On success, holds hb lock and increments | 2740 | * Prepare to wait on uaddr. On success, holds hb lock and increments |
| @@ -2792,7 +2814,7 @@ static long futex_wait_restart(struct restart_block *restart) | |||
| 2792 | static int futex_lock_pi(u32 __user *uaddr, unsigned int flags, | 2814 | static int futex_lock_pi(u32 __user *uaddr, unsigned int flags, |
| 2793 | ktime_t *time, int trylock) | 2815 | ktime_t *time, int trylock) |
| 2794 | { | 2816 | { |
| 2795 | struct hrtimer_sleeper timeout, *to = NULL; | 2817 | struct hrtimer_sleeper timeout, *to; |
| 2796 | struct futex_pi_state *pi_state = NULL; | 2818 | struct futex_pi_state *pi_state = NULL; |
| 2797 | struct rt_mutex_waiter rt_waiter; | 2819 | struct rt_mutex_waiter rt_waiter; |
| 2798 | struct futex_hash_bucket *hb; | 2820 | struct futex_hash_bucket *hb; |
| @@ -2805,13 +2827,7 @@ static int futex_lock_pi(u32 __user *uaddr, unsigned int flags, | |||
| 2805 | if (refill_pi_state_cache()) | 2827 | if (refill_pi_state_cache()) |
| 2806 | return -ENOMEM; | 2828 | return -ENOMEM; |
| 2807 | 2829 | ||
| 2808 | if (time) { | 2830 | to = futex_setup_timer(time, &timeout, FLAGS_CLOCKRT, 0); |
| 2809 | to = &timeout; | ||
| 2810 | hrtimer_init_on_stack(&to->timer, CLOCK_REALTIME, | ||
| 2811 | HRTIMER_MODE_ABS); | ||
| 2812 | hrtimer_init_sleeper(to, current); | ||
| 2813 | hrtimer_set_expires(&to->timer, *time); | ||
| 2814 | } | ||
| 2815 | 2831 | ||
| 2816 | retry: | 2832 | retry: |
| 2817 | ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q.key, FUTEX_WRITE); | 2833 | ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q.key, FUTEX_WRITE); |
| @@ -3208,7 +3224,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, | |||
| 3208 | u32 val, ktime_t *abs_time, u32 bitset, | 3224 | u32 val, ktime_t *abs_time, u32 bitset, |
| 3209 | u32 __user *uaddr2) | 3225 | u32 __user *uaddr2) |
| 3210 | { | 3226 | { |
| 3211 | struct hrtimer_sleeper timeout, *to = NULL; | 3227 | struct hrtimer_sleeper timeout, *to; |
| 3212 | struct futex_pi_state *pi_state = NULL; | 3228 | struct futex_pi_state *pi_state = NULL; |
| 3213 | struct rt_mutex_waiter rt_waiter; | 3229 | struct rt_mutex_waiter rt_waiter; |
| 3214 | struct futex_hash_bucket *hb; | 3230 | struct futex_hash_bucket *hb; |
| @@ -3225,15 +3241,8 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, | |||
| 3225 | if (!bitset) | 3241 | if (!bitset) |
| 3226 | return -EINVAL; | 3242 | return -EINVAL; |
| 3227 | 3243 | ||
| 3228 | if (abs_time) { | 3244 | to = futex_setup_timer(abs_time, &timeout, flags, |
| 3229 | to = &timeout; | 3245 | current->timer_slack_ns); |
| 3230 | hrtimer_init_on_stack(&to->timer, (flags & FLAGS_CLOCKRT) ? | ||
| 3231 | CLOCK_REALTIME : CLOCK_MONOTONIC, | ||
| 3232 | HRTIMER_MODE_ABS); | ||
| 3233 | hrtimer_init_sleeper(to, current); | ||
| 3234 | hrtimer_set_expires_range_ns(&to->timer, *abs_time, | ||
| 3235 | current->timer_slack_ns); | ||
| 3236 | } | ||
| 3237 | 3246 | ||
| 3238 | /* | 3247 | /* |
| 3239 | * The waiter is allocated on our stack, manipulated by the requeue | 3248 | * The waiter is allocated on our stack, manipulated by the requeue |
