Subject: Re: [PATCH] sky2: don't do GRO on second port

From: Jarek Poplawski <[email-masked]>
Date: Mon, 30 Aug 2010 21:09:00 +0200

On Mon, Aug 30, 2010 at 10:51:17AM -0700, Stephen Hemminger wrote:
> 
>  There's something very important I forgot to tell you.
>  What?
> 
>  Don't cross the GRO streams.
>  Why?
> 
>  It would be bad.
>  I'm fuzzy on the whole good/bad thing. What do you mean, "bad"?
> 
>  Try to imagine all the Internet as you know it stopping instantaneously
>   and every bit in every packet swapping at the speed of light.
>  Total packet reordering.
>  Right. That's bad. Okay. All right. Important safety tip. Thanks, Hubert

Looks really bad to me, so... let's forget it! ;-) (At least until
next next.)

Jarek P.

> 
> The simplest way to stop this is just avoid doing GRO on the second port.
> Very few Marvell boards support two ports per ring, and GRO is just
> an optimization.
> 
> Signed-off-by: Stephen Hemminger <[email-masked]>
> 
> 
> --- a/drivers/net/sky2.c	2010-08-30 10:13:28.211536096 -0700
> +++ b/drivers/net/sky2.c	2010-08-30 10:22:01.347183151 -0700
> @@ -2520,24 +2520,27 @@ static inline void sky2_tx_done(struct n
>  	}
>  }
>  
> -static inline void sky2_skb_rx(const struct sky2_port *sky2,
> +static inline void sky2_skb_rx(struct napi_struct *napi,
> +			       const struct sky2_port *sky2,
>  			       u32 status, struct sk_buff *skb)
>  {
>  #ifdef SKY2_VLAN_TAG_USED
> -	u16 vlan_tag = be16_to_cpu(sky2->rx_tag);
>  	if (sky2->vlgrp && (status & GMR_FS_VLAN)) {
> -		if (skb->ip_summed == CHECKSUM_NONE)
> +		u16 vlan_tag = be16_to_cpu(sky2->rx_tag);
> +
> +		if (skb->ip_summed == CHECKSUM_NONE ||
> +		    sky2->netdev != napi->dev)
>  			vlan_hwaccel_receive_skb(skb, sky2->vlgrp, vlan_tag);
>  		else
> -			vlan_gro_receive(&sky2->hw->napi, sky2->vlgrp,
> -					 vlan_tag, skb);
> +			vlan_gro_receive(napi, sky2->vlgrp, vlan_tag, skb);
>  		return;
>  	}
>  #endif
> -	if (skb->ip_summed == CHECKSUM_NONE)
> +	if (skb->ip_summed == CHECKSUM_NONE ||
> +	    sky2->netdev != napi->dev)
>  		netif_receive_skb(skb);
>  	else
> -		napi_gro_receive(&sky2->hw->napi, skb);
> +		napi_gro_receive(napi, skb);
>  }
>  
>  static inline void sky2_rx_done(struct sky2_hw *hw, unsigned port,
> @@ -2638,7 +2641,7 @@ static int sky2_status_intr(struct sky2_
>  
>  			skb->protocol = eth_type_trans(skb, dev);
>  
> -			sky2_skb_rx(sky2, status, skb);
> +			sky2_skb_rx(&hw->napi, sky2, status, skb);
>  
>  			/* Stop after net poll weight */
>  			if (++work_done >= to_do)