Skip to content

Commit 6199496

Browse files
committed
Merge branch 'net-qed-qede-various-stability-fixes'
Alexander Lobakin says: ==================== net: qed/qede: various stability fixes This set addresses several near-critical issues that were observed and reproduced on different test and production configurations. v2: - don't split the "Fixes:" tag across several lines in patch 9; - no functional changes. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents b4730ae + 10f468e commit 6199496

File tree

10 files changed

+80
-43
lines changed

10 files changed

+80
-43
lines changed

drivers/net/ethernet/qlogic/qed/qed_cxt.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ static void qed_cxt_qm_iids(struct qed_hwfn *p_hwfn,
271271
vf_tids += segs[NUM_TASK_PF_SEGMENTS].count;
272272
}
273273

274-
iids->vf_cids += vf_cids * p_mngr->vf_count;
274+
iids->vf_cids = vf_cids;
275275
iids->tids += vf_tids * p_mngr->vf_count;
276276

277277
DP_VERBOSE(p_hwfn, QED_MSG_ILT,
@@ -465,6 +465,20 @@ static struct qed_ilt_cli_blk *qed_cxt_set_blk(struct qed_ilt_cli_blk *p_blk)
465465
return p_blk;
466466
}
467467

468+
static void qed_cxt_ilt_blk_reset(struct qed_hwfn *p_hwfn)
469+
{
470+
struct qed_ilt_client_cfg *clients = p_hwfn->p_cxt_mngr->clients;
471+
u32 cli_idx, blk_idx;
472+
473+
for (cli_idx = 0; cli_idx < MAX_ILT_CLIENTS; cli_idx++) {
474+
for (blk_idx = 0; blk_idx < ILT_CLI_PF_BLOCKS; blk_idx++)
475+
clients[cli_idx].pf_blks[blk_idx].total_size = 0;
476+
477+
for (blk_idx = 0; blk_idx < ILT_CLI_VF_BLOCKS; blk_idx++)
478+
clients[cli_idx].vf_blks[blk_idx].total_size = 0;
479+
}
480+
}
481+
468482
int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn, u32 *line_count)
469483
{
470484
struct qed_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
@@ -484,6 +498,11 @@ int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn, u32 *line_count)
484498

485499
p_mngr->pf_start_line = RESC_START(p_hwfn, QED_ILT);
486500

501+
/* Reset all ILT blocks at the beginning of ILT computing in order
502+
* to prevent memory allocation for irrelevant blocks afterwards.
503+
*/
504+
qed_cxt_ilt_blk_reset(p_hwfn);
505+
487506
DP_VERBOSE(p_hwfn, QED_MSG_ILT,
488507
"hwfn [%d] - Set context manager starting line to be 0x%08x\n",
489508
p_hwfn->my_id, p_hwfn->p_cxt_mngr->pf_start_line);

drivers/net/ethernet/qlogic/qed/qed_dev.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -980,7 +980,7 @@ int qed_llh_add_mac_filter(struct qed_dev *cdev,
980980
struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
981981
struct qed_ptt *p_ptt = qed_ptt_acquire(p_hwfn);
982982
union qed_llh_filter filter = {};
983-
u8 filter_idx, abs_ppfid;
983+
u8 filter_idx, abs_ppfid = 0;
984984
u32 high, low, ref_cnt;
985985
int rc = 0;
986986

@@ -1368,6 +1368,8 @@ static void qed_dbg_user_data_free(struct qed_hwfn *p_hwfn)
13681368

13691369
void qed_resc_free(struct qed_dev *cdev)
13701370
{
1371+
struct qed_rdma_info *rdma_info;
1372+
struct qed_hwfn *p_hwfn;
13711373
int i;
13721374

13731375
if (IS_VF(cdev)) {
@@ -1385,7 +1387,8 @@ void qed_resc_free(struct qed_dev *cdev)
13851387
qed_llh_free(cdev);
13861388

13871389
for_each_hwfn(cdev, i) {
1388-
struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
1390+
p_hwfn = cdev->hwfns + i;
1391+
rdma_info = p_hwfn->p_rdma_info;
13891392

13901393
qed_cxt_mngr_free(p_hwfn);
13911394
qed_qm_info_free(p_hwfn);
@@ -1404,8 +1407,10 @@ void qed_resc_free(struct qed_dev *cdev)
14041407
qed_ooo_free(p_hwfn);
14051408
}
14061409

1407-
if (QED_IS_RDMA_PERSONALITY(p_hwfn))
1410+
if (QED_IS_RDMA_PERSONALITY(p_hwfn) && rdma_info) {
1411+
qed_spq_unregister_async_cb(p_hwfn, rdma_info->proto);
14081412
qed_rdma_info_free(p_hwfn);
1413+
}
14091414

14101415
qed_iov_free(p_hwfn);
14111416
qed_l2_free(p_hwfn);

drivers/net/ethernet/qlogic/qed/qed_iwarp.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2836,8 +2836,6 @@ int qed_iwarp_stop(struct qed_hwfn *p_hwfn)
28362836
if (rc)
28372837
return rc;
28382838

2839-
qed_spq_unregister_async_cb(p_hwfn, PROTOCOLID_IWARP);
2840-
28412839
return qed_iwarp_ll2_stop(p_hwfn);
28422840
}
28432841

drivers/net/ethernet/qlogic/qed/qed_roce.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ void qed_roce_stop(struct qed_hwfn *p_hwfn)
113113
break;
114114
}
115115
}
116-
qed_spq_unregister_async_cb(p_hwfn, PROTOCOLID_ROCE);
117116
}
118117

119118
static void qed_rdma_copy_gids(struct qed_rdma_qp *qp, __le32 *src_gid,

drivers/net/ethernet/qlogic/qed/qed_vf.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,17 @@ static void qed_vf_pf_req_end(struct qed_hwfn *p_hwfn, int req_status)
8181
mutex_unlock(&(p_hwfn->vf_iov_info->mutex));
8282
}
8383

84+
#define QED_VF_CHANNEL_USLEEP_ITERATIONS 90
85+
#define QED_VF_CHANNEL_USLEEP_DELAY 100
86+
#define QED_VF_CHANNEL_MSLEEP_ITERATIONS 10
87+
#define QED_VF_CHANNEL_MSLEEP_DELAY 25
88+
8489
static int qed_send_msg2pf(struct qed_hwfn *p_hwfn, u8 *done, u32 resp_size)
8590
{
8691
union vfpf_tlvs *p_req = p_hwfn->vf_iov_info->vf2pf_request;
8792
struct ustorm_trigger_vf_zone trigger;
8893
struct ustorm_vf_zone *zone_data;
89-
int rc = 0, time = 100;
94+
int iter, rc = 0;
9095

9196
zone_data = (struct ustorm_vf_zone *)PXP_VF_BAR0_START_USDM_ZONE_B;
9297

@@ -126,11 +131,19 @@ static int qed_send_msg2pf(struct qed_hwfn *p_hwfn, u8 *done, u32 resp_size)
126131
REG_WR(p_hwfn, (uintptr_t)&zone_data->trigger, *((u32 *)&trigger));
127132

128133
/* When PF would be done with the response, it would write back to the
129-
* `done' address. Poll until then.
134+
* `done' address from a coherent DMA zone. Poll until then.
130135
*/
131-
while ((!*done) && time) {
132-
msleep(25);
133-
time--;
136+
137+
iter = QED_VF_CHANNEL_USLEEP_ITERATIONS;
138+
while (!*done && iter--) {
139+
udelay(QED_VF_CHANNEL_USLEEP_DELAY);
140+
dma_rmb();
141+
}
142+
143+
iter = QED_VF_CHANNEL_MSLEEP_ITERATIONS;
144+
while (!*done && iter--) {
145+
msleep(QED_VF_CHANNEL_MSLEEP_DELAY);
146+
dma_rmb();
134147
}
135148

136149
if (!*done) {

drivers/net/ethernet/qlogic/qede/qede_main.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1229,7 +1229,7 @@ static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level,
12291229

12301230
/* PTP not supported on VFs */
12311231
if (!is_vf)
1232-
qede_ptp_enable(edev, (mode == QEDE_PROBE_NORMAL));
1232+
qede_ptp_enable(edev);
12331233

12341234
edev->ops->register_ops(cdev, &qede_ll_ops, edev);
12351235

@@ -1318,6 +1318,7 @@ static void __qede_remove(struct pci_dev *pdev, enum qede_remove_mode mode)
13181318
if (system_state == SYSTEM_POWER_OFF)
13191319
return;
13201320
qed_ops->common->remove(cdev);
1321+
edev->cdev = NULL;
13211322

13221323
/* Since this can happen out-of-sync with other flows,
13231324
* don't release the netdevice until after slowpath stop

drivers/net/ethernet/qlogic/qede/qede_ptp.c

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ void qede_ptp_disable(struct qede_dev *edev)
412412
if (ptp->tx_skb) {
413413
dev_kfree_skb_any(ptp->tx_skb);
414414
ptp->tx_skb = NULL;
415+
clear_bit_unlock(QEDE_FLAGS_PTP_TX_IN_PRORGESS, &edev->flags);
415416
}
416417

417418
/* Disable PTP in HW */
@@ -423,7 +424,7 @@ void qede_ptp_disable(struct qede_dev *edev)
423424
edev->ptp = NULL;
424425
}
425426

426-
static int qede_ptp_init(struct qede_dev *edev, bool init_tc)
427+
static int qede_ptp_init(struct qede_dev *edev)
427428
{
428429
struct qede_ptp *ptp;
429430
int rc;
@@ -444,25 +445,19 @@ static int qede_ptp_init(struct qede_dev *edev, bool init_tc)
444445
/* Init work queue for Tx timestamping */
445446
INIT_WORK(&ptp->work, qede_ptp_task);
446447

447-
/* Init cyclecounter and timecounter. This is done only in the first
448-
* load. If done in every load, PTP application will fail when doing
449-
* unload / load (e.g. MTU change) while it is running.
450-
*/
451-
if (init_tc) {
452-
memset(&ptp->cc, 0, sizeof(ptp->cc));
453-
ptp->cc.read = qede_ptp_read_cc;
454-
ptp->cc.mask = CYCLECOUNTER_MASK(64);
455-
ptp->cc.shift = 0;
456-
ptp->cc.mult = 1;
457-
458-
timecounter_init(&ptp->tc, &ptp->cc,
459-
ktime_to_ns(ktime_get_real()));
460-
}
448+
/* Init cyclecounter and timecounter */
449+
memset(&ptp->cc, 0, sizeof(ptp->cc));
450+
ptp->cc.read = qede_ptp_read_cc;
451+
ptp->cc.mask = CYCLECOUNTER_MASK(64);
452+
ptp->cc.shift = 0;
453+
ptp->cc.mult = 1;
461454

462-
return rc;
455+
timecounter_init(&ptp->tc, &ptp->cc, ktime_to_ns(ktime_get_real()));
456+
457+
return 0;
463458
}
464459

465-
int qede_ptp_enable(struct qede_dev *edev, bool init_tc)
460+
int qede_ptp_enable(struct qede_dev *edev)
466461
{
467462
struct qede_ptp *ptp;
468463
int rc;
@@ -483,7 +478,7 @@ int qede_ptp_enable(struct qede_dev *edev, bool init_tc)
483478

484479
edev->ptp = ptp;
485480

486-
rc = qede_ptp_init(edev, init_tc);
481+
rc = qede_ptp_init(edev);
487482
if (rc)
488483
goto err1;
489484

drivers/net/ethernet/qlogic/qede/qede_ptp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ void qede_ptp_rx_ts(struct qede_dev *edev, struct sk_buff *skb);
4141
void qede_ptp_tx_ts(struct qede_dev *edev, struct sk_buff *skb);
4242
int qede_ptp_hw_ts(struct qede_dev *edev, struct ifreq *req);
4343
void qede_ptp_disable(struct qede_dev *edev);
44-
int qede_ptp_enable(struct qede_dev *edev, bool init_tc);
44+
int qede_ptp_enable(struct qede_dev *edev);
4545
int qede_ptp_get_ts_info(struct qede_dev *edev, struct ethtool_ts_info *ts);
4646

4747
static inline void qede_ptp_record_rx_ts(struct qede_dev *edev,

drivers/net/ethernet/qlogic/qede/qede_rdma.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ static void qede_rdma_destroy_wq(struct qede_dev *edev)
105105

106106
qede_rdma_cleanup_event(edev);
107107
destroy_workqueue(edev->rdma_info.rdma_wq);
108+
edev->rdma_info.rdma_wq = NULL;
108109
}
109110

110111
int qede_rdma_dev_add(struct qede_dev *edev, bool recovery)
@@ -325,7 +326,7 @@ static void qede_rdma_add_event(struct qede_dev *edev,
325326
if (edev->rdma_info.exp_recovery)
326327
return;
327328

328-
if (!edev->rdma_info.qedr_dev)
329+
if (!edev->rdma_info.qedr_dev || !edev->rdma_info.rdma_wq)
329330
return;
330331

331332
/* We don't want the cleanup flow to start while we're allocating and

include/linux/qed/qed_chain.h

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -207,28 +207,34 @@ static inline u32 qed_chain_get_cons_idx_u32(struct qed_chain *p_chain)
207207

208208
static inline u16 qed_chain_get_elem_left(struct qed_chain *p_chain)
209209
{
210+
u16 elem_per_page = p_chain->elem_per_page;
211+
u32 prod = p_chain->u.chain16.prod_idx;
212+
u32 cons = p_chain->u.chain16.cons_idx;
210213
u16 used;
211214

212-
used = (u16) (((u32)0x10000 +
213-
(u32)p_chain->u.chain16.prod_idx) -
214-
(u32)p_chain->u.chain16.cons_idx);
215+
if (prod < cons)
216+
prod += (u32)U16_MAX + 1;
217+
218+
used = (u16)(prod - cons);
215219
if (p_chain->mode == QED_CHAIN_MODE_NEXT_PTR)
216-
used -= p_chain->u.chain16.prod_idx / p_chain->elem_per_page -
217-
p_chain->u.chain16.cons_idx / p_chain->elem_per_page;
220+
used -= prod / elem_per_page - cons / elem_per_page;
218221

219222
return (u16)(p_chain->capacity - used);
220223
}
221224

222225
static inline u32 qed_chain_get_elem_left_u32(struct qed_chain *p_chain)
223226
{
227+
u16 elem_per_page = p_chain->elem_per_page;
228+
u64 prod = p_chain->u.chain32.prod_idx;
229+
u64 cons = p_chain->u.chain32.cons_idx;
224230
u32 used;
225231

226-
used = (u32) (((u64)0x100000000ULL +
227-
(u64)p_chain->u.chain32.prod_idx) -
228-
(u64)p_chain->u.chain32.cons_idx);
232+
if (prod < cons)
233+
prod += (u64)U32_MAX + 1;
234+
235+
used = (u32)(prod - cons);
229236
if (p_chain->mode == QED_CHAIN_MODE_NEXT_PTR)
230-
used -= p_chain->u.chain32.prod_idx / p_chain->elem_per_page -
231-
p_chain->u.chain32.cons_idx / p_chain->elem_per_page;
237+
used -= (u32)(prod / elem_per_page - cons / elem_per_page);
232238

233239
return p_chain->capacity - used;
234240
}

0 commit comments

Comments
 (0)