netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: David Miller <davem@davemloft.net>
To: jeffrey.t.kirsher@intel.com
Cc: netdev@vger.kernel.org, gospo@redhat.com,
	john.r.fastabend@intel.com, herbert@gondor.apana.org.au
Subject: Re: [net-next-2.6 PATCH v2] net: consolidate netif_needs_gso() checks
Date: Sat, 27 Feb 2010 03:27:25 -0800 (PST)	[thread overview]
Message-ID: <20100227.032725.158512690.davem@davemloft.net> (raw)
In-Reply-To: <20100227001954.32474.62766.stgit@localhost.localdomain>

From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Fri, 26 Feb 2010 16:20:11 -0800

> From: John Fastabend <john.r.fastabend@intel.com>
> 
> netif_needs_gso() is checked twice in the TX path once,
> before submitting the skb to the qdisc and once after
> it is dequeued from the qdisc just before calling
> ndo_hard_start().  This opens a window for a user to
> change the gso/tso or tx checksum settings that can
> cause netif_needs_gso to be true in one check and false
> in the other.
> 
> Specifically, changing TX checksum setting may cause
> the warning in skb_gso_segment() to be triggered if
> the checksum is calculated earlier.
> 
> This consolidates the netif_needs_gso() calls so that
> the stack only checks if gso is needed in
> dev_hard_start_xmit().
> 
> Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

This looks mostly fine, but I have at least one doubt.

If we have ip_summed == CHECKSUM_PARTIAL might some classifier
or packet scheduler action module require that the
transport header is setup properly before the SKB gets into
there?

Arguably, that's happening already in the GSO case but this
change is bringing the issue more to light.

Herbert, could you also take a look at this patch?

Thanks!

> diff --git a/net/core/dev.c b/net/core/dev.c
> index eb7f1a4..626124d 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -1835,12 +1835,40 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
>  {
>  	const struct net_device_ops *ops = dev->netdev_ops;
>  	int rc = NETDEV_TX_OK;
> +	int need_gso = netif_needs_gso(dev, skb);
> +
> +	if (!need_gso) {
> +		if (skb_has_frags(skb) &&
> +		    !(dev->features & NETIF_F_FRAGLIST) &&
> +		    __skb_linearize(skb))
> +			goto out_kfree_skb;
> +
> +		/* Fragmented skb is linearized if device does not support SG,
> +		 * or if at least one of fragments is in highmem and device
> +		 * does not support DMA from it.
> +		 */
> +		if (skb_shinfo(skb)->nr_frags &&
> +		    (!(dev->features & NETIF_F_SG) ||
> +		      illegal_highdma(dev, skb)) &&
> +		    __skb_linearize(skb))
> +			goto out_kfree_skb;
> +		/* If packet is not checksummed and device does not support
> +		 * checksumming for this protocol, complete checksumming here.
> +		 */
> +		if (skb->ip_summed == CHECKSUM_PARTIAL) {
> +			skb_set_transport_header(skb, skb->csum_start -
> +				      skb_headroom(skb));
> +			if (!dev_can_checksum(dev, skb) &&
> +			     skb_checksum_help(skb))
> +				goto out_kfree_skb;
> +		}
> +	}
>  
>  	if (likely(!skb->next)) {
>  		if (!list_empty(&ptype_all))
>  			dev_queue_xmit_nit(skb, dev);
>  
> -		if (netif_needs_gso(dev, skb)) {
> +		if (need_gso) {
>  			if (unlikely(dev_gso_segment(skb)))
>  				goto out_kfree_skb;
>  			if (skb->next)
> @@ -2056,25 +2084,6 @@ int dev_queue_xmit(struct sk_buff *skb)
>  	struct Qdisc *q;
>  	int rc = -ENOMEM;
>  
> -	/* GSO will handle the following emulations directly. */
> -	if (netif_needs_gso(dev, skb))
> -		goto gso;
> -
> -	/* Convert a paged skb to linear, if required */
> -	if (skb_needs_linearize(skb, dev) && __skb_linearize(skb))
> -		goto out_kfree_skb;
> -
> -	/* If packet is not checksummed and device does not support
> -	 * checksumming for this protocol, complete checksumming here.
> -	 */
> -	if (skb->ip_summed == CHECKSUM_PARTIAL) {
> -		skb_set_transport_header(skb, skb->csum_start -
> -					      skb_headroom(skb));
> -		if (!dev_can_checksum(dev, skb) && skb_checksum_help(skb))
> -			goto out_kfree_skb;
> -	}
> -
> -gso:
>  	/* Disable soft irqs for various locks below. Also
>  	 * stops preemption for RCU.
>  	 */
> @@ -2133,7 +2142,6 @@ gso:
>  	rc = -ENETDOWN;
>  	rcu_read_unlock_bh();
>  
> -out_kfree_skb:
>  	kfree_skb(skb);
>  	return rc;
>  out:
> 


  reply	other threads:[~2010-02-27 11:27 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-02-27  0:20 [net-next-2.6 PATCH v2] net: consolidate netif_needs_gso() checks Jeff Kirsher
2010-02-27 11:27 ` David Miller [this message]
2010-02-27 15:52   ` Herbert Xu
2010-02-27 16:17     ` David Miller
2010-02-28  0:29       ` Herbert Xu
2010-02-28  8:29         ` David Miller
2010-02-28  8:30     ` David Miller
2010-03-06 19:27     ` John Fastabend
2010-03-07  1:43       ` Herbert Xu
2010-03-08 16:56         ` John Fastabend

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100227.032725.158512690.davem@davemloft.net \
    --to=davem@davemloft.net \
    --cc=gospo@redhat.com \
    --cc=herbert@gondor.apana.org.au \
    --cc=jeffrey.t.kirsher@intel.com \
    --cc=john.r.fastabend@intel.com \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).