Skip to content

Commit 1c6dfe6

Browse files
Yunsheng Lindavem330
authored andcommitted
net: hns3: remove mailbox and reset work in hclge_main
There are three work (mbx_service_task, service_task, rst_service_task) in the HNS3 driver, mbx_service_task is for handling mailbox work, service_task is for periodic management issue and rst_service_task is for reset related issue, which can be handled in a single work. This patch removes the mbx_service_task and rst_service_task work, and moves the related handling to the service_task work in order to remove concurrency between the three work and to improve efficiency. BTW, since stats_timer in struct hclge_hw_stats is not needed anymore, so removes the definition of struct hclge_hw_stats, and moves mac_stats into struct hclge_dev. Signed-off-by: Yunsheng Lin <[email protected]> Signed-off-by: Huazhong Tan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b3c3fe8 commit 1c6dfe6

File tree

4 files changed

+118
-73
lines changed

4 files changed

+118
-73
lines changed

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,14 @@ void hclge_dbg_dump_rst_info(struct hclge_dev *hdev)
976976
dev_info(&hdev->pdev->dev, "hdev state: 0x%lx\n", hdev->state);
977977
}
978978

979+
static void hclge_dbg_dump_serv_info(struct hclge_dev *hdev)
980+
{
981+
dev_info(&hdev->pdev->dev, "last_serv_processed: %lu\n",
982+
hdev->last_serv_processed);
983+
dev_info(&hdev->pdev->dev, "last_serv_cnt: %lu\n",
984+
hdev->serv_processed_cnt);
985+
}
986+
979987
static void hclge_dbg_get_m7_stats_info(struct hclge_dev *hdev)
980988
{
981989
struct hclge_desc *desc_src, *desc_tmp;
@@ -1227,6 +1235,8 @@ int hclge_dbg_run_cmd(struct hnae3_handle *handle, const char *cmd_buf)
12271235
hclge_dbg_dump_reg_cmd(hdev, &cmd_buf[sizeof(DUMP_REG)]);
12281236
} else if (strncmp(cmd_buf, "dump reset info", 15) == 0) {
12291237
hclge_dbg_dump_rst_info(hdev);
1238+
} else if (strncmp(cmd_buf, "dump serv info", 14) == 0) {
1239+
hclge_dbg_dump_serv_info(hdev);
12301240
} else if (strncmp(cmd_buf, "dump m7 info", 12) == 0) {
12311241
hclge_dbg_get_m7_stats_info(hdev);
12321242
} else if (strncmp(cmd_buf, "dump ncl_config", 15) == 0) {

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c

Lines changed: 102 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ static int hclge_mac_update_stats_defective(struct hclge_dev *hdev)
416416
{
417417
#define HCLGE_MAC_CMD_NUM 21
418418

419-
u64 *data = (u64 *)(&hdev->hw_stats.mac_stats);
419+
u64 *data = (u64 *)(&hdev->mac_stats);
420420
struct hclge_desc desc[HCLGE_MAC_CMD_NUM];
421421
__le64 *desc_data;
422422
int i, k, n;
@@ -453,7 +453,7 @@ static int hclge_mac_update_stats_defective(struct hclge_dev *hdev)
453453

454454
static int hclge_mac_update_stats_complete(struct hclge_dev *hdev, u32 desc_num)
455455
{
456-
u64 *data = (u64 *)(&hdev->hw_stats.mac_stats);
456+
u64 *data = (u64 *)(&hdev->mac_stats);
457457
struct hclge_desc *desc;
458458
__le64 *desc_data;
459459
u16 i, k, n;
@@ -802,7 +802,7 @@ static void hclge_get_stats(struct hnae3_handle *handle, u64 *data)
802802
struct hclge_dev *hdev = vport->back;
803803
u64 *p;
804804

805-
p = hclge_comm_get_stats(&hdev->hw_stats.mac_stats, g_mac_stats_string,
805+
p = hclge_comm_get_stats(&hdev->mac_stats, g_mac_stats_string,
806806
ARRAY_SIZE(g_mac_stats_string), data);
807807
p = hclge_tqps_get_stats(handle, p);
808808
}
@@ -815,8 +815,8 @@ static void hclge_get_mac_stat(struct hnae3_handle *handle,
815815

816816
hclge_update_stats(handle, NULL);
817817

818-
mac_stats->tx_pause_cnt = hdev->hw_stats.mac_stats.mac_tx_mac_pause_num;
819-
mac_stats->rx_pause_cnt = hdev->hw_stats.mac_stats.mac_rx_mac_pause_num;
818+
mac_stats->tx_pause_cnt = hdev->mac_stats.mac_tx_mac_pause_num;
819+
mac_stats->rx_pause_cnt = hdev->mac_stats.mac_rx_mac_pause_num;
820820
}
821821

822822
static int hclge_parse_func_status(struct hclge_dev *hdev,
@@ -2665,31 +2665,26 @@ static int hclge_mac_init(struct hclge_dev *hdev)
26652665

26662666
static void hclge_mbx_task_schedule(struct hclge_dev *hdev)
26672667
{
2668-
if (!test_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state) &&
2668+
if (!test_bit(HCLGE_STATE_REMOVING, &hdev->state) &&
26692669
!test_and_set_bit(HCLGE_STATE_MBX_SERVICE_SCHED, &hdev->state))
2670-
queue_work_on(cpumask_first(&hdev->affinity_mask), system_wq,
2671-
&hdev->mbx_service_task);
2670+
mod_delayed_work_on(cpumask_first(&hdev->affinity_mask),
2671+
system_wq, &hdev->service_task, 0);
26722672
}
26732673

26742674
static void hclge_reset_task_schedule(struct hclge_dev *hdev)
26752675
{
26762676
if (!test_bit(HCLGE_STATE_REMOVING, &hdev->state) &&
26772677
!test_and_set_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state))
2678-
queue_work_on(cpumask_first(&hdev->affinity_mask), system_wq,
2679-
&hdev->rst_service_task);
2678+
mod_delayed_work_on(cpumask_first(&hdev->affinity_mask),
2679+
system_wq, &hdev->service_task, 0);
26802680
}
26812681

26822682
void hclge_task_schedule(struct hclge_dev *hdev, unsigned long delay_time)
26832683
{
2684-
if (!test_bit(HCLGE_STATE_DOWN, &hdev->state) &&
2685-
!test_bit(HCLGE_STATE_REMOVING, &hdev->state) &&
2686-
!test_and_set_bit(HCLGE_STATE_SERVICE_SCHED, &hdev->state)) {
2687-
hdev->hw_stats.stats_timer++;
2688-
hdev->fd_arfs_expire_timer++;
2684+
if (!test_bit(HCLGE_STATE_REMOVING, &hdev->state))
26892685
mod_delayed_work_on(cpumask_first(&hdev->affinity_mask),
26902686
system_wq, &hdev->service_task,
26912687
delay_time);
2692-
}
26932688
}
26942689

26952690
static int hclge_get_mac_link_status(struct hclge_dev *hdev)
@@ -2748,6 +2743,10 @@ static void hclge_update_link_status(struct hclge_dev *hdev)
27482743

27492744
if (!client)
27502745
return;
2746+
2747+
if (test_and_set_bit(HCLGE_STATE_LINK_UPDATING, &hdev->state))
2748+
return;
2749+
27512750
state = hclge_get_mac_phy_link(hdev);
27522751
if (state != hdev->hw.mac.link) {
27532752
for (i = 0; i < hdev->num_vmdq_vport + 1; i++) {
@@ -2761,6 +2760,8 @@ static void hclge_update_link_status(struct hclge_dev *hdev)
27612760
}
27622761
hdev->hw.mac.link = state;
27632762
}
2763+
2764+
clear_bit(HCLGE_STATE_LINK_UPDATING, &hdev->state);
27642765
}
27652766

27662767
static void hclge_update_port_capability(struct hclge_mac *mac)
@@ -3352,6 +3353,18 @@ static int hclge_set_all_vf_rst(struct hclge_dev *hdev, bool reset)
33523353
return 0;
33533354
}
33543355

3356+
static void hclge_mailbox_service_task(struct hclge_dev *hdev)
3357+
{
3358+
if (!test_and_clear_bit(HCLGE_STATE_MBX_SERVICE_SCHED, &hdev->state) ||
3359+
test_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state) ||
3360+
test_and_set_bit(HCLGE_STATE_MBX_HANDLING, &hdev->state))
3361+
return;
3362+
3363+
hclge_mbx_handler(hdev);
3364+
3365+
clear_bit(HCLGE_STATE_MBX_HANDLING, &hdev->state);
3366+
}
3367+
33553368
static int hclge_func_reset_sync_vf(struct hclge_dev *hdev)
33563369
{
33573370
struct hclge_pf_rst_sync_cmd *req;
@@ -3363,6 +3376,9 @@ static int hclge_func_reset_sync_vf(struct hclge_dev *hdev)
33633376
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QUERY_VF_RST_RDY, true);
33643377

33653378
do {
3379+
/* vf need to down netdev by mbx during PF or FLR reset */
3380+
hclge_mailbox_service_task(hdev);
3381+
33663382
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
33673383
/* for compatible with old firmware, wait
33683384
* 100 ms for VF to stop IO
@@ -3939,36 +3955,19 @@ static void hclge_reset_subtask(struct hclge_dev *hdev)
39393955
hdev->reset_type = HNAE3_NONE_RESET;
39403956
}
39413957

3942-
static void hclge_reset_service_task(struct work_struct *work)
3958+
static void hclge_reset_service_task(struct hclge_dev *hdev)
39433959
{
3944-
struct hclge_dev *hdev =
3945-
container_of(work, struct hclge_dev, rst_service_task);
3960+
if (!test_and_clear_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state))
3961+
return;
39463962

39473963
if (test_and_set_bit(HCLGE_STATE_RST_HANDLING, &hdev->state))
39483964
return;
39493965

3950-
clear_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state);
3951-
39523966
hclge_reset_subtask(hdev);
39533967

39543968
clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state);
39553969
}
39563970

3957-
static void hclge_mailbox_service_task(struct work_struct *work)
3958-
{
3959-
struct hclge_dev *hdev =
3960-
container_of(work, struct hclge_dev, mbx_service_task);
3961-
3962-
if (test_and_set_bit(HCLGE_STATE_MBX_HANDLING, &hdev->state))
3963-
return;
3964-
3965-
clear_bit(HCLGE_STATE_MBX_SERVICE_SCHED, &hdev->state);
3966-
3967-
hclge_mbx_handler(hdev);
3968-
3969-
clear_bit(HCLGE_STATE_MBX_HANDLING, &hdev->state);
3970-
}
3971-
39723971
static void hclge_update_vport_alive(struct hclge_dev *hdev)
39733972
{
39743973
int i;
@@ -3986,29 +3985,62 @@ static void hclge_update_vport_alive(struct hclge_dev *hdev)
39863985
}
39873986
}
39883987

3989-
static void hclge_service_task(struct work_struct *work)
3988+
static void hclge_periodic_service_task(struct hclge_dev *hdev)
39903989
{
3991-
struct hclge_dev *hdev =
3992-
container_of(work, struct hclge_dev, service_task.work);
3990+
unsigned long delta = round_jiffies_relative(HZ);
39933991

3994-
clear_bit(HCLGE_STATE_SERVICE_SCHED, &hdev->state);
3992+
/* Always handle the link updating to make sure link state is
3993+
* updated when it is triggered by mbx.
3994+
*/
3995+
hclge_update_link_status(hdev);
39953996

3996-
if (hdev->hw_stats.stats_timer >= HCLGE_STATS_TIMER_INTERVAL) {
3997-
hclge_update_stats_for_all(hdev);
3998-
hdev->hw_stats.stats_timer = 0;
3997+
if (time_is_after_jiffies(hdev->last_serv_processed + HZ)) {
3998+
delta = jiffies - hdev->last_serv_processed;
3999+
4000+
if (delta < round_jiffies_relative(HZ)) {
4001+
delta = round_jiffies_relative(HZ) - delta;
4002+
goto out;
4003+
}
39994004
}
40004005

4001-
hclge_update_port_info(hdev);
4002-
hclge_update_link_status(hdev);
4006+
hdev->serv_processed_cnt++;
40034007
hclge_update_vport_alive(hdev);
4008+
4009+
if (test_bit(HCLGE_STATE_DOWN, &hdev->state)) {
4010+
hdev->last_serv_processed = jiffies;
4011+
goto out;
4012+
}
4013+
4014+
if (!(hdev->serv_processed_cnt % HCLGE_STATS_TIMER_INTERVAL))
4015+
hclge_update_stats_for_all(hdev);
4016+
4017+
hclge_update_port_info(hdev);
40044018
hclge_sync_vlan_filter(hdev);
40054019

4006-
if (hdev->fd_arfs_expire_timer >= HCLGE_FD_ARFS_EXPIRE_TIMER_INTERVAL) {
4020+
if (!(hdev->serv_processed_cnt % HCLGE_ARFS_EXPIRE_INTERVAL))
40074021
hclge_rfs_filter_expire(hdev);
4008-
hdev->fd_arfs_expire_timer = 0;
4009-
}
40104022

4011-
hclge_task_schedule(hdev, round_jiffies_relative(HZ));
4023+
hdev->last_serv_processed = jiffies;
4024+
4025+
out:
4026+
hclge_task_schedule(hdev, delta);
4027+
}
4028+
4029+
static void hclge_service_task(struct work_struct *work)
4030+
{
4031+
struct hclge_dev *hdev =
4032+
container_of(work, struct hclge_dev, service_task.work);
4033+
4034+
hclge_reset_service_task(hdev);
4035+
hclge_mailbox_service_task(hdev);
4036+
hclge_periodic_service_task(hdev);
4037+
4038+
/* Handle reset and mbx again in case periodical task delays the
4039+
* handling by calling hclge_task_schedule() in
4040+
* hclge_periodic_service_task().
4041+
*/
4042+
hclge_reset_service_task(hdev);
4043+
hclge_mailbox_service_task(hdev);
40124044
}
40134045

40144046
struct hclge_vport *hclge_get_vport(struct hnae3_handle *handle)
@@ -6734,6 +6766,19 @@ static void hclge_reset_tqp_stats(struct hnae3_handle *handle)
67346766
}
67356767
}
67366768

6769+
static void hclge_flush_link_update(struct hclge_dev *hdev)
6770+
{
6771+
#define HCLGE_FLUSH_LINK_TIMEOUT 100000
6772+
6773+
unsigned long last = hdev->serv_processed_cnt;
6774+
int i = 0;
6775+
6776+
while (test_bit(HCLGE_STATE_LINK_UPDATING, &hdev->state) &&
6777+
i++ < HCLGE_FLUSH_LINK_TIMEOUT &&
6778+
last == hdev->serv_processed_cnt)
6779+
usleep_range(1, 1);
6780+
}
6781+
67376782
static void hclge_set_timer_task(struct hnae3_handle *handle, bool enable)
67386783
{
67396784
struct hclge_vport *vport = hclge_get_vport(handle);
@@ -6742,12 +6787,12 @@ static void hclge_set_timer_task(struct hnae3_handle *handle, bool enable)
67426787
if (enable) {
67436788
hclge_task_schedule(hdev, round_jiffies_relative(HZ));
67446789
} else {
6745-
/* Set the DOWN flag here to disable the service to be
6746-
* scheduled again
6747-
*/
6790+
/* Set the DOWN flag here to disable link updating */
67486791
set_bit(HCLGE_STATE_DOWN, &hdev->state);
6749-
cancel_delayed_work_sync(&hdev->service_task);
6750-
clear_bit(HCLGE_STATE_SERVICE_SCHED, &hdev->state);
6792+
6793+
/* flush memory to make sure DOWN is seen by service task */
6794+
smp_mb__before_atomic();
6795+
hclge_flush_link_update(hdev);
67516796
}
67526797
}
67536798

@@ -9269,10 +9314,6 @@ static void hclge_state_uninit(struct hclge_dev *hdev)
92699314
del_timer_sync(&hdev->reset_timer);
92709315
if (hdev->service_task.work.func)
92719316
cancel_delayed_work_sync(&hdev->service_task);
9272-
if (hdev->rst_service_task.func)
9273-
cancel_work_sync(&hdev->rst_service_task);
9274-
if (hdev->mbx_service_task.func)
9275-
cancel_work_sync(&hdev->mbx_service_task);
92769317
}
92779318

92789319
static void hclge_flr_prepare(struct hnae3_ae_dev *ae_dev)
@@ -9477,8 +9518,6 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
94779518

94789519
timer_setup(&hdev->reset_timer, hclge_reset_timer, 0);
94799520
INIT_DELAYED_WORK(&hdev->service_task, hclge_service_task);
9480-
INIT_WORK(&hdev->rst_service_task, hclge_reset_service_task);
9481-
INIT_WORK(&hdev->mbx_service_task, hclge_mailbox_service_task);
94829521

94839522
/* Setup affinity after service timer setup because add_timer_on
94849523
* is called in affinity notify.
@@ -9512,6 +9551,8 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
95129551
dev_info(&hdev->pdev->dev, "%s driver initialization finished.\n",
95139552
HCLGE_DRIVER_NAME);
95149553

9554+
hclge_task_schedule(hdev, round_jiffies_relative(HZ));
9555+
95159556
return 0;
95169557

95179558
err_mdiobus_unreg:
@@ -9534,7 +9575,7 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
95349575

95359576
static void hclge_stats_clear(struct hclge_dev *hdev)
95369577
{
9537-
memset(&hdev->hw_stats, 0, sizeof(hdev->hw_stats));
9578+
memset(&hdev->mac_stats, 0, sizeof(hdev->mac_stats));
95389579
}
95399580

95409581
static int hclge_set_mac_spoofchk(struct hclge_dev *hdev, int vf, bool enable)

0 commit comments

Comments
 (0)