Skip to content

Commit 8ab190f

Browse files
committed
Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-queue
Jeff Kirsher says: ==================== Intel Wired LAN Driver Updates 2017-10-26 This series contains fixes to e1000, igb, ixgbe and i40e. Vincenzo Maffione fixes a potential race condition which would result in the interface being up but transmits are disabled in the hardware. Colin Ian King fixes a possible NULL pointer dereference in e1000, which was found by Coverity. Jean-Philippe Brucker fixes a possible kernel panic when a driver cannot map a transmit buffer, which is caused by an erroneous test. Alex provides a fix for ixgbe, which is a partial revert of the commit ffed21b ("ixgbe: Don't bother clearing buffer memory for descriptor rings") because the previous commit messed up the exception handling path by adding the count back in when we did not need to. Also fixed a typo, where the transmit ITR setting was being used to determine if we were using adaptive receive interrupt moderation or not. Lastly, fixed a memory leak by including programming descriptors in the cleaned count. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 8aec495 + 62b4c66 commit 8ab190f

5 files changed

Lines changed: 22 additions & 21 deletions

File tree

drivers/net/ethernet/intel/e1000/e1000_ethtool.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1824,11 +1824,12 @@ static void e1000_get_ethtool_stats(struct net_device *netdev,
18241824
{
18251825
struct e1000_adapter *adapter = netdev_priv(netdev);
18261826
int i;
1827-
char *p = NULL;
18281827
const struct e1000_stats *stat = e1000_gstrings_stats;
18291828

18301829
e1000_update_stats(adapter);
1831-
for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
1830+
for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++, stat++) {
1831+
char *p;
1832+
18321833
switch (stat->type) {
18331834
case NETDEV_STATS:
18341835
p = (char *)netdev + stat->stat_offset;
@@ -1839,15 +1840,13 @@ static void e1000_get_ethtool_stats(struct net_device *netdev,
18391840
default:
18401841
WARN_ONCE(1, "Invalid E1000 stat type: %u index %d\n",
18411842
stat->type, i);
1842-
break;
1843+
continue;
18431844
}
18441845

18451846
if (stat->sizeof_stat == sizeof(u64))
18461847
data[i] = *(u64 *)p;
18471848
else
18481849
data[i] = *(u32 *)p;
1849-
1850-
stat++;
18511850
}
18521851
/* BUG_ON(i != E1000_STATS_LEN); */
18531852
}

drivers/net/ethernet/intel/e1000/e1000_main.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -520,8 +520,6 @@ void e1000_down(struct e1000_adapter *adapter)
520520
struct net_device *netdev = adapter->netdev;
521521
u32 rctl, tctl;
522522

523-
netif_carrier_off(netdev);
524-
525523
/* disable receives in the hardware */
526524
rctl = er32(RCTL);
527525
ew32(RCTL, rctl & ~E1000_RCTL_EN);
@@ -537,6 +535,15 @@ void e1000_down(struct e1000_adapter *adapter)
537535
E1000_WRITE_FLUSH();
538536
msleep(10);
539537

538+
/* Set the carrier off after transmits have been disabled in the
539+
* hardware, to avoid race conditions with e1000_watchdog() (which
540+
* may be running concurrently to us, checking for the carrier
541+
* bit to decide whether it should enable transmits again). Such
542+
* a race condition would result into transmission being disabled
543+
* in the hardware until the next IFF_DOWN+IFF_UP cycle.
544+
*/
545+
netif_carrier_off(netdev);
546+
540547
napi_disable(&adapter->napi);
541548

542549
e1000_irq_disable(adapter);

drivers/net/ethernet/intel/i40e/i40e_txrx.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2102,6 +2102,7 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
21022102

21032103
if (unlikely(i40e_rx_is_programming_status(qword))) {
21042104
i40e_clean_programming_status(rx_ring, rx_desc, qword);
2105+
cleaned_count++;
21052106
continue;
21062107
}
21072108
size = (qword & I40E_RXD_QW1_LENGTH_PBUF_MASK) >>
@@ -2269,7 +2270,7 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,
22692270
goto enable_int;
22702271
}
22712272

2272-
if (ITR_IS_DYNAMIC(tx_itr_setting)) {
2273+
if (ITR_IS_DYNAMIC(rx_itr_setting)) {
22732274
rx = i40e_set_new_dynamic_itr(&q_vector->rx);
22742275
rxval = i40e_buildreg_itr(I40E_RX_ITR, q_vector->rx.itr);
22752276
}

drivers/net/ethernet/intel/igb/igb_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5326,7 +5326,7 @@ static int igb_tx_map(struct igb_ring *tx_ring,
53265326
DMA_TO_DEVICE);
53275327
dma_unmap_len_set(tx_buffer, len, 0);
53285328

5329-
if (i--)
5329+
if (i-- == 0)
53305330
i += tx_ring->count;
53315331
tx_buffer = &tx_ring->tx_buffer_info[i];
53325332
}

drivers/net/ethernet/intel/ixgbe/ixgbe_main.c

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8020,29 +8020,23 @@ static int ixgbe_tx_map(struct ixgbe_ring *tx_ring,
80208020
return 0;
80218021
dma_error:
80228022
dev_err(tx_ring->dev, "TX DMA map failed\n");
8023-
tx_buffer = &tx_ring->tx_buffer_info[i];
80248023

80258024
/* clear dma mappings for failed tx_buffer_info map */
8026-
while (tx_buffer != first) {
8025+
for (;;) {
8026+
tx_buffer = &tx_ring->tx_buffer_info[i];
80278027
if (dma_unmap_len(tx_buffer, len))
80288028
dma_unmap_page(tx_ring->dev,
80298029
dma_unmap_addr(tx_buffer, dma),
80308030
dma_unmap_len(tx_buffer, len),
80318031
DMA_TO_DEVICE);
80328032
dma_unmap_len_set(tx_buffer, len, 0);
8033-
8034-
if (i--)
8033+
if (tx_buffer == first)
8034+
break;
8035+
if (i == 0)
80358036
i += tx_ring->count;
8036-
tx_buffer = &tx_ring->tx_buffer_info[i];
8037+
i--;
80378038
}
80388039

8039-
if (dma_unmap_len(tx_buffer, len))
8040-
dma_unmap_single(tx_ring->dev,
8041-
dma_unmap_addr(tx_buffer, dma),
8042-
dma_unmap_len(tx_buffer, len),
8043-
DMA_TO_DEVICE);
8044-
dma_unmap_len_set(tx_buffer, len, 0);
8045-
80468040
dev_kfree_skb_any(first->skb);
80478041
first->skb = NULL;
80488042

0 commit comments

Comments
 (0)