Skip to content

Commit

Permalink
Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git…
Browse files Browse the repository at this point in the history
…/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>
  • Loading branch information
David S. Miller committed Oct 27, 2017
2 parents 8aec495 + 62b4c66 commit 8ab190f
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 21 deletions.
9 changes: 4 additions & 5 deletions drivers/net/ethernet/intel/e1000/e1000_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -1824,11 +1824,12 @@ static void e1000_get_ethtool_stats(struct net_device *netdev,
{
struct e1000_adapter *adapter = netdev_priv(netdev);
int i;
char *p = NULL;
const struct e1000_stats *stat = e1000_gstrings_stats;

e1000_update_stats(adapter);
for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++, stat++) {
char *p;

switch (stat->type) {
case NETDEV_STATS:
p = (char *)netdev + stat->stat_offset;
Expand All @@ -1839,15 +1840,13 @@ static void e1000_get_ethtool_stats(struct net_device *netdev,
default:
WARN_ONCE(1, "Invalid E1000 stat type: %u index %d\n",
stat->type, i);
break;
continue;
}

if (stat->sizeof_stat == sizeof(u64))
data[i] = *(u64 *)p;
else
data[i] = *(u32 *)p;

stat++;
}
/* BUG_ON(i != E1000_STATS_LEN); */
}
Expand Down
11 changes: 9 additions & 2 deletions drivers/net/ethernet/intel/e1000/e1000_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -520,8 +520,6 @@ void e1000_down(struct e1000_adapter *adapter)
struct net_device *netdev = adapter->netdev;
u32 rctl, tctl;

netif_carrier_off(netdev);

/* disable receives in the hardware */
rctl = er32(RCTL);
ew32(RCTL, rctl & ~E1000_RCTL_EN);
Expand All @@ -537,6 +535,15 @@ void e1000_down(struct e1000_adapter *adapter)
E1000_WRITE_FLUSH();
msleep(10);

/* Set the carrier off after transmits have been disabled in the
* hardware, to avoid race conditions with e1000_watchdog() (which
* may be running concurrently to us, checking for the carrier
* bit to decide whether it should enable transmits again). Such
* a race condition would result into transmission being disabled
* in the hardware until the next IFF_DOWN+IFF_UP cycle.
*/
netif_carrier_off(netdev);

napi_disable(&adapter->napi);

e1000_irq_disable(adapter);
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/ethernet/intel/i40e/i40e_txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -2102,6 +2102,7 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)

if (unlikely(i40e_rx_is_programming_status(qword))) {
i40e_clean_programming_status(rx_ring, rx_desc, qword);
cleaned_count++;
continue;
}
size = (qword & I40E_RXD_QW1_LENGTH_PBUF_MASK) >>
Expand Down Expand Up @@ -2269,7 +2270,7 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,
goto enable_int;
}

if (ITR_IS_DYNAMIC(tx_itr_setting)) {
if (ITR_IS_DYNAMIC(rx_itr_setting)) {
rx = i40e_set_new_dynamic_itr(&q_vector->rx);
rxval = i40e_buildreg_itr(I40E_RX_ITR, q_vector->rx.itr);
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/igb/igb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5326,7 +5326,7 @@ static int igb_tx_map(struct igb_ring *tx_ring,
DMA_TO_DEVICE);
dma_unmap_len_set(tx_buffer, len, 0);

if (i--)
if (i-- == 0)
i += tx_ring->count;
tx_buffer = &tx_ring->tx_buffer_info[i];
}
Expand Down
18 changes: 6 additions & 12 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -8020,29 +8020,23 @@ static int ixgbe_tx_map(struct ixgbe_ring *tx_ring,
return 0;
dma_error:
dev_err(tx_ring->dev, "TX DMA map failed\n");
tx_buffer = &tx_ring->tx_buffer_info[i];

/* clear dma mappings for failed tx_buffer_info map */
while (tx_buffer != first) {
for (;;) {
tx_buffer = &tx_ring->tx_buffer_info[i];
if (dma_unmap_len(tx_buffer, len))
dma_unmap_page(tx_ring->dev,
dma_unmap_addr(tx_buffer, dma),
dma_unmap_len(tx_buffer, len),
DMA_TO_DEVICE);
dma_unmap_len_set(tx_buffer, len, 0);

if (i--)
if (tx_buffer == first)
break;
if (i == 0)
i += tx_ring->count;
tx_buffer = &tx_ring->tx_buffer_info[i];
i--;
}

if (dma_unmap_len(tx_buffer, len))
dma_unmap_single(tx_ring->dev,
dma_unmap_addr(tx_buffer, dma),
dma_unmap_len(tx_buffer, len),
DMA_TO_DEVICE);
dma_unmap_len_set(tx_buffer, len, 0);

dev_kfree_skb_any(first->skb);
first->skb = NULL;

Expand Down

0 comments on commit 8ab190f

Please sign in to comment.