ia64/xen-unstable

changeset 11217:b85da7cd9ea5

[NET] front: Fix rx buffer leak when tearing down an interface.
Signed-off-by: Gerd Hoffmann <kraxel@suse.de>
author kaf24@localhost.localdomain
date Sat Aug 19 10:58:07 2006 +0100 (2006-08-19)
parents 7258181ab445
children 2d70f2de1809
files linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c linux-2.6-xen-sparse/include/xen/balloon.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Sat Aug 19 10:21:02 2006 +0100
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Sat Aug 19 10:58:07 2006 +0100
     1.3 @@ -606,8 +606,21 @@ void balloon_dealloc_empty_page_range(
     1.4  	schedule_work(&balloon_worker);
     1.5  }
     1.6  
     1.7 +void balloon_release_driver_page(struct page *page)
     1.8 +{
     1.9 +	unsigned long flags;
    1.10 +
    1.11 +	balloon_lock(flags);
    1.12 +	balloon_append(page);
    1.13 +	driver_pages--;
    1.14 +	balloon_unlock(flags);
    1.15 +
    1.16 +	schedule_work(&balloon_worker);
    1.17 +}
    1.18 +
    1.19  EXPORT_SYMBOL_GPL(balloon_update_driver_allowance);
    1.20  EXPORT_SYMBOL_GPL(balloon_alloc_empty_page_range);
    1.21  EXPORT_SYMBOL_GPL(balloon_dealloc_empty_page_range);
    1.22 +EXPORT_SYMBOL_GPL(balloon_release_driver_page);
    1.23  
    1.24  MODULE_LICENSE("Dual BSD/GPL");
     2.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Sat Aug 19 10:21:02 2006 +0100
     2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Sat Aug 19 10:58:07 2006 +0100
     2.3 @@ -1397,6 +1397,85 @@ err:
     2.4  	return more_to_do;
     2.5  }
     2.6  
     2.7 +static void netif_release_rx_bufs(struct netfront_info *np)
     2.8 +{
     2.9 +	struct mmu_update      *mmu = np->rx_mmu;
    2.10 +	struct multicall_entry *mcl = np->rx_mcl;
    2.11 +	struct sk_buff *skb;
    2.12 +	unsigned long mfn;
    2.13 +	int xfer = 0, noxfer = 0, unused = 0;
    2.14 +	int id, ref;
    2.15 +
    2.16 +	if (np->copying_receiver) {
    2.17 +		printk("%s: fix me for copying receiver.\n", __FUNCTION__);
    2.18 +		return;
    2.19 +	}
    2.20 +
    2.21 +	spin_lock(&np->rx_lock);
    2.22 +
    2.23 +	for (id = 0; id < NET_RX_RING_SIZE; id++) {
    2.24 +		if ((ref = np->grant_rx_ref[id]) == GRANT_INVALID_REF) {
    2.25 +			unused++;
    2.26 +			continue;
    2.27 +		}
    2.28 +
    2.29 +		skb = np->rx_skbs[id];
    2.30 +		mfn = gnttab_end_foreign_transfer_ref(ref);
    2.31 +		gnttab_release_grant_reference(&np->gref_rx_head, ref);
    2.32 +		np->grant_rx_ref[id] = GRANT_INVALID_REF;
    2.33 +		add_id_to_freelist(np->rx_skbs, id);
    2.34 +
    2.35 +		if (0 == mfn) {
    2.36 +			struct page *page = skb_shinfo(skb)->frags[0].page;
    2.37 +			balloon_release_driver_page(page);
    2.38 +			skb_shinfo(skb)->nr_frags = 0;
    2.39 +			dev_kfree_skb(skb);
    2.40 +			noxfer++;
    2.41 +			continue;
    2.42 +		}
    2.43 +
    2.44 +		if (!xen_feature(XENFEAT_auto_translated_physmap)) {
    2.45 +			/* Remap the page. */
    2.46 +			struct page *page = skb_shinfo(skb)->frags[0].page;
    2.47 +			unsigned long pfn = page_to_pfn(page);
    2.48 +			void *vaddr = page_address(page);
    2.49 +
    2.50 +			MULTI_update_va_mapping(mcl, (unsigned long)vaddr,
    2.51 +						pfn_pte_ma(mfn, PAGE_KERNEL),
    2.52 +						0);
    2.53 +			mcl++;
    2.54 +			mmu->ptr = ((maddr_t)mfn << PAGE_SHIFT)
    2.55 +				| MMU_MACHPHYS_UPDATE;
    2.56 +			mmu->val = pfn;
    2.57 +			mmu++;
    2.58 +
    2.59 +			set_phys_to_machine(pfn, mfn);
    2.60 +		}
    2.61 +		dev_kfree_skb(skb);
    2.62 +		xfer++;
    2.63 +	}
    2.64 +
    2.65 +	printk("%s: %d xfer, %d noxfer, %d unused\n",
    2.66 +	       __FUNCTION__, xfer, noxfer, unused);
    2.67 +
    2.68 +	if (xfer) {
    2.69 +		/* Some pages are no longer absent... */
    2.70 +		balloon_update_driver_allowance(-xfer);
    2.71 +
    2.72 +		if (!xen_feature(XENFEAT_auto_translated_physmap)) {
    2.73 +			/* Do all the remapping work and M2P updates. */
    2.74 +			mcl->op = __HYPERVISOR_mmu_update;
    2.75 +			mcl->args[0] = (unsigned long)np->rx_mmu;
    2.76 +			mcl->args[1] = mmu - np->rx_mmu;
    2.77 +			mcl->args[2] = 0;
    2.78 +			mcl->args[3] = DOMID_SELF;
    2.79 +			mcl++;
    2.80 +			HYPERVISOR_multicall(np->rx_mcl, mcl - np->rx_mcl);
    2.81 +		}
    2.82 +	}
    2.83 +
    2.84 +	spin_unlock(&np->rx_lock);
    2.85 +}
    2.86  
    2.87  static int network_close(struct net_device *dev)
    2.88  {
    2.89 @@ -1553,6 +1632,7 @@ static void network_connect(struct net_d
    2.90  static void netif_uninit(struct net_device *dev)
    2.91  {
    2.92  	struct netfront_info *np = netdev_priv(dev);
    2.93 +	netif_release_rx_bufs(np);
    2.94  	gnttab_free_grant_references(np->gref_tx_head);
    2.95  	gnttab_free_grant_references(np->gref_rx_head);
    2.96  }
     3.1 --- a/linux-2.6-xen-sparse/include/xen/balloon.h	Sat Aug 19 10:21:02 2006 +0100
     3.2 +++ b/linux-2.6-xen-sparse/include/xen/balloon.h	Sat Aug 19 10:58:07 2006 +0100
     3.3 @@ -52,6 +52,8 @@ extern void
     3.4  balloon_dealloc_empty_page_range(
     3.5  	struct page *page, unsigned long nr_pages);
     3.6  
     3.7 +void balloon_release_driver_page(struct page *page);
     3.8 +
     3.9  /*
    3.10   * Prevent the balloon driver from changing the memory reservation during
    3.11   * a driver critical region.