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 static char memif_buf[MAX_ERRBUF_LEN];
70 const char *memif_errlist[ERRLIST_LEN] = { /* MEMIF_ERR_SUCCESS */
72 /* MEMIF_ERR_SYSCALL */
73 "Unspecified syscall error (build with -DMEMIF_DBG or make debug).",
74 /* MEMIF_ERR_CONNREFUSED */
77 "Permission to resource denied.",
78 /* MEMIF_ERR_NO_FILE */
79 "Socket file does not exist",
80 /* MEMIF_ERR_FILE_LIMIT */
81 "System limit on total numer of open files reached.",
82 /* MEMIF_ERR_PROC_FILE_LIMIT */
83 "Per-process limit on total number of open files reached.",
84 /* MEMIF_ERR_ALREADY */
85 "Connection already requested.",
87 "File descriptor refers to file other than socket, or operation would block.",
88 /* MEMIF_ERR_BAD_FD */
89 "Bad file descriptor.",
92 /* MEMIF_ERR_INVAL_ARG */
94 /* MEMIF_ERR_NOCONN */
95 "Memif connection handle does not point to existing connection",
97 "Memif connection handle points to existing connection",
98 /* MEMIF_ERR_CB_FDUPDATE */
99 "Callback memif_control_fd_update_t returned error",
100 /* MEMIF_ERR_FILE_NOT_SOCK */
101 "File specified by socket filename exists and is not socket.",
102 /* MEMIF_ERR_NO_SHMFD */
103 "Missing shared memory file descriptor. (internal error)",
104 /* MEMIF_ERR_COOKIE */
105 "Invalid cookie on ring. (internal error)",
106 /* MEMIF_ERR_NOBUF_RING */
108 /* MEMIF_ERR_NOBUF */
109 "Not enough memif buffers. There are unreceived data in shared memory.",
110 /* MEMIF_ERR_NOBUF_DET */
111 "Not enough space for memif details in supplied buffer. String data might be malformed.",
112 /* MEMIF_ERR_INT_WRITE */
113 "Send interrupt error.",
114 /* MEMIF_ERR_MFMSG */
115 "Malformed message received on control channel.",
118 /* MEMIF_ERR_PROTO */
119 "Incompatible memory interface protocol version.",
121 "Unmatched interface id.",
122 /* MEMIF_ERR_ACCSLAVE */
123 "Slave cannot accept connection request.",
124 /* MEMIF_ERR_ALRCONN */
125 "Interface is already connected.",
128 /* MEMIF_ERR_SECRET */
130 /* MEMIF_ERR_NOSECRET */
132 /* MEMIF_ERR_MAXREG */
133 "Limit on total number of regions reached.",
134 /* MEMIF_ERR_MAXRING */
135 "Limit on total number of ring reached.",
136 /* MEMIF_ERR_NO_INTFD */
137 "Missing interrupt file descriptor. (internal error)",
138 /* MEMIF_ERR_DISCONNECT */
139 "Interface received disconnect request.",
140 /* MEMIF_ERR_DISCONNECTED */
141 "Interface is disconnected.",
142 /* MEMIF_ERR_UNKNOWN_MSG */
143 "Unknown message type received on control channel. (internal error)",
144 /* MEMIF_ERR_POLL_CANCEL */
145 "Memif event polling was canceled.",
146 /* MEMIF_ERR_MAX_RING */
147 "Maximum log2 ring size is 15",
148 /* MEMIF_ERR_PRIVHDR */
149 "Private headers not supported."
152 #define MEMIF_ERR_UNDEFINED "undefined error"
155 memif_strerror (int err_code)
157 if (err_code >= ERRLIST_LEN)
159 strlcpy (memif_buf, MEMIF_ERR_UNDEFINED, sizeof (memif_buf));
163 strlcpy (memif_buf, memif_errlist[err_code], sizeof (memif_buf));
164 memif_buf[strlen (memif_errlist[err_code])] = '\0';
172 return MEMIF_VERSION;
176 memif_get_version_str ()
178 #define __STR_HELPER(x) #x
179 #define __STR(x) __STR_HELPER (x)
180 return __STR (MEMIF_VERSION_MAJOR) "." __STR (MEMIF_VERSION_MINOR);
185 #define DBG_TX_BUF (0)
186 #define DBG_RX_BUF (1)
190 print_bytes (void *data, uint16_t len, uint8_t q)
193 printf ("\nTX:\n\t");
195 printf ("\nRX:\n\t");
197 for (i = 0; i < len; i++)
200 printf ("\n%d:\t", i);
201 printf ("%02X ", ((uint8_t *) (data))[i]);
205 #endif /* MEMIF_DBG_SHM */
208 memif_syscall_error_handler (int err_code)
210 DBG ("%s", strerror (err_code));
213 return MEMIF_ERR_SUCCESS;
214 if (err_code == EACCES)
215 return MEMIF_ERR_ACCES;
216 if (err_code == ENFILE)
217 return MEMIF_ERR_FILE_LIMIT;
218 if (err_code == EMFILE)
219 return MEMIF_ERR_PROC_FILE_LIMIT;
220 if (err_code == ENOMEM)
221 return MEMIF_ERR_NOMEM;
222 /* connection refused if master does not exist
223 this error would spam the user until master was created */
225 if (err_code == ECONNREFUSED)
226 return MEMIF_ERR_SUCCESS;
228 if (err_code == ECONNREFUSED)
229 return MEMIF_ERR_CONNREFUSED;
230 if (err_code == EALREADY)
231 return MEMIF_ERR_ALREADY;
232 if (err_code == EAGAIN)
233 return MEMIF_ERR_AGAIN;
234 if (err_code == EBADF)
235 return MEMIF_ERR_BAD_FD;
236 if (err_code == ENOENT)
237 return MEMIF_ERR_NO_FILE;
239 /* other syscall errors */
240 return MEMIF_ERR_SYSCALL;
244 memif_add_epoll_fd (memif_socket_t *ms, memif_fd_event_t fde, uint32_t events)
248 DBG ("invalid fd %d", fde.fd);
251 struct epoll_event evt;
252 memset (&evt, 0, sizeof (evt));
254 evt.data.ptr = fde.private_ctx;
255 if (epoll_ctl (ms->epfd, EPOLL_CTL_ADD, fde.fd, &evt) < 0)
257 DBG ("epoll_ctl: %s fd %d", strerror (errno), fde.fd);
260 DBG ("fd %d added to epoll", fde.fd);
265 memif_mod_epoll_fd (memif_socket_t *ms, memif_fd_event_t fde, uint32_t events)
269 DBG ("invalid fd %d", fde.fd);
272 struct epoll_event evt;
273 memset (&evt, 0, sizeof (evt));
275 evt.data.ptr = fde.private_ctx;
276 if (epoll_ctl (ms->epfd, EPOLL_CTL_MOD, fde.fd, &evt) < 0)
278 DBG ("epoll_ctl: %s fd %d", strerror (errno), fde.fd);
281 DBG ("fd %d modified on epoll", fde.fd);
286 memif_del_epoll_fd (memif_socket_t *ms, memif_fd_event_t fde)
290 DBG ("invalid fd %d", fde.fd);
293 struct epoll_event evt;
294 memset (&evt, 0, sizeof (evt));
295 if (epoll_ctl (ms->epfd, EPOLL_CTL_DEL, fde.fd, &evt) < 0)
297 DBG ("epoll_ctl: %s fd %d", strerror (errno), fde.fd);
300 DBG ("fd %d removed from epoll", fde.fd);
305 memif_control_fd_update (memif_fd_event_t fde, void *private_ctx)
307 memif_socket_t *ms = (memif_socket_t *) private_ctx;
311 return MEMIF_ERR_INVAL_ARG;
313 if (fde.type & MEMIF_FD_EVENT_DEL)
314 return memif_del_epoll_fd (ms, fde);
317 if (fde.type & MEMIF_FD_EVENT_READ)
319 if (fde.type & MEMIF_FD_EVENT_WRITE)
322 if (fde.type & MEMIF_FD_EVENT_MOD)
323 return memif_mod_epoll_fd (ms, fde, evt);
325 return memif_add_epoll_fd (ms, fde, evt);
329 memif_control_fd_update_register (memif_socket_t *ms,
330 memif_control_fd_update_t *cb)
332 ms->args.on_control_fd_update = cb;
336 memif_register_external_region (memif_socket_handle_t sock,
337 memif_add_external_region_t *ar,
338 memif_get_external_region_addr_t *gr,
339 memif_del_external_region_t *dr,
340 memif_get_external_buffer_offset_t *go)
342 memif_socket_t *ms = (memif_socket_t *) sock;
343 ms->add_external_region = ar;
344 ms->get_external_region_addr = gr;
345 ms->del_external_region = dr;
346 ms->get_external_buffer_offset = go;
350 memif_alloc_register (memif_socket_t *ms, memif_alloc_t *ma)
356 memif_realloc_register (memif_socket_t *ms, memif_realloc_t *mr)
358 ms->args.realloc = mr;
362 memif_free_register (memif_socket_t *ms, memif_free_t *mf)
367 static inline memif_ring_t *
368 memif_get_ring (memif_connection_t * conn, memif_ring_type_t type,
371 if (&conn->regions[0] == NULL)
373 void *p = conn->regions[0].addr;
375 sizeof (memif_ring_t) +
376 sizeof (memif_desc_t) * (1 << conn->run_args.log2_ring_size);
377 p += (ring_num + type * conn->run_args.num_s2m_rings) * ring_size;
379 return (memif_ring_t *) p;
383 memif_set_rx_mode (memif_conn_handle_t c, memif_rx_mode_t rx_mode,
386 memif_connection_t *conn = (memif_connection_t *) c;
388 return MEMIF_ERR_NOCONN;
390 (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->
391 run_args.num_m2s_rings;
393 return MEMIF_ERR_QID;
395 conn->rx_queues[qid].ring->flags = rx_mode;
396 DBG ("rx_mode flag: %u", conn->rx_queues[qid].ring->flags);
397 return MEMIF_ERR_SUCCESS;
401 memif_poll_cancel_handler (memif_fd_event_type_t type, void *private_ctx)
403 return MEMIF_ERR_POLL_CANCEL;
407 memif_connect_handler (memif_fd_event_type_t type, void *private_ctx)
409 memif_socket_t *ms = (memif_socket_t *) private_ctx;
410 memif_connection_t *c;
412 if (ms->timer_fd >= 0)
415 ssize_t __attribute__ ((unused)) r;
417 Have to read the timer fd else it stays read-ready
418 and makes epoll_pwait() return without sleeping
420 r = read (ms->timer_fd, &u64, sizeof (u64));
423 /* loop ms->slave_interfaces and request connection for disconnected ones */
424 TAILQ_FOREACH (c, &ms->slave_interfaces, next)
426 /* connected or connecting */
427 if (c->control_channel != NULL)
431 memif_request_connection (c);
434 return MEMIF_ERR_SUCCESS;
438 memif_set_connection_request_timer (memif_socket_handle_t sock,
439 struct itimerspec timer)
441 memif_socket_t *ms = (memif_socket_t *) sock;
442 memif_fd_event_t fde;
443 memif_fd_event_data_t *fdata;
447 return MEMIF_ERR_INVAL_ARG;
449 if (ms->timer_fd < 0)
451 /* only create new timer if there is a valid interval */
452 if (timer.it_interval.tv_sec == 0 && timer.it_interval.tv_nsec == 0)
453 return MEMIF_ERR_SUCCESS;
456 ms->timer_fd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
457 if (ms->timer_fd < 0)
458 return memif_syscall_error_handler (errno);
460 /* start listening for events */
461 fdata = ms->args.alloc (sizeof (*fdata));
462 fdata->event_handler = memif_connect_handler;
463 fdata->private_ctx = ms;
465 fde.fd = ms->timer_fd;
466 fde.type = MEMIF_FD_EVENT_READ;
467 fde.private_ctx = fdata;
469 ctx = ms->epfd != -1 ? ms : ms->private_ctx;
470 ms->args.on_control_fd_update (fde, ctx);
473 ms->args.connection_request_timer = timer;
476 if (timerfd_settime (ms->timer_fd, 0, &ms->args.connection_request_timer,
478 return memif_syscall_error_handler (errno);
480 return MEMIF_ERR_SUCCESS;
484 memif_create_socket (memif_socket_handle_t *sock, memif_socket_args_t *args,
487 memif_socket_t *ms = (memif_socket_t *) * sock;
488 memif_fd_event_t fde;
489 memif_fd_event_data_t *fdata;
490 int i, err = MEMIF_ERR_SUCCESS;
493 /* allocate memif_socket_t */
495 if (args->alloc != NULL)
496 ms = args->alloc (sizeof (memif_socket_t));
498 ms = malloc (sizeof (memif_socket_t));
501 err = MEMIF_ERR_NOMEM;
506 memset (ms, 0, sizeof (memif_socket_t));
508 ms->listener_fd = -1;
509 ms->poll_cancel_fd = -1;
512 /* copy arguments to internal struct */
513 memcpy (&ms->args, args, sizeof (*args));
514 ms->private_ctx = private_ctx;
516 if (ms->args.alloc == NULL)
517 memif_alloc_register (ms, malloc);
518 if (ms->args.realloc == NULL)
519 memif_realloc_register (ms, realloc);
520 if (ms->args.free == NULL)
521 memif_free_register (ms, free);
523 TAILQ_INIT (&ms->master_interfaces);
524 TAILQ_INIT (&ms->slave_interfaces);
526 /* FIXME: implement connection request timer */
528 /* initialize internal epoll */
529 if (ms->args.on_control_fd_update == NULL)
531 ms->epfd = epoll_create (1);
532 /* register default fd update callback */
533 memif_control_fd_update_register (ms, memif_control_fd_update);
534 ms->poll_cancel_fd = eventfd (0, EFD_NONBLOCK);
535 if (ms->poll_cancel_fd < 0)
538 DBG ("eventfd: %s", strerror (err));
539 return memif_syscall_error_handler (err);
541 /* add interrupt fd to epfd */
542 fdata = ms->args.alloc (sizeof (*fdata));
543 fdata->event_handler = memif_poll_cancel_handler;
544 fdata->private_ctx = ms;
546 fde.fd = ms->poll_cancel_fd;
547 fde.type = MEMIF_FD_EVENT_READ;
548 fde.private_ctx = fdata;
550 ctx = ms->epfd != -1 ? ms : ms->private_ctx;
551 ms->args.on_control_fd_update (fde, ctx);
555 memif_set_connection_request_timer (ms, ms->args.connection_request_timer);
556 if (err != MEMIF_ERR_SUCCESS)
569 if (ms->poll_cancel_fd != -1)
570 close (ms->poll_cancel_fd);
575 memif_socket_handle_t
576 memif_get_socket_handle (memif_conn_handle_t conn)
578 memif_connection_t *c = (memif_connection_t *) conn;
583 return c->args.socket;
587 memif_get_socket_path (memif_socket_handle_t sock)
589 memif_socket_t *ms = (memif_socket_t *) sock;
594 return ms->args.path;
598 memif_get_listener_fd (memif_socket_handle_t sock)
600 memif_socket_t *ms = (memif_socket_t *) sock;
605 return ms->listener_fd;
609 memif_set_listener_fd (memif_socket_handle_t sock, int fd)
611 memif_socket_t *ms = (memif_socket_t *) sock;
612 memif_fd_event_t fde;
613 memif_fd_event_data_t *fdata;
616 if ((ms == NULL) || (fd < 0))
617 return MEMIF_ERR_INVAL_ARG;
619 fdata = ms->args.alloc (sizeof (*fdata));
621 return MEMIF_ERR_NOMEM;
623 ms->listener_fd = fd;
625 fdata->event_handler = memif_listener_handler;
626 fdata->private_ctx = ms;
627 ctx = ms->epfd != -1 ? ms : ms->private_ctx;
628 /* send fd to epoll */
629 fde.fd = ms->listener_fd;
630 fde.type = MEMIF_FD_EVENT_READ;
631 fde.private_ctx = fdata;
632 ms->args.on_control_fd_update (fde, ctx);
634 return MEMIF_ERR_SUCCESS;
638 memif_create (memif_conn_handle_t *c, memif_conn_args_t *args,
639 memif_connection_update_t *on_connect,
640 memif_connection_update_t *on_disconnect,
641 memif_on_interrupt_t *on_interrupt, void *private_ctx)
644 memif_connection_t *conn = (memif_connection_t *) * c;
645 memif_socket_t *ms = (memif_socket_t *) args->socket;
649 DBG ("This handle already points to existing memif.");
650 return MEMIF_ERR_CONN;
655 DBG ("Missing memif socket");
656 return MEMIF_ERR_INVAL_ARG;
659 conn = (memif_connection_t *) ms->args.alloc (sizeof (*conn));
662 err = MEMIF_ERR_NOMEM;
665 memset (conn, 0, sizeof (memif_connection_t));
667 conn->args.interface_id = args->interface_id;
669 if (args->log2_ring_size == 0)
670 args->log2_ring_size = MEMIF_DEFAULT_LOG2_RING_SIZE;
671 else if (args->log2_ring_size > MEMIF_MAX_LOG2_RING_SIZE)
673 err = MEMIF_ERR_MAX_RING;
676 if (args->buffer_size == 0)
677 args->buffer_size = MEMIF_DEFAULT_BUFFER_SIZE;
678 if (args->num_s2m_rings == 0)
679 args->num_s2m_rings = MEMIF_DEFAULT_TX_QUEUES;
680 if (args->num_m2s_rings == 0)
681 args->num_m2s_rings = MEMIF_DEFAULT_RX_QUEUES;
683 conn->args.num_s2m_rings = args->num_s2m_rings;
684 conn->args.num_m2s_rings = args->num_m2s_rings;
685 conn->args.buffer_size = args->buffer_size;
686 conn->args.log2_ring_size = args->log2_ring_size;
687 conn->args.is_master = args->is_master;
688 conn->args.mode = args->mode;
689 conn->args.socket = args->socket;
690 conn->regions = NULL;
691 conn->tx_queues = NULL;
692 conn->rx_queues = NULL;
693 conn->control_channel = NULL;
694 conn->on_connect = on_connect;
695 conn->on_disconnect = on_disconnect;
696 conn->on_interrupt = on_interrupt;
697 conn->private_ctx = private_ctx;
698 memset (&conn->run_args, 0, sizeof (memif_conn_run_args_t));
700 uint8_t l = sizeof (conn->args.interface_name);
701 strlcpy ((char *) conn->args.interface_name, (char *) args->interface_name,
704 if ((l = strlen ((char *) args->secret)) > 0)
705 strlcpy ((char *) conn->args.secret, (char *) args->secret,
706 sizeof (conn->args.secret));
709 TAILQ_INSERT_TAIL (&ms->master_interfaces, conn, next);
711 TAILQ_INSERT_TAIL (&ms->slave_interfaces, conn, next);
713 err = memif_request_connection (conn);
714 if (err != MEMIF_ERR_SUCCESS && err != MEMIF_ERR_CONNREFUSED)
717 TAILQ_REMOVE (&ms->master_interfaces, conn, next);
719 TAILQ_REMOVE (&ms->slave_interfaces, conn, next);
729 ms->args.free (conn);
735 memif_path_is_abstract (const char *filename)
737 return (filename[0] == '@');
741 memif_request_connection (memif_conn_handle_t c)
743 memif_connection_t *conn = (memif_connection_t *) c;
745 int err = MEMIF_ERR_SUCCESS;
747 struct sockaddr_un un = { 0 };
748 struct stat file_stat;
750 memif_control_channel_t *cc = NULL;
751 memif_fd_event_t fde;
752 memif_fd_event_data_t *fdata = NULL;
753 int sunlen = sizeof (un);
757 return MEMIF_ERR_NOCONN;
759 ms = (memif_socket_t *) conn->args.socket;
761 /* if control channel is assigned, the interface is either connected or
763 if (conn->control_channel != NULL)
764 return MEMIF_ERR_ALRCONN;
765 /* if interface is master and the socket is already listener we are done */
766 if (conn->args.is_master && (ms->listener_fd != -1))
767 return MEMIF_ERR_SUCCESS;
769 sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
772 err = memif_syscall_error_handler (errno);
776 un.sun_family = AF_UNIX;
778 /* use memcpy to support abstract socket
779 * ms->args.path is already a valid socket path
781 memcpy (un.sun_path, ms->args.path, sizeof (un.sun_path) - 1);
783 /* allocate fd event data */
784 fdata = ms->args.alloc (sizeof (*fdata));
787 err = MEMIF_ERR_NOMEM;
791 if (memif_path_is_abstract (ms->args.path))
793 /* Ensure the string is NULL terminated */
794 un.sun_path[sizeof (un.sun_path) - 1] = '\0';
795 /* sunlen is strlen(un.sun_path) + sizeof(un.sun_family) */
796 sunlen = strlen (un.sun_path) + (sizeof (un) - sizeof (un.sun_path));
797 /* Handle abstract socket by converting '@' -> '\0' */
798 un.sun_path[0] = '\0';
801 if (conn->args.is_master != 0)
803 /* Configure socket optins */
804 if (setsockopt (sockfd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
806 err = memif_syscall_error_handler (errno);
809 if (bind (sockfd, (struct sockaddr *) &un, sunlen) < 0)
811 err = memif_syscall_error_handler (errno);
814 if (listen (sockfd, 1) < 0)
816 err = memif_syscall_error_handler (errno);
819 if (!memif_path_is_abstract (ms->args.path))
821 /* Verify that the socket was created */
822 if (stat ((char *) ms->args.path, &file_stat) < 0)
824 err = memif_syscall_error_handler (errno);
829 /* assign listener fd */
830 ms->listener_fd = sockfd;
832 fdata->event_handler = memif_listener_handler;
833 fdata->private_ctx = ms;
837 cc = ms->args.alloc (sizeof (*cc));
840 err = MEMIF_ERR_NOMEM;
843 if (connect (sockfd, (struct sockaddr *) &un, sunlen) != 0)
845 err = MEMIF_ERR_CONNREFUSED;
849 /* Create control channel */
853 TAILQ_INIT (&cc->msg_queue);
855 /* assign control channel to endpoint */
856 conn->control_channel = cc;
858 fdata->event_handler = memif_control_channel_handler;
859 fdata->private_ctx = cc;
862 /* if event polling is done internally, send memif socket as context */
863 ctx = ms->epfd != -1 ? ms : ms->private_ctx;
864 /* send fd to epoll */
866 fde.type = MEMIF_FD_EVENT_READ;
867 fde.private_ctx = fdata;
868 ms->args.on_control_fd_update (fde, ctx);
877 ms->args.free (fdata);
881 conn->control_channel = cc = NULL;
886 memif_control_fd_handler (void *ptr, memif_fd_event_type_t events)
888 memif_fd_event_data_t *fdata = (memif_fd_event_data_t *) ptr;
891 return MEMIF_ERR_INVAL_ARG;
893 return fdata->event_handler (events, fdata->private_ctx);
897 memif_interrupt_handler (memif_fd_event_type_t type, void *private_ctx)
899 memif_interrupt_t *idata = (memif_interrupt_t *) private_ctx;
902 return MEMIF_ERR_INVAL_ARG;
904 return idata->c->on_interrupt (idata->c, idata->c->private_ctx, idata->qid);
908 memif_poll_event (memif_socket_handle_t sock, int timeout)
910 memif_socket_t *ms = (memif_socket_t *) sock;
911 struct epoll_event evt;
912 int en = 0, err = MEMIF_ERR_SUCCESS; /* 0 */
913 memif_fd_event_type_t events = 0;
914 uint64_t counter = 0;
919 return MEMIF_ERR_INVAL_ARG;
921 memset (&evt, 0, sizeof (evt));
922 evt.events = EPOLLIN | EPOLLOUT;
923 sigemptyset (&sigset);
924 en = epoll_pwait (ms->epfd, &evt, 1, timeout, &sigset);
928 DBG ("epoll_pwait: %s", strerror (err));
929 return memif_syscall_error_handler (err);
933 if (evt.events & EPOLLIN)
934 events |= MEMIF_FD_EVENT_READ;
935 if (evt.events & EPOLLOUT)
936 events |= MEMIF_FD_EVENT_WRITE;
937 if (evt.events & EPOLLERR)
938 events |= MEMIF_FD_EVENT_ERROR;
939 return memif_control_fd_handler (evt.data.ptr, events);
941 return MEMIF_ERR_SUCCESS;
945 memif_cancel_poll_event (memif_socket_handle_t sock)
947 memif_socket_t *ms = (memif_socket_t *) sock;
948 uint64_t counter = 1;
951 if (ms->poll_cancel_fd == -1)
952 return MEMIF_ERR_INVAL_ARG;
953 w = write (ms->poll_cancel_fd, &counter, sizeof (counter));
954 if (w < sizeof (counter))
955 return MEMIF_ERR_INT_WRITE;
957 return MEMIF_ERR_SUCCESS;
961 memif_close_queues (memif_socket_t *ms, memif_queue_t *queues, int nqueues)
963 memif_fd_event_t fde;
968 for (i = 0; i < nqueues; i++)
975 /* Stop listening for events */
977 fde.type = MEMIF_FD_EVENT_DEL;
978 ctx = ms->epfd != -1 ? ms : ms->private_ctx;
979 ms->args.on_control_fd_update (fde, ctx);
987 /* send disconnect msg and close interface */
989 memif_disconnect_internal (memif_connection_t * c)
991 int err = MEMIF_ERR_SUCCESS, i; /* 0 */
993 memif_socket_t *ms = (memif_socket_t *) c->args.socket;
994 memif_fd_event_t fde;
997 c->on_disconnect ((void *) c, c->private_ctx);
999 /* Delete control channel */
1000 if (c->control_channel != NULL)
1001 memif_delete_control_channel (c->control_channel);
1003 if (c->tx_queues != NULL)
1005 memif_close_queues (ms, c->tx_queues, c->tx_queues_num);
1006 ms->args.free (c->tx_queues);
1007 c->tx_queues = NULL;
1009 c->tx_queues_num = 0;
1011 if (c->rx_queues != NULL)
1013 memif_close_queues (ms, c->rx_queues, c->rx_queues_num);
1014 ms->args.free (c->rx_queues);
1015 c->rx_queues = NULL;
1017 c->rx_queues_num = 0;
1019 /* TODO: Slave reuse regions */
1021 for (i = 0; i < c->regions_num; i++)
1023 if (&c->regions[i] == NULL)
1025 if (c->regions[i].is_external != 0)
1027 ms->del_external_region (c->regions[i].addr,
1028 c->regions[i].region_size, c->regions[i].fd,
1033 if (munmap (c->regions[i].addr, c->regions[i].region_size) < 0)
1034 return memif_syscall_error_handler (errno);
1035 if (c->regions[i].fd > 0)
1036 close (c->regions[i].fd);
1037 c->regions[i].fd = -1;
1040 ms->args.free (c->regions);
1044 memset (&c->run_args, 0, sizeof (memif_conn_run_args_t));
1050 memif_get_socket_filename (memif_socket_handle_t sock)
1052 memif_socket_t *ms = (memif_socket_t *) sock;
1057 return (char *) ms->args.path;
1061 memif_delete_socket (memif_socket_handle_t * sock)
1063 memif_socket_t *ms = (memif_socket_t *) * sock;
1064 memif_fd_event_t fde;
1067 /* check if socket is in use */
1068 if (ms == NULL || !TAILQ_EMPTY (&ms->master_interfaces) ||
1069 !TAILQ_EMPTY (&ms->slave_interfaces))
1070 return MEMIF_ERR_INVAL_ARG;
1072 if (ms->listener_fd > 0)
1074 fde.fd = ms->listener_fd;
1075 fde.type = MEMIF_FD_EVENT_DEL;
1076 ctx = ms->epfd != -1 ? ms : ms->private_ctx;
1077 ms->args.on_control_fd_update (fde, ctx);
1079 ms->listener_fd = -1;
1081 if (ms->poll_cancel_fd > 0)
1083 fde.fd = ms->poll_cancel_fd;
1084 fde.type = MEMIF_FD_EVENT_DEL;
1085 ctx = ms->epfd != -1 ? ms : ms->private_ctx;
1086 ms->args.on_control_fd_update (fde, ctx);
1088 ms->poll_cancel_fd = -1;
1097 return MEMIF_ERR_SUCCESS;
1101 memif_delete (memif_conn_handle_t * conn)
1103 memif_connection_t *c = (memif_connection_t *) * conn;
1105 int err = MEMIF_ERR_SUCCESS;
1109 DBG ("no connection");
1110 return MEMIF_ERR_NOCONN;
1113 err = memif_disconnect_internal (c);
1115 ms = (memif_socket_t *) c->args.socket;
1117 if (c->args.is_master)
1118 TAILQ_REMOVE (&ms->master_interfaces, c, next);
1120 TAILQ_REMOVE (&ms->slave_interfaces, c, next);
1121 /* TODO: don't listen with empty interface queue */
1131 memif_connect1 (memif_connection_t * c)
1139 return MEMIF_ERR_INVAL_ARG;
1141 ms = (memif_socket_t *) c->args.socket;
1143 for (i = 0; i < c->regions_num; i++)
1145 mr = &c->regions[i];
1150 if (mr->is_external)
1152 if (ms->get_external_region_addr == NULL)
1153 return MEMIF_ERR_INVAL_ARG;
1154 mr->addr = ms->get_external_region_addr (
1155 mr->region_size, mr->fd, c->private_ctx);
1160 return MEMIF_ERR_NO_SHMFD;
1163 mmap (NULL, mr->region_size, PROT_READ | PROT_WRITE,
1164 MAP_SHARED, mr->fd, 0)) == MAP_FAILED)
1166 return memif_syscall_error_handler (errno);
1173 for (i = 0; i < c->rx_queues_num; i++)
1175 mq = &c->rx_queues[i];
1178 mq->ring = c->regions[mq->region].addr + mq->offset;
1179 if (mq->ring->cookie != MEMIF_COOKIE)
1181 DBG ("wrong cookie on rx ring %u", i);
1182 return MEMIF_ERR_COOKIE;
1184 mq->ring->head = mq->ring->tail = mq->last_head = mq->next_buf = 0;
1188 for (i = 0; i < c->tx_queues_num; i++)
1190 mq = &c->tx_queues[i];
1193 mq->ring = c->regions[mq->region].addr + mq->offset;
1194 if (mq->ring->cookie != MEMIF_COOKIE)
1196 DBG ("wrong cookie on tx ring %u", i);
1197 return MEMIF_ERR_COOKIE;
1199 mq->ring->head = mq->ring->tail = mq->last_head = mq->next_buf = 0;
1207 memif_add_region (memif_connection_t *conn, uint8_t has_buffers)
1210 memif_socket_t *ms = (memif_socket_t *) conn->args.socket;
1212 r = ms->args.realloc (conn->regions,
1213 sizeof (memif_region_t) * ++conn->regions_num);
1215 return MEMIF_ERR_NOMEM;
1218 r = &conn->regions[conn->regions_num - 1];
1219 memset (r, 0, sizeof (memif_region_t));
1221 if (has_buffers != 0)
1223 r->buffer_offset = 0;
1228 (conn->run_args.num_s2m_rings +
1229 conn->run_args.num_m2s_rings) * (sizeof (memif_ring_t) +
1230 sizeof (memif_desc_t) *
1232 run_args.log2_ring_size));
1235 r->region_size = (has_buffers == 0) ? r->buffer_offset : r->buffer_offset +
1236 conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1237 (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1239 if ((r->fd = memfd_create ("memif region 0", MFD_ALLOW_SEALING)) == -1)
1240 return memif_syscall_error_handler (errno);
1242 if ((fcntl (r->fd, F_ADD_SEALS, F_SEAL_SHRINK)) == -1)
1243 return memif_syscall_error_handler (errno);
1245 if ((ftruncate (r->fd, r->region_size)) == -1)
1246 return memif_syscall_error_handler (errno);
1248 if ((r->addr = mmap (NULL, r->region_size, PROT_READ | PROT_WRITE,
1249 MAP_SHARED, r->fd, 0)) == MAP_FAILED)
1250 return memif_syscall_error_handler (errno);
1252 return MEMIF_ERR_SUCCESS;
1256 memif_init_queues (memif_connection_t *conn)
1260 memif_socket_t *ms = (memif_socket_t *) conn->args.socket;
1262 for (i = 0; i < conn->run_args.num_s2m_rings; i++)
1264 ring = memif_get_ring (conn, MEMIF_RING_S2M, i);
1265 DBG ("RING: %p I: %d", ring, i);
1266 ring->head = ring->tail = 0;
1267 ring->cookie = MEMIF_COOKIE;
1269 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1271 uint16_t slot = i * (1 << conn->run_args.log2_ring_size) + j;
1272 ring->desc[j].region = 1;
1273 ring->desc[j].offset =
1274 conn->regions[1].buffer_offset +
1275 (uint32_t) (slot * conn->run_args.buffer_size);
1276 ring->desc[j].length = conn->run_args.buffer_size;
1279 for (i = 0; i < conn->run_args.num_m2s_rings; i++)
1281 ring = memif_get_ring (conn, MEMIF_RING_M2S, i);
1282 DBG ("RING: %p I: %d", ring, i);
1283 ring->head = ring->tail = 0;
1284 ring->cookie = MEMIF_COOKIE;
1286 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1288 uint16_t slot = (i + conn->run_args.num_s2m_rings) *
1289 (1 << conn->run_args.log2_ring_size) + j;
1290 ring->desc[j].region = 1;
1291 ring->desc[j].offset =
1292 conn->regions[1].buffer_offset +
1293 (uint32_t) (slot * conn->run_args.buffer_size);
1294 ring->desc[j].length = conn->run_args.buffer_size;
1298 mq = (memif_queue_t *) ms->args.alloc (sizeof (memif_queue_t) *
1299 conn->run_args.num_s2m_rings);
1301 return MEMIF_ERR_NOMEM;
1305 for (x = 0; x < conn->run_args.num_s2m_rings; x++)
1307 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1308 return memif_syscall_error_handler (errno);
1310 mq[x].ring = memif_get_ring (conn, MEMIF_RING_S2M, x);
1311 DBG ("RING: %p I: %d", mq[x].ring, x);
1312 mq[x].log2_ring_size = conn->run_args.log2_ring_size;
1315 (void *) mq[x].ring - (void *) conn->regions[mq->region].addr;
1316 mq[x].last_head = mq[x].last_tail = 0;
1319 conn->tx_queues = mq;
1320 conn->tx_queues_num = conn->run_args.num_s2m_rings;
1322 mq = (memif_queue_t *) ms->args.alloc (sizeof (memif_queue_t) *
1323 conn->run_args.num_m2s_rings);
1325 return MEMIF_ERR_NOMEM;
1327 for (x = 0; x < conn->run_args.num_m2s_rings; x++)
1329 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1330 return memif_syscall_error_handler (errno);
1332 mq[x].ring = memif_get_ring (conn, MEMIF_RING_M2S, x);
1333 DBG ("RING: %p I: %d", mq[x].ring, x);
1334 mq[x].log2_ring_size = conn->run_args.log2_ring_size;
1337 (void *) mq[x].ring - (void *) conn->regions[mq->region].addr;
1338 mq[x].last_head = mq[x].last_tail = 0;
1341 conn->rx_queues = mq;
1342 conn->rx_queues_num = conn->run_args.num_m2s_rings;
1344 return MEMIF_ERR_SUCCESS;
1348 memif_init_regions_and_queues (memif_connection_t * conn)
1351 memif_socket_t *ms = (memif_socket_t *) conn->args.socket;
1353 /* region 0. rings */
1354 memif_add_region (conn, /* has_buffers */ 0);
1356 /* region 1. buffers */
1357 if (ms->add_external_region)
1359 r = (memif_region_t *) ms->args.realloc (
1360 conn->regions, sizeof (memif_region_t) * ++conn->regions_num);
1362 return MEMIF_ERR_NOMEM;
1365 conn->regions[1].region_size =
1366 conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1367 (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1368 conn->regions[1].buffer_offset = 0;
1369 ms->add_external_region (&conn->regions[1].addr,
1370 conn->regions[1].region_size,
1371 &conn->regions[1].fd, conn->private_ctx);
1372 conn->regions[1].is_external = 1;
1376 memif_add_region (conn, 1);
1379 memif_init_queues (conn);
1385 memif_set_next_free_buffer (memif_conn_handle_t conn, uint16_t qid,
1386 memif_buffer_t *buf)
1388 memif_connection_t *c = (memif_connection_t *) conn;
1389 if (EXPECT_FALSE (c == NULL))
1390 return MEMIF_ERR_NOCONN;
1391 if (EXPECT_FALSE (qid >= c->tx_queues_num))
1392 return MEMIF_ERR_QID;
1393 if (EXPECT_FALSE (buf == NULL))
1394 return MEMIF_ERR_INVAL_ARG;
1396 uint16_t ring_size, ns;
1397 memif_queue_t *mq = &c->tx_queues[qid];
1398 memif_ring_t *ring = mq->ring;
1400 ring_size = (1 << mq->log2_ring_size);
1401 if (c->args.is_master)
1402 ns = ring->head - mq->next_buf;
1404 ns = ring_size - mq->next_buf + ring->tail;
1406 if ((mq->next_buf - buf->desc_index) > ns)
1407 return MEMIF_ERR_INVAL_ARG;
1409 mq->next_buf = buf->desc_index;
1411 return MEMIF_ERR_SUCCESS;
1415 memif_buffer_enq_at_idx_internal (memif_queue_t *from_q, memif_queue_t *to_q,
1416 memif_buffer_t *buf, uint16_t slot)
1418 uint16_t from_mask = (1 << from_q->log2_ring_size) - 1;
1419 uint16_t to_mask = (1 << to_q->log2_ring_size) - 1;
1420 memif_desc_t *from_d, *to_d, tmp_d;
1422 /* Get the descriptors */
1423 from_d = &from_q->ring->desc[buf->desc_index & from_mask];
1424 to_d = &to_q->ring->desc[slot & to_mask];
1426 /* Swap descriptors */
1431 /* Update descriptor index and queue for clients buffer */
1432 buf->desc_index = slot;
1437 memif_buffer_requeue (memif_conn_handle_t conn, memif_buffer_t *buf_a,
1438 memif_buffer_t *buf_b)
1440 memif_connection_t *c = (memif_connection_t *) conn;
1441 if (EXPECT_FALSE (c == NULL))
1442 return MEMIF_ERR_NOCONN;
1443 if (EXPECT_FALSE (c->args.is_master))
1444 return MEMIF_ERR_INVAL_ARG;
1445 if ((buf_a == NULL) || (buf_b == NULL))
1446 return MEMIF_ERR_INVAL_ARG;
1449 /* store buf_a information */
1450 uint16_t index_a = buf_a->desc_index;
1451 memif_queue_t *mq_a = buf_a->queue;
1453 /* swap buffers, buf_a was updated with new desc_index and queue */
1454 memif_buffer_enq_at_idx_internal ((memif_queue_t *) buf_a->queue,
1455 (memif_queue_t *) buf_b->queue, buf_a,
1458 /* update buf_b desc_index and queue */
1459 buf_b->desc_index = index_a;
1460 buf_b->queue = mq_a;
1462 return MEMIF_ERR_SUCCESS;
1466 memif_buffer_enq_tx (memif_conn_handle_t conn, uint16_t qid,
1467 memif_buffer_t * bufs, uint16_t count,
1468 uint16_t * count_out)
1470 memif_connection_t *c = (memif_connection_t *) conn;
1471 if (EXPECT_FALSE (c == NULL))
1472 return MEMIF_ERR_NOCONN;
1473 if (EXPECT_FALSE (c->control_channel == NULL))
1474 return MEMIF_ERR_DISCONNECTED;
1475 if (EXPECT_FALSE (qid >= c->tx_queues_num))
1476 return MEMIF_ERR_QID;
1477 if (EXPECT_FALSE (!count_out))
1478 return MEMIF_ERR_INVAL_ARG;
1479 if (EXPECT_FALSE (c->args.is_master))
1480 return MEMIF_ERR_INVAL_ARG;
1482 memif_queue_t *mq = &c->tx_queues[qid];
1483 memif_ring_t *ring = mq->ring;
1485 uint16_t mask = (1 << mq->log2_ring_size) - 1;
1489 int err = MEMIF_ERR_SUCCESS; /* 0 */
1492 ring_size = (1 << mq->log2_ring_size);
1494 /* can only be called by slave */
1495 ns = ring_size - mq->next_buf + ring->tail;
1501 /* Swaps the descriptors, updates next_buf pointer and updates client
1504 memif_buffer_enq_at_idx_internal ((memif_queue_t *) b0->queue, mq, b0,
1507 mq->next_buf++; /* mark the buffer as allocated */
1514 DBG ("allocated: %u/%u bufs. Next buffer pointer %d", *count_out, count,
1519 DBG ("ring buffer full! qid: %u", qid);
1520 err = MEMIF_ERR_NOBUF_RING;
1527 memif_buffer_alloc (memif_conn_handle_t conn, uint16_t qid,
1528 memif_buffer_t * bufs, uint16_t count,
1529 uint16_t * count_out, uint16_t size)
1531 memif_connection_t *c = (memif_connection_t *) conn;
1532 if (EXPECT_FALSE (c == NULL))
1533 return MEMIF_ERR_NOCONN;
1534 if (EXPECT_FALSE (c->control_channel == NULL))
1535 return MEMIF_ERR_DISCONNECTED;
1537 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1538 run_args.num_s2m_rings;
1539 if (EXPECT_FALSE (qid >= num))
1540 return MEMIF_ERR_QID;
1541 if (EXPECT_FALSE (!count_out))
1542 return MEMIF_ERR_INVAL_ARG;
1544 memif_socket_t *ms = (memif_socket_t *) c->args.socket;
1545 memif_queue_t *mq = &c->tx_queues[qid];
1546 memif_ring_t *ring = mq->ring;
1548 uint16_t mask = (1 << mq->log2_ring_size) - 1;
1551 int err = MEMIF_ERR_SUCCESS; /* 0 */
1552 uint16_t dst_left, src_left;
1553 uint16_t saved_count;
1554 uint16_t saved_next_buf;
1556 memif_buffer_t *saved_b;
1559 ring_size = (1 << mq->log2_ring_size);
1561 if (c->args.is_master)
1562 ns = ring->head - mq->next_buf;
1564 ns = ring_size - mq->next_buf + ring->tail;
1568 b0 = (bufs + *count_out);
1571 saved_count = count;
1572 saved_next_buf = mq->next_buf;
1574 b0->desc_index = mq->next_buf;
1575 ring->desc[mq->next_buf & mask].flags = 0;
1578 /* slave can produce buffer with original length */
1579 dst_left = (c->args.is_master) ? ring->desc[mq->next_buf & mask].length :
1580 c->run_args.buffer_size;
1585 if (EXPECT_FALSE (dst_left == 0))
1593 ring->desc[b0->desc_index & mask].flags |=
1594 MEMIF_DESC_FLAG_NEXT;
1595 b0->flags |= MEMIF_BUFFER_FLAG_NEXT;
1597 b0 = (bufs + *count_out);
1598 b0->desc_index = mq->next_buf;
1599 dst_left = (c->args.is_master) ?
1600 ring->desc[mq->next_buf & mask].length :
1601 c->run_args.buffer_size;
1602 ring->desc[mq->next_buf & mask].flags = 0;
1606 /* rollback allocated chain buffers */
1607 memset (saved_b, 0, sizeof (memif_buffer_t)
1608 * (saved_count - count + 1));
1609 *count_out -= saved_count - count;
1610 mq->next_buf = saved_next_buf;
1614 b0->len = memif_min (dst_left, src_left);
1616 /* slave resets buffer offset */
1617 if (c->args.is_master == 0)
1619 memif_desc_t *d = &ring->desc[slot & mask];
1620 if (ms->get_external_buffer_offset)
1621 d->offset = ms->get_external_buffer_offset (c->private_ctx);
1623 d->offset = d->offset - (d->offset % c->run_args.buffer_size);
1625 b0->data = memif_get_buffer (c, ring, mq->next_buf & mask);
1627 src_left -= b0->len;
1628 dst_left -= b0->len;
1639 DBG ("allocated: %u/%u bufs. Next buffer pointer %d", *count_out, count,
1644 DBG ("ring buffer full! qid: %u", qid);
1645 err = MEMIF_ERR_NOBUF_RING;
1652 memif_refill_queue (memif_conn_handle_t conn, uint16_t qid, uint16_t count,
1655 memif_connection_t *c = (memif_connection_t *) conn;
1656 if (EXPECT_FALSE (c == NULL))
1657 return MEMIF_ERR_NOCONN;
1658 if (EXPECT_FALSE (c->control_channel == NULL))
1659 return MEMIF_ERR_DISCONNECTED;
1661 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1662 run_args.num_m2s_rings;
1663 if (EXPECT_FALSE (qid >= num))
1664 return MEMIF_ERR_QID;
1665 memif_socket_t *ms = (memif_socket_t *) c->args.socket;
1666 memif_queue_t *mq = &c->rx_queues[qid];
1667 memif_ring_t *ring = mq->ring;
1668 uint16_t mask = (1 << mq->log2_ring_size) - 1;
1669 uint16_t slot, counter = 0;
1671 if (c->args.is_master)
1673 MEMIF_MEMORY_BARRIER ();
1675 (ring->tail + count <=
1676 mq->last_head) ? ring->tail + count : mq->last_head;
1677 return MEMIF_ERR_SUCCESS;
1680 uint16_t head = ring->head;
1682 uint16_t ns = (1 << mq->log2_ring_size) - head + mq->last_tail;
1683 count = (count < ns) ? count : ns;
1686 while (counter < count)
1688 d = &ring->desc[slot & mask];
1690 d->length = c->run_args.buffer_size - headroom;
1691 if (ms->get_external_buffer_offset)
1692 d->offset = ms->get_external_buffer_offset (c->private_ctx);
1695 d->offset - (d->offset % c->run_args.buffer_size) + headroom;
1700 MEMIF_MEMORY_BARRIER ();
1703 return MEMIF_ERR_SUCCESS; /* 0 */
1707 memif_tx_burst (memif_conn_handle_t conn, uint16_t qid,
1708 memif_buffer_t * bufs, uint16_t count, uint16_t * tx)
1710 memif_connection_t *c = (memif_connection_t *) conn;
1711 if (EXPECT_FALSE (c == NULL))
1712 return MEMIF_ERR_NOCONN;
1713 if (EXPECT_FALSE (c->control_channel == NULL))
1714 return MEMIF_ERR_DISCONNECTED;
1716 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1717 run_args.num_s2m_rings;
1718 if (EXPECT_FALSE (qid >= num))
1719 return MEMIF_ERR_QID;
1720 if (EXPECT_FALSE (!tx))
1721 return MEMIF_ERR_INVAL_ARG;
1723 memif_queue_t *mq = &c->tx_queues[qid];
1724 memif_ring_t *ring = mq->ring;
1725 uint16_t mask = (1 << mq->log2_ring_size) - 1;
1728 int64_t data_offset;
1730 int err = MEMIF_ERR_SUCCESS;
1732 if (EXPECT_FALSE (count == 0))
1733 return MEMIF_ERR_SUCCESS;
1736 if (c->args.is_master)
1744 /* set error to MEMIF_ERR_INVAL_ARG and finish the sending process
1746 if ((b0->desc_index & mask) != (index & mask))
1748 err = MEMIF_ERR_INVAL_ARG;
1751 d = &ring->desc[b0->desc_index & mask];
1752 d->length = b0->len;
1754 ((b0->flags & MEMIF_BUFFER_FLAG_NEXT) == 1) ? MEMIF_DESC_FLAG_NEXT : 0;
1755 if (!c->args.is_master)
1758 d->offset = d->offset - (d->offset % c->run_args.buffer_size);
1759 // calculate offset from user data
1760 data_offset = b0->data - (d->offset + c->regions[d->region].addr);
1761 if (data_offset != 0)
1763 /* verify data offset and buffer length */
1764 if ((data_offset < 0) ||
1765 ((data_offset + b0->len) > c->run_args.buffer_size))
1767 DBG ("slot: %d, data_offset: %ld, length: %d",
1768 b0->desc_index & mask, data_offset, b0->len);
1769 err = MEMIF_ERR_INVAL_ARG;
1772 d->offset += data_offset;
1776 #ifdef MEMIF_DBG_SHM
1777 printf ("offset: %-6d\n", ring->desc[b0->desc_index & mask].offset);
1778 printf ("data: %p\n",
1779 memif_get_buffer (c, ring, b0->desc_index & mask));
1780 printf ("index: %u\n", b0->desc_index);
1781 print_bytes (memif_get_buffer (c, ring, b0->desc_index & mask),
1782 ring->desc[b0->desc_index & mask].length, DBG_TX_BUF);
1783 #endif /* MEMIF_DBG_SHM */
1791 MEMIF_MEMORY_BARRIER ();
1792 if (c->args.is_master)
1793 ring->tail = b0->desc_index + 1;
1795 ring->head = b0->desc_index + 1;
1797 if ((ring->flags & MEMIF_RING_FLAG_MASK_INT) == 0)
1800 int r = write (mq->int_fd, &a, sizeof (a));
1802 return MEMIF_ERR_INT_WRITE;
1809 memif_rx_burst (memif_conn_handle_t conn, uint16_t qid,
1810 memif_buffer_t * bufs, uint16_t count, uint16_t * rx)
1812 memif_connection_t *c = (memif_connection_t *) conn;
1813 if (EXPECT_FALSE (c == NULL))
1814 return MEMIF_ERR_NOCONN;
1815 if (EXPECT_FALSE (c->control_channel == NULL))
1816 return MEMIF_ERR_DISCONNECTED;
1818 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1819 run_args.num_m2s_rings;
1820 if (EXPECT_FALSE (qid >= num))
1821 return MEMIF_ERR_QID;
1822 if (EXPECT_FALSE (!rx))
1823 return MEMIF_ERR_INVAL_ARG;
1825 memif_queue_t *mq = &c->rx_queues[qid];
1826 memif_ring_t *ring = mq->ring;
1827 uint16_t cur_slot, last_slot;
1829 uint16_t mask = (1 << mq->log2_ring_size) - 1;
1836 cur_slot = (c->args.is_master) ? mq->last_head : mq->last_tail;
1837 last_slot = (c->args.is_master) ? ring->head : ring->tail;
1838 if (cur_slot == last_slot)
1840 r = read (mq->int_fd, &b, sizeof (b));
1841 if (EXPECT_FALSE ((r == -1) && (errno != EAGAIN)))
1842 return memif_syscall_error_handler (errno);
1844 return MEMIF_ERR_SUCCESS;
1847 ns = last_slot - cur_slot;
1853 b0->desc_index = cur_slot;
1854 b0->data = memif_get_buffer (c, ring, cur_slot & mask);
1855 b0->len = ring->desc[cur_slot & mask].length;
1857 /* slave resets buffer length */
1858 if (c->args.is_master == 0)
1860 ring->desc[cur_slot & mask].length = c->run_args.buffer_size;
1863 if (ring->desc[cur_slot & mask].flags & MEMIF_DESC_FLAG_NEXT)
1865 b0->flags |= MEMIF_BUFFER_FLAG_NEXT;
1866 ring->desc[cur_slot & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
1870 #ifdef MEMIF_DBG_SHM
1871 printf ("data: %p\n", b0->data);
1872 printf ("index: %u\n", b0->desc_index);
1873 printf ("queue: %p\n", b0->queue);
1874 print_bytes (b0->data, b0->len, DBG_RX_BUF);
1875 #endif /* MEMIF_DBG_SHM */
1883 if (c->args.is_master)
1884 mq->last_head = cur_slot;
1886 mq->last_tail = cur_slot;
1890 DBG ("not enough buffers!");
1891 return MEMIF_ERR_NOBUF;
1894 r = read (mq->int_fd, &b, sizeof (b));
1895 if (EXPECT_FALSE ((r == -1) && (errno != EAGAIN)))
1896 return memif_syscall_error_handler (errno);
1898 return MEMIF_ERR_SUCCESS; /* 0 */
1902 memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
1903 char *buf, ssize_t buflen)
1905 memif_connection_t *c = (memif_connection_t *) conn;
1907 int err = MEMIF_ERR_SUCCESS, i;
1911 return MEMIF_ERR_NOCONN;
1913 ms = (memif_socket_t *) c->args.socket;
1915 l1 = strlen ((char *) c->args.interface_name);
1916 if (l0 + l1 < buflen)
1919 (uint8_t *) strcpy (buf + l0, (char *) c->args.interface_name);
1923 err = MEMIF_ERR_NOBUF_DET;
1925 l1 = strlen ((char *) ms->args.app_name);
1926 if (l0 + l1 < buflen)
1929 (uint8_t *) strcpy (buf + l0, (char *) ms->args.app_name);
1933 err = MEMIF_ERR_NOBUF_DET;
1935 l1 = strlen ((char *) c->remote_if_name);
1936 if (l0 + l1 < buflen)
1938 md->remote_if_name =
1939 (uint8_t *) strcpy (buf + l0, (char *) c->remote_if_name);
1943 err = MEMIF_ERR_NOBUF_DET;
1945 l1 = strlen ((char *) c->remote_name);
1946 if (l0 + l1 < buflen)
1948 md->remote_inst_name =
1949 (uint8_t *) strcpy (buf + l0, (char *) c->remote_name);
1953 err = MEMIF_ERR_NOBUF_DET;
1955 md->id = c->args.interface_id;
1957 if (strlen ((char *) c->args.secret) > 0)
1959 l1 = strlen ((char *) c->args.secret);
1960 if (l0 + l1 < buflen)
1962 md->secret = (uint8_t *) strcpy (buf + l0, (char *) c->args.secret);
1966 err = MEMIF_ERR_NOBUF_DET;
1969 md->role = (c->args.is_master) ? 0 : 1;
1970 md->mode = c->args.mode;
1973 if (l0 + l1 < buflen)
1975 md->socket_path = (uint8_t *) memcpy (buf + l0, ms->args.path, 108);
1979 err = MEMIF_ERR_NOBUF_DET;
1981 l1 = strlen ((char *) c->remote_disconnect_string);
1982 if (l0 + l1 < buflen)
1985 (uint8_t *) strcpy (buf + l0, (char *) c->remote_disconnect_string);
1989 err = MEMIF_ERR_NOBUF_DET;
1991 md->regions_num = c->regions_num;
1992 l1 = sizeof (memif_region_details_t) * md->regions_num;
1993 if (l0 + l1 <= buflen)
1995 md->regions = (memif_region_details_t *) (buf + l0);
1996 for (i = 0; i < md->regions_num; i++)
1998 md->regions[i].index = i;
1999 md->regions[i].addr = c->regions[i].addr;
2000 md->regions[i].size = c->regions[i].region_size;
2001 md->regions[i].fd = c->regions[i].fd;
2002 md->regions[i].is_external = c->regions[i].is_external;
2007 err = MEMIF_ERR_NOBUF_DET;
2010 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2011 run_args.num_m2s_rings;
2013 l1 = sizeof (memif_queue_details_t) * md->rx_queues_num;
2014 if (l0 + l1 <= buflen)
2016 md->rx_queues = (memif_queue_details_t *) (buf + l0);
2017 for (i = 0; i < md->rx_queues_num; i++)
2019 md->rx_queues[i].region = c->rx_queues[i].region;
2020 md->rx_queues[i].qid = i;
2021 md->rx_queues[i].ring_size = (1 << c->rx_queues[i].log2_ring_size);
2022 md->rx_queues[i].flags = c->rx_queues[i].ring->flags;
2023 md->rx_queues[i].head = c->rx_queues[i].ring->head;
2024 md->rx_queues[i].tail = c->rx_queues[i].ring->tail;
2025 md->rx_queues[i].buffer_size = c->run_args.buffer_size;
2030 err = MEMIF_ERR_NOBUF_DET;
2033 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2034 run_args.num_s2m_rings;
2036 l1 = sizeof (memif_queue_details_t) * md->tx_queues_num;
2037 if (l0 + l1 <= buflen)
2039 md->tx_queues = (memif_queue_details_t *) (buf + l0);
2040 for (i = 0; i < md->tx_queues_num; i++)
2042 md->tx_queues[i].region = c->tx_queues[i].region;
2043 md->tx_queues[i].qid = i;
2044 md->tx_queues[i].ring_size = (1 << c->tx_queues[i].log2_ring_size);
2045 md->tx_queues[i].flags = c->tx_queues[i].ring->flags;
2046 md->tx_queues[i].head = c->tx_queues[i].ring->head;
2047 md->tx_queues[i].tail = c->tx_queues[i].ring->tail;
2048 md->tx_queues[i].buffer_size = c->run_args.buffer_size;
2053 err = MEMIF_ERR_NOBUF_DET;
2055 /* This is not completely true, clients should relay on
2056 * on_connect/on_disconnect callbacks */
2057 md->link_up_down = (c->control_channel != NULL) ? 1 : 0;
2063 memif_get_queue_efd (memif_conn_handle_t conn, uint16_t qid, int *efd)
2065 memif_connection_t *c = (memif_connection_t *) conn;
2070 return MEMIF_ERR_NOCONN;
2071 if (c->control_channel == NULL)
2072 return MEMIF_ERR_DISCONNECTED;
2075 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2076 run_args.num_m2s_rings;
2078 return MEMIF_ERR_QID;
2080 *efd = c->rx_queues[qid].int_fd;
2082 return MEMIF_ERR_SUCCESS;