bsd-xfs, signaling to break a wait

Love lha at stacken.kth.se
Thu Apr 1 01:33:10 CEST 1999


Robert Watson <robert at cyrus.watson.org> writes:

> > I see what you are trying to say, but since all (t)sleepings are done
> > by each separate process and the sleepings are independent from each other.
> > (see xfs_message.c:xfs_message_rpc()).
> 
> I observed this behavior specifically on the xfs_message_getroot call--for
> a first pass, I just wrote a small program that listened on /dev/xfs0.  It
> would read messages from it, but never respond.  I observed that when this
> was the case, the interrupt behavior I described occurred.  I'll try it on
> other calls once I get a few more of them working.

Ok, I got the same behavior. The thing is that whole machine freezes since
it seams like the first process sleeps on the process-list. But that would
not be the first time gdb lies to me. Anyway, I'm out of computers for now.
I'll be checking it out later when I'll go over and reboot them.

> > We do ignore SIGIO during the rpc, but that is only because emacs
> > tab-completion breaks if we don't.
> 
> I notice that the rpc to userland is frequently used, but there appears to
> be matching userland code for an rpc to the kernel that is unused.  Is
> that observation correct, or is it in use?

No everything uses xfs_message_send (that is the same thing as
xfs_message_rpc except a bounce check).

> Also, the BSD xfs kernel module appears to implement blocking only on
> select(), not on read() when the file descriptor is set as blocking.  I
> was wondering what the reasoning was there, or if it was just that you
> never do that so didn't implement it? :-)  A

Ops.

With a little bit of luck the patch below might do it, didn't have a
computer to test it on. Please let me know how it works out.

Love


Index: xfs_dev-common.c
===================================================================
RCS file: /usr/local/cvsroot/arla/xfs/bsd/xfs_dev-common.c,v
retrieving revision 1.21
diff -u -w -r1.21 xfs_dev-common.c
--- xfs_dev-common.c	1999/02/27 19:11:20	1.21
+++ xfs_dev-common.c	1999/03/31 23:28:02
@@ -167,6 +167,9 @@
 	XFSDEB(XDEBDEV, ("after outq(sleepq)\n"));
     }
 
+    if (chan->status & CHANNEL_WAITING)
+	wakeup((caddr_t) chan);
+
     if (chan->message_buffer) {
 	xfs_free(chan->message_buffer, MAX_XMSG_SIZE);
 	chan->message_buffer = NULL;
@@ -204,6 +207,9 @@
     XFSDEB(XDEBDEV, ("xfs_devread: m = %p, m->prev = %p, m->next = %p\n",
 		&chan->messageq, chan->messageq.prev, chan->messageq.next));
 
+ again:
+
+    if (!xfs_emptyq (&chan->messageq)) {
     while (!xfs_emptyq (&chan->messageq)) {
 	/* Remove message */
 	first = chan->messageq.next;
@@ -214,7 +220,8 @@
 	XFSDEB(XDEBDEV, ("xfs_devread: message->size = %u\n",
 			 first->message->size));
 
-	error = uiomove((caddr_t) first->message, first->message->size, uiop);
+	    error = uiomove((caddr_t) first->message, first->message->size, 
+			    uiop);
 	if (error)
 	    break;
 
@@ -223,6 +230,17 @@
 	if (first->error_or_size != 0)
 	    xfs_free(first, first->error_or_size);
     }
+    } else {
+	chan->status |= CHANNEL_WAITING;
+	if (tsleep((caddr_t) chan, (PZERO + 1) | PCATCH, "xfsr", 0)) {
+	    XFSDEB(XDEBMSG, ("caught signal xfs_devread\n"));
+	    error = EINTR;
+	} else if ((chan->status & CHANNEL_WAITING) == 0) {
+	    goto again;
+	} else
+	    error = EIO;
+    }
+    
 
     XFSDEB(XDEBDEV, ("xfs_devread done error = %d\n", error));
 
@@ -296,6 +314,10 @@
 
     t->this_message.message = &t->msg;
     xfs_appendq(&chan->messageq, &t->this_message);
+    if (chan->status & CHANNEL_WAITING) {
+	chan->status &= ~CHANNEL_WAITING;
+	wakeup((caddr_t) chan);
+    }
     xfs_select_wakeup(chan);
 
     return 0;
@@ -339,6 +361,11 @@
     xfs_appendq(&chan->sleepq, this_process);
     xfs_select_wakeup(chan);
     this_process->error_or_size = 0;
+
+    if (chan->status & CHANNEL_WAITING) {
+	chan->status &= ~CHANNEL_WAITING;
+	wakeup((caddr_t) chan);
+    }
 
     /*
      * Remove SIGIO from the sigmask so no IO will
Index: xfs/xfs_dev.h
===================================================================
RCS file: /usr/local/cvsroot/arla/xfs/bsd/xfs/xfs_dev.h,v
retrieving revision 1.8
diff -u -w -r1.8 xfs_dev.h
--- xfs_dev.h	1999/01/19 20:03:13	1.8
+++ xfs_dev.h	1999/03/31 23:28:02
@@ -67,6 +67,7 @@
     struct xfs_message_header *message_buffer;
     int status;
 #define CHANNEL_OPENED	0x1
+#define CHANNEL_WAITING 0x2
 };
 
 extern struct xfs_channel xfs_channel[NXFS];





More information about the Arla-drinkers mailing list