Skip to content

Commit d75b4c7

Browse files
committed
Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue
Tony Nguyen says: ==================== Intel Wired LAN Driver Updates 2022-05-06 This series contains updates to ice driver only. Ivan Vecera fixes a race with aux plug/unplug by delaying setting adev until initialization is complete and adding locking. Anatolii ensures VF queues are completely disabled before attempting to reconfigure them. Michal ensures stale Tx timestamps are cleared from hardware. * '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue: ice: fix PTP stale Tx timestamps cleanup ice: clear stale Tx queue settings before configuring ice: Fix race during aux device (un)plugging ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 91a7cda + a11b6c1 commit d75b4c7

File tree

5 files changed

+78
-28
lines changed

5 files changed

+78
-28
lines changed

drivers/net/ethernet/intel/ice/ice.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,7 @@ struct ice_pf {
540540
struct mutex avail_q_mutex; /* protects access to avail_[rx|tx]qs */
541541
struct mutex sw_mutex; /* lock for protecting VSI alloc flow */
542542
struct mutex tc_mutex; /* lock to protect TC changes */
543+
struct mutex adev_mutex; /* lock to protect aux device access */
543544
u32 msg_enable;
544545
struct ice_ptp ptp;
545546
struct tty_driver *ice_gnss_tty_driver;

drivers/net/ethernet/intel/ice/ice_idc.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,17 @@ void ice_send_event_to_aux(struct ice_pf *pf, struct iidc_event *event)
3737
if (WARN_ON_ONCE(!in_task()))
3838
return;
3939

40+
mutex_lock(&pf->adev_mutex);
4041
if (!pf->adev)
41-
return;
42+
goto finish;
4243

4344
device_lock(&pf->adev->dev);
4445
iadrv = ice_get_auxiliary_drv(pf);
4546
if (iadrv && iadrv->event_handler)
4647
iadrv->event_handler(pf, event);
4748
device_unlock(&pf->adev->dev);
49+
finish:
50+
mutex_unlock(&pf->adev_mutex);
4851
}
4952

5053
/**
@@ -290,7 +293,6 @@ int ice_plug_aux_dev(struct ice_pf *pf)
290293
return -ENOMEM;
291294

292295
adev = &iadev->adev;
293-
pf->adev = adev;
294296
iadev->pf = pf;
295297

296298
adev->id = pf->aux_idx;
@@ -300,18 +302,20 @@ int ice_plug_aux_dev(struct ice_pf *pf)
300302

301303
ret = auxiliary_device_init(adev);
302304
if (ret) {
303-
pf->adev = NULL;
304305
kfree(iadev);
305306
return ret;
306307
}
307308

308309
ret = auxiliary_device_add(adev);
309310
if (ret) {
310-
pf->adev = NULL;
311311
auxiliary_device_uninit(adev);
312312
return ret;
313313
}
314314

315+
mutex_lock(&pf->adev_mutex);
316+
pf->adev = adev;
317+
mutex_unlock(&pf->adev_mutex);
318+
315319
return 0;
316320
}
317321

@@ -320,12 +324,17 @@ int ice_plug_aux_dev(struct ice_pf *pf)
320324
*/
321325
void ice_unplug_aux_dev(struct ice_pf *pf)
322326
{
323-
if (!pf->adev)
324-
return;
327+
struct auxiliary_device *adev;
325328

326-
auxiliary_device_delete(pf->adev);
327-
auxiliary_device_uninit(pf->adev);
329+
mutex_lock(&pf->adev_mutex);
330+
adev = pf->adev;
328331
pf->adev = NULL;
332+
mutex_unlock(&pf->adev_mutex);
333+
334+
if (adev) {
335+
auxiliary_device_delete(adev);
336+
auxiliary_device_uninit(adev);
337+
}
329338
}
330339

331340
/**

drivers/net/ethernet/intel/ice/ice_main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3769,6 +3769,7 @@ u16 ice_get_avail_rxq_count(struct ice_pf *pf)
37693769
static void ice_deinit_pf(struct ice_pf *pf)
37703770
{
37713771
ice_service_task_stop(pf);
3772+
mutex_destroy(&pf->adev_mutex);
37723773
mutex_destroy(&pf->sw_mutex);
37733774
mutex_destroy(&pf->tc_mutex);
37743775
mutex_destroy(&pf->avail_q_mutex);
@@ -3847,6 +3848,7 @@ static int ice_init_pf(struct ice_pf *pf)
38473848

38483849
mutex_init(&pf->sw_mutex);
38493850
mutex_init(&pf->tc_mutex);
3851+
mutex_init(&pf->adev_mutex);
38503852

38513853
INIT_HLIST_HEAD(&pf->aq_wait_list);
38523854
spin_lock_init(&pf->aq_wait_lock);

drivers/net/ethernet/intel/ice/ice_ptp.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2287,6 +2287,7 @@ ice_ptp_init_tx_e810(struct ice_pf *pf, struct ice_ptp_tx *tx)
22872287

22882288
/**
22892289
* ice_ptp_tx_tstamp_cleanup - Cleanup old timestamp requests that got dropped
2290+
* @hw: pointer to the hw struct
22902291
* @tx: PTP Tx tracker to clean up
22912292
*
22922293
* Loop through the Tx timestamp requests and see if any of them have been
@@ -2295,7 +2296,7 @@ ice_ptp_init_tx_e810(struct ice_pf *pf, struct ice_ptp_tx *tx)
22952296
* timestamp will never be captured. This might happen if the packet gets
22962297
* discarded before it reaches the PHY timestamping block.
22972298
*/
2298-
static void ice_ptp_tx_tstamp_cleanup(struct ice_ptp_tx *tx)
2299+
static void ice_ptp_tx_tstamp_cleanup(struct ice_hw *hw, struct ice_ptp_tx *tx)
22992300
{
23002301
u8 idx;
23012302

@@ -2304,11 +2305,16 @@ static void ice_ptp_tx_tstamp_cleanup(struct ice_ptp_tx *tx)
23042305

23052306
for_each_set_bit(idx, tx->in_use, tx->len) {
23062307
struct sk_buff *skb;
2308+
u64 raw_tstamp;
23072309

23082310
/* Check if this SKB has been waiting for too long */
23092311
if (time_is_after_jiffies(tx->tstamps[idx].start + 2 * HZ))
23102312
continue;
23112313

2314+
/* Read tstamp to be able to use this register again */
2315+
ice_read_phy_tstamp(hw, tx->quad, idx + tx->quad_offset,
2316+
&raw_tstamp);
2317+
23122318
spin_lock(&tx->lock);
23132319
skb = tx->tstamps[idx].skb;
23142320
tx->tstamps[idx].skb = NULL;
@@ -2330,7 +2336,7 @@ static void ice_ptp_periodic_work(struct kthread_work *work)
23302336

23312337
ice_ptp_update_cached_phctime(pf);
23322338

2333-
ice_ptp_tx_tstamp_cleanup(&pf->ptp.port.tx);
2339+
ice_ptp_tx_tstamp_cleanup(&pf->hw, &pf->ptp.port.tx);
23342340

23352341
/* Run twice a second */
23362342
kthread_queue_delayed_work(ptp->kworker, &ptp->work,

drivers/net/ethernet/intel/ice/ice_virtchnl.c

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,13 +1307,52 @@ static int ice_vc_ena_qs_msg(struct ice_vf *vf, u8 *msg)
13071307
NULL, 0);
13081308
}
13091309

1310+
/**
1311+
* ice_vf_vsi_dis_single_txq - disable a single Tx queue
1312+
* @vf: VF to disable queue for
1313+
* @vsi: VSI for the VF
1314+
* @q_id: VF relative (0-based) queue ID
1315+
*
1316+
* Attempt to disable the Tx queue passed in. If the Tx queue was successfully
1317+
* disabled then clear q_id bit in the enabled queues bitmap and return
1318+
* success. Otherwise return error.
1319+
*/
1320+
static int
1321+
ice_vf_vsi_dis_single_txq(struct ice_vf *vf, struct ice_vsi *vsi, u16 q_id)
1322+
{
1323+
struct ice_txq_meta txq_meta = { 0 };
1324+
struct ice_tx_ring *ring;
1325+
int err;
1326+
1327+
if (!test_bit(q_id, vf->txq_ena))
1328+
dev_dbg(ice_pf_to_dev(vsi->back), "Queue %u on VSI %u is not enabled, but stopping it anyway\n",
1329+
q_id, vsi->vsi_num);
1330+
1331+
ring = vsi->tx_rings[q_id];
1332+
if (!ring)
1333+
return -EINVAL;
1334+
1335+
ice_fill_txq_meta(vsi, ring, &txq_meta);
1336+
1337+
err = ice_vsi_stop_tx_ring(vsi, ICE_NO_RESET, vf->vf_id, ring, &txq_meta);
1338+
if (err) {
1339+
dev_err(ice_pf_to_dev(vsi->back), "Failed to stop Tx ring %d on VSI %d\n",
1340+
q_id, vsi->vsi_num);
1341+
return err;
1342+
}
1343+
1344+
/* Clear enabled queues flag */
1345+
clear_bit(q_id, vf->txq_ena);
1346+
1347+
return 0;
1348+
}
1349+
13101350
/**
13111351
* ice_vc_dis_qs_msg
13121352
* @vf: pointer to the VF info
13131353
* @msg: pointer to the msg buffer
13141354
*
1315-
* called from the VF to disable all or specific
1316-
* queue(s)
1355+
* called from the VF to disable all or specific queue(s)
13171356
*/
13181357
static int ice_vc_dis_qs_msg(struct ice_vf *vf, u8 *msg)
13191358
{
@@ -1350,30 +1389,15 @@ static int ice_vc_dis_qs_msg(struct ice_vf *vf, u8 *msg)
13501389
q_map = vqs->tx_queues;
13511390

13521391
for_each_set_bit(vf_q_id, &q_map, ICE_MAX_RSS_QS_PER_VF) {
1353-
struct ice_tx_ring *ring = vsi->tx_rings[vf_q_id];
1354-
struct ice_txq_meta txq_meta = { 0 };
1355-
13561392
if (!ice_vc_isvalid_q_id(vf, vqs->vsi_id, vf_q_id)) {
13571393
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
13581394
goto error_param;
13591395
}
13601396

1361-
if (!test_bit(vf_q_id, vf->txq_ena))
1362-
dev_dbg(ice_pf_to_dev(vsi->back), "Queue %u on VSI %u is not enabled, but stopping it anyway\n",
1363-
vf_q_id, vsi->vsi_num);
1364-
1365-
ice_fill_txq_meta(vsi, ring, &txq_meta);
1366-
1367-
if (ice_vsi_stop_tx_ring(vsi, ICE_NO_RESET, vf->vf_id,
1368-
ring, &txq_meta)) {
1369-
dev_err(ice_pf_to_dev(vsi->back), "Failed to stop Tx ring %d on VSI %d\n",
1370-
vf_q_id, vsi->vsi_num);
1397+
if (ice_vf_vsi_dis_single_txq(vf, vsi, vf_q_id)) {
13711398
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
13721399
goto error_param;
13731400
}
1374-
1375-
/* Clear enabled queues flag */
1376-
clear_bit(vf_q_id, vf->txq_ena);
13771401
}
13781402
}
13791403

@@ -1622,6 +1646,14 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)
16221646
if (qpi->txq.ring_len > 0) {
16231647
vsi->tx_rings[i]->dma = qpi->txq.dma_ring_addr;
16241648
vsi->tx_rings[i]->count = qpi->txq.ring_len;
1649+
1650+
/* Disable any existing queue first */
1651+
if (ice_vf_vsi_dis_single_txq(vf, vsi, q_idx)) {
1652+
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
1653+
goto error_param;
1654+
}
1655+
1656+
/* Configure a queue with the requested settings */
16251657
if (ice_vsi_cfg_single_txq(vsi, vsi->tx_rings, q_idx)) {
16261658
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
16271659
goto error_param;

0 commit comments

Comments
 (0)