libxcoder  5.2.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 #ifdef _WIN32
40 #include "ni_getopt.h"
41 #else
42 #include <sys/stat.h>
43 #include <unistd.h>
44 #endif
45 
46 #define NI_NAMESPACE_SZ 32
47 
48 static void usage(void)
49 {
50  printf("usage: ni_rsrc_namespace [OPTION]\n"
51  "Provides NETINT QUADRA NVMe block device namespace IO operations.\n"
52  " -v show version.\n"
53  " -d the nvme block namespace. Only PF with nsid 1 allowed\n"
54  " -D the nvme block namespace for target over provision setting\n"
55  " -n the nvme block namespace count.\n"
56  " Default: 0\n"
57  " -p overprovision percent. Use exclusive of -n and -s and -q\n"
58  " -q namespace QoS setting. Use exclusive of -n and -s and -p\n"
59  " Default: 0 disabled.\n"
60  " 1 enable qos\n"
61  " 2 enable qos with overprovision\n"
62  " -s index of virtual PCIe functions in SR-IOV tied to the \n"
63  " physical PCIe function. '0' to select physical PCIe \n"
64  " function.\n"
65  " Eg. '1' to select the first virtual SR-IOV device tied \n"
66  " to the physical block device defined by '-d' option.\n"
67  " Default: 0\n"
68  " -h help info.\n");
69 }
70 
71 int send_config_ns_command(char* dev, int ns, int sr)
72 {
73  ni_device_handle_t handle = ni_device_open(dev, NULL);
74  ni_retcode_t retval;
75  if (handle == NI_INVALID_DEVICE_HANDLE)
76  {
77  fprintf(stderr, "ERROR: open %s failure for %s\n", dev,
78  strerror(NI_ERRNO));
79  exit(-1);
80  } else
81  {
82  printf("Succeed to open block namespace %s\n", dev);
83  }
84 
85  retval = ni_device_config_namespace_num(handle, ns, sr);
86  if (retval != NI_RETCODE_SUCCESS)
87  {
88  fprintf(stderr, "ERROR: Config setting failure for %s\n",
89  strerror(NI_ERRNO));
90  }
91  ni_device_close(handle);
92  return retval;
93 }
94 
95 int send_config_qos_mode(char *dev, int value)
96 {
97  ni_device_handle_t handle = ni_device_open(dev, NULL);
98  ni_retcode_t retval;
99  if (handle == NI_INVALID_DEVICE_HANDLE)
100  {
101  fprintf(stderr, "ERROR: open %s failure for %s\n", dev,
102  strerror(NI_ERRNO));
103  exit(-1);
104  } else
105  {
106  printf("Succeed to open block namespace %s\n", dev);
107  }
108 
109  retval = ni_device_config_qos(handle, value);
110  if (retval != NI_RETCODE_SUCCESS)
111  {
112  fprintf(stderr, "ERROR: Config setting failure for %s\n",
113  strerror(NI_ERRNO));
114  }
115  ni_device_close(handle);
116  return retval;
117 }
118 
119 int send_config_qos_op(char *dev, char *devt, int op)
120 {
121  ni_retcode_t retval;
122  ni_device_handle_t handle = ni_device_open(dev, NULL);
123  if (handle == NI_INVALID_DEVICE_HANDLE)
124  {
125  fprintf(stderr, "ERROR: open %s failure for %s\n", dev,
126  strerror(NI_ERRNO));
127  exit(-1);
128  } else
129  {
130  printf("Succeed to open block namespace %s\n", dev);
131  }
132  ni_device_handle_t handle_t = ni_device_open(devt, NULL);
133  if (handle_t == NI_INVALID_DEVICE_HANDLE)
134  {
135  fprintf(stderr, "ERROR: open %s failure for %s\n", devt,
136  strerror(NI_ERRNO));
137  ni_device_close(handle);
138  exit(-1);
139  } else
140  {
141  printf("Succeed to open block namespace %s\n", dev);
142  }
143 
144  retval = ni_device_config_qos_op(handle, handle_t, op);
145  if (retval != NI_RETCODE_SUCCESS)
146  {
147  fprintf(stderr, "ERROR: Config setting failure for %s\n",
148  strerror(NI_ERRNO));
149  }
150  ni_device_close(handle);
151  ni_device_close(handle_t);
152  return retval;
153 }
154 
155 int main(int argc, char *argv[])
156 {
157  ni_retcode_t retval;
158  int opt;
159  char device_namespace[NI_NAMESPACE_SZ] = {'\0'};
160  char device_namespace_OP[NI_NAMESPACE_SZ] = {'\0'};
161  int namespace_num = 1;
162  float over_provision_percent = -1;
163  int i32_over_provision_percent = 0;
164  int sriov_index = 0;
165  int qos_mode = -1;
166 #ifdef __linux__
167  struct stat sb;
168 #endif
169 
170  while ((opt = getopt(argc, argv, "d:D:n:p:q:s:hv")) != EOF)
171  {
172  switch (opt)
173  {
174  case 'h':
175  usage();
176  exit(0);
177  case 'v':
178  printf("Release ver: %s\n"
179  "API ver: %s\n"
180  "Date: %s\n"
181  "ID: %s\n",
184  exit(0);
185  case 'd':
186  strcpy(device_namespace, optarg);
187 #ifdef __linux__
188  if (lstat(device_namespace, &sb) != 0 ||
189  (sb.st_mode & S_IFMT) != S_IFBLK)
190  {
191  fprintf(stderr, "ERROR: Only block device is supported! "
192  "%s is not block device!\n", device_namespace);
193  exit(-1);
194  }
195 #endif
196  break;
197  case 'D':
198  strcpy(device_namespace_OP, optarg);
199  break;
200  case 'n':
201  // A maximum of 64 namespaces are supported for firmware
202  namespace_num = atoi(optarg);
203  if (namespace_num < 0 || namespace_num > NI_NAMESPACE_MAX_NUM)
204  {
205  fprintf(stderr, "ERROR: The number of namespace cannot "
206  "exceed %d\n", NI_NAMESPACE_MAX_NUM);
207  exit(-1);
208  }
209  break;
210  case 'p':
211  // set overprovision %
212  over_provision_percent = (float)atof(optarg);
213  if (over_provision_percent > 100 || over_provision_percent < 0)
214  {
215  fprintf(stderr, "ERROR: Overprovision percent cannot "
216  "exceed 100%% or become negative\n");
217  exit(-1);
218  }
219  break;
220  case 'q':
221  // 0 disabled, 1 enabled - no idle sharing
222  qos_mode = atoi(optarg);
223  if (qos_mode < QOS_MODE_DISABLED ||
224  qos_mode > QOS_MODE_ENABLED_SHARE)
225  {
226  fprintf(stderr,
227  "ERROR: QoS mode %d not supported\n",
228  qos_mode);
229  exit(-1);
230  }
231  break;
232  case 's':
233  sriov_index = atoi(optarg);
234  if (sriov_index < 0)
235  {
236  fprintf(stderr, "ERROR: Invalid SR-IOV device index: %d\n",
237  sriov_index);
238  exit(-1);
239  }
240  break;
241  default:
242  fprintf(stderr, "ERROR: Invalid option: %c\n", opt);
243  exit(-1);
244  }
245  }
246 
247  if (device_namespace[0] == '\0')
248  {
249  fprintf(stderr, "ERROR: missing argument for -d\n");
250  exit(-1);
251  }
252  if (strlen(device_namespace) < 3 ||
253  strcmp(device_namespace + strlen(device_namespace) - 2, "n1") != 0)
254  {
255  fprintf(stderr, "ERROR: Invalid device name %s, need n1, no vf\n", device_namespace);
256  exit(-1);
257  }
258 
259  if (qos_mode != -1)
260  {
261  if (namespace_num != 1 || sriov_index || over_provision_percent != -1)
262  {
263  fprintf(stderr,
264  "ERROR: QoS mode -q mutually exclusive of namespace and "
265  "SR-IOV\n");
266  exit(-1);
267  }
268  retval = send_config_qos_mode(device_namespace, qos_mode);
269  if (retval == NI_RETCODE_SUCCESS)
270  {
271  printf("QoS mode setting succeed with number of %d\n", qos_mode);
272  }
273  return retval;
274  }
275 
276  if (over_provision_percent != -1)
277  {
278  if (device_namespace_OP[0] == '\0')
279  {
280  fprintf(stderr, "ERROR: missing argument for -D\n");
281  exit(-1);
282  }
283  if (namespace_num != 1 || sriov_index || qos_mode != -1)
284  {
285  fprintf(stderr,
286  "ERROR: Overprovision percent -p mutually exclusive of "
287  "namespace and SR-IOV and QOS mode\n");
288  exit(-1);
289  }
290  memcpy(&i32_over_provision_percent, &over_provision_percent, sizeof(int32_t));
291  retval = send_config_qos_op(device_namespace, device_namespace_OP,
292  i32_over_provision_percent);
293  if (retval == NI_RETCODE_SUCCESS)
294  {
295  printf("Overprovision percent setting succeed with number of %f\n",
296  over_provision_percent);
297  }
298  return retval;
299  }
300 
301  retval = send_config_ns_command(device_namespace, namespace_num, sriov_index);
302  if (retval == NI_RETCODE_SUCCESS)
303  {
304  printf("Namespace setting succeed with number of %d and SR-IOV "
305  "index %d\n",
306  namespace_num, sriov_index);
307  }
308  return retval;
309 }
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:2080
ni_device_close
void ni_device_close(ni_device_handle_t device_handle)
Close device and release resources.
Definition: ni_device_api.c:503
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:216
NI_RETCODE_SUCCESS
@ NI_RETCODE_SUCCESS
Definition: ni_defs.h:427
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:360
NI_XCODER_REVISION
#define NI_XCODER_REVISION
Definition: ni_defs.h:95
ni_retcode_t
ni_retcode_t
Definition: ni_defs.h:425
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:2037
atof
#define atof(p_str)
Definition: ni_device_api.c:7179
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:2058
optarg
char * optarg
Definition: ni_getopt.c:33
QOS_MODE_ENABLED_SHARE
@ QOS_MODE_ENABLED_SHARE
Definition: ni_device_api.h:228
NI_ERRNO
#define NI_ERRNO
Definition: ni_defs.h:217
main
int main(int argc, char *argv[])
Definition: ni_rsrc_namespace.c:155
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:71
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:226
atoi
#define atoi(p_str)
Definition: ni_device_api.c:7178
LIBXCODER_API_VERSION
#define LIBXCODER_API_VERSION
Definition: ni_defs.h:112
NI_NAMESPACE_SZ
#define NI_NAMESPACE_SZ
Definition: ni_rsrc_namespace.c:46
ni_device_api.h
Public definitions for operating NETINT video processing devices for video processing.
send_config_qos_mode
int send_config_qos_mode(char *dev, int value)
Definition: ni_rsrc_namespace.c:95
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:119