Skip to content

Commit 71f9b61

Browse files
committed
Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue
Jeff Kirsher says: ==================== 40GbE Intel Wired LAN Driver Updates 2018-09-25 This series contains updates to i40e and xsk. Mariusz fixes an issue where the VF link state was not being updated properly when the PF is down or up. Also cleaned up the promiscuous configuration during a VF reset. Patryk simplifies the code a bit to use the variables for PF and HW that are declared, rather than using the VSI pointers. Cleaned up the message length parameter to several virtchnl functions, since it was not being used (or needed). Harshitha fixes two potential race conditions when trying to change VF settings by creating a helper function to validate that the VF is enabled and that the VSI is set up. Sergey corrects a double "link down" message by putting in a check for whether or not the link is up or going down. Björn addresses an AF_XDP zero-copy issue that buffers passed from userspace to the kernel was leaked when the hardware descriptor ring was torn down. A zero-copy capable driver picks buffers off the fill ring and places them on the hardware receive ring to be completed at a later point when DMA is complete. Similar on the transmit side; The driver picks buffers off the transmit ring and places them on the transmit hardware ring. In the typical flow, the receive buffer will be placed onto an receive ring (completed to the user), and the transmit buffer will be placed on the completion ring to notify the user that the transfer is done. However, if the driver needs to tear down the hardware rings for some reason (interface goes down, reconfiguration and such), the userspace buffers cannot be leaked. They have to be reused or completed back to userspace. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 7a15365 + 3ab52af commit 71f9b61

File tree

10 files changed

+541
-216
lines changed

10 files changed

+541
-216
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include "i40e.h"
77
#include "i40e_diag.h"
8+
#include "i40e_txrx_common.h"
89

910
/* ethtool statistics helpers */
1011

@@ -1710,6 +1711,13 @@ static int i40e_set_ringparam(struct net_device *netdev,
17101711
(new_rx_count == vsi->rx_rings[0]->count))
17111712
return 0;
17121713

1714+
/* If there is a AF_XDP UMEM attached to any of Rx rings,
1715+
* disallow changing the number of descriptors -- regardless
1716+
* if the netdev is running or not.
1717+
*/
1718+
if (i40e_xsk_any_rx_ring_enabled(vsi))
1719+
return -EBUSY;
1720+
17131721
while (test_and_set_bit(__I40E_CONFIG_BUSY, pf->state)) {
17141722
timeout--;
17151723
if (!timeout)

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

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1532,8 +1532,8 @@ static int i40e_set_mac(struct net_device *netdev, void *p)
15321532
return 0;
15331533
}
15341534

1535-
if (test_bit(__I40E_VSI_DOWN, vsi->back->state) ||
1536-
test_bit(__I40E_RESET_RECOVERY_PENDING, vsi->back->state))
1535+
if (test_bit(__I40E_DOWN, pf->state) ||
1536+
test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state))
15371537
return -EADDRNOTAVAIL;
15381538

15391539
if (ether_addr_equal(hw->mac.addr, addr->sa_data))
@@ -1557,8 +1557,7 @@ static int i40e_set_mac(struct net_device *netdev, void *p)
15571557
if (vsi->type == I40E_VSI_MAIN) {
15581558
i40e_status ret;
15591559

1560-
ret = i40e_aq_mac_address_write(&vsi->back->hw,
1561-
I40E_AQC_WRITE_TYPE_LAA_WOL,
1560+
ret = i40e_aq_mac_address_write(hw, I40E_AQC_WRITE_TYPE_LAA_WOL,
15621561
addr->sa_data, NULL);
15631562
if (ret)
15641563
netdev_info(netdev, "Ignoring error from firmware on LAA update, status %s, AQ ret %s\n",
@@ -1569,7 +1568,7 @@ static int i40e_set_mac(struct net_device *netdev, void *p)
15691568
/* schedule our worker thread which will take care of
15701569
* applying the new filter changes
15711570
*/
1572-
i40e_service_event_schedule(vsi->back);
1571+
i40e_service_event_schedule(pf);
15731572
return 0;
15741573
}
15751574

@@ -6432,7 +6431,10 @@ void i40e_print_link_message(struct i40e_vsi *vsi, bool isup)
64326431
char *req_fec = "";
64336432
char *an = "";
64346433

6435-
new_speed = pf->hw.phy.link_info.link_speed;
6434+
if (isup)
6435+
new_speed = pf->hw.phy.link_info.link_speed;
6436+
else
6437+
new_speed = I40E_LINK_SPEED_UNKNOWN;
64366438

64376439
if ((vsi->current_isup == isup) && (vsi->current_speed == new_speed))
64386440
return;
@@ -8509,14 +8511,9 @@ static void i40e_link_event(struct i40e_pf *pf)
85098511
i40e_status status;
85108512
bool new_link, old_link;
85118513

8512-
/* save off old link status information */
8513-
pf->hw.phy.link_info_old = pf->hw.phy.link_info;
8514-
85158514
/* set this to force the get_link_status call to refresh state */
85168515
pf->hw.phy.get_link_info = true;
8517-
85188516
old_link = (pf->hw.phy.link_info_old.link_info & I40E_AQ_LINK_UP);
8519-
85208517
status = i40e_get_link_status(&pf->hw, &new_link);
85218518

85228519
/* On success, disable temp link polling */

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

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -636,13 +636,18 @@ void i40e_clean_tx_ring(struct i40e_ring *tx_ring)
636636
unsigned long bi_size;
637637
u16 i;
638638

639-
/* ring already cleared, nothing to do */
640-
if (!tx_ring->tx_bi)
641-
return;
639+
if (ring_is_xdp(tx_ring) && tx_ring->xsk_umem) {
640+
i40e_xsk_clean_tx_ring(tx_ring);
641+
} else {
642+
/* ring already cleared, nothing to do */
643+
if (!tx_ring->tx_bi)
644+
return;
642645

643-
/* Free all the Tx ring sk_buffs */
644-
for (i = 0; i < tx_ring->count; i++)
645-
i40e_unmap_and_free_tx_resource(tx_ring, &tx_ring->tx_bi[i]);
646+
/* Free all the Tx ring sk_buffs */
647+
for (i = 0; i < tx_ring->count; i++)
648+
i40e_unmap_and_free_tx_resource(tx_ring,
649+
&tx_ring->tx_bi[i]);
650+
}
646651

647652
bi_size = sizeof(struct i40e_tx_buffer) * tx_ring->count;
648653
memset(tx_ring->tx_bi, 0, bi_size);
@@ -1350,8 +1355,10 @@ void i40e_clean_rx_ring(struct i40e_ring *rx_ring)
13501355
rx_ring->skb = NULL;
13511356
}
13521357

1353-
if (rx_ring->xsk_umem)
1358+
if (rx_ring->xsk_umem) {
1359+
i40e_xsk_clean_rx_ring(rx_ring);
13541360
goto skip_free;
1361+
}
13551362

13561363
/* Free all the Rx ring sk_buffs */
13571364
for (i = 0; i < rx_ring->count; i++) {

drivers/net/ethernet/intel/i40e/i40e_txrx_common.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,8 @@ static inline void i40e_arm_wb(struct i40e_ring *tx_ring,
8787
}
8888
}
8989

90+
void i40e_xsk_clean_rx_ring(struct i40e_ring *rx_ring);
91+
void i40e_xsk_clean_tx_ring(struct i40e_ring *tx_ring);
92+
bool i40e_xsk_any_rx_ring_enabled(struct i40e_vsi *vsi);
93+
9094
#endif /* I40E_TXRX_COMMON_ */

0 commit comments

Comments
 (0)