[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Don't copy all incoming fragmented packets.
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |