2 *------------------------------------------------------------------
3 * Copyright (c) 2016 Cisco and/or its affiliates.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *------------------------------------------------------------------
18 #include <vppinfra/lock.h>
23 #define MEMIF_VERSION_MAJOR 0
24 #define MEMIF_VERSION_MINOR 1
25 #define MEMIF_VERSION ((MEMIF_VERSION_MAJOR << 8) | MEMIF_VERSION_MINOR)
27 #define MEMIF_MSG_TYPE_CONNECT_REQ 0
28 #define MEMIF_MSG_TYPE_CONNECT_RESP 1
29 #define MEMIF_MSG_TYPE_DISCONNECT 2
31 /* Connection-request parameters: */
34 #define MEMIF_DEFAULT_RING_SIZE 1024
36 #define MEMIF_DEFAULT_RX_QUEUES 1
38 #define MEMIF_DEFAULT_TX_QUEUES 1
40 #define MEMIF_DEFAULT_BUFFER_SIZE 2048
43 /* Connection-response parameters: */
47 typedef struct __attribute__ ((packed))
50 #define MEMIF_DESC_FLAG_NEXT (1 << 0)
59 STATIC_ASSERT_SIZEOF (memif_desc_t, 32);
63 u16 head __attribute__ ((aligned (128)));
64 u16 tail __attribute__ ((aligned (128)));
65 memif_desc_t desc[0] __attribute__ ((aligned (128)));
70 u32 cookie __attribute__ ((aligned (128)));
98 memif_file_t connection;
100 } memif_pending_conn_t;
104 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
105 clib_spinlock_t lockp;
107 #define MEMIF_IF_FLAG_ADMIN_UP (1 << 0)
108 #define MEMIF_IF_FLAG_IS_SLAVE (1 << 1)
109 #define MEMIF_IF_FLAG_CONNECTING (1 << 2)
110 #define MEMIF_IF_FLAG_CONNECTED (1 << 3)
111 #define MEMIF_IF_FLAG_DELETING (1 << 4)
118 u32 per_interface_next_index;
120 uword listener_index;
121 memif_file_t connection;
122 memif_file_t interrupt_line;
133 memif_ring_data_t *ring_data;
142 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
144 /** API message ID base */
147 /* pool of all memory interfaces */
148 memif_if_t *interfaces;
150 /* pool of all listeners */
151 memif_listener_t *listeners;
153 /* pool of pending connections */
154 memif_pending_conn_t *pending_conns;
156 /* bitmap of pending rx interfaces */
157 uword *pending_input_bitmap;
159 /* rx buffer cache */
162 /* hash of all registered keys */
163 mhash_t if_index_by_key;
165 /* first cpu index */
166 u32 input_cpu_first_index;
168 /* total cpu count */
172 u8 *default_socket_filename;
173 #define MEMIF_DEFAULT_SOCKET_FILENAME "/var/vpp/memif.sock"
176 extern memif_main_t memif_main;
177 extern vnet_device_class_t memif_device_class;
178 extern vlib_node_registration_t memif_input_node;
182 MEMIF_PROCESS_EVENT_START = 1,
183 MEMIF_PROCESS_EVENT_STOP = 2,
184 } memif_process_event_t;
200 } memif_create_if_args_t;
202 int memif_create_if (vlib_main_t * vm, memif_create_if_args_t * args);
203 int memif_delete_if (vlib_main_t * vm, u64 key);
204 void memif_disconnect (vlib_main_t * vm, memif_if_t * mif);
205 clib_error_t *memif_plugin_api_hookup (vlib_main_t * vm);
207 #ifndef __NR_memfd_create
208 #if defined __x86_64__
209 #define __NR_memfd_create 319
210 #elif defined __arm__
211 #define __NR_memfd_create 385
212 #elif defined __aarch64__
213 #define __NR_memfd_create 279
215 #error "__NR_memfd_create unknown for this architecture"
219 static_always_inline u8
220 memif_get_rx_queues (memif_if_t * mif)
224 if (mif->flags & MEMIF_IF_FLAG_IS_SLAVE)
225 rx_queues = mif->num_m2s_rings;
227 rx_queues = mif->num_s2m_rings;
232 static_always_inline u8
233 memif_get_tx_queues (memif_if_t * mif)
237 if (mif->flags & MEMIF_IF_FLAG_IS_SLAVE)
238 tx_queues = mif->num_s2m_rings;
240 tx_queues = mif->num_m2s_rings;
246 memfd_create (const char *name, unsigned int flags)
248 return syscall (__NR_memfd_create, name, flags);
257 static_always_inline memif_ring_t *
258 memif_get_ring (memif_if_t * mif, memif_ring_type_t type, u16 ring_num)
260 if (vec_len (mif->regions) == 0)
262 void *p = mif->regions[0];
264 sizeof (memif_ring_t) +
265 sizeof (memif_desc_t) * (1 << mif->log2_ring_size);
266 p += sizeof (memif_shm_t);
267 p += (ring_num + type * mif->num_s2m_rings) * ring_size;
269 return (memif_ring_t *) p;
272 static_always_inline void *
273 memif_get_buffer (memif_if_t * mif, memif_ring_t * ring, u16 slot)
275 u16 region = ring->desc[slot].region;
276 return mif->regions[region] + ring->desc[slot].offset;
279 #ifndef F_LINUX_SPECIFIC_BASE
280 #define F_LINUX_SPECIFIC_BASE 1024
282 #define MFD_ALLOW_SEALING 0x0002U
283 #define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
284 #define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10)
286 #define F_SEAL_SEAL 0x0001 /* prevent further seals from being set */
287 #define F_SEAL_SHRINK 0x0002 /* prevent file from shrinking */
288 #define F_SEAL_GROW 0x0004 /* prevent file from growing */
289 #define F_SEAL_WRITE 0x0008 /* prevent writes */
292 * fd.io coding-style-patch-verification: ON
295 * eval: (c-set-style "gnu")