WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Change the grant table interface so that gnttab_end_fore

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Change the grant table interface so that gnttab_end_foreign_access_ref returns
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Sun, 30 Oct 2005 22:34:15 +0000
Delivery-date: Sun, 30 Oct 2005 22:32:52 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User emellor@xxxxxxxxxxxxxxxxxxxxxx
# Node ID b50eb7619dd46427169f3d40580f973604643448
# Parent  ecae9e6c7331184f916c095a2ef7ff90750ed3d7
Change the grant table interface so that gnttab_end_foreign_access_ref returns
an error code if the page is still in use, and gnttab_end_foreign_access takes
a page to free.  This allows us to cope with frontends wanting to end access
while backends are still using pages by, eventually, placing the page and
grant table entry on a list, for freeing later.  At the moment, the page and
grant table entry are leaked, with a diagnostic.

Tidied up netfront.c's clean-up code.

Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx>

diff -r ecae9e6c7331 -r b50eb7619dd4 
linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c     Sun Oct 30 15:25:52 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c     Sun Oct 30 15:33:05 2005
@@ -165,25 +165,39 @@
        return (nflags & (GTF_reading|GTF_writing));
 }
 
-void
+int
 gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly)
 {
        u16 flags, nflags;
 
        nflags = shared[ref].flags;
        do {
-               if ( (flags = nflags) & (GTF_reading|GTF_writing) )
+               if ( (flags = nflags) & (GTF_reading|GTF_writing) ) {
                        printk(KERN_ALERT "WARNING: g.e. still in use!\n");
+                       return 0;
+               }
        }
        while ((nflags = synch_cmpxchg(&shared[ref].flags, flags, 0)) !=
               flags);
-}
-
-void
-gnttab_end_foreign_access(grant_ref_t ref, int readonly)
-{
-       gnttab_end_foreign_access_ref(ref, readonly);
-       put_free_entry(ref);
+
+       return 1;
+}
+
+void
+gnttab_end_foreign_access(grant_ref_t ref, int readonly, unsigned long page)
+{
+       if (gnttab_end_foreign_access_ref(ref, readonly)) {
+               put_free_entry(ref);
+               if (page != 0) {
+                       free_page(page);
+               }
+       }
+       else {
+               /* XXX This needs to be fixed so that the ref and page are
+                  placed on a list to be freed up later. */
+               printk(KERN_WARNING
+                      "WARNING: leaking g.e. and page still in use!\n");
+       }
 }
 
 int
diff -r ecae9e6c7331 -r b50eb7619dd4 
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Sun Oct 30 
15:25:52 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Sun Oct 30 
15:33:05 2005
@@ -350,13 +350,12 @@
        spin_unlock_irq(&blkif_io_lock);
 
        /* Free resources associated with old device channel. */
-       if (info->ring.sring != NULL) {
-               free_page((unsigned long)info->ring.sring);
+       if (info->ring_ref != GRANT_INVALID_REF) {
+               gnttab_end_foreign_access(info->ring_ref, 0,
+                                         (unsigned long)info->ring.sring);
+               info->ring_ref = GRANT_INVALID_REF;
                info->ring.sring = NULL;
        }
-       if (info->ring_ref != GRANT_INVALID_REF)
-               gnttab_end_foreign_access(info->ring_ref, 0);
-       info->ring_ref = GRANT_INVALID_REF;
        if (info->irq)
                unbind_evtchn_from_irqhandler(info->irq, info); 
        info->evtchn = info->irq = 0;
@@ -515,10 +514,10 @@
 
        err = HYPERVISOR_event_channel_op(&op);
        if (err) {
-               gnttab_end_foreign_access(info->ring_ref, 0);
+               gnttab_end_foreign_access(info->ring_ref, 0,
+                                         (unsigned long)info->ring.sring);
                info->ring_ref = GRANT_INVALID_REF;
-               free_page((unsigned long)info->ring.sring);
-               info->ring.sring = 0;
+               info->ring.sring = NULL;
                xenbus_dev_error(dev, err, "allocating event channel");
                return err;
        }
@@ -740,7 +739,7 @@
        int i;
        for (i = 0; i < s->req.nr_segments; i++)
                gnttab_end_foreign_access(
-                       blkif_gref_from_fas(s->req.frame_and_sects[i]), 0);
+                       blkif_gref_from_fas(s->req.frame_and_sects[i]), 0, 0UL);
 }
 
 /*
diff -r ecae9e6c7331 -r b50eb7619dd4 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Sun Oct 30 
15:25:52 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Sun Oct 30 
15:33:05 2005
@@ -90,6 +90,8 @@
 
 static void network_tx_buf_gc(struct net_device *dev);
 static void network_alloc_rx_buffers(struct net_device *dev);
+
+static void netif_free(struct netfront_info *info);
 
 static unsigned long rx_pfn_array[NETIF_RX_RING_SIZE];
 static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE+1];
@@ -978,6 +980,9 @@
 
        info->tx_ring_ref = GRANT_INVALID_REF;
        info->rx_ring_ref = GRANT_INVALID_REF;
+       info->rx = NULL;
+       info->tx = NULL;
+       info->irq = 0;
 
        info->tx = (netif_tx_interface_t *)__get_free_page(GFP_KERNEL);
        if (info->tx == 0) {
@@ -1022,40 +1027,24 @@
        return 0;
 
  out:
-       if (info->tx)
-               free_page((unsigned long)info->tx);
-       info->tx = 0;
-       if (info->rx)
-               free_page((unsigned long)info->rx);
-       info->rx = 0;
-
-       if (info->tx_ring_ref != GRANT_INVALID_REF)
-               gnttab_end_foreign_access(info->tx_ring_ref, 0);
+       netif_free(info);
+       return err;
+}
+
+static void end_access(int ref, void *page)
+{
+       if (ref != GRANT_INVALID_REF)
+               gnttab_end_foreign_access(ref, 0, (unsigned long)page);
+}
+
+static void netif_free(struct netfront_info *info)
+{
+       end_access(info->tx_ring_ref, info->tx);
+       end_access(info->rx_ring_ref, info->rx);
        info->tx_ring_ref = GRANT_INVALID_REF;
-
-       if (info->rx_ring_ref != GRANT_INVALID_REF)
-               gnttab_end_foreign_access(info->rx_ring_ref, 0);
        info->rx_ring_ref = GRANT_INVALID_REF;
-
-       return err;
-}
-
-static void netif_free(struct netfront_info *info)
-{
-       if (info->tx)
-               free_page((unsigned long)info->tx);
-       info->tx = 0;
-       if (info->rx)
-               free_page((unsigned long)info->rx);
-       info->rx = 0;
-
-       if (info->tx_ring_ref != GRANT_INVALID_REF)
-               gnttab_end_foreign_access(info->tx_ring_ref, 0);
-       info->tx_ring_ref = GRANT_INVALID_REF;
-
-       if (info->rx_ring_ref != GRANT_INVALID_REF)
-               gnttab_end_foreign_access(info->rx_ring_ref, 0);
-       info->rx_ring_ref = GRANT_INVALID_REF;
+       info->tx = NULL;
+       info->rx = NULL;
 
        if (info->irq)
                unbind_evtchn_from_irqhandler(info->irq, info->netdev);
diff -r ecae9e6c7331 -r b50eb7619dd4 
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Sun Oct 30 
15:25:52 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Sun Oct 30 
15:33:05 2005
@@ -276,8 +276,8 @@
 
        err = HYPERVISOR_event_channel_op(&op);
        if (err) {
-               gnttab_end_foreign_access(info->ring_ref, 0);
-               free_page((unsigned long)sring);
+               gnttab_end_foreign_access(info->ring_ref, 0,
+                                         (unsigned long)sring);
                tp->tx = NULL;
                xenbus_dev_error(dev, err, "allocating event channel");
                return err;
@@ -294,8 +294,8 @@
        tpmif_set_connected_state(tp,0);
 
        if ( tp->tx != NULL ) {
-               gnttab_end_foreign_access(info->ring_ref, 0);
-               free_page((unsigned long)tp->tx);
+               gnttab_end_foreign_access(info->ring_ref, 0,
+                                         (unsigned long)tp->tx);
                tp->tx = NULL;
        }
 
diff -r ecae9e6c7331 -r b50eb7619dd4 
linux-2.6-xen-sparse/include/asm-xen/gnttab.h
--- a/linux-2.6-xen-sparse/include/asm-xen/gnttab.h     Sun Oct 30 15:25:52 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/gnttab.h     Sun Oct 30 15:33:05 2005
@@ -34,8 +34,21 @@
 int gnttab_grant_foreign_access(domid_t domid, unsigned long frame,
                                int readonly);
 
-void gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly);
-void gnttab_end_foreign_access(grant_ref_t ref, int readonly);
+/*
+ * End access through the given grant reference, iff the grant entry is no
+ * longer in use.  Return 1 if the grant entry was freed, 0 if it is still in
+ * use.
+ */
+int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly);
+
+/*
+ * Eventually end access through the given grant reference, and once that
+ * access has been ended, free the given page too.  Access will be ended
+ * immediately iff the grant entry is not in use, otherwise it will happen
+ * some time later.  page may be 0, in which case no freeing will occur.
+ */
+void gnttab_end_foreign_access(grant_ref_t ref, int readonly,
+                              unsigned long page);
 
 int gnttab_grant_foreign_transfer(domid_t domid);
 

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Change the grant table interface so that gnttab_end_foreign_access_ref returns, Xen patchbot -unstable <=