@@ -243,6 +243,19 @@ static int mlx5_fw_tracer_allocate_strings_db(struct mlx5_fw_tracer *tracer)
243
243
return - ENOMEM ;
244
244
}
245
245
246
+ static void
247
+ mlx5_fw_tracer_init_saved_traces_array (struct mlx5_fw_tracer * tracer )
248
+ {
249
+ tracer -> st_arr .saved_traces_index = 0 ;
250
+ mutex_init (& tracer -> st_arr .lock );
251
+ }
252
+
253
+ static void
254
+ mlx5_fw_tracer_clean_saved_traces_array (struct mlx5_fw_tracer * tracer )
255
+ {
256
+ mutex_destroy (& tracer -> st_arr .lock );
257
+ }
258
+
246
259
static void mlx5_tracer_read_strings_db (struct work_struct * work )
247
260
{
248
261
struct mlx5_fw_tracer * tracer = container_of (work , struct mlx5_fw_tracer ,
@@ -522,6 +535,24 @@ static void mlx5_fw_tracer_clean_ready_list(struct mlx5_fw_tracer *tracer)
522
535
list_del (& str_frmt -> list );
523
536
}
524
537
538
+ static void mlx5_fw_tracer_save_trace (struct mlx5_fw_tracer * tracer ,
539
+ u64 timestamp , bool lost ,
540
+ u8 event_id , char * msg )
541
+ {
542
+ struct mlx5_fw_trace_data * trace_data ;
543
+
544
+ mutex_lock (& tracer -> st_arr .lock );
545
+ trace_data = & tracer -> st_arr .straces [tracer -> st_arr .saved_traces_index ];
546
+ trace_data -> timestamp = timestamp ;
547
+ trace_data -> lost = lost ;
548
+ trace_data -> event_id = event_id ;
549
+ strncpy (trace_data -> msg , msg , TRACE_STR_MSG );
550
+
551
+ tracer -> st_arr .saved_traces_index =
552
+ (tracer -> st_arr .saved_traces_index + 1 ) & (SAVED_TRACES_NUM - 1 );
553
+ mutex_unlock (& tracer -> st_arr .lock );
554
+ }
555
+
525
556
static void mlx5_tracer_print_trace (struct tracer_string_format * str_frmt ,
526
557
struct mlx5_core_dev * dev ,
527
558
u64 trace_timestamp )
@@ -540,6 +571,9 @@ static void mlx5_tracer_print_trace(struct tracer_string_format *str_frmt,
540
571
trace_mlx5_fw (dev -> tracer , trace_timestamp , str_frmt -> lost ,
541
572
str_frmt -> event_id , tmp );
542
573
574
+ mlx5_fw_tracer_save_trace (dev -> tracer , trace_timestamp ,
575
+ str_frmt -> lost , str_frmt -> event_id , tmp );
576
+
543
577
/* remove it from hash */
544
578
mlx5_tracer_clean_message (str_frmt );
545
579
}
@@ -786,6 +820,109 @@ static void mlx5_fw_tracer_ownership_change(struct work_struct *work)
786
820
mlx5_fw_tracer_start (tracer );
787
821
}
788
822
823
+ static int mlx5_fw_tracer_set_core_dump_reg (struct mlx5_core_dev * dev ,
824
+ u32 * in , int size_in )
825
+ {
826
+ u32 out [MLX5_ST_SZ_DW (core_dump_reg )] = {};
827
+
828
+ if (!MLX5_CAP_DEBUG (dev , core_dump_general ) &&
829
+ !MLX5_CAP_DEBUG (dev , core_dump_qp ))
830
+ return - EOPNOTSUPP ;
831
+
832
+ return mlx5_core_access_reg (dev , in , size_in , out , sizeof (out ),
833
+ MLX5_REG_CORE_DUMP , 0 , 1 );
834
+ }
835
+
836
+ int mlx5_fw_tracer_trigger_core_dump_general (struct mlx5_core_dev * dev )
837
+ {
838
+ struct mlx5_fw_tracer * tracer = dev -> tracer ;
839
+ u32 in [MLX5_ST_SZ_DW (core_dump_reg )] = {};
840
+ int err ;
841
+
842
+ if (!MLX5_CAP_DEBUG (dev , core_dump_general ) || !tracer )
843
+ return - EOPNOTSUPP ;
844
+ if (!tracer -> owner )
845
+ return - EPERM ;
846
+
847
+ MLX5_SET (core_dump_reg , in , core_dump_type , 0x0 );
848
+
849
+ err = mlx5_fw_tracer_set_core_dump_reg (dev , in , sizeof (in ));
850
+ if (err )
851
+ return err ;
852
+ queue_work (tracer -> work_queue , & tracer -> handle_traces_work );
853
+ flush_workqueue (tracer -> work_queue );
854
+ return 0 ;
855
+ }
856
+
857
+ static int
858
+ mlx5_devlink_fmsg_fill_trace (struct devlink_fmsg * fmsg ,
859
+ struct mlx5_fw_trace_data * trace_data )
860
+ {
861
+ int err ;
862
+
863
+ err = devlink_fmsg_obj_nest_start (fmsg );
864
+ if (err )
865
+ return err ;
866
+
867
+ err = devlink_fmsg_u64_pair_put (fmsg , "timestamp" , trace_data -> timestamp );
868
+ if (err )
869
+ return err ;
870
+
871
+ err = devlink_fmsg_bool_pair_put (fmsg , "lost" , trace_data -> lost );
872
+ if (err )
873
+ return err ;
874
+
875
+ err = devlink_fmsg_u8_pair_put (fmsg , "event_id" , trace_data -> event_id );
876
+ if (err )
877
+ return err ;
878
+
879
+ err = devlink_fmsg_string_pair_put (fmsg , "msg" , trace_data -> msg );
880
+ if (err )
881
+ return err ;
882
+
883
+ err = devlink_fmsg_obj_nest_end (fmsg );
884
+ if (err )
885
+ return err ;
886
+ return 0 ;
887
+ }
888
+
889
+ int mlx5_fw_tracer_get_saved_traces_objects (struct mlx5_fw_tracer * tracer ,
890
+ struct devlink_fmsg * fmsg )
891
+ {
892
+ struct mlx5_fw_trace_data * straces = tracer -> st_arr .straces ;
893
+ u32 index , start_index , end_index ;
894
+ u32 saved_traces_index ;
895
+ int err ;
896
+
897
+ if (!straces [0 ].timestamp )
898
+ return - ENOMSG ;
899
+
900
+ mutex_lock (& tracer -> st_arr .lock );
901
+ saved_traces_index = tracer -> st_arr .saved_traces_index ;
902
+ if (straces [saved_traces_index ].timestamp )
903
+ start_index = saved_traces_index ;
904
+ else
905
+ start_index = 0 ;
906
+ end_index = (saved_traces_index - 1 ) & (SAVED_TRACES_NUM - 1 );
907
+
908
+ err = devlink_fmsg_arr_pair_nest_start (fmsg , "dump fw traces" );
909
+ if (err )
910
+ goto unlock ;
911
+ index = start_index ;
912
+ while (index != end_index ) {
913
+ err = mlx5_devlink_fmsg_fill_trace (fmsg , & straces [index ]);
914
+ if (err )
915
+ goto unlock ;
916
+
917
+ index = (index + 1 ) & (SAVED_TRACES_NUM - 1 );
918
+ }
919
+
920
+ err = devlink_fmsg_arr_pair_nest_end (fmsg );
921
+ unlock :
922
+ mutex_unlock (& tracer -> st_arr .lock );
923
+ return err ;
924
+ }
925
+
789
926
/* Create software resources (Buffers, etc ..) */
790
927
struct mlx5_fw_tracer * mlx5_fw_tracer_create (struct mlx5_core_dev * dev )
791
928
{
@@ -833,6 +970,7 @@ struct mlx5_fw_tracer *mlx5_fw_tracer_create(struct mlx5_core_dev *dev)
833
970
goto free_log_buf ;
834
971
}
835
972
973
+ mlx5_fw_tracer_init_saved_traces_array (tracer );
836
974
mlx5_core_dbg (dev , "FWTracer: Tracer created\n" );
837
975
838
976
return tracer ;
@@ -917,6 +1055,7 @@ void mlx5_fw_tracer_destroy(struct mlx5_fw_tracer *tracer)
917
1055
cancel_work_sync (& tracer -> read_fw_strings_work );
918
1056
mlx5_fw_tracer_clean_ready_list (tracer );
919
1057
mlx5_fw_tracer_clean_print_hash (tracer );
1058
+ mlx5_fw_tracer_clean_saved_traces_array (tracer );
920
1059
mlx5_fw_tracer_free_strings_db (tracer );
921
1060
mlx5_fw_tracer_destroy_log_buf (tracer );
922
1061
flush_workqueue (tracer -> work_queue );
0 commit comments