diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2012-05-17 18:40:54 +0100 |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2012-08-24 20:10:11 +0100 |
commit | f7251a9ce936f1006fbfdef63dbe42ae5e0fee7c (patch) | |
tree | e0187036af8587b61f4f492a31f3429b33dc0ffb /drivers/net/ethernet/sfc/net_driver.h | |
parent | sfc: Stop TX queues before they fill up (diff) | |
download | linux-dev-f7251a9ce936f1006fbfdef63dbe42ae5e0fee7c.tar.xz linux-dev-f7251a9ce936f1006fbfdef63dbe42ae5e0fee7c.zip |
sfc: Simplify TSO header buffer allocation
TSO header buffers contain a control structure immediately followed by
the packet headers, and are kept on a free list when not in use. This
complicates buffer management and tends to result in cache read misses
when we recycle such buffers (particularly if DMA-coherent memory
requires caches to be disabled).
Replace the free list with a simple mapping by descriptor index. We
know that there is always a payload descriptor between any two
descriptors with TSO header buffers, so we can allocate only one
such buffer for each two descriptors.
While we're at it, use a standard error code for allocation failure,
not -1.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'drivers/net/ethernet/sfc/net_driver.h')
-rw-r--r-- | drivers/net/ethernet/sfc/net_driver.h | 13 |
1 files changed, 6 insertions, 7 deletions
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 28a6d6258692..a4fe9a786ef8 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -94,7 +94,8 @@ struct efx_special_buffer { * struct efx_tx_buffer - buffer state for a TX descriptor * @skb: When @flags & %EFX_TX_BUF_SKB, the associated socket buffer to be * freed when descriptor completes - * @tsoh: When @flags & %EFX_TX_BUF_TSOH, the associated TSO header structure. + * @heap_buf: When @flags & %EFX_TX_BUF_HEAP, the associated heap buffer to be + * freed when descriptor completes. * @dma_addr: DMA address of the fragment. * @flags: Flags for allocation and DMA mapping type * @len: Length of this fragment. @@ -104,7 +105,7 @@ struct efx_special_buffer { struct efx_tx_buffer { union { const struct sk_buff *skb; - struct efx_tso_header *tsoh; + void *heap_buf; }; dma_addr_t dma_addr; unsigned short flags; @@ -113,7 +114,7 @@ struct efx_tx_buffer { }; #define EFX_TX_BUF_CONT 1 /* not last descriptor of packet */ #define EFX_TX_BUF_SKB 2 /* buffer is last part of skb */ -#define EFX_TX_BUF_TSOH 4 /* buffer is TSO header */ +#define EFX_TX_BUF_HEAP 4 /* buffer was allocated with kmalloc() */ #define EFX_TX_BUF_MAP_SINGLE 8 /* buffer was mapped with dma_map_single() */ /** @@ -134,6 +135,7 @@ struct efx_tx_buffer { * @channel: The associated channel * @core_txq: The networking core TX queue structure * @buffer: The software buffer ring + * @tsoh_page: Array of pages of TSO header buffers * @txd: The hardware descriptor ring * @ptr_mask: The size of the ring minus 1. * @initialised: Has hardware queue been initialised? @@ -157,9 +159,6 @@ struct efx_tx_buffer { * variable indicates that the queue is full. This is to * avoid cache-line ping-pong between the xmit path and the * completion path. - * @tso_headers_free: A list of TSO headers allocated for this TX queue - * that are not in use, and so available for new TSO sends. The list - * is protected by the TX queue lock. * @tso_bursts: Number of times TSO xmit invoked by kernel * @tso_long_headers: Number of packets with headers too long for standard * blocks @@ -176,6 +175,7 @@ struct efx_tx_queue { struct efx_channel *channel; struct netdev_queue *core_txq; struct efx_tx_buffer *buffer; + struct efx_buffer *tsoh_page; struct efx_special_buffer txd; unsigned int ptr_mask; bool initialised; @@ -188,7 +188,6 @@ struct efx_tx_queue { unsigned int insert_count ____cacheline_aligned_in_smp; unsigned int write_count; unsigned int old_read_count; - struct efx_tso_header *tso_headers_free; unsigned int tso_bursts; unsigned int tso_long_headers; unsigned int tso_packets; |