Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2010-2014 Intel Corporation
3 : : */
4 : :
5 : : #include <string.h>
6 : : #include <sys/file.h>
7 : : #include <dirent.h>
8 : : #include <fcntl.h>
9 : : #include <stdint.h>
10 : : #include <stdlib.h>
11 : : #include <stdio.h>
12 : : #include <fnmatch.h>
13 : : #include <inttypes.h>
14 : : #include <unistd.h>
15 : : #include <errno.h>
16 : : #include <mntent.h>
17 : : #include <sys/mman.h>
18 : : #include <sys/stat.h>
19 : : #include <sys/statfs.h>
20 : :
21 : : #include <linux/mman.h> /* for hugetlb-related flags */
22 : : #include <linux/magic.h> /* for HUGETLBFS_MAGIC */
23 : :
24 : : #include <rte_lcore.h>
25 : : #include <rte_debug.h>
26 : : #include <rte_log.h>
27 : : #include <rte_common.h>
28 : : #include "rte_string_fns.h"
29 : :
30 : : #include "eal_private.h"
31 : : #include "eal_internal_cfg.h"
32 : : #include "eal_hugepages.h"
33 : : #include "eal_filesystem.h"
34 : :
35 : : static const char sys_dir_path[] = "/sys/kernel/mm/hugepages";
36 : : static const char sys_pages_numa_dir_path[] = "/sys/devices/system/node";
37 : :
38 : : /*
39 : : * Uses mmap to create a shared memory area for storage of data
40 : : * Used in this file to store the hugepage file map on disk
41 : : */
42 : : static void *
43 [ - + ]: 83 : map_shared_memory(const char *filename, const size_t mem_size, int flags)
44 : : {
45 : : void *retval;
46 : : int fd = open(filename, flags, 0600);
47 [ + + ]: 83 : if (fd < 0)
48 : : return NULL;
49 [ - + ]: 82 : if (ftruncate(fd, mem_size) < 0) {
50 : 0 : close(fd);
51 : 0 : return NULL;
52 : : }
53 : 82 : retval = mmap(NULL, mem_size, PROT_READ | PROT_WRITE,
54 : : MAP_SHARED, fd, 0);
55 : 82 : close(fd);
56 [ - + ]: 82 : return retval == MAP_FAILED ? NULL : retval;
57 : : }
58 : :
59 : : static void *
60 : : open_shared_memory(const char *filename, const size_t mem_size)
61 : : {
62 : 27 : return map_shared_memory(filename, mem_size, O_RDWR);
63 : : }
64 : :
65 : : static void *
66 : : create_shared_memory(const char *filename, const size_t mem_size)
67 : : {
68 : 56 : return map_shared_memory(filename, mem_size, O_RDWR | O_CREAT);
69 : : }
70 : :
71 : 272 : static int get_hp_sysfs_value(const char *subdir, const char *file, unsigned long *val)
72 : : {
73 : 272 : char *path = NULL;
74 : : int ret;
75 : :
76 [ + - ]: 272 : if (asprintf(&path, "%s/%s/%s", sys_dir_path, subdir, file) < 0)
77 : : return -1;
78 : 272 : ret = eal_parse_sysfs_value(path, val);
79 : 272 : free(path);
80 : 272 : return ret;
81 : : }
82 : :
83 : : /* this function is only called from eal_hugepage_info_init which itself
84 : : * is only called from a primary process */
85 : : static uint32_t
86 : 68 : get_num_hugepages(const char *subdir, size_t sz, unsigned int reusable_pages)
87 : : {
88 : : unsigned long resv_pages, num_pages, over_pages, surplus_pages;
89 : : const char *nr_hp_file = "free_hugepages";
90 : : const char *nr_rsvd_file = "resv_hugepages";
91 : : const char *nr_over_file = "nr_overcommit_hugepages";
92 : : const char *nr_splus_file = "surplus_hugepages";
93 : :
94 : : /* first, check how many reserved pages kernel reports */
95 [ + - ]: 68 : if (get_hp_sysfs_value(subdir, nr_rsvd_file, &resv_pages) < 0)
96 : : return 0;
97 : :
98 [ + - ]: 68 : if (get_hp_sysfs_value(subdir, nr_hp_file, &num_pages) < 0)
99 : : return 0;
100 : :
101 [ - + ]: 68 : if (get_hp_sysfs_value(subdir, nr_over_file, &over_pages) < 0)
102 : 0 : over_pages = 0;
103 : :
104 [ - + ]: 68 : if (get_hp_sysfs_value(subdir, nr_splus_file, &surplus_pages) < 0)
105 : 0 : surplus_pages = 0;
106 : :
107 : : /* adjust num_pages */
108 [ + - ]: 68 : if (num_pages >= resv_pages)
109 : 68 : num_pages -= resv_pages;
110 : : else if (resv_pages)
111 : 0 : num_pages = 0;
112 : :
113 [ + - ]: 68 : if (over_pages >= surplus_pages)
114 : 68 : over_pages -= surplus_pages;
115 : : else
116 : 0 : over_pages = 0;
117 : :
118 [ + + + - : 68 : if (num_pages == 0 && over_pages == 0 && reusable_pages)
- + ]
119 : 0 : EAL_LOG(WARNING, "No available %zu kB hugepages reported",
120 : : sz >> 10);
121 : :
122 : 68 : num_pages += over_pages;
123 [ - + ]: 68 : if (num_pages < over_pages) /* overflow */
124 : 0 : num_pages = UINT32_MAX;
125 : :
126 : 68 : num_pages += reusable_pages;
127 [ - + ]: 68 : if (num_pages < reusable_pages) /* overflow */
128 : 0 : num_pages = UINT32_MAX;
129 : :
130 : : /* we want to return a uint32_t and more than this looks suspicious
131 : : * anyway ... */
132 [ - + ]: 68 : if (num_pages > UINT32_MAX)
133 : 0 : num_pages = UINT32_MAX;
134 : :
135 : 68 : return num_pages;
136 : : }
137 : :
138 : : static uint32_t
139 : 120 : get_num_hugepages_on_node(const char *subdir, unsigned int socket, size_t sz)
140 : : {
141 : 120 : char *path = NULL, *socketpath = NULL;
142 : : DIR *socketdir;
143 : 120 : unsigned long num_pages = 0;
144 : : const char *nr_hp_file = "free_hugepages";
145 : :
146 [ - + ]: 120 : if (asprintf(&socketpath, "%s/node%u/hugepages", sys_pages_numa_dir_path, socket) < 0) {
147 : 0 : EAL_LOG(ERR, "Can not format node huge page path");
148 : 0 : socketpath = NULL;
149 : 0 : goto nopages;
150 : : }
151 : :
152 : 120 : socketdir = opendir(socketpath);
153 [ + - ]: 120 : if (socketdir) {
154 : : /* Keep calm and carry on */
155 : 120 : closedir(socketdir);
156 : : } else {
157 : : /* Can't find socket dir, so ignore it */
158 : 0 : goto nopages;
159 : : }
160 : :
161 [ - + ]: 120 : if (asprintf(&path, "%s/%s/%s", socketpath, subdir, nr_hp_file) < 0) {
162 : 0 : EAL_LOG(ERR, "Can not format free hugepages path");
163 : 0 : path = NULL;
164 : 0 : goto nopages;
165 : : }
166 : :
167 [ - + ]: 120 : if (eal_parse_sysfs_value(path, &num_pages) < 0)
168 : 0 : goto nopages;
169 : :
170 [ + + ]: 120 : if (num_pages == 0)
171 : 6 : EAL_LOG(WARNING, "No free %zu kB hugepages reported on node %u",
172 : : sz >> 10, socket);
173 : :
174 : : /*
175 : : * we want to return a uint32_t and more than this looks suspicious
176 : : * anyway ...
177 : : */
178 [ + - ]: 120 : if (num_pages > UINT32_MAX)
179 : 0 : num_pages = UINT32_MAX;
180 : :
181 : 120 : nopages:
182 : 120 : free(path);
183 : 120 : free(socketpath);
184 : :
185 : 120 : return num_pages;
186 : : }
187 : :
188 : : static uint64_t
189 : 57 : get_default_hp_size(void)
190 : : {
191 : 57 : const char proc_meminfo[] = "/proc/meminfo";
192 : 57 : const char str_hugepagesz[] = "Hugepagesize:";
193 : : unsigned hugepagesz_len = sizeof(str_hugepagesz) - 1;
194 : : char buffer[256];
195 : : unsigned long long size = 0;
196 : :
197 : 57 : FILE *fd = fopen(proc_meminfo, "r");
198 [ - + ]: 57 : if (fd == NULL)
199 : 0 : rte_panic("Cannot open %s\n", proc_meminfo);
200 [ + - ]: 2679 : while(fgets(buffer, sizeof(buffer), fd)){
201 [ + + ]: 2679 : if (strncmp(buffer, str_hugepagesz, hugepagesz_len) == 0){
202 : 57 : size = rte_str_to_size(&buffer[hugepagesz_len]);
203 : 57 : break;
204 : : }
205 : : }
206 : 57 : fclose(fd);
207 [ - + ]: 57 : if (size == 0)
208 : 0 : rte_panic("Cannot get default hugepage size from %s\n", proc_meminfo);
209 : 57 : return size;
210 : : }
211 : :
212 : : static int
213 : 122 : get_hugepage_dir(uint64_t hugepage_sz, char *hugedir, int len)
214 : : {
215 : : static uint64_t default_size = 0;
216 : : const char pagesize_opt[] = "pagesize=";
217 : : const size_t pagesize_opt_len = sizeof(pagesize_opt) - 1;
218 : : const struct internal_config *internal_conf =
219 : 122 : eal_get_internal_configuration();
220 : : struct mntent *mnt;
221 : : FILE *fp;
222 : :
223 : : /* Fast path: hugepage_dir explicitly specified */
224 [ + + ]: 122 : if (internal_conf->hugepage_dir != NULL) {
225 : : struct statfs sfs;
226 : :
227 : : /* Query info about mounted filesystem */
228 [ + + ]: 8 : if (statfs(internal_conf->hugepage_dir, &sfs) != 0 ||
229 [ + - ]: 4 : (uint32_t)sfs.f_type != HUGETLBFS_MAGIC ||
230 [ + + ]: 4 : (uint64_t)sfs.f_bsize != hugepage_sz)
231 : : return -1;
232 : :
233 : 2 : strlcpy(hugedir, internal_conf->hugepage_dir, len);
234 : 2 : return 0;
235 : : }
236 : :
237 : : /* Discover mount point from /proc/mounts */
238 : 114 : fp = setmntent("/proc/mounts", "r");
239 [ - + ]: 114 : if (fp == NULL)
240 : 0 : rte_panic("Cannot open /proc/mounts\n");
241 : :
242 [ + + ]: 114 : if (default_size == 0)
243 : 57 : default_size = get_default_hp_size();
244 : :
245 [ + + ]: 1539 : while ((mnt = getmntent(fp)) != NULL) {
246 : : const char *pagesz_str;
247 : :
248 [ + + ]: 1482 : if (strcmp(mnt->mnt_type, "hugetlbfs") != 0)
249 : 1368 : continue;
250 : :
251 : 114 : pagesz_str = hasmntopt(mnt, "pagesize");
252 : :
253 [ - + ]: 114 : if (pagesz_str == NULL) {
254 [ # # ]: 0 : if (hugepage_sz != default_size)
255 : 0 : continue;
256 : : } else {
257 : 114 : uint64_t pagesz = rte_str_to_size(&pagesz_str[pagesize_opt_len]);
258 [ + + ]: 114 : if (pagesz != hugepage_sz)
259 : 57 : continue;
260 : : }
261 : :
262 : : /* Found a match */
263 : 57 : strlcpy(hugedir, mnt->mnt_dir, len);
264 : 57 : endmntent(fp);
265 : 57 : return 0;
266 : : }
267 : :
268 : 57 : endmntent(fp);
269 : 57 : return -1;
270 : : }
271 : :
272 : : struct walk_hugedir_data {
273 : : int dir_fd;
274 : : int file_fd;
275 : : const char *file_name;
276 : : void *user_data;
277 : : };
278 : :
279 : : typedef void (walk_hugedir_t)(const struct walk_hugedir_data *whd);
280 : :
281 : : /*
282 : : * Search the hugepage directory for whatever hugepage files there are.
283 : : * Check if the file is in use by another DPDK process.
284 : : * If not, execute a callback on it.
285 : : */
286 : : static int
287 : 59 : walk_hugedir(const char *hugedir, walk_hugedir_t *cb, void *user_data)
288 : : {
289 : : DIR *dir;
290 : : struct dirent *dirent;
291 : : int dir_fd, fd, lck_result;
292 : 59 : const char filter[] = "*map_*"; /* matches hugepage files */
293 : :
294 : 59 : dir = opendir(hugedir);
295 [ - + ]: 59 : if (!dir) {
296 : 0 : EAL_LOG(ERR, "Unable to open hugepage directory %s",
297 : : hugedir);
298 : 0 : goto error;
299 : : }
300 : 59 : dir_fd = dirfd(dir);
301 : :
302 : 59 : dirent = readdir(dir);
303 [ - + ]: 59 : if (!dirent) {
304 : 0 : EAL_LOG(ERR, "Unable to read hugepage directory %s",
305 : : hugedir);
306 : 0 : goto error;
307 : : }
308 : :
309 [ + + ]: 235 : while (dirent != NULL) {
310 : : /* skip files that don't match the hugepage pattern */
311 [ + + ]: 176 : if (fnmatch(filter, dirent->d_name, 0) > 0) {
312 : 126 : dirent = readdir(dir);
313 : 126 : continue;
314 : : }
315 : :
316 : : /* try and lock the file */
317 : : fd = openat(dir_fd, dirent->d_name, O_RDONLY);
318 : :
319 : : /* skip to next file */
320 [ - + ]: 50 : if (fd == -1) {
321 : 0 : dirent = readdir(dir);
322 : 0 : continue;
323 : : }
324 : :
325 : : /* non-blocking lock */
326 : 50 : lck_result = flock(fd, LOCK_EX | LOCK_NB);
327 : :
328 : : /* if lock succeeds, execute callback */
329 [ + + ]: 50 : if (lck_result != -1)
330 : 30 : cb(&(struct walk_hugedir_data){
331 : : .dir_fd = dir_fd,
332 : : .file_fd = fd,
333 : : .file_name = dirent->d_name,
334 : : .user_data = user_data,
335 : : });
336 : :
337 : 50 : close (fd);
338 : 50 : dirent = readdir(dir);
339 : : }
340 : :
341 : 59 : closedir(dir);
342 : 59 : return 0;
343 : :
344 : 0 : error:
345 [ # # ]: 0 : if (dir)
346 : 0 : closedir(dir);
347 : :
348 : 0 : EAL_LOG(ERR, "Error while walking hugepage dir: %s",
349 : : strerror(errno));
350 : :
351 : 0 : return -1;
352 : : }
353 : :
354 : : static void
355 : 30 : clear_hugedir_cb(const struct walk_hugedir_data *whd)
356 : : {
357 : 30 : unlinkat(whd->dir_fd, whd->file_name, 0);
358 : 30 : }
359 : :
360 : : /* Remove hugepage files not used by other DPDK processes from a directory. */
361 : : static int
362 : : clear_hugedir(const char *hugedir)
363 : : {
364 : 58 : return walk_hugedir(hugedir, clear_hugedir_cb, NULL);
365 : : }
366 : :
367 : : static void
368 : 0 : inspect_hugedir_cb(const struct walk_hugedir_data *whd)
369 : : {
370 : 0 : uint64_t *total_size = whd->user_data;
371 : : struct stat st;
372 : :
373 [ # # ]: 0 : if (fstat(whd->file_fd, &st) < 0)
374 : 0 : EAL_LOG(DEBUG, "%s(): stat(\"%s\") failed: %s",
375 : : __func__, whd->file_name, strerror(errno));
376 : : else
377 : 0 : (*total_size) += st.st_size;
378 : 0 : }
379 : :
380 : : /*
381 : : * Count the total size in bytes of all files in the directory
382 : : * not mapped by other DPDK process.
383 : : */
384 : : static int
385 : : inspect_hugedir(const char *hugedir, uint64_t *total_size)
386 : : {
387 : 1 : return walk_hugedir(hugedir, inspect_hugedir_cb, total_size);
388 : : }
389 : :
390 : : static int
391 : 3 : compare_hpi(const void *a, const void *b)
392 : : {
393 : : const struct hugepage_info *hpi_a = a;
394 : : const struct hugepage_info *hpi_b = b;
395 : :
396 : 3 : return hpi_b->hugepage_sz - hpi_a->hugepage_sz;
397 : : }
398 : :
399 : : static void
400 : 62 : calc_num_pages(struct hugepage_info *hpi, struct dirent *dirent,
401 : : unsigned int reusable_pages)
402 : : {
403 : : uint64_t total_pages = 0;
404 : : unsigned int i;
405 : : const struct internal_config *internal_conf =
406 : 62 : eal_get_internal_configuration();
407 : :
408 : : /*
409 : : * first, try to put all hugepages into relevant sockets, but
410 : : * if first attempts fails, fall back to collecting all pages
411 : : * in one socket and sorting them later
412 : : */
413 : : total_pages = 0;
414 : :
415 : : /*
416 : : * We also don't want to do this for legacy init.
417 : : * When there are hugepage files to reuse it is unknown
418 : : * what NUMA node the pages are on.
419 : : * This could be determined by mapping,
420 : : * but it is precisely what hugepage file reuse is trying to avoid.
421 : : */
422 [ + + + - ]: 62 : if (!internal_conf->legacy_mem && reusable_pages == 0)
423 [ + + ]: 180 : for (i = 0; i < rte_socket_count(); i++) {
424 : 120 : int socket = rte_socket_id_by_idx(i);
425 : : unsigned int num_pages =
426 : 120 : get_num_hugepages_on_node(
427 : 120 : dirent->d_name, socket,
428 : : hpi->hugepage_sz);
429 : 120 : hpi->num_pages[socket] = num_pages;
430 : 120 : total_pages += num_pages;
431 : : }
432 : : /*
433 : : * we failed to sort memory from the get go, so fall
434 : : * back to old way
435 : : */
436 [ + + ]: 60 : if (total_pages == 0) {
437 : 5 : hpi->num_pages[0] = get_num_hugepages(dirent->d_name,
438 : : hpi->hugepage_sz, reusable_pages);
439 : :
440 : : #ifndef RTE_ARCH_64
441 : : /* for 32-bit systems, limit number of hugepages to
442 : : * 1GB per page size */
443 : : hpi->num_pages[0] = RTE_MIN(hpi->num_pages[0],
444 : : RTE_PGSIZE_1G / hpi->hugepage_sz);
445 : : #endif
446 : : }
447 : 62 : }
448 : :
449 : : static int
450 : 61 : hugepage_info_init(void)
451 : 61 : { const char dirent_start_text[] = "hugepages-";
452 : : const size_t dirent_start_len = sizeof(dirent_start_text) - 1;
453 : : unsigned int i, num_sizes = 0;
454 : : uint64_t reusable_bytes;
455 : : unsigned int reusable_pages;
456 : : DIR *dir;
457 : : struct dirent *dirent;
458 : : struct internal_config *internal_conf =
459 : 61 : eal_get_internal_configuration();
460 : :
461 : 61 : dir = opendir(sys_dir_path);
462 [ - + ]: 61 : if (dir == NULL) {
463 : 0 : EAL_LOG(ERR,
464 : : "Cannot open directory %s to read system hugepage info",
465 : : sys_dir_path);
466 : 0 : return -1;
467 : : }
468 : :
469 [ + + ]: 305 : for (dirent = readdir(dir); dirent != NULL; dirent = readdir(dir)) {
470 : : struct hugepage_info *hpi;
471 : :
472 [ + + ]: 244 : if (strncmp(dirent->d_name, dirent_start_text,
473 : : dirent_start_len) != 0)
474 : 122 : continue;
475 : :
476 [ + - ]: 122 : if (num_sizes >= MAX_HUGEPAGE_SIZES)
477 : : break;
478 : :
479 : 122 : hpi = &internal_conf->hugepage_info[num_sizes];
480 : 122 : hpi->hugepage_sz =
481 : 122 : rte_str_to_size(&dirent->d_name[dirent_start_len]);
482 : :
483 : : /* first, check if we have a mountpoint */
484 [ + + ]: 122 : if (get_hugepage_dir(hpi->hugepage_sz,
485 : 122 : hpi->hugedir, sizeof(hpi->hugedir)) < 0) {
486 : : uint32_t num_pages;
487 : :
488 : 63 : num_pages = get_num_hugepages(dirent->d_name,
489 : : hpi->hugepage_sz, 0);
490 [ + + ]: 63 : if (num_pages > 0)
491 : 2 : EAL_LOG(NOTICE,
492 : : "%" PRIu32 " hugepages of size "
493 : : "%" PRIu64 " reserved, but no mounted "
494 : : "hugetlbfs found for that size",
495 : : num_pages, hpi->hugepage_sz);
496 : : /* if we have kernel support for reserving hugepages
497 : : * through mmap, and we're in in-memory mode, treat this
498 : : * page size as valid. we cannot be in legacy mode at
499 : : * this point because we've checked this earlier in the
500 : : * init process.
501 : : */
502 : : #ifdef MAP_HUGE_SHIFT
503 [ + + ]: 63 : if (internal_conf->in_memory) {
504 : 3 : EAL_LOG(DEBUG, "In-memory mode enabled, "
505 : : "hugepages of size %" PRIu64 " bytes "
506 : : "will be allocated anonymously",
507 : : hpi->hugepage_sz);
508 : 3 : calc_num_pages(hpi, dirent, 0);
509 : 3 : num_sizes++;
510 : : }
511 : : #endif
512 : 63 : continue;
513 : : }
514 : :
515 : : /* try to obtain a writelock */
516 : 59 : hpi->lock_descriptor = open(hpi->hugedir, O_RDONLY);
517 : :
518 : : /* if blocking lock failed */
519 [ - + ]: 59 : if (flock(hpi->lock_descriptor, LOCK_EX) == -1) {
520 : 0 : EAL_LOG(CRIT,
521 : : "Failed to lock hugepage directory!");
522 : 0 : break;
523 : : }
524 : :
525 : : /*
526 : : * Check for existing hugepage files and either remove them
527 : : * or count how many of them can be reused.
528 : : */
529 : : reusable_pages = 0;
530 [ + + ]: 59 : if (!internal_conf->hugepage_file.unlink_existing) {
531 : 1 : reusable_bytes = 0;
532 [ + - ]: 1 : if (inspect_hugedir(hpi->hugedir,
533 : : &reusable_bytes) < 0)
534 : : break;
535 : : RTE_ASSERT(reusable_bytes % hpi->hugepage_sz == 0);
536 : 1 : reusable_pages = reusable_bytes / hpi->hugepage_sz;
537 [ + - ]: 58 : } else if (clear_hugedir(hpi->hugedir) < 0) {
538 : : break;
539 : : }
540 : 59 : calc_num_pages(hpi, dirent, reusable_pages);
541 : :
542 : 59 : num_sizes++;
543 : : }
544 : 61 : closedir(dir);
545 : :
546 : : /* something went wrong, and we broke from the for loop above */
547 [ + - ]: 61 : if (dirent != NULL)
548 : : return -1;
549 : :
550 : 61 : internal_conf->num_hugepage_sizes = num_sizes;
551 : :
552 : : /* sort the page directory entries by size, largest to smallest */
553 : 61 : qsort(&internal_conf->hugepage_info[0], num_sizes,
554 : : sizeof(internal_conf->hugepage_info[0]), compare_hpi);
555 : :
556 : : /* now we have all info, check we have at least one valid size */
557 [ + + ]: 64 : for (i = 0; i < num_sizes; i++) {
558 : : /* pages may no longer all be on socket 0, so check all */
559 : : unsigned int j, num_pages = 0;
560 : : struct hugepage_info *hpi = &internal_conf->hugepage_info[i];
561 : :
562 [ + + ]: 2046 : for (j = 0; j < RTE_MAX_NUMA_NODES; j++)
563 : 1984 : num_pages += hpi->num_pages[j];
564 [ + + ]: 62 : if (num_pages > 0)
565 : : return 0;
566 : : }
567 : :
568 : : /* no valid hugepage mounts available, return error */
569 : : return -1;
570 : : }
571 : :
572 : : /*
573 : : * when we initialize the hugepage info, everything goes
574 : : * to socket 0 by default. it will later get sorted by memory
575 : : * initialization procedure.
576 : : */
577 : : int
578 : 61 : eal_hugepage_info_init(void)
579 : : {
580 : : struct hugepage_info *hpi, *tmp_hpi;
581 : : unsigned int i;
582 : : struct internal_config *internal_conf =
583 : 61 : eal_get_internal_configuration();
584 : :
585 [ + + ]: 61 : if (hugepage_info_init() < 0)
586 : : return -1;
587 : :
588 : : /* for no shared files mode, we're done */
589 [ + + ]: 59 : if (internal_conf->no_shconf)
590 : : return 0;
591 : :
592 : 56 : hpi = &internal_conf->hugepage_info[0];
593 : :
594 : 56 : tmp_hpi = create_shared_memory(eal_hugepage_info_path(),
595 : : sizeof(internal_conf->hugepage_info));
596 [ - + ]: 56 : if (tmp_hpi == NULL) {
597 : 0 : EAL_LOG(ERR, "Failed to create shared memory!");
598 : 0 : return -1;
599 : : }
600 : :
601 : : memcpy(tmp_hpi, hpi, sizeof(internal_conf->hugepage_info));
602 : :
603 : : /* we've copied file descriptors along with everything else, but they
604 : : * will be invalid in secondary process, so overwrite them
605 : : */
606 [ + + ]: 224 : for (i = 0; i < RTE_DIM(internal_conf->hugepage_info); i++) {
607 : 168 : struct hugepage_info *tmp = &tmp_hpi[i];
608 : 168 : tmp->lock_descriptor = -1;
609 : : }
610 : :
611 [ - + ]: 56 : if (munmap(tmp_hpi, sizeof(internal_conf->hugepage_info)) < 0) {
612 : 0 : EAL_LOG(ERR, "Failed to unmap shared memory!");
613 : 0 : return -1;
614 : : }
615 : : return 0;
616 : : }
617 : :
618 : 27 : int eal_hugepage_info_read(void)
619 : : {
620 : : struct internal_config *internal_conf =
621 : 27 : eal_get_internal_configuration();
622 : 27 : struct hugepage_info *hpi = &internal_conf->hugepage_info[0];
623 : : struct hugepage_info *tmp_hpi;
624 : :
625 : 27 : tmp_hpi = open_shared_memory(eal_hugepage_info_path(),
626 : : sizeof(internal_conf->hugepage_info));
627 [ + + ]: 27 : if (tmp_hpi == NULL) {
628 : 1 : EAL_LOG(ERR, "Failed to open shared memory!");
629 : 1 : return -1;
630 : : }
631 : :
632 : : memcpy(hpi, tmp_hpi, sizeof(internal_conf->hugepage_info));
633 : :
634 [ - + ]: 26 : if (munmap(tmp_hpi, sizeof(internal_conf->hugepage_info)) < 0) {
635 : 0 : EAL_LOG(ERR, "Failed to unmap shared memory!");
636 : 0 : return -1;
637 : : }
638 : : return 0;
639 : : }
|