eal: fix evaluation of log level option
[dpdk.git] / lib / librte_eal / windows / eal.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019 Intel Corporation
3  */
4
5 #include <fcntl.h>
6 #include <io.h>
7 #include <share.h>
8 #include <sys/stat.h>
9
10 #include <rte_debug.h>
11 #include <rte_eal.h>
12 #include <eal_memcfg.h>
13 #include <rte_errno.h>
14 #include <rte_lcore.h>
15 #include <eal_thread.h>
16 #include <eal_internal_cfg.h>
17 #include <eal_filesystem.h>
18 #include <eal_options.h>
19 #include <eal_private.h>
20 #include <rte_service_component.h>
21 #include <rte_vfio.h>
22
23 #include "eal_hugepages.h"
24 #include "eal_trace.h"
25 #include "eal_log.h"
26 #include "eal_windows.h"
27
28 #define MEMSIZE_IF_NO_HUGE_PAGE (64ULL * 1024ULL * 1024ULL)
29
30 /* define fd variable here, because file needs to be kept open for the
31  * duration of the program, as we hold a write lock on it in the primary proc
32  */
33 static int mem_cfg_fd = -1;
34
35 /* internal configuration (per-core) */
36 struct lcore_config lcore_config[RTE_MAX_LCORE];
37
38 /* Detect if we are a primary or a secondary process */
39 enum rte_proc_type_t
40 eal_proc_type_detect(void)
41 {
42         enum rte_proc_type_t ptype = RTE_PROC_PRIMARY;
43         const char *pathname = eal_runtime_config_path();
44         const struct rte_config *config = rte_eal_get_configuration();
45
46         /* if we can open the file but not get a write-lock we are a secondary
47          * process. NOTE: if we get a file handle back, we keep that open
48          * and don't close it to prevent a race condition between multiple opens
49          */
50         errno_t err = _sopen_s(&mem_cfg_fd, pathname,
51                 _O_RDWR, _SH_DENYNO, _S_IREAD | _S_IWRITE);
52         if (err == 0) {
53                 OVERLAPPED soverlapped = { 0 };
54                 soverlapped.Offset = sizeof(*config->mem_config);
55                 soverlapped.OffsetHigh = 0;
56
57                 HANDLE hwinfilehandle = (HANDLE)_get_osfhandle(mem_cfg_fd);
58
59                 if (!LockFileEx(hwinfilehandle,
60                         LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0,
61                         sizeof(*config->mem_config), 0, &soverlapped))
62                         ptype = RTE_PROC_SECONDARY;
63         }
64
65         RTE_LOG(INFO, EAL, "Auto-detected process type: %s\n",
66                 ptype == RTE_PROC_PRIMARY ? "PRIMARY" : "SECONDARY");
67
68         return ptype;
69 }
70
71 bool
72 rte_mp_disable(void)
73 {
74         return true;
75 }
76
77 /* display usage */
78 static void
79 eal_usage(const char *prgname)
80 {
81         rte_usage_hook_t hook = eal_get_application_usage_hook();
82
83         printf("\nUsage: %s ", prgname);
84         eal_common_usage();
85         /* Allow the application to print its usage message too
86          * if hook is set
87          */
88         if (hook) {
89                 printf("===== Application Usage =====\n\n");
90                 (hook)(prgname);
91         }
92 }
93
94 /* Parse the arguments for --log-level only */
95 static void
96 eal_log_level_parse(int argc, char **argv)
97 {
98         int opt;
99         char **argvopt;
100         int option_index;
101         struct internal_config *internal_conf =
102                 eal_get_internal_configuration();
103
104         argvopt = argv;
105
106         eal_reset_internal_config(internal_conf);
107
108         while ((opt = getopt_long(argc, argvopt, eal_short_options,
109                 eal_long_options, &option_index)) != EOF) {
110
111                 int ret;
112
113                 /* getopt is not happy, stop right now */
114                 if (opt == '?')
115                         break;
116
117                 ret = (opt == OPT_LOG_LEVEL_NUM) ?
118                         eal_parse_common_option(opt, optarg,
119                                 internal_conf) : 0;
120
121                 /* common parser is not happy */
122                 if (ret < 0)
123                         break;
124         }
125
126         optind = 0; /* reset getopt lib */
127 }
128
129 /* Parse the argument given in the command line of the application */
130 static int
131 eal_parse_args(int argc, char **argv)
132 {
133         int opt, ret;
134         char **argvopt;
135         int option_index;
136         char *prgname = argv[0];
137         struct internal_config *internal_conf =
138                 eal_get_internal_configuration();
139
140         argvopt = argv;
141
142         while ((opt = getopt_long(argc, argvopt, eal_short_options,
143                 eal_long_options, &option_index)) != EOF) {
144
145                 int ret;
146
147                 /* getopt is not happy, stop right now */
148                 if (opt == '?') {
149                         eal_usage(prgname);
150                         return -1;
151                 }
152
153                 /* eal_log_level_parse() already handled this option */
154                 if (opt == OPT_LOG_LEVEL_NUM)
155                         continue;
156
157                 ret = eal_parse_common_option(opt, optarg, internal_conf);
158                 /* common parser is not happy */
159                 if (ret < 0) {
160                         eal_usage(prgname);
161                         return -1;
162                 }
163                 /* common parser handled this option */
164                 if (ret == 0)
165                         continue;
166
167                 switch (opt) {
168                 case 'h':
169                         eal_usage(prgname);
170                         exit(EXIT_SUCCESS);
171                 default:
172                         if (opt < OPT_LONG_MIN_NUM && isprint(opt)) {
173                                 RTE_LOG(ERR, EAL, "Option %c is not supported "
174                                         "on Windows\n", opt);
175                         } else if (opt >= OPT_LONG_MIN_NUM &&
176                                 opt < OPT_LONG_MAX_NUM) {
177                                 RTE_LOG(ERR, EAL, "Option %s is not supported "
178                                         "on Windows\n",
179                                         eal_long_options[option_index].name);
180                         } else {
181                                 RTE_LOG(ERR, EAL, "Option %d is not supported "
182                                         "on Windows\n", opt);
183                         }
184                         eal_usage(prgname);
185                         return -1;
186                 }
187         }
188
189         if (eal_adjust_config(internal_conf) != 0)
190                 return -1;
191
192         /* sanity checks */
193         if (eal_check_common_options(internal_conf) != 0) {
194                 eal_usage(prgname);
195                 return -1;
196         }
197
198         if (optind >= 0)
199                 argv[optind - 1] = prgname;
200         ret = optind - 1;
201         optind = 0; /* reset getopt lib */
202         return ret;
203 }
204
205 static int
206 sync_func(void *arg __rte_unused)
207 {
208         return 0;
209 }
210
211 static void
212 rte_eal_init_alert(const char *msg)
213 {
214         fprintf(stderr, "EAL: FATAL: %s\n", msg);
215         RTE_LOG(ERR, EAL, "%s\n", msg);
216 }
217
218 /* Stubs to enable EAL trace point compilation
219  * until eal_common_trace.c can be compiled.
220  */
221
222 RTE_DEFINE_PER_LCORE(volatile int, trace_point_sz);
223 RTE_DEFINE_PER_LCORE(void *, trace_mem);
224
225 void
226 __rte_trace_mem_per_thread_alloc(void)
227 {
228 }
229
230 void
231 trace_mem_per_thread_free(void)
232 {
233 }
234
235 void
236 __rte_trace_point_emit_field(size_t sz, const char *field,
237         const char *type)
238 {
239         RTE_SET_USED(sz);
240         RTE_SET_USED(field);
241         RTE_SET_USED(type);
242 }
243
244 int
245 __rte_trace_point_register(rte_trace_point_t *trace, const char *name,
246         void (*register_fn)(void))
247 {
248         RTE_SET_USED(trace);
249         RTE_SET_USED(name);
250         RTE_SET_USED(register_fn);
251         return -ENOTSUP;
252 }
253
254 int
255 rte_eal_cleanup(void)
256 {
257         struct internal_config *internal_conf =
258                 eal_get_internal_configuration();
259         /* after this point, any DPDK pointers will become dangling */
260         rte_eal_memory_detach();
261         eal_cleanup_config(internal_conf);
262         return 0;
263 }
264
265 /* Launch threads, called at application init(). */
266 int
267 rte_eal_init(int argc, char **argv)
268 {
269         int i, fctret, bscan;
270         const struct rte_config *config = rte_eal_get_configuration();
271         struct internal_config *internal_conf =
272                 eal_get_internal_configuration();
273         int ret;
274
275         eal_log_init(NULL, 0);
276
277         eal_log_level_parse(argc, argv);
278
279         if (eal_create_cpu_map() < 0) {
280                 rte_eal_init_alert("Cannot discover CPU and NUMA.");
281                 /* rte_errno is set */
282                 return -1;
283         }
284
285         if (rte_eal_cpu_init() < 0) {
286                 rte_eal_init_alert("Cannot detect lcores.");
287                 rte_errno = ENOTSUP;
288                 return -1;
289         }
290
291         fctret = eal_parse_args(argc, argv);
292         if (fctret < 0)
293                 exit(1);
294
295         if (eal_option_device_parse()) {
296                 rte_errno = ENODEV;
297                 return -1;
298         }
299
300         /* Prevent creation of shared memory files. */
301         if (internal_conf->in_memory == 0) {
302                 RTE_LOG(WARNING, EAL, "Multi-process support is requested, "
303                         "but not available.\n");
304                 internal_conf->in_memory = 1;
305                 internal_conf->no_shconf = 1;
306         }
307
308         if (!internal_conf->no_hugetlbfs && (eal_hugepage_info_init() < 0)) {
309                 rte_eal_init_alert("Cannot get hugepage information");
310                 rte_errno = EACCES;
311                 return -1;
312         }
313
314         if (internal_conf->memory == 0 && !internal_conf->force_sockets) {
315                 if (internal_conf->no_hugetlbfs)
316                         internal_conf->memory = MEMSIZE_IF_NO_HUGE_PAGE;
317         }
318
319         if (eal_mem_win32api_init() < 0) {
320                 rte_eal_init_alert("Cannot access Win32 memory management");
321                 rte_errno = ENOTSUP;
322                 return -1;
323         }
324
325         if (eal_mem_virt2iova_init() < 0) {
326                 /* Non-fatal error if physical addresses are not required. */
327                 RTE_LOG(WARNING, EAL, "Cannot access virt2phys driver, "
328                         "PA will not be available\n");
329         }
330
331         if (rte_eal_memzone_init() < 0) {
332                 rte_eal_init_alert("Cannot init memzone");
333                 rte_errno = ENODEV;
334                 return -1;
335         }
336
337         if (rte_eal_memory_init() < 0) {
338                 rte_eal_init_alert("Cannot init memory");
339                 rte_errno = ENOMEM;
340                 return -1;
341         }
342
343         if (rte_eal_malloc_heap_init() < 0) {
344                 rte_eal_init_alert("Cannot init malloc heap");
345                 rte_errno = ENODEV;
346                 return -1;
347         }
348
349         if (rte_eal_tailqs_init() < 0) {
350                 rte_eal_init_alert("Cannot init tail queues for objects");
351                 rte_errno = EFAULT;
352                 return -1;
353         }
354
355         if (rte_eal_intr_init() < 0) {
356                 rte_eal_init_alert("Cannot init interrupt-handling thread");
357                 return -1;
358         }
359
360         if (rte_eal_timer_init() < 0) {
361                 rte_eal_init_alert("Cannot init TSC timer");
362                 rte_errno = EFAULT;
363                 return -1;
364         }
365
366         __rte_thread_init(config->main_lcore,
367                 &lcore_config[config->main_lcore].cpuset);
368
369         bscan = rte_bus_scan();
370         if (bscan < 0) {
371                 rte_eal_init_alert("Cannot init PCI");
372                 rte_errno = ENODEV;
373                 return -1;
374         }
375
376         RTE_LCORE_FOREACH_WORKER(i) {
377
378                 /*
379                  * create communication pipes between main thread
380                  * and children
381                  */
382                 if (_pipe(lcore_config[i].pipe_main2worker,
383                         sizeof(char), _O_BINARY) < 0)
384                         rte_panic("Cannot create pipe\n");
385                 if (_pipe(lcore_config[i].pipe_worker2main,
386                         sizeof(char), _O_BINARY) < 0)
387                         rte_panic("Cannot create pipe\n");
388
389                 lcore_config[i].state = WAIT;
390
391                 /* create a thread for each lcore */
392                 if (eal_thread_create(&lcore_config[i].thread_id) != 0)
393                         rte_panic("Cannot create thread\n");
394         }
395
396         /* Initialize services so drivers can register services during probe. */
397         ret = rte_service_init();
398         if (ret) {
399                 rte_eal_init_alert("rte_service_init() failed");
400                 rte_errno = -ret;
401                 return -1;
402         }
403
404         if (rte_bus_probe()) {
405                 rte_eal_init_alert("Cannot probe devices");
406                 rte_errno = ENOTSUP;
407                 return -1;
408         }
409
410         /*
411          * Launch a dummy function on all worker lcores, so that main lcore
412          * knows they are all ready when this function returns.
413          */
414         rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MAIN);
415         rte_eal_mp_wait_lcore();
416         return fctret;
417 }
418
419 int
420 rte_vfio_container_dma_map(__rte_unused int container_fd,
421                         __rte_unused uint64_t vaddr,
422                         __rte_unused uint64_t iova,
423                         __rte_unused uint64_t len)
424 {
425         return -1;
426 }
427
428 int
429 rte_vfio_container_dma_unmap(__rte_unused int container_fd,
430                         __rte_unused uint64_t vaddr,
431                         __rte_unused uint64_t iova,
432                         __rte_unused uint64_t len)
433 {
434         return -1;
435 }