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@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ppc-devel
|