ia64/xen-unstable

changeset 11763:0fe7624dde63

[NET] back: Allocate pages for foreign mappings individually rather than contiguously.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Oct 05 22:49:26 2006 +0100 (2006-10-05)
parents 0cda1a7988ee
children 9d0b22eb1758
files linux-2.6-xen-sparse/drivers/xen/netback/netback.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Thu Oct 05 22:14:39 2006 +0100
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Thu Oct 05 22:49:26 2006 +0100
     1.3 @@ -70,8 +70,11 @@ static struct timer_list net_timer;
     1.4  
     1.5  static struct sk_buff_head rx_queue;
     1.6  
     1.7 -static unsigned long mmap_vstart;
     1.8 -#define MMAP_VADDR(_req) (mmap_vstart + ((_req) * PAGE_SIZE))
     1.9 +static struct page **mmap_pages;
    1.10 +static inline unsigned long idx_to_kaddr(unsigned int idx)
    1.11 +{
    1.12 +	return (unsigned long)pfn_to_kaddr(page_to_pfn(mmap_pages[idx]));
    1.13 +}
    1.14  
    1.15  #define PKT_PROT_LEN 64
    1.16  
    1.17 @@ -817,7 +820,7 @@ inline static void net_tx_action_dealloc
    1.18  	gop = tx_unmap_ops;
    1.19  	while (dc != dp) {
    1.20  		pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)];
    1.21 -		gnttab_set_unmap_op(gop, MMAP_VADDR(pending_idx),
    1.22 +		gnttab_set_unmap_op(gop, idx_to_kaddr(pending_idx),
    1.23  				    GNTMAP_host_map,
    1.24  				    grant_tx_handle[pending_idx]);
    1.25  		gop++;
    1.26 @@ -905,7 +908,7 @@ static gnttab_map_grant_ref_t *netbk_get
    1.27  		txp = RING_GET_REQUEST(&netif->tx, cons++);
    1.28  		pending_idx = pending_ring[MASK_PEND_IDX(pending_cons++)];
    1.29  
    1.30 -		gnttab_set_map_op(mop++, MMAP_VADDR(pending_idx),
    1.31 +		gnttab_set_map_op(mop++, idx_to_kaddr(pending_idx),
    1.32  				  GNTMAP_host_map | GNTMAP_readonly,
    1.33  				  txp->gref, netif->domid);
    1.34  
    1.35 @@ -938,7 +941,7 @@ static int netbk_tx_check_mop(struct sk_
    1.36  		netif_put(netif);
    1.37  	} else {
    1.38  		set_phys_to_machine(
    1.39 -			__pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT,
    1.40 +			__pa(idx_to_kaddr(pending_idx)) >> PAGE_SHIFT,
    1.41  			FOREIGN_FRAME(mop->dev_bus_addr >> PAGE_SHIFT));
    1.42  		grant_tx_handle[pending_idx] = mop->handle;
    1.43  	}
    1.44 @@ -955,7 +958,7 @@ static int netbk_tx_check_mop(struct sk_
    1.45  		newerr = (++mop)->status;
    1.46  		if (likely(!newerr)) {
    1.47  			set_phys_to_machine(
    1.48 -				__pa(MMAP_VADDR(pending_idx))>>PAGE_SHIFT,
    1.49 +				__pa(idx_to_kaddr(pending_idx))>>PAGE_SHIFT,
    1.50  				FOREIGN_FRAME(mop->dev_bus_addr>>PAGE_SHIFT));
    1.51  			grant_tx_handle[pending_idx] = mop->handle;
    1.52  			/* Had a previous error? Invalidate this fragment. */
    1.53 @@ -1003,7 +1006,7 @@ static void netbk_fill_frags(struct sk_b
    1.54  
    1.55  		pending_idx = (unsigned long)frag->page;
    1.56  		txp = &pending_tx_info[pending_idx].req;
    1.57 -		frag->page = virt_to_page(MMAP_VADDR(pending_idx));
    1.58 +		frag->page = virt_to_page(idx_to_kaddr(pending_idx));
    1.59  		frag->size = txp->size;
    1.60  		frag->page_offset = txp->offset;
    1.61  
    1.62 @@ -1199,7 +1202,7 @@ static void net_tx_action(unsigned long 
    1.63  			}
    1.64  		}
    1.65  
    1.66 -		gnttab_set_map_op(mop, MMAP_VADDR(pending_idx),
    1.67 +		gnttab_set_map_op(mop, idx_to_kaddr(pending_idx),
    1.68  				  GNTMAP_host_map | GNTMAP_readonly,
    1.69  				  txreq.gref, netif->domid);
    1.70  		mop++;
    1.71 @@ -1258,8 +1261,8 @@ static void net_tx_action(unsigned long 
    1.72  		}
    1.73  
    1.74  		data_len = skb->len;
    1.75 -		memcpy(skb->data, 
    1.76 -		       (void *)(MMAP_VADDR(pending_idx)|txp->offset),
    1.77 +		memcpy(skb->data,
    1.78 +		       (void *)(idx_to_kaddr(pending_idx)|txp->offset),
    1.79  		       data_len);
    1.80  		if (data_len < txp->size) {
    1.81  			/* Append the packet payload as a fragment. */
    1.82 @@ -1313,12 +1316,10 @@ static void netif_idx_release(u16 pendin
    1.83  
    1.84  static void netif_page_release(struct page *page)
    1.85  {
    1.86 -	u16 pending_idx = page - virt_to_page(mmap_vstart);
    1.87 -
    1.88  	/* Ready for next use. */
    1.89  	set_page_count(page, 1);
    1.90  
    1.91 -	netif_idx_release(pending_idx);
    1.92 +	netif_idx_release(page->index);
    1.93  }
    1.94  
    1.95  irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs)
    1.96 @@ -1438,17 +1439,22 @@ static int __init netback_init(void)
    1.97  	init_timer(&net_timer);
    1.98  	net_timer.data = 0;
    1.99  	net_timer.function = net_alarm;
   1.100 -    
   1.101 -	page = balloon_alloc_empty_page_range(MAX_PENDING_REQS);
   1.102 -	if (page == NULL)
   1.103 -		return -ENOMEM;
   1.104  
   1.105 -	mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
   1.106 +	mmap_pages = kmalloc(sizeof(mmap_pages[0]) * MAX_PENDING_REQS,
   1.107 +			     GFP_KERNEL);
   1.108 +	if (mmap_pages == NULL)
   1.109 +		goto out_of_memory;
   1.110  
   1.111  	for (i = 0; i < MAX_PENDING_REQS; i++) {
   1.112 -		page = virt_to_page(MMAP_VADDR(i));
   1.113 +		page = mmap_pages[i] = balloon_alloc_empty_page();
   1.114 +		if (page == NULL) {
   1.115 +			while (--i >= 0)
   1.116 +				balloon_free_empty_page(mmap_pages[i]);
   1.117 +			goto out_of_memory;
   1.118 +		}
   1.119  		set_page_count(page, 1);
   1.120  		SetPageForeign(page, netif_page_release);
   1.121 +		page->index = i;
   1.122  	}
   1.123  
   1.124  	pending_cons = 0;
   1.125 @@ -1472,6 +1478,11 @@ static int __init netback_init(void)
   1.126  #endif
   1.127  
   1.128  	return 0;
   1.129 +
   1.130 + out_of_memory:
   1.131 +	kfree(mmap_pages);
   1.132 +	printk("%s: out of memory\n", __FUNCTION__);
   1.133 +	return -ENOMEM;
   1.134  }
   1.135  
   1.136  module_init(netback_init);