mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
bitkeeper revision 1.22.1.9 (3e428de1nQwf1QUfwsp1nTiJP4ByhQ)
Zero-copy receive path now works over discontiguous memory with no guest-side pool.
This commit is contained in:
1 parent
07b29e865c
commit
cb4878ee12
18 files changed
+161
-3463
No files matched your search
@@ -67,10 +67,8 @@
|
||||
3ddb79bdDWFwINnKn29RlFDwGJhjYg xen-2.4.16/drivers/ide/ide-taskfile.c
|
||||
3ddb79bdkDY1bSOYkToP1Cc49VdBxg xen-2.4.16/drivers/ide/ide.c
|
||||
3ddb79bdPyAvT_WZTAFhaX0jp-yXSw xen-2.4.16/drivers/ide/ide_modes.h
|
||||
3ddb79bfogeJNHTIepPjd8fy1TyoTw xen-2.4.16/drivers/net/3c509.c
|
||||
3ddb79bfMlOcWUwjtg6oMYhGySHDDw xen-2.4.16/drivers/net/3c59x.c
|
||||
3ddb79bfl_DWxZQFKiJ2BXrSedV4lg xen-2.4.16/drivers/net/8139cp.c
|
||||
3ddb79bfLVGtyXNJS4NQg-lP21rndA xen-2.4.16/drivers/net/8139too.c
|
||||
3ddb79c0tWiE8xIFHszxipeVCGKTSA xen-2.4.16/drivers/net/Makefile
|
||||
3ddb79bfU-H1Hms4BuJEPPydjXUEaQ xen-2.4.16/drivers/net/Space.c
|
||||
3ddb79c0GejJrp1U6W4G6dYi-RiH4A xen-2.4.16/drivers/net/eepro100.c
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
|
||||
static unsigned long remap_base = 0;
|
||||
|
||||
#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
|
||||
#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY)
|
||||
#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
|
||||
#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY)
|
||||
|
||||
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
#include <asm/msr.h>
|
||||
#include <xeno/multiboot.h>
|
||||
|
||||
#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED)
|
||||
#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED|_PAGE_DIRTY)
|
||||
#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED)
|
||||
#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED|_PAGE_DIRTY)
|
||||
|
||||
extern int nr_mods;
|
||||
extern module_t *mod;
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -188,13 +188,15 @@
|
||||
/* "Knobs" that adjust features and parameters. */
|
||||
/* Set the copy breakpoint for the copy-only-tiny-frames scheme.
|
||||
Setting to > 1512 effectively disables this feature. */
|
||||
#ifndef __arm__
|
||||
/*#ifndef __arm__
|
||||
static const int rx_copybreak = 200;
|
||||
#else
|
||||
#else*/
|
||||
/* ARM systems perform better by disregarding the bus-master
|
||||
transfer capability of these cards. -- rmk */
|
||||
static const int rx_copybreak = 1513;
|
||||
#endif
|
||||
/*static const int rx_copybreak = 1513;
|
||||
#endif*/
|
||||
static const int rx_copybreak = 0; /* Xen doesn't copybreak in drivers. */
|
||||
|
||||
/* Allow setting MTU to a larger size, bypassing the normal ethernet setup. */
|
||||
static const int mtu = 1500;
|
||||
/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
|
||||
|
||||
@@ -78,13 +78,17 @@ MODULE_PARM (multicast_filter_limit, "i");
|
||||
MODULE_PARM_DESC (multicast_filter_limit, "8139cp maximum number of filtered multicast addresses");
|
||||
|
||||
/* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */
|
||||
#if defined(__alpha__) || defined(__arm__) || defined(__hppa__) \
|
||||
/*#if defined(__alpha__) || defined(__arm__) || defined(__hppa__) \
|
||||
|| defined(__sparc_) || defined(__ia64__) \
|
||||
|| defined(__sh__) || defined(__mips__)
|
||||
static int rx_copybreak = 1518;
|
||||
#else
|
||||
static int rx_copybreak = 100;
|
||||
#endif
|
||||
#endif*/
|
||||
|
||||
/* Xen doesn't do rx_copybreak in drivers. */
|
||||
static int rx_copybreak = 0;
|
||||
|
||||
MODULE_PARM (rx_copybreak, "i");
|
||||
MODULE_PARM_DESC (rx_copybreak, "8139cp Breakpoint at which Rx packets are copied");
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -43,12 +43,15 @@ static int rxdmacount /* = 0 */;
|
||||
|
||||
/* Set the copy breakpoint for the copy-only-tiny-buffer Rx method.
|
||||
Lower values use more memory, but are faster. */
|
||||
#if defined(__alpha__) || defined(__sparc__) || defined(__mips__) || \
|
||||
/*#if defined(__alpha__) || defined(__sparc__) || defined(__mips__) || \
|
||||
defined(__arm__)
|
||||
static int rx_copybreak = 1518;
|
||||
#else
|
||||
static int rx_copybreak = 200;
|
||||
#endif
|
||||
#endif*/
|
||||
|
||||
/* Xen doesn't do rx_copybreak in drivers. */
|
||||
static int rx_copybreak = 0;
|
||||
|
||||
/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
|
||||
static int max_interrupt_work = 20;
|
||||
|
||||
@@ -66,7 +66,7 @@ static int tx_start = 1; /* Mapping -- 0:20, 1:64, 2:128, 3:~220 (depends on chi
|
||||
static struct net_device *pcnet32_dev;
|
||||
|
||||
static const int max_interrupt_work = 80;
|
||||
static const int rx_copybreak = 200;
|
||||
static const int rx_copybreak = 0; /* 200; Xen doesn't do in-driver copybreak. */
|
||||
|
||||
#define PORT_AUI 0x00
|
||||
#define PORT_10BT 0x01
|
||||
|
||||
@@ -170,9 +170,9 @@ static int tulip_rx(struct net_device *dev)
|
||||
#endif
|
||||
/* Check if the packet is long enough to accept without copying
|
||||
to a minimally-sized skbuff. */
|
||||
//if (pkt_len < tulip_rx_copybreak
|
||||
// && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
|
||||
if (0) {
|
||||
if (pkt_len < tulip_rx_copybreak
|
||||
&& (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
|
||||
//if (0) {
|
||||
skb->dev = dev;
|
||||
skb_reserve(skb, 2); /* 16 byte align the IP header */
|
||||
pci_dma_sync_single(tp->pdev,
|
||||
|
||||
@@ -60,13 +60,16 @@ const char * const medianame[32] = {
|
||||
};
|
||||
|
||||
/* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */
|
||||
#if defined(__alpha__) || defined(__arm__) || defined(__hppa__) \
|
||||
/*#if defined(__alpha__) || defined(__arm__) || defined(__hppa__) \
|
||||
|| defined(__sparc_) || defined(__ia64__) \
|
||||
|| defined(__sh__) || defined(__mips__)
|
||||
static int rx_copybreak = 1518;
|
||||
#else
|
||||
static int rx_copybreak = 100;
|
||||
#endif
|
||||
*/
|
||||
/* Xen doesn't do rx_copybreak in drivers. */
|
||||
static int rx_copybreak = 0;
|
||||
|
||||
/*
|
||||
Set the bus performance register.
|
||||
|
||||
@@ -89,7 +89,7 @@ typedef struct pfn_info {
|
||||
* references exist of teh current type. A change in type can only occur
|
||||
* when type_count == 0.
|
||||
*/
|
||||
#define PG_type_mask (7<<24) /* bits 24-26 */
|
||||
#define PG_type_mask (15<<24) /* bits 24-27 */
|
||||
#define PGT_none (0<<24) /* no special uses of this page */
|
||||
#define PGT_l1_page_table (1<<24) /* using this page as an L1 page table? */
|
||||
#define PGT_l2_page_table (2<<24) /* using this page as an L2 page table? */
|
||||
@@ -98,6 +98,7 @@ typedef struct pfn_info {
|
||||
#define PGT_gdt_page (5<<24) /* using this page in a GDT? */
|
||||
#define PGT_ldt_page (6<<24) /* using this page in an LDT? */
|
||||
#define PGT_writeable_page (7<<24) /* has writable mappings of this page? */
|
||||
#define PGT_net_rx_buf (8<<24) /* this page has been pirated by the net code. */
|
||||
|
||||
#define PageSlab(page) test_bit(PG_slab, &(page)->flags)
|
||||
#define PageSetSlab(page) set_bit(PG_slab, &(page)->flags)
|
||||
@@ -120,6 +121,7 @@ void init_frametable(unsigned long nr_pages);
|
||||
* will use it to store a "physical" frame number to give the appearance of
|
||||
* contiguous (or near contiguous) physical memory.
|
||||
*/
|
||||
#undef machine_to_phys_mapping
|
||||
#define machine_to_phys_mapping ((unsigned long *)RDWR_MPT_VIRT_START)
|
||||
|
||||
/* Part of the domain API. */
|
||||
|
||||
+42
-18
@@ -714,8 +714,7 @@ void deliver_packet(struct sk_buff *skb, net_vif_t *vif)
|
||||
if ( (skb->len + ETH_HLEN) < rx->size )
|
||||
rx->size = skb->len + ETH_HLEN;
|
||||
|
||||
if (rx->flush_count == tlb_flush_count[smp_processor_id()])
|
||||
flush_tlb_all();
|
||||
|
||||
|
||||
g_pte = map_domain_mem(rx->addr);
|
||||
|
||||
@@ -723,15 +722,21 @@ void deliver_packet(struct sk_buff *skb, net_vif_t *vif)
|
||||
h_pfn = skb->pf;
|
||||
|
||||
//flip and/or set relevant pf_info fields.
|
||||
tmp = g_pfn->next; g_pfn->next = h_pfn->next; h_pfn->next = tmp;
|
||||
tmp = g_pfn->prev; g_pfn->prev = h_pfn->prev; h_pfn->prev = tmp;
|
||||
//tmp = g_pfn->next; g_pfn->next = h_pfn->next; h_pfn->next = tmp;
|
||||
//tmp = g_pfn->prev; g_pfn->prev = h_pfn->prev; h_pfn->prev = tmp;
|
||||
tmp = g_pfn->flags; g_pfn->flags = h_pfn->flags; h_pfn->flags = tmp;
|
||||
h_pfn->tot_count = 1;
|
||||
h_pfn->type_count = g_pfn->type_count;
|
||||
h_pfn->tot_count = h_pfn->type_count = 1;
|
||||
g_pfn->tot_count = g_pfn->type_count = 0;
|
||||
h_pfn->flags = current->domain | PGT_l1_page_table;
|
||||
g_pfn->flags = PGT_l1_page_table;
|
||||
h_pfn->flags = g_pfn->flags & ~ PG_type_mask;
|
||||
if (*g_pte & _PAGE_RW) h_pfn->flags |= PGT_writeable_page;
|
||||
g_pfn->flags = 0;
|
||||
//point guest pte at the new page:
|
||||
|
||||
//printk("newmpfn: %lx, old mpfn: %lx, old:(%lx) new:(%lx)\n", h_pfn - frame_table, *g_pte >> PAGE_SHIFT, machine_to_phys_mapping[h_pfn - frame_table], machine_to_phys_mapping[*g_pte >> PAGE_SHIFT]);
|
||||
|
||||
machine_to_phys_mapping[h_pfn - frame_table]
|
||||
= machine_to_phys_mapping[g_pfn - frame_table];
|
||||
|
||||
*g_pte = (*g_pte & ~PAGE_MASK)
|
||||
| (((h_pfn - frame_table) << PAGE_SHIFT) & PAGE_MASK);
|
||||
*g_pte |= _PAGE_PRESENT;
|
||||
@@ -1000,6 +1005,9 @@ void update_shared_ring(void)
|
||||
shadow_ring->rx_idx = RX_RING_INC(shadow_ring->rx_idx);
|
||||
net_ring->rx_cons = RX_RING_INC(net_ring->rx_cons);
|
||||
|
||||
if (rx->flush_count == tlb_flush_count[smp_processor_id()])
|
||||
__flush_tlb();
|
||||
|
||||
if ( net_ring->rx_cons == net_ring->rx_event )
|
||||
set_bit(_EVENT_NET_RX_FOR_VIF(nvif), &s->events);
|
||||
|
||||
@@ -1124,8 +1132,8 @@ void flush_rx_queue(void)
|
||||
h_pfn = skb->pf;
|
||||
|
||||
|
||||
tmp = g_pfn->next; g_pfn->next = h_pfn->next; h_pfn->next = tmp;
|
||||
tmp = g_pfn->prev; g_pfn->prev = h_pfn->prev; h_pfn->prev = tmp;
|
||||
//tmp = g_pfn->next; g_pfn->next = h_pfn->next; h_pfn->next = tmp;
|
||||
//tmp = g_pfn->prev; g_pfn->prev = h_pfn->prev; h_pfn->prev = tmp;
|
||||
tmp = g_pfn->flags; g_pfn->flags = h_pfn->flags; h_pfn->flags = tmp;
|
||||
|
||||
h_pfn->tot_count = 1;
|
||||
@@ -2244,23 +2252,39 @@ printk("LOCAL DELIVERY!\n");
|
||||
pfn = rx->addr >> PAGE_SHIFT;
|
||||
page = frame_table + pfn;
|
||||
|
||||
shadow_ring->rx_ring[i].status = RING_STATUS_OK;
|
||||
shadow_ring->rx_ring[i].status = RING_STATUS_BAD_PAGE;
|
||||
|
||||
if (!(page->flags & PGT_l1_page_table)
|
||||
|| !((page->flags & PG_domain_mask) == current->domain))
|
||||
shadow_ring->rx_ring[i].status = RING_STATUS_BAD_PAGE;
|
||||
if ( page->flags != (PGT_l1_page_table | current->domain) )
|
||||
{
|
||||
BUG();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
g_pte = map_domain_mem(rx->addr);
|
||||
|
||||
if (!(*g_pte & _PAGE_PRESENT))
|
||||
shadow_ring->rx_ring[i].status = RING_STATUS_BAD_PAGE;
|
||||
page = (*g_pte >> PAGE_SHIFT) + frame_table;
|
||||
if (page->tot_count != 1)
|
||||
shadow_ring->rx_ring[i].status = RING_STATUS_BAD_PAGE;
|
||||
{
|
||||
BUG();
|
||||
unmap_domain_mem(g_pte);
|
||||
continue;
|
||||
}
|
||||
|
||||
page = (*g_pte >> PAGE_SHIFT) + frame_table;
|
||||
|
||||
if (page->tot_count != 1)
|
||||
{
|
||||
printk("!\n");
|
||||
unmap_domain_mem(g_pte);
|
||||
continue;
|
||||
}
|
||||
|
||||
// The pte they passed was good, so we take it away from them.
|
||||
shadow_ring->rx_ring[i].status = RING_STATUS_OK;
|
||||
*g_pte &= ~_PAGE_PRESENT;
|
||||
page->flags = (page->flags & ~PG_type_mask) | PGT_net_rx_buf;
|
||||
rx->flush_count = tlb_flush_count[smp_processor_id()];
|
||||
|
||||
unmap_domain_mem(g_pte);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ static inline u8 *alloc_skb_data_page(struct sk_buff *skb)
|
||||
pf = list_entry(list_ptr, struct pfn_info, list);
|
||||
pf->flags = 0; // owned by dom0
|
||||
list_del(&pf->list);
|
||||
pf->next = pf->prev = (pf - frame_table);
|
||||
//pf->next = pf->prev = (pf - frame_table);
|
||||
free_pfns--;
|
||||
|
||||
spin_unlock_irqrestore(&free_list_lock, flags);
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
#define NET_TX_IRQ _EVENT_NET_TX
|
||||
@@ -48,6 +49,8 @@ static void cleanup_module(void);
|
||||
|
||||
static struct list_head dev_list;
|
||||
|
||||
static unsigned int net_countx;
|
||||
|
||||
/*
|
||||
* RX RING: RX_IDX <= rx_cons <= rx_prod
|
||||
* TX RING: TX_IDX <= tx_cons <= tx_prod
|
||||
@@ -72,7 +75,7 @@ struct net_private
|
||||
static int network_open(struct net_device *dev)
|
||||
{
|
||||
struct net_private *np = dev->priv;
|
||||
int error;
|
||||
int error = 0;
|
||||
char *rxlabel, *txlabel;
|
||||
|
||||
// This is inevitably not the right way to allocate a couple of static strings.
|
||||
@@ -179,13 +182,59 @@ static void network_tx_buf_gc(struct net_device *dev)
|
||||
spin_unlock_irqrestore(&np->tx_lock, flags);
|
||||
}
|
||||
|
||||
inline unsigned long get_ppte(unsigned long addr)
|
||||
{
|
||||
unsigned long ppte = 0xdeadbeef;
|
||||
pgd_t *pgd; pmd_t *pmd; pte_t *ptep;
|
||||
pgd = pgd_offset_k(addr);
|
||||
|
||||
if (pgd_none(*pgd) || pgd_bad(*pgd)) BUG();
|
||||
|
||||
pmd = pmd_offset(pgd, addr);
|
||||
if (pmd_none(*pmd)) BUG();
|
||||
if (pmd_bad(*pmd)) BUG();
|
||||
|
||||
ptep = pte_offset(pmd, addr);
|
||||
ppte = (unsigned long)phys_to_machine(virt_to_phys(ptep));
|
||||
|
||||
return ppte;
|
||||
}
|
||||
/*
|
||||
static void validate_free_list(void)
|
||||
{
|
||||
unsigned long addr, ppfn, mpfn, mpfn2, flags;
|
||||
struct list_head *i;
|
||||
struct net_page_info *np;
|
||||
|
||||
printk(KERN_ALERT "Walking free pages:\n");
|
||||
|
||||
spin_lock_irqsave(&net_page_list_lock, flags);
|
||||
|
||||
list_for_each(i, &net_page_list)
|
||||
{
|
||||
np = list_entry(i, struct net_page_info, list);
|
||||
addr = np->virt_addr;
|
||||
ppfn = virt_to_phys(addr) >> PAGE_SHIFT;
|
||||
mpfn = get_ppte(addr);
|
||||
mpfn2 = phys_to_machine_mapping[ppfn];
|
||||
|
||||
mpfn = (*(unsigned long *)phys_to_virt(machine_to_phys(mpfn))) >> PAGE_SHIFT;
|
||||
if (mpfn != mpfn2) printk(KERN_ALERT "mpfn %lu != %lu\n", mpfn, mpfn2);
|
||||
|
||||
if (machine_to_phys_mapping[mpfn] != ppfn) printk(KERN_ALERT "ppfn %lu != %lu\n", machine_to_phys_mapping[mpfn], ppfn);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&net_page_list_lock, flags);
|
||||
|
||||
}
|
||||
*/
|
||||
static void network_alloc_rx_buffers(struct net_device *dev)
|
||||
{
|
||||
unsigned int i;
|
||||
struct net_private *np = dev->priv;
|
||||
struct sk_buff *skb;
|
||||
unsigned int end = RX_RING_ADD(np->rx_idx, RX_MAX_ENTRIES);
|
||||
|
||||
|
||||
for ( i = np->net_ring->rx_prod; i != end; i = RX_RING_INC(i) )
|
||||
{
|
||||
@@ -194,8 +243,9 @@ static void network_alloc_rx_buffers(struct net_device *dev)
|
||||
skb->dev = dev;
|
||||
//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->net_page->ppte; //data;
|
||||
np->net_ring->rx_ring[i].addr = get_ppte(skb->head);
|
||||
np->net_ring->rx_ring[i].size = RX_BUF_SIZE - 16; /* arbitrary */
|
||||
//printk(KERN_ALERT "[%p]\n", phys_to_machine(virt_to_phys(skb->page_ptr)));
|
||||
}
|
||||
|
||||
np->net_ring->rx_prod = i;
|
||||
@@ -273,6 +323,8 @@ static void network_rx_int(int irq, void *dev_id, struct pt_regs *ptregs)
|
||||
struct net_private *np = dev->priv;
|
||||
struct sk_buff *skb;
|
||||
|
||||
/*if (net_countx++ % 100 == 0) validate_free_list();*/
|
||||
|
||||
again:
|
||||
for ( i = np->rx_idx; i != np->net_ring->rx_cons; i = RX_RING_INC(i) )
|
||||
{
|
||||
@@ -283,7 +335,14 @@ static void network_rx_int(int irq, void *dev_id, struct pt_regs *ptregs)
|
||||
continue;
|
||||
}
|
||||
skb = np->rx_skb_ring[i];
|
||||
|
||||
|
||||
//printk(KERN_ALERT "[%u]: ptmm[%lx] old:(%lx) new:(%lx)\n", i , virt_to_phys(skb->head) >> PAGE_SHIFT, phys_to_machine_mapping[virt_to_phys(skb->head) >> PAGE_SHIFT], (*(unsigned long *)phys_to_virt(machine_to_phys(np->net_ring->rx_ring[i].addr))) >> PAGE_SHIFT);
|
||||
|
||||
phys_to_machine_mapping[virt_to_phys(skb->head) >> PAGE_SHIFT] =
|
||||
(*(unsigned long *)phys_to_virt(
|
||||
machine_to_phys(np->net_ring->rx_ring[i].addr))
|
||||
) >> PAGE_SHIFT;
|
||||
|
||||
skb_put(skb, np->net_ring->rx_ring[i].size);
|
||||
skb->protocol = eth_type_trans(skb, dev);
|
||||
np->stats.rx_packets++;
|
||||
|
||||
@@ -78,17 +78,6 @@ static inline void * phys_to_virt(unsigned long address)
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@@ -43,7 +43,8 @@
|
||||
#define SKB_ZERO_COPY 1
|
||||
|
||||
#define NUM_NET_PAGES 9 // about 1Meg of buffers. (2^9)
|
||||
struct net_page_info {
|
||||
|
||||
/*struct net_page_info {
|
||||
struct list_head list;
|
||||
unsigned long virt_addr;
|
||||
unsigned long ppte;
|
||||
@@ -54,7 +55,7 @@ extern struct net_page_info *net_page_table;
|
||||
extern struct list_head net_page_list;
|
||||
extern spinlock_t net_page_list_lock;
|
||||
extern unsigned int net_pages;
|
||||
|
||||
*/
|
||||
/* End zero copy additions */
|
||||
|
||||
#define HAVE_ALLOC_SKB /* For the drivers to know */
|
||||
|
||||
@@ -64,12 +64,13 @@
|
||||
#include <asm/system.h>
|
||||
|
||||
/* zc globals: */
|
||||
/*
|
||||
char *net_page_chunk;
|
||||
struct net_page_info *net_page_table;
|
||||
struct list_head net_page_list;
|
||||
spinlock_t net_page_list_lock = SPIN_LOCK_UNLOCKED;
|
||||
unsigned int net_pages;
|
||||
|
||||
*/
|
||||
|
||||
|
||||
int sysctl_hot_list_len = 128;
|
||||
@@ -229,7 +230,7 @@ nohead:
|
||||
}
|
||||
|
||||
/* begin zc code additions: */
|
||||
|
||||
/*
|
||||
void init_net_pages(unsigned long order_pages)
|
||||
{
|
||||
int i;
|
||||
@@ -248,16 +249,16 @@ void init_net_pages(unsigned long order_pages)
|
||||
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) || pgd_bad(*pgd)) BUG();
|
||||
//np->ppte = 0xdeadbeef;
|
||||
//pgd = pgd_offset_k(np->virt_addr);
|
||||
//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);
|
||||
//if (pmd_none(*pmd)) BUG();
|
||||
//if (pmd_bad(*pmd)) BUG();
|
||||
|
||||
//ptep = pte_offset(pmd, np->virt_addr);
|
||||
//np->ppte = phys_to_machine(virt_to_phys(ptep));
|
||||
|
||||
list_add_tail(&np->list, &net_page_list);
|
||||
}
|
||||
net_pages = nr_pages;
|
||||
@@ -267,6 +268,7 @@ void init_net_pages(unsigned long order_pages)
|
||||
|
||||
struct net_page_info *get_net_page(void)
|
||||
{
|
||||
|
||||
struct list_head *list_ptr;
|
||||
struct net_page_info *np;
|
||||
unsigned long flags;
|
||||
@@ -301,7 +303,7 @@ void free_net_page(struct net_page_info *np)
|
||||
spin_unlock_irqrestore(&net_page_list_lock, flags);
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
struct sk_buff *alloc_zc_skb(unsigned int size,int gfp_mask)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
@@ -332,12 +334,13 @@ struct sk_buff *alloc_zc_skb(unsigned int size,int gfp_mask)
|
||||
printk("alloc_zc_skb called with unruly size.\n");
|
||||
size = PAGE_SIZE;
|
||||
}
|
||||
skb->net_page = get_net_page();
|
||||
/*skb->net_page = get_net_page();
|
||||
if (skb->net_page == NULL)
|
||||
{
|
||||
goto nodata;
|
||||
}
|
||||
data = (u8 *)skb->net_page->virt_addr;
|
||||
data = (u8 *)skb->net_page->virt_addr;*/
|
||||
data = (char *)__get_free_page(gfp_mask);
|
||||
if (data == NULL)
|
||||
goto nodata;
|
||||
/* XXX: does not include slab overhead */
|
||||
@@ -443,7 +446,9 @@ static void skb_release_data(struct sk_buff *skb)
|
||||
{
|
||||
kfree(skb->head);
|
||||
} else {// SKB_ZERO_COPY
|
||||
free_net_page(skb->net_page);
|
||||
//free_net_page(skb->net_page);
|
||||
//printk(KERN_ALERT "<%p>\n", phys_to_machine(virt_to_phys(skb->head)));
|
||||
free_page((void *)skb->head);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -559,7 +564,7 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask)
|
||||
C(tc_index);
|
||||
#endif
|
||||
C(skb_type);
|
||||
C(net_page);
|
||||
//C(net_page);
|
||||
atomic_inc(&(skb_shinfo(skb)->dataref));
|
||||
skb->cloned = 1;
|
||||
#ifdef CONFIG_NETFILTER
|
||||
@@ -1361,7 +1366,7 @@ void __init skb_init(void)
|
||||
if (!skbuff_head_cache)
|
||||
panic("cannot create skbuff cache");
|
||||
|
||||
init_net_pages(NUM_NET_PAGES);
|
||||
//init_net_pages(NUM_NET_PAGES);
|
||||
|
||||
for (i=0; i<NR_CPUS; i++)
|
||||
skb_queue_head_init(&skb_head_pool[i].list);
|
||||
|
||||