@@ -416,7 +416,7 @@ static int hclge_mac_update_stats_defective(struct hclge_dev *hdev)
416
416
{
417
417
#define HCLGE_MAC_CMD_NUM 21
418
418
419
- u64 * data = (u64 * )(& hdev -> hw_stats . mac_stats );
419
+ u64 * data = (u64 * )(& hdev -> mac_stats );
420
420
struct hclge_desc desc [HCLGE_MAC_CMD_NUM ];
421
421
__le64 * desc_data ;
422
422
int i , k , n ;
@@ -453,7 +453,7 @@ static int hclge_mac_update_stats_defective(struct hclge_dev *hdev)
453
453
454
454
static int hclge_mac_update_stats_complete (struct hclge_dev * hdev , u32 desc_num )
455
455
{
456
- u64 * data = (u64 * )(& hdev -> hw_stats . mac_stats );
456
+ u64 * data = (u64 * )(& hdev -> mac_stats );
457
457
struct hclge_desc * desc ;
458
458
__le64 * desc_data ;
459
459
u16 i , k , n ;
@@ -802,7 +802,7 @@ static void hclge_get_stats(struct hnae3_handle *handle, u64 *data)
802
802
struct hclge_dev * hdev = vport -> back ;
803
803
u64 * p ;
804
804
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 ,
806
806
ARRAY_SIZE (g_mac_stats_string ), data );
807
807
p = hclge_tqps_get_stats (handle , p );
808
808
}
@@ -815,8 +815,8 @@ static void hclge_get_mac_stat(struct hnae3_handle *handle,
815
815
816
816
hclge_update_stats (handle , NULL );
817
817
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 ;
820
820
}
821
821
822
822
static int hclge_parse_func_status (struct hclge_dev * hdev ,
@@ -2665,31 +2665,26 @@ static int hclge_mac_init(struct hclge_dev *hdev)
2665
2665
2666
2666
static void hclge_mbx_task_schedule (struct hclge_dev * hdev )
2667
2667
{
2668
- if (!test_bit (HCLGE_STATE_CMD_DISABLE , & hdev -> state ) &&
2668
+ if (!test_bit (HCLGE_STATE_REMOVING , & hdev -> state ) &&
2669
2669
!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 );
2672
2672
}
2673
2673
2674
2674
static void hclge_reset_task_schedule (struct hclge_dev * hdev )
2675
2675
{
2676
2676
if (!test_bit (HCLGE_STATE_REMOVING , & hdev -> state ) &&
2677
2677
!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 );
2680
2680
}
2681
2681
2682
2682
void hclge_task_schedule (struct hclge_dev * hdev , unsigned long delay_time )
2683
2683
{
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 ))
2689
2685
mod_delayed_work_on (cpumask_first (& hdev -> affinity_mask ),
2690
2686
system_wq , & hdev -> service_task ,
2691
2687
delay_time );
2692
- }
2693
2688
}
2694
2689
2695
2690
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)
2748
2743
2749
2744
if (!client )
2750
2745
return ;
2746
+
2747
+ if (test_and_set_bit (HCLGE_STATE_LINK_UPDATING , & hdev -> state ))
2748
+ return ;
2749
+
2751
2750
state = hclge_get_mac_phy_link (hdev );
2752
2751
if (state != hdev -> hw .mac .link ) {
2753
2752
for (i = 0 ; i < hdev -> num_vmdq_vport + 1 ; i ++ ) {
@@ -2761,6 +2760,8 @@ static void hclge_update_link_status(struct hclge_dev *hdev)
2761
2760
}
2762
2761
hdev -> hw .mac .link = state ;
2763
2762
}
2763
+
2764
+ clear_bit (HCLGE_STATE_LINK_UPDATING , & hdev -> state );
2764
2765
}
2765
2766
2766
2767
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)
3352
3353
return 0 ;
3353
3354
}
3354
3355
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
+
3355
3368
static int hclge_func_reset_sync_vf (struct hclge_dev * hdev )
3356
3369
{
3357
3370
struct hclge_pf_rst_sync_cmd * req ;
@@ -3363,6 +3376,9 @@ static int hclge_func_reset_sync_vf(struct hclge_dev *hdev)
3363
3376
hclge_cmd_setup_basic_desc (& desc , HCLGE_OPC_QUERY_VF_RST_RDY , true);
3364
3377
3365
3378
do {
3379
+ /* vf need to down netdev by mbx during PF or FLR reset */
3380
+ hclge_mailbox_service_task (hdev );
3381
+
3366
3382
ret = hclge_cmd_send (& hdev -> hw , & desc , 1 );
3367
3383
/* for compatible with old firmware, wait
3368
3384
* 100 ms for VF to stop IO
@@ -3939,36 +3955,19 @@ static void hclge_reset_subtask(struct hclge_dev *hdev)
3939
3955
hdev -> reset_type = HNAE3_NONE_RESET ;
3940
3956
}
3941
3957
3942
- static void hclge_reset_service_task (struct work_struct * work )
3958
+ static void hclge_reset_service_task (struct hclge_dev * hdev )
3943
3959
{
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 ;
3946
3962
3947
3963
if (test_and_set_bit (HCLGE_STATE_RST_HANDLING , & hdev -> state ))
3948
3964
return ;
3949
3965
3950
- clear_bit (HCLGE_STATE_RST_SERVICE_SCHED , & hdev -> state );
3951
-
3952
3966
hclge_reset_subtask (hdev );
3953
3967
3954
3968
clear_bit (HCLGE_STATE_RST_HANDLING , & hdev -> state );
3955
3969
}
3956
3970
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
-
3972
3971
static void hclge_update_vport_alive (struct hclge_dev * hdev )
3973
3972
{
3974
3973
int i ;
@@ -3986,29 +3985,62 @@ static void hclge_update_vport_alive(struct hclge_dev *hdev)
3986
3985
}
3987
3986
}
3988
3987
3989
- static void hclge_service_task (struct work_struct * work )
3988
+ static void hclge_periodic_service_task (struct hclge_dev * hdev )
3990
3989
{
3991
- struct hclge_dev * hdev =
3992
- container_of (work , struct hclge_dev , service_task .work );
3990
+ unsigned long delta = round_jiffies_relative (HZ );
3993
3991
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 );
3995
3996
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
+ }
3999
4004
}
4000
4005
4001
- hclge_update_port_info (hdev );
4002
- hclge_update_link_status (hdev );
4006
+ hdev -> serv_processed_cnt ++ ;
4003
4007
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 );
4004
4018
hclge_sync_vlan_filter (hdev );
4005
4019
4006
- if (hdev -> fd_arfs_expire_timer >= HCLGE_FD_ARFS_EXPIRE_TIMER_INTERVAL ) {
4020
+ if (!( hdev -> serv_processed_cnt % HCLGE_ARFS_EXPIRE_INTERVAL ))
4007
4021
hclge_rfs_filter_expire (hdev );
4008
- hdev -> fd_arfs_expire_timer = 0 ;
4009
- }
4010
4022
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 );
4012
4044
}
4013
4045
4014
4046
struct hclge_vport * hclge_get_vport (struct hnae3_handle * handle )
@@ -6734,6 +6766,19 @@ static void hclge_reset_tqp_stats(struct hnae3_handle *handle)
6734
6766
}
6735
6767
}
6736
6768
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
+
6737
6782
static void hclge_set_timer_task (struct hnae3_handle * handle , bool enable )
6738
6783
{
6739
6784
struct hclge_vport * vport = hclge_get_vport (handle );
@@ -6742,12 +6787,12 @@ static void hclge_set_timer_task(struct hnae3_handle *handle, bool enable)
6742
6787
if (enable ) {
6743
6788
hclge_task_schedule (hdev , round_jiffies_relative (HZ ));
6744
6789
} 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 */
6748
6791
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 );
6751
6796
}
6752
6797
}
6753
6798
@@ -9269,10 +9314,6 @@ static void hclge_state_uninit(struct hclge_dev *hdev)
9269
9314
del_timer_sync (& hdev -> reset_timer );
9270
9315
if (hdev -> service_task .work .func )
9271
9316
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 );
9276
9317
}
9277
9318
9278
9319
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)
9477
9518
9478
9519
timer_setup (& hdev -> reset_timer , hclge_reset_timer , 0 );
9479
9520
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 );
9482
9521
9483
9522
/* Setup affinity after service timer setup because add_timer_on
9484
9523
* is called in affinity notify.
@@ -9512,6 +9551,8 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
9512
9551
dev_info (& hdev -> pdev -> dev , "%s driver initialization finished.\n" ,
9513
9552
HCLGE_DRIVER_NAME );
9514
9553
9554
+ hclge_task_schedule (hdev , round_jiffies_relative (HZ ));
9555
+
9515
9556
return 0 ;
9516
9557
9517
9558
err_mdiobus_unreg :
@@ -9534,7 +9575,7 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
9534
9575
9535
9576
static void hclge_stats_clear (struct hclge_dev * hdev )
9536
9577
{
9537
- memset (& hdev -> hw_stats , 0 , sizeof (hdev -> hw_stats ));
9578
+ memset (& hdev -> mac_stats , 0 , sizeof (hdev -> mac_stats ));
9538
9579
}
9539
9580
9540
9581
static int hclge_set_mac_spoofchk (struct hclge_dev * hdev , int vf , bool enable )
0 commit comments