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

Re: [Xen-devel] [patch 6/6] netif_release_rx_bufs



  Hi,

> Best bet is to free the page to the balloon driver, and then set nr_frags to
> zero. This is perfectly valid -- it was netfront that set it to non-zero in
> the first place.

Perfect.  New version of the patch is attached below.

cheers,

  Gerd

-- 
Gerd Hoffmann <kraxel@xxxxxxx>
http://www.suse.de/~kraxel/julika-dora.jpeg
Signed-off-by: Gerd Hoffmann <kraxel@xxxxxxx>
Index: source-lnx-stable-22813/drivers/xen/netfront/netfront.c
===================================================================
--- source-lnx-stable-22813.orig/drivers/xen/netfront/netfront.c        
2006-08-18 10:47:12.000000000 +0200
+++ source-lnx-stable-22813/drivers/xen/netfront/netfront.c     2006-08-18 
14:39:56.000000000 +0200
@@ -494,6 +494,7 @@ static int network_open(struct net_devic
 {
        struct netfront_info *np = netdev_priv(dev);
 
+       DPRINTK("%s\n", np->xbdev->nodename);
        memset(&np->stats, 0, sizeof(np->stats));
 
        network_alloc_rx_buffers(dev);
@@ -1285,10 +1286,86 @@ err:
        return more_to_do;
 }
 
+static void netif_release_rx_bufs(struct netfront_info *np)
+{
+       struct mmu_update      *mmu = np->rx_mmu;
+       struct multicall_entry *mcl = np->rx_mcl;
+       struct sk_buff *skb;
+       unsigned long mfn;
+       int xfer = 0, noxfer = 0, unused = 0;
+       int id, ref, rc;
+
+       printk("%s: enter\n", __FUNCTION__);
+
+       spin_lock(&np->rx_lock);
+
+       for (id = 0; id < NET_RX_RING_SIZE; id++) {
+               if ((ref = np->grant_rx_ref[id]) == GRANT_INVALID_REF) {
+                       unused++;
+                       continue;
+               }
+
+               skb = np->rx_skbs[id];
+               mfn = gnttab_end_foreign_transfer_ref(ref);
+               gnttab_release_grant_reference(&np->gref_rx_head, ref);
+               np->grant_rx_ref[id] = GRANT_INVALID_REF;
+               add_id_to_freelist(np->rx_skbs, id);
+
+               if (0 == mfn) {
+                       struct page *page = skb_shinfo(skb)->frags[0].page;
+                       balloon_release_driver_page(page);
+                       skb_shinfo(skb)->nr_frags = 0;
+                       dev_kfree_skb(skb);
+                       noxfer++;
+                       continue;
+               }
+
+               if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+                       /* Remap the page. */
+                       struct page *page = skb_shinfo(skb)->frags[0].page;
+                       unsigned long pfn = page_to_pfn(page);
+                       void *vaddr = page_address(page);
+
+                       MULTI_update_va_mapping(mcl, (unsigned long)vaddr,
+                                               pfn_pte_ma(mfn, PAGE_KERNEL),
+                                               0);
+                       mcl++;
+                       mmu->ptr = ((maddr_t)mfn << PAGE_SHIFT)
+                               | MMU_MACHPHYS_UPDATE;
+                       mmu->val = pfn;
+                       mmu++;
+
+                       set_phys_to_machine(pfn, mfn);
+               }
+               dev_kfree_skb(skb);
+               xfer++;
+       }
+       printk("%s: %d xfer, %d noxfer, %d unused\n",
+              __FUNCTION__, xfer, noxfer, unused);
+
+       if (xfer) {
+               /* Some pages are no longer absent... */
+               balloon_update_driver_allowance(-xfer);
+
+               if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+                       /* Do all the remapping work, and M2P updates, in one 
big hypercall. */
+                       mcl->op = __HYPERVISOR_mmu_update;
+                       mcl->args[0] = (unsigned long)np->rx_mmu;
+                       mcl->args[1] = mmu - np->rx_mmu;
+                       mcl->args[2] = 0;
+                       mcl->args[3] = DOMID_SELF;
+                       mcl++;
+                       HYPERVISOR_multicall(np->rx_mcl, mcl - np->rx_mcl);
+               }
+       }
+
+       spin_unlock(&np->rx_lock);
+}
 
 static int network_close(struct net_device *dev)
 {
        struct netfront_info *np = netdev_priv(dev);
+       DPRINTK("%s\n", np->xbdev->nodename);
        netif_stop_queue(np->netdev);
        return 0;
 }
@@ -1427,6 +1504,8 @@ static void network_connect(struct net_d
 static void netif_uninit(struct net_device *dev)
 {
        struct netfront_info *np = netdev_priv(dev);
+       DPRINTK("%s\n", np->xbdev->nodename);
+       netif_release_rx_bufs(np);
        gnttab_free_grant_references(np->gref_tx_head);
        gnttab_free_grant_references(np->gref_rx_head);
 }
Index: source-lnx-stable-22813/drivers/xen/balloon/balloon.c
===================================================================
--- source-lnx-stable-22813.orig/drivers/xen/balloon/balloon.c  2006-08-18 
10:38:47.000000000 +0200
+++ source-lnx-stable-22813/drivers/xen/balloon/balloon.c       2006-08-18 
12:13:44.000000000 +0200
@@ -612,8 +612,21 @@ void balloon_dealloc_empty_page_range(
        schedule_work(&balloon_worker);
 }
 
+void balloon_release_driver_page(struct page *page)
+{
+       unsigned long flags;
+
+       balloon_lock(flags);
+       balloon_append(page);
+       driver_pages--;
+       balloon_unlock(flags);
+
+       schedule_work(&balloon_worker);
+}
+
 EXPORT_SYMBOL_GPL(balloon_update_driver_allowance);
 EXPORT_SYMBOL_GPL(balloon_alloc_empty_page_range);
 EXPORT_SYMBOL_GPL(balloon_dealloc_empty_page_range);
+EXPORT_SYMBOL_GPL(balloon_release_driver_page);
 
 MODULE_LICENSE("Dual BSD/GPL");
Index: source-lnx-stable-22813/drivers/xen/netfront/Makefile
===================================================================
--- source-lnx-stable-22813.orig/drivers/xen/netfront/Makefile  2006-08-18 
11:14:35.000000000 +0200
+++ source-lnx-stable-22813/drivers/xen/netfront/Makefile       2006-08-18 
12:20:14.000000000 +0200
@@ -1,3 +1,4 @@
+EXTRA_CFLAGS += -DDEBUG=1
 
 obj-$(CONFIG_XEN_NETDEV_FRONTEND)      := xennet.o
 
Index: source-lnx-stable-22813/include/xen/balloon.h
===================================================================
--- source-lnx-stable-22813.orig/include/xen/balloon.h  2006-08-17 
16:29:59.000000000 +0200
+++ source-lnx-stable-22813/include/xen/balloon.h       2006-08-18 
12:13:17.000000000 +0200
@@ -52,6 +52,8 @@ extern void
 balloon_dealloc_empty_page_range(
        struct page *page, unsigned long nr_pages);
 
+void balloon_release_driver_page(struct page *page);
+
 /*
  * Prevent the balloon driver from changing the memory reservation during
  * a driver critical region.
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.