|
|
|
|
|
|
|
|
|
|
xen-changelog
[Xen-changelog] [xen-unstable] Don't copy all incoming fragmented packet
# HG changeset patch
# User ack@xxxxxxxxxxxxxxxxxxxxx
# Node ID e16d57440134a92239fb22bfa2667d1303ca0fee
# Parent 01a4266e4dc9c1ca4a0cefc3f1c8fbe73bbf4e17
Don't copy all incoming fragmented packets.
Some drivers (ie the e1000) hand up packets with the header in
the main area and the data in a fragment. Unless there are
multiple references on any of the data, we don't need to
make a full copy of those packets.
Signed-off-by: Emmanuel Ackaouy <ack@xxxxxxxxxxxxx>
---
linux-2.6-xen-sparse/drivers/xen/netback/netback.c | 32 +++++++++++++++++++--
1 files changed, 29 insertions(+), 3 deletions(-)
diff -r 01a4266e4dc9 -r e16d57440134
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Tue Aug 15
11:17:36 2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Tue Aug 15
15:48:31 2006 +0100
@@ -143,6 +143,31 @@ static inline int is_xen_skb(struct sk_b
return (cp == skbuff_cachep);
}
+/*
+ * We can flip without copying the packet unless:
+ * 1. The data is not allocated from our special cache; or
+ * 2. The main data area is shared; or
+ * 3. One or more fragments are shared; or
+ * 4. There are chained fragments.
+ */
+static inline int is_flippable_skb(struct sk_buff *skb)
+{
+ int frag;
+
+ if (!is_xen_skb(skb) || skb_cloned(skb))
+ return 0;
+
+ for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
+ if (page_count(skb_shinfo(skb)->frags[frag].page) > 1)
+ return 0;
+ }
+
+ if (skb_shinfo(skb)->frag_list != NULL)
+ return 0;
+
+ return 1;
+}
+
static struct sk_buff *netbk_copy_skb(struct sk_buff *skb)
{
struct skb_shared_info *ninfo;
@@ -152,6 +177,8 @@ static struct sk_buff *netbk_copy_skb(st
int len;
int headlen;
+ BUG_ON(skb_shinfo(skb)->frag_list != NULL);
+
nskb = alloc_skb(SKB_MAX_HEAD(0), GFP_ATOMIC);
if (unlikely(!nskb))
goto err;
@@ -252,11 +279,10 @@ int netif_be_start_xmit(struct sk_buff *
/*
* We do not copy the packet unless:
- * 1. The data is shared; or
+ * 1. The data -- including any in fragments -- is shared; or
* 2. The data is not allocated from our special cache.
- * 3. The data is fragmented.
*/
- if (skb_cloned(skb) || skb_is_nonlinear(skb) || !is_xen_skb(skb)) {
+ if (!is_flippable_skb(skb)) {
struct sk_buff *nskb = netbk_copy_skb(skb);
if ( unlikely(nskb == NULL) )
goto drop;
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|
<Prev in Thread] |
Current Thread |
[Next in Thread> |
- [Xen-changelog] [xen-unstable] Don't copy all incoming fragmented packets.,
Xen patchbot-unstable <=
|
|
|
|
|