Skip to content

Commit

Permalink
net: hns3: add log for workqueue scheduled late
Browse files Browse the repository at this point in the history
When the mbx or reset message arrives, the driver is informed
through an interrupt. This task can be processed only after
the workqueue is scheduled. In some cases, this workqueue
scheduling takes a long time. As a result, the mbx or reset
service task cannot be processed in time. So add some warning
message to improve debugging efficiency for this case.

Signed-off-by: Yufeng Mo <moyufeng@huawei.com>
Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Yufeng Mo authored and David S. Miller committed Nov 24, 2021
1 parent 4593222 commit d9069da
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 2 deletions.
3 changes: 3 additions & 0 deletions drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ enum hclge_mbx_tbl_cfg_subcode {
#define HCLGE_MBX_MAX_RESP_DATA_SIZE 8U
#define HCLGE_MBX_MAX_RING_CHAIN_PARAM_NUM 4

#define HCLGE_RESET_SCHED_TIMEOUT (3 * HZ)
#define HCLGE_MBX_SCHED_TIMEOUT (HZ / 2)

struct hclge_ring_chain_param {
u8 ring_type;
u8 tqp_index;
Expand Down
22 changes: 20 additions & 2 deletions drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2933,16 +2933,20 @@ static int hclge_mac_init(struct hclge_dev *hdev)
static void hclge_mbx_task_schedule(struct hclge_dev *hdev)
{
if (!test_bit(HCLGE_STATE_REMOVING, &hdev->state) &&
!test_and_set_bit(HCLGE_STATE_MBX_SERVICE_SCHED, &hdev->state))
!test_and_set_bit(HCLGE_STATE_MBX_SERVICE_SCHED, &hdev->state)) {
hdev->last_mbx_scheduled = jiffies;
mod_delayed_work(hclge_wq, &hdev->service_task, 0);
}
}

static void hclge_reset_task_schedule(struct hclge_dev *hdev)
{
if (!test_bit(HCLGE_STATE_REMOVING, &hdev->state) &&
test_bit(HCLGE_STATE_SERVICE_INITED, &hdev->state) &&
!test_and_set_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state))
!test_and_set_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state)) {
hdev->last_rst_scheduled = jiffies;
mod_delayed_work(hclge_wq, &hdev->service_task, 0);
}
}

static void hclge_errhand_task_schedule(struct hclge_dev *hdev)
Expand Down Expand Up @@ -3831,6 +3835,13 @@ static void hclge_mailbox_service_task(struct hclge_dev *hdev)
test_and_set_bit(HCLGE_STATE_MBX_HANDLING, &hdev->state))
return;

if (time_is_before_jiffies(hdev->last_mbx_scheduled +
HCLGE_MBX_SCHED_TIMEOUT))
dev_warn(&hdev->pdev->dev,
"mbx service task is scheduled after %ums on cpu%u!\n",
jiffies_to_msecs(jiffies - hdev->last_mbx_scheduled),
smp_processor_id());

hclge_mbx_handler(hdev);

clear_bit(HCLGE_STATE_MBX_HANDLING, &hdev->state);
Expand Down Expand Up @@ -4480,6 +4491,13 @@ static void hclge_reset_service_task(struct hclge_dev *hdev)
if (!test_and_clear_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state))
return;

if (time_is_before_jiffies(hdev->last_rst_scheduled +
HCLGE_RESET_SCHED_TIMEOUT))
dev_warn(&hdev->pdev->dev,
"reset service task is scheduled after %ums on cpu%u!\n",
jiffies_to_msecs(jiffies - hdev->last_rst_scheduled),
smp_processor_id());

down(&hdev->reset_sem);
set_bit(HCLGE_STATE_RST_HANDLING, &hdev->state);

Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,8 @@ struct hclge_dev {
u16 hclge_fd_rule_num;
unsigned long serv_processed_cnt;
unsigned long last_serv_processed;
unsigned long last_rst_scheduled;
unsigned long last_mbx_scheduled;
unsigned long fd_bmap[BITS_TO_LONGS(MAX_FD_FILTER_NUM)];
enum HCLGE_FD_ACTIVE_RULE_TYPE fd_active_type;
u8 fd_en;
Expand Down
8 changes: 8 additions & 0 deletions drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,14 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
if (hnae3_get_bit(req->mbx_need_resp, HCLGE_MBX_NEED_RESP_B) &&
req->msg.code < HCLGE_MBX_GET_VF_FLR_STATUS) {
resp_msg.status = ret;
if (time_is_before_jiffies(hdev->last_mbx_scheduled +
HCLGE_MBX_SCHED_TIMEOUT))
dev_warn(&hdev->pdev->dev,
"resp vport%u mbx(%u,%u) late\n",
req->mbx_src_vfid,
req->msg.code,
req->msg.subcode);

hclge_gen_resp_to_vf(vport, req, &resp_msg);
}

Expand Down

0 comments on commit d9069da

Please sign in to comment.