libxcoder 5.9.0
Loading...
Searching...
No Matches
ni_rsrc_mon.c
Go to the documentation of this file.
1/*******************************************************************************
2 *
3 * Copyright (C) 2022 NETINT Technologies
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
18 * SOFTWARE.
19 *
20 ******************************************************************************/
21
22/*!*****************************************************************************
23 * \file ni_rsrc_mon.c
24 *
25 * \brief Application to query and print live performance/load info of
26 * registered NETINT video processing devices on system
27 ******************************************************************************/
28
29#if __linux__ || __APPLE__
30#include <unistd.h>
31#include <signal.h>
32#include <syslog.h>
33#endif
34
35#include <stdio.h>
36#include <stdlib.h>
37#include <stdarg.h>
38
39#include <errno.h>
40#include <time.h>
41#include <ctype.h>
42#include <string.h>
43#include "ni_device_api.h"
44#include "ni_rsrc_api.h"
45#include "ni_rsrc_priv.h"
46#include "ni_util.h"
47#include "ni_quadraprobe.h"
48
49#define MAX_DEVICE_NAME_SIZE (9)
50#define ABSOLUTE_TEMP_ZERO (-273)
51#define NP_LOAD (0)
52#define TP_LOAD (1)
53#define PCIE_LOAD (2)
54
55#define VIDEO_PROCESSING_SLICES 4
56#define THROTTLE_REF_WIN_US (1 << (10 + 7)) // 131072us or 0x20000 us, period between qos credit refresh
57#define VIDEO_SLICE_TIME (THROTTLE_REF_WIN_US * VIDEO_PROCESSING_SLICES)
58
59uint32_t* g_temp_load = NULL; //TP load storage
60uint32_t* g_temp_pload = NULL; //Pcie load storage
61uint32_t* g_temp_pthroughput = NULL; //Pcie throughput storage
62uint32_t* g_temp_sharemem = NULL; //TP sharedmem storage
63
66
73
74static const char *ni_rsrc_mon_card_error_str(ni_rsrc_mon_card_error_t err)
75{
76 switch (err) {
77 case NI_RSRC_MON_ERR_WARN_TEMP: return "warn_temp";
78 case NI_RSRC_MON_ERR_CRITICAL_TEMP: return "critical_temp";
79 case NI_RSRC_MON_ERR_PCIE_MISMATCH: return "pcie_mismatch";
81 default: return "none";
82 }
83}
84
85static ni_rsrc_mon_card_error_t ni_rsrc_mon_get_card_error(
86 ni_device_handle_t handle,
87 const ni_device_extra_info_t *p_extra,
88 const ni_device_info_t *p_info)
89{
90 if (p_info && p_extra && handle != NI_INVALID_DEVICE_HANDLE &&
91 p_extra->composite_temp > 0) {
92 ni_device_capability_t cap = {0};
93 if (ni_device_capability_query2(handle, &cap, false) == NI_RETCODE_SUCCESS) {
94 if ((int32_t)p_extra->composite_temp >= cap.critical_temp)
96 if ((int32_t)p_extra->composite_temp >= cap.warning_temp)
98 }
99 }
100#ifdef __linux__
101 if (p_info && p_info->pcie_gen3_on_gen4_host == 1)
103#endif
105}
106
107#ifdef _ANDROID
108
109#include <cutils/properties.h>
110#define PROP_DECODER_TYPE "nidec_service_init"
111#define LOG_TAG "ni_rsrc_mon"
112#endif
113
124
125#ifdef _WIN32
126#include "ni_getopt.h"
127#else
128#include <getopt.h>
129#endif
130
131#ifdef _WIN32
132static BOOL WINAPI console_ctrl_handler(DWORD ctrl_type)
133{
135 return TRUE;
156}
157
158#elif __linux__
159/*!******************************************************************************
160 * \brief
161 *
162 * \param
163 *
164 * \return
165 *******************************************************************************/
166void sig_handler(int sig)
167{
168 if (sig == SIGTERM || sig == SIGINT || sig == SIGHUP)
169 {
171 }
172}
173
174/*!******************************************************************************
175 * \brief
176 *
177 * \param
178 *
179 * \return
180 *******************************************************************************/
181void setup_signal_handler(void)
182{
183 if (signal(SIGTERM, sig_handler) == SIG_ERR ||
184 signal(SIGHUP, sig_handler) == SIG_ERR ||
185 signal(SIGINT, sig_handler) == SIG_ERR)
186 {
187 perror("ERROR: signal handler setup");
188 }
189}
190
191/*!******************************************************************************
192 * \brief get PCIe address
193 *
194 * \param[in] char *device_name e.g. /dev/nvme0n1
195 *
196 * \return void
197 * *******************************************************************************/
198void get_pcie_addr(char *device_name, char *pcie)
199{
200 get_dev_pcie_addr(device_name, pcie, NULL, NULL, NULL, NULL);
201}
202
203/*!******************************************************************************
204 * \brief get linux numa_node
205 *
206 * \param[in] char *device_name
207 *
208 * \return int atoi(cmd_ret)
209 *******************************************************************************/
210int get_numa_node(char *device_name)
211{
212 return ni_rsrc_get_numa_node(device_name);
213}
214
215#endif //__linux__
216
217/*!******************************************************************************
218 * \brief remove one device from stored device_handles
219 *
220 * \param ni_device_type_t device_type
221 *
222 * \param int32_t module_id
223 *
224 * \param ni_device_handle_t device_handle
225 *
226 * \return int 0 for success, -1 for failure
227 *******************************************************************************/
228int remove_device_from_saved(ni_device_type_t device_type, int32_t module_id,
229 ni_device_handle_t device_handle)
230{
231 if (!IS_XCODER_DEVICE_TYPE(device_type))
232 {
233 (void)fprintf(stderr, "Error: device_type %d is not a valid device type\n",
234 device_type);
235 return -1;
236 }
237 ni_device_type_t xcoder_device_type = GET_XCODER_DEVICE_TYPE(device_type);
238 if (device_handles[xcoder_device_type][module_id] == device_handle)
239 {
240 device_handles[xcoder_device_type][module_id] =
241 NI_INVALID_DEVICE_HANDLE;
242 return 0;
243 } else
244 {
245 (void)fprintf(stderr,
246 "Error: device_handle to remove %" PRId64
247 "not match device_handles[%d][%d]=%" PRId64 "\n",
248 (int64_t)device_handle, device_type, module_id,
249 (int64_t)device_handles[xcoder_device_type][module_id]);
250 return -1;
251 }
252}
253
254/*!******************************************************************************
255 * \brief convert number from argv input to integer if safe
256 *
257 * \param char *numArray
258 *
259 * \return int atoi(numArray)
260 *******************************************************************************/
261int argToI(char *numArray)
262{
263 int i;
264
265 if( !numArray )
266 {
267 return 0;
268 }
269
270 const size_t len = strlen(numArray);
271
272 for (i = 0; i < len; i++)
273 {
274 if (!isdigit(numArray[i]))
275 {
276 (void)fprintf(stderr, "invalid, ABORTING\n");
277 abort();
278 }
279 }
280
281 if (len != i)
282 return 0;
283 int32_t tmp_val;
284 if (ni_strtoi(numArray, &tmp_val) != NI_RETCODE_SUCCESS)
285 {
286 ni_log(NI_LOG_ERROR, "ERROR: %s invalid value: %s\n", __func__, numArray);
287 return 0;
288 }
289 return (int)tmp_val;
290}
291
292/*!******************************************************************************
293 * \brief compare two int32_t for qsort
294 *
295 * \param[in] const void *a
296 * \param[in] const void *b
297 *
298 * \return int atoi(numArray)
299 *******************************************************************************/
300int compareInt32_t(const void *a, const void *b)
301{
302 if ( *(int32_t*)a < *(int32_t*)b ) return -1;
303 if ( *(int32_t*)a > *(int32_t*)b ) return 1;
304 return 0;
305}
306
307char *get_pixel_format(ni_device_context_t *p_device_context, int index)
308{
310 "6s3") < 0)
311 {
312 return "UNSUPPORT";
313 }
314 else if ((index >= 0 && index < 4) || (index >= 10 && index < 13))
315 {
316 return "YUV";
317 }
318 else if (index >= 4 && index < 10)
319 {
320 return "RGB";
321 }
322 else if (index >= 13 && index < 15)
323 {
324 return "TILE";
325 }
326 else{
327 return "INVALID";
328 }
329}
330
331static char sid[5] = "0000";
332char *get_session_id(ni_device_context_t *p_device_context, int id)
333{
335 "6s3") < 0)
336 {
337 (void)snprintf(sid, sizeof(sid), "%04x", 0);
338 return sid;
339 }
340 else
341 {
342 (void)snprintf(sid, sizeof(sid), "%04x", id);
343 return sid;
344 }
345}
346
347unsigned int get_modules(ni_device_type_t device_type,
348 ni_device_queue_t *p_device_queue,
349 char *device_name,
350 int32_t **module_ids)
351{
352 unsigned int device_count;
353 size_t size_of_i32;
354
355 size_of_i32 = sizeof(int32_t);
356
357 device_count = p_device_queue->xcoder_cnt[device_type];
358 *module_ids = malloc(size_of_i32 * device_count);
359 if (!(*module_ids))
360 {
361 (void)fprintf(stderr, "ERROR: malloc() failed for module_ids\n");
362 return 0;
363 }
364
365 memcpy(*module_ids,
366 p_device_queue->xcoders[device_type],
367 size_of_i32 * device_count);
368
369 qsort(*module_ids,
370 device_count,
371 size_of_i32,
373
374 ni_strncpy(device_name, MAX_DEVICE_NAME_SIZE,
375 g_device_type_str[device_type],
377
378 return device_count;
379}
380
382 ni_device_context_t *p_device_context,
383 ni_session_context_t *p_session_context,
384 char *device_name, int detail, ni_instance_mgr_detail_status_v1_t *detail_data_v1)
385{
386 ni_retcode_t return_code;
387
388 if (!p_device_context)
389 {
390 return false;
391 }
392
393 // check if device has been opened already
394 ni_device_type_t xcoder_device_type = GET_XCODER_DEVICE_TYPE(device_type);
395 int module_id = p_device_context->p_device_info->module_id;
396 if (device_handles[xcoder_device_type][module_id] != NI_INVALID_DEVICE_HANDLE)
397 {
398 p_session_context->device_handle =
399 device_handles[xcoder_device_type][module_id];
400 } else
401 {
402 p_session_context->device_handle =
403 ni_device_open2(p_device_context->p_device_info->dev_name,
405 if (p_session_context->device_handle != NI_INVALID_DEVICE_HANDLE)
406 {
407 device_handles[xcoder_device_type][module_id] =
408 p_session_context->device_handle;
409 }
410 }
411
412 if (p_session_context->device_handle == NI_INVALID_DEVICE_HANDLE)
413 {
414 char errmsg[NI_ERRNO_LEN] = {0};
416 (void)fprintf(stderr,
417 "ERROR: ni_device_open2() failed for %s: %s\n",
418 p_device_context->p_device_info->dev_name,
419 errmsg);
420 ni_rsrc_free_device_context(p_device_context);
421 return false;
422 }
423
424 p_session_context->blk_io_handle =
425 p_session_context->device_handle;
426 p_session_context->hw_id =
427 p_device_context->p_device_info->hw_id;
428
429 if(detail)
430 {
431 if (ni_cmp_fw_api_ver((char*) &p_device_context->p_device_info->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6tD") < 0 &&
432 device_type >= NI_DEVICE_TYPE_SCALER)
433 {
434 (void)fprintf(stderr,
435 "ERROR: cannot print scaler and ai detailed info for %s as it has FW API "
436 "version <6tD\n", p_device_context->p_device_info->dev_name);
437 return false;
438 }
439
441 "6i") < 0)
442 {
443 (void)fprintf(stderr,
444 "ERROR: cannot print detailed info for %s as it has FW API "
445 "version < 6.i\n", p_device_context->p_device_info->dev_name);
446 return false;
447 }
448 else if (ni_cmp_fw_api_ver((char*)&p_device_context->p_device_info->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6r6") < 0)
449 {
450 return_code = ni_device_session_query_detail(p_session_context,
451 GET_XCODER_DEVICE_TYPE(device_type), (ni_instance_mgr_detail_status_t *)detail_data_v1);
452 }
453 else
454 {
455 return_code = ni_device_session_query_detail_v1(p_session_context,
456 GET_XCODER_DEVICE_TYPE(device_type), detail_data_v1);
457 }
458 }
459 else
460 {
461 return_code = ni_device_session_query(p_session_context,
462 GET_XCODER_DEVICE_TYPE(device_type));
463 }
464 if (return_code != NI_RETCODE_SUCCESS)
465 {
466 (void)fprintf(stderr,
467 "ERROR: ni_device_session_query() returned %d for %s:%s:%d\n",
468 return_code,
469 device_name,
470 p_device_context->p_device_info->dev_name,
471 p_device_context->p_device_info->hw_id);
472 remove_device_from_saved(device_type, module_id,
473 p_session_context->device_handle);
474 ni_device_close(p_session_context->device_handle);
475 ni_rsrc_free_device_context(p_device_context);
476 return false;
477 }
478
479 if (!p_session_context->load_query.total_contexts)
480 {
481 p_session_context->load_query.current_load = 0;
482 }
483
484 memcpy(p_session_context->fw_rev,
485 p_device_context->p_device_info->fw_rev,
486 8);
487
488 return true;
489}
490
492 ni_session_context_t *p_session_context,
493 void** p_log_buffer,
494 bool gen_log_file)
495{
496 ni_retcode_t return_code;
497 if (!p_device_context)
498 return false;
499
500 p_session_context->device_handle =
501 ni_device_open2(p_device_context->p_device_info->blk_name,
503 if (p_session_context->device_handle == NI_INVALID_DEVICE_HANDLE)
504 {
505 char errmsg[NI_ERRNO_LEN] = {0};
507 (void)fprintf(stderr,
508 "ERROR: ni_device_open2() failed for %s: %s\n",
509 p_device_context->p_device_info->blk_name,
510 errmsg);
511 ni_rsrc_free_device_context(p_device_context);
512 return false;
513 }
514 p_session_context->blk_io_handle =
515 p_session_context->device_handle;
516 p_session_context->hw_id =
517 p_device_context->p_device_info->module_id;
518 memcpy(p_session_context->fw_rev,
519 p_device_context->p_device_info->fw_rev,
520 sizeof(p_session_context->fw_rev));
521
522 return_code = ni_device_alloc_and_get_firmware_logs(p_session_context, p_log_buffer, gen_log_file);
523 return return_code ? false : true;
524}
525
526/*!*****************************************************************************
527 * \brief Dump firmware logs and log artifacts (if present) for one Quadra card.
528 *
529 * Downloads the five per-core log buffers (NP/EP/DP/TP/FP) via NVMe,
530 * then attempts to read log_artifacts (artifacts.tar.gz).
531 *
532 * \param[in] p_device_context Device context
533 * \param[in] p_session_context Session context used for NVMe commands
534 * \param[in] gen_log_file true - write logs and artifacts to disk
535*******************************************************************************/
536static void dump_fw_log_and_artifacts(ni_device_context_t *p_device_context,
537 ni_session_context_t *p_session_context,
538 bool gen_log_file)
539{
540 void *p_log_buffer = NULL;
541 int module_id = p_device_context->p_device_info->module_id;
542 const char *blk_name = p_device_context->p_device_info->blk_name;
543
544 if (!open_and_get_log(p_device_context, p_session_context, &p_log_buffer, gen_log_file)) {
545 printf("Error: failed to dump fw log of card:%d blk_name:%s\n", module_id, blk_name);
546 } else {
547 printf("Success: dumped fw log of card:%d blk_name:%s\n", module_id, blk_name);
548 }
549
550 /* Artifacts supported in firmware >= 6tA, older firmware does not support */
552 (char *)&p_device_context->p_device_info->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX],
553 "6tA") < 0)
554 {
555 printf("Info: artifacts not supported by card:%d fw_rev:%.8s, skipping\n",
556 module_id, (char *)p_device_context->p_device_info->fw_rev);
557 }
558 else
559 {
560 ni_retcode_t artifacts_rc =
561 ni_device_alloc_and_get_fw_log_artifacts(p_session_context, gen_log_file);
562 if (artifacts_rc == NI_RETCODE_SUCCESS)
563 {
564 printf("Info: fw log artifacts checked for card:%d blk_name:%s\n", module_id, blk_name);
565 }
566 else
567 {
568 printf("Error: fw log artifacts read failed for card:%d blk_name:%s\n", module_id, blk_name);
569 }
570 }
571}
572
573/*!*****************************************************************************
574 * \brief Dump firmware logs and artifacts for one or all Quadra cards.
575 *
576 * If devid is a valid card index, dumps only for that card;
577 * otherwise dumps every card. For each card it downloads
578 * the five per-core log buffers and the log artifacts via NVMe and
579 * writes them to the current directory.
580 *
581 * \param[in] coders Device queue
582 * \param[in] sessionCtxt Session context for NVMe commands
583 * \param[in] devid Card index to dump, or -1 to dump all cards
584*******************************************************************************/
585void dump_fw_log(ni_device_queue_t *coders, ni_session_context_t *sessionCtxt, int devid)
586{
587 uint32_t i;
588 unsigned int module_count;
589 int32_t *module_id_arr = NULL;
590 char module_name[MAX_DEVICE_NAME_SIZE];
591 ni_device_context_t *p_device_context = NULL;
593
594 module_count = get_modules(module_type, coders, module_name, &module_id_arr);
595 if (!module_count) {
596 printf("Error: module not found!\n");
597 return;
598 }
599
600 bool gen_log_file = true; // dump and write fw logs to runtime dir
601
602 if (devid >= 0 && (uint32_t)devid < module_count)
603 {
604 // dump fw logs and artifacts of specified card
605 p_device_context = ni_rsrc_get_device_context(module_type, module_id_arr[devid]);
606 if (!p_device_context)
607 return;
608 if (p_device_context->p_device_info->module_id == devid)
609 {
610 dump_fw_log_and_artifacts(p_device_context, sessionCtxt, gen_log_file);
611 ni_device_close(sessionCtxt->device_handle);
612 ni_rsrc_free_device_context(p_device_context);
613 }
614 }
615 else
616 {
617 // dump fw logs and artifacts of all quadra cards
618 for (i = 0; i < module_count; i++)
619 {
620 p_device_context = ni_rsrc_get_device_context(module_type, module_id_arr[i]);
621 dump_fw_log_and_artifacts(p_device_context, sessionCtxt, gen_log_file);
622 ni_device_close(sessionCtxt->device_handle);
623 ni_rsrc_free_device_context(p_device_context);
624 }
625 }
626
627 free(module_id_arr);
628}
629
630#if defined(__linux__)
631/*!*****************************************************************************
632 * \brief Run a NOR command on either one selected or all Quadra devices.
633 *
634 * A single device is selected using -s or -b, without a selector, the
635 * nor command will be excuted on all quadraprobe identified Quadra
636 * devices.
637 *
638 * \param[in] nor_cmd NOR command string ("w","r","e","ex").
639 * \param[in] t_domain --domain value, defaults to "0000".
640 * \param[in] t_slot -s slot value
641 * \param[in] t_blkdev -b block-device name
642 *
643 * \return 0 on success,
644 * non-zero on failure.
645 ******************************************************************************/
646static int run_bar4_operations(const char *nor_cmd,
647 const char *t_domain, const char *t_slot,
648 const char *t_blkdev)
649{
650 if (geteuid() != 0)
651 {
652 (void)fprintf(stderr,
653 "This operation requires root (sudo). "
654 "Please rerun: sudo ni_rsrc_mon [options]\n");
655 return 1;
656 }
657
658 bool is_device_selected = (t_slot != NULL || t_blkdev != NULL);
659 int rc;
660
661 if (!is_device_selected)
662 {
663 /* ---- All-device path ---- */
664 rc = ni_rsrc_nor_log_command(nor_cmd, ".");
665 if (rc == 0)
666 (void)fprintf(stderr, "NOR flash command: all devices successful.\n");
667 else if (rc == 1)
668 (void)fprintf(stderr, "NOR flash command: No Quadra devices found.\n");
669 else if (rc == 2)
670 (void)fprintf(stderr,
671 "NOR flash command: One or more devices failed.\n");
672 else
673 (void)fprintf(stderr,
674 "NOR flash command: Unexpected error %d.\n", rc);
675 }
676 else
677 {
678 /* ---- Single-device path (-s / -b) ---- */
679 uint32_t cmd;
680 if (nor_cmd_decode(nor_cmd, &cmd) != 0)
681 return 1;
682
683 QuadraDevice *dev = NULL;
684 rc = t_slot
685 ? quadra_device_find_by_bdf(t_domain ? t_domain : "0000",
686 t_slot, &dev)
687 : quadra_device_find_by_block_dev(t_blkdev, &dev);
688 if (rc != 0 || !dev)
689 {
690 (void)fprintf(stderr, "[ERROR] Target Quadra device not found.\n");
691 free(dev);
692 return 1;
693 }
694
695 rc = ni_rsrc_nor_cmd_run(dev, 1, cmd, ".");
696 free(dev); /* ni_rsrc_nor_cmd_run handles mmap cleanup internally */
697 }
698 return rc;
699}
700#endif /* __linux__ */
701
702
704 char *device_name)
705{
706 switch (*p_device_type)
707 {
709 *p_device_type = NI_DEVICE_TYPE_UPLOAD;
710 ni_strcpy(device_name, MAX_DEVICE_NAME_SIZE, "uploader");
711 return true;
713 *p_device_type = NI_DEVICE_TYPE_ENCODER;
714 default:
715 return false;
716 }
717}
718
719#define DYN_STR_BUF_CHUNK_SIZE 4096
720typedef struct dyn_str_buf
721{
722 int str_len; // Note: this does not include EOL char
723 int buf_size;
724 char *str_buf; // Pointer to string
726
727/*!*****************************************************************************
728 * \brief Accumulate string data in a dynamically sized buffer. This is
729 * useful to separate error messages from json and table output.
730 *
731 * \param[in] *dyn_str_buf pointer to structure holding dyn_str_buf info
732 * \param[in] *fmt printf format specifier
733 * \param[in] ... additional arguments
734 *
735 * \return 0 for success, -1 for error
736 ******************************************************************************/
737int strcat_dyn_buf(dyn_str_buf_t *dyn_str_buf, const char *fmt, ...)
738{
739 int avail_buf;
740 int formatted_len;
741 int add_buf_size = 0;
742 char *tmp_char_ptr = NULL;
743
744 if (!dyn_str_buf)
745 {
746 (void)fprintf(stderr, "ERROR: invalid param *dyn_str_buf\n");
747 return -1;
748 }
749
750 if (!fmt)
751 {
752 return 0;
753 }
754
755 va_list vl, tmp_vl;
756 va_start(vl, fmt);
757 va_copy(tmp_vl, vl);
758
759 // determine length of string to add
760 formatted_len = vsnprintf(NULL, 0, fmt, tmp_vl);
761 va_end(tmp_vl);
762
763 // check if str_buf needs to be expanded in increments of chunk size
764 avail_buf = dyn_str_buf->buf_size - dyn_str_buf->str_len;
765 add_buf_size = (formatted_len + 1) > avail_buf ?
766 ((formatted_len + 1 - avail_buf + DYN_STR_BUF_CHUNK_SIZE - 1) /
769 0;
770
771 // realloc() to expand str_buf if necessary
772 if (add_buf_size)
773 {
774 tmp_char_ptr = (char *)realloc(dyn_str_buf->str_buf,
775 sizeof(char) * dyn_str_buf->buf_size +
776 add_buf_size);
777 if (!tmp_char_ptr)
778 {
779 (void)fprintf(stderr, "ERROR: strcat_dyn_buf() failed realloc()\n");
780 va_end(vl);
781 return -1;
782 }
783 dyn_str_buf->str_buf = tmp_char_ptr;
784 dyn_str_buf->buf_size += add_buf_size;
785 avail_buf = dyn_str_buf->buf_size - dyn_str_buf->str_len;
786 }
787
788 // concatenate string to buffer
789 ni_vsprintf(dyn_str_buf->str_buf + dyn_str_buf->str_len, avail_buf, fmt, vl);
790 dyn_str_buf->str_len += formatted_len;
791
792 va_end(vl);
793 return 0;
794}
795
797{
798 free(dyn_str_buf->str_buf);
799 memset(dyn_str_buf, 0, sizeof(dyn_str_buf_t));
800}
801
802
803#define NI_RSRC_MON_CARD_CACHE_MAX NI_MAX_DEVICE_CNT
804
812
813static void clear_card_cache(ni_rsrc_mon_card_cache_t *cache, unsigned int n)
814{
815 unsigned int i;
816 for (i = 0; i < n; i++) {
817 clear_dyn_str_buf(&cache[i].card_obj);
818 clear_dyn_str_buf(&cache[i].qos_suffix);
819 cache[i].valid = false;
820 }
821}
822
823static const ni_rsrc_mon_card_cache_t *
824lookup_card_cache(const ni_rsrc_mon_card_cache_t *cache, unsigned int n,
825 const char *blk_name)
826{
827 unsigned int i;
828 if (!blk_name || !blk_name[0])
829 return NULL;
830 for (i = 0; i < n; i++) {
831 if (cache[i].valid &&
832 !strncmp(cache[i].blk_name, blk_name, NI_MAX_DEVICE_NAME_LEN))
833 return &cache[i];
834 }
835 return NULL;
836}
837
838static unsigned int build_card_and_qos_cache(
839 ni_device_queue_t *p_device_queue,
840 ni_session_context_t *p_session_context,
841 int detail,
844{
845 char device_name[MAX_DEVICE_NAME_SIZE] = {0};
846 unsigned int index, card_count;
847 int32_t *card_module_ids = NULL;
849 ni_device_context_t *p_device_context;
850 ni_device_extra_info_t dev_extra = {0};
851 char power_consumption[16];
852#ifdef __linux__
853 char pcie[64] = {0};
854 int numa_node;
855#endif
856
857 card_count = get_modules(card_type, p_device_queue, device_name,
858 &card_module_ids);
859 if (!card_count)
860 return 0;
861
862
863 for (index = 0; index < card_count; index++) {
865 ni_qos_header_info_log_page_t qos_header = {0};
866 ni_qos_namespace_info_log_page_t qos_ns_info = {0};
867 ni_device_vf_ns_id_t ns_vf_id = {0};
868 uint16_t namespace_id = 0;
869 uint8_t qos_mode = 0;
870
871 cache[index].valid = false;
872 memset(cache[index].blk_name, 0, sizeof(cache[index].blk_name));
873
874 p_device_context = ni_rsrc_get_device_context(card_type,
875 card_module_ids[index]);
876 if (!p_device_context)
877 continue;
878
879 if (!open_and_query(card_type, p_device_context, p_session_context,
880 device_name, detail, detail_data_v1)) {
881 ni_rsrc_free_device_context(p_device_context);
882 continue;
883 }
884
885 ni_strncpy(cache[index].blk_name, NI_MAX_DEVICE_NAME_LEN, p_device_context->p_device_info->blk_name,
887 cache[index].module_id = p_device_context->p_device_info->module_id;
888 cache[index].valid = true;
889
890 memset(&dev_extra, 0, sizeof(dev_extra));
891 if (ni_query_extra_info(p_session_context->device_handle, &dev_extra,
892 p_device_context->p_device_info->fw_rev))
893 {
894 dev_extra.composite_temp = 0;
895 dev_extra.fw_flavour = '-';
896 }
897 if (dev_extra.power_consumption + 1)
898 ni_sprintf(power_consumption, 16, "%umW", dev_extra.power_consumption);
899
900 card_err = ni_rsrc_mon_get_card_error(p_session_context->device_handle,
901 &dev_extra,
902 p_device_context->p_device_info);
903
904#ifdef __linux__
905 get_pcie_addr(p_device_context->p_device_info->dev_name, pcie);
906 numa_node = get_numa_node(p_device_context->p_device_info->dev_name);
907#endif
908
909 strcat_dyn_buf(&cache[index].card_obj,
910 "\n\t\t\"DEVICE\": \"%s\",\n"
911 "\t\t\"L_FL2V\": \"%s\",\n"
912 "\t\t\"N_FL2V\": \"%s\",\n"
913 "\t\t\"FR\": \"%.8s\",\n"
914 "\t\t\"N_FR\": \"%.8s\",\n"
915#ifdef __linux__
916 "\t\t\"NUMA_NODE\": %d,\n"
917 "\t\t\"PCIE_ADDR\": \"%s\",\n"
918#endif
919 "\t\t\"TEMP\": %d,\n"
920 "\t\t\"POWER\": \"%s\",\n"
921 "\t\t\"SN\": \"%-8.*s\",\n"
922 "\t\t\"ERROR\": \"%s\",\n"
923 "\t\t\"FLAVOR\": \"%1c\"",
924 p_device_context->p_device_info->dev_name,
925 p_device_context->p_device_info->fl_ver_last_ran,
926 p_device_context->p_device_info->fl_ver_nor_flash,
927 p_device_context->p_device_info->fw_rev,
928 p_device_context->p_device_info->fw_rev_nor_flash,
929#ifdef __linux__
930 numa_node, pcie,
931#endif
933 (dev_extra.power_consumption + 1) ? power_consumption : "N/A",
934 (int)sizeof(p_device_context->p_device_info->serial_number),
935 p_device_context->p_device_info->serial_number,
936 ni_rsrc_mon_card_error_str(card_err),
937 dev_extra.fw_flavour
938 );
939
940
941 if (ni_query_vf_ns_id(p_session_context->device_handle, &ns_vf_id,
942 p_device_context->p_device_info->fw_rev) ==
944 {
945 namespace_id = ns_vf_id.ns_id;
946 if (ni_query_qos_info(p_session_context->device_handle, &qos_header,
947 p_device_context->p_device_info->fw_rev) ==
949 {
951 &qos_ns_info,
952 p_device_context->p_device_info->fw_rev);
953 qos_mode = (uint8_t)(qos_header.ui16QosState & 0xFF);
954 {
955 float opmax = (float)(qos_ns_info.ui32OPmaxUs * 100) / VIDEO_SLICE_TIME;
956 strcat_dyn_buf(&cache[index].qos_suffix,
957 ",\n\t\t\"QOS_MODE\": %u,\n"
958 "\t\t\"QOS_NS\": %u,\n"
959 "\t\t\"QOS_ALLOW\": %.1f,\n"
960 "\t\t\"QOS_OPMAX\": %.1f",
961 (uint8_t)(qos_header.ui16QosState & 0xFF),
962 namespace_id,
963 (qos_mode == 0 ? 0 : qos_ns_info.fAllowance),
964 (qos_mode == 0 ? 0 : opmax));
965 }
966 }
967 }
968
969 ni_rsrc_free_device_context(p_device_context);
970 }
971
972 free(card_module_ids);
973 return card_count;
974}
975
977 ni_session_context_t *p_session_context, int detail, ni_instance_mgr_detail_status_v1_t *detail_data_v1)
978{
979 char device_name[MAX_DEVICE_NAME_SIZE] = {0};
980 unsigned int index, device_count;
981 int32_t *module_ids;
982 dyn_str_buf_t output_buf = {0};
983
984 ni_device_context_t *p_device_context;
985 ni_device_type_t device_type;
986 ni_load_query_t load_query;
987 ni_retcode_t return_code;
988 char _ml[16];
989
990 for (device_type = NI_DEVICE_TYPE_DECODER;
991 device_type != NI_DEVICE_TYPE_XCODER_MAX;
992 device_type++)
993 {
994 device_count = get_modules(device_type,
995 p_device_queue,
996 device_name,
997 &module_ids);
998 if (!device_count)
999 {
1000 continue;
1001 }
1002UPLOADER:
1003 strcat_dyn_buf(&output_buf, "Num %ss: %u\n", device_name, device_count);
1004
1005 switch (device_type)
1006 {
1008 strcat_dyn_buf(&output_buf,
1009 "INDEX LOAD(VPU MODEL FW ) INST MEM(TOTAL CRITICAL SHARE ) "
1010 "DEVICE L_FL2V N_FL2V FR N_FR\n");
1011 break;
1013 case NI_DEVICE_TYPE_AI:
1014 strcat_dyn_buf(&output_buf,
1015 "INDEX LOAD(VPU FW ) INST MEM(TOTAL SHARE ) "
1016 "DEVICE L_FL2V N_FL2V FR N_FR\n");
1017 break;
1019 strcat_dyn_buf(&output_buf,
1020 "INDEX LOAD(VPU MODEL FW ) INST MEM(TOTAL CRITICAL SHARE P2P) "
1021 "DEVICE L_FL2V N_FL2V FR N_FR\n");
1022 break;
1024 strcat_dyn_buf(&output_buf,
1025 "INDEX LOAD( FW ) INST MEM(TOTAL SHARE P2P) "
1026 "DEVICE L_FL2V N_FL2V FR N_FR\n");
1027 break;
1028 default:
1029 break;
1030 }
1031
1032 for (index = 0; index < device_count; index++)
1033 {
1034 p_device_context =
1035 ni_rsrc_get_device_context(device_type,
1036 module_ids[index]);
1037 if (!open_and_query(device_type,
1038 p_device_context,
1039 p_session_context,
1040 device_name, detail, detail_data_v1))
1041 {
1042 continue;
1043 }
1044
1045 /* PF prints overall statistics; VFs print their own per-NS statistics. */
1046 uint32_t disp_load = p_session_context->load_query.current_load;
1047 uint32_t disp_total_ctx = p_session_context->load_query.total_contexts;
1048 uint32_t disp_model_load = p_session_context->load_query.fw_model_load;
1049 if (p_session_context->overall_load_query.admin_queried &&
1050 device_type != NI_DEVICE_TYPE_UPLOAD)
1051 {
1052 disp_load = p_session_context->overall_load_query.overall_current_load;
1053 disp_total_ctx = p_session_context->overall_load_query.overall_instance_count;
1054 disp_model_load = p_session_context->overall_load_query.overall_fw_model_load;
1055 }
1056
1057 switch (device_type)
1058 {
1060 strcat_dyn_buf(&output_buf,
1061 "%-5d %-3u %-3s %-3u %-3u/%-3d %-3u %-3u "
1062 "%-3u %-11s %-8.8s %-8.8s %-8.8s %-8.8s\n",
1063 p_device_context->p_device_info->module_id,
1064 disp_load,
1065 (disp_model_load == 4294967295U) ? "N/A" : ((void)snprintf(_ml, sizeof(_ml), "%u", disp_model_load), _ml),
1066 p_session_context->load_query.fw_load,
1067 disp_total_ctx,
1068 p_device_context->p_device_info->max_instance_cnt,
1069 p_session_context->load_query.fw_video_mem_usage,
1070 p_session_context->load_query.fw_video_shared_mem_usage,
1071 p_session_context->load_query.fw_share_mem_usage,
1072 p_device_context->p_device_info->dev_name,
1073 p_device_context->p_device_info->fl_ver_last_ran,
1074 p_device_context->p_device_info->fl_ver_nor_flash,
1075 p_device_context->p_device_info->fw_rev,
1076 p_device_context->p_device_info->fw_rev_nor_flash);
1077 break;
1079 case NI_DEVICE_TYPE_AI:
1080 strcat_dyn_buf(&output_buf,
1081 "%-5d %-3u %-3u %-3u/%-3d %-3u "
1082 "%-3u %-11s %-8.8s %-8.8s %-8.8s %-8.8s\n",
1083 p_device_context->p_device_info->module_id,
1084 disp_load,
1085 p_session_context->load_query.fw_load,
1086 disp_total_ctx,
1087 p_device_context->p_device_info->max_instance_cnt,
1088 p_session_context->load_query.fw_video_mem_usage,
1089 p_session_context->load_query.fw_share_mem_usage,
1090 p_device_context->p_device_info->dev_name,
1091 p_device_context->p_device_info->fl_ver_last_ran,
1092 p_device_context->p_device_info->fl_ver_nor_flash,
1093 p_device_context->p_device_info->fw_rev,
1094 p_device_context->p_device_info->fw_rev_nor_flash);
1095 break;
1097 strcat_dyn_buf(&output_buf,
1098 "%-5d %-3u %-3s %-3u %-3u/%-3d %-3u %-3u "
1099 "%-3u %-3u %-11s %-8.8s %-8.8s %-8.8s %-8.8s\n",
1100 p_device_context->p_device_info->module_id,
1101 disp_load,
1102 (disp_model_load == 4294967295U) ? "N/A" : ((void)snprintf(_ml, sizeof(_ml), "%u", disp_model_load), _ml),
1103 p_session_context->load_query.fw_load,
1104 disp_total_ctx,
1105 p_device_context->p_device_info->max_instance_cnt,
1106 p_session_context->load_query.fw_video_mem_usage,
1107 p_session_context->load_query.fw_video_shared_mem_usage,
1108 p_session_context->load_query.fw_share_mem_usage,
1109 p_session_context->load_query.fw_p2p_mem_usage,
1110 p_device_context->p_device_info->dev_name,
1111 p_device_context->p_device_info->fl_ver_last_ran,
1112 p_device_context->p_device_info->fl_ver_nor_flash,
1113 p_device_context->p_device_info->fw_rev,
1114 p_device_context->p_device_info->fw_rev_nor_flash);
1115 break;
1117 strcat_dyn_buf(&output_buf,
1118 "%-5d %-3u %-3u/%-3d %-3u "
1119 "%-3u %-3u %-11s %-8.8s %-8.8s %-8.8s %-8.8s\n",
1120 p_device_context->p_device_info->module_id,
1121 p_session_context->load_query.fw_load,
1122 p_session_context->load_query.active_hwuploaders,
1123 p_device_context->p_device_info->max_instance_cnt,
1124 p_session_context->load_query.fw_video_mem_usage,
1125 p_session_context->load_query.fw_share_mem_usage,
1126 p_session_context->load_query.fw_p2p_mem_usage,
1127 p_device_context->p_device_info->dev_name,
1128 p_device_context->p_device_info->fl_ver_last_ran,
1129 p_device_context->p_device_info->fl_ver_nor_flash,
1130 p_device_context->p_device_info->fw_rev,
1131 p_device_context->p_device_info->fw_rev_nor_flash);
1132 break;
1133 default:
1134 break;
1135 }
1136
1137 ni_rsrc_free_device_context(p_device_context);
1138 }
1139
1140 if (swap_encoder_and_uploader(&device_type, device_name))
1141 {
1142 goto UPLOADER;
1143 }
1144
1145 free(module_ids);
1146 }
1147
1148 // Skip printing NVME, TP and PCIE status if ni_query_nvme_status is not supported in FW
1149 if (ni_cmp_fw_api_ver((char*) &p_session_context->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6O") < 0) {
1150 goto PRINT_OUTPUT;
1151 }
1152
1153 //Nvme[0] and TP[1] and Pcie[2] load
1154 for (int icore = NP_LOAD; icore <= PCIE_LOAD; icore++)
1155 {
1156 // ASSUMPTION: Each Quadra has at least and only one encoder.
1157 device_type = NI_DEVICE_TYPE_ENCODER;
1158 device_count = get_modules(device_type,
1159 p_device_queue,
1160 device_name,
1161 &module_ids);
1162
1163 if (icore == NP_LOAD)
1164 {
1165 strcat_dyn_buf(&output_buf, "Num Nvmes: ");
1166 g_temp_load = (uint32_t*)calloc(device_count, sizeof(uint32_t));
1167 if (!g_temp_load)
1168 {
1169 (void)fprintf(stderr, "ERROR: calloc() failed for g_temp_load\n");
1170 return;
1171 }
1172 g_temp_pload = (uint32_t*)calloc(device_count, sizeof(uint32_t));
1173 if (!g_temp_pload)
1174 {
1175 (void)fprintf(stderr, "ERROR: calloc() failed for g_temp_pload\n");
1176 return;
1177 }
1178 g_temp_pthroughput = (uint32_t*)calloc(device_count, sizeof(uint32_t));
1179 if (!g_temp_pthroughput)
1180 {
1181 (void)fprintf(stderr, "ERROR: calloc() failed for g_temp_pthroughput\n");
1182 return;
1183 }
1184 g_temp_sharemem = (uint32_t*)calloc(device_count, sizeof(uint32_t));
1185 if (!g_temp_sharemem)
1186 {
1187 (void)fprintf(stderr, "ERROR: calloc() failed for g_temp_sharemem\n");
1188 return;
1189 }
1190 }
1191 else
1192 {
1193 (icore == TP_LOAD)?strcat_dyn_buf(&output_buf, "Num TPs: "):strcat_dyn_buf(&output_buf, "Num PCIes: ");
1194 }
1195
1196 strcat_dyn_buf(&output_buf, "%u\n", device_count);
1197 if (icore == PCIE_LOAD)
1198 {
1199 strcat_dyn_buf(&output_buf,
1200 "INDEX LOAD( FW ) PCIE_Card2Host_Gbps "
1201 "DEVICE L_FL2V N_FL2V FR N_FR\n");
1202 }
1203 else
1204 {
1205 strcat_dyn_buf(&output_buf,
1206 "INDEX LOAD( FW ) MEM( SHARE ) "
1207 "DEVICE L_FL2V N_FL2V FR N_FR\n");
1208 }
1209 if (!device_count)
1210 {
1211 if (output_buf.str_buf)
1212 printf("%s", output_buf.str_buf);
1213 clear_dyn_str_buf(&output_buf);
1214 free(g_temp_load);
1215 free(g_temp_pload);
1216 free(g_temp_pthroughput);
1217 free(g_temp_sharemem);
1218 return;
1219 }
1220
1221 for (index = 0; index < device_count; index++)
1222 {
1223 p_device_context = ni_rsrc_get_device_context(device_type,
1224 module_ids[index]);
1225 if (!p_device_context)
1226 continue;
1227 if (icore == NP_LOAD)
1228 {
1229 if (!open_and_query(device_type,
1230 p_device_context,
1231 p_session_context,
1232 device_name, detail, detail_data_v1))
1233 {
1234 continue;
1235 }
1236
1237 return_code = ni_query_nvme_status(p_session_context, &load_query);
1238 if (return_code != NI_RETCODE_SUCCESS)
1239 {
1240 (void)fprintf(stderr,
1241 "ERROR: ni_query_nvme_status() returned %d for %s:%s:%d\n",
1242 return_code,
1243 device_name,
1244 p_device_context->p_device_info->dev_name,
1245 p_device_context->p_device_info->hw_id);
1246 remove_device_from_saved(device_type,
1247 p_device_context->p_device_info->module_id,
1248 p_session_context->device_handle);
1249 ni_device_close(p_session_context->device_handle);
1250 goto CLOSE;
1251 }
1252 g_temp_load[index] = load_query.tp_fw_load;
1253 g_temp_pload[index] = load_query.pcie_load;
1254 g_temp_pthroughput[index] = load_query.pcie_throughput;
1255 g_temp_sharemem[index] = load_query.fw_share_mem_usage;
1256 }
1257 if (icore==PCIE_LOAD)
1258 {
1259 load_query.fw_load = g_temp_pload[index];
1260 load_query.fw_share_mem_usage = g_temp_pthroughput[index];
1261
1262 strcat_dyn_buf(&output_buf,
1263 "%-5d %-3u %-3.1f "
1264 "%-11s %-8.8s %-8.8s %-8.8s %-8.8s\n",
1265 p_device_context->p_device_info->module_id,
1266 load_query.fw_load,
1267 (float)load_query.fw_share_mem_usage/10,
1268 p_device_context->p_device_info->dev_name,
1269 p_device_context->p_device_info->fl_ver_last_ran,
1270 p_device_context->p_device_info->fl_ver_nor_flash,
1271 p_device_context->p_device_info->fw_rev,
1272 p_device_context->p_device_info->fw_rev_nor_flash);
1273 }
1274 else
1275 {
1276 load_query.fw_load = (icore==TP_LOAD)?g_temp_load[index]:load_query.fw_load;
1277 load_query.fw_share_mem_usage = (icore==TP_LOAD)?g_temp_sharemem[index]:load_query.fw_share_mem_usage;
1278
1279 strcat_dyn_buf(&output_buf,
1280 "%-5d %-3u %-3u "
1281 "%-11s %-8.8s %-8.8s %-8.8s %-8.8s\n",
1282 p_device_context->p_device_info->module_id,
1283 load_query.fw_load,
1284 load_query.fw_share_mem_usage,
1285 p_device_context->p_device_info->dev_name,
1286 p_device_context->p_device_info->fl_ver_last_ran,
1287 p_device_context->p_device_info->fl_ver_nor_flash,
1288 p_device_context->p_device_info->fw_rev,
1289 p_device_context->p_device_info->fw_rev_nor_flash);
1290 }
1291
1292 CLOSE:
1293 ni_rsrc_free_device_context(p_device_context);
1294 }
1295 }
1296
1297 free(g_temp_load);
1298 free(g_temp_pload);
1299 free(g_temp_pthroughput);
1300 free(g_temp_sharemem);
1301 free(module_ids);
1302
1303PRINT_OUTPUT:
1304 if (output_buf.str_buf)
1305 printf("%s", output_buf.str_buf);
1306 clear_dyn_str_buf(&output_buf);
1307}
1308
1310 ni_session_context_t *p_session_context, int detail, ni_instance_mgr_detail_status_v1_t *detail_data_v1)
1311{
1312 bool copied_block_name;
1313 char block_name[NI_MAX_DEVICE_NAME_LEN] = {0};
1314 char device_name[MAX_DEVICE_NAME_SIZE] = {0};
1315 unsigned int guid;
1316 unsigned int number_of_quadras;
1317 unsigned int number_of_device_types_present;
1318 unsigned int device_type_counter;
1319 unsigned int *maximum_firmware_loads;
1320 unsigned int *maximum_firmware_loads_per_quadra;
1321 dyn_str_buf_t output_buf = {0};
1322
1323 ni_device_context_t *p_device_context;
1324 ni_device_type_t device_type;
1325 ni_device_type_t maximum_device_type;
1326 ni_load_query_t load_query;
1327 ni_retcode_t return_code;
1328
1329 // Use NI_DEVICE_TYPE_ENCODER instead of NI_DEVICE_TYPE_NVME
1330 // so that Quadras running older firmware will show up.
1331 // Assumption: Each Quadra has at least one encoder.
1332 number_of_quadras = p_device_queue->xcoder_cnt[NI_DEVICE_TYPE_ENCODER];
1333
1334 maximum_firmware_loads = calloc(number_of_quadras, sizeof(unsigned int));
1335 if (!maximum_firmware_loads)
1336 {
1337 (void)fprintf(stderr, "calloc() returned NULL\n");
1338 return;
1339 }
1340
1341 maximum_firmware_loads_per_quadra = NULL;
1342 p_device_context = NULL;
1343
1344 for (guid = 0; guid < number_of_quadras; guid++)
1345 {
1346 maximum_device_type = NI_DEVICE_TYPE_XCODER_MAX;
1347 maximum_firmware_loads_per_quadra = maximum_firmware_loads + guid;
1348 number_of_device_types_present = 0;
1349 device_type_counter = 0;
1350 copied_block_name = false;
1351
1352 for (device_type = NI_DEVICE_TYPE_DECODER;
1353 device_type < maximum_device_type;
1354 device_type++)
1355 {
1356 if (p_device_queue->xcoders[device_type][guid] != -1)
1357 {
1358 number_of_device_types_present++;
1359 }
1360 }
1361
1362 for (device_type = NI_DEVICE_TYPE_DECODER;
1363 device_type < maximum_device_type;
1364 device_type++)
1365 {
1366 memcpy(device_name,
1367 g_device_type_str[device_type],
1369
1370 if (p_device_queue->xcoders[device_type][guid] == -1)
1371 {
1372 continue;
1373 }
1374
1375 p_device_context =
1376 ni_rsrc_get_device_context(device_type,
1377 p_device_queue->xcoders[device_type][guid]);
1378 if (!open_and_query(device_type,
1379 p_device_context,
1380 p_session_context,
1381 device_name, detail, detail_data_v1))
1382 {
1383 continue;
1384 }
1385
1386 if (ni_cmp_fw_api_ver((char*) &p_session_context->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX],
1387 "6O") < 0)
1388 {
1389 if (maximum_device_type == NI_DEVICE_TYPE_XCODER_MAX)
1390 {
1391 strcat_dyn_buf(&output_buf,
1392 "%s: Simple output not supported. Try '-o full' "
1393 "instead.\n",
1394 p_device_context->p_device_info->dev_name);
1395 maximum_device_type = NI_DEVICE_TYPE_ENCODER;
1396 }
1397 ni_device_close(p_session_context->device_handle);
1398 ni_rsrc_free_device_context(p_device_context);
1399 continue;
1400 }
1401
1402 if (!copied_block_name)
1403 {
1405 p_device_context->p_device_info->dev_name,
1407 copied_block_name = true;
1408 }
1409
1410 if (*maximum_firmware_loads_per_quadra < p_session_context->load_query.fw_load)
1411 {
1412 *maximum_firmware_loads_per_quadra = p_session_context->load_query.fw_load;
1413 }
1414
1415 device_type_counter++;
1416 if (device_type_counter < number_of_device_types_present)
1417 {
1418 remove_device_from_saved(device_type,
1419 p_device_context->p_device_info->module_id,
1420 p_session_context->device_handle);
1421 ni_device_close(p_session_context->device_handle);
1422 ni_rsrc_free_device_context(p_device_context);
1423 }
1424 }
1425
1426 if (maximum_device_type == NI_DEVICE_TYPE_ENCODER)
1427 {
1428 continue;
1429 }
1430
1431 //Nvme and TP load
1432 {
1433 return_code =
1434 ni_query_nvme_status(p_session_context, &load_query);
1435 if (return_code == NI_RETCODE_SUCCESS)
1436 {
1437 if (*maximum_firmware_loads_per_quadra < load_query.fw_load)
1438 {
1439 *maximum_firmware_loads_per_quadra = load_query.fw_load;
1440 }
1441 if (*maximum_firmware_loads_per_quadra < load_query.tp_fw_load)
1442 {
1443 *maximum_firmware_loads_per_quadra = load_query.tp_fw_load;
1444 }
1445 strcat_dyn_buf(&output_buf, "%s: %u%%\n", block_name,
1446 *maximum_firmware_loads_per_quadra);
1447 }
1448 else
1449 {
1450 (void)fprintf(
1451 stderr, "ERROR: ni_query_nvme_status() returned %d for %s:%s:%d\n",
1452 return_code, device_name, p_device_context->p_device_info->dev_name,
1453 p_device_context->p_device_info->hw_id);
1454 remove_device_from_saved(device_type,
1455 p_device_context->p_device_info->module_id,
1456 p_session_context->device_handle);
1457 ni_device_close(p_session_context->device_handle);
1458 }
1459 }
1460
1461 ni_rsrc_free_device_context(p_device_context);
1462 }
1463
1464 if (output_buf.str_buf)
1465 printf("%s", output_buf.str_buf);
1466 clear_dyn_str_buf(&output_buf);
1467 free(maximum_firmware_loads);
1468}
1469
1470void print_json_detail(ni_device_queue_t *p_device_queue, ni_session_context_t *p_session_context, ni_instance_mgr_detail_status_v1_t *detail_data_v1)
1471{
1472 char device_name[MAX_DEVICE_NAME_SIZE] = {0};
1473 unsigned int i, index, device_count;
1474 int instance_count;
1475 int32_t *module_ids;
1476
1477 int detail = 1;
1478
1479 dyn_str_buf_t output_buf = {0};
1480 ni_device_context_t *p_device_context;
1481 ni_device_type_t device_type;
1482 int max_device_type = NI_DEVICE_TYPE_XCODER_MAX;
1483 int first_item_printed = 0;
1484 int first_device_type_printed = 0;
1485
1486 strcat_dyn_buf(&output_buf, "{\n");
1487
1488 for (device_type = NI_DEVICE_TYPE_DECODER;
1489 device_type != max_device_type;
1490 device_type++)
1491 {
1492 instance_count = 0;
1493 device_count = get_modules(device_type,
1494 p_device_queue,
1495 device_name,
1496 &module_ids);
1497 if (!device_count)
1498 {
1499 continue;
1500 }
1501
1502 if(first_device_type_printed)
1503 {
1504 strcat_dyn_buf(&output_buf, ",\n");
1505 }
1506 strcat_dyn_buf(&output_buf,
1507 "\t\"%s\" :"
1508 "[\n",
1509 device_name
1510 );
1511 first_item_printed = 0;
1512
1513 for (i = 0; i < device_count; i++)
1514 {
1515 p_device_context =
1516 ni_rsrc_get_device_context(device_type,
1517 module_ids[i]);
1518 if (!open_and_query(device_type,
1519 p_device_context,
1520 p_session_context,
1521 device_name, detail, detail_data_v1))
1522 {
1523 continue;
1524 }
1525
1526 for(index = 0; index < NI_MAX_CONTEXTS_PER_HW_INSTANCE; index++)
1527 {
1528 if(detail_data_v1->sInstDetailStatus[index].ui16FrameRate)
1529 {
1530 if(first_item_printed)
1531 {
1532 strcat_dyn_buf(&output_buf, ",\n");
1533 }
1534
1535 if(device_type == NI_DEVICE_TYPE_DECODER)
1536 {
1537 strcat_dyn_buf(&output_buf,
1538 "\t\t{\n"
1539 "\t\t\t\"NUMBER\": %u,\n"
1540 "\t\t\t\"INDEX\": %u,\n"
1541 "\t\t\t\"AvgCost\": %u,\n"
1542 "\t\t\t\"FrameRate\": %u,\n"
1543 "\t\t\t\"IDR\": %u,\n"
1544 "\t\t\t\"InFrame\": %u,\n"
1545 "\t\t\t\"OutFrame\": %u,\n"
1546 "\t\t\t\"Width\": %u,\n"
1547 "\t\t\t\"Height\": %u,\n"
1548 "\t\t\t\"SID\": \"%s\",\n"
1549 "\t\t\t\"DEVICE\": \"%s\"\n"
1550 "\t\t}",
1551 device_count,
1552 instance_count++,
1553 detail_data_v1->sInstDetailStatus[index].ui8AvgCost,
1554 detail_data_v1->sInstDetailStatus[index].ui16FrameRate,
1555 detail_data_v1->sInstDetailStatus[index].ui32NumIDR,
1556 detail_data_v1->sInstDetailStatus[index].ui32NumInFrame,
1557 detail_data_v1->sInstDetailStatus[index].ui32NumOutFrame,
1558 detail_data_v1->sInstDetailStatusAppend[index].ui32Width,
1559 detail_data_v1->sInstDetailStatusAppend[index].ui32Height,
1560 get_session_id(p_device_context, (int)detail_data_v1->sInstDetailStatusAppend[index].u32InstanceId),
1561 p_device_context->p_device_info->dev_name);
1562 }
1563 else if (device_type == NI_DEVICE_TYPE_ENCODER)
1564 {
1565 strcat_dyn_buf(&output_buf,
1566 "\t\t{\n"
1567 "\t\t\t\"NUMBER\": %u,\n"
1568 "\t\t\t\"INDEX\": %u,\n"
1569 "\t\t\t\"AvgCost\": %u,\n"
1570 "\t\t\t\"FrameRate\": %u,\n"
1571 "\t\t\t\"IDR\": %u,\n"
1572 "\t\t\t\"UserIDR\": %u,\n"
1573 "\t\t\t\"InFrame\": %u,\n"
1574 "\t\t\t\"OutFrame\": %u,\n"
1575 "\t\t\t\"BR\": %u,\n"
1576 "\t\t\t\"AvgBR\": %u,\n"
1577 "\t\t\t\"Width\": %u,\n"
1578 "\t\t\t\"Height\": %u,\n"
1579 "\t\t\t\"Format\": \"%s\",\n"
1580 "\t\t\t\"SID\": \"%s\",\n"
1581 "\t\t\t\"DEVICE\": \"%s\"\n"
1582 "\t\t}",
1583 device_count,
1584 instance_count++,
1585 detail_data_v1->sInstDetailStatus[index].ui8AvgCost,
1586 detail_data_v1->sInstDetailStatus[index].ui16FrameRate,
1587 detail_data_v1->sInstDetailStatus[index].ui32NumIDR,
1588 detail_data_v1->sInstDetailStatusAppend[index].ui32UserIDR,
1589 detail_data_v1->sInstDetailStatus[index].ui32NumInFrame,
1590 detail_data_v1->sInstDetailStatus[index].ui32NumOutFrame,
1591 detail_data_v1->sInstDetailStatus[index].ui32BitRate,
1592 detail_data_v1->sInstDetailStatus[index].ui32AvgBitRate,
1593 detail_data_v1->sInstDetailStatusAppend[index].ui32Width,
1594 detail_data_v1->sInstDetailStatusAppend[index].ui32Height,
1595 get_pixel_format(p_device_context, detail_data_v1->sInstDetailStatusAppend[index].u8PixelFormat),
1596 get_session_id(p_device_context, (int)detail_data_v1->sInstDetailStatusAppend[index].u32InstanceId),
1597 p_device_context->p_device_info->dev_name);
1598 }
1599 else if(device_type == NI_DEVICE_TYPE_SCALER ||
1600 device_type == NI_DEVICE_TYPE_AI)
1601 {
1602 strcat_dyn_buf(&output_buf,
1603 "\t\t{\n"
1604 "\t\t\t\"NUMBER\": %u,\n"
1605 "\t\t\t\"INDEX\": %u,\n"
1606 "\t\t\t\"VpuLoad\": %u,\n"
1607 "\t\t\t\"InFrame\": %u,\n"
1608 "\t\t\t\"OutFrame\": %u,\n"
1609 "\t\t\t\"Width\": %u,\n"
1610 "\t\t\t\"Height\": %u,\n"
1611 "\t\t\t\"SID\": \"%s\",\n"
1612 "\t\t\t\"DEVICE\": \"%s\"\n"
1613 "\t\t}",
1614 device_count,
1615 instance_count++,
1616 detail_data_v1->sInstDetailStatusAppend[index].ui16RealVpuLoad,
1617 detail_data_v1->sInstDetailStatus[index].ui32NumInFrame,
1618 detail_data_v1->sInstDetailStatus[index].ui32NumOutFrame,
1619 detail_data_v1->sInstDetailStatusAppend[index].ui32Width,
1620 detail_data_v1->sInstDetailStatusAppend[index].ui32Height,
1621 get_session_id(p_device_context, (int)detail_data_v1->sInstDetailStatusAppend[index].u32InstanceId),
1622 p_device_context->p_device_info->dev_name);
1623 }
1624 first_item_printed = 1;
1625 }
1626 }
1627 }
1628
1629 strcat_dyn_buf(&output_buf, "\n");
1630 strcat_dyn_buf(&output_buf,
1631 "\t]"
1632 );
1633 first_device_type_printed = 1;
1634 }
1635
1636 strcat_dyn_buf(&output_buf, "\n");
1637 strcat_dyn_buf(&output_buf, "}\n");
1638
1639 if(output_buf.str_buf)
1640 {
1641 printf("%s", output_buf.str_buf);
1642 }
1643
1644 clear_dyn_str_buf(&output_buf);
1645
1646}
1647
1649 ni_session_context_t *p_session_context,
1650 int detail,
1651 ni_instance_mgr_detail_status_v1_t *detail_data_v1)
1652{
1653 bool has_written_start = false;
1654 char device_name[MAX_DEVICE_NAME_SIZE] = {0};
1655 unsigned int index, device_count, card_count = 0;
1656 int32_t *module_ids = NULL;
1657 uint32_t total_contexts, vpu_load, model_load;
1658 dyn_str_buf_t output_buf = {0};
1660
1661 ni_device_context_t *p_device_context;
1662 ni_device_type_t device_type;
1663 ni_load_query_t load_query;
1664 ni_retcode_t return_code;
1665 const ni_rsrc_mon_card_cache_t *p_card = NULL;
1666
1667 int32_t *extra_temp_per_index = NULL;
1668 uint32_t *extra_power_per_index = NULL;
1669
1670 memset(card_cache, 0, sizeof(card_cache));
1671
1672 card_count = build_card_and_qos_cache(p_device_queue, p_session_context,
1673 detail, detail_data_v1,
1674 card_cache);
1675
1676
1677 for (device_type = NI_DEVICE_TYPE_DECODER;
1678 device_type != NI_DEVICE_TYPE_XCODER_MAX;
1679 device_type++)
1680 {
1681 device_count = get_modules(device_type, p_device_queue, device_name,
1682 &module_ids);
1683 if (!device_count)
1684 continue;
1685
1686UPLOADER:
1687 if (!has_written_start)
1688 {
1689 strcat_dyn_buf(&output_buf, "{\n \"%ss\": [\n", device_name);
1690 has_written_start = true;
1691 }
1692 else
1693 {
1694 strcat_dyn_buf(&output_buf, " ],\n \"%ss\": [\n", device_name);
1695 }
1696
1697 for (index = 0; index < device_count; index++)
1698 {
1699 p_device_context = ni_rsrc_get_device_context(device_type,
1700 module_ids[index]);
1701 if (!open_and_query(device_type, p_device_context, p_session_context,
1702 device_name, detail, detail_data_v1))
1703 continue;
1704
1705 if (device_type == NI_DEVICE_TYPE_UPLOAD) {
1706 total_contexts = p_session_context->load_query.active_hwuploaders;
1707 vpu_load = 0;
1708 model_load = 0;
1709 } else {
1710 total_contexts = p_session_context->load_query.total_contexts;
1711 vpu_load = p_session_context->load_query.current_load;
1712 model_load = p_session_context->load_query.fw_model_load;
1713 }
1714
1715 p_card = lookup_card_cache(card_cache, card_count,
1716 p_device_context->p_device_info->blk_name);
1717
1718 if (p_session_context->overall_load_query.admin_queried &&
1719 device_type != NI_DEVICE_TYPE_UPLOAD)
1720 {
1721 strcat_dyn_buf(&output_buf,
1722 "\t{\n"
1723 "\t\t\"NUMBER\": %u,\n"
1724 "\t\t\"INDEX\": %d,\n"
1725 "\t\t\"LOAD\": %u,\n"
1726 "\t\t\"LOAD-ALL\": %u,\n"
1727 "\t\t\"MODEL_LOAD\": %u,\n"
1728 "\t\t\"MODEL_LOAD-ALL\": %u,\n"
1729 "\t\t\"FW_LOAD\": %u,\n"
1730 "\t\t\"INST\": %u,\n"
1731 "\t\t\"INST-ALL\": %u,\n"
1732 "\t\t\"MAX_INST\": %d,\n"
1733 "\t\t\"MEM\": %u,\n"
1734 "\t\t\"CRITICAL_MEM\": %u,\n"
1735 "\t\t\"SHARE_MEM\": %u,\n"
1736 "\t\t\"P2P_MEM\": %u,\n"
1737 ,
1738 device_count, p_device_context->p_device_info->module_id,
1739 vpu_load,
1740 p_session_context->overall_load_query.overall_current_load,
1741 model_load,
1742 p_session_context->overall_load_query.overall_fw_model_load,
1743 p_session_context->load_query.fw_load, total_contexts,
1744 p_session_context->overall_load_query.overall_instance_count,
1745 p_device_context->p_device_info->max_instance_cnt,
1746 p_session_context->load_query.fw_video_mem_usage,
1747 p_session_context->load_query.fw_video_shared_mem_usage,
1748 p_session_context->load_query.fw_share_mem_usage,
1749 p_session_context->load_query.fw_p2p_mem_usage
1750 );
1751 }
1752 else
1753 {
1754 strcat_dyn_buf(&output_buf,
1755 "\t{\n"
1756 "\t\t\"NUMBER\": %u,\n"
1757 "\t\t\"INDEX\": %d,\n"
1758 "\t\t\"LOAD\": %u,\n"
1759 "\t\t\"MODEL_LOAD\": %u,\n"
1760 "\t\t\"FW_LOAD\": %u,\n"
1761 "\t\t\"INST\": %u,\n"
1762 "\t\t\"MAX_INST\": %d,\n"
1763 "\t\t\"MEM\": %u,\n"
1764 "\t\t\"CRITICAL_MEM\": %u,\n"
1765 "\t\t\"SHARE_MEM\": %u,\n"
1766 "\t\t\"P2P_MEM\": %u,\n"
1767 ,
1768 device_count, p_device_context->p_device_info->module_id,
1769 vpu_load, model_load,
1770 p_session_context->load_query.fw_load, total_contexts,
1771 p_device_context->p_device_info->max_instance_cnt,
1772 p_session_context->load_query.fw_video_mem_usage,
1773 p_session_context->load_query.fw_video_shared_mem_usage,
1774 p_session_context->load_query.fw_share_mem_usage,
1775 p_session_context->load_query.fw_p2p_mem_usage
1776 );
1777 }
1778
1779 if (p_card && p_card->card_obj.str_buf)
1780 strcat_dyn_buf(&output_buf, "%s", p_card->card_obj.str_buf + 1);
1781
1782 if ((device_type == NI_DEVICE_TYPE_ENCODER ||
1783 device_type == NI_DEVICE_TYPE_DECODER) &&
1784 p_card && p_card->qos_suffix.str_buf)
1785 strcat_dyn_buf(&output_buf, "%s", p_card->qos_suffix.str_buf);
1786
1787 strcat_dyn_buf(&output_buf, "\n\t}");
1788 strcat_dyn_buf(&output_buf, (index < device_count - 1) ? ",\n" : "\n");
1789
1790 ni_rsrc_free_device_context(p_device_context);
1791 }
1792
1793 if (swap_encoder_and_uploader(&device_type, device_name))
1794 goto UPLOADER;
1795 free(module_ids);
1796 module_ids = NULL;
1797 }
1798
1799 if (ni_cmp_fw_api_ver((char *)&p_session_context->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6O") < 0)
1800 goto PRINT_OUTPUT_FINAL;
1801
1802 strcat_dyn_buf(&output_buf, " ],\n");
1803
1804 for (int icore = NP_LOAD; icore <= PCIE_LOAD; icore++)
1805 {
1806 device_type = NI_DEVICE_TYPE_ENCODER;
1807 device_count = get_modules(device_type, p_device_queue, device_name,
1808 &module_ids);
1809 if (!device_count) {
1810 clear_card_cache(card_cache, card_count);
1811 if (output_buf.str_buf)
1812 printf("%s", output_buf.str_buf);
1813 clear_dyn_str_buf(&output_buf);
1814 return;
1815 }
1816
1817 if (icore == NP_LOAD)
1818 {
1819 extra_temp_per_index = (int32_t *)calloc(device_count, sizeof(int32_t));
1820 extra_power_per_index = (uint32_t *)calloc(device_count, sizeof(uint32_t));
1821 strcat_dyn_buf(&output_buf, " \"nvmes\": [\n");
1822 g_temp_load = (uint32_t *)calloc(device_count, sizeof(uint32_t));
1823 g_temp_pload = (uint32_t *)calloc(device_count, sizeof(uint32_t));
1824 g_temp_pthroughput = (uint32_t *)calloc(device_count, sizeof(uint32_t));
1825 g_temp_sharemem = (uint32_t *)calloc(device_count, sizeof(uint32_t));
1826 }
1827 else
1828 {
1829 strcat_dyn_buf(&output_buf,
1830 (icore == TP_LOAD) ? " \"tps\": [\n" : " \"pcies\": [\n");
1831 }
1832
1833 for (index = 0; index < device_count; index++)
1834 {
1835 p_device_context = ni_rsrc_get_device_context(device_type,
1836 module_ids[index]);
1837 if (!p_device_context)
1838 continue;
1839 if (icore == NP_LOAD)
1840 {
1841 if (!open_and_query(device_type, p_device_context, p_session_context,
1842 device_name, detail, detail_data_v1))
1843 continue;
1844 return_code = ni_query_nvme_status(p_session_context, &load_query);
1845 if (return_code != NI_RETCODE_SUCCESS)
1846 {
1847 remove_device_from_saved(device_type,
1848 p_device_context->p_device_info->module_id,
1849 p_session_context->device_handle);
1850 ni_device_close(p_session_context->device_handle);
1851 goto CLOSE_FINAL;
1852 }
1853 g_temp_load[index] = load_query.tp_fw_load;
1854 g_temp_pload[index] = load_query.pcie_load;
1855 g_temp_pthroughput[index] = load_query.pcie_throughput;
1856 g_temp_sharemem[index] = load_query.fw_share_mem_usage;
1857 }
1858
1859 p_card = lookup_card_cache(card_cache, card_count,
1860 p_device_context->p_device_info->blk_name);
1861
1862
1863 if (icore==PCIE_LOAD)
1864 {
1865 strcat_dyn_buf(&output_buf,
1866 "\t{\n"
1867 "\t\t\"NUMBER\": %u,\n"
1868 "\t\t\"INDEX\": %d,\n"
1869 "\t\t\"LOAD\": 0,\n"
1870 "\t\t\"MODEL_LOAD\": 0,\n"
1871 "\t\t\"FW_LOAD\": %u,\n"
1872 "\t\t\"INST\": 0,\n"
1873 "\t\t\"MAX_INST\": 0,\n"
1874 "\t\t\"MEM\": 0,\n"
1875 "\t\t\"CRITICAL_MEM\": 0,\n"
1876 "\t\t\"SHARE_MEM\": 0,\n"
1877 "\t\t\"PCIE_THROUGHPUT\": %.1f,\n"
1878 "\t\t\"P2P_MEM\": 0,\n"
1879 , device_count,
1880 p_device_context->p_device_info->module_id,
1881 g_temp_pload[index],
1882 (float)g_temp_pthroughput[index]/10
1883 );
1884 }
1885 else
1886 {
1887 load_query.fw_load = (icore==TP_LOAD)?g_temp_load[index]:load_query.fw_load;
1888 load_query.fw_share_mem_usage = (icore==TP_LOAD)?g_temp_sharemem[index]:load_query.fw_share_mem_usage;
1889
1890 strcat_dyn_buf(&output_buf,
1891 "\t{\n"
1892 "\t\t\"NUMBER\": %u,\n"
1893 "\t\t\"INDEX\": %d,\n"
1894 "\t\t\"LOAD\": 0,\n"
1895 "\t\t\"MODEL_LOAD\": 0,\n"
1896 "\t\t\"FW_LOAD\": %u,\n"
1897 "\t\t\"INST\": 0,\n"
1898 "\t\t\"MAX_INST\": 0,\n"
1899 "\t\t\"MEM\": 0,\n"
1900 "\t\t\"CRITICAL_MEM\": 0,\n"
1901 "\t\t\"SHARE_MEM\": %u,\n"
1902 "\t\t\"P2P_MEM\": 0,\n"
1903 , device_count,
1904 p_device_context->p_device_info->module_id,
1905 load_query.fw_load,
1906 load_query.fw_share_mem_usage
1907 );
1908 }
1909
1910 if (p_card && p_card->card_obj.str_buf)
1911 strcat_dyn_buf(&output_buf, "%s", p_card->card_obj.str_buf + 1);
1912
1913 strcat_dyn_buf(&output_buf, "\n\t}");
1914 strcat_dyn_buf(&output_buf, (index < device_count - 1) ? ",\n" : "\n");
1915 if (index == device_count - 1 && icore != PCIE_LOAD)
1916 strcat_dyn_buf(&output_buf, " ],\n");
1917
1918CLOSE_FINAL:
1919 ni_rsrc_free_device_context(p_device_context);
1920 }
1921 free(module_ids);
1922 module_ids = NULL;
1923 }
1924
1925 free(g_temp_load);
1926 free(g_temp_pload);
1927 free(g_temp_pthroughput);
1928 free(g_temp_sharemem);
1929 free(extra_temp_per_index);
1930 free(extra_power_per_index);
1932
1933PRINT_OUTPUT_FINAL:
1934 strcat_dyn_buf(&output_buf, " ]\n}\n");
1935 clear_card_cache(card_cache, card_count);
1936 if (output_buf.str_buf)
1937 printf("%s", output_buf.str_buf);
1938 clear_dyn_str_buf(&output_buf);
1939}
1940
1941void print_json1(ni_device_queue_t *p_device_queue,
1942 ni_session_context_t *p_session_context, int detail, ni_instance_mgr_detail_status_v1_t *detail_data_v1, int format)
1943{
1944 bool has_written_start = false;
1945 char device_name[MAX_DEVICE_NAME_SIZE] = {0};
1946 unsigned int index, device_count;
1947 int32_t *module_ids;
1948 uint32_t total_contexts;
1949 uint32_t vpu_load;
1950 uint32_t model_load;
1951#ifdef __linux__
1952 char pcie[64] = {0};
1953 int numa_node;
1954#endif
1955 dyn_str_buf_t output_buf = {0};
1956 ni_device_extra_info_t p_dev_extra_info = {0};
1957 char power_consumption[16];
1958
1959 uint16_t namespace_id = 0;
1960 uint8_t qos_mode;
1961
1962 ni_device_context_t *p_device_context;
1963 ni_device_type_t device_type;
1964 ni_load_query_t load_query;
1965 ni_retcode_t return_code;
1966
1967 int32_t *extra_temp_per_index = NULL;
1968 uint32_t *extra_power_per_index = NULL;
1969
1970 for (device_type = NI_DEVICE_TYPE_DECODER;
1971 device_type != NI_DEVICE_TYPE_XCODER_MAX;
1972 device_type++)
1973 {
1974 device_count = get_modules(device_type,
1975 p_device_queue,
1976 device_name,
1977 &module_ids);
1978 if (!device_count)
1979 {
1980 continue;
1981 }
1982
1983UPLOADER:
1984 if (!has_written_start)
1985 {
1986 strcat_dyn_buf(&output_buf, "{\n \"%ss\": [\n", device_name);
1987 has_written_start = true;
1988 }
1989 else
1990 {
1991 strcat_dyn_buf(&output_buf, " ],\n \"%ss\": [\n", device_name);
1992 }
1993
1994 for (index = 0; index < device_count; index++)
1995 {
1996 p_device_context =
1997 ni_rsrc_get_device_context(device_type,
1998 module_ids[index]);
1999 if (!open_and_query(device_type,
2000 p_device_context,
2001 p_session_context,
2002 device_name, detail, detail_data_v1))
2003 {
2004 continue;
2005 }
2006
2007 if (device_type == NI_DEVICE_TYPE_UPLOAD)
2008 {
2009 total_contexts = p_session_context->load_query.active_hwuploaders;
2010 vpu_load = 0;
2011 model_load = 0;
2012 }
2013 else
2014 {
2015 total_contexts = p_session_context->load_query.total_contexts;
2016 vpu_load = p_session_context->load_query.current_load;
2017 model_load = p_session_context->load_query.fw_model_load;
2018 }
2019#ifdef __linux__
2020 get_pcie_addr(p_device_context->p_device_info->dev_name, pcie);
2021 numa_node = get_numa_node(p_device_context->p_device_info->dev_name);
2022#endif
2023 if (format == 2)
2024 {
2025 if (ni_query_extra_info(p_session_context->device_handle,
2026 &p_dev_extra_info,
2027 p_device_context->p_device_info->fw_rev))
2028 {
2029 p_dev_extra_info.composite_temp = 0;
2030 }
2031 if (p_dev_extra_info.power_consumption + 1)
2032 {
2033 ni_sprintf(power_consumption, 16, "%umW", p_dev_extra_info.power_consumption);
2034 }
2035 }
2036 if (p_session_context->overall_load_query.admin_queried &&
2037 device_type != NI_DEVICE_TYPE_UPLOAD)
2038 {
2039 strcat_dyn_buf(&output_buf,
2040 "\t{\n"
2041 "\t\t\"NUMBER\": %u,\n"
2042 "\t\t\"INDEX\": %d,\n"
2043 "\t\t\"LOAD\": %u,\n"
2044 "\t\t\"LOAD-ALL\": %u,\n"
2045 "\t\t\"MODEL_LOAD\": %u,\n"
2046 "\t\t\"MODEL_LOAD-ALL\": %u,\n"
2047 "\t\t\"FW_LOAD\": %u,\n"
2048 "\t\t\"INST\": %u,\n"
2049 "\t\t\"INST-ALL\": %u,\n"
2050 "\t\t\"MAX_INST\": %d,\n"
2051 "\t\t\"MEM\": %u,\n"
2052 "\t\t\"CRITICAL_MEM\": %u,\n"
2053 "\t\t\"SHARE_MEM\": %u,\n"
2054 "\t\t\"P2P_MEM\": %u,\n"
2055 "\t\t\"DEVICE\": \"%s\",\n"
2056 "\t\t\"L_FL2V\": \"%s\",\n"
2057 "\t\t\"N_FL2V\": \"%s\",\n"
2058 "\t\t\"FR\": \"%.8s\",\n"
2059 "\t\t\"N_FR\": \"%.8s\""
2060#ifdef __linux__
2061 ",\n\t\t\"NUMA_NODE\": %d,\n"
2062 "\t\t\"PCIE_ADDR\": \"%s\""
2063#endif
2064 , device_count, p_device_context->p_device_info->module_id,
2065 vpu_load,
2066 p_session_context->overall_load_query.overall_current_load,
2067 model_load,
2068 p_session_context->overall_load_query.overall_fw_model_load,
2069 p_session_context->load_query.fw_load, total_contexts,
2070 p_session_context->overall_load_query.overall_instance_count,
2071 p_device_context->p_device_info->max_instance_cnt,
2072 p_session_context->load_query.fw_video_mem_usage,
2073 p_session_context->load_query.fw_video_shared_mem_usage,
2074 p_session_context->load_query.fw_share_mem_usage,
2075 p_session_context->load_query.fw_p2p_mem_usage,
2076 p_device_context->p_device_info->dev_name,
2077 p_device_context->p_device_info->fl_ver_last_ran,
2078 p_device_context->p_device_info->fl_ver_nor_flash,
2079 p_device_context->p_device_info->fw_rev,
2080 p_device_context->p_device_info->fw_rev_nor_flash
2081#ifdef __linux__
2082 , numa_node, pcie
2083#endif
2084 );
2085 } else
2086 {
2087 strcat_dyn_buf(&output_buf,
2088 "\t{\n"
2089 "\t\t\"NUMBER\": %u,\n"
2090 "\t\t\"INDEX\": %d,\n"
2091 "\t\t\"LOAD\": %u,\n"
2092 "\t\t\"MODEL_LOAD\": %u,\n"
2093 "\t\t\"FW_LOAD\": %u,\n"
2094 "\t\t\"INST\": %u,\n"
2095 "\t\t\"MAX_INST\": %d,\n"
2096 "\t\t\"MEM\": %u,\n"
2097 "\t\t\"CRITICAL_MEM\": %u,\n"
2098 "\t\t\"SHARE_MEM\": %u,\n"
2099 "\t\t\"P2P_MEM\": %u,\n"
2100 "\t\t\"DEVICE\": \"%s\",\n"
2101 "\t\t\"L_FL2V\": \"%s\",\n"
2102 "\t\t\"N_FL2V\": \"%s\",\n"
2103 "\t\t\"FR\": \"%.8s\",\n"
2104 "\t\t\"N_FR\": \"%.8s\""
2105#ifdef __linux__
2106 ",\n\t\t\"NUMA_NODE\": %d,\n"
2107 "\t\t\"PCIE_ADDR\": \"%s\""
2108#endif
2109 ,device_count, p_device_context->p_device_info->module_id,
2110 vpu_load,
2111 model_load,
2112 p_session_context->load_query.fw_load, total_contexts,
2113 p_device_context->p_device_info->max_instance_cnt,
2114 p_session_context->load_query.fw_video_mem_usage,
2115 p_session_context->load_query.fw_video_shared_mem_usage,
2116 p_session_context->load_query.fw_share_mem_usage,
2117 p_session_context->load_query.fw_p2p_mem_usage,
2118 p_device_context->p_device_info->dev_name,
2119 p_device_context->p_device_info->fl_ver_last_ran,
2120 p_device_context->p_device_info->fl_ver_nor_flash,
2121 p_device_context->p_device_info->fw_rev,
2122 p_device_context->p_device_info->fw_rev_nor_flash
2123#ifdef __linux__
2124 ,
2125 numa_node, pcie
2126#endif
2127 );
2128 }
2129 if (format == 2)
2130 {
2131 strcat_dyn_buf(&output_buf,
2132 ",\n\t\t\"TEMP\": %d,\n"
2133 "\t\t\"POWER\": \"%s\"",
2134 p_dev_extra_info.composite_temp + ABSOLUTE_TEMP_ZERO,
2135 (p_dev_extra_info.power_consumption + 1) ? power_consumption : "N/A");
2136 if ((device_type == NI_DEVICE_TYPE_ENCODER) || (device_type == NI_DEVICE_TYPE_DECODER))
2137 {
2138 ni_qos_header_info_log_page_t qos_header = {0};
2139 ni_qos_namespace_info_log_page_t qos_ns_info = {0};
2140 ni_device_vf_ns_id_t ns_vf_id = {0};
2141
2142 if (ni_query_vf_ns_id(p_session_context->device_handle, &ns_vf_id,
2143 p_device_context->p_device_info->fw_rev) == NI_RETCODE_SUCCESS)
2144 {
2145 namespace_id = ns_vf_id.ns_id;
2146
2147 if (ni_query_qos_info(p_session_context->device_handle, &qos_header,
2148 p_device_context->p_device_info->fw_rev) == NI_RETCODE_SUCCESS)
2149 {
2150 ni_query_qos_namespace_info(p_session_context->device_handle, &qos_ns_info,
2151 p_device_context->p_device_info->fw_rev);
2152
2153 qos_mode = (uint8_t)(qos_header.ui16QosState & 0xFF);
2154 float _opmax = (float)(qos_ns_info.ui32OPmaxUs * 100) / VIDEO_SLICE_TIME;
2155
2156 strcat_dyn_buf(&output_buf,
2157 ",\n\t\t\"QOS MODE\": %u,\n"
2158 "\t\t\"QOS NS\": %u,\n"
2159 "\t\t\"QOS ALLOW\": %.1f,\n"
2160 "\t\t\"QOS OPMAX\": %.1f",
2161 (uint8_t)(qos_header.ui16QosState & 0xFF),
2162 namespace_id,
2163 (qos_mode == 0 ? 0 : qos_ns_info.fAllowance),
2164 (qos_mode == 0 ? 0 :_opmax)
2165 );
2166 }
2167 }
2168 }
2169 strcat_dyn_buf(&output_buf, "\n\t}");
2170 }
2171 else
2172 {
2173 strcat_dyn_buf(&output_buf, "\n\t}");
2174 }
2175 if (index < device_count - 1)
2176 {
2177 strcat_dyn_buf(&output_buf, ",\n");
2178 }
2179 else
2180 {
2181 strcat_dyn_buf(&output_buf, "\n");
2182 }
2183
2184 ni_rsrc_free_device_context(p_device_context);
2185 }
2186
2187 if (swap_encoder_and_uploader(&device_type, device_name))
2188 {
2189 goto UPLOADER;
2190 }
2191
2192 free(module_ids);
2193 }
2194
2195 // Skip printing NVME, TP and PCIE status if ni_query_nvme_status is not supported in FW
2196 if (ni_cmp_fw_api_ver((char*) &p_session_context->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6O") < 0) {
2197 goto PRINT_OUTPUT;
2198 }
2199 else
2200 {
2201 strcat_dyn_buf(&output_buf, " ],\n");
2202 }
2203
2204 //Nvme[0] and TP[1] load
2205 for (int icore = NP_LOAD; icore <= PCIE_LOAD; icore++)
2206 {
2207 // ASSUMPTION: Each Quadra has at least and only one encoder.
2208 device_type = NI_DEVICE_TYPE_ENCODER;
2209 device_count = get_modules(device_type,
2210 p_device_queue,
2211 device_name,
2212 &module_ids);
2213
2214 if (!device_count)
2215 {
2216 if (output_buf.str_buf)
2217 printf("%s", output_buf.str_buf);
2218 clear_dyn_str_buf(&output_buf);
2219 return;
2220 }
2221 if (icore == NP_LOAD)
2222 {
2223 extra_temp_per_index = (int32_t *)calloc(device_count, sizeof(int32_t));
2224 extra_power_per_index = (uint32_t *)calloc(device_count, sizeof(uint32_t));
2225 if (!extra_temp_per_index || !extra_power_per_index)
2226 {
2227 (void)fprintf(stderr, "ERROR: calloc() failed for extra info arrays\n");
2228 if (extra_temp_per_index) free(extra_temp_per_index);
2229 if (extra_power_per_index) free(extra_power_per_index);
2230 }
2231 strcat_dyn_buf(&output_buf, " \"nvmes\": [\n");
2232 g_temp_load = (uint32_t*)calloc(device_count, sizeof(uint32_t));
2233 if (!g_temp_load)
2234 {
2235 (void)fprintf(stderr, "ERROR: calloc() failed for g_temp_load\n");
2236 return;
2237 }
2238 g_temp_pload = (uint32_t*)calloc(device_count, sizeof(uint32_t));
2239 if (!g_temp_pload)
2240 {
2241 (void)fprintf(stderr, "ERROR: calloc() failed for g_temp_pload\n");
2242 return;
2243 }
2244 g_temp_pthroughput = (uint32_t*)calloc(device_count, sizeof(uint32_t));
2245 if (!g_temp_pthroughput)
2246 {
2247 (void)fprintf(stderr, "ERROR: calloc() failed for g_temp_pthroughput\n");
2248 return;
2249 }
2250 g_temp_sharemem = (uint32_t*)calloc(device_count, sizeof(uint32_t));
2251 if (!g_temp_sharemem)
2252 {
2253 (void)fprintf(stderr, "ERROR: calloc() failed for g_temp_sharemem\n");
2254 return;
2255 }
2256 }
2257 else
2258 {
2259 (icore == TP_LOAD)?strcat_dyn_buf(&output_buf, " \"tps\": [\n"):strcat_dyn_buf(&output_buf, " \"pcies\": [\n");
2260 }
2261 for (index = 0; index < device_count; index++)
2262 {
2263 p_device_context = ni_rsrc_get_device_context(device_type,
2264 module_ids[index]);
2265 if (!p_device_context)
2266 continue;
2267 if (icore == NP_LOAD)
2268 {
2269 if (!open_and_query(device_type,
2270 p_device_context,
2271 p_session_context,
2272 device_name, detail, detail_data_v1))
2273 {
2274 continue;
2275 }
2276
2277 return_code =
2278 ni_query_nvme_status(p_session_context, &load_query);
2279 if (return_code != NI_RETCODE_SUCCESS)
2280 {
2281 (void)fprintf(stderr,
2282 "ERROR: ni_query_nvme_status() returned %d for %s:%s:%d\n",
2283 return_code,
2284 device_name,
2285 p_device_context->p_device_info->dev_name,
2286 p_device_context->p_device_info->hw_id);
2287 remove_device_from_saved(device_type,
2288 p_device_context->p_device_info->module_id,
2289 p_session_context->device_handle);
2290 ni_device_close(p_session_context->device_handle);
2291 goto CLOSE;
2292 }
2293 g_temp_load[index] = load_query.tp_fw_load;
2294 g_temp_pload[index] = load_query.pcie_load;
2295 g_temp_pthroughput[index] = load_query.pcie_throughput;
2296 g_temp_sharemem[index] = load_query.fw_share_mem_usage;
2297 if (format == 2)
2298 {
2299 if (ni_query_extra_info(p_session_context->device_handle,
2300 &p_dev_extra_info,
2301 p_device_context->p_device_info->fw_rev))
2302 {
2303 p_dev_extra_info.composite_temp = 0;
2304 }
2305 extra_temp_per_index[index] = p_dev_extra_info.composite_temp;
2306 extra_power_per_index[index] = p_dev_extra_info.power_consumption;
2307 }
2308 }
2309#ifdef __linux__
2310 get_pcie_addr(p_device_context->p_device_info->dev_name, pcie);
2311 numa_node = get_numa_node(p_device_context->p_device_info->dev_name);
2312#endif
2313
2314 if (icore==PCIE_LOAD)
2315 {
2316 strcat_dyn_buf(&output_buf,
2317 "\t{\n"
2318 "\t\t\"NUMBER\": %u,\n"
2319 "\t\t\"INDEX\": %d,\n"
2320 "\t\t\"LOAD\": 0,\n"
2321 "\t\t\"MODEL_LOAD\": 0,\n"
2322 "\t\t\"FW_LOAD\": %u,\n"
2323 "\t\t\"INST\": 0,\n"
2324 "\t\t\"MAX_INST\": 0,\n"
2325 "\t\t\"MEM\": 0,\n"
2326 "\t\t\"CRITICAL_MEM\": 0,\n"
2327 "\t\t\"SHARE_MEM\": %u,\n"
2328 "\t\t\"PCIE_THROUGHPUT\": %.1f,\n"
2329 "\t\t\"P2P_MEM\": 0,\n"
2330 "\t\t\"DEVICE\": \"%s\",\n"
2331 "\t\t\"L_FL2V\": \"%s\",\n"
2332 "\t\t\"N_FL2V\": \"%s\",\n"
2333 "\t\t\"FR\": \"%.8s\",\n"
2334 "\t\t\"N_FR\": \"%.8s\""
2335#ifdef __linux__
2336 ",\n\t\t\"NUMA_NODE\": %d,\n"
2337 "\t\t\"PCIE_ADDR\": \"%s\""
2338#endif
2339 , device_count, p_device_context->p_device_info->module_id,
2340 g_temp_pload[index], 0, (float)g_temp_pthroughput[index]/10,
2341 p_device_context->p_device_info->dev_name,
2342 p_device_context->p_device_info->fl_ver_last_ran,
2343 p_device_context->p_device_info->fl_ver_nor_flash,
2344 p_device_context->p_device_info->fw_rev,
2345 p_device_context->p_device_info->fw_rev_nor_flash
2346#ifdef __linux__
2347 , numa_node, pcie
2348#endif
2349 );
2350 }
2351 else
2352 {
2353 load_query.fw_load = (icore==TP_LOAD)?g_temp_load[index]:load_query.fw_load;
2354 load_query.fw_share_mem_usage = (icore==TP_LOAD)?g_temp_sharemem[index]:load_query.fw_share_mem_usage;
2355
2356 strcat_dyn_buf(&output_buf,
2357 "\t{\n"
2358 "\t\t\"NUMBER\": %u,\n"
2359 "\t\t\"INDEX\": %d,\n"
2360 "\t\t\"LOAD\": 0,\n"
2361 "\t\t\"MODEL_LOAD\": 0,\n"
2362 "\t\t\"FW_LOAD\": %u,\n"
2363 "\t\t\"INST\": 0,\n"
2364 "\t\t\"MAX_INST\": 0,\n"
2365 "\t\t\"MEM\": 0,\n"
2366 "\t\t\"CRITICAL_MEM\": 0,\n"
2367 "\t\t\"SHARE_MEM\": %u,\n"
2368 "\t\t\"P2P_MEM\": 0,\n"
2369 "\t\t\"DEVICE\": \"%s\",\n"
2370 "\t\t\"L_FL2V\": \"%s\",\n"
2371 "\t\t\"N_FL2V\": \"%s\",\n"
2372 "\t\t\"FR\": \"%.8s\",\n"
2373 "\t\t\"N_FR\": \"%.8s\""
2374#ifdef __linux__
2375 ",\n\t\t\"NUMA_NODE\": %d,\n"
2376 "\t\t\"PCIE_ADDR\": \"%s\""
2377#endif
2378 , device_count, p_device_context->p_device_info->module_id,
2379 load_query.fw_load, load_query.fw_share_mem_usage,
2380 p_device_context->p_device_info->dev_name,
2381 p_device_context->p_device_info->fl_ver_last_ran,
2382 p_device_context->p_device_info->fl_ver_nor_flash,
2383 p_device_context->p_device_info->fw_rev,
2384 p_device_context->p_device_info->fw_rev_nor_flash
2385#ifdef __linux__
2386 , numa_node, pcie
2387#endif
2388 );
2389 }
2390 if (format == 2)
2391 {
2392 if (p_dev_extra_info.power_consumption + 1)
2393 {
2394 ni_sprintf(power_consumption, 16, "%umW", extra_power_per_index[index]);
2395 }
2396 strcat_dyn_buf(&output_buf,
2397 ",\n\t\t\"TEMP\": %d,\n"
2398 "\t\t\"POWER\": \"%s\"\n"
2399 "\t}",
2400 extra_temp_per_index[index] + ABSOLUTE_TEMP_ZERO,
2401 (extra_power_per_index[index] + 1) ? power_consumption : "N/A");
2402 }
2403 else
2404 {
2405 strcat_dyn_buf(&output_buf, "\n\t}");
2406 }
2407 if (index < device_count - 1)
2408 {
2409 strcat_dyn_buf(&output_buf, ",\n");
2410 }
2411 else
2412 {
2413 strcat_dyn_buf(&output_buf, "\n");
2414 if (icore != PCIE_LOAD)
2415 {
2416 strcat_dyn_buf(&output_buf, " ],\n");
2417 }
2418 }
2419
2420CLOSE:
2421 ni_rsrc_free_device_context(p_device_context);
2422 }
2423 }
2424
2425 free(g_temp_load);
2426 free(g_temp_pload);
2427 free(g_temp_pthroughput);
2428 free(g_temp_sharemem);
2429 free(module_ids);
2430
2431PRINT_OUTPUT:
2432 strcat_dyn_buf(&output_buf, " ]\n}\n");
2433 if (output_buf.str_buf)
2434 printf("%s", output_buf.str_buf);
2435 clear_dyn_str_buf(&output_buf);
2436}
2437
2439 ni_session_context_t *sessionCtxt, int detail, ni_instance_mgr_detail_status_v1_t *detail_data_v1, ni_instance_mgr_detail_status_v1_t (*previous_detail_data_p)[NI_MAX_DEVICE_CNT], int checkInterval)
2440{
2441 int index, instance_count; // used in later FOR-loop when compiled without c99
2442 unsigned int i;
2443 unsigned int module_count;
2444 char module_name[MAX_DEVICE_NAME_SIZE] = {0};
2445 int32_t *module_id_arr = NULL;
2446 dyn_str_buf_t output_buf = {0};
2447 ni_device_context_t *p_device_context = NULL;
2448 ni_device_type_t module_type;
2449 int max_device_type = NI_DEVICE_TYPE_XCODER_MAX;
2450 char _ml[16];
2451
2452 for (module_type = NI_DEVICE_TYPE_DECODER;
2453 module_type != max_device_type;
2454 module_type++)
2455 {
2456 instance_count = 0;
2457 module_count = get_modules(module_type,
2458 coders,
2459 module_name,
2460 &module_id_arr);
2461
2462 if (!module_count)
2463 {
2464 continue;
2465 }
2466
2467 strcat_dyn_buf(&output_buf, "Num %ss: %u\n", module_name, module_count);
2468 if(detail)
2469 {
2470 if(module_type == NI_DEVICE_TYPE_DECODER)
2471 {
2472 if(checkInterval)
2473 {
2474 strcat_dyn_buf(&output_buf,
2475 "%-5s %-7s %-7s %-9s %-5s %-7s %-8s %-4s %-5s %-6s %-5s %-14s %-20s\n", "INDEX",
2476 "AvgCost", "VpuLoad", "FrameRate", "IDR", "InFrame", "OutFrame", "fps", "Width", "Height",
2477 "SID", "DEVICE", "NAMESPACE");
2478 }
2479 else
2480 {
2481 strcat_dyn_buf(&output_buf,
2482 "%-5s %-7s %-7s %-9s %-5s %-7s %-8s %-5s %-6s %-5s %-14s %-20s\n", "INDEX",
2483 "AvgCost", "VpuLoad", "FrameRate", "IDR", "InFrame", "OutFrame", "Width", "Height",
2484 "SID", "DEVICE", "NAMESPACE");
2485 }
2486 }
2487 else if (module_type == NI_DEVICE_TYPE_ENCODER)
2488 {
2489 if(checkInterval)
2490 {
2491 strcat_dyn_buf(&output_buf,
2492 "%-5s %-7s %-7s %-9s %-5s %-7s %-7s %-8s %-4s %-10s %-10s %-5s %-6s %-9s %-5s %-14s %-20s\n", "INDEX",
2493 "AvgCost", "VpuLoad", "FrameRate", "IDR", "UserIDR", "InFrame", "OutFrame", "fps", "BR", "AvgBR", "Width", "Height",
2494 "Format", "SID", "DEVICE", "NAMESPACE");
2495 }
2496 else
2497 {
2498 strcat_dyn_buf(&output_buf,
2499 "%-5s %-7s %-7s %-9s %-5s %-7s %-7s %-8s %-10s %-10s %-5s %-6s %-9s %-5s %-14s %-20s\n", "INDEX",
2500 "AvgCost", "VpuLoad", "FrameRate", "IDR", "UserIDR", "InFrame", "OutFrame", "BR", "AvgBR", "Width", "Height",
2501 "Format", "SID", "DEVICE", "NAMESPACE");
2502 }
2503 }
2504 else if(module_type == NI_DEVICE_TYPE_SCALER || module_type == NI_DEVICE_TYPE_AI)
2505 {
2506 if(checkInterval)
2507 {
2508 strcat_dyn_buf(&output_buf,
2509 "%-5s %-7s %-7s %-8s %-4s %-5s %-6s %-5s %-14s %-20s\n", "INDEX",
2510 "VpuLoad", "InFrame", "OutFrame", "fps", "Width", "Height",
2511 "SID", "DEVICE", "NAMESPACE");
2512 }
2513 else
2514 {
2515 strcat_dyn_buf(&output_buf,
2516 "%-5s %-7s %-7s %-8s %-5s %-6s %-5s %-14s %-20s\n", "INDEX",
2517 "VpuLoad", "InFrame", "OutFrame", "Width", "Height",
2518 "SID", "DEVICE", "NAMESPACE");
2519 }
2520 }
2521 }
2522 else
2523 strcat_dyn_buf(&output_buf,
2524 "%-5s %-4s %-10s %-4s %-4s %-9s %-7s %-14s\n", "INDEX",
2525 "LOAD", "MODEL_LOAD", "INST", "MEM", "SHARE_MEM", "P2P_MEM",
2526 "DEVICE");
2527
2529 for (i = 0; i < module_count; i++)
2530 {
2531 p_device_context = ni_rsrc_get_device_context(module_type, module_id_arr[i]);
2532
2534 if (open_and_query(module_type,
2535 p_device_context,
2536 sessionCtxt,
2537 module_name, detail, detail_data_v1))
2538 {
2539 if(detail)
2540 {
2541 for(index = 0; index < NI_MAX_CONTEXTS_PER_HW_INSTANCE; index++)
2542 {
2543 if(detail_data_v1->sInstDetailStatus[index].ui16FrameRate)
2544 {
2545 if(previous_detail_data_p && checkInterval)
2546 {
2547 if(previous_detail_data_p[module_type][i].sInstDetailStatus[index].ui16FrameRate)
2548 {
2549 if(module_type == NI_DEVICE_TYPE_DECODER)
2550 {
2551 strcat_dyn_buf(&output_buf,
2552 "%-5d %-7d %-7d %-9d %-5u %-7d %-8d %-4d %-5d %-6d %-5s %-14s %-20s\n",
2553 instance_count++,
2554 detail_data_v1->sInstDetailStatus[index].ui8AvgCost,
2555 detail_data_v1->sInstDetailStatusAppend[index].ui16RealVpuLoad,
2556 detail_data_v1->sInstDetailStatus[index].ui16FrameRate,
2557 detail_data_v1->sInstDetailStatus[index].ui32NumIDR,
2558 detail_data_v1->sInstDetailStatus[index].ui32NumInFrame,
2559 detail_data_v1->sInstDetailStatus[index].ui32NumOutFrame,
2560 (detail_data_v1->sInstDetailStatus[index].ui32NumOutFrame - previous_detail_data_p[module_type][i].sInstDetailStatus[index].ui32NumOutFrame) / checkInterval,
2561 detail_data_v1->sInstDetailStatusAppend[index].ui32Width,
2562 detail_data_v1->sInstDetailStatusAppend[index].ui32Height,
2563 get_session_id(p_device_context, (int)detail_data_v1->sInstDetailStatusAppend[index].u32InstanceId),
2564 p_device_context->p_device_info->dev_name,
2565 p_device_context->p_device_info->blk_name);
2566 }
2567 else if (module_type == NI_DEVICE_TYPE_ENCODER)
2568 {
2569 strcat_dyn_buf(&output_buf,
2570 "%-5d %-7d %-7d %-9d %-5u %-7d %-7d %-8d %-4d %-10d %-10d %-5d %-6d %-9s %-5s %-14s %-20s\n",
2571 instance_count++,
2572 detail_data_v1->sInstDetailStatus[index].ui8AvgCost,
2573 detail_data_v1->sInstDetailStatusAppend[index].ui16RealVpuLoad,
2574 detail_data_v1->sInstDetailStatus[index].ui16FrameRate,
2575 detail_data_v1->sInstDetailStatus[index].ui32NumIDR,
2576 detail_data_v1->sInstDetailStatusAppend[index].ui32UserIDR,
2577 detail_data_v1->sInstDetailStatus[index].ui32NumInFrame,
2578 detail_data_v1->sInstDetailStatus[index].ui32NumOutFrame,
2579 (detail_data_v1->sInstDetailStatus[index].ui32NumOutFrame - previous_detail_data_p[module_type][i].sInstDetailStatus[index].ui32NumOutFrame) / checkInterval,
2580 detail_data_v1->sInstDetailStatus[index].ui32BitRate,
2581 detail_data_v1->sInstDetailStatus[index].ui32AvgBitRate,
2582 detail_data_v1->sInstDetailStatusAppend[index].ui32Width,
2583 detail_data_v1->sInstDetailStatusAppend[index].ui32Height,
2584 get_pixel_format(p_device_context, detail_data_v1->sInstDetailStatusAppend[index].u8PixelFormat),
2585 get_session_id(p_device_context, (int)detail_data_v1->sInstDetailStatusAppend[index].u32InstanceId),
2586 p_device_context->p_device_info->dev_name,
2587 p_device_context->p_device_info->blk_name);
2588 }
2589 else if(module_type == NI_DEVICE_TYPE_SCALER || module_type == NI_DEVICE_TYPE_AI)
2590 {
2591 strcat_dyn_buf(&output_buf,
2592 "%-5d %-7d %-7d %-8d %-4d %-5d %-6d %-5s %-14s %-20s\n",
2593 instance_count++,
2594 detail_data_v1->sInstDetailStatusAppend[index].ui16RealVpuLoad,
2595 detail_data_v1->sInstDetailStatus[index].ui32NumInFrame,
2596 detail_data_v1->sInstDetailStatus[index].ui32NumOutFrame,
2597 (detail_data_v1->sInstDetailStatus[index].ui32NumOutFrame - previous_detail_data_p[module_type][i].sInstDetailStatus[index].ui32NumOutFrame) / checkInterval,
2598 detail_data_v1->sInstDetailStatusAppend[index].ui32Width,
2599 detail_data_v1->sInstDetailStatusAppend[index].ui32Height,
2600 get_session_id(p_device_context, (int)detail_data_v1->sInstDetailStatusAppend[index].u32InstanceId),
2601 p_device_context->p_device_info->dev_name,
2602 p_device_context->p_device_info->blk_name);
2603 }
2604 }
2605 }
2606 else
2607 {
2608 if(module_type == NI_DEVICE_TYPE_DECODER)
2609 {
2610 strcat_dyn_buf(&output_buf,
2611 "%-5d %-7d %-7d %-9d %-5u %-7d %-8d %-5d %-6d %-5s %-14s %-20s\n",
2612 instance_count++,
2613 detail_data_v1->sInstDetailStatus[index].ui8AvgCost,
2614 detail_data_v1->sInstDetailStatusAppend[index].ui16RealVpuLoad,
2615 detail_data_v1->sInstDetailStatus[index].ui16FrameRate,
2616 detail_data_v1->sInstDetailStatus[index].ui32NumIDR,
2617 detail_data_v1->sInstDetailStatus[index].ui32NumInFrame,
2618 detail_data_v1->sInstDetailStatus[index].ui32NumOutFrame,
2619 detail_data_v1->sInstDetailStatusAppend[index].ui32Width,
2620 detail_data_v1->sInstDetailStatusAppend[index].ui32Height,
2621 get_session_id(p_device_context, (int)detail_data_v1->sInstDetailStatusAppend[index].u32InstanceId),
2622 p_device_context->p_device_info->dev_name,
2623 p_device_context->p_device_info->blk_name);
2624 }
2625 else if (module_type == NI_DEVICE_TYPE_ENCODER)
2626 {
2627 strcat_dyn_buf(&output_buf,
2628 "%-5d %-7d %-7d %-9d %-5u %-7d %-7d %-8d %-10d %-10d %-5d %-6d %-9s %-5s %-14s %-20s\n",
2629 instance_count++,
2630 detail_data_v1->sInstDetailStatus[index].ui8AvgCost,
2631 detail_data_v1->sInstDetailStatusAppend[index].ui16RealVpuLoad,
2632 detail_data_v1->sInstDetailStatus[index].ui16FrameRate,
2633 detail_data_v1->sInstDetailStatus[index].ui32NumIDR,
2634 detail_data_v1->sInstDetailStatusAppend[index].ui32UserIDR,
2635 detail_data_v1->sInstDetailStatus[index].ui32NumInFrame,
2636 detail_data_v1->sInstDetailStatus[index].ui32NumOutFrame,
2637 detail_data_v1->sInstDetailStatus[index].ui32BitRate,
2638 detail_data_v1->sInstDetailStatus[index].ui32AvgBitRate,
2639 detail_data_v1->sInstDetailStatusAppend[index].ui32Width,
2640 detail_data_v1->sInstDetailStatusAppend[index].ui32Height,
2641 get_pixel_format(p_device_context, detail_data_v1->sInstDetailStatusAppend[index].u8PixelFormat),
2642 get_session_id(p_device_context, (int)detail_data_v1->sInstDetailStatusAppend[index].u32InstanceId),
2643 p_device_context->p_device_info->dev_name,
2644 p_device_context->p_device_info->blk_name);
2645 }
2646 else if(module_type == NI_DEVICE_TYPE_SCALER || module_type == NI_DEVICE_TYPE_AI)
2647 {
2648 strcat_dyn_buf(&output_buf,
2649 "%-5d %-7d %-7d %-8d %-5d %-6d %-5s %-14s %-20s\n",
2650 instance_count++,
2651 detail_data_v1->sInstDetailStatusAppend[index].ui16RealVpuLoad,
2652 detail_data_v1->sInstDetailStatus[index].ui32NumInFrame,
2653 detail_data_v1->sInstDetailStatus[index].ui32NumOutFrame,
2654 detail_data_v1->sInstDetailStatusAppend[index].ui32Width,
2655 detail_data_v1->sInstDetailStatusAppend[index].ui32Height,
2656 get_session_id(p_device_context, (int)detail_data_v1->sInstDetailStatusAppend[index].u32InstanceId),
2657 p_device_context->p_device_info->dev_name,
2658 p_device_context->p_device_info->blk_name);
2659 }
2660 }
2661 }
2662 }
2663 if(previous_detail_data_p)
2664 {
2665 memcpy(&previous_detail_data_p[module_type][i], detail_data_v1, sizeof(ni_instance_mgr_detail_status_v1_t));
2666 }
2667 }
2668 else
2669 {
2670 /* PF prints overall statistics; VFs print their own per-NS statistics. */
2671 uint32_t disp_load = sessionCtxt->load_query.current_load;
2672 uint32_t disp_total_ctx = sessionCtxt->load_query.total_contexts;
2673 uint32_t disp_model_load = sessionCtxt->load_query.fw_model_load;
2674 if (sessionCtxt->overall_load_query.admin_queried &&
2675 module_type != NI_DEVICE_TYPE_UPLOAD)
2676 {
2677 disp_load = sessionCtxt->overall_load_query.overall_current_load;
2678 disp_total_ctx = sessionCtxt->overall_load_query.overall_instance_count;
2679 disp_model_load = sessionCtxt->overall_load_query.overall_fw_model_load;
2680 }
2681
2682 if((module_type == NI_DEVICE_TYPE_DECODER) || (module_type == NI_DEVICE_TYPE_ENCODER))
2683 {
2684 strcat_dyn_buf(&output_buf,
2685 "%-5d %-4u %-10s %-4u %-4u %-9u %-7u %-14s\n",
2686 p_device_context->p_device_info->module_id,
2687#ifdef XCODER_311
2688 disp_load,
2689#else
2690 (disp_total_ctx == 0 || disp_load > sessionCtxt->load_query.fw_load) ? disp_load : sessionCtxt->load_query.fw_load,
2691#endif
2692 (disp_model_load == 4294967295U) ? "N/A" : ((void)snprintf(_ml, sizeof(_ml), "%u", disp_model_load), _ml),
2693 disp_total_ctx,
2694 sessionCtxt->load_query.fw_video_mem_usage,
2695 sessionCtxt->load_query.fw_share_mem_usage,
2696 sessionCtxt->load_query.fw_p2p_mem_usage,
2697 p_device_context->p_device_info->dev_name);
2698 }
2699 else
2700 {
2701 strcat_dyn_buf(&output_buf,
2702 "%-5d %-4u %-10u %-4u %-4u %-9u %-7u %-14s\n",
2703 p_device_context->p_device_info->module_id,
2704#ifdef XCODER_311
2705 disp_load,
2706#else
2707 (disp_total_ctx == 0 || disp_load > sessionCtxt->load_query.fw_load) ? disp_load : sessionCtxt->load_query.fw_load,
2708#endif
2709 disp_model_load,
2710 disp_total_ctx,
2711 sessionCtxt->load_query.fw_video_mem_usage,
2712 sessionCtxt->load_query.fw_share_mem_usage,
2713 sessionCtxt->load_query.fw_p2p_mem_usage,
2714 p_device_context->p_device_info->dev_name);
2715 }
2716 }
2717
2718 ni_rsrc_free_device_context(p_device_context);
2719 }
2720 }
2721 free(module_id_arr);
2722 }
2723
2724 if (output_buf.str_buf)
2725 printf("%s", output_buf.str_buf);
2726 clear_dyn_str_buf(&output_buf);
2727}
2728
2729void print_extra(ni_device_queue_t *p_device_queue, ni_session_context_t *p_session_context, int internal_call, int show_qos_info)
2730{
2731 char device_name[MAX_DEVICE_NAME_SIZE];
2732 unsigned int index, device_count;
2733 int32_t *module_ids;
2734 dyn_str_buf_t output_buf = {0};
2735 ni_device_context_t *p_device_context;
2736 ni_device_type_t device_type;
2737 ni_device_extra_info_t p_dev_extra_info = {0};
2738 char power_consumption[16];
2739 int instance_count = 0;
2740#ifdef __linux__
2741 unsigned int gen3_mismatch_index[NI_MAX_DEVICE_CNT];
2742 unsigned int num_gen3_mismatch = 0;
2743#endif
2744
2745 ni_qos_header_info_log_page_t qos_header = {0};
2746 ni_qos_namespace_info_log_page_t qos_ns_info = {0};
2747 ni_device_vf_ns_id_t ns_vf_id = {0};
2748 bool has_qos_data = false;
2749 char qos_str[64] = {0};
2750 uint16_t namespace_id = 0;
2751
2752 // ASSUMPTION: Each Quadra has at least and only one encoder.
2753 device_type = NI_DEVICE_TYPE_ENCODER;
2754 device_count = get_modules(device_type,
2755 p_device_queue,
2756 device_name,
2757 &module_ids);
2758
2759 if (!device_count)
2760 {
2761 if (output_buf.str_buf)
2762 printf("%s", output_buf.str_buf);
2763 clear_dyn_str_buf(&output_buf);
2764 return;
2765 }
2766
2767 for (index = 0; index < device_count; index++)
2768 {
2769 p_device_context = ni_rsrc_get_device_context(device_type, module_ids[index]);
2770 if (!p_device_context)
2771 {
2772 continue;
2773 }
2774 // check if device has been opened already
2775 ni_device_type_t xcoder_device_type = GET_XCODER_DEVICE_TYPE(device_type);
2776 int module_id = p_device_context->p_device_info->module_id;
2777 if (device_handles[xcoder_device_type][module_id] != NI_INVALID_DEVICE_HANDLE)
2778 {
2779 p_session_context->device_handle =
2780 device_handles[xcoder_device_type][module_id];
2781 } else
2782 {
2783 p_session_context->device_handle =
2784 ni_device_open2(p_device_context->p_device_info->dev_name,
2786 if (p_session_context->device_handle != NI_INVALID_DEVICE_HANDLE)
2787 {
2788 device_handles[xcoder_device_type][module_id] =
2789 p_session_context->device_handle;
2790 }
2791 }
2792
2793 if (p_session_context->device_handle == NI_INVALID_DEVICE_HANDLE)
2794 {
2795 char errmsg[NI_ERRNO_LEN] = {0};
2797 (void)fprintf(stderr,
2798 "ERROR: ni_device_open2() failed for %s: %s\n",
2799 p_device_context->p_device_info->dev_name,
2800 errmsg);
2801 ni_rsrc_free_device_context(p_device_context);
2802 continue;
2803 }
2804
2805 if (ni_query_extra_info(p_session_context->device_handle,
2806 &p_dev_extra_info,
2807 p_device_context->p_device_info->fw_rev))
2808 {
2809 p_dev_extra_info.composite_temp = 0;
2810 p_dev_extra_info.fw_flavour = '-';
2811 }
2812
2813 if (p_dev_extra_info.power_consumption + 1)
2814 {
2815 ni_sprintf(power_consumption, 16, "%umW", p_dev_extra_info.power_consumption);
2816 }
2817
2818 if (show_qos_info)
2819 {
2820 if (ni_query_vf_ns_id(p_session_context->device_handle, &ns_vf_id,
2821 p_device_context->p_device_info->fw_rev) == NI_RETCODE_SUCCESS)
2822 {
2823 namespace_id = ns_vf_id.ns_id;
2824 }
2825
2826 if (ni_query_qos_info(p_session_context->device_handle, &qos_header,
2827 p_device_context->p_device_info->fw_rev) == NI_RETCODE_SUCCESS)
2828 {
2829 has_qos_data = true;
2830 ni_query_qos_namespace_info(p_session_context->device_handle, &qos_ns_info,
2831 p_device_context->p_device_info->fw_rev);
2832 }
2833 }
2834
2835 if (show_qos_info && has_qos_data)
2836 {
2837 char _allowance[16];
2838 uint8_t qos_mode = (uint8_t)(qos_header.ui16QosState & 0xFF);
2839 float _opmax = (float) (qos_ns_info.ui32OPmaxUs * 100) / VIDEO_SLICE_TIME;
2840 (void)snprintf(qos_str, sizeof(qos_str), " %-9u %-7u %-10s %-8.1f",
2841 (uint8_t)(qos_header.ui16QosState & 0xFF),
2842 namespace_id,
2843 (qos_mode == 0) ? "N/A" : ((void)snprintf(_allowance, sizeof(_allowance), "%.1f", qos_ns_info.fAllowance), _allowance),
2844 (qos_mode == 0 ? 0 :_opmax));
2845 }
2846
2847 if (!internal_call)
2848 {
2849 strcat_dyn_buf(&output_buf,
2850 "%-4s %-8s %-8s %-14s %s\n", "TEMP", "POWER", "FLAVOR", "DEVICE",
2851 (show_qos_info && has_qos_data) ? " QOS_MODE QOS_NS QOS_ALLOW QOS_OPMAX" : "");
2852 strcat_dyn_buf(&output_buf,
2853 "%-4d %-8s %-8c %-14s %s\n",
2854 p_dev_extra_info.composite_temp + ABSOLUTE_TEMP_ZERO,
2855 (p_dev_extra_info.power_consumption + 1) ? power_consumption : "N/A",
2856 p_dev_extra_info.fw_flavour,
2857 p_device_context->p_device_info->dev_name,
2858 (show_qos_info && has_qos_data) ? qos_str:"");
2859 }
2860 else
2861 {
2862 if (instance_count == 0)
2863 {
2864 strcat_dyn_buf(&output_buf,
2865 "%-8s %-8s %-8s %-8s %-8.8s %-20.8s %s\n", "INDEX", "TEMP", "POWER", "FLAVOR", "FR", "SN",
2866 (show_qos_info && has_qos_data) ? "QOS_MODE QOS_NS QOS_ALLOW QOS_OPMAX" : "");
2867 }
2868 strcat_dyn_buf(&output_buf,
2869 "%-8d %-8d %-8s %-8c %-8.8s %-8.*s %s\n",
2870 instance_count++ , p_dev_extra_info.composite_temp + ABSOLUTE_TEMP_ZERO,
2871 (p_dev_extra_info.power_consumption + 1) ? power_consumption : "N/A",
2872 p_dev_extra_info.fw_flavour,
2873 p_device_context->p_device_info->fw_rev,
2874 (int)sizeof(p_device_context->p_device_info->serial_number), p_device_context->p_device_info->serial_number,
2875 (show_qos_info && has_qos_data) ? qos_str:"");
2876
2877 }
2878
2879 //Temperature overshoot detection
2880 ni_device_capability_t device_capability_t = {0};
2881 int32_t temp_deg = p_dev_extra_info.composite_temp - 273;
2882 if (ni_device_capability_query2(p_session_context->device_handle, &device_capability_t, false) != NI_RETCODE_SUCCESS)
2883 {
2884 char errmsg[NI_ERRNO_LEN] = {0};
2886 (void)fprintf(stderr,
2887 "ERROR: ni_device_capability_query() failed for %s: %s\n",
2888 p_device_context->p_device_info->dev_name,
2889 errmsg);
2890 ni_rsrc_free_device_context(p_device_context);
2891 continue;
2892
2893 }
2894 if (p_dev_extra_info.composite_temp >= device_capability_t.critical_temp)
2895 {
2896 ni_log(NI_LOG_ERROR, "ERROR: CRITICAL TEMP HIT %ddegC on SN %s\n",temp_deg, device_capability_t.serial_number);
2897#if __linux__
2898 syslog(LOG_WARNING, "ERROR: CRITICAL TEMP %ddegC HIT on SN %s!!!\n",temp_deg,device_capability_t.serial_number);
2899#endif
2900 }
2901 else if (p_dev_extra_info.composite_temp >= device_capability_t.warning_temp)
2902 {
2903 ni_log(NI_LOG_ERROR, "ERROR: WARNING TEMP HIT %ddegC on SN %s\n",temp_deg, device_capability_t.serial_number);
2904#if __linux__
2905 syslog(LOG_WARNING, "ERROR: WARNING TEMP %ddegC HIT on SN %s!!!\n",temp_deg, device_capability_t.serial_number);
2906#endif
2907 }
2908
2909 //Pcie gen mismatch detection
2910#ifdef __linux__
2911 if (p_device_context->p_device_info->pcie_gen3_on_gen4_host == 1)
2912 {
2913 gen3_mismatch_index[num_gen3_mismatch++] = index;
2914 }
2915#endif
2916
2917 ni_rsrc_free_device_context(p_device_context);
2918 }
2919
2920#ifdef __linux__
2921 if (num_gen3_mismatch > 0)
2922 {
2923 char index_list[128] = {0};
2924 size_t len = 0;
2925 for (unsigned int i = 0; i < num_gen3_mismatch && len < sizeof(index_list) - 4; i++)
2926 {
2927 len += snprintf(index_list + len, sizeof(index_list) - len,
2928 "%s%u", (i > 0) ? ", " : "", gen3_mismatch_index[i]);
2929 }
2930 strcat_dyn_buf(&output_buf,
2931 "This system supports Gen4 PCIe speeds, but the following Quadra cards are "
2932 "currently running firmware that only supports PCIe Gen3 (Index: %s). "
2933 "All Quadra VPUs on this system can be firmware upgraded to support "
2934 "PCIe Gen 4 speeds, please update the firmware on each Quadra card to "
2935 "the default firmware flavor.\n",
2936 index_list);
2937 }
2938#endif
2939
2940 if (output_buf.str_buf)
2941 printf("%s", output_buf.str_buf);
2942 clear_dyn_str_buf(&output_buf);
2943 free(module_ids);
2944}
2945
2946int main(int argc, char *argv[])
2947{
2948 (void)setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
2949 int checkInterval;
2950 int skip_init_rsrc = 0;
2951 int should_match_rev = 1;
2952 int detail = 0;
2953 ni_instance_mgr_detail_status_v1_t detail_data_v1 = {0};
2954 ni_instance_mgr_detail_status_v1_t (*previous_detail_data)[NI_MAX_DEVICE_CNT] = NULL;
2955 ni_device_pool_t *p_device_pool = NULL;
2956 ni_device_queue_t *coders = NULL;
2957 ni_session_context_t *p_xCtxt = NULL;
2958 time_t startTime = {0}, now = {0};
2959 int timeout_seconds = 0;
2960 struct tm *ltime = NULL;
2961 char buf[64] = {0};
2962 long long time_diff_hours, time_diff_minutes, time_diff_seconds;
2963 int opt;
2964 ni_log_level_t log_level = NI_LOG_INFO;
2965 enum outFormat printFormat = FMT_TEXT;
2966 checkInterval = 0;
2967 bool fw_log_dump = false;
2968 bool core_reset_log_dump = false;
2969 int devid = -1;
2970 int refresh_device_pool = 1;
2971 bool is_first_query = true;
2972 int ret = 0;
2973 int show_qos_info = 0;
2974 char *nor_command = NULL;
2975#if defined(__linux__)
2976 /* Per-device selection (-s / -b / --domain) — apply to --nor */
2977 const char *target_slot = NULL; /* -s <bus_hex> */
2978 const char *target_domain = NULL; /* --domain <hex> */
2979 const char *target_blkdev = NULL; /* -b <nvme_dev> */
2980#endif
2981
2982#ifdef _WIN32
2983 SetConsoleCtrlHandler(console_ctrl_handler, TRUE);
2984#elif __linux__
2985 setup_signal_handler();
2986#endif
2987
2988 /* Long-option table - mirrors quadraprobe.py flags where possible.
2989 * Short flags -s, -b are free in ni_rsrc_mon and match quadraprobe.
2990 * --domain maps quadraprobe's -d (conflicts with our detail flag).
2991 * -N / --nor: short -N is preferred; --nor kept as an alias because
2992 * quadraprobe's short form -n collides with our interval flag. */
2993 static struct option long_opts[] = {
2994 {"domain", required_argument, NULL, 0},
2995 {"nor", required_argument, NULL, 'N'},
2996 {NULL, 0, NULL, 0}
2997 };
2998 int long_idx = 0;
2999 // arg handling
3000 // NOLINTNEXTLINE(concurrency-mt-unsafe) - single-threaded CLI tool
3001 while ((opt = getopt_long(argc, argv,
3002#if defined(__linux__)
3003 "n:o:D:C:k:R:rt:Sl:hvdqs:b:N:",
3004#else
3005 "n:o:D:C:k:R:rt:Sl:hvdqN:",
3006#endif
3007 long_opts, &long_idx)) != -1)
3008 {
3009 switch (opt)
3010 {
3011 case 0: /* long option without a short equivalent */
3012#if defined(__linux__)
3013 if (strcmp(long_opts[long_idx].name, "domain") == 0)
3014 target_domain = optarg;
3015#endif
3016 break;
3017 case 'N':
3018 nor_command = optarg;
3019 break;
3020 case 'o':
3021 // Output print format
3022 if (!strcmp(optarg, "json"))
3023 {
3024 printFormat = FMT_JSON;
3025 }
3026 else if (!strcmp(optarg, "simple"))
3027 {
3028 printFormat = FMT_SIMPLE_TEXT;
3029 }
3030 else if (!strcmp(optarg, "text"))
3031 {
3032 printFormat = FMT_TEXT;
3033 }
3034 else if (!strcmp(optarg, "full"))
3035 {
3036 printFormat = FMT_FULL_TEXT;
3037 }
3038 else if (!strcmp(optarg, "json1"))
3039 {
3040 printFormat = FMT_JSON1;
3041 }
3042 else if (!strcmp(optarg, "json2"))
3043 {
3044 printFormat = FMT_JSON2;
3045 }
3046 else if (!strcmp(optarg, "extra"))
3047 {
3048 printFormat = FMT_EXTRA;
3049 }
3050 else
3051 {
3052 (void)fprintf(stderr, "Error: unknown selection for outputFormat: %s\n", optarg);
3053 return 1;
3054 }
3055 break;
3056 case 'n':
3057 {
3058 int32_t tmp_val;
3059 if (ni_strtoi(optarg, &tmp_val) != NI_RETCODE_SUCCESS)
3060 {
3061 ni_log(NI_LOG_ERROR, "ERROR: %s invalid value for -%c: %s\n", __func__, opt, optarg);
3062 return 1;
3063 }
3064 checkInterval = (int)tmp_val;
3065 break;
3066 }
3067 case 'D':
3068 {
3069 int32_t tmp_val;
3070 if (ni_strtoi(optarg, &tmp_val) != NI_RETCODE_SUCCESS)
3071 {
3072 ni_log(NI_LOG_ERROR, "ERROR: %s invalid value for -%c: %s\n", __func__, opt, optarg);
3073 return 1;
3074 }
3075 fw_log_dump = tmp_val;
3076 break;
3077 }
3078 case 'C':
3079 {
3080 int32_t tmp_val;
3081 if (ni_strtoi(optarg, &tmp_val) != NI_RETCODE_SUCCESS)
3082 {
3083 ni_log(NI_LOG_ERROR, "ERROR: %s invalid value for -%c: %s\n", __func__, opt, optarg);
3084 return 1;
3085 }
3086 core_reset_log_dump = tmp_val;
3087 if (core_reset_log_dump)
3088 fw_log_dump = true;
3089 break;
3090 }
3091 case 'k':
3092 {
3093 int32_t tmp_val;
3094 if (ni_strtoi(optarg, &tmp_val) != NI_RETCODE_SUCCESS)
3095 {
3096 ni_log(NI_LOG_ERROR, "ERROR: %s invalid value for -%c: %s\n", __func__, opt, optarg);
3097 return 1;
3098 }
3099 devid = (int)tmp_val;
3100 break;
3101 }
3102 case 'R':
3103 {
3104 int32_t tmp_val;
3105 if (ni_strtoi(optarg, &tmp_val) != NI_RETCODE_SUCCESS)
3106 {
3107 ni_log(NI_LOG_ERROR, "ERROR: %s invalid value for -%c: %s\n", __func__, opt, optarg);
3108 return 1;
3109 }
3110 refresh_device_pool = (int)tmp_val;
3111 }
3112 case 'r':
3113 should_match_rev = 0;
3114 break;
3115 case 't':
3116 {
3117 int32_t tmp_val;
3118 if (ni_strtoi(optarg, &tmp_val) != NI_RETCODE_SUCCESS)
3119 {
3120 ni_log(NI_LOG_ERROR, "ERROR: %s invalid value for -%c: %s\n", __func__, opt, optarg);
3121 return 1;
3122 }
3123 timeout_seconds = (int)tmp_val;
3124 printf("Timeout will be set %d\n", timeout_seconds);
3125 break;
3126 }
3127 case 'S':
3128 skip_init_rsrc = 1;
3129 break;
3130 case 'l':
3131 log_level = arg_to_ni_log_level(optarg);
3132 if (log_level != NI_LOG_INVALID)
3133 {
3134 ni_log_set_level(log_level);
3135 } else {
3136 (void)fprintf(stderr, "FATAL: invalid log level selected: %s\n", optarg);
3137 return 1;
3138 }
3139 break;
3140 case 'q':
3141 show_qos_info = 1;
3142 break;
3143 case 'h':
3144 // help message (limit to 80 characters wide)
3145 printf("-------- ni_rsrc_mon v%s --------\n"
3146 "The ni_rsrc_mon program provides a real-time view of NETINT Quadra resources\n"
3147 "running on the system.\n"
3148 "\n"
3149 "Usage: ni_rsrc_mon [OPTIONS]\n"
3150 "\n"
3151 "Monitoring options:\n"
3152 "-n Specify reporting interval in one second interval. If 0 or no selection,\n"
3153 " report only once.\n"
3154 " Default: 0\n"
3155 "-R Specify if refresh devices on host in each monitor interval.\n"
3156 " If 0, only refresh devices at the start.\n"
3157 " Default: 1\n"
3158 "-o Output format. [text, simple, full, json, json1, json2, extra]\n"
3159 " Default: text\n"
3160 "-k Specify to dump which card's firmware logs.\n"
3161 " Default: -1(dump fw log of all cards).\n"
3162 "-r Initialize Quadra device regardless firmware release version to\n"
3163 " libxcoder version compatibility.\n"
3164 " Default: only initialize devices with compatible firmware version.\n"
3165 "-t Set timeout time in seconds for device polling. Program will exit with\n"
3166 " failure if timeout is reached without finding at least one device. If 0 or\n"
3167 " no selection, poll indefinitely until a Quadra device is found.\n"
3168 " Default: 0\n"
3169 "-S Skip init_rsrc.\n"
3170 "-d Print detailed information for decoder/encoder in text and json formats.\n"
3171 "-l Set loglevel of libxcoder API.\n"
3172 " [none, fatal, error, info, debug, trace]\n"
3173 " Default: info\n"
3174 "-q Show QoS information - MODE,NS,ALLOW,OPMAX.\n"
3175 " MODE - QoS mode 0,1,2.[Default: 0\n"
3176 " NS - QoS NS set in mode 1/2. Default:1\n"
3177 " ALLOW - QoS allowance set in mode 1/2. Default:0\n"
3178 " OPMAX - QoS OverProvisioning max set in 2. Default:0\n"
3179 "-h Open this help message.\n"
3180 "-v Print version info.\n"
3181 "The Error information for critical/warning temperature and Pcie-gen mismatch is shown in all modes\n"
3182 "\n"
3183 "Firmware log dump options (Linux):\n"
3184 "-D Dump firmware logs (all devices) to current directory.\n"
3185 " Default: 0 (do not dump).\n"
3186 "-C Dump firmware core-reset logs (all devices) to current directory.\n"
3187 " Default: 0 (do not dump).\n"
3188 "-s Select a single device by PCIe slot \n"
3189 "-b Select a single device by NVMe block device name (Mutually exclusive with -s)\n"
3190 "\n"
3191 "NOR flash options (Linux, requires root):\n"
3192 "-N <cmd> NOR flash persistent log command. [w, r, e, ex], (long form: --nor)\n"
3193 " w - Write current DDR logs into NOR flash\n"
3194 " r - Read persistent logs from NOR flash into DDR, then dump\n"
3195 " e - Erase persistent logs from NOR flash\n"
3196 " ex - Simulate exception (DDR logs saved to NOR flash)\n"
3197 " -s / -b / --domain selector to choose specific card.\n"
3198 "\n"
3199 "Examples:\n"
3200 " ni_rsrc_mon -D 1 Dump firmware logs from all devices\n"
3201 " ni_rsrc_mon -C 1 Dump core-reset logs from all devices\n"
3202 " ni_rsrc_mon -N r Read NOR flash logs on all devices\n"
3203 " ni_rsrc_mon -N w -s 1 Write NOR flash logs on device slot 1, i.e. 0000:01:00.0\n"
3204 " ni_rsrc_mon --nor r -b nvme0n1 Read NOR flash and dump logs for block dev nvme0n1\n"
3205 "\n"
3206 "Simple output shows the maximum firmware load amongst the subsystems on the\n"
3207 "Quadra device.\n"
3208 "\n"
3209 "Reporting columns for text output format\n"
3210 "INDEX index number used by resource manager to identify the resource\n"
3211 "LOAD realtime load given in percentage. This value is max of VPU and FW load reported in full output format\n"
3212 "MODEL_LOAD estimated load based on framerate and resolution\n"
3213 "INST number of job instances\n"
3214 "MEM usage of memory by the subsystem\n"
3215 "SHARE_MEM usage of memory shared across subsystems on the same device\n"
3216 "P2P_MEM usage of memory by P2P\n"
3217 "DEVICE path to NVMe device file handle\n"
3218 "NAMESPACE path to NVMe namespace file handle\n"
3219 "Additional information only in text(Default) mode \n"
3220 "TEMP current temperature (degrees Celsius)\n"
3221 "POWER current power(mW), N/A when query power not supported\n"
3222 "FLAVOR current Flavor, N/A when query flavor not supported\n"
3223 "FR current firmware revision\n"
3224 "SN serial number of the Quadra device\n"
3225 "\n"
3226 "Additional reporting columns for full output format\n"
3227 "VPU same as LOAD in JSON outputs\n"
3228 "FW system load\n"
3229 "TOTAL same as MEM\n"
3230 "CRITICAL usage of memory considered critical\n"
3231 "L_FL2V last ran firmware loader 2 version\n"
3232 "N_FL2V nor flash firmware loader 2 version\n"
3233 "FR current firmware revision\n"
3234 "N_FR nor flash firmware revision\n"
3235 "TEMP current temperature (degrees Celsius)\n"
3236 "POWER current power(mW), N/A when query power not supported\n"
3237 "FLAVOR current Flavor, N/A when query flavor not supported\n"
3238 "FR current firmware revision\n"
3239 "SN serial number of the Quadra device\n"
3240 "QOS Header shows QoS information when enabled\n"
3241 "Unique field PCIe_Card2Host_Gbps for PCIE throughput from card to host in GBps(Values in steps of 100 Mbps)\n"
3242 "\n"
3243 "Additional reporting columns for full JSON formats\n"
3244 "LOAD VPU load\n"
3245 "FW_LOAD system load\n"
3246 "TEMP current temperature (degrees Celsius)\n"
3247 "POWER current power(mW), N/A when query power not supported\n"
3248 "FLAVOR current Flavor, N/A when query flavor not supported\n"
3249 "FR current firmware revision\n"
3250 "SN serial number of the Quadra device\n"
3251 "QOS decoder and encoder show QoS Information\n"
3252 "Unique field PCIe_Card2Host_Gbps for PCIE throughput from card to host in GBps(Values in steps of 100 Mbps)\n"
3253 "\n"
3254 "Following detailed data is displayed per instance for decoder and encoder when -d flag is used"
3255 "INDEX index number used by resource manager to identify the instance\n"
3256 "AvgCost estimated load given in percentage based on framerate and resolution\n"
3257 "VpuLoad vpu load: per-channel consumption ratio in 1/10000 units. Always 0 on firmware < 6tD\n"
3258 "FrameRate framerate of current session\n"
3259 "IDR number of IDR frame it processes\n"
3260 "UserIDR number of force IDR frame set by user(encoder only)\n"
3261 "InFrame number of frames sent to the decoder or encoder\n"
3262 "OutFrame number of frames got from the decoder or encoder\n"
3263 "BR instantaneous bitrate of current encoder session\n"
3264 "AvgBR average bitrate of current encoder session\n"
3265 "Width width of decoder or encoder\n"
3266 "Height height of decoder or encoder\n"
3267 "Format input frame format send to encoder\n"
3268 "SID session id\n"
3269 "DEVICE path to NVMe device file handle\n"
3270 "NAMESPACE path to NVMe namespace file handle\n"
3271 "\n"
3272 "Extra output shows TEMP and POWER and FLAVOR of the Quadra device \n",
3274 return 0;
3275 case 'v':
3276 printf("Release ver: %s\n"
3277 "API ver: %s\n"
3278 "Date: %s\n"
3279 "ID: %s\n",
3282 return 0;
3283 /* ---- New flags (mirrors quadraprobe.py) ---- */
3284#if defined(__linux__)
3285 case 's':
3286 target_slot = optarg;
3287 break;
3288 case 'b':
3289 target_blkdev = optarg;
3290 break;
3291#endif
3292 /* ---- Existing flags ---- */
3293 case '?':
3294 if (isprint(opt))
3295 {
3296 (void)fprintf(stderr, "FATAL: unknown option '-%c'\n", opt);
3297 } else
3298 {
3299 (void)fprintf(stderr, "FATAL: unknown option character '\\x%x'\n", opt);
3300 }
3301 return 1;
3302 case 'd':
3303 detail = 1;
3304 break;
3305 case ':':
3306 (void)fprintf(stderr, "FATAL: option '-%c' lacks arg\n", opt);
3307 return 1;
3308 default:
3309 (void)fprintf(stderr, "FATAL: unhandled option\n");
3310 return 1;
3311 }
3312 }
3313
3314#if defined(__linux__)
3315 /* -s and -b are mutually exclusive */
3316 if (target_slot && target_blkdev)
3317 {
3318 (void)fprintf(stderr, "FATAL: -s and -b are mutually exclusive; "
3319 "specify a PCIe slot or a block device name, not both.\n");
3320 return 1;
3321 }
3322#endif
3323
3324 if ((argc <= 2) && (optind == 1))
3325 {
3326 for (; optind < argc; optind++)
3327 {
3328 checkInterval = argToI(argv[optind]);
3329 }
3330 }
3331
3332#ifdef _ANDROID
3333 ni_log_set_log_tag(LOG_TAG);
3334#endif
3335
3337 if(!p_xCtxt)
3338 {
3339 (void)fprintf(stderr, "FATAL: cannot allocate momory for ni_session_context_t\n");
3340 return 1;
3341 }
3342
3343 ni_log_set_level(NI_LOG_ERROR); // silence informational prints
3344 if (!skip_init_rsrc)
3345 {
3346 ret = ni_rsrc_init(should_match_rev, timeout_seconds);
3347 }
3348 if (!skip_init_rsrc && ret != 0)
3349 {
3351 ni_rsrc_refresh(should_match_rev);
3352 (void)fprintf(stderr, "FATAL: NI resource unavailable\n");
3353#if defined(__linux__)
3354 if (fw_log_dump)
3355 {
3356 (void)fprintf(stderr, "Proceeding to dump firmware logs as root\n");
3357 if (geteuid() != 0)
3358 {
3359 (void)fprintf(stderr, "This operation requires root (sudo). Please rerun: sudo %s \n", argv[0]);
3360 exit(1); // NOLINT(concurrency-mt-unsafe) - single-threaded CLI tool
3361 }
3362 int rc = ni_rsrc_log_dump(".", core_reset_log_dump);
3363 if (rc == 0)
3364 (void)fprintf(stderr, "Firmware log dump: all devices successful.\n");
3365 else if (rc == 1)
3366 (void)fprintf(stderr, "Firmware log dump: No Quadra devices found. Nothing to dump.\n");
3367 else if (rc == 2)
3368 (void)fprintf(stderr, "Firmware log dump: One or more device logs failed to dump. Check previous error messages for details.\n");
3369 else
3370 (void)fprintf(stderr, "Firmware log dump: Unexpected error, return code %d\n", rc);
3371 }
3372#endif
3373 ret = 0;
3374#if defined(__linux__)
3375 if (nor_command)
3376 {
3377 ret = run_bar4_operations(nor_command, target_domain, target_slot,
3378 target_blkdev);
3379 }
3380#endif
3381 } else
3382 {
3383 ret = 1;
3384 (void)fprintf(stderr, "FATAL: cannot access NI resource\n");
3385 }
3386 LRETURN;
3387 }
3388 ni_log_set_level(log_level);
3389
3390 p_device_pool = ni_rsrc_get_device_pool();
3391 if (!p_device_pool)
3392 {
3393 (void)fprintf(stderr, "FATAL: cannot get devices info\n");
3394 ret = 1;
3395 LRETURN;
3396 }
3397
3398 if (log_level >= NI_LOG_INFO)
3399 {
3400 printf("**************************************************\n");
3401 }
3402
3403 // initialise device handles
3404 for (int i = 0; i < NI_DEVICE_TYPE_XCODER_MAX; i++)
3405 {
3406 for (int j = 0; j < NI_MAX_DEVICE_CNT; j++)
3407 {
3408 device_handles[i][j] = NI_INVALID_DEVICE_HANDLE;
3409 }
3410 }
3411
3412 startTime = time(NULL);
3413 if(checkInterval)
3414 {
3415 int allocate_size = (int)((size_t)NI_MAX_DEVICE_CNT * NI_DEVICE_TYPE_XCODER_MAX * sizeof(ni_instance_mgr_detail_status_v1_t));
3416 previous_detail_data = (ni_instance_mgr_detail_status_v1_t (*)[NI_MAX_DEVICE_CNT])malloc(allocate_size);
3417 if(previous_detail_data == NULL)
3418 {
3419 (void)fprintf(stderr, "FATAL: Allocate buffer fail\n");
3420 ret = 1;
3421 LRETURN;
3422 }
3423 memset((void *)previous_detail_data, 0, allocate_size);
3424 }
3425 while (!g_xcoder_stop_process)
3426 {
3427 now = time(NULL);
3428 struct tm temp_time;
3429 ltime = ni_localtime(&temp_time, &now);
3430 if (ltime)
3431 {
3432 (void)strftime(buf, sizeof(buf), "%c", ltime);
3433 }
3434 time_diff_seconds = (long long)difftime(now, startTime);
3435 time_diff_minutes = time_diff_seconds / 60;
3436 time_diff_hours = time_diff_minutes / 60;
3437
3438
3439 if (is_first_query || refresh_device_pool)
3440 {
3441 ni_rsrc_refresh(should_match_rev);
3442 }
3443
3444 if (log_level >= NI_LOG_INFO)
3445 {
3446 printf("%s up %02lld" ":%02lld" ":%02lld" " v%s\n", buf, time_diff_hours, time_diff_minutes % 60, time_diff_seconds % 60,
3448 }
3449
3452#ifdef _WIN32
3453 if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->lock, INFINITE)) // no time-out interval)
3454 {
3455 (void)fprintf(stderr, "ERROR: Failed to obtain mutex: %p\n", p_device_pool->lock);
3456 ret = 1;
3457 LRETURN;
3458 }
3459#elif __linux__
3460 if ( lockf(p_device_pool->lock, F_LOCK, 0) )
3461 {
3462 perror("ERROR: cannot lock p_device_pool");
3463 }
3464#endif
3465
3466 coders = p_device_pool->p_device_queue;
3467
3468#ifdef _WIN32
3469 ReleaseMutex((HANDLE)p_device_pool->lock);
3470#elif __linux__
3471 if ( lockf(p_device_pool->lock, F_ULOCK, 0) )
3472 {
3473 perror("ERROR: cannot unlock p_device_pool");
3474 }
3475#endif
3476
3477 switch (printFormat)
3478 {
3479 case FMT_TEXT:
3480 print_extra(coders, p_xCtxt, 1, show_qos_info);
3481 print_text(coders, p_xCtxt, detail, &detail_data_v1, previous_detail_data, checkInterval);
3482 break;
3483 case FMT_FULL_TEXT:
3484 show_qos_info=1;
3485 print_extra(coders, p_xCtxt, 1, show_qos_info);
3486 print_full_text(coders, p_xCtxt, 0, &detail_data_v1);
3487 break;
3488 case FMT_SIMPLE_TEXT:
3489 print_simple_text(coders, p_xCtxt, 0, &detail_data_v1);
3490 break;
3491 case FMT_JSON:
3492 if(!detail)
3493 {
3494 print_json_final(coders, p_xCtxt, 0, &detail_data_v1);
3495 }
3496 else
3497 {
3498 print_json_detail(coders, p_xCtxt, &detail_data_v1);
3499 }
3500 break;
3501 case FMT_JSON1:
3502 if(!detail)
3503 {
3504 print_json1(coders, p_xCtxt, 0, &detail_data_v1, 1);
3505 }
3506 else
3507 {
3508 print_json_detail(coders, p_xCtxt, &detail_data_v1);
3509 }
3510 break;
3511 case FMT_JSON2:
3512 if(!detail)
3513 {
3514 print_json1(coders, p_xCtxt, 0, &detail_data_v1, 2);
3515 }
3516 else
3517 {
3518 print_json_detail(coders, p_xCtxt, &detail_data_v1);
3519 }
3520 break;
3521 case FMT_EXTRA:
3522 print_extra(coders, p_xCtxt, 0, show_qos_info);
3523 break;
3524 }
3525
3526 is_first_query = false;
3527
3528 if (log_level >= NI_LOG_INFO)
3529 {
3530 printf("**************************************************\n");
3531 }
3532
3533 (void)fflush(stdout);
3534
3535 if (checkInterval == 0)
3536 {
3537 // run once
3538 break;
3539 }
3540 ni_usleep((int64_t)checkInterval * 1000 * 1000);
3541 }
3542
3543 if (fw_log_dump)
3544 {
3545 // dump fw log
3546#ifdef _WIN32
3547 if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->lock, INFINITE)) // no time-out interval)
3548 {
3549 (void)fprintf(stderr, "ERROR: Failed to obtain mutex: %p\n", p_device_pool->lock);
3550 ret = 1;
3551 LRETURN;
3552 }
3553#elif __linux__
3554 if ( lockf(p_device_pool->lock, F_LOCK, 0) )
3555 {
3556 perror("ERROR: cannot lock p_device_pool");
3557 }
3558#endif
3559 coders = p_device_pool->p_device_queue;
3560#ifdef _WIN32
3561 ReleaseMutex((HANDLE)p_device_pool->lock);
3562#elif __linux__
3563 if ( lockf(p_device_pool->lock, F_ULOCK, 0) )
3564 {
3565 perror("ERROR: cannot unlock p_device_pool");
3566 }
3567#endif
3568#if defined(__linux__)
3569 if (core_reset_log_dump)
3570 {
3571 (void)fprintf(stderr, "Proceeding to dump firmware logs as root\n");
3572 if (geteuid() != 0)
3573 {
3574 (void)fprintf(stderr, "This operation requires root (sudo). Please rerun: sudo %s \n", argv[0]);
3575 exit(1); // NOLINT(concurrency-mt-unsafe) - single-threaded CLI tool
3576 }
3577 int rc = ni_rsrc_log_dump(".", core_reset_log_dump);
3578 if (rc == 0)
3579 (void)fprintf(stderr, "Firmware log dump: all devices successful.\n");
3580 else if (rc == 1)
3581 (void)fprintf(stderr, "Firmware log dump: No Quadra devices found. Nothing to dump.\n");
3582 else if (rc == 2)
3583 (void)fprintf(stderr, "Firmware log dump: One or more device logs failed to dump. Check previous error messages for details.\n");
3584 else
3585 (void)fprintf(stderr, "Firmware log dump: Unexpected error, return code %d\n", rc);
3586 }
3587 else
3588#endif
3589 {
3590 dump_fw_log(coders, p_xCtxt, devid);
3591 }
3592 }
3593
3594#if defined(__linux__)
3595 if (nor_command)
3596 {
3597 /* NOR flash commands; -s / -b / --domain target a single device. */
3598 ret = run_bar4_operations(nor_command, target_domain, target_slot,
3599 target_blkdev);
3600 }
3601#endif
3602
3603 // close all opened devices
3604 for (int i = 0; i < NI_DEVICE_TYPE_XCODER_MAX; i++)
3605 {
3606 for (int j = 0; j < NI_MAX_DEVICE_CNT; j++)
3607 {
3608 if (device_handles[i][j] != NI_INVALID_DEVICE_HANDLE)
3609 {
3611 }
3612 }
3613 }
3614
3615#ifdef __OPENHARMONY__
3616 (void)system("chmod -R 777 /dev/shm/"); // NOLINT(cert-env33-c,concurrency-mt-unsafe) - init-time only, no user input
3617#ifdef XCODER_LINUX_VIRTIO_DRIVER_ENABLED
3618 (void)system("chmod 777 /dev/block/vd* 2>/dev/null"); // NOLINT(cert-env33-c,concurrency-mt-unsafe) - init-time only, no user input
3619#endif
3620#elif defined(_ANDROID)
3621 (void)system("chmod -R 777 /dev/shm/"); // NOLINT(cert-env33-c,concurrency-mt-unsafe) - init-time only, no user input
3622 (void)system("chmod 777 /dev/block/nvme* 2>/dev/null"); // NOLINT(cert-env33-c,concurrency-mt-unsafe) - init-time only, no user input
3623 (void)system("chmod 777 /dev/nvme* 2>/dev/null"); // NOLINT(cert-env33-c,concurrency-mt-unsafe) - init-time only, no user input
3624 property_set("ni_rsrc_init_completed", "yes");
3625#endif
3626
3627END:
3628 if(checkInterval && previous_detail_data)
3629 {
3630 free(previous_detail_data);
3631 }
3633 ni_rsrc_free_device_pool(p_device_pool);
3634 free(p_xCtxt);
3635 return ret;
3636}
#define LOG_TAG
int main()
Definition client.cpp:51
#define NI_XCODER_REVISION_API_MAJOR_VER_IDX
Definition ni_defs.h:99
#define NI_MAX_DEVICE_CNT
Definition ni_defs.h:235
#define END
Definition ni_defs.h:338
#define NI_XCODER_REVISION
Definition ni_defs.h:98
#define LIBXCODER_API_VERSION
Definition ni_defs.h:115
#define NI_MAX_DEVICE_NAME_LEN
Definition ni_defs.h:236
#define NI_MAX_CONTEXTS_PER_HW_INSTANCE
Definition ni_defs.h:248
ni_device_type_t
Definition ni_defs.h:356
@ NI_DEVICE_TYPE_SCALER
Definition ni_defs.h:362
@ NI_DEVICE_TYPE_AI
Definition ni_defs.h:363
@ NI_DEVICE_TYPE_DECODER
Definition ni_defs.h:360
@ NI_DEVICE_TYPE_UPLOAD
Definition ni_defs.h:367
@ NI_DEVICE_TYPE_ENCODER
Definition ni_defs.h:361
@ NI_DEVICE_TYPE_XCODER_MAX
Definition ni_defs.h:364
#define NI_ERRNO
Definition ni_defs.h:229
#define GET_XCODER_DEVICE_TYPE(t)
Definition ni_defs.h:434
#define LRETURN
Definition ni_defs.h:337
ni_retcode_t
Definition ni_defs.h:447
@ NI_RETCODE_SUCCESS
Definition ni_defs.h:448
@ NI_RETCODE_ERROR_RESOURCE_UNAVAILABLE
Definition ni_defs.h:455
#define IS_XCODER_DEVICE_TYPE(t)
Definition ni_defs.h:431
ni_retcode_t ni_query_nvme_status(ni_session_context_t *p_ctx, ni_load_query_t *p_load_query)
Query NVMe load from the device.
ni_retcode_t ni_device_alloc_and_get_fw_log_artifacts(ni_session_context_t *p_ctx, bool gen_artifacts_file)
Read log artifacts from the device and save to disk.
ni_retcode_t ni_device_capability_query2(ni_device_handle_t device_handle, ni_device_capability_t *p_cap, bool device_in_ctxt)
Query device and return device capability structure This function had replaced ni_device_capability_q...
ni_retcode_t ni_device_session_query(ni_session_context_t *p_ctx, ni_device_type_t device_type)
Query session data from the device - If device_type is valid, will query session data from specified ...
ni_session_context_t * ni_device_session_context_alloc_init(void)
Allocate and initialize a new ni_session_context_t struct.
ni_retcode_t ni_device_session_query_detail_v1(ni_session_context_t *p_ctx, ni_device_type_t device_type, ni_instance_mgr_detail_status_v1_t *detail_data)
Query detail session data from the device - If device_type is valid, will query session data from spe...
ni_retcode_t ni_query_vf_ns_id(ni_device_handle_t device_handle, ni_device_vf_ns_id_t *p_dev_ns_vf, uint8_t fw_rev[])
Query VF and NS id from device.
ni_retcode_t ni_device_session_query_detail(ni_session_context_t *p_ctx, ni_device_type_t device_type, ni_instance_mgr_detail_status_t *detail_data)
Query detail session data from the device - If device_type is valid, will query session data from spe...
void ni_device_close(ni_device_handle_t device_handle)
Close device and release resources.
ni_retcode_t ni_query_qos_info(ni_device_handle_t device_handle, ni_qos_header_info_log_page_t *p_dev_qos_header, uint8_t fw_rev[])
Query QoS information for the device.
ni_retcode_t ni_device_alloc_and_get_firmware_logs(ni_session_context_t *p_ctx, void **p_log_buffer, bool gen_log_file)
Allocate log buffer if needed and retrieve firmware logs from device.
ni_retcode_t ni_query_extra_info(ni_device_handle_t device_handle, ni_device_extra_info_t *p_dev_extra_info, uint8_t fw_rev[])
Query Extra Info from device.
ni_device_handle_t ni_device_open2(const char *p_dev, ni_device_mode_t mode)
Open device and return device device_handle if successful.
void ni_device_session_context_clear(ni_session_context_t *p_ctx)
Clear already allocated session context.
ni_retcode_t ni_query_qos_namespace_info(ni_device_handle_t device_handle, ni_qos_namespace_info_log_page_t *p_dev_qos_ns, uint8_t fw_rev[])
Query QoS information for a specific namespace.
Public definitions for operating NETINT video processing devices for video processing.
@ NI_DEVICE_READ_ONLY
struct _ni_instance_mgr_detail_status_v1 ni_instance_mgr_detail_status_v1_t
int optind
Definition ni_getopt.c:34
char * optarg
Definition ni_getopt.c:33
int getopt_long(int argc, char *argv[], const char *optstring, const struct option *longopts, int *longindex)
Definition ni_getopt.c:99
Implementation of getopt() and getopt_long() for Windows environment.
#define required_argument
Definition ni_getopt.h:86
ni_log_level_t arg_to_ni_log_level(const char *arg_str)
Convert terminal arg string to ni_log_level_t.
Definition ni_log.c:262
void ni_log_set_level(ni_log_level_t level)
Set ni_log_level.
Definition ni_log.c:202
void ni_log(ni_log_level_t level, const char *fmt,...)
print log message using ni_log_callback
Definition ni_log.c:183
#define NI_ERRNO_LEN
Definition ni_log.h:51
ni_log_level_t
Definition ni_log.h:58
@ NI_LOG_ERROR
Definition ni_log.h:62
@ NI_LOG_INFO
Definition ni_log.h:63
@ NI_LOG_INVALID
Definition ni_log.h:59
Quadraprobe definitions.
#define NI_SW_RELEASE_ID
#define NI_SW_RELEASE_TIME
int ni_rsrc_get_numa_node(char *device_name)
get linux numa_node
void ni_rsrc_free_device_context(ni_device_context_t *p_device_context)
Free previously allocated device context.
ni_retcode_t ni_rsrc_refresh(int should_match_rev)
Scan and refresh all resources on the host, taking into account hot-plugged and pulled out cards.
void ni_rsrc_free_device_pool(ni_device_pool_t *p_device_pool)
Free all resources taken by the device pool.
Public definitions for managing NETINT video processing devices.
LIB_API ni_device_context_t * ni_rsrc_get_device_context(ni_device_type_t type, int guid)
Allocates and returns a pointer to ni_device_context_t struct based on provided device_type and guid....
LIB_API ni_device_pool_t * ni_rsrc_get_device_pool(void)
Create and return the allocated ni_device_pool_t struct.
LIB_API int ni_rsrc_init(int should_match_rev, int timeout_seconds)
Initialize and create all resources required to work with NETINT NVMe transcoder devices....
outFormat
void print_json_final(ni_device_queue_t *p_device_queue, ni_session_context_t *p_session_context, int detail, ni_instance_mgr_detail_status_v1_t *detail_data_v1)
int compareInt32_t(const void *a, const void *b)
compare two int32_t for qsort
uint32_t * g_temp_load
Definition ni_rsrc_mon.c:59
void print_text(ni_device_queue_t *coders, ni_session_context_t *sessionCtxt, int detail, ni_instance_mgr_detail_status_v1_t *detail_data_v1, ni_instance_mgr_detail_status_v1_t(*previous_detail_data_p)[NI_MAX_DEVICE_CNT], int checkInterval)
char * get_pixel_format(ni_device_context_t *p_device_context, int index)
uint32_t * g_temp_pthroughput
Definition ni_rsrc_mon.c:61
#define DYN_STR_BUF_CHUNK_SIZE
#define NP_LOAD
Definition ni_rsrc_mon.c:51
uint32_t * g_temp_sharemem
Definition ni_rsrc_mon.c:62
#define MAX_DEVICE_NAME_SIZE
Definition ni_rsrc_mon.c:49
bool open_and_get_log(ni_device_context_t *p_device_context, ni_session_context_t *p_session_context, void **p_log_buffer, bool gen_log_file)
int remove_device_from_saved(ni_device_type_t device_type, int32_t module_id, ni_device_handle_t device_handle)
remove one device from stored device_handles
struct dyn_str_buf dyn_str_buf_t
uint32_t * g_temp_pload
Definition ni_rsrc_mon.c:60
#define TP_LOAD
Definition ni_rsrc_mon.c:52
int strcat_dyn_buf(dyn_str_buf_t *dyn_str_buf, const char *fmt,...)
Accumulate string data in a dynamically sized buffer. This is useful to separate error messages from ...
void print_full_text(ni_device_queue_t *p_device_queue, ni_session_context_t *p_session_context, int detail, ni_instance_mgr_detail_status_v1_t *detail_data_v1)
#define VIDEO_SLICE_TIME
Definition ni_rsrc_mon.c:57
@ FMT_JSON2
@ FMT_JSON
@ FMT_SIMPLE_TEXT
@ FMT_FULL_TEXT
@ FMT_EXTRA
@ FMT_JSON1
@ FMT_TEXT
bool open_and_query(ni_device_type_t device_type, ni_device_context_t *p_device_context, ni_session_context_t *p_session_context, char *device_name, int detail, ni_instance_mgr_detail_status_v1_t *detail_data_v1)
int argToI(char *numArray)
convert number from argv input to integer if safe
void clear_dyn_str_buf(dyn_str_buf_t *dyn_str_buf)
void print_json_detail(ni_device_queue_t *p_device_queue, ni_session_context_t *p_session_context, ni_instance_mgr_detail_status_v1_t *detail_data_v1)
void print_json1(ni_device_queue_t *p_device_queue, ni_session_context_t *p_session_context, int detail, ni_instance_mgr_detail_status_v1_t *detail_data_v1, int format)
ni_device_handle_t device_handles[NI_DEVICE_TYPE_XCODER_MAX][NI_MAX_DEVICE_CNT]
Definition ni_rsrc_mon.c:65
ni_rsrc_mon_card_error_t
Definition ni_rsrc_mon.c:67
@ NI_RSRC_MON_ERR_CRITICAL_TEMP
Definition ni_rsrc_mon.c:70
@ NI_RSRC_MON_ERR_WARN_TEMP
Definition ni_rsrc_mon.c:69
@ NI_RSRC_MON_ERR_PCIE_MISMATCH
Definition ni_rsrc_mon.c:71
@ NI_RSRC_MON_ERR_NONE
Definition ni_rsrc_mon.c:68
bool swap_encoder_and_uploader(ni_device_type_t *p_device_type, char *device_name)
#define NI_RSRC_MON_CARD_CACHE_MAX
void print_extra(ni_device_queue_t *p_device_queue, ni_session_context_t *p_session_context, int internal_call, int show_qos_info)
char * get_session_id(ni_device_context_t *p_device_context, int id)
#define PCIE_LOAD
Definition ni_rsrc_mon.c:53
void dump_fw_log(ni_device_queue_t *coders, ni_session_context_t *sessionCtxt, int devid)
Dump firmware logs and artifacts for one or all Quadra cards.
unsigned int get_modules(ni_device_type_t device_type, ni_device_queue_t *p_device_queue, char *device_name, int32_t **module_ids)
#define ABSOLUTE_TEMP_ZERO
Definition ni_rsrc_mon.c:50
void print_simple_text(ni_device_queue_t *p_device_queue, ni_session_context_t *p_session_context, int detail, ni_instance_mgr_detail_status_v1_t *detail_data_v1)
uint32_t g_xcoder_stop_process
Private definitions used by ni_rsrc_api.cpp for management of NETINT video processing devices.
void get_dev_pcie_addr(char *device_name, char *pcie, char *domain, char *slot, char *dev, char *func)
ni_retcode_t ni_strncpy(char *dest, size_t dmax, const char *src, size_t slen)
Definition ni_util.c:525
ni_retcode_t ni_strerror(char *dest, size_t dmax, int errnum)
Definition ni_util.c:663
ni_retcode_t ni_strcpy(char *dest, size_t dmax, const char *src)
Definition ni_util.c:460
void ni_usleep(int64_t usec)
Definition ni_util.c:366
struct tm * ni_localtime(struct tm *dest, const time_t *src)
Definition ni_util.c:1018
int ni_vsprintf(char *dest, const size_t dmax, const char *fmt, va_list args)
Definition ni_util.c:1054
int ni_sprintf(char *dest, size_t dmax, const char *fmt,...)
Definition ni_util.c:1077
ni_retcode_t ni_strtoi(const char *str, int32_t *out_val)
Safely convert a decimal string to a 32-bit integer with full validation. Trailing whitespace is tole...
Definition ni_util.c:2577
int ni_cmp_fw_api_ver(const char ver1[], const char ver2[])
Compare two 3 character strings containing a FW API version. Handle comparision when FW API version f...
Definition ni_util.c:4387
Utility definitions.
device capability type
ni_device_info_t * p_device_info
uint8_t serial_number[20]
char dev_name[NI_MAX_DEVICE_NAME_LEN]
uint8_t fw_rev[8]
char blk_name[NI_MAX_DEVICE_NAME_LEN]
uint8_t fl_ver_last_ran[8]
uint8_t fw_rev_nor_flash[8]
uint8_t fl_ver_nor_flash[8]
ni_device_queue_t * p_device_queue
Definition ni_rsrc_api.h:99
ni_lock_handle_t lock
Definition ni_rsrc_api.h:98
int32_t xcoders[NI_DEVICE_TYPE_XCODER_MAX][NI_MAX_DEVICE_CNT]
Definition ni_rsrc_api.h:70
uint32_t xcoder_cnt[NI_DEVICE_TYPE_XCODER_MAX]
Definition ni_rsrc_api.h:69
ni_instance_mgr_detail_status_append_t sInstDetailStatusAppend[NI_MAX_CONTEXTS_PER_HW_INSTANCE]
ni_instance_mgr_detail_status_t sInstDetailStatus[NI_MAX_CONTEXTS_PER_HW_INSTANCE]
uint32_t fw_share_mem_usage
uint32_t fw_model_load
uint32_t fw_p2p_mem_usage
uint32_t fw_video_shared_mem_usage
uint32_t pcie_throughput
uint32_t current_load
uint32_t total_contexts
uint32_t active_hwuploaders
uint32_t fw_video_mem_usage
ni_device_handle_t device_handle
ni_load_query_t load_query
ni_device_handle_t blk_io_handle
ni_overall_load_query_t overall_load_query
char * str_buf
const char * name
Definition ni_getopt.h:75