libxcoder  5.4.0
ni_rsrc_namespace.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_namespace.c
24  *
25  * \brief This utility aims to set the NVMe namespace number for a Quadra NVMe
26  * block device. It can operate on physical devices (PCIe physical
27  * function) or virtual devices (PCIe virtual function). Before setting
28  * namespace number, use SR-IOV to create the PCIe virtual function.
29  * Note that only block device name is accepted for this utility.
30  *
31  * To effect the name space change, reload the NVMe driver:
32  * sudo modprobe -r nvme
33  * sudo modprobe nvme
34  * sudo nvme list #check the result with nvme list
35  ******************************************************************************/
36 
37 #include "ni_device_api.h"
38 #include "ni_nvme.h"
39 #include "ni_util.h"
40 #ifdef _WIN32
41 #include "ni_getopt.h"
42 #else
43 #include <sys/stat.h>
44 #include <unistd.h>
45 #endif
46 
47 #define NI_NAMESPACE_SZ 32
48 
49 static void usage(void)
50 {
51  printf("usage: ni_rsrc_namespace [OPTION]\n"
52  "Provides NETINT QUADRA NVMe block device namespace IO operations.\n"
53  " -v show version.\n"
54  " -d the nvme block namespace. Only PF with nsid 1 allowed\n"
55  " -D the nvme block namespace for target over provision setting\n"
56  " -n the nvme block namespace count.\n"
57  " Default: 0\n"
58  " -p overprovision percent. Use exclusive of -n and -s and -q\n"
59  " -q namespace QoS setting. Use exclusive of -n and -s and -p\n"
60  " Default: 0 disabled.\n"
61  " 1 enable qos\n"
62  " 2 enable qos with overprovision\n"
63  " -s index of virtual PCIe functions in SR-IOV tied to the \n"
64  " physical PCIe function. '0' to select physical PCIe \n"
65  " function.\n"
66  " Eg. '1' to select the first virtual SR-IOV device tied \n"
67  " to the physical block device defined by '-d' option.\n"
68  " Default: 0\n"
69  " -c Persist the configuration of the namespace\n"
70  " -h help info.\n");
71 }
72 
73 int send_config_ns_command(char* dev, int ns, int sr)
74 {
75  ni_device_handle_t handle = ni_device_open(dev, NULL);
76  ni_retcode_t retval;
77  char errmsg[NI_ERRNO_LEN] = {0};
78  if (handle == NI_INVALID_DEVICE_HANDLE)
79  {
81  fprintf(stderr, "ERROR: open %s failure for %s\n", dev,
82  errmsg);
83  exit(-1);
84  } else
85  {
86  printf("Succeed to open block namespace %s\n", dev);
87  }
88 
89  retval = ni_device_config_namespace_num(handle, ns, sr);
90  if (retval != NI_RETCODE_SUCCESS)
91  {
93  fprintf(stderr, "ERROR: Config setting failure for %s\n",
94  errmsg);
95  }
96  ni_device_close(handle);
97  return retval;
98 }
99 
100 int send_config_qos_mode(char *dev, int value)
101 {
102  ni_device_handle_t handle = ni_device_open(dev, NULL);
103  ni_retcode_t retval;
104  char errmsg[NI_ERRNO_LEN] = {0};
105  if (handle == NI_INVALID_DEVICE_HANDLE)
106  {
108  fprintf(stderr, "ERROR: open %s failure for %s\n", dev,
109  errmsg);
110  exit(-1);
111  } else
112  {
113  printf("Succeed to open block namespace %s\n", dev);
114  }
115 
116  retval = ni_device_config_qos(handle, value);
117  if (retval != NI_RETCODE_SUCCESS)
118  {
120  fprintf(stderr, "ERROR: Config setting failure for %s\n",
121  errmsg);
122  }
123  ni_device_close(handle);
124  return retval;
125 }
126 
127 int send_config_qos_op(char *dev, char *devt, int op)
128 {
129  ni_retcode_t retval;
130  ni_device_handle_t handle = ni_device_open(dev, NULL);
131  char errmsg[NI_ERRNO_LEN] = {0};
132  if (handle == NI_INVALID_DEVICE_HANDLE)
133  {
135  fprintf(stderr, "ERROR: open %s failure for %s\n", dev,
136  errmsg);
137  exit(-1);
138  } else
139  {
140  printf("Succeed to open block namespace %s\n", dev);
141  }
142  ni_device_handle_t handle_t = ni_device_open(devt, NULL);
143  if (handle_t == NI_INVALID_DEVICE_HANDLE)
144  {
146  fprintf(stderr, "ERROR: open %s failure for %s\n", devt,
147  errmsg);
148  ni_device_close(handle);
149  exit(-1);
150  } else
151  {
152  printf("Succeed to open block namespace %s\n", dev);
153  }
154 
155  retval = ni_device_config_qos_op(handle, handle_t, op);
156  if (retval != NI_RETCODE_SUCCESS)
157  {
159  fprintf(stderr, "ERROR: Config setting failure for %s\n",
160  errmsg);
161  }
162  ni_device_close(handle);
163  ni_device_close(handle_t);
164  return retval;
165 }
166 
167 int main(int argc, char *argv[])
168 {
169  ni_retcode_t retval;
170  int opt;
171  char device_namespace[NI_NAMESPACE_SZ] = {'\0'};
172  char device_namespace_OP[NI_NAMESPACE_SZ] = {'\0'};
173  int namespace_num = 1;
174  float over_provision_percent = -1;
175  int i32_over_provision_percent = 0;
176  int sriov_index = 0;
177  int qos_mode = -1;
178  int persistence = 0;
179 #ifdef __linux__
180  struct stat sb;
181 #endif
182 
183  while ((opt = getopt(argc, argv, "d:D:n:p:q:s:chv")) != EOF)
184  {
185  switch (opt)
186  {
187  case 'h':
188  usage();
189  exit(0);
190  case 'v':
191  printf("Release ver: %s\n"
192  "API ver: %s\n"
193  "Date: %s\n"
194  "ID: %s\n",
197  exit(0);
198  case 'd':
199  ni_strcpy(device_namespace, NI_NAMESPACE_SZ, optarg);
200 #ifdef __linux__
201  if (lstat(device_namespace, &sb) != 0 ||
202  (sb.st_mode & S_IFMT) != S_IFBLK)
203  {
204  fprintf(stderr, "ERROR: Only block device is supported! "
205  "%s is not block device!\n", device_namespace);
206  exit(-1);
207  }
208 #endif
209  break;
210  case 'D':
211  ni_strcpy(device_namespace_OP, NI_NAMESPACE_SZ, optarg);
212  break;
213  case 'n':
214  // A maximum of 64 namespaces are supported for firmware
215  namespace_num = atoi(optarg);
216  if (namespace_num < 0 || namespace_num > NI_NAMESPACE_MAX_NUM)
217  {
218  fprintf(stderr, "ERROR: The number of namespace cannot "
219  "exceed %d\n", NI_NAMESPACE_MAX_NUM);
220  exit(-1);
221  }
222  break;
223  case 'p':
224  // set overprovision %
225  over_provision_percent = (float)atof(optarg);
226  if (over_provision_percent > 100 || over_provision_percent < 0)
227  {
228  fprintf(stderr, "ERROR: Overprovision percent cannot "
229  "exceed 100%% or become negative\n");
230  exit(-1);
231  }
232  break;
233  case 'q':
234  // 0 disabled, 1 enabled - no idle sharing
235  qos_mode = atoi(optarg);
236  if (qos_mode < QOS_MODE_DISABLED ||
237  qos_mode > QOS_MODE_ENABLED_SHARE)
238  {
239  fprintf(stderr,
240  "ERROR: QoS mode %d not supported\n",
241  qos_mode);
242  exit(-1);
243  }
244  break;
245  case 's':
246  sriov_index = atoi(optarg);
247  if (sriov_index < 0)
248  {
249  fprintf(stderr, "ERROR: Invalid SR-IOV device index: %d\n",
250  sriov_index);
251  exit(-1);
252  }
253  break;
254  case 'c':
255  persistence = 1;
256  break;
257  default:
258  fprintf(stderr, "ERROR: Invalid option: %c\n", opt);
259  exit(-1);
260  }
261  }
262 
263  if (device_namespace[0] == '\0')
264  {
265  fprintf(stderr, "ERROR: missing argument for -d\n");
266  exit(-1);
267  }
268  if (strlen(device_namespace) < 3 ||
269  strcmp(device_namespace + strlen(device_namespace) - 2, "n1") != 0)
270  {
271  fprintf(stderr, "ERROR: Invalid device name %s, need n1, no vf\n", device_namespace);
272  exit(-1);
273  }
274 
275  if (qos_mode != -1)
276  {
277  if (namespace_num != 1 || sriov_index || over_provision_percent != -1)
278  {
279  fprintf(stderr,
280  "ERROR: QoS mode -q mutually exclusive of namespace and "
281  "SR-IOV\n");
282  exit(-1);
283  }
284  retval = send_config_qos_mode(device_namespace, qos_mode);
285  if (retval == NI_RETCODE_SUCCESS)
286  {
287  printf("QoS mode setting succeed with number of %d\n", qos_mode);
288  }
289  return retval;
290  }
291 
292  if (over_provision_percent != -1)
293  {
294  if (device_namespace_OP[0] == '\0')
295  {
296  fprintf(stderr, "ERROR: missing argument for -D\n");
297  exit(-1);
298  }
299  if (namespace_num != 1 || sriov_index || qos_mode != -1)
300  {
301  fprintf(stderr,
302  "ERROR: Overprovision percent -p mutually exclusive of "
303  "namespace and SR-IOV and QOS mode\n");
304  exit(-1);
305  }
306  memcpy(&i32_over_provision_percent, &over_provision_percent, sizeof(int32_t));
307  retval = send_config_qos_op(device_namespace, device_namespace_OP,
308  i32_over_provision_percent);
309  if (retval == NI_RETCODE_SUCCESS)
310  {
311  printf("Overprovision percent setting succeed with number of %f\n",
312  over_provision_percent);
313  }
314  return retval;
315  }
316 
317  if (persistence) namespace_num += 256;
318  retval = send_config_ns_command(device_namespace, namespace_num, sriov_index);
319  if (retval == NI_RETCODE_SUCCESS)
320  {
321  printf("Namespace setting succeed with number of %d and SR-IOV "
322  "index %d\n",
323  namespace_num, sriov_index);
324  }
325  return retval;
326 }
ni_strerror
ni_retcode_t ni_strerror(char *dest, size_t dmax, int errnum)
Definition: ni_util.c:652
ni_device_config_qos_op
ni_retcode_t ni_device_config_qos_op(ni_device_handle_t device_handle, ni_device_handle_t device_handle_t, uint32_t over_provision)
Send qos over provisioning mode to target namespace with specified logic block address.
Definition: ni_device_api.c:2092
ni_device_close
void ni_device_close(ni_device_handle_t device_handle)
Close device and release resources.
Definition: ni_device_api.c:511
ni_strcpy
ni_retcode_t ni_strcpy(char *dest, size_t dmax, const char *src)
Definition: ni_util.c:449
NI_SW_RELEASE_ID
#define NI_SW_RELEASE_ID
Definition: ni_release_info.h:29
NI_NAMESPACE_MAX_NUM
#define NI_NAMESPACE_MAX_NUM
Definition: ni_device_api.h:219
NI_RETCODE_SUCCESS
@ NI_RETCODE_SUCCESS
Definition: ni_defs.h:441
ni_device_open
ni_device_handle_t ni_device_open(const char *p_dev, uint32_t *p_max_io_size_out)
Open device and return device device_handle if successful.
Definition: ni_device_api.c:366
NI_XCODER_REVISION
#define NI_XCODER_REVISION
Definition: ni_defs.h:98
ni_retcode_t
ni_retcode_t
Definition: ni_defs.h:439
NI_ERRNO_LEN
#define NI_ERRNO_LEN
Definition: ni_log.h:51
ni_device_config_namespace_num
ni_retcode_t ni_device_config_namespace_num(ni_device_handle_t device_handle, uint32_t namespace_num, uint32_t sriov_index)
Send namespace num and SRIOv index to the device with specified logic block address.
Definition: ni_device_api.c:2049
atof
#define atof(p_str)
Definition: ni_device_api.c:7339
NI_SW_RELEASE_TIME
#define NI_SW_RELEASE_TIME
Definition: ni_release_info.h:28
ni_device_config_qos
ni_retcode_t ni_device_config_qos(ni_device_handle_t device_handle, uint32_t mode)
Send qos mode to the device with specified logic block address.
Definition: ni_device_api.c:2070
optarg
char * optarg
Definition: ni_getopt.c:33
QOS_MODE_ENABLED_SHARE
@ QOS_MODE_ENABLED_SHARE
Definition: ni_device_api.h:231
NI_ERRNO
#define NI_ERRNO
Definition: ni_defs.h:229
main
int main(int argc, char *argv[])
Definition: ni_rsrc_namespace.c:167
getopt
int getopt(int argc, char *argv[], const char *optstring)
Definition: ni_getopt.c:38
send_config_ns_command
int send_config_ns_command(char *dev, int ns, int sr)
Definition: ni_rsrc_namespace.c:73
ni_nvme.h
Private definitions for interfacing with NETINT video processing devices over NVMe.
QOS_MODE_DISABLED
@ QOS_MODE_DISABLED
Definition: ni_device_api.h:229
atoi
#define atoi(p_str)
Definition: ni_device_api.c:7338
LIBXCODER_API_VERSION
#define LIBXCODER_API_VERSION
Definition: ni_defs.h:115
NI_NAMESPACE_SZ
#define NI_NAMESPACE_SZ
Definition: ni_rsrc_namespace.c:47
ni_device_api.h
Public definitions for operating NETINT video processing devices for video processing.
ni_util.h
Utility definitions.
send_config_qos_mode
int send_config_qos_mode(char *dev, int value)
Definition: ni_rsrc_namespace.c:100
ni_getopt.h
Implementation of getopt() and getopt_long() for Windows environment.
send_config_qos_op
int send_config_qos_op(char *dev, char *devt, int op)
Definition: ni_rsrc_namespace.c:127