FD.io VPP  v17.01-9-ge7dcee4
Vector Packet Processing
ssvm.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 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 "ssvm.h"
16 
17 int
18 ssvm_master_init (ssvm_private_t * ssvm, u32 master_index)
19 {
20  int ssvm_fd;
21  u8 *ssvm_filename;
22  u8 junk = 0;
23  int flags;
25  u64 ticks = clib_cpu_time_now ();
26  u64 randomize_baseva;
27  void *oldheap;
28 
29  if (ssvm->ssvm_size == 0)
30  return SSVM_API_ERROR_NO_SIZE;
31 
32  ssvm_filename = format (0, "/dev/shm/%s%c", ssvm->name, 0);
33 
34  unlink ((char *) ssvm_filename);
35 
36  vec_free (ssvm_filename);
37 
38  ssvm_fd = shm_open ((char *) ssvm->name, O_RDWR | O_CREAT | O_EXCL, 0777);
39 
40  if (ssvm_fd < 0)
41  {
42  clib_unix_warning ("create segment '%s'", ssvm->name);
43  return SSVM_API_ERROR_CREATE_FAILURE;
44  }
45 
46  if (lseek (ssvm_fd, ssvm->ssvm_size, SEEK_SET) < 0)
47  {
48  clib_unix_warning ("lseek");
49  close (ssvm_fd);
50  return SSVM_API_ERROR_SET_SIZE;
51  }
52 
53  if (write (ssvm_fd, &junk, 1) != 1)
54  {
55  clib_unix_warning ("set ssvm size");
56  close (ssvm_fd);
57  return SSVM_API_ERROR_SET_SIZE;
58  }
59 
60  flags = MAP_SHARED;
61  if (ssvm->requested_va)
62  flags |= MAP_FIXED;
63 
64  randomize_baseva = (ticks & 15) * MMAP_PAGESIZE;
65 
66  if (ssvm->requested_va)
67  ssvm->requested_va += randomize_baseva;
68 
69  sh = ssvm->sh =
70  (ssvm_shared_header_t *) mmap ((void *) ssvm->requested_va,
71  ssvm->ssvm_size, PROT_READ | PROT_WRITE,
72  flags, ssvm_fd, 0);
73 
74  if (ssvm->sh == MAP_FAILED)
75  {
76  clib_unix_warning ("mmap");
77  close (ssvm_fd);
78  return SSVM_API_ERROR_MMAP;
79  }
80 
81  close (ssvm_fd);
82 
83  ssvm->my_pid = getpid ();
84  sh->master_pid = ssvm->my_pid;
85  sh->ssvm_size = ssvm->ssvm_size;
87  (((u8 *) sh) + MMAP_PAGESIZE, ssvm->ssvm_size - MMAP_PAGESIZE,
89 
90  sh->ssvm_va = pointer_to_uword (sh);
91  sh->master_index = master_index;
92 
93  oldheap = ssvm_push_heap (sh);
94  sh->name = format (0, "%s%c", ssvm->name, 0);
95  ssvm_pop_heap (oldheap);
96 
97  ssvm->i_am_master = 1;
98 
99  /* The application has to set set sh->ready... */
100  return 0;
101 }
102 
103 int
104 ssvm_slave_init (ssvm_private_t * ssvm, int timeout_in_seconds)
105 {
106  struct stat stat;
107  int ssvm_fd = -1;
109 
110  ssvm->i_am_master = 0;
111 
112  while (timeout_in_seconds-- > 0)
113  {
114  if (ssvm_fd < 0)
115  ssvm_fd = shm_open ((char *) ssvm->name, O_RDWR, 0777);
116  if (ssvm_fd < 0)
117  {
118  sleep (1);
119  continue;
120  }
121  if (fstat (ssvm_fd, &stat) < 0)
122  {
123  sleep (1);
124  continue;
125  }
126 
127  if (stat.st_size > 0)
128  goto map_it;
129  }
130  clib_warning ("slave timeout");
131  return SSVM_API_ERROR_SLAVE_TIMEOUT;
132 
133 map_it:
134  sh = (void *) mmap (0, MMAP_PAGESIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
135  ssvm_fd, 0);
136  if (sh == MAP_FAILED)
137  {
138  clib_unix_warning ("slave research mmap");
139  close (ssvm_fd);
140  return SSVM_API_ERROR_MMAP;
141  }
142 
143  while (timeout_in_seconds-- > 0)
144  {
145  if (sh->ready)
146  goto re_map_it;
147  }
148  close (ssvm_fd);
149  munmap (sh, MMAP_PAGESIZE);
150  clib_warning ("slave timeout 2");
151  return SSVM_API_ERROR_SLAVE_TIMEOUT;
152 
153 re_map_it:
154  ssvm->requested_va = (u64) sh->ssvm_va;
155  ssvm->ssvm_size = sh->ssvm_size;
156  munmap (sh, MMAP_PAGESIZE);
157 
158  sh = ssvm->sh = (void *) mmap ((void *) ssvm->requested_va, ssvm->ssvm_size,
159  PROT_READ | PROT_WRITE,
160  MAP_SHARED | MAP_FIXED, ssvm_fd, 0);
161 
162  if (sh == MAP_FAILED)
163  {
164  clib_unix_warning ("slave final mmap");
165  close (ssvm_fd);
166  return SSVM_API_ERROR_MMAP;
167  }
168  sh->slave_pid = getpid ();
169  return 0;
170 }
171 
172 /*
173  * fd.io coding-style-patch-verification: ON
174  *
175  * Local Variables:
176  * eval: (c-set-style "gnu")
177  * End:
178  */
u64 ssvm_size
Definition: ssvm.h:74
uword requested_va
Definition: ssvm.h:78
int ssvm_master_init(ssvm_private_t *ssvm, u32 master_index)
Definition: ssvm.c:18
volatile u32 ready
Definition: ssvm.h:65
static u64 clib_cpu_time_now(void)
Definition: time.h:73
ssvm_shared_header_t * sh
Definition: ssvm.h:73
#define MHEAP_FLAG_THREAD_SAFE
#define MHEAP_FLAG_DISABLE_VM
static void * ssvm_push_heap(ssvm_shared_header_t *sh)
Definition: ssvm.h:114
#define clib_warning(format, args...)
Definition: error.h:59
unsigned long u64
Definition: types.h:89
static void ssvm_pop_heap(void *oldheap)
Definition: ssvm.h:122
static uword pointer_to_uword(const void *p)
Definition: types.h:131
int ssvm_slave_init(ssvm_private_t *ssvm, int timeout_in_seconds)
Definition: ssvm.c:104
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:300
#define clib_unix_warning(format, args...)
Definition: error.h:68
u32 my_pid
Definition: ssvm.h:75
void * mheap_alloc_with_flags(void *memory, uword memory_size, uword flags)
Definition: mheap.c:875
unsigned int u32
Definition: types.h:88
u8 * name
Definition: ssvm.h:77
#define MMAP_PAGESIZE
Definition: ssvm.h:41
unsigned char u8
Definition: types.h:56
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
u32 flags
Definition: vhost-user.h:75
int i_am_master
Definition: ssvm.h:79