WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

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

To: Keir Fraser <Keir.Fraser@xxxxxxxxxxxx>
Subject: Re: [Xen-devel] [patch 6/6] netif_release_rx_bufs
From: Gerd Hoffmann <kraxel@xxxxxxx>
Date: Fri, 18 Aug 2006 14:41:54 +0200
Cc: Xen devel list <xen-devel@xxxxxxxxxxxxxxxxxxx>
Delivery-date: Fri, 18 Aug 2006 05:42:27 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <C10B704F.10F9%Keir.Fraser@xxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <C10B704F.10F9%Keir.Fraser@xxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Thunderbird 1.5.0.5 (X11/20060725)
  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