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