All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gerd Hoffmann <kraxel@suse.de>
To: Xen devel list <xen-devel@lists.xensource.com>
Subject: [patch 6/6] netif_release_rx_bufs
Date: Thu, 17 Aug 2006 16:13:32 +0200	[thread overview]
Message-ID: <44E4798C.30007@suse.de> (raw)

[-- Attachment #1: Type: text/plain, Size: 680 bytes --]

  Hi,

This patch adds a netif_release_rx_bufs() function to the netfront
driver.  It intends to fix the rx buffer page leak.  Unfortunaly it
doesn't work perfectly, the reason is that reclaiming the pages granted
to the backend driver works only if the backend driver gave them back
already, filled with network data.  Reclaiming unfilled rx buffers does
NOT work.

I think we need either a way to get back pages with transfer grants
without cooperation from the backend driver, or we need some way to say
"pretty pretty please, give me back my rx buffers" to the netback driver.

comments?

  Gerd

-- 
Gerd Hoffmann <kraxel@suse.de>
http://www.suse.de/~kraxel/julika-dora.jpeg

[-- Attachment #2: netfront-release-rx --]
[-- Type: text/plain, Size: 2983 bytes --]

Signed-off-by: Gerd Hoffmann <kraxel@suse.de>
Index: source-lnx-stable-22813/drivers/xen/netfront/netfront.c
===================================================================
--- source-lnx-stable-22813.orig/drivers/xen/netfront/netfront.c	2006-08-17 15:20:17.000000000 +0200
+++ source-lnx-stable-22813/drivers/xen/netfront/netfront.c	2006-08-17 15:20:17.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,80 @@ 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 bufs = 0, gnttab = 0, unused = 0;
+	int id, ref;
+
+	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;
+		}
+		if ((mfn = gnttab_end_foreign_transfer_ref(ref)) == 0) {
+			gnttab++;
+			continue;
+		}
+
+		gnttab_release_grant_reference(&np->gref_rx_head, ref);
+		np->grant_rx_ref[id] = GRANT_INVALID_REF;
+
+		skb = np->rx_skbs[id];
+		add_id_to_freelist(np->rx_skbs, id);
+
+		if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+			/* Remap the page. */
+			MULTI_update_va_mapping(mcl, (unsigned long)skb->head,
+						pfn_pte_ma(mfn, PAGE_KERNEL),
+						0);
+			mcl++;
+			mmu->ptr = ((maddr_t)mfn << PAGE_SHIFT)
+				| MMU_MACHPHYS_UPDATE;
+			mmu->val = __pa(skb->head) >> PAGE_SHIFT;
+			mmu++;
+
+			set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT,
+					    mfn);
+		}
+		bufs++;
+
+#if 0 /* FIXME */
+		dev_kfree_skb(skb);
+#endif
+	}
+
+	printk("%s: %d released ok, %d gnttab errs, %d unused slots\n",
+	       __FUNCTION__, bufs, gnttab, unused);
+	if (0 == bufs)
+		return;
+
+	/* Some pages are no longer absent... */
+	balloon_update_driver_allowance(-bufs);
+
+	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 +1498,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);
 }

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

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

             reply	other threads:[~2006-08-17 14:13 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-08-17 14:13 Gerd Hoffmann [this message]
2006-08-17 15:04 ` [patch 6/6] netif_release_rx_bufs Keir Fraser
2006-08-17 15:13   ` Gerd Hoffmann
2006-08-17 15:54     ` Keir Fraser
2006-08-18  6:43       ` Gerd Hoffmann
2006-08-18  8:54         ` Keir Fraser
2006-08-18 11:34           ` Gerd Hoffmann
2006-08-18 12:25             ` Keir Fraser
2006-08-18 12:41               ` Gerd Hoffmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=44E4798C.30007@suse.de \
    --to=kraxel@suse.de \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.