Skip to content

Commit 7f5acea

Browse files
committed
Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue
Tony Nguyen says: ==================== Intel Wired LAN Driver Updates 2023-07-17 (iavf) This series contains updates to iavf driver only. Ding Hui fixes use-after-free issue by calling netif_napi_del() for all allocated q_vectors. He also resolves out-of-bounds issue by not updating to new values when timeout is encountered. Marcin and Ahmed change the way resets are handled so that the callback operating under the RTNL lock will wait for the reset to finish, the rtnl_lock sensitive functions in reset flow will schedule the netdev update for later in order to remove circular dependency with the critical lock. * '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue: iavf: fix reset task race with iavf_remove() iavf: fix a deadlock caused by rtnl and driver's lock circular dependencies Revert "iavf: Do not restart Tx queues after reset task failure" Revert "iavf: Detach device during reset task" iavf: Wait for reset in callbacks which trigger it iavf: use internal state to free traffic IRQs iavf: Fix out-of-bounds when setting channels on remove iavf: Fix use-after-free in free_netdev ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents e9b2bd9 + c34743d commit 7f5acea

File tree

4 files changed

+176
-111
lines changed

4 files changed

+176
-111
lines changed

drivers/net/ethernet/intel/iavf/iavf.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,10 @@ struct iavf_adapter {
255255
struct workqueue_struct *wq;
256256
struct work_struct reset_task;
257257
struct work_struct adminq_task;
258+
struct work_struct finish_config;
258259
struct delayed_work client_task;
259260
wait_queue_head_t down_waitqueue;
261+
wait_queue_head_t reset_waitqueue;
260262
wait_queue_head_t vc_waitqueue;
261263
struct iavf_q_vector *q_vectors;
262264
struct list_head vlan_filter_list;
@@ -518,8 +520,9 @@ int iavf_up(struct iavf_adapter *adapter);
518520
void iavf_down(struct iavf_adapter *adapter);
519521
int iavf_process_config(struct iavf_adapter *adapter);
520522
int iavf_parse_vf_resource_msg(struct iavf_adapter *adapter);
521-
void iavf_schedule_reset(struct iavf_adapter *adapter);
523+
void iavf_schedule_reset(struct iavf_adapter *adapter, u64 flags);
522524
void iavf_schedule_request_stats(struct iavf_adapter *adapter);
525+
void iavf_schedule_finish_config(struct iavf_adapter *adapter);
523526
void iavf_reset(struct iavf_adapter *adapter);
524527
void iavf_set_ethtool_ops(struct net_device *netdev);
525528
void iavf_update_stats(struct iavf_adapter *adapter);
@@ -582,4 +585,5 @@ void iavf_add_adv_rss_cfg(struct iavf_adapter *adapter);
582585
void iavf_del_adv_rss_cfg(struct iavf_adapter *adapter);
583586
struct iavf_mac_filter *iavf_add_filter(struct iavf_adapter *adapter,
584587
const u8 *macaddr);
588+
int iavf_wait_for_reset(struct iavf_adapter *adapter);
585589
#endif /* _IAVF_H_ */

drivers/net/ethernet/intel/iavf/iavf_ethtool.c

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,7 @@ static int iavf_set_priv_flags(struct net_device *netdev, u32 flags)
484484
{
485485
struct iavf_adapter *adapter = netdev_priv(netdev);
486486
u32 orig_flags, new_flags, changed_flags;
487+
int ret = 0;
487488
u32 i;
488489

489490
orig_flags = READ_ONCE(adapter->flags);
@@ -531,12 +532,14 @@ static int iavf_set_priv_flags(struct net_device *netdev, u32 flags)
531532
/* issue a reset to force legacy-rx change to take effect */
532533
if (changed_flags & IAVF_FLAG_LEGACY_RX) {
533534
if (netif_running(netdev)) {
534-
adapter->flags |= IAVF_FLAG_RESET_NEEDED;
535-
queue_work(adapter->wq, &adapter->reset_task);
535+
iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED);
536+
ret = iavf_wait_for_reset(adapter);
537+
if (ret)
538+
netdev_warn(netdev, "Changing private flags timeout or interrupted waiting for reset");
536539
}
537540
}
538541

539-
return 0;
542+
return ret;
540543
}
541544

542545
/**
@@ -627,6 +630,7 @@ static int iavf_set_ringparam(struct net_device *netdev,
627630
{
628631
struct iavf_adapter *adapter = netdev_priv(netdev);
629632
u32 new_rx_count, new_tx_count;
633+
int ret = 0;
630634

631635
if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
632636
return -EINVAL;
@@ -671,11 +675,13 @@ static int iavf_set_ringparam(struct net_device *netdev,
671675
}
672676

673677
if (netif_running(netdev)) {
674-
adapter->flags |= IAVF_FLAG_RESET_NEEDED;
675-
queue_work(adapter->wq, &adapter->reset_task);
678+
iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED);
679+
ret = iavf_wait_for_reset(adapter);
680+
if (ret)
681+
netdev_warn(netdev, "Changing ring parameters timeout or interrupted waiting for reset");
676682
}
677683

678-
return 0;
684+
return ret;
679685
}
680686

681687
/**
@@ -1830,7 +1836,7 @@ static int iavf_set_channels(struct net_device *netdev,
18301836
{
18311837
struct iavf_adapter *adapter = netdev_priv(netdev);
18321838
u32 num_req = ch->combined_count;
1833-
int i;
1839+
int ret = 0;
18341840

18351841
if ((adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADQ) &&
18361842
adapter->num_tc) {
@@ -1852,22 +1858,13 @@ static int iavf_set_channels(struct net_device *netdev,
18521858

18531859
adapter->num_req_queues = num_req;
18541860
adapter->flags |= IAVF_FLAG_REINIT_ITR_NEEDED;
1855-
iavf_schedule_reset(adapter);
1861+
iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED);
18561862

1857-
/* wait for the reset is done */
1858-
for (i = 0; i < IAVF_RESET_WAIT_COMPLETE_COUNT; i++) {
1859-
msleep(IAVF_RESET_WAIT_MS);
1860-
if (adapter->flags & IAVF_FLAG_RESET_PENDING)
1861-
continue;
1862-
break;
1863-
}
1864-
if (i == IAVF_RESET_WAIT_COMPLETE_COUNT) {
1865-
adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED;
1866-
adapter->num_active_queues = num_req;
1867-
return -EOPNOTSUPP;
1868-
}
1863+
ret = iavf_wait_for_reset(adapter);
1864+
if (ret)
1865+
netdev_warn(netdev, "Changing channel count timeout or interrupted waiting for reset");
18691866

1870-
return 0;
1867+
return ret;
18711868
}
18721869

18731870
/**

0 commit comments

Comments
 (0)