2 patches that need to be applied one after the other.
netback works for a little longer, but it is still buggy.

Any feedback on this is good.
-JX
===

diff -r f4d382795e57 arch/powerpc/platforms/xen/gnttab.c
--- a/arch/powerpc/platforms/xen/gnttab.c       Wed Oct 25 17:22:54 2006 -0400
+++ b/arch/powerpc/platforms/xen/gnttab.c       Fri Oct 27 15:39:57 2006 -0500
@@ -25,6 +25,33 @@ static ulong foreign_map_base;
 static ulong foreign_map_base;
 static ulong foreign_map_end;
 
+
+/* hijack _mapcount */
+static inline int gnt_mapcount(struct page *page)
+{
+       return atomic_read(&(page)->_mapcount) + 1;
+}
+
+static inline int gnt_map(struct page *page)
+{
+       /* return true is transition from -1 to 0 */
+       return atomic_inc_and_test(&page->_mapcount);
+}
+
+static inline int gnt_unmap(struct page *page)
+{
+       int val;
+
+       val = atomic_dec_return(&page->_mapcount);
+       if (val < -1) {
+               atomic_inc(&page->_mapcount);
+               printk(KERN_EMERG "%s: %d\n", __func__, val);
+       }
+
+       return (val == -1);
+}
+
+
 static long map_to_linear(ulong paddr)
 {
        unsigned long vaddr;
@@ -136,21 +163,20 @@ static void gnttab_pre_unmap_grant_ref(
        int i;
        ulong ea;
        unsigned long dummy1, dummy2;
+       ulong flags;
+
+       /* paranoia */
+       local_irq_save(flags);
 
        for (i = 0 ; i < count; i++) {
                struct page *page;
 
                ea = unmap[i].host_addr;
                page = virt_to_page(ea);
-
-               /* Unfortunately, there is no put_page_testone() like
-                * put_page_testzero(). The Linear Map starts all
-                * pages with a count of 1, so there may be SMP issues
-                * here. */
-
-               put_page(page);
-               if (page_count(page) > 1) {
-                       DBG("%s: skip: 0x%lx\n", __func__, ea);
+               
+               if (!gnt_unmap(page)) {
+                       DBG("%s[0x%x]: skip: 0x%lx, mapcount 0x%x\n",
+                           __func__, i, ea, gnt_mapcount(page));
                        continue;
                }
                slot = find_map_slot(ea);
@@ -160,10 +186,11 @@ static void gnttab_pre_unmap_grant_ref(
                        continue;
                }
 
-               DBG("%s: 0x%lx: page count: 0x%x\n",
-                      __func__, ea, page_count(virt_to_page(ea)));
+               DBG("%s[0x%x]: 0x%lx: mapcount: 0x%x\n",
+                   __func__, i, ea, gnt_mapcount(page));
                plpar_pte_remove(0, slot, 0, &dummy1, &dummy2);
        }
+       local_irq_restore(flags);
 }
 
 static void gnttab_post_map_grant_ref(
@@ -171,6 +198,10 @@ static void gnttab_post_map_grant_ref(
 {
        int i;
        long slot;
+       ulong flags;
+
+       /* paranoia */
+       local_irq_save(flags);
 
        for (i = 0 ; i < count; i++) {
                ulong pa = map[i].dev_bus_addr;
@@ -182,10 +213,7 @@ static void gnttab_post_map_grant_ref(
                map[i].host_addr = (ulong)__va(pa);
                page = virt_to_page(map[i].host_addr);
 
-               DBG("%s: 0x%lx: 0x%x\n",
-                   __func__, pa, page_count(page));
-
-               if (page_count(page) == 1) {
+               if (gnt_map(page)) {
 #ifdef DEBUG                   
                        /* we need to get smarted than this */
                        slot = find_map_slot((ulong)__va(pa));
@@ -195,11 +223,15 @@ static void gnttab_post_map_grant_ref(
                        }
 #endif
                        slot = map_to_linear(pa);
+                       DBG("%s[0x%x]: 0x%lx, mapcount:0x%x\n",
+                           __func__, i, pa, gnt_mapcount(page));
+
                } else {
-                       DBG("%s: skip 0x%lx\n", __func__, pa);
-               }
-               get_page(page);
-       }
+                       DBG("%s[0x%x] skip 0x%lx, mapcount:0x%x\n",
+                           __func__, i, pa, gnt_mapcount(page));
+               }
+       }
+       local_irq_restore(flags);
 }
 
 int HYPERVISOR_grant_table_op(unsigned int cmd, void *op, unsigned int count)
diff -r f4d382795e57 drivers/xen/netback/netback.c
--- a/drivers/xen/netback/netback.c     Wed Oct 25 17:22:54 2006 -0400
+++ b/drivers/xen/netback/netback.c     Fri Oct 27 15:54:04 2006 -0500
@@ -84,6 +84,9 @@ static inline void update_mmap_pages(
        unsigned int idx, gnttab_map_grant_ref_t *mop)
 {
        struct page *p;
+
+       p = pfn_to_page(mop->dev_bus_addr >> PAGE_SHIFT);
+
 #ifdef PPC_NOT_YET
        struct page *cp = mmap_pages[idx];
        extern int arch_is_foreign_page(struct page *page);
@@ -97,11 +100,9 @@ static inline void update_mmap_pages(
        //              __free_page(mmap_pages[idx]);
        }
        
+       printk(KERN_EMERG "%s insert[%d]:  %p, 0x%x\n",
+              __func__, idx, __va(mop->dev_bus_addr), page_count(p));
 #endif
-       p = pfn_to_page(mop->dev_bus_addr >> PAGE_SHIFT);
-
-       DPRINTK(KERN_EMERG "%s insert[%d]:  0x%lx, 0x%x\n",
-              __func__, idx, __va(mop->dev_bus_addr), page_count(p));
 
        SetPageForeign(p, netif_page_release);
        p->index = idx;
@@ -1379,10 +1380,6 @@ static void netif_page_release(struct pa
 {
        /* Ready for next use. */
        init_page_count(page);
-#ifdef CONFIG_PPC_XEN
-       /* we need the count to be 2 so the unmap occurs */
-       get_page(page);
-#endif
        netif_idx_release(page->index);
 }
 
diff -r f4d382795e57 drivers/xen/netfront/netfront.c
--- a/drivers/xen/netfront/netfront.c   Wed Oct 25 17:22:54 2006 -0400
+++ b/drivers/xen/netfront/netfront.c   Wed Oct 25 14:05:17 2006 -0500
@@ -655,6 +655,13 @@ static void network_tx_buf_gc(struct net
                                       "domain.\n");
                                BUG();
                        }
+                       if ((ulong)skb < 0xc000000000000000ULL) {
+                               printk(KERN_EMERG "%s: bad skb: %p id: %d "
+                                      "status: 0x%x\n", __func__,
+                                      skb, id, txrsp->status);
+                               continue;
+//                             asm volatile(".long 0x200;nop");
+                       }
                        gnttab_end_foreign_access_ref(
                                np->grant_tx_ref[id], GNTMAP_readonly);
                        gnttab_release_grant_reference(
diff -u arch/powerpc/platforms/xen/gnttab.c 
arch/powerpc/platforms/xen/gnttab.jimix.c
--- a/arch/powerpc/platforms/xen/gnttab.c       2006-10-31 10:23:06.000000000 
-0500
+++ b/arch/powerpc/platforms/xen/gnttab.jimix.c 2006-10-30 16:34:27.000000000 
-0500
@@ -207,11 +207,6 @@
                ulong pa = map[i].dev_bus_addr;
                struct page *page;
 
-               if (map[i].status != GNTST_okay) {
-                       printk(KERN_EMERG "%s: status, skip\n", __func__);
-                       continue;
-               }
-
                BUG_ON(pa < foreign_map_base || pa >= foreign_map_end);
 
                /* ??? store the slot somewhere ??? */

_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@lists.xensource.com
http://lists.xensource.com/xen-ppc-devel

Reply via email to