2 * Copyright (c) 2017 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
18 memfd_master_init (memfd_private_t * memfd, u32 master_index)
21 memfd_shared_header_t *sh;
22 u64 ticks = clib_cpu_time_now ();
26 if (memfd->memfd_size == 0)
27 return MEMFD_API_ERROR_NO_SIZE;
29 ASSERT (vec_c_string_is_terminated (memfd->name));
30 memfd->name = format (0, "memfd svm region %d", master_index);
32 memfd->fd = memfd_create ((char *) memfd->name, MFD_ALLOW_SEALING);
35 clib_unix_warning ("create segment '%s'", memfd->name);
36 return MEMFD_API_ERROR_CREATE_FAILURE;
39 if ((ftruncate (memfd->fd, memfd->memfd_size)) == -1)
41 clib_unix_warning ("set memfd size");
42 return MEMFD_API_ERROR_SET_SIZE;
45 if ((fcntl (memfd->fd, F_ADD_SEALS, F_SEAL_SHRINK)) == -1)
46 clib_unix_warning ("fcntl (F_ADD_SEALS, F_SEAL_SHRINK)");
49 if (memfd->requested_va)
52 randomize_baseva = (ticks & 15) * MMAP_PAGESIZE;
54 if (memfd->requested_va)
55 memfd->requested_va += randomize_baseva;
58 (memfd_shared_header_t *) mmap ((void *) memfd->requested_va,
59 memfd->memfd_size, PROT_READ | PROT_WRITE,
62 if (memfd->sh == MAP_FAILED)
64 clib_unix_warning ("mmap");
66 return MEMFD_API_ERROR_MMAP;
69 memfd->my_pid = getpid ();
70 sh->master_pid = memfd->my_pid;
71 sh->memfd_size = memfd->memfd_size;
72 sh->heap = mheap_alloc_with_flags
73 (((u8 *) sh) + MMAP_PAGESIZE, memfd->memfd_size - MMAP_PAGESIZE,
74 MHEAP_FLAG_DISABLE_VM | MHEAP_FLAG_THREAD_SAFE);
76 sh->memfd_va = pointer_to_uword (sh);
77 sh->master_index = master_index;
79 oldheap = memfd_push_heap (sh);
80 sh->name = format (0, "%s%c", memfd->name, 0);
81 memfd_pop_heap (oldheap);
83 memfd->i_am_master = 1;
85 /* The application has to set set sh->ready... */
90 * Subtly different than svm_slave_init. The caller
91 * needs to acquire a usable file descriptor for the memfd segment
92 * e.g. via vppinfra/socket.c:default_socket_recvmsg
96 memfd_slave_init (memfd_private_t * memfd)
98 memfd_shared_header_t *sh;
100 memfd->i_am_master = 0;
102 /* Map the segment once, to look at the shared header */
103 sh = (void *) mmap (0, MMAP_PAGESIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
105 if (sh == MAP_FAILED)
107 clib_unix_warning ("slave research mmap");
109 return MEMFD_API_ERROR_MMAP;
112 memfd->requested_va = (u64) sh->memfd_va;
113 memfd->memfd_size = sh->memfd_size;
114 munmap (sh, MMAP_PAGESIZE);
117 (void *) mmap ((void *) memfd->requested_va, memfd->memfd_size,
118 PROT_READ | PROT_WRITE,
119 MAP_SHARED | MAP_FIXED, memfd->fd, 0);
121 if (sh == MAP_FAILED)
123 clib_unix_warning ("slave final mmap");
125 return MEMFD_API_ERROR_MMAP;
127 sh->slave_pid = getpid ();
132 * fd.io coding-style-patch-verification: ON
135 * eval: (c-set-style "gnu")