[PATCH replace] Fix pushable_tasks list corruption

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: gilles.carry <gilles.carry@xxxxxxxx>

Symptoms:
System hang (endless loop in plist_check_list)
or BUG because of faulty prev/next pointers in
pushable_task node.

When push_rt_task successes finding a task to push away, it
performs a double lock on the runqueues (local and target) but
before getting both locks, it releases the local rq lock allowing
other cpus grab the task in between. (eg. pull_rt_task, timers...)
In some situations, when push_rt_task calls dequeue_pushable_task
the task may have already been removed from the pushable_tasks
list by another cpu. Removing the node again corrupts the list.

This patch adds a sanity check to dequeue_pushable_task which only
removes the node if it's still on the original list.

Signed-off-by: Gilles Carry <gilles.carry@xxxxxxxx>
Cc: ghaskins@xxxxxxxxxx
---
 kernel/sched_rt.c |   18 +++++++++++++++++-
 1 files changed, 17 insertions(+), 1 deletions(-)

diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
index 57a0c0d..7aa4450 100644
--- a/kernel/sched_rt.c
+++ b/kernel/sched_rt.c
@@ -62,7 +62,17 @@ static void enqueue_pushable_task(struct rq *rq, struct task_struct *p)
 
 static void dequeue_pushable_task(struct rq *rq, struct task_struct *p)
 {
-	plist_del(&p->pushable_tasks, &rq->rt.pushable_tasks);
+	struct plist_node *next;
+
+	/* Sanity check: delete only if node is still on this list */
+	plist_for_each(next, &rq->rt.pushable_tasks) {
+		if (&p->pushable_tasks == next) {
+			plist_del(&p->pushable_tasks, &rq->rt.pushable_tasks);
+			return;
+		}
+	}
+
+
 }
 
 #else
@@ -1105,6 +1115,12 @@ static int push_rt_task(struct rq *rq)
 		 * try again, since the other cpus will pull from us
 		 * when they are ready
 		 */
+
+		/*
+		 * If we reach here and the task has migrated to another cpu
+		 * (paranoid == 0?) calling dequeue_pushable_task may cause
+		 * pushable_tasks list corruption.
+		 */
 		dequeue_pushable_task(rq, next_task);
 		goto out;
 	}
-- 
1.5.5.GIT

--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [RT Stable]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]

  Powered by Linux