aboutsummaryrefslogtreecommitdiffstats
path: root/xenolinux-2.4.16-sparse
diff options
context:
space:
mode:
authorakw27@boulderdash.cl.cam.ac.uk <akw27@boulderdash.cl.cam.ac.uk>2003-02-05 13:40:29 +0000
committerakw27@boulderdash.cl.cam.ac.uk <akw27@boulderdash.cl.cam.ac.uk>2003-02-05 13:40:29 +0000
commite5e9ce51999838451bf4854a533a1bca25455133 (patch)
treebcd9fdeadaa740f2fd1a7dc6b02c22d327bb1280 /xenolinux-2.4.16-sparse
parentfbc79ebdf40b7035b2083a78526a42486c819d6b (diff)
downloadxen-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.c12
-rw-r--r--xenolinux-2.4.16-sparse/include/asm-xeno/io.h18
-rw-r--r--xenolinux-2.4.16-sparse/net/core/skbuff.c30
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);
}
}
+
}
/*