Skip to content

Commit ccd382c

Browse files
committed
Merge: qed: lower the scheduling latency caused by ethtool -d
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/5288 JIRA: https://issues.redhat.com/browse/RHEL-6372 This fixes a customer case where ethtool -d (run by a sosreport cronjob) causes soft-lockups due to the qed driver keeping the CPU busy without scheduling for more than 26 seconds. Signed-off-by: Michal Schmidt <mschmidt@redhat.com> Approved-by: Kamal Heib <kheib@redhat.com> Approved-by: José Ignacio Tornos Martínez <jtornosm@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Rado Vrbovsky <rvrbovsk@redhat.com>
2 parents c370061 + 2af64d7 commit ccd382c

File tree

3 files changed

+38
-37
lines changed

3 files changed

+38
-37
lines changed

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

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1832,7 +1832,8 @@ static enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn,
18321832
struct qed_ptt *p_ptt,
18331833
u32 image_type,
18341834
u32 *nvram_offset_bytes,
1835-
u32 *nvram_size_bytes)
1835+
u32 *nvram_size_bytes,
1836+
bool b_can_sleep)
18361837
{
18371838
u32 ret_mcp_resp, ret_mcp_param, ret_txn_size;
18381839
struct mcp_file_att file_att;
@@ -1846,7 +1847,8 @@ static enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn,
18461847
&ret_mcp_resp,
18471848
&ret_mcp_param,
18481849
&ret_txn_size,
1849-
(u32 *)&file_att, false);
1850+
(u32 *)&file_att,
1851+
b_can_sleep);
18501852

18511853
/* Check response */
18521854
if (nvm_result || (ret_mcp_resp & FW_MSG_CODE_MASK) !=
@@ -1873,7 +1875,9 @@ static enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn,
18731875
static enum dbg_status qed_nvram_read(struct qed_hwfn *p_hwfn,
18741876
struct qed_ptt *p_ptt,
18751877
u32 nvram_offset_bytes,
1876-
u32 nvram_size_bytes, u32 *ret_buf)
1878+
u32 nvram_size_bytes,
1879+
u32 *ret_buf,
1880+
bool b_can_sleep)
18771881
{
18781882
u32 ret_mcp_resp, ret_mcp_param, ret_read_size, bytes_to_copy;
18791883
s32 bytes_left = nvram_size_bytes;
@@ -1899,7 +1903,7 @@ static enum dbg_status qed_nvram_read(struct qed_hwfn *p_hwfn,
18991903
&ret_mcp_resp,
19001904
&ret_mcp_param, &ret_read_size,
19011905
(u32 *)((u8 *)ret_buf + read_offset),
1902-
false))
1906+
b_can_sleep))
19031907
return DBG_STATUS_NVRAM_READ_FAILED;
19041908

19051909
/* Check response */
@@ -2868,6 +2872,7 @@ static u32 qed_grc_dump_ctx_data(struct qed_hwfn *p_hwfn,
28682872
false,
28692873
SPLIT_TYPE_NONE, 0);
28702874
}
2875+
cond_resched();
28712876
}
28722877

28732878
return offset;
@@ -3379,7 +3384,8 @@ static u32 qed_grc_dump_mcp_hw_dump(struct qed_hwfn *p_hwfn,
33793384
p_ptt,
33803385
NVM_TYPE_HW_DUMP_OUT,
33813386
&hw_dump_offset_bytes,
3382-
&hw_dump_size_bytes);
3387+
&hw_dump_size_bytes,
3388+
false);
33833389
if (status != DBG_STATUS_OK)
33843390
return 0;
33853391

@@ -3396,7 +3402,9 @@ static u32 qed_grc_dump_mcp_hw_dump(struct qed_hwfn *p_hwfn,
33963402
status = qed_nvram_read(p_hwfn,
33973403
p_ptt,
33983404
hw_dump_offset_bytes,
3399-
hw_dump_size_bytes, dump_buf + offset);
3405+
hw_dump_size_bytes,
3406+
dump_buf + offset,
3407+
false);
34003408
if (status != DBG_STATUS_OK) {
34013409
DP_NOTICE(p_hwfn,
34023410
"Failed to read MCP HW Dump image from NVRAM\n");
@@ -4122,7 +4130,9 @@ static enum dbg_status qed_mcp_trace_get_meta_info(struct qed_hwfn *p_hwfn,
41224130
return qed_find_nvram_image(p_hwfn,
41234131
p_ptt,
41244132
nvram_image_type,
4125-
trace_meta_offset, trace_meta_size);
4133+
trace_meta_offset,
4134+
trace_meta_size,
4135+
true);
41264136
}
41274137

41284138
/* Reads the MCP Trace meta data from NVRAM into the specified buffer */
@@ -4138,7 +4148,10 @@ static enum dbg_status qed_mcp_trace_read_meta(struct qed_hwfn *p_hwfn,
41384148
/* Read meta data from NVRAM */
41394149
status = qed_nvram_read(p_hwfn,
41404150
p_ptt,
4141-
nvram_offset_in_bytes, size_in_bytes, buf);
4151+
nvram_offset_in_bytes,
4152+
size_in_bytes,
4153+
buf,
4154+
true);
41424155
if (status != DBG_STATUS_OK)
41434156
return status;
41444157

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,7 @@ static int qed_dmae_operation_wait(struct qed_hwfn *p_hwfn)
578578
barrier();
579579
while (*p_hwfn->dmae_info.p_completion_word != DMAE_COMPLETION_VAL) {
580580
udelay(DMAE_MIN_WAIT_TIME);
581+
cond_resched();
581582
if (++wait_cnt > wait_cnt_limit) {
582583
DP_NOTICE(p_hwfn->cdev,
583584
"Timed-out waiting for operation to complete. Completion word is 0x%08x expected 0x%08x.\n",

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

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -459,12 +459,11 @@ static void qed_mcp_print_cpu_info(struct qed_hwfn *p_hwfn,
459459
static int
460460
_qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
461461
struct qed_ptt *p_ptt,
462-
struct qed_mcp_mb_params *p_mb_params,
463-
u32 max_retries, u32 usecs)
462+
struct qed_mcp_mb_params *p_mb_params)
464463
{
465-
u32 cnt = 0, msecs = DIV_ROUND_UP(usecs, 1000);
466464
struct qed_mcp_cmd_elem *p_cmd_elem;
467465
u16 seq_num;
466+
u32 cnt = 0;
468467
int rc = 0;
469468

470469
/* Wait until the mailbox is non-occupied */
@@ -488,12 +487,13 @@ _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
488487
spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock);
489488

490489
if (QED_MB_FLAGS_IS_SET(p_mb_params, CAN_SLEEP))
491-
msleep(msecs);
490+
usleep_range(QED_MCP_RESP_ITER_US,
491+
QED_MCP_RESP_ITER_US * 2);
492492
else
493-
udelay(usecs);
494-
} while (++cnt < max_retries);
493+
udelay(QED_MCP_RESP_ITER_US);
494+
} while (++cnt < QED_DRV_MB_MAX_RETRIES);
495495

496-
if (cnt >= max_retries) {
496+
if (cnt >= QED_DRV_MB_MAX_RETRIES) {
497497
DP_NOTICE(p_hwfn,
498498
"The MFW mailbox is occupied by an uncompleted command. Failed to send command 0x%08x [param 0x%08x].\n",
499499
p_mb_params->cmd, p_mb_params->param);
@@ -520,9 +520,10 @@ _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
520520
*/
521521

522522
if (QED_MB_FLAGS_IS_SET(p_mb_params, CAN_SLEEP))
523-
msleep(msecs);
523+
usleep_range(QED_MCP_RESP_ITER_US,
524+
QED_MCP_RESP_ITER_US * 2);
524525
else
525-
udelay(usecs);
526+
udelay(QED_MCP_RESP_ITER_US);
526527

527528
spin_lock_bh(&p_hwfn->mcp_info->cmd_lock);
528529

@@ -536,9 +537,9 @@ _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
536537
goto err;
537538

538539
spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock);
539-
} while (++cnt < max_retries);
540+
} while (++cnt < QED_DRV_MB_MAX_RETRIES);
540541

541-
if (cnt >= max_retries) {
542+
if (cnt >= QED_DRV_MB_MAX_RETRIES) {
542543
DP_NOTICE(p_hwfn,
543544
"The MFW failed to respond to command 0x%08x [param 0x%08x].\n",
544545
p_mb_params->cmd, p_mb_params->param);
@@ -564,7 +565,8 @@ _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
564565
"MFW mailbox: response 0x%08x param 0x%08x [after %d.%03d ms]\n",
565566
p_mb_params->mcp_resp,
566567
p_mb_params->mcp_param,
567-
(cnt * usecs) / 1000, (cnt * usecs) % 1000);
568+
(cnt * QED_MCP_RESP_ITER_US) / 1000,
569+
(cnt * QED_MCP_RESP_ITER_US) % 1000);
568570

569571
/* Clear the sequence number from the MFW response */
570572
p_mb_params->mcp_resp &= FW_MSG_CODE_MASK;
@@ -581,8 +583,6 @@ static int qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
581583
struct qed_mcp_mb_params *p_mb_params)
582584
{
583585
size_t union_data_size = sizeof(union drv_union_data);
584-
u32 max_retries = QED_DRV_MB_MAX_RETRIES;
585-
u32 usecs = QED_MCP_RESP_ITER_US;
586586

587587
/* MCP not initialized */
588588
if (!qed_mcp_is_init(p_hwfn)) {
@@ -606,13 +606,7 @@ static int qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
606606
return -EINVAL;
607607
}
608608

609-
if (QED_MB_FLAGS_IS_SET(p_mb_params, CAN_SLEEP)) {
610-
max_retries = DIV_ROUND_UP(max_retries, 1000);
611-
usecs *= 1000;
612-
}
613-
614-
return _qed_mcp_cmd_and_union(p_hwfn, p_ptt, p_mb_params, max_retries,
615-
usecs);
609+
return _qed_mcp_cmd_and_union(p_hwfn, p_ptt, p_mb_params);
616610
}
617611

618612
static int _qed_mcp_cmd(struct qed_hwfn *p_hwfn,
@@ -3085,20 +3079,13 @@ int qed_mcp_nvm_read(struct qed_dev *cdev, u32 addr, u8 *p_buf, u32 len)
30853079
DRV_MB_PARAM_NVM_LEN_OFFSET),
30863080
&resp, &resp_param,
30873081
&read_len,
3088-
(u32 *)(p_buf + offset), false);
3082+
(u32 *)(p_buf + offset), true);
30893083

30903084
if (rc || (resp != FW_MSG_CODE_NVM_OK)) {
30913085
DP_NOTICE(cdev, "MCP command rc = %d\n", rc);
30923086
break;
30933087
}
30943088

3095-
/* This can be a lengthy process, and it's possible scheduler
3096-
* isn't preemptible. Sleep a bit to prevent CPU hogging.
3097-
*/
3098-
if (bytes_left % 0x1000 <
3099-
(bytes_left - read_len) % 0x1000)
3100-
usleep_range(1000, 2000);
3101-
31023089
offset += read_len;
31033090
bytes_left -= read_len;
31043091
}

0 commit comments

Comments
 (0)