All of lore.kernel.org
 help / color / mirror / Atom feed
From: Waiman Long <Waiman.Long@hpe.com>
To: Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Jonathan Corbet <corbet@lwn.net>
Cc: linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org,
	Davidlohr Bueso <dave@stgolabs.net>,
	Jason Low <jason.low2@hpe.com>,
	Scott J Norton <scott.norton@hpe.com>,
	Douglas Hatch <doug.hatch@hpe.com>,
	Waiman Long <Waiman.Long@hpe.com>
Subject: [RFC PATCH v2 4/5] futex: Add timeout support to TO futexes
Date: Tue, 20 Sep 2016 09:42:42 -0400	[thread overview]
Message-ID: <1474378963-15496-5-git-send-email-Waiman.Long@hpe.com> (raw)
In-Reply-To: <1474378963-15496-1-git-send-email-Waiman.Long@hpe.com>

This patch adds the timeout support in other futex types to TO
futexes. However, the timeout isn't as precise as the other futex
types due to the fact timer expiration can't currently be detected
when the thread is waiting in the serialization mutex.

Signed-off-by: Waiman Long <Waiman.Long@hpe.com>
---
 kernel/futex.c |   40 +++++++++++++++++++++++++++++++---------
 1 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/kernel/futex.c b/kernel/futex.c
index 7daba56..c73be79 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -3423,7 +3423,8 @@ static inline int futex_set_waiters_unlocked(u32 __user *uaddr, u32 *puval)
  * Return: 0 if futex acquired, < 0 if an error happens.
  */
 static int futex_spin_on_owner(u32 __user *uaddr, u32 vpid,
-			       struct futex_state *state)
+			       struct futex_state *state,
+			       struct hrtimer_sleeper *timeout)
 {
 	int ret, loop = TO_SPIN_THRESHOLD;
 	u32 uval, curval;
@@ -3483,8 +3484,11 @@ static int futex_spin_on_owner(u32 __user *uaddr, u32 vpid,
 			continue;
 		}
 
-		/* Check for signal */
-		if (signal_pending(current)) {
+		/* Check for timeout & signal */
+		if (timeout && !timeout->task) {
+			ret = -ETIMEDOUT;
+			break;
+		} else if (signal_pending(current)) {
 			ret = -EINTR;
 			break;
 		}
@@ -3594,6 +3598,12 @@ efault:
  * This function is not inlined so that it can show up in stack trace for
  * analysis purpose.
  *
+ * The timeout functionality isn't as precise as other other futex types
+ * as timer expiration will not be detected while waiting in the
+ * serialization mutex. One possible solution is to modify the expiration
+ * function to send out a signal as well so as to break the thread out of
+ * the mutex code if we really want more precise timeout.
+ *
  * Return:
  *  < 0 - an error happens
  *  0   - acquires the lock via futex_spin_on_owner()
@@ -3601,8 +3611,9 @@ efault:
  *  2   - lock handed off from unlocker
  */
 static noinline int
-futex_lock_to(u32 __user *uaddr, unsigned int flags)
+futex_lock_to(u32 __user *uaddr, unsigned int flags, ktime_t *time)
 {
+	struct hrtimer_sleeper timeout, *to = NULL;
 	struct futex_hash_bucket *hb;
 	union futex_key key = FUTEX_KEY_INIT;
 	struct futex_state *state;
@@ -3627,6 +3638,8 @@ futex_lock_to(u32 __user *uaddr, unsigned int flags)
 	if (refill_futex_state_cache())
 		return -ENOMEM;
 
+	futex_set_timer(time, &to, &timeout, flags, current->timer_slack_ns);
+
 	ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key, VERIFY_WRITE);
 	if (unlikely(ret))
 		goto out;
@@ -3651,10 +3664,15 @@ futex_lock_to(u32 __user *uaddr, unsigned int flags)
 	/*
 	 * Acquiring the serialization mutex.
 	 */
-	if (state->type != TYPE_TO)
+	if (state->type != TYPE_TO) {
 		ret = -EINVAL;
-	else
+	} else {
+		if (to)
+			hrtimer_start_expires(&to->timer, HRTIMER_MODE_ABS);
 		ret = mutex_lock_interruptible(&state->mutex);
+		if (ret && to && !timeout.task)
+			ret = -ETIMEDOUT;
+	}
 
 	if (unlikely(ret))
 		/*
@@ -3667,7 +3685,7 @@ futex_lock_to(u32 __user *uaddr, unsigned int flags)
 	 * As the mutex owner, we can now spin on the futex word as well as
 	 * the active-ness of the futex owner.
 	 */
-	ret = futex_spin_on_owner(uaddr, vpid, state);
+	ret = futex_spin_on_owner(uaddr, vpid, state, to ? &timeout : NULL);
 
 	mutex_unlock(&state->mutex);
 
@@ -3684,6 +3702,10 @@ out_put_state_key:
 	put_futex_key(&key);
 
 out:
+	if (to) {
+		hrtimer_cancel(&to->timer);
+		destroy_hrtimer_on_stack(&to->timer);
+	}
 	return ret;
 }
 
@@ -3831,7 +3853,7 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
 		return futex_requeue(uaddr, flags, uaddr2, val, val2, &val3, 1);
 #ifdef CONFIG_SMP
 	case FUTEX_LOCK_TO:
-		return futex_lock_to(uaddr, flags);
+		return futex_lock_to(uaddr, flags, timeout);
 	case FUTEX_UNLOCK_TO:
 		return futex_unlock_to(uaddr, flags);
 #endif
@@ -3850,7 +3872,7 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val,
 	int cmd = op & FUTEX_CMD_MASK;
 
 	if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI ||
-		      cmd == FUTEX_WAIT_BITSET ||
+		      cmd == FUTEX_WAIT_BITSET || cmd == FUTEX_LOCK_TO ||
 		      cmd == FUTEX_WAIT_REQUEUE_PI)) {
 		if (unlikely(should_fail_futex(!(op & FUTEX_PRIVATE_FLAG))))
 			return -EFAULT;
-- 
1.7.1

  parent reply	other threads:[~2016-09-20 13:44 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-20 13:42 [RFC PATCH v2 0/5] futex: Introducing throughput-optimized futexes Waiman Long
2016-09-20 13:42 ` [RFC PATCH v2 1/5] futex: Add futex_set_timer() helper function Waiman Long
2016-09-22 21:31   ` Thomas Gleixner
2016-09-23  0:45     ` Waiman Long
2016-09-20 13:42 ` [RFC PATCH v2 2/5] futex: Rename futex_pi_state to futex_state Waiman Long
2016-09-20 13:42 ` [RFC PATCH v2 3/5] futex: Throughput-optimized (TO) futexes Waiman Long
2016-09-21  6:59   ` Mike Galbraith
2016-09-21 23:37     ` Waiman Long
2016-09-22  7:49       ` Peter Zijlstra
2016-09-22 13:04         ` Waiman Long
2016-09-22 13:34         ` Thomas Gleixner
2016-09-22 14:41           ` Davidlohr Bueso
2016-09-22 14:46             ` Thomas Gleixner
2016-09-22 15:11               ` Davidlohr Bueso
2016-09-22 20:08                 ` Waiman Long
2016-09-22 20:28                   ` Waiman Long
2016-09-22 20:38                     ` Thomas Gleixner
2016-09-22 21:48                       ` Waiman Long
2016-09-23 13:02                         ` Thomas Gleixner
2016-09-26 22:02                           ` Waiman Long
2016-09-22 21:39                     ` Davidlohr Bueso
2016-09-22 21:41                       ` Thomas Gleixner
2016-09-22 21:59                         ` Waiman Long
2016-09-27 19:02                           ` [PATCH v2 -tip] locking/rtmutex: Reduce top-waiter blocking on a lock Davidlohr Bueso
2016-10-24 18:08                             ` Davidlohr Bueso
2016-10-24 18:48                               ` Thomas Gleixner
2016-09-24  1:28                         ` [PATCH " Davidlohr Bueso
2016-09-26 21:40                           ` Waiman Long
2016-09-22 19:56           ` [RFC PATCH v2 3/5] futex: Throughput-optimized (TO) futexes Waiman Long
2016-09-22 20:26             ` Thomas Gleixner
2016-09-22 21:13               ` Waiman Long
2016-09-22 13:23   ` Peter Zijlstra
2016-09-22 17:21     ` Waiman Long
2016-09-20 13:42 ` Waiman Long [this message]
2016-09-20 13:42 ` [RFC PATCH v2 5/5] futex, doc: TO futexes document Waiman Long

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1474378963-15496-5-git-send-email-Waiman.Long@hpe.com \
    --to=waiman.long@hpe.com \
    --cc=corbet@lwn.net \
    --cc=dave@stgolabs.net \
    --cc=doug.hatch@hpe.com \
    --cc=jason.low2@hpe.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=scott.norton@hpe.com \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.