diff options
author | akw27@boulderdash.cl.cam.ac.uk <akw27@boulderdash.cl.cam.ac.uk> | 2003-02-05 13:40:29 +0000 |
---|---|---|
committer | akw27@boulderdash.cl.cam.ac.uk <akw27@boulderdash.cl.cam.ac.uk> | 2003-02-05 13:40:29 +0000 |
commit | e5e9ce51999838451bf4854a533a1bca25455133 (patch) | |
tree | bcd9fdeadaa740f2fd1a7dc6b02c22d327bb1280 /xenolinux-2.4.16-sparse | |
parent | fbc79ebdf40b7035b2083a78526a42486c819d6b (diff) | |
download | xen-e5e9ce51999838451bf4854a533a1bca25455133.tar.gz xen-e5e9ce51999838451bf4854a533a1bca25455133.tar.bz2 xen-e5e9ce51999838451bf4854a533a1bca25455133.zip |
bitkeeper revision 1.15.1.13 (3e41144dWc5GH88F3idrXT41kpovhQ)
Zero copy RX path is working with guest-allocated page pool.
Diffstat (limited to 'xenolinux-2.4.16-sparse')
-rw-r--r-- | xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c | 12 | ||||
-rw-r--r-- | xenolinux-2.4.16-sparse/include/asm-xeno/io.h | 18 | ||||
-rw-r--r-- | xenolinux-2.4.16-sparse/net/core/skbuff.c | 30 |
3 files changed, 43 insertions, 17 deletions
diff --git a/xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c b/xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c index b018e29e49..9c40ad0066 100644 --- a/xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c +++ b/xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c @@ -192,9 +192,9 @@ static void network_alloc_rx_buffers(struct net_device *dev) skb = dev_alloc_skb(RX_BUF_SIZE); if ( skb == NULL ) break; skb->dev = dev; - skb_reserve(skb, 2); /* word align the IP header */ + //skb_reserve(skb, 2); /* word align the IP header */ np->rx_skb_ring[i] = skb; - np->net_ring->rx_ring[i].addr = (unsigned long)skb->data; + np->net_ring->rx_ring[i].addr = (unsigned long)skb->net_page->ppte; //data; np->net_ring->rx_ring[i].size = RX_BUF_SIZE - 16; /* arbitrary */ } @@ -276,10 +276,18 @@ static void network_rx_int(int irq, void *dev_id, struct pt_regs *ptregs) again: for ( i = np->rx_idx; i != np->net_ring->rx_cons; i = RX_RING_INC(i) ) { + if (np->net_ring->rx_ring[i].status != RING_STATUS_OK) + { + printk("bad buffer on RX ring!(%d)\n", + np->net_ring->rx_ring[i].status); + continue; + } skb = np->rx_skb_ring[i]; + skb_put(skb, np->net_ring->rx_ring[i].size); skb->protocol = eth_type_trans(skb, dev); np->stats.rx_packets++; + np->stats.rx_bytes += np->net_ring->rx_ring[i].size; netif_rx(skb); dev->last_rx = jiffies; diff --git a/xenolinux-2.4.16-sparse/include/asm-xeno/io.h b/xenolinux-2.4.16-sparse/include/asm-xeno/io.h index 250b64fac8..0f097342ba 100644 --- a/xenolinux-2.4.16-sparse/include/asm-xeno/io.h +++ b/xenolinux-2.4.16-sparse/include/asm-xeno/io.h @@ -2,7 +2,7 @@ #define _ASM_IO_H #include <linux/config.h> - +#include <asm/hypervisor.h> /* * This file contains the definitions for the x86 IO instructions * inb/inw/inl/outb/outw/outl and the "string versions" of the same @@ -74,6 +74,22 @@ static inline void * phys_to_virt(unsigned long address) } /* + * Change virtual addresses to machine addresses and vv. + * These are equally trivial. + */ + +static inline unsigned long virt_to_mach(volatile void * address) +{ + return __pa(address) + (unsigned long) start_info.phys_base; +} + +static inline void *mach_to_virt(unsigned long address) +{ + return __va(address) - (unsigned long) start_info.phys_base; +} + + +/* * Change "struct page" to physical address. */ #define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT) diff --git a/xenolinux-2.4.16-sparse/net/core/skbuff.c b/xenolinux-2.4.16-sparse/net/core/skbuff.c index e6891de566..ec76f00de0 100644 --- a/xenolinux-2.4.16-sparse/net/core/skbuff.c +++ b/xenolinux-2.4.16-sparse/net/core/skbuff.c @@ -59,7 +59,7 @@ #include <net/tcp.h> #include <net/udp.h> #include <net/sock.h> - +#include <asm/io.h> #include <asm/uaccess.h> #include <asm/system.h> @@ -246,19 +246,17 @@ void init_net_pages(unsigned long order_pages) { np = net_page_table + i; np->virt_addr = (unsigned long)net_page_chunk + (i * PAGE_SIZE); - + // now fill the pte pointer: np->ppte = 0xdeadbeef; pgd = pgd_offset_k(np->virt_addr); - if (!pgd_none(*pgd)) - { - pmd = pmd_offset(pgd, np->virt_addr); - if (!pmd_none(*pmd)) - { - ptep = pte_offset(pmd, np->virt_addr); - np->ppte = (unsigned long)ptep; // neet to virt_to_phys this? - } - } + if (pgd_none(*pgd) || pgd_bad(*pgd)) BUG(); + + if (pmd_none(*pmd)) BUG(); + if (pmd_bad(*pmd)) BUG(); + + ptep = pte_offset(pmd, np->virt_addr); + np->ppte = (unsigned long)virt_to_mach(ptep); list_add_tail(&np->list, &net_page_list); } @@ -297,10 +295,11 @@ void free_net_page(struct net_page_info *np) spin_lock_irqsave(&net_page_list_lock, flags); - list_add_tail(&np->list, &net_page_list); + list_add(&np->list, &net_page_list); net_pages++; spin_unlock_irqrestore(&net_page_list_lock, flags); + } struct sk_buff *alloc_zc_skb(unsigned int size,int gfp_mask) @@ -427,12 +426,14 @@ static void skb_clone_fraglist(struct sk_buff *skb) static void skb_release_data(struct sk_buff *skb) { - if (!skb->cloned || + if (!skb->cloned || atomic_dec_and_test(&(skb_shinfo(skb)->dataref))) { if (skb_shinfo(skb)->nr_frags) { int i; - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) +{ put_page(skb_shinfo(skb)->frags[i].page); +} } if (skb_shinfo(skb)->frag_list) @@ -445,6 +446,7 @@ static void skb_release_data(struct sk_buff *skb) free_net_page(skb->net_page); } } + } /* |