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

[Xen-changelog] Change semantics of gnttab_transfer to take the page away



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 52020caa244f9c86c434b8332783c1edc658d852
# Parent  e336e186e5f96a0e93f842ca3a2e39601c2a0193
Change semantics of gnttab_transfer to take the page away
from the calling domain, even on error (except for special
error GNTST_bad_page). This has a knock-on advantage of
simplifying Linux's netback driver.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r e336e186e5f9 -r 52020caa244f 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Mon Nov 21 
16:30:43 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Mon Nov 21 
17:10:35 2005
@@ -97,27 +97,6 @@
                mfn = mfn_list[--alloc_index];
        spin_unlock_irqrestore(&mfn_lock, flags);
        return mfn;
-}
-
-static void free_mfn(unsigned long mfn)
-{
-       unsigned long flags;
-       struct xen_memory_reservation reservation = {
-               .extent_start = &mfn,
-               .nr_extents   = 1,
-               .extent_order = 0,
-               .domid        = DOMID_SELF
-       };
-       spin_lock_irqsave(&mfn_lock, flags);
-       if ( alloc_index != MAX_MFN_ALLOC )
-               mfn_list[alloc_index++] = mfn;
-       else {
-               int ret;
-               ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
-                                           &reservation);
-               BUG_ON(ret != 1);
-       }
-       spin_unlock_irqrestore(&mfn_lock, flags);
 }
 
 static inline void maybe_schedule_tx_action(void)
@@ -306,14 +285,18 @@
                netif->stats.tx_packets++;
 
                /* The update_va_mapping() must not fail. */
-               BUG_ON(mcl[0].result != 0);
+               BUG_ON(mcl->result != 0);
 
                /* Check the reassignment error code. */
                status = NETIF_RSP_OKAY;
                if (gop->status != 0) { 
                        DPRINTK("Bad status %d from grant transfer to DOM%u\n",
                                gop->status, netif->domid);
-                       free_mfn(old_mfn);
+                       /*
+                         * Page no longer belongs to us unless GNTST_bad_page,
+                         * but that should be a fatal error anyway.
+                         */
+                       BUG_ON(gop->status == GNTST_bad_page);
                        status = NETIF_RSP_ERROR; 
                }
                irq = netif->irq;
diff -r e336e186e5f9 -r 52020caa244f xen/common/grant_table.c
--- a/xen/common/grant_table.c  Mon Nov 21 16:30:43 2005
+++ b/xen/common/grant_table.c  Mon Nov 21 17:10:35 2005
@@ -714,26 +714,18 @@
         /* Read from caller address space. */
         if ( unlikely(__copy_from_user(&gop, &uop[i], sizeof(gop))) )
         {
-            /* Caller error: bail immediately. */
             DPRINTK("gnttab_transfer: error reading req %d/%d\n", i, count);
-            return -EFAULT;
+            (void)__put_user(GNTST_bad_page, &uop[i].status);
+            return -EFAULT; /* This is *very* fatal. */
         }
 
         /* Check the passed page frame for basic validity. */
         page = &frame_table[gop.mfn];
         if ( unlikely(!pfn_valid(gop.mfn) || IS_XEN_HEAP_FRAME(page)) )
         { 
-            /* Caller error: bail immediately. */
             DPRINTK("gnttab_transfer: out-of-range or xen frame %lx\n",
                     (unsigned long)gop.mfn);
-            return -EINVAL;
-        }
-
-        /* Find the target domain. */
-        if ( unlikely((e = find_domain_by_id(gop.domid)) == NULL) )
-        {
-            DPRINTK("gnttab_transfer: can't find domain %d\n", gop.domid);
-            (void)__put_user(GNTST_bad_domain, &uop[i].status);
+            (void)__put_user(GNTST_bad_page, &uop[i].status);
             continue;
         }
 
@@ -752,15 +744,14 @@
             x = y;
             if (unlikely((x & (PGC_count_mask|PGC_allocated)) !=
                          (1 | PGC_allocated)) || unlikely(_nd != _d)) { 
-                /* Caller error: bail immediately. */
                 DPRINTK("gnttab_transfer: Bad page %p: ed=%p(%u), sd=%p,"
                        " caf=%08x, taf=%" PRtype_info "\n", 
                        (void *) page_to_pfn(page),
                         d, d->domain_id, unpickle_domptr(_nd), x, 
                         page->u.inuse.type_info);
                 spin_unlock(&d->page_alloc_lock);
-                put_domain(e);
-                return -EINVAL;
+                (void)__put_user(GNTST_bad_page, &uop[i].status);
+                continue;
             }
             __asm__ __volatile__(
                 LOCK_PREFIX "cmpxchg8b %2"
@@ -778,6 +769,16 @@
         list_del(&page->list);
 
         spin_unlock(&d->page_alloc_lock);
+
+        /* Find the target domain. */
+        if ( unlikely((e = find_domain_by_id(gop.domid)) == NULL) )
+        {
+            DPRINTK("gnttab_transfer: can't find domain %d\n", gop.domid);
+            (void)__put_user(GNTST_bad_domain, &uop[i].status);
+            page->count_info &= ~(PGC_count_mask|PGC_allocated);
+            free_domheap_page(page);
+            continue;
+        }
 
         spin_lock(&e->page_alloc_lock);
 
@@ -797,6 +798,8 @@
             spin_unlock(&e->page_alloc_lock);
             put_domain(e);
             (void)__put_user(GNTST_general_error, &uop[i].status);
+            page->count_info &= ~(PGC_count_mask|PGC_allocated);
+            free_domheap_page(page);
             continue;
         }
 
diff -r e336e186e5f9 -r 52020caa244f xen/common/page_alloc.c
--- a/xen/common/page_alloc.c   Mon Nov 21 16:30:43 2005
+++ b/xen/common/page_alloc.c   Mon Nov 21 17:10:35 2005
@@ -645,7 +645,9 @@
     }
     else
     {
-        /* Freeing an anonymous domain-heap page. */
+        /* Freeing anonymous domain-heap pages. */
+        for ( i = 0; i < (1 << order); i++ )
+            pg[i].u.free.cpumask = CPU_MASK_NONE;
         free_heap_pages(pfn_dom_zone_type(page_to_pfn(pg)), pg, order);
         drop_dom_ref = 0;
     }
diff -r e336e186e5f9 -r 52020caa244f xen/include/public/grant_table.h
--- a/xen/include/public/grant_table.h  Mon Nov 21 16:30:43 2005
+++ b/xen/include/public/grant_table.h  Mon Nov 21 17:10:35 2005
@@ -215,9 +215,12 @@
 } gnttab_dump_table_t;
 
 /*
- * GNTTABOP_transfer_grant_ref: Transfer <frame> to a foreign domain.  The
- * foreign domain has previously registered the details of the transfer.
- * These can be identified from <handle>, a grant reference.
+ * GNTTABOP_transfer_grant_ref: Transfer <frame> to a foreign domain. The
+ * foreign domain has previously registered its interest in the transfer via
+ * <domid, ref>.
+ * 
+ * Note that, even if the transfer fails, the specified page no longer belongs
+ * to the calling domain *unless* the error is GNTST_bad_page.
  */
 #define GNTTABOP_transfer                4
 typedef struct {
@@ -269,6 +272,7 @@
 #define GNTST_bad_dev_addr     (-6) /* Inappropriate device address to unmap.*/
 #define GNTST_no_device_space  (-7) /* Out of space in I/O MMU.              */
 #define GNTST_permission_denied (-8) /* Not enough privilege for operation.  */
+#define GNTST_bad_page         (-9) /* Specified page was invalid for op.    */
 
 #define GNTTABOP_error_msgs {                   \
     "okay",                                     \

_______________________________________________
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®.