Kip Macy
2005-May-02  06:52 UTC
[Xen-devel] [PATCH] make XenFreeBSD VBD ring full handling sensible
# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2005/05/01 23:48:15-07:00 kmacy@curly.lab.netapp.com 
#   make ring full handling sensible
#   Signed-off-by: Kip Macy <kmacy@netapp.com>
# 
# freebsd-5.3-xen-sparse/i386-xen/xen/blkfront/xb_blkfront.c
#   2005/05/01 23:48:12-07:00 kmacy@curly.lab.netapp.com +48 -5
#   make ring full handling sensible
# 
diff -Nru a/freebsd-5.3-xen-sparse/i386-xen/xen/blkfront/xb_blkfront.c
b/freebsd-5.3-xen-sparse/i386-xen/xen/blkfront/xb_blkfront.c
--- a/freebsd-5.3-xen-sparse/i386-xen/xen/blkfront/xb_blkfront.c	2005-04-30
23:53:20 -07:00
+++ b/freebsd-5.3-xen-sparse/i386-xen/xen/blkfront/xb_blkfront.c	2005-04-30
23:53:21 -07:00
@@ -68,6 +68,7 @@
     void		 *xb_resp_handler;
     int			  xb_unit;
     int			  xb_flags;
+    struct xb_softc      *xb_next_blocked;
 #define XB_OPEN	(1<<0)		/* drive is open (can''t shut down) */
 };
 
@@ -118,6 +119,9 @@
     (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLKIF_RING_SIZE)
 #endif
 
+static struct xb_softc *xb_kick_pending_head = NULL;
+static struct xb_softc *xb_kick_pending_tail = NULL;
+static struct mtx blkif_io_block_lock;
 
 static unsigned long rec_ring_free;		
 blkif_request_t rec_ring[BLK_RING_SIZE];
@@ -246,6 +250,7 @@
     /* sometimes we seem to lose i/o.  stay in the interrupt handler while
      * there is stuff to process: continually recheck the response producer.
      */
+ process_rcvd:
     for ( i = blk_ring.rsp_cons; i != (rp = blk_ring.sring->rsp_prod); i++ )
{
 	unsigned long id;
         bret = RING_GET_RESPONSE(&blk_ring, i);
@@ -298,9 +303,28 @@
     
     blk_ring.rsp_cons = i;
 
-    if (sc && xb_kick_pending) {
-    	xb_kick_pending = FALSE;
-	xb_startio(sc);
+    if (xb_kick_pending) {
+	unsigned long flags;
+	mtx_lock_irqsave(&blkif_io_block_lock, flags);
+   	xb_kick_pending = FALSE;
+	/* Run as long as there are blocked devs or queue fills again */
+	while ((NULL != xb_kick_pending_head) && (FALSE == xb_kick_pending)) {
+	    struct xb_softc *xb_cur = xb_kick_pending_head;
+	    xb_kick_pending_head = xb_cur->xb_next_blocked;
+	    if(NULL == xb_kick_pending_head) {
+		xb_kick_pending_tail = NULL;
+	    }
+	    xb_cur->xb_next_blocked = NULL;
+	    mtx_unlock_irqrestore(&blkif_io_block_lock, flags);
+	    xb_startio(xb_cur);
+	    mtx_lock_irqsave(&blkif_io_block_lock, flags);
+	}
+	mtx_unlock_irqrestore(&blkif_io_block_lock, flags);
+
+	if(blk_ring.rsp_cons != blk_ring.sring->rsp_prod) {
+	    /* Consume those, too */
+	    goto process_rcvd;
+	}
     }
 
     mtx_unlock_irqrestore(&blkif_io_lock, flags);
@@ -448,8 +472,22 @@
 
     }
 
-    if (RING_FULL(&blk_ring))
+    if (RING_FULL(&blk_ring)) {
+	unsigned long flags;
+	mtx_lock_irqsave(&blkif_io_block_lock, flags);
 	xb_kick_pending = TRUE;
+        /* If we are not already on blocked list, add us */
+        if((NULL == sc->xb_next_blocked) && (xb_kick_pending_tail !=
sc)) {
+
+            if(NULL == xb_kick_pending_head) {
+                xb_kick_pending_head = xb_kick_pending_tail = sc;
+            } else {
+                xb_kick_pending_tail->xb_next_blocked = sc;
+                xb_kick_pending_tail = sc;
+            }
+        }
+        mtx_unlock_irqrestore(&blkif_io_block_lock, flags);
+    }
     
     if (queued != 0) 
 	flush_requests();
@@ -501,6 +539,7 @@
     
     sc = (struct xb_softc *)malloc(sizeof(*sc), M_DEVBUF, M_WAITOK);
     sc->xb_unit = unit;
+    sc->xb_next_blocked = NULL;
 
     memset(&sc->xb_disk, 0, sizeof(sc->xb_disk)); 
     sc->xb_disk.d_unit = unit;
@@ -947,7 +986,10 @@
         return;
     printk("Blkif frontend is using grant tables.\n");
 #endif
-
+ 
+    xb_kick_pending = FALSE;
+    xb_kick_pending_head = NULL;
+    xb_kick_pending_tail = NULL;
 
     rec_ring_free = 0;
     for (i = 0; i < BLK_RING_SIZE; i++) {
@@ -1002,4 +1044,5 @@
 #endif    
 }
 MTX_SYSINIT(ioreq, &blkif_io_lock, "BIO LOCK", MTX_SPIN |
MTX_NOWITNESS); /* XXX how does one enroll a lock? */
+ MTX_SYSINIT(ioreq_block, &blkif_io_block_lock, "BIO BLOCK LOCK",
MTX_SPIN | MTX_NOWITNESS);
 SYSINIT(xbdev, SI_SUB_PSEUDO, SI_ORDER_ANY, xb_init, NULL)
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel