diff options
author | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-09-04 17:19:46 +0000 |
---|---|---|
committer | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-09-04 17:19:46 +0000 |
commit | a4912107ca9b2d8b7394472f413fdbc185e9ec8b (patch) | |
tree | ae01b40a04beac344498ed3e1d77ac294ada6fd0 /xen | |
parent | 86e3ea12a629a61eef29f623fa405548c37a61dc (diff) | |
download | xen-a4912107ca9b2d8b7394472f413fdbc185e9ec8b.tar.gz xen-a4912107ca9b2d8b7394472f413fdbc185e9ec8b.tar.bz2 xen-a4912107ca9b2d8b7394472f413fdbc185e9ec8b.zip |
bitkeeper revision 1.408 (3f5774320u8HbDt_UW94uvftWnuvBA)
skbuff.c, dev.c, skbuff.h:
Fix transmit path for NICs which need a linearised skbuff.
Diffstat (limited to 'xen')
-rw-r--r-- | xen/include/xeno/skbuff.h | 7 | ||||
-rw-r--r-- | xen/net/dev.c | 8 | ||||
-rw-r--r-- | xen/net/skbuff.c | 51 |
3 files changed, 10 insertions, 56 deletions
diff --git a/xen/include/xeno/skbuff.h b/xen/include/xeno/skbuff.h index 30d62155ea..a0dbd110a1 100644 --- a/xen/include/xeno/skbuff.h +++ b/xen/include/xeno/skbuff.h @@ -440,19 +440,20 @@ static inline struct sk_buff *dev_alloc_skb(unsigned int length) return __dev_alloc_skb(length, GFP_ATOMIC); } +#include <asm/domain_page.h> + static inline void *kmap_skb_frag(const skb_frag_t *frag) { - return page_address(frag->page); + return map_domain_mem(__pa(page_address(frag->page))); } static inline void kunmap_skb_frag(void *vaddr) { + unmap_domain_mem(vaddr); } extern int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len); extern void skb_init(void); -extern int skb_linearize(struct sk_buff *skn, int gfp_mask); - #endif /* _LINUX_SKBUFF_H */ diff --git a/xen/net/dev.c b/xen/net/dev.c index ca35f5aa66..83d057a378 100644 --- a/xen/net/dev.c +++ b/xen/net/dev.c @@ -733,7 +733,7 @@ static void net_tx_action(unsigned long unused) { struct net_device *dev = the_dev; struct list_head *ent; - struct sk_buff *skb; + struct sk_buff *skb, *nskb; net_vif_t *vif; tx_shadow_entry_t *tx; @@ -794,7 +794,11 @@ static void net_tx_action(unsigned long unused) /* Is the NIC crap? */ if ( !(dev->features & NETIF_F_SG) ) - skb_linearize(skb, GFP_KERNEL); + { + nskb = skb_copy(skb, GFP_KERNEL); + kfree_skb(skb); + skb = nskb; + } /* Transmit should always work, or the queue would be stopped. */ if ( dev->hard_start_xmit(skb, dev) != 0 ) diff --git a/xen/net/skbuff.c b/xen/net/skbuff.c index f2cb1e0b81..cf60a573a9 100644 --- a/xen/net/skbuff.c +++ b/xen/net/skbuff.c @@ -430,57 +430,6 @@ struct sk_buff *skb_copy(const struct sk_buff *skb, int gfp_mask) return n; } -/* Keep head the same: replace data */ -int skb_linearize(struct sk_buff *skb, int gfp_mask) -{ - unsigned int size; - u8 *data; - long offset; - int headerlen = skb->data - skb->head; - int expand = (skb->tail+skb->data_len) - skb->end; - - if (skb_shinfo(skb)->nr_frags == 0) - return 0; - - if (expand <= 0) - expand = 0; - - size = (skb->end - skb->head + expand); - size = SKB_DATA_ALIGN(size); - data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask); - if (data == NULL) - return -ENOMEM; - - /* Copy entire thing */ - if (skb_copy_bits(skb, -headerlen, data, headerlen+skb->len)) - BUG(); - - /* Offset between the two in bytes */ - offset = data - skb->head; - - /* Free old data. */ - skb_release_data(skb); - - skb->head = data; - skb->end = data + size; - - /* Set up new pointers */ - skb->h.raw += offset; - skb->nh.raw += offset; - skb->mac.raw += offset; - skb->tail += offset; - skb->data += offset; - - skb->skb_type = SKB_NORMAL; - - /* Set up shinfo */ - skb_shinfo(skb)->nr_frags = 0; - - skb->tail += skb->data_len; - skb->data_len = 0; - return 0; -} - /* Copy some data bits from skb to kernel buffer. */ int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) |