Skip to content

Commit ff20009

Browse files
Yunsheng Lindavem330
authored andcommitted
net: hns3: remove unnecessary work in hclgevf_main
There are four work (mbx_service_task, service_task, rst_service_task and keep_alive_task)in the hclgevf module, mbx_service_task is for handling mailbox issue, service_task is for periodic management issue and rst_service_task is for reset related issue, keep_alive_task is used to keepalive between PF and VF, which can be done in a single work. This patch removes the mbx_service_task, rst_service_task and keep_alive_task, and moves the related handling to the service_task work in order to remove concurrency between the four work and to improve efficiency. Signed-off-by: Yunsheng Lin <[email protected]> Signed-off-by: Huazhong Tan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 1c6dfe6 commit ff20009

File tree

2 files changed

+88
-96
lines changed

2 files changed

+88
-96
lines changed

drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c

Lines changed: 85 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,9 @@ void hclgevf_update_link_status(struct hclgevf_dev *hdev, int link_state)
440440
struct hnae3_client *rclient;
441441
struct hnae3_client *client;
442442

443+
if (test_and_set_bit(HCLGEVF_STATE_LINK_UPDATING, &hdev->state))
444+
return;
445+
443446
client = handle->client;
444447
rclient = hdev->roce_client;
445448

@@ -452,6 +455,8 @@ void hclgevf_update_link_status(struct hclgevf_dev *hdev, int link_state)
452455
rclient->ops->link_status_change(rhandle, !!link_state);
453456
hdev->hw.mac.link = link_state;
454457
}
458+
459+
clear_bit(HCLGEVF_STATE_LINK_UPDATING, &hdev->state);
455460
}
456461

457462
static void hclgevf_update_link_mode(struct hclgevf_dev *hdev)
@@ -1767,54 +1772,38 @@ static void hclgevf_get_misc_vector(struct hclgevf_dev *hdev)
17671772

17681773
void hclgevf_reset_task_schedule(struct hclgevf_dev *hdev)
17691774
{
1770-
if (!test_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state) &&
1771-
!test_bit(HCLGEVF_STATE_REMOVING, &hdev->state)) {
1772-
set_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state);
1773-
schedule_work(&hdev->rst_service_task);
1774-
}
1775+
if (!test_bit(HCLGEVF_STATE_REMOVING, &hdev->state) &&
1776+
!test_and_set_bit(HCLGEVF_STATE_RST_SERVICE_SCHED,
1777+
&hdev->state))
1778+
mod_delayed_work(system_wq, &hdev->service_task, 0);
17751779
}
17761780

17771781
void hclgevf_mbx_task_schedule(struct hclgevf_dev *hdev)
17781782
{
1779-
if (!test_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state) &&
1780-
!test_bit(HCLGEVF_STATE_MBX_HANDLING, &hdev->state)) {
1781-
set_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state);
1782-
schedule_work(&hdev->mbx_service_task);
1783-
}
1783+
if (!test_bit(HCLGEVF_STATE_REMOVING, &hdev->state) &&
1784+
!test_and_set_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED,
1785+
&hdev->state))
1786+
mod_delayed_work(system_wq, &hdev->service_task, 0);
17841787
}
17851788

1786-
static void hclgevf_task_schedule(struct hclgevf_dev *hdev)
1789+
static void hclgevf_task_schedule(struct hclgevf_dev *hdev,
1790+
unsigned long delay)
17871791
{
1788-
if (!test_bit(HCLGEVF_STATE_DOWN, &hdev->state) &&
1789-
!test_and_set_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state)) {
1790-
mod_delayed_work(system_wq, &hdev->service_task,
1791-
round_jiffies_relative(HZ));
1792-
hdev->stats_timer++;
1793-
}
1792+
if (!test_bit(HCLGEVF_STATE_REMOVING, &hdev->state))
1793+
mod_delayed_work(system_wq, &hdev->service_task, delay);
17941794
}
17951795

1796-
static void hclgevf_deferred_task_schedule(struct hclgevf_dev *hdev)
1797-
{
1798-
/* if we have any pending mailbox event then schedule the mbx task */
1799-
if (hdev->mbx_event_pending)
1800-
hclgevf_mbx_task_schedule(hdev);
1801-
1802-
if (test_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state))
1803-
hclgevf_reset_task_schedule(hdev);
1804-
}
1805-
1806-
static void hclgevf_reset_service_task(struct work_struct *work)
1796+
static void hclgevf_reset_service_task(struct hclgevf_dev *hdev)
18071797
{
18081798
#define HCLGEVF_MAX_RESET_ATTEMPTS_CNT 3
18091799

1810-
struct hclgevf_dev *hdev =
1811-
container_of(work, struct hclgevf_dev, rst_service_task);
18121800
int ret;
18131801

1814-
if (test_and_set_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state))
1802+
if (!test_and_clear_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state))
18151803
return;
18161804

1817-
clear_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state);
1805+
if (test_and_set_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state))
1806+
return;
18181807

18191808
if (test_and_clear_bit(HCLGEVF_RESET_PENDING,
18201809
&hdev->reset_state)) {
@@ -1877,39 +1866,24 @@ static void hclgevf_reset_service_task(struct work_struct *work)
18771866
clear_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state);
18781867
}
18791868

1880-
static void hclgevf_mailbox_service_task(struct work_struct *work)
1869+
static void hclgevf_mailbox_service_task(struct hclgevf_dev *hdev)
18811870
{
1882-
struct hclgevf_dev *hdev;
1883-
1884-
hdev = container_of(work, struct hclgevf_dev, mbx_service_task);
1871+
if (!test_and_clear_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state))
1872+
return;
18851873

18861874
if (test_and_set_bit(HCLGEVF_STATE_MBX_HANDLING, &hdev->state))
18871875
return;
18881876

1889-
clear_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state);
1890-
18911877
hclgevf_mbx_async_handler(hdev);
18921878

18931879
clear_bit(HCLGEVF_STATE_MBX_HANDLING, &hdev->state);
18941880
}
18951881

1896-
static void hclgevf_keep_alive_timer(struct timer_list *t)
1897-
{
1898-
struct hclgevf_dev *hdev = from_timer(hdev, t, keep_alive_timer);
1899-
1900-
schedule_work(&hdev->keep_alive_task);
1901-
mod_timer(&hdev->keep_alive_timer, jiffies +
1902-
HCLGEVF_KEEP_ALIVE_TASK_INTERVAL * HZ);
1903-
}
1904-
1905-
static void hclgevf_keep_alive_task(struct work_struct *work)
1882+
static void hclgevf_keep_alive(struct hclgevf_dev *hdev)
19061883
{
1907-
struct hclgevf_dev *hdev;
19081884
u8 respmsg;
19091885
int ret;
19101886

1911-
hdev = container_of(work, struct hclgevf_dev, keep_alive_task);
1912-
19131887
if (test_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state))
19141888
return;
19151889

@@ -1920,19 +1894,32 @@ static void hclgevf_keep_alive_task(struct work_struct *work)
19201894
"VF sends keep alive cmd failed(=%d)\n", ret);
19211895
}
19221896

1923-
static void hclgevf_service_task(struct work_struct *work)
1897+
static void hclgevf_periodic_service_task(struct hclgevf_dev *hdev)
19241898
{
1925-
struct hnae3_handle *handle;
1926-
struct hclgevf_dev *hdev;
1899+
unsigned long delta = round_jiffies_relative(HZ);
1900+
struct hnae3_handle *handle = &hdev->nic;
19271901

1928-
hdev = container_of(work, struct hclgevf_dev, service_task.work);
1929-
handle = &hdev->nic;
1902+
if (time_is_after_jiffies(hdev->last_serv_processed + HZ)) {
1903+
delta = jiffies - hdev->last_serv_processed;
19301904

1931-
if (hdev->stats_timer >= HCLGEVF_STATS_TIMER_INTERVAL) {
1932-
hclgevf_tqps_update_stats(handle);
1933-
hdev->stats_timer = 0;
1905+
if (delta < round_jiffies_relative(HZ)) {
1906+
delta = round_jiffies_relative(HZ) - delta;
1907+
goto out;
1908+
}
1909+
}
1910+
1911+
hdev->serv_processed_cnt++;
1912+
if (!(hdev->serv_processed_cnt % HCLGEVF_KEEP_ALIVE_TASK_INTERVAL))
1913+
hclgevf_keep_alive(hdev);
1914+
1915+
if (test_bit(HCLGEVF_STATE_DOWN, &hdev->state)) {
1916+
hdev->last_serv_processed = jiffies;
1917+
goto out;
19341918
}
19351919

1920+
if (!(hdev->serv_processed_cnt % HCLGEVF_STATS_TIMER_INTERVAL))
1921+
hclgevf_tqps_update_stats(handle);
1922+
19361923
/* request the link status from the PF. PF would be able to tell VF
19371924
* about such updates in future so we might remove this later
19381925
*/
@@ -1942,11 +1929,27 @@ static void hclgevf_service_task(struct work_struct *work)
19421929

19431930
hclgevf_sync_vlan_filter(hdev);
19441931

1945-
hclgevf_deferred_task_schedule(hdev);
1932+
hdev->last_serv_processed = jiffies;
19461933

1947-
clear_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state);
1934+
out:
1935+
hclgevf_task_schedule(hdev, delta);
1936+
}
1937+
1938+
static void hclgevf_service_task(struct work_struct *work)
1939+
{
1940+
struct hclgevf_dev *hdev = container_of(work, struct hclgevf_dev,
1941+
service_task.work);
19481942

1949-
hclgevf_task_schedule(hdev);
1943+
hclgevf_reset_service_task(hdev);
1944+
hclgevf_mailbox_service_task(hdev);
1945+
hclgevf_periodic_service_task(hdev);
1946+
1947+
/* Handle reset and mbx again in case periodical task delays the
1948+
* handling by calling hclgevf_task_schedule() in
1949+
* hclgevf_periodic_service_task()
1950+
*/
1951+
hclgevf_reset_service_task(hdev);
1952+
hclgevf_mailbox_service_task(hdev);
19501953
}
19511954

19521955
static void hclgevf_clear_event_cause(struct hclgevf_dev *hdev, u32 regclr)
@@ -2183,16 +2186,31 @@ static int hclgevf_init_vlan_config(struct hclgevf_dev *hdev)
21832186
false);
21842187
}
21852188

2189+
static void hclgevf_flush_link_update(struct hclgevf_dev *hdev)
2190+
{
2191+
#define HCLGEVF_FLUSH_LINK_TIMEOUT 100000
2192+
2193+
unsigned long last = hdev->serv_processed_cnt;
2194+
int i = 0;
2195+
2196+
while (test_bit(HCLGEVF_STATE_LINK_UPDATING, &hdev->state) &&
2197+
i++ < HCLGEVF_FLUSH_LINK_TIMEOUT &&
2198+
last == hdev->serv_processed_cnt)
2199+
usleep_range(1, 1);
2200+
}
2201+
21862202
static void hclgevf_set_timer_task(struct hnae3_handle *handle, bool enable)
21872203
{
21882204
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
21892205

21902206
if (enable) {
2191-
hclgevf_task_schedule(hdev);
2207+
hclgevf_task_schedule(hdev, 0);
21922208
} else {
21932209
set_bit(HCLGEVF_STATE_DOWN, &hdev->state);
2194-
cancel_delayed_work_sync(&hdev->service_task);
2195-
clear_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state);
2210+
2211+
/* flush memory to make sure DOWN is seen by service task */
2212+
smp_mb__before_atomic();
2213+
hclgevf_flush_link_update(hdev);
21962214
}
21972215
}
21982216

@@ -2239,16 +2257,12 @@ static int hclgevf_set_alive(struct hnae3_handle *handle, bool alive)
22392257

22402258
static int hclgevf_client_start(struct hnae3_handle *handle)
22412259
{
2242-
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
22432260
int ret;
22442261

22452262
ret = hclgevf_set_alive(handle, true);
22462263
if (ret)
22472264
return ret;
22482265

2249-
mod_timer(&hdev->keep_alive_timer, jiffies +
2250-
HCLGEVF_KEEP_ALIVE_TASK_INTERVAL * HZ);
2251-
22522266
return 0;
22532267
}
22542268

@@ -2261,22 +2275,14 @@ static void hclgevf_client_stop(struct hnae3_handle *handle)
22612275
if (ret)
22622276
dev_warn(&hdev->pdev->dev,
22632277
"%s failed %d\n", __func__, ret);
2264-
2265-
del_timer_sync(&hdev->keep_alive_timer);
2266-
cancel_work_sync(&hdev->keep_alive_task);
22672278
}
22682279

22692280
static void hclgevf_state_init(struct hclgevf_dev *hdev)
22702281
{
2271-
/* setup tasks for the MBX */
2272-
INIT_WORK(&hdev->mbx_service_task, hclgevf_mailbox_service_task);
22732282
clear_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state);
22742283
clear_bit(HCLGEVF_STATE_MBX_HANDLING, &hdev->state);
22752284

22762285
INIT_DELAYED_WORK(&hdev->service_task, hclgevf_service_task);
2277-
clear_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state);
2278-
2279-
INIT_WORK(&hdev->rst_service_task, hclgevf_reset_service_task);
22802286

22812287
mutex_init(&hdev->mbx_resp.mbx_mutex);
22822288

@@ -2289,16 +2295,8 @@ static void hclgevf_state_uninit(struct hclgevf_dev *hdev)
22892295
set_bit(HCLGEVF_STATE_DOWN, &hdev->state);
22902296
set_bit(HCLGEVF_STATE_REMOVING, &hdev->state);
22912297

2292-
if (hdev->keep_alive_timer.function)
2293-
del_timer_sync(&hdev->keep_alive_timer);
2294-
if (hdev->keep_alive_task.func)
2295-
cancel_work_sync(&hdev->keep_alive_task);
22962298
if (hdev->service_task.work.func)
22972299
cancel_delayed_work_sync(&hdev->service_task);
2298-
if (hdev->mbx_service_task.func)
2299-
cancel_work_sync(&hdev->mbx_service_task);
2300-
if (hdev->rst_service_task.func)
2301-
cancel_work_sync(&hdev->rst_service_task);
23022300

23032301
mutex_destroy(&hdev->mbx_resp.mbx_mutex);
23042302
}
@@ -2796,6 +2794,8 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
27962794
dev_info(&hdev->pdev->dev, "finished initializing %s driver\n",
27972795
HCLGEVF_DRIVER_NAME);
27982796

2797+
hclgevf_task_schedule(hdev, round_jiffies_relative(HZ));
2798+
27992799
return 0;
28002800

28012801
err_config:
@@ -2827,7 +2827,6 @@ static void hclgevf_uninit_hdev(struct hclgevf_dev *hdev)
28272827
static int hclgevf_init_ae_dev(struct hnae3_ae_dev *ae_dev)
28282828
{
28292829
struct pci_dev *pdev = ae_dev->pdev;
2830-
struct hclgevf_dev *hdev;
28312830
int ret;
28322831

28332832
ret = hclgevf_alloc_hdev(ae_dev);
@@ -2842,10 +2841,6 @@ static int hclgevf_init_ae_dev(struct hnae3_ae_dev *ae_dev)
28422841
return ret;
28432842
}
28442843

2845-
hdev = ae_dev->priv;
2846-
timer_setup(&hdev->keep_alive_timer, hclgevf_keep_alive_timer, 0);
2847-
INIT_WORK(&hdev->keep_alive_task, hclgevf_keep_alive_task);
2848-
28492844
return 0;
28502845
}
28512846

drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,12 @@ enum hclgevf_states {
142142
HCLGEVF_STATE_REMOVING,
143143
HCLGEVF_STATE_NIC_REGISTERED,
144144
/* task states */
145-
HCLGEVF_STATE_SERVICE_SCHED,
146145
HCLGEVF_STATE_RST_SERVICE_SCHED,
147146
HCLGEVF_STATE_RST_HANDLING,
148147
HCLGEVF_STATE_MBX_SERVICE_SCHED,
149148
HCLGEVF_STATE_MBX_HANDLING,
150149
HCLGEVF_STATE_CMD_DISABLE,
150+
HCLGEVF_STATE_LINK_UPDATING,
151151
};
152152

153153
struct hclgevf_mac {
@@ -283,11 +283,7 @@ struct hclgevf_dev {
283283
struct hclgevf_mbx_resp_status mbx_resp; /* mailbox response */
284284
struct hclgevf_mbx_arq_ring arq; /* mailbox async rx queue */
285285

286-
struct timer_list keep_alive_timer;
287286
struct delayed_work service_task;
288-
struct work_struct keep_alive_task;
289-
struct work_struct rst_service_task;
290-
struct work_struct mbx_service_task;
291287

292288
struct hclgevf_tqp *htqp;
293289

@@ -297,7 +293,8 @@ struct hclgevf_dev {
297293
struct hnae3_client *nic_client;
298294
struct hnae3_client *roce_client;
299295
u32 flag;
300-
u32 stats_timer;
296+
unsigned long serv_processed_cnt;
297+
unsigned long last_serv_processed;
301298
};
302299

303300
static inline bool hclgevf_is_reset_pending(struct hclgevf_dev *hdev)

0 commit comments

Comments
 (0)