NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
apsh_common.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2022 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 #include <string.h>
26 #include <unistd.h>
27 
28 #include <doca_argp.h>
29 #include <doca_log.h>
30 #include <doca_apsh.h>
31 #include <doca_apsh_attr.h>
32 
33 #include "common.h"
34 #include "apsh_common.h"
35 
36 DOCA_LOG_REGISTER(APSH_COMMON);
37 
38 static struct doca_dev *dma_device;
39 static struct doca_dev_rep *pci_device;
40 
41 /*
42  * ARGP Callback - Handle PID parameter
43  *
44  * @param [in]: Input parameter
45  * @config [in/out]: Program configuration context
46  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
47  */
48 static doca_error_t pid_callback(void *param, void *config)
49 {
50  struct apsh_config *conf = (struct apsh_config *)config;
51 
52  conf->pid = *(DOCA_APSH_PROCESS_PID_TYPE *)param;
53  return DOCA_SUCCESS;
54 }
55 
56 /*
57  * ARGP Callback - Handle VUID parameter
58  *
59  * @param [in]: Input parameter
60  * @config [in/out]: Program configuration context
61  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
62  */
63 static doca_error_t vuid_callback(void *param, void *config)
64 {
65  struct apsh_config *conf = (struct apsh_config *)config;
66  size_t size = sizeof(conf->system_vuid);
67 
68  if (strnlen(param, size) >= size) {
69  DOCA_LOG_ERR("System VUID argument too long. Must be <=%zu long", size - 1);
71  }
72  strcpy(conf->system_vuid, param);
73  return DOCA_SUCCESS;
74 }
75 
76 /*
77  * ARGP Callback - Handle DMA device name parameter
78  *
79  * @param [in]: Input parameter
80  * @config [in/out]: Program configuration context
81  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
82  */
83 static doca_error_t dma_callback(void *param, void *config)
84 {
85  struct apsh_config *conf = (struct apsh_config *)config;
86  size_t size = sizeof(conf->dma_dev_name);
87 
88  if (strnlen(param, size) >= size) {
89  DOCA_LOG_ERR("DMA device name argument too long. Must be <=%zu long", size - 1);
91  }
92  strcpy(conf->dma_dev_name, param);
93  return DOCA_SUCCESS;
94 }
95 
96 /*
97  * ARGP Callback - Handle OS Type parameter
98  *
99  * @param [in]: Input parameter
100  * @config [in/out]: Program configuration context
101  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
102  */
103 static doca_error_t os_type_callback(void *param, void *config)
104 {
105  struct apsh_config *conf = (struct apsh_config *)config;
106  char *str_param = (char *)param;
107 
108  if (!strcasecmp(str_param, "windows"))
110  else if (!strcasecmp(str_param, "linux"))
112  else {
113  DOCA_LOG_ERR("OS type is not windows/linux (case insensitive)");
115  }
116  return DOCA_SUCCESS;
117 }
118 
119 /*
120  * ARGP Callback - Handle mem_regions.json path parameter
121  *
122  * @param [in]: Input parameter
123  * @config [in/out]: Program configuration context
124  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
125  */
126 static doca_error_t memr_callback(void *param, void *config)
127 {
128  struct apsh_config *conf = (struct apsh_config *)config;
129  size_t size = sizeof(conf->system_mem_region_path);
130 
131  if (strnlen(param, size) >= size) {
132  DOCA_LOG_ERR("System memory regions map argument too long, must be <=%zu long", size - 1);
134  }
135  strcpy(conf->system_mem_region_path, param);
136 
137  if (access(conf->system_mem_region_path, F_OK) == -1) {
138  DOCA_LOG_ERR("System memory regions map json file not found %s", conf->system_mem_region_path);
139  return DOCA_ERROR_NOT_FOUND;
140  }
141  return DOCA_SUCCESS;
142 }
143 
144 /*
145  * ARGP Callback - Handle os_symbols.json path parameter
146  *
147  * @param [in]: Input parameter
148  * @config [in/out]: Program configuration context
149  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
150  */
151 static doca_error_t os_syms_callback(void *param, void *config)
152 {
153  struct apsh_config *conf = (struct apsh_config *)config;
154  size_t size = sizeof(conf->system_os_symbol_map_path);
155 
156  if (strnlen(param, size) >= size) {
157  DOCA_LOG_ERR("System os symbols map argument too long, must be <=%zu long", size - 1);
159  }
160  strcpy(conf->system_os_symbol_map_path, param);
161 
162  if (access(conf->system_os_symbol_map_path, F_OK) == -1) {
163  DOCA_LOG_ERR("System os symbols map json file not found %s", conf->system_os_symbol_map_path);
164  return DOCA_ERROR_NOT_FOUND;
165  }
166  return DOCA_SUCCESS;
167 }
168 
169 doca_error_t register_apsh_params(bool add_os_arg, bool add_pid_arg)
170 {
172  struct doca_argp_param *pid_param, *vuid_param, *dma_param, *os_type_param, *memr_param, *os_syms_param;
173 
174  /* Create and register pid param */
175  if (!add_pid_arg)
176  goto skip_pid;
177  result = doca_argp_param_create(&pid_param);
178  if (result != DOCA_SUCCESS) {
179  DOCA_LOG_ERR("Failed to create ARGP param: %s", doca_error_get_descr(result));
180  return result;
181  }
182  doca_argp_param_set_short_name(pid_param, "p");
183  doca_argp_param_set_long_name(pid_param, "pid");
184  doca_argp_param_set_description(pid_param, "Process ID of process to be analyzed");
187  result = doca_argp_register_param(pid_param);
188  if (result != DOCA_SUCCESS) {
189  DOCA_LOG_ERR("Failed to register program param: %s", doca_error_get_descr(result));
190  return result;
191  }
192 
193 skip_pid:
194  /* Create and register VUID param */
195  result = doca_argp_param_create(&vuid_param);
196  if (result != DOCA_SUCCESS) {
197  DOCA_LOG_ERR("Failed to create ARGP param: %s", doca_error_get_descr(result));
198  return result;
199  }
200  doca_argp_param_set_short_name(vuid_param, "f");
201  doca_argp_param_set_long_name(vuid_param, "vuid");
202  doca_argp_param_set_description(vuid_param, "VUID of the System device");
205  result = doca_argp_register_param(vuid_param);
206  if (result != DOCA_SUCCESS) {
207  DOCA_LOG_ERR("Failed to register program param: %s", doca_error_get_descr(result));
208  return result;
209  }
210 
211  /* Create and register DMA param */
212  result = doca_argp_param_create(&dma_param);
213  if (result != DOCA_SUCCESS) {
214  DOCA_LOG_ERR("Failed to create ARGP param: %s", doca_error_get_descr(result));
215  return result;
216  }
217  doca_argp_param_set_short_name(dma_param, "d");
218  doca_argp_param_set_long_name(dma_param, "dma");
219  doca_argp_param_set_description(dma_param, "DMA device name");
222  result = doca_argp_register_param(dma_param);
223  if (result != DOCA_SUCCESS) {
224  DOCA_LOG_ERR("Failed to register program param: %s", doca_error_get_descr(result));
225  return result;
226  }
227 
228  /* Create and register system OS type param */
229  if (!add_os_arg)
230  return DOCA_SUCCESS;
231  result = doca_argp_param_create(&os_type_param);
232  if (result != DOCA_SUCCESS) {
233  DOCA_LOG_ERR("Failed to create ARGP param: %s", doca_error_get_descr(result));
234  return result;
235  }
236  doca_argp_param_set_short_name(os_type_param, "s");
237  doca_argp_param_set_long_name(os_type_param, "osty");
238  doca_argp_param_set_arguments(os_type_param, "<windows|linux>");
239  doca_argp_param_set_description(os_type_param, "System OS type - windows/linux");
242  result = doca_argp_register_param(os_type_param);
243  if (result != DOCA_SUCCESS) {
244  DOCA_LOG_ERR("Failed to register program param: %s", doca_error_get_descr(result));
245  return result;
246  }
247 
248  /* Create and register system memory map param */
249  result = doca_argp_param_create(&memr_param);
250  if (result != DOCA_SUCCESS) {
251  DOCA_LOG_ERR("Failed to create ARGP param: %s", doca_error_get_descr(result));
252  return result;
253  }
254  doca_argp_param_set_short_name(memr_param, "m");
255  doca_argp_param_set_long_name(memr_param, "memr");
256  doca_argp_param_set_arguments(memr_param, "<path>");
257  doca_argp_param_set_description(memr_param, "System memory regions map");
260  result = doca_argp_register_param(memr_param);
261  if (result != DOCA_SUCCESS) {
262  DOCA_LOG_ERR("Failed to register program param: %s", doca_error_get_descr(result));
263  return result;
264  }
265 
266  /* Create and register system OS map param */
267  result = doca_argp_param_create(&os_syms_param);
268  if (result != DOCA_SUCCESS) {
269  DOCA_LOG_ERR("Failed to create ARGP param: %s", doca_error_get_descr(result));
270  return result;
271  }
272  doca_argp_param_set_short_name(os_syms_param, "o");
273  doca_argp_param_set_long_name(os_syms_param, "osym");
274  doca_argp_param_set_arguments(os_syms_param, "<path>");
275  doca_argp_param_set_description(os_syms_param, "System OS symbol map path");
278  result = doca_argp_register_param(os_syms_param);
279  if (result != DOCA_SUCCESS) {
280  DOCA_LOG_ERR("Failed to register program param: %s", doca_error_get_descr(result));
281  return result;
282  }
283 
284  return DOCA_SUCCESS;
285 }
286 
287 doca_error_t init_doca_apsh(const char *dma_device_name, struct doca_apsh_ctx **ctx)
288 {
290  struct doca_apsh_ctx *apsh_ctx;
291 
292  /* Get dma device */
293  result = open_doca_device_with_ibdev_name((const uint8_t *)dma_device_name,
294  strlen(dma_device_name),
295  NULL,
296  &dma_device);
297  if (result != DOCA_SUCCESS)
298  return result;
299 
300  /* Init apsh library */
301  apsh_ctx = doca_apsh_create();
302  if (apsh_ctx == NULL) {
304  return DOCA_ERROR_NO_MEMORY;
305  }
306 
307  /* set the DMA device */
309  if (result != DOCA_SUCCESS) {
310  cleanup_doca_apsh(apsh_ctx, NULL);
311  return result;
312  }
313 
314  /* Start apsh context */
315  result = doca_apsh_start(apsh_ctx);
316  if (result != DOCA_SUCCESS) {
317  cleanup_doca_apsh(apsh_ctx, NULL);
318  return result;
319  }
320 
321  *ctx = apsh_ctx;
322  return DOCA_SUCCESS;
323 }
324 
325 doca_error_t init_doca_apsh_system(struct doca_apsh_ctx *ctx,
326  enum doca_apsh_system_os os_type,
327  const char *os_symbols,
328  const char *mem_region,
329  const char *pci_vuid,
330  struct doca_apsh_system **system)
331 {
333  struct doca_apsh_system *sys = NULL;
334 
335  /* Get pci device that connects to the system */
338  (const uint8_t *)pci_vuid,
339  strlen(pci_vuid),
340  &pci_device);
341  if (result != DOCA_SUCCESS)
342  goto err;
343 
344  /* Create a new system handler to introspect */
346  if (sys == NULL) {
349  }
350 
351  /* Set the system os type - linux/widows */
352  result = doca_apsh_sys_os_type_set(sys, os_type);
353  if (result != DOCA_SUCCESS)
354  goto err;
355 
356  /* Set the system os symbol map */
357  result = doca_apsh_sys_os_symbol_map_set(sys, os_symbols);
358  if (result != DOCA_SUCCESS)
359  goto err;
360 
361  /* Set the system memory region the apsh handler is allowed to access */
362  result = doca_apsh_sys_mem_region_set(sys, mem_region);
363  if (result != DOCA_SUCCESS)
364  goto err;
365 
366  /* Set the system device for the apsh library to use */
368  if (result != DOCA_SUCCESS)
369  goto err;
370 
371  /* Start system handler and init connection to the system and the devices */
373  if (result != DOCA_SUCCESS)
374  goto err;
375 
376  *system = sys;
377  return DOCA_SUCCESS;
378 
379 err:
380  cleanup_doca_apsh(ctx, sys);
381  return result;
382 }
383 
384 doca_error_t cleanup_doca_apsh(struct doca_apsh_ctx *ctx, struct doca_apsh_system *system)
385 {
387  if (system != NULL)
388  doca_apsh_system_destroy(system);
389  if (pci_device != NULL)
391  if (dma_device != NULL)
393 
394  return DOCA_SUCCESS;
395 }
396 
398  struct doca_apsh_system *sys,
399  int *nb_procs,
400  struct doca_apsh_process ***processes,
401  struct doca_apsh_process **process)
402 {
403  struct doca_apsh_process **pslist;
404  int num_processes, i;
406 
407  *process = NULL;
408 
409  /* Read host processes list */
410  result = doca_apsh_processes_get(sys, &pslist, &num_processes);
411  if (result != DOCA_SUCCESS)
412  return result;
413 
414  /* Search for the requested process */
415  for (i = 0; i < num_processes; ++i) {
417  *process = pslist[i];
418  break;
419  }
420  }
421  if (*process == NULL) {
423  return DOCA_ERROR_NOT_FOUND;
424  }
425 
426  /* Should not release the pslist, it will also release the memory of the requested process (with "pid") */
427  *processes = pslist;
428  *nb_procs = num_processes;
429  return DOCA_SUCCESS;
430 }
#define NULL
Definition: __stddef_null.h:26
int32_t pid
int32_t result
DOCA_LOG_REGISTER(APSH_COMMON)
static doca_error_t os_syms_callback(void *param, void *config)
Definition: apsh_common.c:151
static doca_error_t os_type_callback(void *param, void *config)
Definition: apsh_common.c:103
static struct doca_dev * dma_device
Definition: apsh_common.c:38
static doca_error_t memr_callback(void *param, void *config)
Definition: apsh_common.c:126
static doca_error_t dma_callback(void *param, void *config)
Definition: apsh_common.c:83
doca_error_t register_apsh_params(bool add_os_arg, bool add_pid_arg)
Definition: apsh_common.c:169
static doca_error_t pid_callback(void *param, void *config)
Definition: apsh_common.c:48
doca_error_t process_get(DOCA_APSH_PROCESS_PID_TYPE pid, struct doca_apsh_system *sys, int *nb_procs, struct doca_apsh_process ***processes, struct doca_apsh_process **process)
Definition: apsh_common.c:397
static struct doca_dev_rep * pci_device
Definition: apsh_common.c:39
static doca_error_t vuid_callback(void *param, void *config)
Definition: apsh_common.c:63
doca_error_t cleanup_doca_apsh(struct doca_apsh_ctx *ctx, struct doca_apsh_system *system)
Definition: apsh_common.c:384
doca_error_t init_doca_apsh_system(struct doca_apsh_ctx *ctx, enum doca_apsh_system_os os_type, const char *os_symbols, const char *mem_region, const char *pci_vuid, struct doca_apsh_system **system)
Definition: apsh_common.c:325
doca_error_t init_doca_apsh(const char *dma_device_name, struct doca_apsh_ctx **ctx)
Definition: apsh_common.c:287
doca_error_t pslist(const char *dma_device_name, const char *pci_vuid, enum doca_apsh_system_os os_type, const char *mem_region, const char *os_symbols)
doca_error_t open_doca_device_rep_with_vuid(struct doca_dev *local, enum doca_devinfo_rep_filter filter, const uint8_t *value, size_t val_size, struct doca_dev_rep **retval)
Definition: common.c:222
doca_error_t open_doca_device_with_ibdev_name(const uint8_t *value, size_t val_size, tasks_check func, struct doca_dev **retval)
Definition: common.c:84
if(bitoffset % 64+bitlength > 64) result|
uint32_t DOCA_APSH_PROCESS_PID_TYPE
process pid type
doca_apsh_system_os
system os types
@ DOCA_APSH_SYSTEM_WINDOWS
@ DOCA_APSH_SYSTEM_LINUX
@ DOCA_APSH_PROCESS_PID
DOCA_EXPERIMENTAL doca_error_t doca_apsh_sys_mem_region_set(struct doca_apsh_system *system, const char *system_mem_region_path)
Set system allowed memory regions.
DOCA_EXPERIMENTAL doca_error_t doca_apsh_sys_dev_set(struct doca_apsh_system *system, struct doca_dev_rep *dev)
Set system device.
DOCA_EXPERIMENTAL doca_error_t doca_apsh_processes_get(struct doca_apsh_system *system, struct doca_apsh_process ***processes, int *processes_size)
Get array of current processes running on the system.
DOCA_EXPERIMENTAL doca_error_t doca_apsh_start(struct doca_apsh_ctx *ctx)
Start apsh handler.
DOCA_EXPERIMENTAL doca_error_t doca_apsh_sys_os_type_set(struct doca_apsh_system *system, enum doca_apsh_system_os os_type)
Set system os type.
DOCA_EXPERIMENTAL struct doca_apsh_ctx * doca_apsh_create(void)
Create a new apsh handler.
DOCA_EXPERIMENTAL doca_error_t doca_apsh_dma_dev_set(struct doca_apsh_ctx *ctx, struct doca_dev *dma_dev)
Set apsh dma device.
DOCA_EXPERIMENTAL struct doca_apsh_system * doca_apsh_system_create(struct doca_apsh_ctx *ctx)
Create a new system handler.
DOCA_EXPERIMENTAL doca_error_t doca_apsh_sys_os_symbol_map_set(struct doca_apsh_system *system, const char *system_os_symbol_map_path)
Set system os symbol map.
DOCA_EXPERIMENTAL void doca_apsh_destroy(struct doca_apsh_ctx *ctx)
Free the APSH memory and close connections.
#define doca_apsh_process_info_get(process, attr)
Get attribute value for a process.
Definition: doca_apsh.h:618
DOCA_EXPERIMENTAL void doca_apsh_processes_free(struct doca_apsh_process **processes)
Destroys a process context.
DOCA_EXPERIMENTAL void doca_apsh_system_destroy(struct doca_apsh_system *system)
Destroy system handler.
DOCA_EXPERIMENTAL doca_error_t doca_apsh_system_start(struct doca_apsh_system *system)
Start system handler.
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 void doca_argp_param_set_arguments(struct doca_argp_param *param, const char *arguments)
Set the description of the expected arguments of the program param, used during program usage.
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_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
DOCA_STABLE doca_error_t doca_dev_rep_close(struct doca_dev_rep *dev)
Destroy allocated representor device instance.
DOCA_STABLE doca_error_t doca_dev_close(struct doca_dev *dev)
Destroy allocated local device instance.
@ DOCA_DEVINFO_REP_FILTER_NET
Definition: doca_dev.h:67
enum doca_error doca_error_t
DOCA API return codes.
DOCA_STABLE const char * doca_error_get_descr(doca_error_t error)
Returns the description string of an error code.
@ DOCA_ERROR_INVALID_VALUE
Definition: doca_error.h:44
@ DOCA_ERROR_INITIALIZATION
Definition: doca_error.h:46
@ DOCA_ERROR_NOT_FOUND
Definition: doca_error.h:54
@ DOCA_ERROR_NOT_SUPPORTED
Definition: doca_error.h:42
@ DOCA_SUCCESS
Definition: doca_error.h:38
@ DOCA_ERROR_NO_MEMORY
Definition: doca_error.h:45
#define DOCA_LOG_ERR(format,...)
Generates an ERROR application log message.
Definition: doca_log.h:466
char system_vuid[DOCA_DEVINFO_VUID_SIZE+1]
DOCA_APSH_PROCESS_PID_TYPE pid
char dma_dev_name[DOCA_DEVINFO_IBDEV_NAME_SIZE+1]
char system_mem_region_path[MAX_PATH_LEN]
char system_os_symbol_map_path[MAX_PATH_LEN]
enum doca_apsh_system_os os_type
struct upf_accel_ctx * ctx