mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
bitkeeper revision 1.15.1.12 (3e3bb848bQ7Yn0pGaQ3H5n8g3MYQWQ)
Merge boulderdash.cl.cam.ac.uk:/usr/groups/xeno/users/akw27/xeno into boulderdash.cl.cam.ac.uk:/anfs/scratch/boulderdash/akw27/argh/xeno
This commit is contained in:
commit
fbc79ebdf4
13 files changed
+2786
-41
No files matched your search
@@ -399,9 +399,11 @@
|
||||
3ddb79ba2qYtIQAT_-vCFkkZUXu_UQ xenolinux-2.4.16-sparse/include/asm-xeno/user.h
|
||||
3ddb79bbqhb9X9qWOz5Bv4wOzrkITg xenolinux-2.4.16-sparse/include/asm-xeno/vga.h
|
||||
3ddb79bbA52x94o6uwDYsbzrH2hjzA xenolinux-2.4.16-sparse/include/asm-xeno/xor.h
|
||||
3e37c39fVCSGQENtY6g7muaq_THliw xenolinux-2.4.16-sparse/include/linux/skbuff.h
|
||||
3ddb79bb_7YG4U75ZmEic9YXWTW7Vw xenolinux-2.4.16-sparse/include/linux/sunrpc/debug.h
|
||||
3ddb79bcxkVPfWlZ1PQKvDrfArzOVw xenolinux-2.4.16-sparse/kernel/panic.c
|
||||
3ddb79bbP31im-mx2NbfthSeqty1Dg xenolinux-2.4.16-sparse/mk
|
||||
3e15d52e0_j129JPvo7xfYGndVFpwQ xenolinux-2.4.16-sparse/mm/memory.c
|
||||
3e15d535DLvpzTrLRUIerB69LpJD1g xenolinux-2.4.16-sparse/mm/mremap.c
|
||||
3e15d531m1Y1_W8ki64AFOU_ua4C4w xenolinux-2.4.16-sparse/mm/swapfile.c
|
||||
3e37c312QFuzIxXsuAgO6IRt3Tp96Q xenolinux-2.4.16-sparse/net/core/skbuff.c
|
||||
@@ -334,10 +334,13 @@ static unsigned int alloc_new_dom_mem(struct task_struct *p, unsigned int kbytes
|
||||
struct pfn_info *pf, *pf_head;
|
||||
unsigned int alloc_pfns;
|
||||
unsigned int req_pages;
|
||||
unsigned long flags;
|
||||
|
||||
/* how many pages do we need to alloc? */
|
||||
req_pages = kbytes >> (PAGE_SHIFT - 10);
|
||||
|
||||
spin_lock_irqsave(&free_list_lock, flags);
|
||||
|
||||
/* is there enough mem to serve the request? */
|
||||
if(req_pages > free_pfns)
|
||||
return -1;
|
||||
@@ -369,6 +372,8 @@ static unsigned int alloc_new_dom_mem(struct task_struct *p, unsigned int kbytes
|
||||
|
||||
free_pfns--;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&free_list_lock, flags);
|
||||
|
||||
p->tot_pages = req_pages;
|
||||
|
||||
|
||||
@@ -206,6 +206,7 @@ unsigned long frame_table_size;
|
||||
unsigned long max_page;
|
||||
|
||||
struct list_head free_list;
|
||||
spinlock_t free_list_lock = SPIN_LOCK_UNLOCKED;
|
||||
unsigned int free_pfns;
|
||||
|
||||
static int tlb_flush[NR_CPUS];
|
||||
@@ -219,6 +220,7 @@ void __init init_frametable(unsigned long nr_pages)
|
||||
{
|
||||
struct pfn_info *pf;
|
||||
unsigned long page_index;
|
||||
unsigned long flags;
|
||||
|
||||
memset(tlb_flush, 0, sizeof(tlb_flush));
|
||||
|
||||
@@ -232,6 +234,7 @@ void __init init_frametable(unsigned long nr_pages)
|
||||
memset(frame_table, 0, frame_table_size);
|
||||
|
||||
/* Put all domain-allocatable memory on a free list. */
|
||||
spin_lock_irqsave(&free_list_lock, flags);
|
||||
INIT_LIST_HEAD(&free_list);
|
||||
for( page_index = (MAX_MONITOR_ADDRESS + frame_table_size) >> PAGE_SHIFT;
|
||||
page_index < nr_pages;
|
||||
@@ -240,6 +243,7 @@ void __init init_frametable(unsigned long nr_pages)
|
||||
pf = list_entry(&frame_table[page_index].list, struct pfn_info, list);
|
||||
list_add_tail(&pf->list, &free_list);
|
||||
}
|
||||
spin_unlock_irqrestore(&free_list_lock, flags);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -170,8 +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 (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,
|
||||
|
||||
@@ -75,7 +75,19 @@ static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
|
||||
if (direction == PCI_DMA_NONE)
|
||||
BUG();
|
||||
flush_write_buffers();
|
||||
return virt_to_bus(ptr);
|
||||
|
||||
if ((unsigned long) ptr > PAGE_OFFSET)
|
||||
return virt_to_bus(ptr);
|
||||
|
||||
/* If an address that is not in hypervisor VM is passed to this
|
||||
* function (ie > PAGE_OFFSET) we assume that the passer knows
|
||||
* what they are doing, and have passed a physical address that
|
||||
* should not be converted here. This is a little hackish, but
|
||||
* is being added to allow references to domain memory in order
|
||||
* to support zero-copy network code.
|
||||
*/
|
||||
|
||||
return (dma_addr_t) ptr;
|
||||
}
|
||||
|
||||
/* Unmap a single streaming mode DMA translation. The dma_addr and size
|
||||
|
||||
@@ -26,8 +26,8 @@ typedef struct rx_entry_st {
|
||||
int status; /* per descriptor status. */
|
||||
} rx_entry_t;
|
||||
|
||||
#define TX_RING_SIZE 1024
|
||||
#define RX_RING_SIZE 1024
|
||||
#define TX_RING_SIZE 256
|
||||
#define RX_RING_SIZE 256
|
||||
typedef struct net_ring_st {
|
||||
/*
|
||||
* Guest OS places packets into ring at tx_prod.
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <asm/desc.h>
|
||||
#include <xeno/list.h>
|
||||
#include <hypervisor-ifs/hypervisor-if.h>
|
||||
#include <xeno/spinlock.h>
|
||||
|
||||
/* XXX KAF: These may die eventually, but so many refs in slab.c :((( */
|
||||
|
||||
@@ -110,6 +111,7 @@ typedef struct pfn_info {
|
||||
extern frame_table_t * frame_table;
|
||||
extern unsigned long frame_table_size;
|
||||
extern struct list_head free_list;
|
||||
extern spinlock_t free_list_lock;
|
||||
extern unsigned int free_pfns;
|
||||
extern unsigned long max_page;
|
||||
void init_frametable(unsigned long nr_pages);
|
||||
|
||||
@@ -34,6 +34,10 @@
|
||||
#define VIF_DROP -3
|
||||
#define VIF_ANY_INTERFACE -4
|
||||
|
||||
//skb_type values:
|
||||
#define SKB_NORMAL 0
|
||||
#define SKB_ZERO_COPY 1
|
||||
|
||||
#define HAVE_ALLOC_SKB /* For the drivers to know */
|
||||
#define HAVE_ALIGNABLE_SKB /* Ditto 8) */
|
||||
#define SLAB_SKB /* Slabified skbuffs */
|
||||
@@ -187,7 +191,7 @@ struct sk_buff {
|
||||
unsigned int data_len;
|
||||
unsigned int csum; /* Checksum */
|
||||
unsigned char __unused, /* Dead field, may be reused */
|
||||
cloned, /* head may be cloned (check refcnt to be sure). */
|
||||
cloned, /* head may be cloned (check refcnt to be sure) */
|
||||
pkt_type, /* Packet class */
|
||||
ip_summed; /* Driver fed us an IP checksum */
|
||||
__u32 priority; /* Packet queueing priority */
|
||||
@@ -203,8 +207,12 @@ struct sk_buff {
|
||||
|
||||
void (*destructor)(struct sk_buff *); /* Destruct function */
|
||||
|
||||
int src_vif; /* vif we came from */
|
||||
int dst_vif; /* vif we are bound for */
|
||||
unsigned int skb_type; /* SKB_NORMAL or SKB_ZERO_COPY */
|
||||
struct pfn_info *pf; /* record of physical pf address for freeing */
|
||||
int src_vif; /* vif we came from */
|
||||
int dst_vif; /* vif we are bound for */
|
||||
struct skb_shared_info shinfo; /* shared info is no longer shared in Xen. */
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -244,6 +252,7 @@ struct sk_buff {
|
||||
|
||||
extern void __kfree_skb(struct sk_buff *skb);
|
||||
extern struct sk_buff * alloc_skb(unsigned int size, int priority);
|
||||
extern struct sk_buff * alloc_zc_skb(unsigned int size, int priority);
|
||||
extern void kfree_skbmem(struct sk_buff *skb);
|
||||
extern struct sk_buff * skb_clone(struct sk_buff *skb, int priority);
|
||||
extern struct sk_buff * skb_copy(const struct sk_buff *skb, int priority);
|
||||
@@ -259,7 +268,8 @@ extern void skb_over_panic(struct sk_buff *skb, int len, void *here);
|
||||
extern void skb_under_panic(struct sk_buff *skb, int len, void *here);
|
||||
|
||||
/* Internal */
|
||||
#define skb_shinfo(SKB) ((struct skb_shared_info *)((SKB)->end))
|
||||
//#define skb_shinfo(SKB) ((struct skb_shared_info *)((SKB)->end))
|
||||
#define skb_shinfo(SKB) ((struct skb_shared_info *)(&(SKB)->shinfo))
|
||||
|
||||
/**
|
||||
* skb_queue_empty - check if a queue is empty
|
||||
@@ -1045,7 +1055,8 @@ static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = alloc_skb(length+16, gfp_mask);
|
||||
//skb = alloc_skb(length+16, gfp_mask);
|
||||
skb = alloc_zc_skb(length+16, gfp_mask);
|
||||
if (skb)
|
||||
skb_reserve(skb,16);
|
||||
return skb;
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <linux/pkt_sched.h>
|
||||
|
||||
#include <linux/event.h>
|
||||
#include <asm/domain_page.h>
|
||||
|
||||
#define BUG_TRAP ASSERT
|
||||
#define notifier_call_chain(_a,_b,_c) ((void)0)
|
||||
@@ -695,6 +696,21 @@ int netif_rx(struct sk_buff *skb)
|
||||
if (skb->stamp.tv_sec == 0)
|
||||
get_fast_time(&skb->stamp);
|
||||
|
||||
/* Attempt to handle zero-copy packets here: */
|
||||
if (skb->skb_type == SKB_ZERO_COPY)
|
||||
{
|
||||
skb->head = (u8 *)map_domain_mem(((skb->pf - frame_table) << PAGE_SHIFT));
|
||||
|
||||
/* remapping this address really screws up all the skb pointers. We need
|
||||
* to map them all here sufficiently to get the packet demultiplexed.
|
||||
*/
|
||||
|
||||
skb->data = skb->head;
|
||||
skb_reserve(skb,16); // need to ensure that all the drivers and not just tulip do this.
|
||||
skb->mac.raw = skb->data;
|
||||
skb->data += ETH_HLEN;
|
||||
}
|
||||
|
||||
/* The code is rearranged so that the path is the most
|
||||
short when CPU is congested, but is still operating.
|
||||
*/
|
||||
@@ -747,10 +763,18 @@ drop:
|
||||
netdev_rx_stat[this_cpu].dropped++;
|
||||
local_irq_restore(flags);
|
||||
|
||||
if (skb->skb_type == SKB_ZERO_COPY)
|
||||
unmap_domain_mem(skb->head);
|
||||
|
||||
kfree_skb(skb);
|
||||
return NET_RX_DROP;
|
||||
|
||||
found:
|
||||
if (skb->skb_type == SKB_ZERO_COPY) {
|
||||
unmap_domain_mem(skb->head);
|
||||
//skb->head = (u8 *)((skb->pf - frame_table) << PAGE_SHIFT);
|
||||
skb->head = skb->data = skb->tail = (void *)0xdeadbeef;
|
||||
}
|
||||
hyp_event_notify(cpu_mask);
|
||||
local_irq_restore(flags);
|
||||
return 0;
|
||||
@@ -930,8 +954,28 @@ void flush_rx_queue(void)
|
||||
rx = shadow_ring->rx_ring+i;
|
||||
if ( (skb->len + ETH_HLEN) < rx->size )
|
||||
rx->size = skb->len + ETH_HLEN;
|
||||
|
||||
/* remap the packet again. This is very temporary and will shortly be
|
||||
* replaced with a page swizzle.
|
||||
*/
|
||||
|
||||
if (skb->skb_type == SKB_ZERO_COPY)
|
||||
{
|
||||
skb->head = (u8 *)map_domain_mem(((skb->pf - frame_table) << PAGE_SHIFT));
|
||||
skb->data = skb->head;
|
||||
skb_reserve(skb,16);
|
||||
skb->mac.raw = skb->data;
|
||||
skb->data += ETH_HLEN;
|
||||
}
|
||||
|
||||
copy_to_user((void *)rx->addr, skb->mac.raw, rx->size);
|
||||
copy_to_user(net_ring->rx_ring+i, rx, sizeof(rx));
|
||||
|
||||
if (skb->skb_type == SKB_ZERO_COPY)
|
||||
{
|
||||
unmap_domain_mem(skb->head);
|
||||
skb->head = skb->data = skb->tail = (void *)0xdeadbeef;
|
||||
}
|
||||
}
|
||||
net_ring->rx_cons = (i+1) & (RX_RING_SIZE-1);
|
||||
if ( net_ring->rx_cons == net_ring->rx_event )
|
||||
|
||||
+40
-30
@@ -161,52 +161,62 @@ unsigned short eth_type_trans(struct sk_buff *skb, struct net_device *dev)
|
||||
struct ethhdr *eth;
|
||||
unsigned char *rawp;
|
||||
|
||||
skb->mac.raw=skb->data;
|
||||
skb_pull(skb,dev->hard_header_len);
|
||||
eth= skb->mac.ethernet;
|
||||
if (skb->skb_type == SKB_ZERO_COPY)
|
||||
{
|
||||
skb_pull(skb,dev->hard_header_len);
|
||||
skb->mac.raw= (void *)0xdeadbeef;
|
||||
return htons(ETH_P_802_2);
|
||||
|
||||
} else { // SKB_NORMAL
|
||||
|
||||
skb->mac.raw=skb->data;
|
||||
skb_pull(skb,dev->hard_header_len);
|
||||
eth= skb->mac.ethernet;
|
||||
|
||||
if(*eth->h_dest&1)
|
||||
{
|
||||
if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0)
|
||||
if(*eth->h_dest&1)
|
||||
{
|
||||
if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0)
|
||||
skb->pkt_type=PACKET_BROADCAST;
|
||||
else
|
||||
skb->pkt_type=PACKET_MULTICAST;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This ALLMULTI check should be redundant by 1.4
|
||||
* so don't forget to remove it.
|
||||
*
|
||||
* Seems, you forgot to remove it. All silly devices
|
||||
* seems to set IFF_PROMISC.
|
||||
*/
|
||||
/*
|
||||
* This ALLMULTI check should be redundant by 1.4
|
||||
* so don't forget to remove it.
|
||||
*
|
||||
* Seems, you forgot to remove it. All silly devices
|
||||
* seems to set IFF_PROMISC.
|
||||
*/
|
||||
|
||||
else if(1 /*dev->flags&IFF_PROMISC*/)
|
||||
{
|
||||
else if(1 /*dev->flags&IFF_PROMISC*/)
|
||||
{
|
||||
if(memcmp(eth->h_dest,dev->dev_addr, ETH_ALEN))
|
||||
skb->pkt_type=PACKET_OTHERHOST;
|
||||
}
|
||||
}
|
||||
|
||||
if (ntohs(eth->h_proto) >= 1536)
|
||||
if (ntohs(eth->h_proto) >= 1536)
|
||||
return eth->h_proto;
|
||||
|
||||
rawp = skb->data;
|
||||
rawp = skb->data;
|
||||
|
||||
/*
|
||||
* This is a magic hack to spot IPX packets. Older Novell breaks
|
||||
* the protocol design and runs IPX over 802.3 without an 802.2 LLC
|
||||
* layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
|
||||
* won't work for fault tolerant netware but does for the rest.
|
||||
*/
|
||||
if (*(unsigned short *)rawp == 0xFFFF)
|
||||
/*
|
||||
* This is a magic hack to spot IPX packets. Older Novell breaks
|
||||
* the protocol design and runs IPX over 802.3 without an 802.2 LLC
|
||||
* layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
|
||||
* won't work for fault tolerant netware but does for the rest.
|
||||
*/
|
||||
if (*(unsigned short *)rawp == 0xFFFF)
|
||||
return htons(ETH_P_802_3);
|
||||
|
||||
/*
|
||||
* Real 802.2 LLC
|
||||
*/
|
||||
return htons(ETH_P_802_2);
|
||||
/*
|
||||
* Real 802.2 LLC
|
||||
*/
|
||||
return htons(ETH_P_802_2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int eth_header_parse(struct sk_buff *skb, unsigned char *haddr)
|
||||
{
|
||||
struct ethhdr *eth = skb->mac.ethernet;
|
||||
|
||||
+104
-1
@@ -149,6 +149,102 @@ static __inline__ void skb_head_to_pool(struct sk_buff *skb)
|
||||
kmem_cache_free(skbuff_head_cache, skb);
|
||||
}
|
||||
|
||||
static inline u8 *alloc_skb_data_page(struct sk_buff *skb)
|
||||
{
|
||||
struct list_head *list_ptr;
|
||||
struct pfn_info *pf;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&free_list_lock, flags);
|
||||
|
||||
if (!free_pfns) return NULL;
|
||||
|
||||
list_ptr = free_list.next;
|
||||
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);
|
||||
free_pfns--;
|
||||
|
||||
spin_unlock_irqrestore(&free_list_lock, flags);
|
||||
|
||||
skb->pf = pf;
|
||||
return (u8 *)((pf - frame_table) << PAGE_SHIFT);
|
||||
}
|
||||
|
||||
static inline void dealloc_skb_data_page(struct sk_buff *skb)
|
||||
{
|
||||
struct pfn_info *pf;
|
||||
unsigned long flags;
|
||||
|
||||
pf = skb->pf;
|
||||
|
||||
spin_lock_irqsave(&free_list_lock, flags);
|
||||
|
||||
list_add_tail(&pf->list, &free_list);
|
||||
free_pfns++;
|
||||
|
||||
spin_unlock_irqrestore(&free_list_lock, flags);
|
||||
}
|
||||
|
||||
struct sk_buff *alloc_zc_skb(unsigned int size,int gfp_mask)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
u8 *data;
|
||||
|
||||
if (in_interrupt() && (gfp_mask & __GFP_WAIT)) {
|
||||
static int count = 0;
|
||||
if (++count < 5) {
|
||||
printk(KERN_ERR "alloc_skb called nonatomically "
|
||||
"from interrupt %p\n", NET_CALLER(size));
|
||||
BUG();
|
||||
}
|
||||
gfp_mask &= ~__GFP_WAIT;
|
||||
}
|
||||
|
||||
/* Get the HEAD */
|
||||
skb = skb_head_from_pool();
|
||||
if (skb == NULL) {
|
||||
skb = kmem_cache_alloc(skbuff_head_cache, gfp_mask & ~__GFP_DMA);
|
||||
if (skb == NULL)
|
||||
goto nohead;
|
||||
}
|
||||
|
||||
/* Get the DATA. Size must match skb_add_mtu(). */
|
||||
size = SKB_DATA_ALIGN(size);
|
||||
data = alloc_skb_data_page(skb);
|
||||
if (data == NULL)
|
||||
goto nodata;
|
||||
|
||||
/* XXX: does not include slab overhead */
|
||||
skb->truesize = size + sizeof(struct sk_buff);
|
||||
|
||||
/* Load the data pointers. */
|
||||
skb->head = data;
|
||||
skb->data = data;
|
||||
skb->tail = data;
|
||||
skb->end = data + size;
|
||||
|
||||
/* Set up other state */
|
||||
skb->len = 0;
|
||||
skb->cloned = 0;
|
||||
skb->data_len = 0;
|
||||
skb->src_vif = VIF_UNKNOWN_INTERFACE;
|
||||
skb->dst_vif = VIF_UNKNOWN_INTERFACE;
|
||||
skb->skb_type = SKB_ZERO_COPY;
|
||||
|
||||
atomic_set(&skb->users, 1);
|
||||
atomic_set(&(skb_shinfo(skb)->dataref), 1);
|
||||
skb_shinfo(skb)->nr_frags = 0;
|
||||
skb_shinfo(skb)->frag_list = NULL;
|
||||
return skb;
|
||||
|
||||
nodata:
|
||||
skb_head_to_pool(skb);
|
||||
nohead:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Allocate a new skbuff. We do this ourselves so we can fill in a few
|
||||
* 'private' fields and also do memory statistics to find all the
|
||||
@@ -213,6 +309,7 @@ struct sk_buff *alloc_skb(unsigned int size,int gfp_mask)
|
||||
skb->data_len = 0;
|
||||
skb->src_vif = VIF_UNKNOWN_INTERFACE;
|
||||
skb->dst_vif = VIF_UNKNOWN_INTERFACE;
|
||||
skb->skb_type = SKB_NORMAL;
|
||||
|
||||
atomic_set(&skb->users, 1);
|
||||
atomic_set(&(skb_shinfo(skb)->dataref), 1);
|
||||
@@ -295,7 +392,13 @@ static void skb_release_data(struct sk_buff *skb)
|
||||
if (skb_shinfo(skb)->frag_list)
|
||||
skb_drop_fraglist(skb);
|
||||
|
||||
kfree(skb->head);
|
||||
if (skb->skb_type == SKB_NORMAL) {
|
||||
kfree(skb->head);
|
||||
} else if (skb->skb_type == SKB_ZERO_COPY) {
|
||||
dealloc_skb_data_page(skb);
|
||||
} else {
|
||||
printk("skb_release_data called with unknown skb type!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff