bitkeeper revision 1.915 (40ab9035Tu7lOz9f8aWhpKXAF9q49Q)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Wed, 19 May 2004 16:49:57 +0000 (16:49 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Wed, 19 May 2004 16:49:57 +0000 (16:49 +0000)
Fix a page release bug in network backend.

xenolinux-2.4.26-sparse/arch/xen/drivers/netif/backend/main.c

index 44ca0d0554e8dd28e22ec750111baea3868cfa67..737876a04a4577b87798778e569b0a6caeb1fad1 100644 (file)
@@ -574,9 +574,16 @@ static void net_tx_action(unsigned long unused)
         skb->dev      = netif->dev;
         skb->protocol = eth_type_trans(skb, skb->dev);
 
-        /* Destructor information. */
-        atomic_set(&page->count, 1);
+        /*
+         * Destructor information. We hideously abuse the 'mapping' pointer,
+         * which isn't otherwise used by us. The page deallocator is modified
+         * to interpret a non-NULL value as a destructor function to be called.
+         * This works okay because in all other cases the pointer must be NULL
+         * when the page is freed (normally Linux will explicitly bug out if
+         * it sees otherwise.
+         */
         page->mapping = (struct address_space *)netif_page_release;
+        atomic_set(&page->count, 1);
         pending_id[pending_idx] = txreq.id;
         pending_netif[pending_idx] = netif;
 
@@ -595,6 +602,9 @@ static void netif_page_release(struct page *page)
     unsigned long flags;
     u16 pending_idx = page - virt_to_page(mmap_vstart);
 
+    /* Stop the abuse. */
+    page->mapping = NULL;
+
     spin_lock_irqsave(&dealloc_lock, flags);
     dealloc_ring[MASK_PEND_IDX(dealloc_prod++)] = pending_idx;
     spin_unlock_irqrestore(&dealloc_lock, flags);