aboutsummaryrefslogtreecommitdiffstats
path: root/xen
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-09-04 17:19:46 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-09-04 17:19:46 +0000
commita4912107ca9b2d8b7394472f413fdbc185e9ec8b (patch)
treeae01b40a04beac344498ed3e1d77ac294ada6fd0 /xen
parent86e3ea12a629a61eef29f623fa405548c37a61dc (diff)
downloadxen-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.h7
-rw-r--r--xen/net/dev.c8
-rw-r--r--xen/net/skbuff.c51
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)