public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Manfred Spraul <manfred@colorfullife.com>
To: Luca Tettamanti <kronos.it@gmail.com>
Cc: Christoph Lameter <cl@linux-foundation.org>,
	linux-kernel@vger.kernel.org, Julia Lawall <julia@diku.dk>,
	Andrew Morton <akpm@linux-foundation.org>,
	maciej.rutecki@gmail.com
Subject: Re: 2.6.35-rc3 deadlocks on semaphore operations
Date: Wed, 23 Jun 2010 18:29:11 +0200	[thread overview]
Message-ID: <4C223657.3030507@colorfullife.com> (raw)
In-Reply-To: <20100621200118.GA4021@nb-core2.darkstar.lan>

[-- Attachment #1: Type: text/plain, Size: 476 bytes --]

Hi,

I think I found it:
Previously, queue.status was never IN_WAKEUP when the semaphore spinlock 
was held.

The last patch changes that:
Now the change from IN_WAKEUP to the final result code happens after the 
the semaphore spinlock is dropped.
Thus a task can observe IN_WAKEUP even when it acquired the semaphore 
spinlock.

As a result, semop() sometimes returned 1 (IN_WAKEUP) for a successful 
operation.

Attached is a patch that should fix the bug.

--
     Manfred

[-- Attachment #2: 0001-ipc-sem.c-Bugfix-for-semop.patch --]
[-- Type: text/plain, Size: 2498 bytes --]

>From 5e047a60a625397d7b4c4a5f6ab088296258e065 Mon Sep 17 00:00:00 2001
From: Manfred Spraul <manfred@colorfullife.com>
Date: Wed, 23 Jun 2010 18:05:46 +0200
Subject: [PATCH] ipc/sem.c: Bugfix for semop() not reporting successful operation

The last change to improve the scalability moved the actual wake-up out of
the section that is protected by spin_lock(sma->sem_perm.lock).

This means that IN_WAKEUP can be in queue.status even when the spinlock is
acquired by the current task. Thus the same loop that is performed when
queue.status is read without the spinlock acquired must be performed when
the spinlock is acquired.

Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
---
 ipc/sem.c |   36 ++++++++++++++++++++++++++++++------
 1 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/ipc/sem.c b/ipc/sem.c
index 506c849..523665f 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -1256,6 +1256,32 @@ out:
 	return un;
 }
 
+
+/** get_queue_result - Retrieve the result code from sem_queue
+ * @q: Pointer to queue structure
+ *
+ * The function retrieve the return code from the pending queue. If 
+ * IN_WAKEUP is found in q->status, then we must loop until the value
+ * is replaced with the final value: This may happen if a task is
+ * woken up by an unrelated event (e.g. signal) and in parallel the task
+ * is woken up by another task because it got the requested semaphores.
+ *
+ * The function can be called with or without holding the semaphore spinlock.
+ */
+static int get_queue_result(struct sem_queue *q)
+{
+	int error;
+
+	error = q->status;
+	while(unlikely(error == IN_WAKEUP)) {
+		cpu_relax();
+		error = q->status;
+	}
+
+	return error;
+}
+
+
 SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
 		unsigned, nsops, const struct timespec __user *, timeout)
 {
@@ -1409,11 +1435,7 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
 	else
 		schedule();
 
-	error = queue.status;
-	while(unlikely(error == IN_WAKEUP)) {
-		cpu_relax();
-		error = queue.status;
-	}
+	error = get_queue_result(&queue);
 
 	if (error != -EINTR) {
 		/* fast path: update_queue already obtained all requested
@@ -1427,10 +1449,12 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
 		goto out_free;
 	}
 
+	error = get_queue_result(&queue);
+
 	/*
 	 * If queue.status != -EINTR we are woken up by another process
 	 */
-	error = queue.status;
+
 	if (error != -EINTR) {
 		goto out_unlock_free;
 	}
-- 
1.7.0.1


  reply	other threads:[~2010-06-23 16:28 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-06-18 14:49 2.6.35-rc3 deadlocks on semaphore operations Christoph Lameter
2010-06-18 14:56 ` Christoph Lameter
2010-06-19 14:43   ` Manfred Spraul
2010-06-21 14:31     ` Christoph Lameter
2010-06-21 16:52       ` Manfred Spraul
2010-06-21 17:13         ` Christoph Lameter
2010-06-18 15:34 ` Julia Lawall
2010-06-19 11:06 ` Manfred Spraul
2010-06-21 17:05   ` Christoph Lameter
2010-06-21 17:16     ` Christoph Lameter
2010-06-21 18:05       ` 2.6.35-rc3 deadlocks on wakeup(?) (was on semaphore operations) Christoph Lameter
2010-06-20  6:55 ` 2.6.35-rc3 deadlocks on semaphore operations Maciej Rutecki
2010-06-21 20:01 ` Luca Tettamanti
2010-06-23 16:29   ` Manfred Spraul [this message]
2010-06-23 19:14     ` Luca Tettamanti
2010-06-24 19:22       ` Luca Tettamanti
2010-06-25 21:09         ` Manfred Spraul
2010-06-26 12:52           ` Luca Tettamanti
2010-06-26 15:47             ` 2.6.35-rc3: System unresponsive under load Manfred Spraul
2010-06-26 15:49               ` Manfred Spraul
2010-06-26 16:47               ` Luca Tettamanti
2010-06-30 19:07                 ` Manfred Spraul
2010-07-06 16:01                   ` Luca Tettamanti
2010-07-07 19:34                   ` Luca Tettamanti
2010-07-02 15:53             ` 2.6.35-rc3 deadlocks on semaphore operations Manfred Spraul
2010-06-23 20:27     ` Christoph Lameter

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=4C223657.3030507@colorfullife.com \
    --to=manfred@colorfullife.com \
    --cc=akpm@linux-foundation.org \
    --cc=cl@linux-foundation.org \
    --cc=julia@diku.dk \
    --cc=kronos.it@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maciej.rutecki@gmail.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox