[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-3.0-testing] [LINUX][BLK] front: More care over device teardown.



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 6ce2965720ee2ed191700834102e867009ea14ce
# Parent  98a4aad0751a6d0f594b8f17864ea9cfb9fe4d15
[LINUX][BLK] front: More care over device teardown.
 1. We must ensure gnttab callbacks are disabled and all work
    flushed before tearing down device state. A new gnttab interface
    call is added for this purpose.
 2. blkif_free() must check for a request_queue before deref'ing it.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
xen-unstable changeset:   10346:5552bc2c3716e9e0f57dbba80f61332b895a0f2a
xen-unstable date:        Wed Jun 14 11:19:53 2006 +0100
---
 linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c |   19 ++++++++++++++++++-
 linux-2.6-xen-sparse/drivers/xen/core/gnttab.c       |   15 +++++++++++++++
 linux-2.6-xen-sparse/include/xen/gnttab.h            |    1 +
 3 files changed, 34 insertions(+), 1 deletion(-)

diff -r 98a4aad0751a -r 6ce2965720ee 
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Tue Jun 13 
17:38:16 2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Wed Jun 14 
11:44:09 2006 +0100
@@ -342,8 +342,20 @@ static void blkfront_closing(struct xenb
 static void blkfront_closing(struct xenbus_device *dev)
 {
        struct blkfront_info *info = dev->data;
+       unsigned long flags;
 
        DPRINTK("blkfront_closing: %s removed\n", dev->nodename);
+
+       if (info->rq == NULL)
+               return;
+
+       spin_lock_irqsave(&blkif_io_lock, flags);
+       /* No more blkif_request(). */
+       blk_stop_queue(info->rq);
+       /* No more gnttab callback work. */
+       gnttab_cancel_free_callback(&info->callback);
+       flush_scheduled_work();
+       spin_unlock_irqrestore(&blkif_io_lock, flags);
 
        xlvbd_del(info);
 
@@ -696,7 +708,12 @@ static void blkif_free(struct blkfront_i
        spin_lock_irq(&blkif_io_lock);
        info->connected = suspend ?
                BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED;
-       blk_stop_queue(info->rq); /* no more blkif_request() */
+       /* No more blkif_request(). */
+       if (info->rq)
+               blk_stop_queue(info->rq);
+       /* No more gnttab callback work. */
+       gnttab_cancel_free_callback(&info->callback);
+       flush_scheduled_work();
        spin_unlock_irq(&blkif_io_lock);
 
        /* Free resources associated with old device channel. */
diff -r 98a4aad0751a -r 6ce2965720ee 
linux-2.6-xen-sparse/drivers/xen/core/gnttab.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c    Tue Jun 13 17:38:16 
2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c    Wed Jun 14 11:44:09 
2006 +0100
@@ -359,6 +359,21 @@ gnttab_request_free_callback(struct gntt
        spin_unlock_irqrestore(&gnttab_list_lock, flags);
 }
 
+void gnttab_cancel_free_callback(struct gnttab_free_callback *callback)
+{
+       struct gnttab_free_callback **pcb;
+       unsigned long flags;
+
+       spin_lock_irqsave(&gnttab_list_lock, flags);
+       for (pcb = &gnttab_free_callback_list; *pcb; pcb = &(*pcb)->next) {
+               if (*pcb == callback) {
+                       *pcb = callback->next;
+                       break;
+               }
+       }
+       spin_unlock_irqrestore(&gnttab_list_lock, flags);
+}
+
 #ifndef __ia64__
 static int map_pte_fn(pte_t *pte, struct page *pmd_page,
                      unsigned long addr, void *data)
diff -r 98a4aad0751a -r 6ce2965720ee linux-2.6-xen-sparse/include/xen/gnttab.h
--- a/linux-2.6-xen-sparse/include/xen/gnttab.h Tue Jun 13 17:38:16 2006 +0100
+++ b/linux-2.6-xen-sparse/include/xen/gnttab.h Wed Jun 14 11:44:09 2006 +0100
@@ -97,6 +97,7 @@ void gnttab_release_grant_reference(gran
 
 void gnttab_request_free_callback(struct gnttab_free_callback *callback,
                                  void (*fn)(void *), void *arg, u16 count);
+void gnttab_cancel_free_callback(struct gnttab_free_callback *callback);
 
 void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid,
                                     unsigned long frame, int readonly);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.