FD.io VPP  v18.01.1-37-g7ea3975
Vector Packet Processing
memfd.c
Go to the documentation of this file.
1 /*
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:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
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.
14  */
15 #include "memfd.h"
16 
17 int
18 memfd_master_init (memfd_private_t * memfd, u32 master_index)
19 {
20  int flags;
22  u64 ticks = clib_cpu_time_now ();
23  u64 randomize_baseva;
24  void *oldheap;
25 
26  if (memfd->memfd_size == 0)
27  return MEMFD_API_ERROR_NO_SIZE;
28 
30  memfd->name = format (0, "memfd svm region %d", master_index);
31 
32  memfd->fd = memfd_create ((char *) memfd->name, MFD_ALLOW_SEALING);
33  if (memfd->fd < 0)
34  {
35  clib_unix_warning ("create segment '%s'", memfd->name);
36  return MEMFD_API_ERROR_CREATE_FAILURE;
37  }
38 
39  if ((ftruncate (memfd->fd, memfd->memfd_size)) == -1)
40  {
41  clib_unix_warning ("set memfd size");
42  return MEMFD_API_ERROR_SET_SIZE;
43  }
44 
45  if ((fcntl (memfd->fd, F_ADD_SEALS, F_SEAL_SHRINK)) == -1)
46  clib_unix_warning ("fcntl (F_ADD_SEALS, F_SEAL_SHRINK)");
47 
48  flags = MAP_SHARED;
49  if (memfd->requested_va)
50  flags |= MAP_FIXED;
51 
52  randomize_baseva = (ticks & 15) * MMAP_PAGESIZE;
53 
54  if (memfd->requested_va)
55  memfd->requested_va += randomize_baseva;
56 
57  sh = memfd->sh =
58  (memfd_shared_header_t *) mmap ((void *) memfd->requested_va,
59  memfd->memfd_size, PROT_READ | PROT_WRITE,
60  flags, memfd->fd, 0);
61 
62  if (memfd->sh == MAP_FAILED)
63  {
64  clib_unix_warning ("mmap");
65  close (memfd->fd);
66  return MEMFD_API_ERROR_MMAP;
67  }
68 
69  memfd->my_pid = getpid ();
70  sh->master_pid = memfd->my_pid;
71  sh->memfd_size = memfd->memfd_size;
73  (((u8 *) sh) + MMAP_PAGESIZE, memfd->memfd_size - MMAP_PAGESIZE,
75 
76  sh->memfd_va = pointer_to_uword (sh);
77  sh->master_index = master_index;
78 
79  oldheap = memfd_push_heap (sh);
80  sh->name = format (0, "%s%c", memfd->name, 0);
81  memfd_pop_heap (oldheap);
82 
83  memfd->i_am_master = 1;
84 
85  /* The application has to set set sh->ready... */
86  return 0;
87 }
88 
89 /*
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
93  */
94 
95 int
97 {
99 
100  memfd->i_am_master = 0;
101 
102  /* Map the segment once, to look at the shared header */
103  sh = (void *) mmap (0, MMAP_PAGESIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
104  memfd->fd, 0);
105  if (sh == MAP_FAILED)
106  {
107  clib_unix_warning ("slave research mmap");
108  close (memfd->fd);
109  return MEMFD_API_ERROR_MMAP;
110  }
111 
112  memfd->requested_va = (u64) sh->memfd_va;
113  memfd->memfd_size = sh->memfd_size;
114  munmap (sh, MMAP_PAGESIZE);
115 
116  sh = memfd->sh =
117  (void *) mmap ((void *) memfd->requested_va, memfd->memfd_size,
118  PROT_READ | PROT_WRITE,
119  MAP_SHARED | MAP_FIXED, memfd->fd, 0);
120 
121  if (sh == MAP_FAILED)
122  {
123  clib_unix_warning ("slave final mmap");
124  close (memfd->fd);
125  return MEMFD_API_ERROR_MMAP;
126  }
127  sh->slave_pid = getpid ();
128  return 0;
129 }
130 
131 /*
132  * fd.io coding-style-patch-verification: ON
133  *
134  * Local Variables:
135  * eval: (c-set-style "gnu")
136  * End:
137  */
#define MFD_ALLOW_SEALING
Definition: memfd.h:177
#define vec_c_string_is_terminated(V)
Test whether a vector is a NULL terminated c-string.
Definition: vec.h:982
#define F_ADD_SEALS
Definition: mem.c:39
static int memfd_create(const char *name, unsigned int flags)
Definition: syscall.h:44
static u64 clib_cpu_time_now(void)
Definition: time.h:73
uword requested_va
Definition: memfd.h:83
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
#define MHEAP_FLAG_THREAD_SAFE
u8 * name
Definition: memfd.h:87
#define MMAP_PAGESIZE
Definition: memfd.h:44
#define MHEAP_FLAG_DISABLE_VM
u64 memfd_size
Definition: memfd.h:80
unsigned long u64
Definition: types.h:89
#define F_SEAL_SHRINK
Definition: mem.c:43
static uword pointer_to_uword(const void *p)
Definition: types.h:131
int memfd_master_init(memfd_private_t *memfd, u32 master_index)
Definition: memfd.c:18
int i_am_master
Definition: memfd.h:84
memfd_shared_header_t * sh
Definition: memfd.h:78
int memfd_slave_init(memfd_private_t *memfd)
Definition: memfd.c:96
static void * memfd_push_heap(memfd_shared_header_t *sh)
Definition: memfd.h:137
void * mheap_alloc_with_flags(void *memory, uword memory_size, uword flags)
Definition: mheap.c:869
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
u32 my_pid
Definition: memfd.h:81
unsigned char u8
Definition: types.h:56
#define clib_unix_warning(format, args...)
Definition: error.h:68
static void memfd_pop_heap(void *oldheap)
Definition: memfd.h:145
u32 flags
Definition: vhost-user.h:77