LKML Archive on lore.kernel.org
 help / color / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: LKML <linux-kernel@vger.kernel.org>
Cc: Ingo Molnar <mingo@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Steven Rostedt <rostedt@goodmis.org>,
	Lai Jiangshan <laijs@cn.fujitsu.com>
Subject: [patch 6/6] rtmutex: Avoid pointless requeueing in the deadlock detection chain walk
Date: Thu, 22 May 2014 03:25:57 -0000
Message-ID: <20140522031950.280830190@linutronix.de> (raw)
In-Reply-To: <20140522031841.797415507@linutronix.de>


[-- Attachment #0: rtmutex-avoid-pointless-requeueing.patch --]
[-- Type: text/plain, Size: 4631 bytes --]

In case the dead lock detector is enabled we follow the lock chain to
the end in rt_mutex_adjust_prio_chain, even if we could stop earlier
due to the priority/waiter constellation.

But once we are not longer the top priority waiter in a certain step
or the task holding the lock has already the same priority then there
is no point in dequeing and enqueing along the lock chain as there is
no change at all.

So stop the queueing at this point.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/locking/rtmutex.c |   87 +++++++++++++++++++++++++++++------------------
 1 file changed, 54 insertions(+), 33 deletions(-)

Index: tip/kernel/locking/rtmutex.c
===================================================================
--- tip.orig/kernel/locking/rtmutex.c
+++ tip/kernel/locking/rtmutex.c
@@ -307,6 +307,7 @@ static int rt_mutex_adjust_prio_chain(st
 	int detect_deadlock, ret = 0, depth = 0;
 	struct rt_mutex *lock;
 	unsigned long flags;
+	bool requeue = true;
 
 	detect_deadlock = rt_mutex_cond_detect_deadlock(orig_waiter,
 							deadlock_detect);
@@ -366,8 +367,11 @@ static int rt_mutex_adjust_prio_chain(st
 		if (!task_has_pi_waiters(task))
 			goto out_unlock_pi;
 
-		if (!detect_deadlock && top_waiter != task_top_pi_waiter(task))
-			goto out_unlock_pi;
+		if (top_waiter != task_top_pi_waiter(task)) {
+			if (!detect_deadlock)
+				goto out_unlock_pi;
+			requeue = false;
+		}
 	}
 
 	/*
@@ -377,6 +381,7 @@ static int rt_mutex_adjust_prio_chain(st
 	if (waiter->prio == task->prio) {
 		if (!detect_deadlock)
 			goto out_unlock_pi;
+		requeue = false;
 	}
 
 	lock = waiter->lock;
@@ -410,10 +415,16 @@ static int rt_mutex_adjust_prio_chain(st
 	 */
 	prerequeue_top_waiter = rt_mutex_top_waiter(lock);
 
-	/* Requeue the waiter */
-	rt_mutex_dequeue(lock, waiter);
-	waiter->prio = task->prio;
-	rt_mutex_enqueue(lock, waiter);
+	/*
+	 * Requeue the waiter, if we are in the boost/deboost
+	 * operation and not just following the lock chain for
+	 * deadlock detection.
+	 */
+	if (requeue) {
+		rt_mutex_dequeue(lock, waiter);
+		waiter->prio = task->prio;
+		rt_mutex_enqueue(lock, waiter);
+	}
 
 	/* Release the task */
 	raw_spin_unlock_irqrestore(&task->pi_lock, flags);
@@ -428,7 +439,8 @@ static int rt_mutex_adjust_prio_chain(st
 		 * If the requeue above changed the top waiter, then we need
 		 * to wake the new top waiter up to try to get the lock.
 		 */
-		if (prerequeue_top_waiter != rt_mutex_top_waiter(lock))
+		if (requeue &&
+		    prerequeue_top_waiter != rt_mutex_top_waiter(lock))
 			wake_up_process(rt_mutex_top_waiter(lock)->task);
 		raw_spin_unlock(&lock->wait_lock);
 		goto out_put_task;
@@ -440,32 +452,41 @@ static int rt_mutex_adjust_prio_chain(st
 	get_task_struct(task);
 	raw_spin_lock_irqsave(&task->pi_lock, flags);
 
-	if (waiter == rt_mutex_top_waiter(lock)) {
-		/*
-		 * The waiter became the top waiter on the
-		 * lock. Remove the previous top waiter from the tasks
-		 * pi waiters list and add waiter to it.
-		 */
-		rt_mutex_dequeue_pi(task, prerequeue_top_waiter);
-		rt_mutex_enqueue_pi(task, waiter);
-		__rt_mutex_adjust_prio(task);
-
-	} else if (prerequeue_top_waiter == waiter) {
-		/*
-		 * The waiter was the top waiter on the lock. Remove
-		 * waiter from the tasks pi waiters list and add the
-		 * new top waiter to it.
-		 */
-		rt_mutex_dequeue_pi(task, waiter);
-		waiter = rt_mutex_top_waiter(lock);
-		rt_mutex_enqueue_pi(task, waiter);
-		__rt_mutex_adjust_prio(task);
-
-	} else {
-		/*
-		 * Nothing changed. No need to do any priority
-		 * adjustment.
-		 */
+	/*
+	 * In case we are just following the lock chain for deadlock
+	 * detection we can avoid the whole requeue and priority
+	 * adjustment business.
+	 */
+	if (requeue) {
+		if (waiter == rt_mutex_top_waiter(lock)) {
+			/*
+			 * The waiter became the top waiter on the
+			 * lock. Remove the previous top waiter from
+			 * the tasks pi waiters list and add waiter to
+			 * it.
+			 */
+			rt_mutex_dequeue_pi(task, prerequeue_top_waiter);
+			rt_mutex_enqueue_pi(task, waiter);
+			__rt_mutex_adjust_prio(task);
+
+		} else if (prerequeue_top_waiter == waiter) {
+			/*
+			 * The waiter was the top waiter on the
+			 * lock. Remove waiter from the tasks pi
+			 * waiters list and add the new top waiter to
+			 * it.
+			 */
+			rt_mutex_dequeue_pi(task, waiter);
+			waiter = rt_mutex_top_waiter(lock);
+			rt_mutex_enqueue_pi(task, waiter);
+			__rt_mutex_adjust_prio(task);
+
+		} else {
+			/*
+			 * Nothing changed. No need to do any priority
+			 * adjustment.
+			 */
+		}
 	}
 
 	raw_spin_unlock_irqrestore(&task->pi_lock, flags);



  parent reply index

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-22  3:25 [patch 0/6] rtmutex: Repair deadlock detector and cleanup Thomas Gleixner
2014-05-22  3:25 ` [patch 1/6] rtmutex: Fix deadlock detector for real Thomas Gleixner
2014-05-27 22:09   ` Steven Rostedt
2014-05-28  9:57     ` Thomas Gleixner
2014-05-28 19:28   ` [tip:core/urgent] " tip-bot for Thomas Gleixner
2014-05-22  3:25 ` [patch 2/6] rtmutex: Remove builtin tester Thomas Gleixner
2014-05-30 21:36   ` Steven Rostedt
2014-05-22  3:25 ` [patch 3/6] rtmutex: Cleanup deadlock detector debug logic Thomas Gleixner
2014-05-30 22:08   ` Steven Rostedt
2014-06-21 20:32   ` [tip:locking/core] " tip-bot for Thomas Gleixner
2014-05-22  3:25 ` [patch 4/6] rtmutex: Confine deadlock logic to futex Thomas Gleixner
2014-05-22  7:10   ` Peter Zijlstra
2014-05-28 20:28     ` Thomas Gleixner
2014-05-31  2:06   ` Steven Rostedt
2014-05-22  3:25 ` [patch 5/6] rtmutex: Clarify the lock chain walk Thomas Gleixner
2014-05-31  2:19   ` Steven Rostedt
2014-05-22  3:25 ` Thomas Gleixner [this message]
2014-05-27 22:49   ` [patch 6/6] rtmutex: Avoid pointless requeueing in the deadlock detection " Jason Low
2014-05-28  9:43     ` Thomas Gleixner
2014-05-31  2:21       ` Steven Rostedt
2014-06-21 20:33   ` [tip:locking/core] " tip-bot for Thomas Gleixner

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=20140522031950.280830190@linutronix.de \
    --to=tglx@linutronix.de \
    --cc=laijs@cn.fujitsu.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    /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

LKML Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/lkml/0 lkml/git/0.git
	git clone --mirror https://lore.kernel.org/lkml/1 lkml/git/1.git
	git clone --mirror https://lore.kernel.org/lkml/2 lkml/git/2.git
	git clone --mirror https://lore.kernel.org/lkml/3 lkml/git/3.git
	git clone --mirror https://lore.kernel.org/lkml/4 lkml/git/4.git
	git clone --mirror https://lore.kernel.org/lkml/5 lkml/git/5.git
	git clone --mirror https://lore.kernel.org/lkml/6 lkml/git/6.git
	git clone --mirror https://lore.kernel.org/lkml/7 lkml/git/7.git
	git clone --mirror https://lore.kernel.org/lkml/8 lkml/git/8.git
	git clone --mirror https://lore.kernel.org/lkml/9 lkml/git/9.git
	git clone --mirror https://lore.kernel.org/lkml/10 lkml/git/10.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 lkml lkml/ https://lore.kernel.org/lkml \
		linux-kernel@vger.kernel.org
	public-inbox-index lkml

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-kernel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git