Skip to content

Commit

Permalink
qed: make 'ethtool -d' 10 times faster
Browse files Browse the repository at this point in the history
As a side effect of commit 5401c3e ("qed: allow sleep in
qed_mcp_trace_dump()"), 'ethtool -d' became much slower.
Almost all the time is spent collecting the "mcp_trace".
It is caused by sleeping too long in _qed_mcp_cmd_and_union.
When called with sleeping not allowed, the function delays for 10 µs
between firmware polls. But if sleeping is allowed, it sleeps for 10 ms
instead.

The sleeps in _qed_mcp_cmd_and_union are unnecessarily long.
Replace msleep with usleep_range, which allows to achieve a similar
polling interval like in the no-sleeping mode (10 - 20 µs).

The only caller, qed_mcp_cmd_and_union, can stop doing the
multiplication/division of the usecs/max_retries. The polling interval
and the number of retries do not need to be parameters at all.

On my test system, 'ethtool -d' now takes 4 seconds instead of 44.

Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
Link: https://patch.msgid.link/20240930201307.330692-2-mschmidt@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Michal Schmidt authored and Jakub Kicinski committed Oct 4, 2024
1 parent 4cd0bd1 commit b8db67d
Showing 1 changed file with 15 additions and 21 deletions.
36 changes: 15 additions & 21 deletions drivers/net/ethernet/qlogic/qed/qed_mcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -459,12 +459,11 @@ static void qed_mcp_print_cpu_info(struct qed_hwfn *p_hwfn,
static int
_qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
struct qed_mcp_mb_params *p_mb_params,
u32 max_retries, u32 usecs)
struct qed_mcp_mb_params *p_mb_params)
{
u32 cnt = 0, msecs = DIV_ROUND_UP(usecs, 1000);
struct qed_mcp_cmd_elem *p_cmd_elem;
u16 seq_num;
u32 cnt = 0;
int rc = 0;

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

if (QED_MB_FLAGS_IS_SET(p_mb_params, CAN_SLEEP))
msleep(msecs);
usleep_range(QED_MCP_RESP_ITER_US,
QED_MCP_RESP_ITER_US * 2);
else
udelay(usecs);
} while (++cnt < max_retries);
udelay(QED_MCP_RESP_ITER_US);
} while (++cnt < QED_DRV_MB_MAX_RETRIES);

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

if (QED_MB_FLAGS_IS_SET(p_mb_params, CAN_SLEEP))
msleep(msecs);
usleep_range(QED_MCP_RESP_ITER_US,
QED_MCP_RESP_ITER_US * 2);
else
udelay(usecs);
udelay(QED_MCP_RESP_ITER_US);

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

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

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

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

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

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

if (QED_MB_FLAGS_IS_SET(p_mb_params, CAN_SLEEP)) {
max_retries = DIV_ROUND_UP(max_retries, 1000);
usecs *= 1000;
}

return _qed_mcp_cmd_and_union(p_hwfn, p_ptt, p_mb_params, max_retries,
usecs);
return _qed_mcp_cmd_and_union(p_hwfn, p_ptt, p_mb_params);
}

static int _qed_mcp_cmd(struct qed_hwfn *p_hwfn,
Expand Down

0 comments on commit b8db67d

Please sign in to comment.