2 *------------------------------------------------------------------
3 * Copyright (c) 2017 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 *------------------------------------------------------------------
21 #include <sys/types.h>
23 #include <sys/ioctl.h>
24 #include <sys/socket.h>
28 #include <sys/prctl.h>
34 #include <linux/icmp.h>
35 #include <arpa/inet.h>
37 #include <netinet/if_ether.h>
38 #include <net/if_arp.h>
39 #include <asm/byteorder.h>
44 #include <sys/eventfd.h>
45 #include <sys/timerfd.h>
46 #include <sys/epoll.h>
48 #include <linux/memfd.h>
50 /* memif protocol msg, ring and descriptor definitions */
54 /* socket messaging functions */
56 /* private structs and functions */
57 #include <memif_private.h>
59 #define ERRLIST_LEN 40
60 #define MAX_ERRBUF_LEN 256
63 #define MEMIF_MEMORY_BARRIER() __builtin_ia32_sfence ()
65 #define MEMIF_MEMORY_BARRIER() __sync_synchronize ()
66 #endif /* __x86_x64__ */
68 libmemif_main_t libmemif_main;
70 static char memif_buf[MAX_ERRBUF_LEN];
72 const char *memif_errlist[ERRLIST_LEN] = { /* MEMIF_ERR_SUCCESS */
74 /* MEMIF_ERR_SYSCALL */
75 "Unspecified syscall error (build with -DMEMIF_DBG or make debug).",
76 /* MEMIF_ERR_CONNREFUSED */
79 "Permission to resource denied.",
80 /* MEMIF_ERR_NO_FILE */
81 "Socket file does not exist",
82 /* MEMIF_ERR_FILE_LIMIT */
83 "System limit on total numer of open files reached.",
84 /* MEMIF_ERR_PROC_FILE_LIMIT */
85 "Per-process limit on total number of open files reached.",
86 /* MEMIF_ERR_ALREADY */
87 "Connection already requested.",
89 "File descriptor refers to file other than socket, or operation would block.",
90 /* MEMIF_ERR_BAD_FD */
91 "Bad file descriptor.",
94 /* MEMIF_ERR_INVAL_ARG */
96 /* MEMIF_ERR_NOCONN */
97 "Memif connection handle does not point to existing connection",
99 "Memif connection handle points to existing connection",
100 /* MEMIF_ERR_CB_FDUPDATE */
101 "Callback memif_control_fd_update_t returned error",
102 /* MEMIF_ERR_FILE_NOT_SOCK */
103 "File specified by socket filename exists and is not socket.",
104 /* MEMIF_ERR_NO_SHMFD */
105 "Missing shared memory file descriptor. (internal error)",
106 /* MEMIF_ERR_COOKIE */
107 "Invalid cookie on ring. (internal error)",
108 /* MEMIF_ERR_NOBUF_RING */
110 /* MEMIF_ERR_NOBUF */
111 "Not enough memif buffers. There are unreceived data in shared memory.",
112 /* MEMIF_ERR_NOBUF_DET */
113 "Not enough space for memif details in supplied buffer. String data might be malformed.",
114 /* MEMIF_ERR_INT_WRITE */
115 "Send interrupt error.",
116 /* MEMIF_ERR_MFMSG */
117 "Malformed message received on control channel.",
120 /* MEMIF_ERR_PROTO */
121 "Incompatible memory interface protocol version.",
123 "Unmatched interface id.",
124 /* MEMIF_ERR_ACCSLAVE */
125 "Slave cannot accept connection request.",
126 /* MEMIF_ERR_ALRCONN */
127 "Interface is already connected.",
130 /* MEMIF_ERR_SECRET */
132 /* MEMIF_ERR_NOSECRET */
134 /* MEMIF_ERR_MAXREG */
135 "Limit on total number of regions reached.",
136 /* MEMIF_ERR_MAXRING */
137 "Limit on total number of ring reached.",
138 /* MEMIF_ERR_NO_INTFD */
139 "Missing interrupt file descriptor. (internal error)",
140 /* MEMIF_ERR_DISCONNECT */
141 "Interface received disconnect request.",
142 /* MEMIF_ERR_DISCONNECTED */
143 "Interface is disconnected.",
144 /* MEMIF_ERR_UNKNOWN_MSG */
145 "Unknown message type received on control channel. (internal error)",
146 /* MEMIF_ERR_POLL_CANCEL */
147 "Memif event polling was canceled.",
148 /* MEMIF_ERR_MAX_RING */
149 "Maximum log2 ring size is 15",
150 /* MEMIF_ERR_PRIVHDR */
151 "Private headers not supported."
154 #define MEMIF_ERR_UNDEFINED "undefined error"
157 memif_strerror (int err_code)
159 if (err_code >= ERRLIST_LEN)
161 strlcpy (memif_buf, MEMIF_ERR_UNDEFINED, sizeof (memif_buf));
165 strlcpy (memif_buf, memif_errlist[err_code], sizeof (memif_buf));
173 return MEMIF_VERSION;
176 #define DBG_TX_BUF (0)
177 #define DBG_RX_BUF (1)
181 print_bytes (void *data, uint16_t len, uint8_t q)
184 printf ("\nTX:\n\t");
186 printf ("\nRX:\n\t");
188 for (i = 0; i < len; i++)
191 printf ("\n%d:\t", i);
192 printf ("%02X ", ((uint8_t *) (data))[i]);
196 #endif /* MEMIF_DBG_SHM */
199 memif_syscall_error_handler (int err_code)
201 DBG ("%s", strerror (err_code));
204 return MEMIF_ERR_SUCCESS;
205 if (err_code == EACCES)
206 return MEMIF_ERR_ACCES;
207 if (err_code == ENFILE)
208 return MEMIF_ERR_FILE_LIMIT;
209 if (err_code == EMFILE)
210 return MEMIF_ERR_PROC_FILE_LIMIT;
211 if (err_code == ENOMEM)
212 return MEMIF_ERR_NOMEM;
213 /* connection refused if master does not exist
214 this error would spam the user until master was created */
216 if (err_code == ECONNREFUSED)
217 return MEMIF_ERR_SUCCESS;
219 if (err_code == ECONNREFUSED)
220 return MEMIF_ERR_CONNREFUSED;
221 if (err_code == EALREADY)
222 return MEMIF_ERR_ALREADY;
223 if (err_code == EAGAIN)
224 return MEMIF_ERR_AGAIN;
225 if (err_code == EBADF)
226 return MEMIF_ERR_BAD_FD;
227 if (err_code == ENOENT)
228 return MEMIF_ERR_NO_FILE;
230 /* other syscall errors */
231 return MEMIF_ERR_SYSCALL;
236 get_libmemif_main (memif_socket_t * ms)
238 if (ms != NULL && ms->lm != NULL)
240 return &libmemif_main;
244 memif_add_epoll_fd (libmemif_main_t * lm, int fd, uint32_t events)
248 DBG ("invalid fd %d", fd);
251 struct epoll_event evt;
252 memset (&evt, 0, sizeof (evt));
255 if (epoll_ctl (lm->epfd, EPOLL_CTL_ADD, fd, &evt) < 0)
257 DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
260 DBG ("fd %d added to epoll", fd);
265 memif_mod_epoll_fd (libmemif_main_t * lm, int fd, uint32_t events)
269 DBG ("invalid fd %d", fd);
272 struct epoll_event evt;
273 memset (&evt, 0, sizeof (evt));
276 if (epoll_ctl (lm->epfd, EPOLL_CTL_MOD, fd, &evt) < 0)
278 DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
281 DBG ("fd %d modified on epoll", fd);
286 memif_del_epoll_fd (libmemif_main_t * lm, int fd)
290 DBG ("invalid fd %d", fd);
293 struct epoll_event evt;
294 memset (&evt, 0, sizeof (evt));
295 if (epoll_ctl (lm->epfd, EPOLL_CTL_DEL, fd, &evt) < 0)
297 DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
300 DBG ("fd %d removed from epoll", fd);
305 memif_control_fd_update (int fd, uint8_t events, void *private_ctx)
309 lm = (private_ctx == NULL) ? &libmemif_main : (libmemif_main_t *) private_ctx;
311 if (events & MEMIF_FD_EVENT_DEL)
312 return memif_del_epoll_fd (lm, fd);
315 if (events & MEMIF_FD_EVENT_READ)
317 if (events & MEMIF_FD_EVENT_WRITE)
320 if (events & MEMIF_FD_EVENT_MOD)
321 return memif_mod_epoll_fd (lm, fd, evt);
323 return memif_add_epoll_fd (lm, fd, evt);
327 add_list_elt (libmemif_main_t * lm, memif_list_elt_t * e,
328 memif_list_elt_t ** list, uint16_t * len)
330 memif_list_elt_t *tmp;
333 for (i = 0; i < *len; i++)
335 if ((*list)[i].data_struct == NULL)
337 (*list)[i].key = e->key;
338 (*list)[i].data_struct = e->data_struct;
343 tmp = lm->realloc (*list, sizeof (memif_list_elt_t) * *len * 2);
347 for (i = *len; i < *len * 2; i++)
350 tmp[i].data_struct = NULL;
353 tmp[*len].key = e->key;
354 tmp[*len].data_struct = e->data_struct;
363 get_list_elt (memif_list_elt_t ** e, memif_list_elt_t * list, uint16_t len,
373 for (i = 0; i < len; i++)
375 if (list[i].key == key)
385 /* does not free memory, only marks element as free */
387 free_list_elt (memif_list_elt_t * list, uint16_t len, int key)
390 for (i = 0; i < len; i++)
392 if (list[i].key == key)
395 list[i].data_struct = NULL;
404 free_list_elt_ctx (memif_list_elt_t * list, uint16_t len,
405 memif_connection_t * ctx)
408 for (i = 0; i < len; i++)
410 if (list[i].key == -1)
412 if (list[i].data_struct == ctx)
414 list[i].data_struct = NULL;
424 memif_control_fd_update_register (libmemif_main_t * lm,
425 memif_control_fd_update_t * cb)
427 lm->control_fd_update = cb;
431 memif_register_external_region (memif_add_external_region_t * ar,
432 memif_get_external_region_addr_t * gr,
433 memif_del_external_region_t * dr,
434 memif_get_external_buffer_offset_t * go)
436 libmemif_main_t *lm = &libmemif_main;
437 lm->add_external_region = ar;
438 lm->get_external_region_addr = gr;
439 lm->del_external_region = dr;
440 lm->get_external_buffer_offset = go;
444 memif_alloc_register (libmemif_main_t * lm, memif_alloc_t * ma)
450 memif_realloc_register (libmemif_main_t * lm, memif_realloc_t * mr)
456 memif_free_register (libmemif_main_t * lm, memif_free_t * mf)
462 memif_set_connection_request_timer (struct itimerspec timer)
464 libmemif_main_t *lm = &libmemif_main;
465 int err = MEMIF_ERR_SUCCESS;
469 /* overwrite timer, if already armed */
470 if (lm->disconn_slaves != 0)
472 if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
474 err = memif_syscall_error_handler (errno);
481 memif_per_thread_set_connection_request_timer (memif_per_thread_main_handle_t
483 struct itimerspec timer)
485 libmemif_main_t *lm = (libmemif_main_t *) pt_main;
486 int err = MEMIF_ERR_SUCCESS;
490 /* overwrite timer, if already armed */
491 if (lm->disconn_slaves != 0)
493 if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
495 err = memif_syscall_error_handler (errno);
502 memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name,
503 memif_alloc_t * memif_alloc, memif_realloc_t * memif_realloc,
504 memif_free_t * memif_free)
506 int err = MEMIF_ERR_SUCCESS; /* 0 */
507 libmemif_main_t *lm = &libmemif_main;
508 memset (lm, 0, sizeof (libmemif_main_t));
510 /* register custom memory management */
511 if (memif_alloc != NULL)
513 memif_alloc_register (lm, memif_alloc);
516 memif_alloc_register (lm, malloc);
518 if (memif_realloc != NULL)
520 memif_realloc_register (lm, memif_realloc);
523 memif_realloc_register (lm, realloc);
525 if (memif_free != NULL)
526 memif_free_register (lm, memif_free);
528 memif_free_register (lm, free);
530 if (app_name != NULL)
532 strlcpy ((char *) lm->app_name, app_name, sizeof (lm->app_name));
536 strlcpy ((char *) lm->app_name, MEMIF_DEFAULT_APP_NAME,
537 sizeof (lm->app_name));
540 lm->poll_cancel_fd = -1;
541 /* register control fd update callback */
542 if (on_control_fd_update != NULL)
543 memif_control_fd_update_register (lm, on_control_fd_update);
546 lm->epfd = epoll_create (1);
547 memif_control_fd_update_register (lm, memif_control_fd_update);
548 if ((lm->poll_cancel_fd = eventfd (0, EFD_NONBLOCK)) < 0)
551 DBG ("eventfd: %s", strerror (err));
552 return memif_syscall_error_handler (err);
554 lm->control_fd_update (lm->poll_cancel_fd, MEMIF_FD_EVENT_READ, lm->private_ctx);
555 DBG ("libmemif event polling initialized");
558 lm->control_list_len = 2;
559 lm->interrupt_list_len = 2;
560 lm->socket_list_len = 1;
561 lm->pending_list_len = 1;
564 lm->alloc (sizeof (memif_list_elt_t) * lm->control_list_len);
565 if (lm->control_list == NULL)
567 err = MEMIF_ERR_NOMEM;
571 lm->alloc (sizeof (memif_list_elt_t) * lm->interrupt_list_len);
572 if (lm->interrupt_list == NULL)
574 err = MEMIF_ERR_NOMEM;
578 lm->alloc (sizeof (memif_list_elt_t) * lm->socket_list_len);
579 if (lm->socket_list == NULL)
581 err = MEMIF_ERR_NOMEM;
585 lm->alloc (sizeof (memif_list_elt_t) * lm->pending_list_len);
586 if (lm->pending_list == NULL)
588 err = MEMIF_ERR_NOMEM;
593 for (i = 0; i < lm->control_list_len; i++)
595 lm->control_list[i].key = -1;
596 lm->control_list[i].data_struct = NULL;
598 for (i = 0; i < lm->interrupt_list_len; i++)
600 lm->interrupt_list[i].key = -1;
601 lm->interrupt_list[i].data_struct = NULL;
603 for (i = 0; i < lm->socket_list_len; i++)
605 lm->socket_list[i].key = -1;
606 lm->socket_list[i].data_struct = NULL;
608 for (i = 0; i < lm->pending_list_len; i++)
610 lm->pending_list[i].key = -1;
611 lm->pending_list[i].data_struct = NULL;
614 lm->disconn_slaves = 0;
616 lm->timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
619 err = memif_syscall_error_handler (errno);
623 lm->arm.it_value.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
624 lm->arm.it_value.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
625 lm->arm.it_interval.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
626 lm->arm.it_interval.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
628 if (lm->control_fd_update (lm->timerfd, MEMIF_FD_EVENT_READ, lm->private_ctx) < 0)
630 DBG ("callback type memif_control_fd_update_t error!");
631 err = MEMIF_ERR_CB_FDUPDATE;
635 /* Create default socket */
636 err = memif_create_socket ((memif_socket_handle_t *) &
638 MEMIF_DEFAULT_SOCKET_PATH, NULL);
639 if (err != MEMIF_ERR_SUCCESS)
650 memif_per_thread_init (memif_per_thread_main_handle_t * pt_main,
652 memif_control_fd_update_t * on_control_fd_update,
653 char *app_name, memif_alloc_t * memif_alloc,
654 memif_realloc_t * memif_realloc,
655 memif_free_t * memif_free)
657 memif_err_t err = MEMIF_ERR_SUCCESS;
661 /* Allocate unique libmemif main */
662 if (memif_alloc != NULL)
663 lm = memif_alloc (sizeof (libmemif_main_t));
665 lm = malloc (sizeof (libmemif_main_t));
668 return MEMIF_ERR_NOMEM;
670 memset (lm, 0, sizeof (libmemif_main_t));
672 /* register custom memory management */
673 if (memif_alloc != NULL)
675 memif_alloc_register (lm, memif_alloc);
678 memif_alloc_register (lm, malloc);
680 if (memif_realloc != NULL)
682 memif_realloc_register (lm, memif_realloc);
685 memif_realloc_register (lm, realloc);
687 if (memif_free != NULL)
688 memif_free_register (lm, memif_free);
690 memif_free_register (lm, free);
692 lm->private_ctx = private_ctx;
695 if (app_name != NULL)
697 strlcpy ((char *) lm->app_name, app_name, MEMIF_NAME_LEN);
701 strlcpy ((char *) lm->app_name, MEMIF_DEFAULT_APP_NAME,
702 sizeof (lm->app_name));
705 lm->poll_cancel_fd = -1;
706 /* register control fd update callback */
707 if (on_control_fd_update != NULL)
708 memif_control_fd_update_register (lm, on_control_fd_update);
711 /* private_ctx only used internally by memif_control_fd_update
712 * pointer to this libmemif main
714 lm->private_ctx = lm;
715 lm->epfd = epoll_create (1);
716 memif_control_fd_update_register (lm, memif_control_fd_update);
717 if ((lm->poll_cancel_fd = eventfd (0, EFD_NONBLOCK)) < 0)
720 DBG ("eventfd: %s", strerror (err));
721 return memif_syscall_error_handler (err);
723 lm->control_fd_update (lm->poll_cancel_fd, MEMIF_FD_EVENT_READ,
725 DBG ("libmemif event polling initialized");
728 /* Initialize lists */
729 lm->control_list_len = 2;
730 lm->interrupt_list_len = 2;
731 lm->socket_list_len = 1;
732 lm->pending_list_len = 1;
735 lm->alloc (sizeof (memif_list_elt_t) * lm->control_list_len);
736 if (lm->control_list == NULL)
738 err = MEMIF_ERR_NOMEM;
742 lm->alloc (sizeof (memif_list_elt_t) * lm->interrupt_list_len);
743 if (lm->interrupt_list == NULL)
745 err = MEMIF_ERR_NOMEM;
749 lm->alloc (sizeof (memif_list_elt_t) * lm->socket_list_len);
750 if (lm->socket_list == NULL)
752 err = MEMIF_ERR_NOMEM;
756 lm->alloc (sizeof (memif_list_elt_t) * lm->pending_list_len);
757 if (lm->pending_list == NULL)
759 err = MEMIF_ERR_NOMEM;
763 for (i = 0; i < lm->control_list_len; i++)
765 lm->control_list[i].key = -1;
766 lm->control_list[i].data_struct = NULL;
768 for (i = 0; i < lm->interrupt_list_len; i++)
770 lm->interrupt_list[i].key = -1;
771 lm->interrupt_list[i].data_struct = NULL;
773 for (i = 0; i < lm->socket_list_len; i++)
775 lm->socket_list[i].key = -1;
776 lm->socket_list[i].data_struct = NULL;
778 for (i = 0; i < lm->pending_list_len; i++)
780 lm->pending_list[i].key = -1;
781 lm->pending_list[i].data_struct = NULL;
784 /* Initialize autoconnect */
785 lm->disconn_slaves = 0;
787 lm->timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
790 err = memif_syscall_error_handler (errno);
794 lm->arm.it_value.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
795 lm->arm.it_value.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
796 lm->arm.it_interval.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
797 lm->arm.it_interval.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
799 if (lm->control_fd_update (lm->timerfd, MEMIF_FD_EVENT_READ,
800 lm->private_ctx) < 0)
802 DBG ("callback type memif_control_fd_update_t error!");
803 err = MEMIF_ERR_CB_FDUPDATE;
813 memif_per_thread_cleanup (pt_main);
817 static inline memif_ring_t *
818 memif_get_ring (memif_connection_t * conn, memif_ring_type_t type,
821 if (&conn->regions[0] == NULL)
823 void *p = conn->regions[0].addr;
825 sizeof (memif_ring_t) +
826 sizeof (memif_desc_t) * (1 << conn->run_args.log2_ring_size);
827 p += (ring_num + type * conn->run_args.num_s2m_rings) * ring_size;
829 return (memif_ring_t *) p;
833 memif_set_rx_mode (memif_conn_handle_t c, memif_rx_mode_t rx_mode,
836 memif_connection_t *conn = (memif_connection_t *) c;
838 return MEMIF_ERR_NOCONN;
840 (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->
841 run_args.num_m2s_rings;
843 return MEMIF_ERR_QID;
845 conn->rx_queues[qid].ring->flags = rx_mode;
846 DBG ("rx_mode flag: %u", conn->rx_queues[qid].ring->flags);
847 return MEMIF_ERR_SUCCESS;
851 memif_socket_start_listening (memif_socket_t * ms)
853 libmemif_main_t *lm = get_libmemif_main (ms);
854 memif_list_elt_t elt;
855 struct stat file_stat;
856 struct sockaddr_un un = { 0 };
858 int err = MEMIF_ERR_SUCCESS;
860 if (ms->type == MEMIF_SOCKET_TYPE_CLIENT)
861 return MEMIF_ERR_INVAL_ARG;
863 /* check if file exists */
864 if (stat ((char *) ms->filename, &file_stat) == 0)
866 if (S_ISSOCK (file_stat.st_mode))
867 unlink ((char *) ms->filename);
869 return memif_syscall_error_handler (errno);
872 ms->fd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
875 err = memif_syscall_error_handler (errno);
879 DBG ("socket %d created", ms->fd);
880 un.sun_family = AF_UNIX;
881 strlcpy ((char *) un.sun_path, (char *) ms->filename, sizeof (un.sun_path));
882 if (setsockopt (ms->fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
884 err = memif_syscall_error_handler (errno);
887 if (bind (ms->fd, (struct sockaddr *) &un, sizeof (un)) < 0)
889 err = memif_syscall_error_handler (errno);
892 if (listen (ms->fd, 1) < 0)
894 err = memif_syscall_error_handler (errno);
897 if (stat ((char *) ms->filename, &file_stat) < 0)
899 err = memif_syscall_error_handler (errno);
903 /* add socket to libmemif main */
905 elt.data_struct = ms;
906 add_list_elt (lm, &elt, &lm->socket_list, &lm->socket_list_len);
907 /* if lm->private_ctx == lm event polling is done by libmemif */
908 lm->control_fd_update (ms->fd, MEMIF_FD_EVENT_READ, lm->private_ctx);
910 ms->type = MEMIF_SOCKET_TYPE_LISTENER;
924 memif_create_socket (memif_socket_handle_t * sock, const char *filename,
927 libmemif_main_t *lm = &libmemif_main;
928 memif_socket_t *ms = (memif_socket_t *) * sock;
929 int i, err = MEMIF_ERR_SUCCESS;
931 for (i = 0; i < lm->socket_list_len; i++)
933 if ((ms = (memif_socket_t *) lm->socket_list[i].data_struct) != NULL)
935 if (strncmp ((char *) ms->filename, filename,
936 strlen ((char *) ms->filename)) == 0)
937 return MEMIF_ERR_INVAL_ARG;
941 /* allocate memif_socket_t */
943 ms = lm->alloc (sizeof (memif_socket_t));
946 err = MEMIF_ERR_NOMEM;
949 memset (ms, 0, sizeof (memif_socket_t));
951 memset (ms->filename, 0, sizeof (ms->filename));
952 strlcpy ((char *) ms->filename, filename, sizeof (ms->filename));
954 ms->type = MEMIF_SOCKET_TYPE_NONE;
956 ms->interface_list_len = 1;
958 lm->alloc (sizeof (memif_list_elt_t) * ms->interface_list_len);
959 if (ms->interface_list == NULL)
961 err = MEMIF_ERR_NOMEM;
964 ms->interface_list[0].key = -1;
965 ms->interface_list[0].data_struct = NULL;
979 if (ms->interface_list != NULL)
981 lm->free (ms->interface_list);
982 ms->interface_list = NULL;
983 ms->interface_list_len = 0;
992 memif_per_thread_create_socket (memif_per_thread_main_handle_t pt_main,
993 memif_socket_handle_t * sock,
994 const char *filename, void *private_ctx)
996 libmemif_main_t *lm = (libmemif_main_t *) pt_main;
997 memif_socket_t *ms = (memif_socket_t *) * sock;
998 int i, err = MEMIF_ERR_SUCCESS;
1001 return MEMIF_ERR_INVAL_ARG;
1003 for (i = 0; i < lm->socket_list_len; i++)
1005 if ((ms = (memif_socket_t *) lm->socket_list[i].data_struct) != NULL)
1007 if (strncmp ((char *) ms->filename, filename,
1008 strlen ((char *) ms->filename)) == 0)
1009 return MEMIF_ERR_INVAL_ARG;
1013 /* allocate memif_socket_t */
1015 ms = lm->alloc (sizeof (memif_socket_t));
1018 err = MEMIF_ERR_NOMEM;
1021 memset (ms, 0, sizeof (memif_socket_t));
1024 memset (ms->filename, 0, sizeof (ms->filename));
1025 strlcpy ((char *) ms->filename, filename, sizeof (ms->filename));
1027 ms->type = MEMIF_SOCKET_TYPE_NONE;
1029 ms->interface_list_len = 1;
1030 ms->interface_list =
1031 lm->alloc (sizeof (memif_list_elt_t) * ms->interface_list_len);
1032 if (ms->interface_list == NULL)
1034 err = MEMIF_ERR_NOMEM;
1037 ms->interface_list[0].key = -1;
1038 ms->interface_list[0].data_struct = NULL;
1052 if (ms->interface_list != NULL)
1054 lm->free (ms->interface_list);
1055 ms->interface_list = NULL;
1056 ms->interface_list_len = 0;
1065 memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
1066 memif_connection_update_t * on_connect,
1067 memif_connection_update_t * on_disconnect,
1068 memif_interrupt_t * on_interrupt, void *private_ctx)
1070 libmemif_main_t *lm = get_libmemif_main (args->socket);
1072 memif_list_elt_t elt;
1073 memif_connection_t *conn = (memif_connection_t *) * c;
1078 DBG ("This handle already points to existing memif.");
1079 return MEMIF_ERR_CONN;
1082 conn = (memif_connection_t *) lm->alloc (sizeof (memif_connection_t));
1085 err = MEMIF_ERR_NOMEM;
1088 memset (conn, 0, sizeof (memif_connection_t));
1090 conn->args.interface_id = args->interface_id;
1092 if (args->log2_ring_size == 0)
1093 args->log2_ring_size = MEMIF_DEFAULT_LOG2_RING_SIZE;
1094 else if (args->log2_ring_size > MEMIF_MAX_LOG2_RING_SIZE)
1096 err = MEMIF_ERR_MAX_RING;
1099 if (args->buffer_size == 0)
1100 args->buffer_size = MEMIF_DEFAULT_BUFFER_SIZE;
1101 if (args->num_s2m_rings == 0)
1102 args->num_s2m_rings = MEMIF_DEFAULT_TX_QUEUES;
1103 if (args->num_m2s_rings == 0)
1104 args->num_m2s_rings = MEMIF_DEFAULT_RX_QUEUES;
1106 conn->args.num_s2m_rings = args->num_s2m_rings;
1107 conn->args.num_m2s_rings = args->num_m2s_rings;
1108 conn->args.buffer_size = args->buffer_size;
1109 conn->args.log2_ring_size = args->log2_ring_size;
1110 conn->args.is_master = args->is_master;
1111 conn->args.mode = args->mode;
1112 conn->msg_queue = NULL;
1113 conn->regions = NULL;
1114 conn->tx_queues = NULL;
1115 conn->rx_queues = NULL;
1117 conn->on_connect = on_connect;
1118 conn->on_disconnect = on_disconnect;
1119 conn->on_interrupt = on_interrupt;
1120 conn->private_ctx = private_ctx;
1121 memset (&conn->run_args, 0, sizeof (memif_conn_run_args_t));
1123 strlcpy ((char *) conn->args.interface_name, (char *) args->interface_name,
1124 sizeof (conn->args.interface_name));
1126 if ((strlen ((char *) args->secret)) > 0)
1127 strlcpy ((char *) conn->args.secret, (char *) args->secret,
1128 sizeof (conn->args.secret));
1130 if (args->socket != NULL)
1131 conn->args.socket = args->socket;
1132 else if (lm->default_socket != NULL)
1133 conn->args.socket = lm->default_socket;
1136 err = MEMIF_ERR_INVAL_ARG;
1140 ms = (memif_socket_t *) conn->args.socket;
1142 if ((conn->args.is_master && ms->type == MEMIF_SOCKET_TYPE_CLIENT) ||
1143 (!conn->args.is_master && ms->type == MEMIF_SOCKET_TYPE_LISTENER))
1145 err = MEMIF_ERR_INVAL_ARG;
1149 elt.key = conn->args.interface_id;
1150 elt.data_struct = conn;
1151 add_list_elt (lm, &elt, &ms->interface_list, &ms->interface_list_len);
1154 if (conn->args.is_master)
1156 if (ms->type == MEMIF_SOCKET_TYPE_NONE)
1158 err = memif_socket_start_listening (ms);
1159 if (err != MEMIF_ERR_SUCCESS)
1166 elt.data_struct = conn;
1168 add_list_elt (lm, &elt, &lm->control_list,
1169 &lm->control_list_len)) < 0)
1171 err = MEMIF_ERR_NOMEM;
1175 conn->index = index;
1177 /* try connecting to master */
1178 err = memif_request_connection (conn);
1179 if ((err != MEMIF_ERR_SUCCESS) && (lm->disconn_slaves == 0))
1181 /* connection failed, arm reconnect timer (if not armed) */
1182 if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
1184 err = memif_syscall_error_handler (errno);
1188 lm->disconn_slaves++;
1203 memif_request_connection (memif_conn_handle_t c)
1205 memif_connection_t *conn = (memif_connection_t *) c;
1206 libmemif_main_t *lm;
1208 int err = MEMIF_ERR_SUCCESS;
1210 struct sockaddr_un sun;
1213 return MEMIF_ERR_NOCONN;
1215 ms = (memif_socket_t *) conn->args.socket;
1216 lm = get_libmemif_main (ms);
1219 if (conn->args.is_master || ms->type == MEMIF_SOCKET_TYPE_LISTENER)
1220 return MEMIF_ERR_INVAL_ARG;
1222 return MEMIF_ERR_ALRCONN;
1224 sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
1227 err = memif_syscall_error_handler (errno);
1231 sun.sun_family = AF_UNIX;
1233 strlcpy (sun.sun_path, (char *) ms->filename, sizeof (sun.sun_path));
1235 if (connect (sockfd, (struct sockaddr *) &sun,
1236 sizeof (struct sockaddr_un)) == 0)
1239 conn->read_fn = memif_conn_fd_read_ready;
1240 conn->write_fn = memif_conn_fd_write_ready;
1241 conn->error_fn = memif_conn_fd_error;
1243 lm->control_list[conn->index].key = conn->fd;
1244 lm->control_fd_update (sockfd,
1245 MEMIF_FD_EVENT_READ |
1246 MEMIF_FD_EVENT_WRITE, lm->private_ctx);
1248 lm->disconn_slaves--;
1249 if (lm->disconn_slaves == 0)
1251 if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL) < 0)
1253 err = memif_syscall_error_handler (errno);
1260 err = memif_syscall_error_handler (errno);
1261 strcpy ((char *) conn->remote_disconnect_string, memif_strerror (err));
1265 ms->type = MEMIF_SOCKET_TYPE_CLIENT;
1277 memif_control_fd_handler (int fd, uint8_t events)
1279 int i, err = MEMIF_ERR_SUCCESS; /* 0 */
1281 memif_list_elt_t *e = NULL;
1282 memif_connection_t *conn;
1283 libmemif_main_t *lm = &libmemif_main;
1284 if (fd == lm->timerfd)
1288 size = read (fd, &b, sizeof (b));
1293 for (i = 0; i < lm->control_list_len; i++)
1295 if ((lm->control_list[i].key < 0)
1296 && (lm->control_list[i].data_struct != NULL))
1298 conn = lm->control_list[i].data_struct;
1299 if (conn->args.is_master)
1301 err = memif_request_connection (conn);
1302 if (err != MEMIF_ERR_SUCCESS)
1303 DBG ("memif_request_connection: %s", memif_strerror (err));
1309 get_list_elt (&e, lm->interrupt_list, lm->interrupt_list_len, fd);
1312 if (((memif_connection_t *) e->data_struct)->on_interrupt != NULL)
1315 (((memif_connection_t *) e->data_struct)->
1316 args.is_master) ? ((memif_connection_t *) e->
1317 data_struct)->run_args.
1318 num_s2m_rings : ((memif_connection_t *) e->data_struct)->
1319 run_args.num_m2s_rings;
1320 for (i = 0; i < num; i++)
1322 if (((memif_connection_t *) e->data_struct)->
1323 rx_queues[i].int_fd == fd)
1325 ((memif_connection_t *) e->data_struct)->
1326 on_interrupt ((void *) e->data_struct,
1327 ((memif_connection_t *) e->
1328 data_struct)->private_ctx, i);
1329 return MEMIF_ERR_SUCCESS;
1333 return MEMIF_ERR_SUCCESS;
1335 get_list_elt (&e, lm->socket_list, lm->socket_list_len, fd);
1337 && ((memif_socket_t *) e->data_struct)->type ==
1338 MEMIF_SOCKET_TYPE_LISTENER)
1341 memif_conn_fd_accept_ready ((memif_socket_t *) e->data_struct);
1345 get_list_elt (&e, lm->pending_list, lm->pending_list_len, fd);
1348 err = memif_read_ready (lm, fd);
1352 get_list_elt (&e, lm->control_list, lm->control_list_len, fd);
1355 if (events & MEMIF_FD_EVENT_READ)
1358 ((memif_connection_t *) e->data_struct)->
1359 read_fn (e->data_struct);
1360 if (err != MEMIF_ERR_SUCCESS)
1363 if (events & MEMIF_FD_EVENT_WRITE)
1366 ((memif_connection_t *) e->data_struct)->
1367 write_fn (e->data_struct);
1368 if (err != MEMIF_ERR_SUCCESS)
1371 if (events & MEMIF_FD_EVENT_ERROR)
1374 ((memif_connection_t *) e->data_struct)->
1375 error_fn (e->data_struct);
1376 if (err != MEMIF_ERR_SUCCESS)
1382 return MEMIF_ERR_SUCCESS; /* 0 */
1389 memif_per_thread_control_fd_handler (memif_per_thread_main_handle_t pt_main,
1390 int fd, uint8_t events)
1392 int i, err = MEMIF_ERR_SUCCESS; /* 0 */
1394 memif_list_elt_t *e = NULL;
1395 memif_connection_t *conn;
1396 libmemif_main_t *lm = (libmemif_main_t *) pt_main;
1398 if (fd == lm->timerfd)
1402 size = read (fd, &b, sizeof (b));
1407 for (i = 0; i < lm->control_list_len; i++)
1409 if ((lm->control_list[i].key < 0)
1410 && (lm->control_list[i].data_struct != NULL))
1412 conn = lm->control_list[i].data_struct;
1413 if (conn->args.is_master)
1415 err = memif_request_connection (conn);
1416 if (err != MEMIF_ERR_SUCCESS)
1417 DBG ("memif_request_connection: %s", memif_strerror (err));
1423 get_list_elt (&e, lm->interrupt_list, lm->interrupt_list_len, fd);
1426 if (((memif_connection_t *) e->data_struct)->on_interrupt != NULL)
1429 (((memif_connection_t *) e->data_struct)->
1430 args.is_master) ? ((memif_connection_t *) e->
1431 data_struct)->run_args.
1432 num_s2m_rings : ((memif_connection_t *) e->data_struct)->
1433 run_args.num_m2s_rings;
1434 for (i = 0; i < num; i++)
1436 if (((memif_connection_t *) e->data_struct)->
1437 rx_queues[i].int_fd == fd)
1439 ((memif_connection_t *) e->data_struct)->
1440 on_interrupt ((void *) e->data_struct,
1441 ((memif_connection_t *) e->
1442 data_struct)->private_ctx, i);
1443 return MEMIF_ERR_SUCCESS;
1447 return MEMIF_ERR_SUCCESS;
1449 get_list_elt (&e, lm->socket_list, lm->socket_list_len, fd);
1451 && ((memif_socket_t *) e->data_struct)->type ==
1452 MEMIF_SOCKET_TYPE_LISTENER)
1455 memif_conn_fd_accept_ready ((memif_socket_t *) e->data_struct);
1459 get_list_elt (&e, lm->pending_list, lm->pending_list_len, fd);
1462 err = memif_read_ready (lm, fd);
1466 get_list_elt (&e, lm->control_list, lm->control_list_len, fd);
1469 if (events & MEMIF_FD_EVENT_READ)
1472 ((memif_connection_t *) e->data_struct)->
1473 read_fn (e->data_struct);
1474 if (err != MEMIF_ERR_SUCCESS)
1477 if (events & MEMIF_FD_EVENT_WRITE)
1480 ((memif_connection_t *) e->data_struct)->
1481 write_fn (e->data_struct);
1482 if (err != MEMIF_ERR_SUCCESS)
1485 if (events & MEMIF_FD_EVENT_ERROR)
1488 ((memif_connection_t *) e->data_struct)->
1489 error_fn (e->data_struct);
1490 if (err != MEMIF_ERR_SUCCESS)
1496 return MEMIF_ERR_SUCCESS; /* 0 */
1503 memif_poll_event (int timeout)
1505 libmemif_main_t *lm = &libmemif_main;
1506 struct epoll_event evt;
1507 int en = 0, err = MEMIF_ERR_SUCCESS; /* 0 */
1508 uint32_t events = 0;
1509 uint64_t counter = 0;
1511 memset (&evt, 0, sizeof (evt));
1512 evt.events = EPOLLIN | EPOLLOUT;
1514 sigemptyset (&sigset);
1515 en = epoll_pwait (lm->epfd, &evt, 1, timeout, &sigset);
1519 DBG ("epoll_pwait: %s", strerror (err));
1520 return memif_syscall_error_handler (err);
1524 if (evt.data.fd == lm->poll_cancel_fd)
1526 r = read (evt.data.fd, &counter, sizeof (counter));
1528 return MEMIF_ERR_DISCONNECTED;
1530 return MEMIF_ERR_POLL_CANCEL;
1532 if (evt.events & EPOLLIN)
1533 events |= MEMIF_FD_EVENT_READ;
1534 if (evt.events & EPOLLOUT)
1535 events |= MEMIF_FD_EVENT_WRITE;
1536 if (evt.events & EPOLLERR)
1537 events |= MEMIF_FD_EVENT_ERROR;
1538 err = memif_control_fd_handler (evt.data.fd, events);
1545 memif_per_thread_poll_event (memif_per_thread_main_handle_t pt_main,
1548 libmemif_main_t *lm = (libmemif_main_t *) pt_main;
1549 struct epoll_event evt;
1550 int en = 0, err = MEMIF_ERR_SUCCESS; /* 0 */
1551 uint32_t events = 0;
1552 uint64_t counter = 0;
1554 memset (&evt, 0, sizeof (evt));
1555 evt.events = EPOLLIN | EPOLLOUT;
1557 sigemptyset (&sigset);
1558 en = epoll_pwait (lm->epfd, &evt, 1, timeout, &sigset);
1562 DBG ("epoll_pwait: %s", strerror (err));
1563 return memif_syscall_error_handler (err);
1567 if (evt.data.fd == lm->poll_cancel_fd)
1569 r = read (evt.data.fd, &counter, sizeof (counter));
1571 return MEMIF_ERR_DISCONNECTED;
1573 return MEMIF_ERR_POLL_CANCEL;
1575 if (evt.events & EPOLLIN)
1576 events |= MEMIF_FD_EVENT_READ;
1577 if (evt.events & EPOLLOUT)
1578 events |= MEMIF_FD_EVENT_WRITE;
1579 if (evt.events & EPOLLERR)
1580 events |= MEMIF_FD_EVENT_ERROR;
1581 err = memif_control_fd_handler (evt.data.fd, events);
1588 memif_cancel_poll_event ()
1590 libmemif_main_t *lm = &libmemif_main;
1591 uint64_t counter = 1;
1594 if (lm->poll_cancel_fd == -1)
1596 w = write (lm->poll_cancel_fd, &counter, sizeof (counter));
1597 if (w < sizeof (counter))
1598 return MEMIF_ERR_INT_WRITE;
1604 memif_per_thread_cancel_poll_event (memif_per_thread_main_handle_t pt_main)
1606 libmemif_main_t *lm = (libmemif_main_t *) pt_main;
1607 uint64_t counter = 1;
1611 return MEMIF_ERR_INVAL_ARG;
1613 if (lm->poll_cancel_fd == -1)
1615 w = write (lm->poll_cancel_fd, &counter, sizeof (counter));
1616 if (w < sizeof (counter))
1617 return MEMIF_ERR_INT_WRITE;
1623 memif_msg_queue_free (libmemif_main_t * lm, memif_msg_queue_elt_t ** e)
1627 memif_msg_queue_free (lm, &(*e)->next);
1633 /* send disconnect msg and close interface */
1635 memif_disconnect_internal (memif_connection_t * c)
1637 int err = MEMIF_ERR_SUCCESS, i; /* 0 */
1639 libmemif_main_t *lm;
1640 memif_list_elt_t *e;
1644 DBG ("no connection");
1645 return MEMIF_ERR_NOCONN;
1648 lm = get_libmemif_main (c->args.socket);
1650 c->on_disconnect ((void *) c, c->private_ctx);
1654 memif_msg_send_disconnect (c->fd, (uint8_t *) "interface deleted", 0);
1655 lm->control_fd_update (c->fd, MEMIF_FD_EVENT_DEL, lm->private_ctx);
1658 get_list_elt (&e, lm->control_list, lm->control_list_len, c->fd);
1661 if (c->args.is_master)
1662 free_list_elt (lm->control_list, lm->control_list_len, c->fd);
1663 e->key = c->fd = -1;
1666 if (c->tx_queues != NULL)
1668 for (i = 0; i < c->tx_queues_num; i++)
1670 mq = &c->tx_queues[i];
1675 free_list_elt (lm->interrupt_list, lm->interrupt_list_len,
1680 lm->free (c->tx_queues);
1681 c->tx_queues = NULL;
1683 c->tx_queues_num = 0;
1685 if (c->rx_queues != NULL)
1687 for (i = 0; i < c->rx_queues_num; i++)
1689 mq = &c->rx_queues[i];
1694 if (c->on_interrupt != NULL)
1695 lm->control_fd_update (mq->int_fd, MEMIF_FD_EVENT_DEL,
1699 free_list_elt (lm->interrupt_list, lm->interrupt_list_len,
1704 lm->free (c->rx_queues);
1705 c->rx_queues = NULL;
1707 c->rx_queues_num = 0;
1709 for (i = 0; i < c->regions_num; i++)
1711 if (&c->regions[i] == NULL)
1713 if (c->regions[i].is_external != 0)
1715 lm->del_external_region (c->regions[i].addr,
1716 c->regions[i].region_size,
1717 c->regions[i].fd, c->private_ctx);
1721 if (munmap (c->regions[i].addr, c->regions[i].region_size) < 0)
1722 return memif_syscall_error_handler (errno);
1723 if (c->regions[i].fd > 0)
1724 close (c->regions[i].fd);
1725 c->regions[i].fd = -1;
1728 lm->free (c->regions);
1732 memset (&c->run_args, 0, sizeof (memif_conn_run_args_t));
1734 memif_msg_queue_free (lm, &c->msg_queue);
1736 if (!(c->args.is_master))
1738 if (lm->disconn_slaves == 0)
1740 if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
1742 err = memif_syscall_error_handler (errno);
1743 DBG ("timerfd_settime: arm");
1746 lm->disconn_slaves++;
1753 memif_get_socket_filename (memif_socket_handle_t sock)
1755 memif_socket_t *ms = (memif_socket_t *) sock;
1760 return (char *) ms->filename;
1764 memif_delete_socket (memif_socket_handle_t * sock)
1766 memif_socket_t *ms = (memif_socket_t *) * sock;
1767 libmemif_main_t *lm;
1769 /* check if socket is in use */
1770 if (ms == NULL || ms->use_count > 0)
1771 return MEMIF_ERR_INVAL_ARG;
1773 lm = get_libmemif_main (ms);
1775 lm->free (ms->interface_list);
1776 ms->interface_list = NULL;
1780 return MEMIF_ERR_SUCCESS;
1784 memif_delete (memif_conn_handle_t * conn)
1786 memif_connection_t *c = (memif_connection_t *) * conn;
1787 libmemif_main_t *lm;
1788 memif_socket_t *ms = NULL;
1789 int err = MEMIF_ERR_SUCCESS;
1793 DBG ("no connection");
1794 return MEMIF_ERR_NOCONN;
1799 DBG ("DISCONNECTING");
1800 err = memif_disconnect_internal (c);
1801 if (err == MEMIF_ERR_NOCONN)
1805 lm = get_libmemif_main (c->args.socket);
1807 free_list_elt_ctx (lm->control_list, lm->control_list_len, c);
1809 ms = (memif_socket_t *) c->args.socket;
1811 free_list_elt (ms->interface_list, ms->interface_list_len,
1812 c->args.interface_id);
1813 if (ms->use_count <= 0)
1815 /* stop listening on this socket */
1816 if (ms->type == MEMIF_SOCKET_TYPE_LISTENER)
1818 lm->control_fd_update (ms->fd, MEMIF_FD_EVENT_DEL, lm->private_ctx);
1819 free_list_elt (lm->socket_list, lm->socket_list_len, ms->fd);
1823 /* socket not in use */
1824 ms->type = MEMIF_SOCKET_TYPE_NONE;
1827 if (!c->args.is_master)
1829 lm->disconn_slaves--;
1830 if (lm->disconn_slaves <= 0)
1832 if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL) < 0)
1834 err = memif_syscall_error_handler (errno);
1835 DBG ("timerfd_settime: disarm");
1848 memif_connect1 (memif_connection_t * c)
1850 libmemif_main_t *lm;
1856 return MEMIF_ERR_INVAL_ARG;
1858 lm = get_libmemif_main (c->args.socket);
1860 for (i = 0; i < c->regions_num; i++)
1862 mr = &c->regions[i];
1867 if (mr->is_external)
1869 if (lm->get_external_region_addr == NULL)
1870 return MEMIF_ERR_INVAL_ARG;
1872 lm->get_external_region_addr (mr->region_size, mr->fd,
1878 return MEMIF_ERR_NO_SHMFD;
1881 mmap (NULL, mr->region_size, PROT_READ | PROT_WRITE,
1882 MAP_SHARED, mr->fd, 0)) == MAP_FAILED)
1884 return memif_syscall_error_handler (errno);
1891 for (i = 0; i < c->rx_queues_num; i++)
1893 mq = &c->rx_queues[i];
1896 mq->ring = c->regions[mq->region].addr + mq->offset;
1897 if (mq->ring->cookie != MEMIF_COOKIE)
1899 DBG ("wrong cookie on rx ring %u", i);
1900 return MEMIF_ERR_COOKIE;
1902 mq->ring->head = mq->ring->tail = mq->last_head = mq->next_buf = 0;
1906 for (i = 0; i < c->tx_queues_num; i++)
1908 mq = &c->tx_queues[i];
1911 mq->ring = c->regions[mq->region].addr + mq->offset;
1912 if (mq->ring->cookie != MEMIF_COOKIE)
1914 DBG ("wrong cookie on tx ring %u", i);
1915 return MEMIF_ERR_COOKIE;
1917 mq->ring->head = mq->ring->tail = mq->last_head = mq->next_buf = 0;
1921 lm->control_fd_update (c->fd, MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_MOD,
1928 memif_add_region (libmemif_main_t * lm, memif_connection_t * conn,
1929 uint8_t has_buffers)
1934 lm->realloc (conn->regions,
1935 sizeof (memif_region_t) * ++conn->regions_num);
1937 return MEMIF_ERR_NOMEM;
1940 r = &conn->regions[conn->regions_num - 1];
1941 memset (r, 0, sizeof (memif_region_t));
1943 if (has_buffers != 0)
1945 r->buffer_offset = 0;
1950 (conn->run_args.num_s2m_rings +
1951 conn->run_args.num_m2s_rings) * (sizeof (memif_ring_t) +
1952 sizeof (memif_desc_t) *
1954 run_args.log2_ring_size));
1957 r->region_size = (has_buffers == 0) ? r->buffer_offset : r->buffer_offset +
1958 conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1959 (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1961 if ((r->fd = memfd_create ("memif region 0", MFD_ALLOW_SEALING)) == -1)
1962 return memif_syscall_error_handler (errno);
1964 if ((fcntl (r->fd, F_ADD_SEALS, F_SEAL_SHRINK)) == -1)
1965 return memif_syscall_error_handler (errno);
1967 if ((ftruncate (r->fd, r->region_size)) == -1)
1968 return memif_syscall_error_handler (errno);
1970 if ((r->addr = mmap (NULL, r->region_size, PROT_READ | PROT_WRITE,
1971 MAP_SHARED, r->fd, 0)) == MAP_FAILED)
1972 return memif_syscall_error_handler (errno);
1974 return MEMIF_ERR_SUCCESS;
1978 memif_init_queues (libmemif_main_t * lm, memif_connection_t * conn)
1983 for (i = 0; i < conn->run_args.num_s2m_rings; i++)
1985 ring = memif_get_ring (conn, MEMIF_RING_S2M, i);
1986 DBG ("RING: %p I: %d", ring, i);
1987 ring->head = ring->tail = 0;
1988 ring->cookie = MEMIF_COOKIE;
1990 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1992 uint16_t slot = i * (1 << conn->run_args.log2_ring_size) + j;
1993 ring->desc[j].region = 1;
1994 ring->desc[j].offset =
1995 conn->regions[1].buffer_offset +
1996 (uint32_t) (slot * conn->run_args.buffer_size);
1997 ring->desc[j].length = conn->run_args.buffer_size;
2000 for (i = 0; i < conn->run_args.num_m2s_rings; i++)
2002 ring = memif_get_ring (conn, MEMIF_RING_M2S, i);
2003 DBG ("RING: %p I: %d", ring, i);
2004 ring->head = ring->tail = 0;
2005 ring->cookie = MEMIF_COOKIE;
2007 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
2009 uint16_t slot = (i + conn->run_args.num_s2m_rings) *
2010 (1 << conn->run_args.log2_ring_size) + j;
2011 ring->desc[j].region = 1;
2012 ring->desc[j].offset =
2013 conn->regions[1].buffer_offset +
2014 (uint32_t) (slot * conn->run_args.buffer_size);
2015 ring->desc[j].length = conn->run_args.buffer_size;
2019 DBG ("alloc: %p", lm->alloc);
2020 DBG ("size: %lu", sizeof (memif_queue_t) * conn->run_args.num_s2m_rings);
2022 (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
2023 conn->run_args.num_s2m_rings);
2025 return MEMIF_ERR_NOMEM;
2029 for (x = 0; x < conn->run_args.num_s2m_rings; x++)
2031 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
2032 return memif_syscall_error_handler (errno);
2033 e.key = mq[x].int_fd;
2034 e.data_struct = conn;
2035 add_list_elt (lm, &e, &lm->interrupt_list, &lm->interrupt_list_len);
2037 mq[x].ring = memif_get_ring (conn, MEMIF_RING_S2M, x);
2038 DBG ("RING: %p I: %d", mq[x].ring, x);
2039 mq[x].log2_ring_size = conn->run_args.log2_ring_size;
2042 (void *) mq[x].ring - (void *) conn->regions[mq->region].addr;
2043 mq[x].last_head = mq[x].last_tail = 0;
2046 conn->tx_queues = mq;
2047 conn->tx_queues_num = conn->run_args.num_s2m_rings;
2050 (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
2051 conn->run_args.num_m2s_rings);
2053 return MEMIF_ERR_NOMEM;
2055 for (x = 0; x < conn->run_args.num_m2s_rings; x++)
2057 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
2058 return memif_syscall_error_handler (errno);
2059 e.key = mq[x].int_fd;
2060 e.data_struct = conn;
2061 add_list_elt (lm, &e, &lm->interrupt_list, &lm->interrupt_list_len);
2063 mq[x].ring = memif_get_ring (conn, MEMIF_RING_M2S, x);
2064 DBG ("RING: %p I: %d", mq[x].ring, x);
2065 mq[x].log2_ring_size = conn->run_args.log2_ring_size;
2068 (void *) mq[x].ring - (void *) conn->regions[mq->region].addr;
2069 mq[x].last_head = mq[x].last_tail = 0;
2072 conn->rx_queues = mq;
2073 conn->rx_queues_num = conn->run_args.num_m2s_rings;
2075 return MEMIF_ERR_SUCCESS;
2079 memif_init_regions_and_queues (memif_connection_t * conn)
2082 libmemif_main_t *lm;
2085 return MEMIF_ERR_INVAL_ARG;
2087 lm = get_libmemif_main (conn->args.socket);
2089 /* region 0. rings */
2090 memif_add_region (lm, conn, /* has_buffers */ 0);
2092 /* region 1. buffers */
2093 if (lm->add_external_region)
2096 (memif_region_t *) lm->realloc (conn->regions,
2097 sizeof (memif_region_t) *
2098 ++conn->regions_num);
2100 return MEMIF_ERR_NOMEM;
2103 conn->regions[1].region_size =
2104 conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
2105 (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
2106 conn->regions[1].buffer_offset = 0;
2107 lm->add_external_region (&conn->regions[1].addr,
2108 conn->regions[1].region_size,
2109 &conn->regions[1].fd, conn->private_ctx);
2110 conn->regions[1].is_external = 1;
2114 memif_add_region (lm, conn, 1);
2117 memif_init_queues (lm, conn);
2123 memif_set_next_free_buffer (memif_conn_handle_t conn, uint16_t qid,
2124 memif_buffer_t *buf)
2126 memif_connection_t *c = (memif_connection_t *) conn;
2127 if (EXPECT_FALSE (c == NULL))
2128 return MEMIF_ERR_NOCONN;
2129 if (EXPECT_FALSE (qid >= c->tx_queues_num))
2130 return MEMIF_ERR_QID;
2131 if (EXPECT_FALSE (buf == NULL))
2132 return MEMIF_ERR_INVAL_ARG;
2134 uint16_t ring_size, ns;
2135 memif_queue_t *mq = &c->tx_queues[qid];
2136 memif_ring_t *ring = mq->ring;
2138 ring_size = (1 << mq->log2_ring_size);
2139 if (c->args.is_master)
2140 ns = ring->head - mq->next_buf;
2142 ns = ring_size - mq->next_buf + ring->tail;
2144 if ((mq->next_buf - buf->desc_index) > ns)
2145 return MEMIF_ERR_INVAL_ARG;
2147 mq->next_buf = buf->desc_index;
2149 return MEMIF_ERR_SUCCESS;
2153 memif_buffer_enq_at_idx_internal (memif_queue_t *from_q, memif_queue_t *to_q,
2154 memif_buffer_t *buf, uint16_t slot)
2156 uint16_t from_mask = (1 << from_q->log2_ring_size) - 1;
2157 uint16_t to_mask = (1 << to_q->log2_ring_size) - 1;
2158 memif_desc_t *from_d, *to_d, tmp_d;
2160 /* Get the descriptors */
2161 from_d = &from_q->ring->desc[buf->desc_index & from_mask];
2162 to_d = &to_q->ring->desc[slot & to_mask];
2164 /* Swap descriptors */
2169 /* Update descriptor index and queue for clients buffer */
2170 buf->desc_index = slot;
2175 memif_buffer_requeue (memif_conn_handle_t conn, memif_buffer_t *buf_a,
2176 memif_buffer_t *buf_b)
2178 memif_connection_t *c = (memif_connection_t *) conn;
2179 if (EXPECT_FALSE (c == NULL))
2180 return MEMIF_ERR_NOCONN;
2181 if (EXPECT_FALSE (c->args.is_master))
2182 return MEMIF_ERR_INVAL_ARG;
2183 if ((buf_a == NULL) || (buf_b == NULL))
2184 return MEMIF_ERR_INVAL_ARG;
2187 /* store buf_a information */
2188 uint16_t index_a = buf_a->desc_index;
2189 memif_queue_t *mq_a = buf_a->queue;
2191 /* swap buffers, buf_a was updated with new desc_index and queue */
2192 memif_buffer_enq_at_idx_internal ((memif_queue_t *) buf_a->queue,
2193 (memif_queue_t *) buf_b->queue, buf_a,
2196 /* update buf_b desc_index and queue */
2197 buf_b->desc_index = index_a;
2198 buf_b->queue = mq_a;
2200 return MEMIF_ERR_SUCCESS;
2204 memif_buffer_enq_tx (memif_conn_handle_t conn, uint16_t qid,
2205 memif_buffer_t * bufs, uint16_t count,
2206 uint16_t * count_out)
2208 memif_connection_t *c = (memif_connection_t *) conn;
2209 if (EXPECT_FALSE (c == NULL))
2210 return MEMIF_ERR_NOCONN;
2211 if (EXPECT_FALSE (c->fd < 0))
2212 return MEMIF_ERR_DISCONNECTED;
2213 if (EXPECT_FALSE (qid >= c->tx_queues_num))
2214 return MEMIF_ERR_QID;
2215 if (EXPECT_FALSE (!count_out))
2216 return MEMIF_ERR_INVAL_ARG;
2217 if (EXPECT_FALSE (c->args.is_master))
2218 return MEMIF_ERR_INVAL_ARG;
2220 memif_queue_t *mq = &c->tx_queues[qid];
2221 memif_ring_t *ring = mq->ring;
2223 uint16_t mask = (1 << mq->log2_ring_size) - 1;
2227 int err = MEMIF_ERR_SUCCESS; /* 0 */
2230 ring_size = (1 << mq->log2_ring_size);
2232 /* can only be called by slave */
2233 ns = ring_size - mq->next_buf + ring->tail;
2239 /* Swaps the descriptors, updates next_buf pointer and updates client
2242 memif_buffer_enq_at_idx_internal ((memif_queue_t *) b0->queue, mq, b0,
2245 mq->next_buf++; /* mark the buffer as allocated */
2252 DBG ("allocated: %u/%u bufs. Next buffer pointer %d", *count_out, count,
2257 DBG ("ring buffer full! qid: %u", qid);
2258 err = MEMIF_ERR_NOBUF_RING;
2265 memif_buffer_alloc (memif_conn_handle_t conn, uint16_t qid,
2266 memif_buffer_t * bufs, uint16_t count,
2267 uint16_t * count_out, uint16_t size)
2269 memif_connection_t *c = (memif_connection_t *) conn;
2270 if (EXPECT_FALSE (c == NULL))
2271 return MEMIF_ERR_NOCONN;
2272 if (EXPECT_FALSE (c->fd < 0))
2273 return MEMIF_ERR_DISCONNECTED;
2275 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2276 run_args.num_s2m_rings;
2277 if (EXPECT_FALSE (qid >= num))
2278 return MEMIF_ERR_QID;
2279 if (EXPECT_FALSE (!count_out))
2280 return MEMIF_ERR_INVAL_ARG;
2282 libmemif_main_t *lm = get_libmemif_main (c->args.socket);
2283 memif_queue_t *mq = &c->tx_queues[qid];
2284 memif_ring_t *ring = mq->ring;
2286 uint16_t mask = (1 << mq->log2_ring_size) - 1;
2287 uint32_t offset_mask = c->run_args.buffer_size - 1;
2290 int err = MEMIF_ERR_SUCCESS; /* 0 */
2291 uint16_t dst_left, src_left;
2292 uint16_t saved_count;
2293 uint16_t saved_next_buf;
2294 memif_buffer_t *saved_b;
2297 ring_size = (1 << mq->log2_ring_size);
2299 if (c->args.is_master)
2300 ns = ring->head - mq->next_buf;
2302 ns = ring_size - mq->next_buf + ring->tail;
2306 b0 = (bufs + *count_out);
2309 saved_count = count;
2310 saved_next_buf = mq->next_buf;
2312 b0->desc_index = mq->next_buf;
2313 ring->desc[mq->next_buf & mask].flags = 0;
2315 /* slave can produce buffer with original length */
2316 dst_left = (c->args.is_master) ? ring->desc[mq->next_buf & mask].length :
2317 c->run_args.buffer_size;
2322 if (EXPECT_FALSE (dst_left == 0))
2330 ring->desc[b0->desc_index & mask].flags |=
2331 MEMIF_DESC_FLAG_NEXT;
2332 b0->flags |= MEMIF_BUFFER_FLAG_NEXT;
2334 b0 = (bufs + *count_out);
2335 b0->desc_index = mq->next_buf;
2336 dst_left = (c->args.is_master) ?
2337 ring->desc[mq->next_buf & mask].length :
2338 c->run_args.buffer_size;
2339 ring->desc[mq->next_buf & mask].flags = 0;
2343 /* rollback allocated chain buffers */
2344 memset (saved_b, 0, sizeof (memif_buffer_t)
2345 * (saved_count - count + 1));
2346 *count_out -= saved_count - count;
2347 mq->next_buf = saved_next_buf;
2351 b0->len = memif_min (dst_left, src_left);
2353 /* slave resets buffer offset */
2354 if (c->args.is_master == 0)
2356 memif_desc_t *d = &ring->desc[mq->next_buf & mask];
2357 if (lm->get_external_buffer_offset)
2358 d->offset = lm->get_external_buffer_offset (c->private_ctx);
2360 d->offset = d->offset - (d->offset & offset_mask);
2362 b0->data = memif_get_buffer (c, ring, mq->next_buf & mask);
2364 src_left -= b0->len;
2365 dst_left -= b0->len;
2376 DBG ("allocated: %u/%u bufs. Next buffer pointer %d", *count_out, count,
2381 DBG ("ring buffer full! qid: %u", qid);
2382 err = MEMIF_ERR_NOBUF_RING;
2389 memif_refill_queue (memif_conn_handle_t conn, uint16_t qid, uint16_t count,
2392 memif_connection_t *c = (memif_connection_t *) conn;
2393 if (EXPECT_FALSE (c == NULL))
2394 return MEMIF_ERR_NOCONN;
2395 if (EXPECT_FALSE (c->fd < 0))
2396 return MEMIF_ERR_DISCONNECTED;
2398 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2399 run_args.num_m2s_rings;
2400 if (EXPECT_FALSE (qid >= num))
2401 return MEMIF_ERR_QID;
2402 libmemif_main_t *lm = get_libmemif_main (c->args.socket);
2403 memif_queue_t *mq = &c->rx_queues[qid];
2404 memif_ring_t *ring = mq->ring;
2405 uint16_t mask = (1 << mq->log2_ring_size) - 1;
2406 uint32_t offset_mask = c->run_args.buffer_size - 1;
2407 uint16_t slot, counter = 0;
2409 if (c->args.is_master)
2411 MEMIF_MEMORY_BARRIER ();
2413 (ring->tail + count <=
2414 mq->last_head) ? ring->tail + count : mq->last_head;
2415 return MEMIF_ERR_SUCCESS;
2418 uint16_t head = ring->head;
2420 uint16_t ns = (1 << mq->log2_ring_size) - head + mq->last_tail;
2421 count = (count < ns) ? count : ns;
2424 while (counter < count)
2426 d = &ring->desc[slot & mask];
2428 d->length = c->run_args.buffer_size - headroom;
2429 if (lm->get_external_buffer_offset)
2430 d->offset = lm->get_external_buffer_offset (c->private_ctx);
2432 d->offset = d->offset - (d->offset & offset_mask) + headroom;
2437 MEMIF_MEMORY_BARRIER ();
2440 return MEMIF_ERR_SUCCESS; /* 0 */
2444 memif_tx_burst (memif_conn_handle_t conn, uint16_t qid,
2445 memif_buffer_t * bufs, uint16_t count, uint16_t * tx)
2447 memif_connection_t *c = (memif_connection_t *) conn;
2448 if (EXPECT_FALSE (c == NULL))
2449 return MEMIF_ERR_NOCONN;
2450 if (EXPECT_FALSE (c->fd < 0))
2451 return MEMIF_ERR_DISCONNECTED;
2453 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2454 run_args.num_s2m_rings;
2455 if (EXPECT_FALSE (qid >= num))
2456 return MEMIF_ERR_QID;
2457 if (EXPECT_FALSE (!tx))
2458 return MEMIF_ERR_INVAL_ARG;
2460 memif_queue_t *mq = &c->tx_queues[qid];
2461 memif_ring_t *ring = mq->ring;
2462 uint16_t mask = (1 << mq->log2_ring_size) - 1;
2463 uint32_t offset_mask = c->run_args.buffer_size - 1;
2466 int64_t data_offset;
2468 int err = MEMIF_ERR_SUCCESS;
2470 if (EXPECT_FALSE (count == 0))
2471 return MEMIF_ERR_SUCCESS;
2474 if (c->args.is_master)
2482 /* set error to MEMIF_ERR_INVAL_ARG and finish the sending process
2484 if ((b0->desc_index & mask) != (index & mask))
2486 err = MEMIF_ERR_INVAL_ARG;
2489 d = &ring->desc[b0->desc_index & mask];
2490 d->length = b0->len;
2491 if (!c->args.is_master)
2494 d->offset = d->offset - (d->offset & offset_mask);
2495 // calculate offset from user data
2496 data_offset = b0->data - (d->offset + c->regions[d->region].addr);
2497 if (data_offset != 0)
2499 /* verify data offset and buffer length */
2500 if ((data_offset < 0) ||
2501 ((data_offset + b0->len) > c->run_args.buffer_size))
2503 DBG ("slot: %d, data_offset: %d, length: %d",
2504 b0->desc_index & mask, data_offset, b0->len);
2505 err = MEMIF_ERR_INVAL_ARG;
2508 d->offset += data_offset;
2512 #ifdef MEMIF_DBG_SHM
2513 printf ("offset: %-6d\n", ring->desc[b0->desc_index & mask].offset);
2514 printf ("data: %p\n",
2515 memif_get_buffer (c, ring, b0->desc_index & mask));
2516 printf ("index: %u\n", b0->desc_index);
2517 print_bytes (memif_get_buffer (c, ring, b0->desc_index & mask),
2518 ring->desc[b0->desc_index & mask].length, DBG_TX_BUF);
2519 #endif /* MEMIF_DBG_SHM */
2527 MEMIF_MEMORY_BARRIER ();
2528 if (c->args.is_master)
2529 ring->tail = b0->desc_index + 1;
2531 ring->head = b0->desc_index + 1;
2533 if ((ring->flags & MEMIF_RING_FLAG_MASK_INT) == 0)
2536 int r = write (mq->int_fd, &a, sizeof (a));
2538 return MEMIF_ERR_INT_WRITE;
2545 memif_rx_burst (memif_conn_handle_t conn, uint16_t qid,
2546 memif_buffer_t * bufs, uint16_t count, uint16_t * rx)
2548 memif_connection_t *c = (memif_connection_t *) conn;
2549 if (EXPECT_FALSE (c == NULL))
2550 return MEMIF_ERR_NOCONN;
2551 if (EXPECT_FALSE (c->fd < 0))
2552 return MEMIF_ERR_DISCONNECTED;
2554 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2555 run_args.num_m2s_rings;
2556 if (EXPECT_FALSE (qid >= num))
2557 return MEMIF_ERR_QID;
2558 if (EXPECT_FALSE (!rx))
2559 return MEMIF_ERR_INVAL_ARG;
2561 memif_queue_t *mq = &c->rx_queues[qid];
2562 memif_ring_t *ring = mq->ring;
2563 uint16_t cur_slot, last_slot;
2565 uint16_t mask = (1 << mq->log2_ring_size) - 1;
2572 cur_slot = (c->args.is_master) ? mq->last_head : mq->last_tail;
2573 last_slot = (c->args.is_master) ? ring->head : ring->tail;
2574 if (cur_slot == last_slot)
2576 r = read (mq->int_fd, &b, sizeof (b));
2577 if (EXPECT_FALSE ((r == -1) && (errno != EAGAIN)))
2578 return memif_syscall_error_handler (errno);
2580 return MEMIF_ERR_SUCCESS;
2583 ns = last_slot - cur_slot;
2589 b0->desc_index = cur_slot;
2590 b0->data = memif_get_buffer (c, ring, cur_slot & mask);
2591 b0->len = ring->desc[cur_slot & mask].length;
2592 /* slave resets buffer length */
2593 if (c->args.is_master == 0)
2595 ring->desc[cur_slot & mask].length = c->run_args.buffer_size;
2598 if (ring->desc[cur_slot & mask].flags & MEMIF_DESC_FLAG_NEXT)
2600 b0->flags |= MEMIF_BUFFER_FLAG_NEXT;
2601 ring->desc[cur_slot & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
2605 #ifdef MEMIF_DBG_SHM
2606 printf ("data: %p\n", b0->data);
2607 printf ("index: %u\n", b0->desc_index);
2608 printf ("queue: %p\n", b0->queue);
2609 print_bytes (b0->data, b0->len, DBG_RX_BUF);
2610 #endif /* MEMIF_DBG_SHM */
2618 if (c->args.is_master)
2619 mq->last_head = cur_slot;
2621 mq->last_tail = cur_slot;
2625 DBG ("not enough buffers!");
2626 return MEMIF_ERR_NOBUF;
2629 r = read (mq->int_fd, &b, sizeof (b));
2630 if (EXPECT_FALSE ((r == -1) && (errno != EAGAIN)))
2631 return memif_syscall_error_handler (errno);
2633 return MEMIF_ERR_SUCCESS; /* 0 */
2637 memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
2638 char *buf, ssize_t buflen)
2640 memif_connection_t *c = (memif_connection_t *) conn;
2641 libmemif_main_t *lm;
2643 int err = MEMIF_ERR_SUCCESS, i;
2647 return MEMIF_ERR_NOCONN;
2649 ms = (memif_socket_t *) c->args.socket;
2650 lm = get_libmemif_main (ms);
2652 l1 = strlen ((char *) c->args.interface_name);
2653 if (l0 + l1 < buflen)
2656 (uint8_t *) strcpy (buf + l0, (char *) c->args.interface_name);
2660 err = MEMIF_ERR_NOBUF_DET;
2662 l1 = strlen ((char *) lm->app_name);
2663 if (l0 + l1 < buflen)
2665 md->inst_name = (uint8_t *) strcpy (buf + l0, (char *) lm->app_name);
2669 err = MEMIF_ERR_NOBUF_DET;
2671 l1 = strlen ((char *) c->remote_if_name);
2672 if (l0 + l1 < buflen)
2674 md->remote_if_name =
2675 (uint8_t *) strcpy (buf + l0, (char *) c->remote_if_name);
2679 err = MEMIF_ERR_NOBUF_DET;
2681 l1 = strlen ((char *) c->remote_name);
2682 if (l0 + l1 < buflen)
2684 md->remote_inst_name =
2685 (uint8_t *) strcpy (buf + l0, (char *) c->remote_name);
2689 err = MEMIF_ERR_NOBUF_DET;
2691 md->id = c->args.interface_id;
2693 if (strlen ((char *) c->args.secret) > 0)
2695 l1 = strlen ((char *) c->args.secret);
2696 if (l0 + l1 < buflen)
2698 md->secret = (uint8_t *) strcpy (buf + l0, (char *) c->args.secret);
2702 err = MEMIF_ERR_NOBUF_DET;
2705 md->role = (c->args.is_master) ? 0 : 1;
2706 md->mode = c->args.mode;
2708 l1 = strlen ((char *) ms->filename);
2709 if (l0 + l1 < buflen)
2711 md->socket_filename =
2712 (uint8_t *) strcpy (buf + l0, (char *) ms->filename);
2716 err = MEMIF_ERR_NOBUF_DET;
2718 l1 = strlen ((char *) c->remote_disconnect_string);
2719 if (l0 + l1 < buflen)
2722 (uint8_t *) strcpy (buf + l0, (char *) c->remote_disconnect_string);
2726 err = MEMIF_ERR_NOBUF_DET;
2728 md->regions_num = c->regions_num;
2729 l1 = sizeof (memif_region_details_t) * md->regions_num;
2730 if (l0 + l1 <= buflen)
2732 md->regions = (memif_region_details_t *) (buf + l0);
2733 for (i = 0; i < md->regions_num; i++)
2735 md->regions[i].index = i;
2736 md->regions[i].addr = c->regions[i].addr;
2737 md->regions[i].size = c->regions[i].region_size;
2738 md->regions[i].fd = c->regions[i].fd;
2739 md->regions[i].is_external = c->regions[i].is_external;
2744 err = MEMIF_ERR_NOBUF_DET;
2747 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2748 run_args.num_m2s_rings;
2750 l1 = sizeof (memif_queue_details_t) * md->rx_queues_num;
2751 if (l0 + l1 <= buflen)
2753 md->rx_queues = (memif_queue_details_t *) (buf + l0);
2754 for (i = 0; i < md->rx_queues_num; i++)
2756 md->rx_queues[i].region = c->rx_queues[i].region;
2757 md->rx_queues[i].qid = i;
2758 md->rx_queues[i].ring_size = (1 << c->rx_queues[i].log2_ring_size);
2759 md->rx_queues[i].flags = c->rx_queues[i].ring->flags;
2760 md->rx_queues[i].head = c->rx_queues[i].ring->head;
2761 md->rx_queues[i].tail = c->rx_queues[i].ring->tail;
2762 md->rx_queues[i].buffer_size = c->run_args.buffer_size;
2767 err = MEMIF_ERR_NOBUF_DET;
2770 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2771 run_args.num_s2m_rings;
2773 l1 = sizeof (memif_queue_details_t) * md->tx_queues_num;
2774 if (l0 + l1 <= buflen)
2776 md->tx_queues = (memif_queue_details_t *) (buf + l0);
2777 for (i = 0; i < md->tx_queues_num; i++)
2779 md->tx_queues[i].region = c->tx_queues[i].region;
2780 md->tx_queues[i].qid = i;
2781 md->tx_queues[i].ring_size = (1 << c->tx_queues[i].log2_ring_size);
2782 md->tx_queues[i].flags = c->tx_queues[i].ring->flags;
2783 md->tx_queues[i].head = c->tx_queues[i].ring->head;
2784 md->tx_queues[i].tail = c->tx_queues[i].ring->tail;
2785 md->tx_queues[i].buffer_size = c->run_args.buffer_size;
2790 err = MEMIF_ERR_NOBUF_DET;
2792 md->link_up_down = (c->fd > 0) ? 1 : 0;
2798 memif_get_queue_efd (memif_conn_handle_t conn, uint16_t qid, int *efd)
2800 memif_connection_t *c = (memif_connection_t *) conn;
2805 return MEMIF_ERR_NOCONN;
2807 return MEMIF_ERR_DISCONNECTED;
2810 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2811 run_args.num_m2s_rings;
2813 return MEMIF_ERR_QID;
2815 *efd = c->rx_queues[qid].int_fd;
2817 return MEMIF_ERR_SUCCESS;
2823 libmemif_main_t *lm = &libmemif_main;
2826 err = memif_delete_socket ((memif_socket_handle_t *) & lm->default_socket);
2827 if (err != MEMIF_ERR_SUCCESS)
2830 if (lm->control_list)
2831 lm->free (lm->control_list);
2832 lm->control_list = NULL;
2833 if (lm->interrupt_list)
2834 lm->free (lm->interrupt_list);
2835 lm->interrupt_list = NULL;
2836 if (lm->socket_list)
2837 lm->free (lm->socket_list);
2838 lm->socket_list = NULL;
2839 if (lm->pending_list)
2840 lm->free (lm->pending_list);
2841 lm->pending_list = NULL;
2842 if (lm->poll_cancel_fd != -1)
2843 close (lm->poll_cancel_fd);
2845 return MEMIF_ERR_SUCCESS; /* 0 */
2849 memif_per_thread_cleanup (memif_per_thread_main_handle_t * pt_main)
2851 libmemif_main_t *lm = (libmemif_main_t *) * pt_main;
2854 return MEMIF_ERR_INVAL_ARG;
2856 /* No default socket in case of per thread */
2858 if (lm->control_list)
2859 lm->free (lm->control_list);
2860 lm->control_list = NULL;
2861 if (lm->interrupt_list)
2862 lm->free (lm->interrupt_list);
2863 lm->interrupt_list = NULL;
2864 if (lm->socket_list)
2865 lm->free (lm->socket_list);
2866 lm->socket_list = NULL;
2867 if (lm->pending_list)
2868 lm->free (lm->pending_list);
2869 lm->pending_list = NULL;
2870 if (lm->poll_cancel_fd != -1)
2871 close (lm->poll_cancel_fd);
2877 return MEMIF_ERR_SUCCESS; /* 0 */