Commit 7e6d06f0de3f74ca929441add094518ae332257c

Authored by Ben Hutchings
Committed by David S. Miller
1 parent 30b678d844

sfc: Fix maximum number of TSO segments and minimum TX queue size

Currently an skb requiring TSO may not fit within a minimum-size TX
queue.  The TX queue selected for the skb may stall and trigger the TX
watchdog repeatedly (since the problem skb will be retried after the
TX reset).  This issue is designated as CVE-2012-3412.

Set the maximum number of TSO segments for our devices to 100.  This
should make no difference to behaviour unless the actual MSS is less
than about 700.  Increase the minimum TX queue size accordingly to
allow for 2 worst-case skbs, so that there will definitely be space
to add an skb after we wake a queue.

To avoid invalidating existing configurations, change
efx_ethtool_set_ringparam() to fix up values that are too small rather
than returning -EINVAL.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 4 changed files with 46 additions and 9 deletions Side-by-side Diff

drivers/net/ethernet/sfc/efx.c
... ... @@ -1503,6 +1503,11 @@
1503 1503 goto fail2;
1504 1504 }
1505 1505  
  1506 + BUILD_BUG_ON(EFX_DEFAULT_DMAQ_SIZE < EFX_RXQ_MIN_ENT);
  1507 + if (WARN_ON(EFX_DEFAULT_DMAQ_SIZE < EFX_TXQ_MIN_ENT(efx))) {
  1508 + rc = -EINVAL;
  1509 + goto fail3;
  1510 + }
1506 1511 efx->rxq_entries = efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE;
1507 1512  
1508 1513 rc = efx_probe_filters(efx);
... ... @@ -2070,6 +2075,7 @@
2070 2075 net_dev->irq = efx->pci_dev->irq;
2071 2076 net_dev->netdev_ops = &efx_netdev_ops;
2072 2077 SET_ETHTOOL_OPS(net_dev, &efx_ethtool_ops);
  2078 + net_dev->gso_max_segs = EFX_TSO_MAX_SEGS;
2073 2079  
2074 2080 rtnl_lock();
2075 2081  
drivers/net/ethernet/sfc/efx.h
... ... @@ -30,6 +30,7 @@
30 30 efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
31 31 extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index);
32 32 extern int efx_setup_tc(struct net_device *net_dev, u8 num_tc);
  33 +extern unsigned int efx_tx_max_skb_descs(struct efx_nic *efx);
33 34  
34 35 /* RX */
35 36 extern int efx_probe_rx_queue(struct efx_rx_queue *rx_queue);
... ... @@ -52,10 +53,15 @@
52 53 #define EFX_MAX_EVQ_SIZE 16384UL
53 54 #define EFX_MIN_EVQ_SIZE 512UL
54 55  
55   -/* The smallest [rt]xq_entries that the driver supports. Callers of
56   - * efx_wake_queue() assume that they can subsequently send at least one
57   - * skb. Falcon/A1 may require up to three descriptors per skb_frag. */
58   -#define EFX_MIN_RING_SIZE (roundup_pow_of_two(2 * 3 * MAX_SKB_FRAGS))
  56 +/* Maximum number of TCP segments we support for soft-TSO */
  57 +#define EFX_TSO_MAX_SEGS 100
  58 +
  59 +/* The smallest [rt]xq_entries that the driver supports. RX minimum
  60 + * is a bit arbitrary. For TX, we must have space for at least 2
  61 + * TSO skbs.
  62 + */
  63 +#define EFX_RXQ_MIN_ENT 128U
  64 +#define EFX_TXQ_MIN_ENT(efx) (2 * efx_tx_max_skb_descs(efx))
59 65  
60 66 /* Filters */
61 67 extern int efx_probe_filters(struct efx_nic *efx);
drivers/net/ethernet/sfc/ethtool.c
... ... @@ -680,21 +680,27 @@
680 680 struct ethtool_ringparam *ring)
681 681 {
682 682 struct efx_nic *efx = netdev_priv(net_dev);
  683 + u32 txq_entries;
683 684  
684 685 if (ring->rx_mini_pending || ring->rx_jumbo_pending ||
685 686 ring->rx_pending > EFX_MAX_DMAQ_SIZE ||
686 687 ring->tx_pending > EFX_MAX_DMAQ_SIZE)
687 688 return -EINVAL;
688 689  
689   - if (ring->rx_pending < EFX_MIN_RING_SIZE ||
690   - ring->tx_pending < EFX_MIN_RING_SIZE) {
  690 + if (ring->rx_pending < EFX_RXQ_MIN_ENT) {
691 691 netif_err(efx, drv, efx->net_dev,
692   - "TX and RX queues cannot be smaller than %ld\n",
693   - EFX_MIN_RING_SIZE);
  692 + "RX queues cannot be smaller than %u\n",
  693 + EFX_RXQ_MIN_ENT);
694 694 return -EINVAL;
695 695 }
696 696  
697   - return efx_realloc_channels(efx, ring->rx_pending, ring->tx_pending);
  697 + txq_entries = max(ring->tx_pending, EFX_TXQ_MIN_ENT(efx));
  698 + if (txq_entries != ring->tx_pending)
  699 + netif_warn(efx, drv, efx->net_dev,
  700 + "increasing TX queue size to minimum of %u\n",
  701 + txq_entries);
  702 +
  703 + return efx_realloc_channels(efx, ring->rx_pending, txq_entries);
698 704 }
699 705  
700 706 static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
drivers/net/ethernet/sfc/tx.c
... ... @@ -119,6 +119,25 @@
119 119 return len;
120 120 }
121 121  
  122 +unsigned int efx_tx_max_skb_descs(struct efx_nic *efx)
  123 +{
  124 + /* Header and payload descriptor for each output segment, plus
  125 + * one for every input fragment boundary within a segment
  126 + */
  127 + unsigned int max_descs = EFX_TSO_MAX_SEGS * 2 + MAX_SKB_FRAGS;
  128 +
  129 + /* Possibly one more per segment for the alignment workaround */
  130 + if (EFX_WORKAROUND_5391(efx))
  131 + max_descs += EFX_TSO_MAX_SEGS;
  132 +
  133 + /* Possibly more for PCIe page boundaries within input fragments */
  134 + if (PAGE_SIZE > EFX_PAGE_SIZE)
  135 + max_descs += max_t(unsigned int, MAX_SKB_FRAGS,
  136 + DIV_ROUND_UP(GSO_MAX_SIZE, EFX_PAGE_SIZE));
  137 +
  138 + return max_descs;
  139 +}
  140 +
122 141 /*
123 142 * Add a socket buffer to a TX queue
124 143 *