NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
telemetry_dpa_main.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2025 NVIDIA CORPORATION AND AFFILIATES. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, are permitted
5  * provided that the following conditions are met:
6  * * Redistributions of source code must retain the above copyright notice, this list of
7  * conditions and the following disclaimer.
8  * * Redistributions in binary form must reproduce the above copyright notice, this list of
9  * conditions and the following disclaimer in the documentation and/or other materials
10  * provided with the distribution.
11  * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
12  * to endorse or promote products derived from this software without specific prior written
13  * permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
21  * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  */
25 
26 #include <errno.h>
27 #include <stdbool.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <json-c/json.h>
32 
33 #include <doca_argp.h>
34 #include <doca_dev.h>
35 #include <doca_error.h>
36 #include <doca_log.h>
37 #include <doca_telemetry_dpa.h>
38 #include "telemetry_dpa_sample.h"
39 
40 DOCA_LOG_REGISTER(TELEMETRY_DPA::MAIN);
41 
42 #define DEFAULT_TOTAL_RUN_TIME_MILLISECS 2000
43 #define DEFAULT_MAX_PERF_EVENT_SAMPLES 0
44 
45 /*
46  * ARGP Callback - Handle PCI device address parameter
47  *
48  * @param [in]: Input parameter
49  * @config [in/out]: Program configuration context
50  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
51  */
52 static doca_error_t pci_address_callback(void *param, void *config)
53 {
55  char *pci_address = (char *)param;
56  int len;
57 
58  len = strnlen(pci_address, DOCA_DEVINFO_PCI_ADDR_SIZE);
60  DOCA_LOG_ERR("Entered device PCI address exceeding the maximum size of %d",
63  }
64  strncpy(telemetry_dpa_sample_cfg->pci_addr, pci_address, len + 1);
66  return DOCA_SUCCESS;
67 }
68 
69 /*
70  * ARGP Callback - Handle sample time parameter
71  *
72  * @param [in]: Input parameter
73  * @config [in/out]: Program configuration context
74  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
75  */
76 static doca_error_t run_time_callback(void *param, void *config)
77 {
79  uint32_t *run_time = (uint32_t *)param;
80 
82  return DOCA_SUCCESS;
83 }
84 
85 /*
86  * ARGP Callback - Handle counter type parameter
87  *
88  * @param [in]: Input parameter
89  * @config [in/out]: Program configuration context
90  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
91  */
92 static doca_error_t counter_type_callback(void *param, void *config)
93 {
96 
99  DOCA_LOG_ERR("Entered counter type=%d is invalid", *counter_type);
101  }
102 
104  return DOCA_SUCCESS;
105 }
106 
107 /*
108  * ARGP Callback - Handle event samples parameter
109  *
110  * @param [in]: Input parameter
111  * @config [in/out]: Program configuration context
112  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
113  */
114 static doca_error_t event_samples_callback(void *param, void *config)
115 {
117  uint32_t *max_event_sample = (uint32_t *)param;
118 
120  return DOCA_SUCCESS;
121 }
122 
123 /*
124  * ARGP Callback - Handle process_id parameter
125  *
126  * @param [in]: Input parameter
127  * @config [in/out]: Program configuration context
128  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
129  */
130 static doca_error_t process_id_callback(void *param, void *config)
131 {
133  uint32_t *process_id = (uint32_t *)param;
134 
137  return DOCA_SUCCESS;
138 }
139 
140 /*
141  * ARGP Callback - Handle thread_id parameter
142  *
143  * @param [in]: Input parameter
144  * @config [in/out]: Program configuration context
145  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
146  */
147 static doca_error_t thread_id_callback(void *param, void *config)
148 {
150  uint32_t *thread_id = (uint32_t *)param;
151 
154  return DOCA_SUCCESS;
155 }
156 
157 /*
158  * Register the command line parameters for the sample.
159  *
160  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
161  */
163 {
165  struct doca_argp_param *pci_param, *run_time_param, *counter_type_param, *event_samples_param,
166  *process_id_param, *thread_id_param;
167 
168  result = doca_argp_param_create(&pci_param);
169  if (result != DOCA_SUCCESS) {
170  DOCA_LOG_ERR("Failed to create ARGP param: %s", doca_error_get_name(result));
171  return result;
172  }
173  doca_argp_param_set_short_name(pci_param, "p");
174  doca_argp_param_set_long_name(pci_param, "pci-addr");
175  doca_argp_param_set_description(pci_param, "DOCA device PCI device address");
178  result = doca_argp_register_param(pci_param);
179  if (result != DOCA_SUCCESS) {
180  DOCA_LOG_ERR("Failed to register program param: %s", doca_error_get_name(result));
181  return result;
182  }
183 
184  result = doca_argp_param_create(&run_time_param);
185  if (result != DOCA_SUCCESS) {
186  DOCA_LOG_ERR("Failed to create ARGP param: %s", doca_error_get_name(result));
187  return result;
188  }
189  doca_argp_param_set_short_name(run_time_param, "rt");
190  doca_argp_param_set_long_name(run_time_param, "sample-run-time");
191  doca_argp_param_set_description(run_time_param, "Total sample run time, in miliseconds");
194  result = doca_argp_register_param(run_time_param);
195  if (result != DOCA_SUCCESS) {
196  DOCA_LOG_ERR("Failed to register program param: %s", doca_error_get_name(result));
197  return result;
198  }
199 
200  result = doca_argp_param_create(&counter_type_param);
201  if (result != DOCA_SUCCESS) {
202  DOCA_LOG_ERR("Failed to create ARGP param: %s", doca_error_get_name(result));
203  return result;
204  }
205  doca_argp_param_set_short_name(counter_type_param, "ct");
206  doca_argp_param_set_long_name(counter_type_param, "counter-type");
207  doca_argp_param_set_description(counter_type_param, "Counter type, cumulus (0) or event (1)");
209  doca_argp_param_set_type(counter_type_param, DOCA_ARGP_TYPE_INT);
210  result = doca_argp_register_param(counter_type_param);
211  if (result != DOCA_SUCCESS) {
212  DOCA_LOG_ERR("Failed to register program param: %s", doca_error_get_name(result));
213  return result;
214  }
215 
216  result = doca_argp_param_create(&event_samples_param);
217  if (result != DOCA_SUCCESS) {
218  DOCA_LOG_ERR("Failed to create ARGP param: %s", doca_error_get_name(result));
219  return result;
220  }
221  doca_argp_param_set_short_name(event_samples_param, "es");
222  doca_argp_param_set_long_name(event_samples_param, "event-samples");
223  doca_argp_param_set_description(event_samples_param,
224  "Set the maximum number of perf event samples to retrieve");
226  doca_argp_param_set_type(event_samples_param, DOCA_ARGP_TYPE_INT);
227  result = doca_argp_register_param(event_samples_param);
228  if (result != DOCA_SUCCESS) {
229  DOCA_LOG_ERR("Failed to register program param: %s", doca_error_get_name(result));
230  return result;
231  }
232 
233  result = doca_argp_param_create(&process_id_param);
234  if (result != DOCA_SUCCESS) {
235  DOCA_LOG_ERR("Failed to create ARGP param: %s", doca_error_get_name(result));
236  return result;
237  }
238  doca_argp_param_set_short_name(process_id_param, "pi");
239  doca_argp_param_set_long_name(process_id_param, "process-id");
240  doca_argp_param_set_description(process_id_param, "Specific process id to address");
242  doca_argp_param_set_type(process_id_param, DOCA_ARGP_TYPE_INT);
243  result = doca_argp_register_param(process_id_param);
244  if (result != DOCA_SUCCESS) {
245  DOCA_LOG_ERR("Failed to register program param: %s", doca_error_get_name(result));
246  return result;
247  }
248 
249  result = doca_argp_param_create(&thread_id_param);
250  if (result != DOCA_SUCCESS) {
251  DOCA_LOG_ERR("Failed to create ARGP param: %s", doca_error_get_name(result));
252  return result;
253  }
254  doca_argp_param_set_short_name(thread_id_param, "ti");
255  doca_argp_param_set_long_name(thread_id_param, "thread-id");
256  doca_argp_param_set_description(thread_id_param, "Specific thread id to address");
259  result = doca_argp_register_param(thread_id_param);
260  if (result != DOCA_SUCCESS) {
261  DOCA_LOG_ERR("Failed to register program param: %s", doca_error_get_name(result));
262  return result;
263  }
264 
265  return DOCA_SUCCESS;
266 }
267 
268 /*
269  * Set the default parameters to be used in the sample.
270  *
271  * @cfg [in]: the sample configuration
272  */
274 {
276  cfg->pci_set = false;
277  cfg->process_id_set = false;
278  cfg->thread_id_set = false;
280  cfg->max_event_sample = DEFAULT_MAX_PERF_EVENT_SAMPLES;
281 }
282 
283 /*
284  * Sample main function
285  *
286  * @argc [in]: command line arguments size
287  * @argv [in]: array of command line arguments
288  * @return: EXIT_SUCCESS on success and EXIT_FAILURE otherwise
289  */
290 int main(int argc, char **argv)
291 {
293  int exit_status = EXIT_FAILURE;
294  struct telemetry_dpa_sample_cfg sample_cfg = {};
295  struct doca_log_backend *sdk_log;
296 
297  /* Register a logger backend */
299  if (result != DOCA_SUCCESS)
300  goto sample_exit;
301 
302  /* Register a logger backend for internal SDK errors and warnings */
303  result = doca_log_backend_create_with_file_sdk(stderr, &sdk_log);
304  if (result != DOCA_SUCCESS)
305  goto sample_exit;
307  if (result != DOCA_SUCCESS)
308  goto sample_exit;
309 
310  set_default_params(&sample_cfg);
311 
312  DOCA_LOG_INFO("Starting the sample");
313 
314  result = doca_argp_init(NULL, &sample_cfg);
315  if (result != DOCA_SUCCESS) {
316  DOCA_LOG_ERR("Failed to init ARGP resources: %s", doca_error_get_name(result));
317  goto sample_exit;
318  }
319 
321  if (result != DOCA_SUCCESS) {
322  DOCA_LOG_ERR("Failed to register ARGP params: %s", doca_error_get_name(result));
323  goto argp_cleanup;
324  }
325 
326  result = doca_argp_start(argc, argv);
327  if (result != DOCA_SUCCESS) {
328  DOCA_LOG_ERR("Failed to parse sample input: %s", doca_error_get_name(result));
329  goto argp_cleanup;
330  }
331 
332  if (!sample_cfg.pci_set) {
333  DOCA_LOG_ERR("PCI address must be provided");
334  goto argp_cleanup;
335  }
336 
337  result = telemetry_dpa_sample_run(&sample_cfg);
338  if (result != DOCA_SUCCESS) {
339  DOCA_LOG_ERR("telemetry_dpa_sample_run() encountered an error: %s", doca_error_get_name(result));
340  goto argp_cleanup;
341  }
342 
343  exit_status = EXIT_SUCCESS;
344 
345 argp_cleanup:
347 sample_exit:
348  if (exit_status == EXIT_SUCCESS)
349  DOCA_LOG_INFO("Sample finished successfully");
350  else
351  DOCA_LOG_INFO("Sample finished with errors");
352  return exit_status;
353 }
#define NULL
Definition: __stddef_null.h:26
int32_t result
uint64_t len
DOCA_EXPERIMENTAL void doca_argp_param_set_description(struct doca_argp_param *param, const char *description)
Set the description of the program param, used during program usage.
DOCA_EXPERIMENTAL void doca_argp_param_set_long_name(struct doca_argp_param *param, const char *name)
Set the long name of the program param.
DOCA_EXPERIMENTAL doca_error_t doca_argp_start(int argc, char **argv)
Parse incoming arguments (cmd line/json).
DOCA_EXPERIMENTAL doca_error_t doca_argp_init(const char *program_name, void *program_config)
Initialize the parser interface.
DOCA_EXPERIMENTAL void doca_argp_param_set_callback(struct doca_argp_param *param, doca_argp_param_cb_t callback)
Set the callback function of the program param.
DOCA_EXPERIMENTAL doca_error_t doca_argp_param_create(struct doca_argp_param **param)
Create new program param.
DOCA_EXPERIMENTAL void doca_argp_param_set_type(struct doca_argp_param *param, enum doca_argp_type type)
Set the type of the param arguments.
DOCA_EXPERIMENTAL void doca_argp_param_set_short_name(struct doca_argp_param *param, const char *name)
Set the short name of the program param.
DOCA_EXPERIMENTAL doca_error_t doca_argp_destroy(void)
ARG Parser destroy.
DOCA_EXPERIMENTAL doca_error_t doca_argp_register_param(struct doca_argp_param *input_param)
Register a program flag.
@ DOCA_ARGP_TYPE_STRING
Definition: doca_argp.h:56
@ DOCA_ARGP_TYPE_INT
Definition: doca_argp.h:57
#define DOCA_DEVINFO_PCI_ADDR_SIZE
Buffer size to hold PCI BDF format: "XXXX:XX:XX.X". Including a null terminator.
Definition: doca_dev.h:313
enum doca_error doca_error_t
DOCA API return codes.
DOCA_STABLE const char * doca_error_get_name(doca_error_t error)
Returns the string representation of an error code name.
@ DOCA_ERROR_INVALID_VALUE
Definition: doca_error.h:44
@ DOCA_SUCCESS
Definition: doca_error.h:38
DOCA_EXPERIMENTAL doca_error_t doca_log_backend_create_standard(void)
Create default, non configurable backend for application messages.
#define DOCA_LOG_ERR(format,...)
Generates an ERROR application log message.
Definition: doca_log.h:466
#define DOCA_LOG_INFO(format,...)
Generates an INFO application log message.
Definition: doca_log.h:486
DOCA_EXPERIMENTAL doca_error_t doca_log_backend_create_with_file_sdk(FILE *fptr, struct doca_log_backend **backend)
Create a logging backend with a FILE* stream for SDK messages.
DOCA_EXPERIMENTAL doca_error_t doca_log_backend_set_sdk_level(struct doca_log_backend *backend, uint32_t level)
Set the log level limit for SDK logging backends.
@ DOCA_LOG_LEVEL_WARNING
Definition: doca_log.h:47
doca_telemetry_dpa_counter_type
Performance counters type.
@ DOCA_TELEMETRY_DPA_COUNTER_TYPE_EVENT_TRACER
@ DOCA_TELEMETRY_DPA_COUNTER_TYPE_CUMULATIVE_EVENT
const struct ip_frag_config * cfg
Definition: ip_frag_dp.c:0
enum doca_telemetry_dpa_counter_type counter_type
char pci_addr[DOCA_DEVINFO_PCI_ADDR_SIZE]
static doca_error_t counter_type_callback(void *param, void *config)
#define DEFAULT_TOTAL_RUN_TIME_MILLISECS
int main(int argc, char **argv)
static doca_error_t pci_address_callback(void *param, void *config)
static doca_error_t process_id_callback(void *param, void *config)
static void set_default_params(struct telemetry_dpa_sample_cfg *cfg)
static doca_error_t event_samples_callback(void *param, void *config)
#define DEFAULT_MAX_PERF_EVENT_SAMPLES
static doca_error_t run_time_callback(void *param, void *config)
static doca_error_t thread_id_callback(void *param, void *config)
static doca_error_t register_telemetry_dpa_params(void)
DOCA_LOG_REGISTER(TELEMETRY_DPA::MAIN)
doca_error_t telemetry_dpa_sample_run(const struct telemetry_dpa_sample_cfg *cfg)