Module: xenomai-3
Branch: master
Commit: ed6465cc08e6f93e6771d9d07ff43fb570396b83
URL:    
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=ed6465cc08e6f93e6771d9d07ff43fb570396b83

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