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:
akw27@boulderdash.cl.cam.ac.uk committed 2003-02-06 16:31:29 +00:00
1 parent 07b29e865c
commit cb4878ee12
18 files changed
+161 -3463

No files matched your search

-2
View File
@@ -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
+2 -2
View File
@@ -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)
+2 -2
View File
@@ -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
+6 -4
View File
@@ -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. */
+6 -2
View File
@@ -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
+5 -2
View File
@@ -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;
+1 -1
View File
@@ -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
+3 -3
View File
@@ -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,
+4 -1
View File
@@ -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.
+3 -1
View File
@@ -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
View File
@@ -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);
}
}
+1 -1
View File
@@ -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 */
+21 -16
View File
@@ -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);
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.