All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Dumazet <eric.dumazet@gmail.com>
To: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Cc: davem@davemloft.net,
	Alexander Duyck <alexander.h.duyck@intel.com>,
	netdev@vger.kernel.org, gospo@redhat.com, sassmann@redhat.com
Subject: Re: [net-next 05/10] igb: Update igb to use a path similar to ixgbe to determine when to stop Tx
Date: Fri, 08 Feb 2013 04:26:09 -0800	[thread overview]
Message-ID: <1360326369.28557.95.camel@edumazet-glaptop> (raw)
In-Reply-To: <1360319958-10497-6-git-send-email-jeffrey.t.kirsher@intel.com>

On Fri, 2013-02-08 at 02:39 -0800, Jeff Kirsher wrote:
> From: Alexander Duyck <alexander.h.duyck@intel.com>
> 
> After reviewing the igb and ixgbe code I realized there are a few issues in
> how the code is structured.  Specifically we are not checking the size of the
> buffers being used in transmits and we are not using the same value to
> determine when to stop or start a Tx queue.  As such the code is prone to be
> buggy.
> 
> This patch makes it so that we have one value DESC_NEEDED that we will use for
> starting and stopping the queue.  In addition we will check the size of
> buffers being used when setting up a transmit so as to avoid a possible buffer
> overrun if we were to receive a frame with a block of data larger than 32K in
> skb->data.
> 
> Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
> Tested-by: Aaron Brown <aaron.f.brown@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> ---
>  drivers/net/ethernet/intel/igb/igb.h      | 13 +++++++++++--
>  drivers/net/ethernet/intel/igb/igb_main.c | 32 ++++++++++++++++++-------------
>  2 files changed, 30 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
> index afdb8bb..d27edbc 100644
> --- a/drivers/net/ethernet/intel/igb/igb.h
> +++ b/drivers/net/ethernet/intel/igb/igb.h
> @@ -139,8 +139,6 @@ struct vf_data_storage {
>  #define IGB_RX_HDR_LEN		IGB_RXBUFFER_256
>  #define IGB_RX_BUFSZ		IGB_RXBUFFER_2048
>  
> -/* How many Tx Descriptors do we need to call netif_wake_queue ? */
> -#define IGB_TX_QUEUE_WAKE	16
>  /* How many Rx Buffers do we bundle into one write to the hardware ? */
>  #define IGB_RX_BUFFER_WRITE	16	/* Must be power of 2 */
>  
> @@ -169,6 +167,17 @@ enum igb_tx_flags {
>  #define IGB_TX_FLAGS_VLAN_MASK		0xffff0000
>  #define IGB_TX_FLAGS_VLAN_SHIFT	16
>  
> +/*
> + * The largest size we can write to the descriptor is 65535.  In order to
> + * maintain a power of two alignment we have to limit ourselves to 32K.
> + */
> +#define IGB_MAX_TXD_PWR	15
> +#define IGB_MAX_DATA_PER_TXD	(1 << IGB_MAX_TXD_PWR)
> +
> +/* Tx Descriptors needed, worst case */
> +#define TXD_USE_COUNT(S) DIV_ROUND_UP((S), IGB_MAX_DATA_PER_TXD)
> +#define DESC_NEEDED (MAX_SKB_FRAGS + 4)
> +
>  /* wrapper around a pointer to a socket buffer,
>   * so a DMA handle can be stored along with the buffer */
>  struct igb_tx_buffer {
> diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
> index ebf8384..e69dd4f 100644
> --- a/drivers/net/ethernet/intel/igb/igb_main.c
> +++ b/drivers/net/ethernet/intel/igb/igb_main.c
> @@ -4434,13 +4434,6 @@ static void igb_tx_olinfo_status(struct igb_ring *tx_ring,
>  	tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status);
>  }
>  
> -/*
> - * The largest size we can write to the descriptor is 65535.  In order to
> - * maintain a power of two alignment we have to limit ourselves to 32K.
> - */
> -#define IGB_MAX_TXD_PWR	15
> -#define IGB_MAX_DATA_PER_TXD	(1<<IGB_MAX_TXD_PWR)
> -
>  static void igb_tx_map(struct igb_ring *tx_ring,
>  		       struct igb_tx_buffer *first,
>  		       const u8 hdr_len)
> @@ -4609,15 +4602,27 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
>  	struct igb_tx_buffer *first;
>  	int tso;
>  	u32 tx_flags = 0;
> +#if PAGE_SIZE > IGB_MAX_DATA_PER_TXD
> +	unsigned short f;
> +#endif
> +	u16 count = TXD_USE_COUNT(skb_headlen(skb));
>  	__be16 protocol = vlan_get_protocol(skb);
>  	u8 hdr_len = 0;
>  
> -	/* need: 1 descriptor per page,
> +	/*
> +	 * need: 1 descriptor per page * PAGE_SIZE/IGB_MAX_DATA_PER_TXD,
> +	 *       + 1 desc for skb_headlen/IGB_MAX_DATA_PER_TXD,
>  	 *       + 2 desc gap to keep tail from touching head,
> -	 *       + 1 desc for skb->data,
>  	 *       + 1 desc for context descriptor,
> -	 * otherwise try next time */
> -	if (igb_maybe_stop_tx(tx_ring, skb_shinfo(skb)->nr_frags + 4)) {
> +	 * otherwise try next time
> +	 */
> +#if PAGE_SIZE > IGB_MAX_DATA_PER_TXD

This code assumes a frag is at most PAGE_SIZE, but its not true.

> +	for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
> +		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size);
> +#else
> +	count += skb_shinfo(skb)->nr_frags;
> +#endif

Current practical limit is 32768 bytes on x86

  reply	other threads:[~2013-02-08 12:26 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-02-08 10:39 [net-next 00/10][pull request] Intel Wired LAN Driver Updates Jeff Kirsher
2013-02-08 10:39 ` [net-next 01/10] igb: Support using build_skb in the case that jumbo frames are disabled Jeff Kirsher
2013-02-08 10:39 ` [net-next 02/10] igb: Fix for improper exit in igb_get_i2c_client Jeff Kirsher
2013-02-08 10:39 ` [net-next 03/10] igb: Fix for improper allocation flag " Jeff Kirsher
2013-02-08 10:39 ` [net-next 04/10] igb: Fix for sparse warning " Jeff Kirsher
2013-02-11 17:05   ` Ben Hutchings
2013-02-11 17:27     ` Wyborny, Carolyn
2013-02-12 17:12     ` Wyborny, Carolyn
2013-02-12 17:17     ` Wyborny, Carolyn
2013-02-08 10:39 ` [net-next 05/10] igb: Update igb to use a path similar to ixgbe to determine when to stop Tx Jeff Kirsher
2013-02-08 12:26   ` Eric Dumazet [this message]
2013-02-08 17:11     ` Alexander Duyck
2013-02-08 19:18       ` David Miller
2013-02-08 20:19         ` Alexander Duyck
2013-02-08 10:39 ` [net-next 06/10] igb: Initialize PHY function pointers Jeff Kirsher
2013-02-08 10:39 ` [net-next 07/10] igb: Initialize NVM " Jeff Kirsher
2013-02-08 10:39 ` [net-next 08/10] igb: Intialize MAC " Jeff Kirsher
2013-02-08 10:39 ` [net-next 09/10] igb: Refractoring function pointers in igb_get_invariants function Jeff Kirsher
2013-02-08 10:39 ` [net-next 10/10] ixgbe: refactor initialization of feature flags Jeff Kirsher

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=1360326369.28557.95.camel@edumazet-glaptop \
    --to=eric.dumazet@gmail.com \
    --cc=alexander.h.duyck@intel.com \
    --cc=davem@davemloft.net \
    --cc=gospo@redhat.com \
    --cc=jeffrey.t.kirsher@intel.com \
    --cc=netdev@vger.kernel.org \
    --cc=sassmann@redhat.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.