direct-io.hg

changeset 11121:e16d57440134

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@xensource.com>
author ack@localhost.localdomain
date Tue Aug 15 15:48:31 2006 +0100 (2006-08-15)
parents 01a4266e4dc9
children e86343be4730
files linux-2.6-xen-sparse/drivers/xen/netback/netback.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Tue Aug 15 11:17:36 2006 +0100
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Tue Aug 15 15:48:31 2006 +0100
     1.3 @@ -143,6 +143,31 @@ static inline int is_xen_skb(struct sk_b
     1.4  	return (cp == skbuff_cachep);
     1.5  }
     1.6  
     1.7 +/*
     1.8 + * We can flip without copying the packet unless:
     1.9 + *  1. The data is not allocated from our special cache; or
    1.10 + *  2. The main data area is shared; or
    1.11 + *  3. One or more fragments are shared; or
    1.12 + *  4. There are chained fragments.
    1.13 + */
    1.14 +static inline int is_flippable_skb(struct sk_buff *skb)
    1.15 +{
    1.16 +	int frag;
    1.17 +
    1.18 +	if (!is_xen_skb(skb) || skb_cloned(skb))
    1.19 +		return 0;
    1.20 +
    1.21 +	for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
    1.22 +		if (page_count(skb_shinfo(skb)->frags[frag].page) > 1)
    1.23 +			return 0;
    1.24 +	}
    1.25 +
    1.26 +	if (skb_shinfo(skb)->frag_list != NULL)
    1.27 +		return 0;
    1.28 +
    1.29 +	return 1;
    1.30 +}
    1.31 +
    1.32  static struct sk_buff *netbk_copy_skb(struct sk_buff *skb)
    1.33  {
    1.34  	struct skb_shared_info *ninfo;
    1.35 @@ -152,6 +177,8 @@ static struct sk_buff *netbk_copy_skb(st
    1.36  	int len;
    1.37  	int headlen;
    1.38  
    1.39 +	BUG_ON(skb_shinfo(skb)->frag_list != NULL);
    1.40 +
    1.41  	nskb = alloc_skb(SKB_MAX_HEAD(0), GFP_ATOMIC);
    1.42  	if (unlikely(!nskb))
    1.43  		goto err;
    1.44 @@ -252,11 +279,10 @@ int netif_be_start_xmit(struct sk_buff *
    1.45  
    1.46  	/*
    1.47  	 * We do not copy the packet unless:
    1.48 -	 *  1. The data is shared; or
    1.49 +	 *  1. The data -- including any in fragments -- is shared; or
    1.50  	 *  2. The data is not allocated from our special cache.
    1.51 -	 *  3. The data is fragmented.
    1.52  	 */
    1.53 -	if (skb_cloned(skb) || skb_is_nonlinear(skb) || !is_xen_skb(skb)) {
    1.54 +	if (!is_flippable_skb(skb)) {
    1.55  		struct sk_buff *nskb = netbk_copy_skb(skb);
    1.56  		if ( unlikely(nskb == NULL) )
    1.57  			goto drop;