Module: xenomai-jki
Branch: for-forge
Commit: c87a84c1047221bcde10403278fcf3e7e991e95d
URL:    
http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=c87a84c1047221bcde10403278fcf3e7e991e95d

Author: Jan Kiszka <jan.kis...@siemens.com>
Date:   Fri Dec 12 16:59:05 2014 +0100

cobalt/pipe: Avoid running init_waitqueue_head under xnlock

This operation can be more complex than simple structure initialization,
namely if lockdep is enabled.

The approach take here is to break up user connection into two stages.
The first one is "lingering connection", which simply reserves the pipe
for the caller of xnpipe_open. After that we release xnlock, perform the
Linux part of the initialization and then finish the second stage under
xnlock again to reach USER_CONN just as before.

This issue can be triggered by running smokey test #10 (xddp).

Signed-off-by: Jan Kiszka <jan.kis...@siemens.com>

---

 include/cobalt/kernel/pipe.h |    1 +
 kernel/cobalt/pipe.c         |   12 ++++++++++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/include/cobalt/kernel/pipe.h b/include/cobalt/kernel/pipe.h
index 01b4642..8a82c7b 100644
--- a/include/cobalt/kernel/pipe.h
+++ b/include/cobalt/kernel/pipe.h
@@ -36,6 +36,7 @@
 #define XNPIPE_USER_WREAD_READY  0x20
 #define XNPIPE_USER_WSYNC        0x40
 #define XNPIPE_USER_WSYNC_READY  0x80
+#define XNPIPE_USER_LCONN        0x100
 
 #define XNPIPE_USER_ALL_WAIT \
 (XNPIPE_USER_WREAD|XNPIPE_USER_WSYNC)
diff --git a/kernel/cobalt/pipe.c b/kernel/cobalt/pipe.c
index a649ecf..716cbf9 100644
--- a/kernel/cobalt/pipe.c
+++ b/kernel/cobalt/pipe.c
@@ -693,15 +693,23 @@ static int xnpipe_open(struct inode *inode, struct file 
*file)
        xnlock_get_irqsave(&nklock, s);
 
        /* Enforce exclusive open for the message queues. */
-       if (state->status & XNPIPE_USER_CONN) {
+       if (state->status & (XNPIPE_USER_CONN | XNPIPE_USER_LCONN)) {
                xnlock_put_irqrestore(&nklock, s);
                return -EBUSY;
        }
 
-       state->status |= XNPIPE_USER_CONN;
+       state->status |= XNPIPE_USER_LCONN;
+
+       xnlock_put_irqrestore(&nklock, s);
+
        file->private_data = state;
        init_waitqueue_head(&state->readq);
        init_waitqueue_head(&state->syncq);
+
+       xnlock_get_irqsave(&nklock, s);
+
+       state->status |= XNPIPE_USER_CONN;
+       state->status &= ~XNPIPE_USER_LCONN;
        state->wcount = 0;
 
        state->status &=


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to