.. | .. |
---|
30 | 30 | * SOFTWARE. |
---|
31 | 31 | */ |
---|
32 | 32 | #define CREATE_TRACE_POINTS |
---|
| 33 | +#include "lib/eq.h" |
---|
33 | 34 | #include "fw_tracer.h" |
---|
34 | 35 | #include "fw_tracer_tracepoint.h" |
---|
35 | 36 | |
---|
.. | .. |
---|
63 | 64 | MLX5_GET(mtrc_cap, out, num_string_trace); |
---|
64 | 65 | tracer->str_db.num_string_db = MLX5_GET(mtrc_cap, out, num_string_db); |
---|
65 | 66 | tracer->owner = !!MLX5_GET(mtrc_cap, out, trace_owner); |
---|
| 67 | + tracer->str_db.loaded = false; |
---|
66 | 68 | |
---|
67 | 69 | for (i = 0; i < tracer->str_db.num_string_db; i++) { |
---|
68 | 70 | mtrc_cap_sp = MLX5_ADDR_OF(mtrc_cap, out, string_db_param[i]); |
---|
.. | .. |
---|
123 | 125 | static int mlx5_fw_tracer_create_log_buf(struct mlx5_fw_tracer *tracer) |
---|
124 | 126 | { |
---|
125 | 127 | struct mlx5_core_dev *dev = tracer->dev; |
---|
126 | | - struct device *ddev = &dev->pdev->dev; |
---|
| 128 | + struct device *ddev; |
---|
127 | 129 | dma_addr_t dma; |
---|
128 | 130 | void *buff; |
---|
129 | 131 | gfp_t gfp; |
---|
.. | .. |
---|
141 | 143 | } |
---|
142 | 144 | tracer->buff.log_buf = buff; |
---|
143 | 145 | |
---|
| 146 | + ddev = mlx5_core_dma_dev(dev); |
---|
144 | 147 | dma = dma_map_single(ddev, buff, tracer->buff.size, DMA_FROM_DEVICE); |
---|
145 | 148 | if (dma_mapping_error(ddev, dma)) { |
---|
146 | 149 | mlx5_core_warn(dev, "FWTracer: Unable to map DMA: %d\n", |
---|
.. | .. |
---|
161 | 164 | static void mlx5_fw_tracer_destroy_log_buf(struct mlx5_fw_tracer *tracer) |
---|
162 | 165 | { |
---|
163 | 166 | struct mlx5_core_dev *dev = tracer->dev; |
---|
164 | | - struct device *ddev = &dev->pdev->dev; |
---|
| 167 | + struct device *ddev; |
---|
165 | 168 | |
---|
166 | 169 | if (!tracer->buff.log_buf) |
---|
167 | 170 | return; |
---|
168 | 171 | |
---|
| 172 | + ddev = mlx5_core_dma_dev(dev); |
---|
169 | 173 | dma_unmap_single(ddev, tracer->buff.dma, tracer->buff.size, DMA_FROM_DEVICE); |
---|
170 | 174 | free_pages((unsigned long)tracer->buff.log_buf, get_order(tracer->buff.size)); |
---|
171 | 175 | } |
---|
.. | .. |
---|
187 | 191 | |
---|
188 | 192 | MLX5_SET(create_mkey_in, in, translations_octword_actual_size, |
---|
189 | 193 | DIV_ROUND_UP(TRACER_BUFFER_PAGE_NUM, 2)); |
---|
190 | | - mtt = (u64 *)MLX5_ADDR_OF(create_mkey_in, in, klm_pas_mtt); |
---|
| 194 | + mtt = (__be64 *)MLX5_ADDR_OF(create_mkey_in, in, klm_pas_mtt); |
---|
191 | 195 | for (i = 0 ; i < TRACER_BUFFER_PAGE_NUM ; i++) |
---|
192 | 196 | mtt[i] = cpu_to_be64(tracer->buff.dma + i * PAGE_SIZE); |
---|
193 | 197 | |
---|
.. | .. |
---|
240 | 244 | free_strings_db: |
---|
241 | 245 | mlx5_fw_tracer_free_strings_db(tracer); |
---|
242 | 246 | return -ENOMEM; |
---|
| 247 | +} |
---|
| 248 | + |
---|
| 249 | +static void |
---|
| 250 | +mlx5_fw_tracer_init_saved_traces_array(struct mlx5_fw_tracer *tracer) |
---|
| 251 | +{ |
---|
| 252 | + tracer->st_arr.saved_traces_index = 0; |
---|
| 253 | + mutex_init(&tracer->st_arr.lock); |
---|
| 254 | +} |
---|
| 255 | + |
---|
| 256 | +static void |
---|
| 257 | +mlx5_fw_tracer_clean_saved_traces_array(struct mlx5_fw_tracer *tracer) |
---|
| 258 | +{ |
---|
| 259 | + mutex_destroy(&tracer->st_arr.lock); |
---|
243 | 260 | } |
---|
244 | 261 | |
---|
245 | 262 | static void mlx5_tracer_read_strings_db(struct work_struct *work) |
---|
.. | .. |
---|
466 | 483 | (u64)timestamp_low; |
---|
467 | 484 | break; |
---|
468 | 485 | default: |
---|
469 | | - if (tracer_event->event_id >= tracer->str_db.first_string_trace || |
---|
| 486 | + if (tracer_event->event_id >= tracer->str_db.first_string_trace && |
---|
470 | 487 | tracer_event->event_id <= tracer->str_db.first_string_trace + |
---|
471 | 488 | tracer->str_db.num_string_trace) { |
---|
472 | 489 | tracer_event->type = TRACER_EVENT_TYPE_STRING; |
---|
.. | .. |
---|
521 | 538 | list_del(&str_frmt->list); |
---|
522 | 539 | } |
---|
523 | 540 | |
---|
524 | | -static void mlx5_tracer_print_trace(struct tracer_string_format *str_frmt, |
---|
525 | | - struct mlx5_core_dev *dev, |
---|
526 | | - u64 trace_timestamp) |
---|
| 541 | +static void mlx5_fw_tracer_save_trace(struct mlx5_fw_tracer *tracer, |
---|
| 542 | + u64 timestamp, bool lost, |
---|
| 543 | + u8 event_id, char *msg) |
---|
| 544 | +{ |
---|
| 545 | + struct mlx5_fw_trace_data *trace_data; |
---|
| 546 | + |
---|
| 547 | + mutex_lock(&tracer->st_arr.lock); |
---|
| 548 | + trace_data = &tracer->st_arr.straces[tracer->st_arr.saved_traces_index]; |
---|
| 549 | + trace_data->timestamp = timestamp; |
---|
| 550 | + trace_data->lost = lost; |
---|
| 551 | + trace_data->event_id = event_id; |
---|
| 552 | + strscpy_pad(trace_data->msg, msg, TRACE_STR_MSG); |
---|
| 553 | + |
---|
| 554 | + tracer->st_arr.saved_traces_index = |
---|
| 555 | + (tracer->st_arr.saved_traces_index + 1) & (SAVED_TRACES_NUM - 1); |
---|
| 556 | + mutex_unlock(&tracer->st_arr.lock); |
---|
| 557 | +} |
---|
| 558 | + |
---|
| 559 | +static noinline |
---|
| 560 | +void mlx5_tracer_print_trace(struct tracer_string_format *str_frmt, |
---|
| 561 | + struct mlx5_core_dev *dev, |
---|
| 562 | + u64 trace_timestamp) |
---|
527 | 563 | { |
---|
528 | 564 | char tmp[512]; |
---|
529 | 565 | |
---|
.. | .. |
---|
538 | 574 | |
---|
539 | 575 | trace_mlx5_fw(dev->tracer, trace_timestamp, str_frmt->lost, |
---|
540 | 576 | str_frmt->event_id, tmp); |
---|
| 577 | + |
---|
| 578 | + mlx5_fw_tracer_save_trace(dev->tracer, trace_timestamp, |
---|
| 579 | + str_frmt->lost, str_frmt->event_id, tmp); |
---|
541 | 580 | |
---|
542 | 581 | /* remove it from hash */ |
---|
543 | 582 | mlx5_tracer_clean_message(str_frmt); |
---|
.. | .. |
---|
564 | 603 | } else { |
---|
565 | 604 | cur_string = mlx5_tracer_message_get(tracer, tracer_event); |
---|
566 | 605 | if (!cur_string) { |
---|
567 | | - pr_debug("%s Got string event for unknown string tdsm: %d\n", |
---|
| 606 | + pr_debug("%s Got string event for unknown string tmsn: %d\n", |
---|
568 | 607 | __func__, tracer_event->string_event.tmsn); |
---|
569 | 608 | return -1; |
---|
570 | 609 | } |
---|
.. | .. |
---|
600 | 639 | trace_timestamp = (timestamp_event.timestamp & MASK_52_7) | |
---|
601 | 640 | (str_frmt->timestamp & MASK_6_0); |
---|
602 | 641 | else |
---|
603 | | - trace_timestamp = ((timestamp_event.timestamp & MASK_52_7) - 1) | |
---|
| 642 | + trace_timestamp = ((timestamp_event.timestamp - 1) & MASK_52_7) | |
---|
604 | 643 | (str_frmt->timestamp & MASK_6_0); |
---|
605 | 644 | |
---|
606 | 645 | mlx5_tracer_print_trace(str_frmt, dev, trace_timestamp); |
---|
.. | .. |
---|
637 | 676 | if (!tracer->owner) |
---|
638 | 677 | return; |
---|
639 | 678 | |
---|
| 679 | + if (unlikely(!tracer->str_db.loaded)) |
---|
| 680 | + goto arm; |
---|
| 681 | + |
---|
640 | 682 | block_count = tracer->buff.size / TRACER_BLOCK_SIZE_BYTE; |
---|
641 | 683 | start_offset = tracer->buff.consumer_index * TRACER_BLOCK_SIZE_BYTE; |
---|
642 | 684 | |
---|
643 | | - /* Copy the block to local buffer to avoid HW override while being processed*/ |
---|
| 685 | + /* Copy the block to local buffer to avoid HW override while being processed */ |
---|
644 | 686 | memcpy(tmp_trace_block, tracer->buff.log_buf + start_offset, |
---|
645 | 687 | TRACER_BLOCK_SIZE_BYTE); |
---|
646 | 688 | |
---|
.. | .. |
---|
648 | 690 | get_block_timestamp(tracer, &tmp_trace_block[TRACES_PER_BLOCK - 1]); |
---|
649 | 691 | |
---|
650 | 692 | while (block_timestamp > tracer->last_timestamp) { |
---|
651 | | - /* Check block override if its not the first block */ |
---|
| 693 | + /* Check block override if it's not the first block */ |
---|
652 | 694 | if (!tracer->last_timestamp) { |
---|
653 | 695 | u64 *ts_event; |
---|
654 | 696 | /* To avoid block override be the HW in case of buffer |
---|
.. | .. |
---|
694 | 736 | &tmp_trace_block[TRACES_PER_BLOCK - 1]); |
---|
695 | 737 | } |
---|
696 | 738 | |
---|
| 739 | +arm: |
---|
697 | 740 | mlx5_fw_tracer_arm(dev); |
---|
698 | 741 | } |
---|
699 | 742 | |
---|
.. | .. |
---|
714 | 757 | if (err) |
---|
715 | 758 | mlx5_core_warn(dev, "FWTracer: Failed to set tracer configurations %d\n", err); |
---|
716 | 759 | |
---|
| 760 | + tracer->buff.consumer_index = 0; |
---|
717 | 761 | return err; |
---|
718 | 762 | } |
---|
719 | 763 | |
---|
.. | .. |
---|
778 | 822 | mlx5_core_dbg(tracer->dev, "FWTracer: ownership changed, current=(%d)\n", tracer->owner); |
---|
779 | 823 | if (tracer->owner) { |
---|
780 | 824 | tracer->owner = false; |
---|
781 | | - tracer->buff.consumer_index = 0; |
---|
782 | 825 | return; |
---|
783 | 826 | } |
---|
784 | 827 | |
---|
785 | 828 | mlx5_fw_tracer_start(tracer); |
---|
| 829 | +} |
---|
| 830 | + |
---|
| 831 | +static int mlx5_fw_tracer_set_core_dump_reg(struct mlx5_core_dev *dev, |
---|
| 832 | + u32 *in, int size_in) |
---|
| 833 | +{ |
---|
| 834 | + u32 out[MLX5_ST_SZ_DW(core_dump_reg)] = {}; |
---|
| 835 | + |
---|
| 836 | + if (!MLX5_CAP_DEBUG(dev, core_dump_general) && |
---|
| 837 | + !MLX5_CAP_DEBUG(dev, core_dump_qp)) |
---|
| 838 | + return -EOPNOTSUPP; |
---|
| 839 | + |
---|
| 840 | + return mlx5_core_access_reg(dev, in, size_in, out, sizeof(out), |
---|
| 841 | + MLX5_REG_CORE_DUMP, 0, 1); |
---|
| 842 | +} |
---|
| 843 | + |
---|
| 844 | +int mlx5_fw_tracer_trigger_core_dump_general(struct mlx5_core_dev *dev) |
---|
| 845 | +{ |
---|
| 846 | + struct mlx5_fw_tracer *tracer = dev->tracer; |
---|
| 847 | + u32 in[MLX5_ST_SZ_DW(core_dump_reg)] = {}; |
---|
| 848 | + int err; |
---|
| 849 | + |
---|
| 850 | + if (!MLX5_CAP_DEBUG(dev, core_dump_general) || !tracer) |
---|
| 851 | + return -EOPNOTSUPP; |
---|
| 852 | + if (!tracer->owner) |
---|
| 853 | + return -EPERM; |
---|
| 854 | + |
---|
| 855 | + MLX5_SET(core_dump_reg, in, core_dump_type, 0x0); |
---|
| 856 | + |
---|
| 857 | + err = mlx5_fw_tracer_set_core_dump_reg(dev, in, sizeof(in)); |
---|
| 858 | + if (err) |
---|
| 859 | + return err; |
---|
| 860 | + queue_work(tracer->work_queue, &tracer->handle_traces_work); |
---|
| 861 | + flush_workqueue(tracer->work_queue); |
---|
| 862 | + return 0; |
---|
| 863 | +} |
---|
| 864 | + |
---|
| 865 | +static int |
---|
| 866 | +mlx5_devlink_fmsg_fill_trace(struct devlink_fmsg *fmsg, |
---|
| 867 | + struct mlx5_fw_trace_data *trace_data) |
---|
| 868 | +{ |
---|
| 869 | + int err; |
---|
| 870 | + |
---|
| 871 | + err = devlink_fmsg_obj_nest_start(fmsg); |
---|
| 872 | + if (err) |
---|
| 873 | + return err; |
---|
| 874 | + |
---|
| 875 | + err = devlink_fmsg_u64_pair_put(fmsg, "timestamp", trace_data->timestamp); |
---|
| 876 | + if (err) |
---|
| 877 | + return err; |
---|
| 878 | + |
---|
| 879 | + err = devlink_fmsg_bool_pair_put(fmsg, "lost", trace_data->lost); |
---|
| 880 | + if (err) |
---|
| 881 | + return err; |
---|
| 882 | + |
---|
| 883 | + err = devlink_fmsg_u8_pair_put(fmsg, "event_id", trace_data->event_id); |
---|
| 884 | + if (err) |
---|
| 885 | + return err; |
---|
| 886 | + |
---|
| 887 | + err = devlink_fmsg_string_pair_put(fmsg, "msg", trace_data->msg); |
---|
| 888 | + if (err) |
---|
| 889 | + return err; |
---|
| 890 | + |
---|
| 891 | + err = devlink_fmsg_obj_nest_end(fmsg); |
---|
| 892 | + if (err) |
---|
| 893 | + return err; |
---|
| 894 | + return 0; |
---|
| 895 | +} |
---|
| 896 | + |
---|
| 897 | +int mlx5_fw_tracer_get_saved_traces_objects(struct mlx5_fw_tracer *tracer, |
---|
| 898 | + struct devlink_fmsg *fmsg) |
---|
| 899 | +{ |
---|
| 900 | + struct mlx5_fw_trace_data *straces = tracer->st_arr.straces; |
---|
| 901 | + u32 index, start_index, end_index; |
---|
| 902 | + u32 saved_traces_index; |
---|
| 903 | + int err; |
---|
| 904 | + |
---|
| 905 | + if (!straces[0].timestamp) |
---|
| 906 | + return -ENOMSG; |
---|
| 907 | + |
---|
| 908 | + mutex_lock(&tracer->st_arr.lock); |
---|
| 909 | + saved_traces_index = tracer->st_arr.saved_traces_index; |
---|
| 910 | + if (straces[saved_traces_index].timestamp) |
---|
| 911 | + start_index = saved_traces_index; |
---|
| 912 | + else |
---|
| 913 | + start_index = 0; |
---|
| 914 | + end_index = (saved_traces_index - 1) & (SAVED_TRACES_NUM - 1); |
---|
| 915 | + |
---|
| 916 | + err = devlink_fmsg_arr_pair_nest_start(fmsg, "dump fw traces"); |
---|
| 917 | + if (err) |
---|
| 918 | + goto unlock; |
---|
| 919 | + index = start_index; |
---|
| 920 | + while (index != end_index) { |
---|
| 921 | + err = mlx5_devlink_fmsg_fill_trace(fmsg, &straces[index]); |
---|
| 922 | + if (err) |
---|
| 923 | + goto unlock; |
---|
| 924 | + |
---|
| 925 | + index = (index + 1) & (SAVED_TRACES_NUM - 1); |
---|
| 926 | + } |
---|
| 927 | + |
---|
| 928 | + err = devlink_fmsg_arr_pair_nest_end(fmsg); |
---|
| 929 | +unlock: |
---|
| 930 | + mutex_unlock(&tracer->st_arr.lock); |
---|
| 931 | + return err; |
---|
786 | 932 | } |
---|
787 | 933 | |
---|
788 | 934 | /* Create software resources (Buffers, etc ..) */ |
---|
.. | .. |
---|
832 | 978 | goto free_log_buf; |
---|
833 | 979 | } |
---|
834 | 980 | |
---|
| 981 | + mlx5_fw_tracer_init_saved_traces_array(tracer); |
---|
835 | 982 | mlx5_core_dbg(dev, "FWTracer: Tracer created\n"); |
---|
836 | 983 | |
---|
837 | 984 | return tracer; |
---|
.. | .. |
---|
846 | 993 | return ERR_PTR(err); |
---|
847 | 994 | } |
---|
848 | 995 | |
---|
849 | | -/* Create HW resources + start tracer |
---|
850 | | - * must be called before Async EQ is created |
---|
851 | | - */ |
---|
| 996 | +static int fw_tracer_event(struct notifier_block *nb, unsigned long action, void *data); |
---|
| 997 | + |
---|
| 998 | +/* Create HW resources + start tracer */ |
---|
852 | 999 | int mlx5_fw_tracer_init(struct mlx5_fw_tracer *tracer) |
---|
853 | 1000 | { |
---|
854 | 1001 | struct mlx5_core_dev *dev; |
---|
.. | .. |
---|
865 | 1012 | err = mlx5_core_alloc_pd(dev, &tracer->buff.pdn); |
---|
866 | 1013 | if (err) { |
---|
867 | 1014 | mlx5_core_warn(dev, "FWTracer: Failed to allocate PD %d\n", err); |
---|
868 | | - return err; |
---|
| 1015 | + goto err_cancel_work; |
---|
869 | 1016 | } |
---|
870 | 1017 | |
---|
871 | 1018 | err = mlx5_fw_tracer_create_mkey(tracer); |
---|
.. | .. |
---|
874 | 1021 | goto err_dealloc_pd; |
---|
875 | 1022 | } |
---|
876 | 1023 | |
---|
877 | | - mlx5_fw_tracer_start(tracer); |
---|
| 1024 | + MLX5_NB_INIT(&tracer->nb, fw_tracer_event, DEVICE_TRACER); |
---|
| 1025 | + mlx5_eq_notifier_register(dev, &tracer->nb); |
---|
878 | 1026 | |
---|
| 1027 | + err = mlx5_fw_tracer_start(tracer); |
---|
| 1028 | + if (err) { |
---|
| 1029 | + mlx5_core_warn(dev, "FWTracer: Failed to start tracer %d\n", err); |
---|
| 1030 | + goto err_notifier_unregister; |
---|
| 1031 | + } |
---|
879 | 1032 | return 0; |
---|
880 | 1033 | |
---|
| 1034 | +err_notifier_unregister: |
---|
| 1035 | + mlx5_eq_notifier_unregister(dev, &tracer->nb); |
---|
| 1036 | + mlx5_core_destroy_mkey(dev, &tracer->buff.mkey); |
---|
881 | 1037 | err_dealloc_pd: |
---|
882 | 1038 | mlx5_core_dealloc_pd(dev, tracer->buff.pdn); |
---|
| 1039 | +err_cancel_work: |
---|
| 1040 | + cancel_work_sync(&tracer->read_fw_strings_work); |
---|
883 | 1041 | return err; |
---|
884 | 1042 | } |
---|
885 | 1043 | |
---|
886 | | -/* Stop tracer + Cleanup HW resources |
---|
887 | | - * must be called after Async EQ is destroyed |
---|
888 | | - */ |
---|
| 1044 | +/* Stop tracer + Cleanup HW resources */ |
---|
889 | 1045 | void mlx5_fw_tracer_cleanup(struct mlx5_fw_tracer *tracer) |
---|
890 | 1046 | { |
---|
891 | 1047 | if (IS_ERR_OR_NULL(tracer)) |
---|
.. | .. |
---|
893 | 1049 | |
---|
894 | 1050 | mlx5_core_dbg(tracer->dev, "FWTracer: Cleanup, is owner ? (%d)\n", |
---|
895 | 1051 | tracer->owner); |
---|
896 | | - |
---|
| 1052 | + mlx5_eq_notifier_unregister(tracer->dev, &tracer->nb); |
---|
897 | 1053 | cancel_work_sync(&tracer->ownership_change_work); |
---|
898 | 1054 | cancel_work_sync(&tracer->handle_traces_work); |
---|
899 | 1055 | |
---|
.. | .. |
---|
915 | 1071 | cancel_work_sync(&tracer->read_fw_strings_work); |
---|
916 | 1072 | mlx5_fw_tracer_clean_ready_list(tracer); |
---|
917 | 1073 | mlx5_fw_tracer_clean_print_hash(tracer); |
---|
| 1074 | + mlx5_fw_tracer_clean_saved_traces_array(tracer); |
---|
918 | 1075 | mlx5_fw_tracer_free_strings_db(tracer); |
---|
919 | 1076 | mlx5_fw_tracer_destroy_log_buf(tracer); |
---|
920 | 1077 | flush_workqueue(tracer->work_queue); |
---|
.. | .. |
---|
922 | 1079 | kvfree(tracer); |
---|
923 | 1080 | } |
---|
924 | 1081 | |
---|
925 | | -void mlx5_fw_tracer_event(struct mlx5_core_dev *dev, struct mlx5_eqe *eqe) |
---|
| 1082 | +static int mlx5_fw_tracer_recreate_strings_db(struct mlx5_fw_tracer *tracer) |
---|
926 | 1083 | { |
---|
927 | | - struct mlx5_fw_tracer *tracer = dev->tracer; |
---|
| 1084 | + struct mlx5_core_dev *dev; |
---|
| 1085 | + int err; |
---|
928 | 1086 | |
---|
929 | | - if (!tracer) |
---|
930 | | - return; |
---|
| 1087 | + cancel_work_sync(&tracer->read_fw_strings_work); |
---|
| 1088 | + mlx5_fw_tracer_clean_ready_list(tracer); |
---|
| 1089 | + mlx5_fw_tracer_clean_print_hash(tracer); |
---|
| 1090 | + mlx5_fw_tracer_clean_saved_traces_array(tracer); |
---|
| 1091 | + mlx5_fw_tracer_free_strings_db(tracer); |
---|
| 1092 | + |
---|
| 1093 | + dev = tracer->dev; |
---|
| 1094 | + err = mlx5_query_mtrc_caps(tracer); |
---|
| 1095 | + if (err) { |
---|
| 1096 | + mlx5_core_dbg(dev, "FWTracer: Failed to query capabilities %d\n", err); |
---|
| 1097 | + return err; |
---|
| 1098 | + } |
---|
| 1099 | + |
---|
| 1100 | + err = mlx5_fw_tracer_allocate_strings_db(tracer); |
---|
| 1101 | + if (err) { |
---|
| 1102 | + mlx5_core_warn(dev, "FWTracer: Allocate strings DB failed %d\n", err); |
---|
| 1103 | + return err; |
---|
| 1104 | + } |
---|
| 1105 | + mlx5_fw_tracer_init_saved_traces_array(tracer); |
---|
| 1106 | + |
---|
| 1107 | + return 0; |
---|
| 1108 | +} |
---|
| 1109 | + |
---|
| 1110 | +int mlx5_fw_tracer_reload(struct mlx5_fw_tracer *tracer) |
---|
| 1111 | +{ |
---|
| 1112 | + struct mlx5_core_dev *dev; |
---|
| 1113 | + int err; |
---|
| 1114 | + |
---|
| 1115 | + if (IS_ERR_OR_NULL(tracer)) |
---|
| 1116 | + return -EINVAL; |
---|
| 1117 | + |
---|
| 1118 | + dev = tracer->dev; |
---|
| 1119 | + mlx5_fw_tracer_cleanup(tracer); |
---|
| 1120 | + err = mlx5_fw_tracer_recreate_strings_db(tracer); |
---|
| 1121 | + if (err) { |
---|
| 1122 | + mlx5_core_warn(dev, "Failed to recreate FW tracer strings DB\n"); |
---|
| 1123 | + return err; |
---|
| 1124 | + } |
---|
| 1125 | + err = mlx5_fw_tracer_init(tracer); |
---|
| 1126 | + if (err) { |
---|
| 1127 | + mlx5_core_warn(dev, "Failed to re-initialize FW tracer\n"); |
---|
| 1128 | + return err; |
---|
| 1129 | + } |
---|
| 1130 | + |
---|
| 1131 | + return 0; |
---|
| 1132 | +} |
---|
| 1133 | + |
---|
| 1134 | +static int fw_tracer_event(struct notifier_block *nb, unsigned long action, void *data) |
---|
| 1135 | +{ |
---|
| 1136 | + struct mlx5_fw_tracer *tracer = mlx5_nb_cof(nb, struct mlx5_fw_tracer, nb); |
---|
| 1137 | + struct mlx5_core_dev *dev = tracer->dev; |
---|
| 1138 | + struct mlx5_eqe *eqe = data; |
---|
931 | 1139 | |
---|
932 | 1140 | switch (eqe->sub_type) { |
---|
933 | 1141 | case MLX5_TRACER_SUBTYPE_OWNERSHIP_CHANGE: |
---|
.. | .. |
---|
935 | 1143 | queue_work(tracer->work_queue, &tracer->ownership_change_work); |
---|
936 | 1144 | break; |
---|
937 | 1145 | case MLX5_TRACER_SUBTYPE_TRACES_AVAILABLE: |
---|
938 | | - if (likely(tracer->str_db.loaded)) |
---|
939 | | - queue_work(tracer->work_queue, &tracer->handle_traces_work); |
---|
| 1146 | + queue_work(tracer->work_queue, &tracer->handle_traces_work); |
---|
940 | 1147 | break; |
---|
941 | 1148 | default: |
---|
942 | 1149 | mlx5_core_dbg(dev, "FWTracer: Event with unrecognized subtype: sub_type %d\n", |
---|
943 | 1150 | eqe->sub_type); |
---|
944 | 1151 | } |
---|
| 1152 | + |
---|
| 1153 | + return NOTIFY_OK; |
---|
945 | 1154 | } |
---|
946 | 1155 | |
---|
947 | 1156 | EXPORT_TRACEPOINT_SYMBOL(mlx5_fw); |
---|