Message ID | 1396257768-4865-1-git-send-email-maxim.uvarov@linaro.org |
---|---|
State | Superseded |
Headers | show |
On 31 March 2014 11:22, Maxim Uvarov <maxim.uvarov@linaro.org> wrote: > Dynamically select type of packet I/O > sock_params->type = > ODP_PKTIO_TYPE_SOCKET_BASIC > ODP_PKTIO_TYPE_SOCKET_MMSG > ODP_PKTIO_TYPE_SOCKET_MMAP > ODP_PKTIO_TYPE_NETMAP > sock_params->fanout = 1; > pktio = odp_pktio_open(thr_args->pktio_dev, thr_args->pool, ¶ms); > > v2: > - remove NETMAP define in enum; > - add command line parameters to odp_example_pktio for I/O selection. > v3: > - add default cases for switch to fix compilation. > I think it would be better if the commit message just said what the patch is. If you need to describe what happened between different versions that should go below the "---" Cheers, Anders > > Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org> > --- > .../linux-generic/include/api/odp_pktio_socket.h | 1 + > .../linux-generic/include/api/odp_pktio_types.h | 8 +- > .../linux-generic/include/odp_packet_io_internal.h | 1 + > platform/linux-generic/include/odp_packet_socket.h | 55 ++++------- > platform/linux-generic/source/odp_packet_io.c | 71 +++++++++++--- > platform/linux-generic/source/odp_packet_socket.c | 103 > +++++++++------------ > test/packet/odp_example_pktio.c | 30 +++++- > 7 files changed, 155 insertions(+), 114 deletions(-) > > diff --git a/platform/linux-generic/include/api/odp_pktio_socket.h > b/platform/linux-generic/include/api/odp_pktio_socket.h > index e0211bf..deeeeed 100644 > --- a/platform/linux-generic/include/api/odp_pktio_socket.h > +++ b/platform/linux-generic/include/api/odp_pktio_socket.h > @@ -15,6 +15,7 @@ extern "C" { > > typedef struct { > odp_pktio_type_t type; > + int fanout; > } socket_params_t; > > #ifdef __cplusplus > diff --git a/platform/linux-generic/include/api/odp_pktio_types.h > b/platform/linux-generic/include/api/odp_pktio_types.h > index e6b4cbf..8d195a5 100644 > --- a/platform/linux-generic/include/api/odp_pktio_types.h > +++ b/platform/linux-generic/include/api/odp_pktio_types.h > @@ -17,10 +17,10 @@ extern "C" { > */ > > typedef enum { > - ODP_PKTIO_TYPE_SOCKET = 0x01, > -#ifdef ODP_HAVE_NETMAP > - ODP_PKTIO_TYPE_NETMAP = 0x02, > -#endif > + ODP_PKTIO_TYPE_SOCKET_BASIC = 0x1, > + ODP_PKTIO_TYPE_SOCKET_MMSG, > + ODP_PKTIO_TYPE_SOCKET_MMAP, > + ODP_PKTIO_TYPE_NETMAP, > } odp_pktio_type_t; > > #include <odp_pktio_socket.h> > diff --git a/platform/linux-generic/include/odp_packet_io_internal.h > b/platform/linux-generic/include/odp_packet_io_internal.h > index ba1ee9b..3ab7fa0 100644 > --- a/platform/linux-generic/include/odp_packet_io_internal.h > +++ b/platform/linux-generic/include/odp_packet_io_internal.h > @@ -31,6 +31,7 @@ struct pktio_entry { > odp_queue_t outq_default; /**< default out queue */ > odp_pktio_params_t params; /**< pktio parameters */ > pkt_sock_t pkt_sock; /**< using socket API for IO */ > + pkt_sock_mmap_t pkt_sock_mmap; /**< using socket mmap API for IO > */ > #ifdef ODP_HAVE_NETMAP > pkt_netmap_t pkt_nm; /**< using netmap API for IO */ > #endif > diff --git a/platform/linux-generic/include/odp_packet_socket.h > b/platform/linux-generic/include/odp_packet_socket.h > index fe216bb..086de05 100644 > --- a/platform/linux-generic/include/odp_packet_socket.h > +++ b/platform/linux-generic/include/odp_packet_socket.h > @@ -20,37 +20,15 @@ > > #include <linux/version.h> > > - > /* > * Packet socket config: > */ > -#define ODP_PACKET_SOCKET_BASIC 0 /** use recv()/send() */ > -#define ODP_PACKET_SOCKET_MMSG 1 /** use recvmmsg()/sendmmsg() */ > -#define ODP_PACKET_SOCKET_MMAP 2 /** use PACKET_MMAP */ > - > - > -#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 1, 0) > -/* PACKET_FANOUT feature not supported */ > -#define ODP_PACKET_SOCKET_FANOUT 0 > -#define ODP_PACKET_SOCKET_MODE (ODP_PACKET_SOCKET_BASIC) > -#else > -/** PACKET_FANOUT mode spreads incoming packets over multiple sockets*/ > -#define ODP_PACKET_SOCKET_FANOUT 1 /* 0=Off, 1=On */ > -/** Choose one from the alternatives above */ > -#define ODP_PACKET_SOCKET_MODE (ODP_PACKET_SOCKET_MMAP) > -#endif > - > > /** Max receive (Rx) burst size*/ > #define ODP_PACKET_SOCKET_MAX_BURST_RX 32 > /** Max transmit (Tx) burst size*/ > #define ODP_PACKET_SOCKET_MAX_BURST_TX 32 > > - > - > -#if (ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_BASIC) || \ > - (ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_MMSG) > - > typedef struct { > int sockfd; /**< socket descriptor */ > odp_buffer_pool_t pool; /**< buffer pool to alloc packets from */ > @@ -60,12 +38,6 @@ typedef struct { > unsigned char if_mac[ETH_ALEN]; /**< IF eth mac addr */ > } pkt_sock_t; > > -#elif ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_MMAP > - > -#if ODP_PACKET_SOCKET_FANOUT == 0 > -#error "ODP_PACKET_SOCKET_MMAP requires ODP_PACKET_SOCKET_FANOUT=1" > -#endif > - > /** packet mmap ring */ > struct ring { > struct iovec *rd; > @@ -99,31 +71,44 @@ typedef struct { > unsigned mmap_len; > unsigned char if_mac[ETH_ALEN]; > struct sockaddr_ll ll; > -} pkt_sock_t; > - > -#else > -#error "Unsupported ODP_PACKET_SOCKET_MODE!" > -#endif > +} pkt_sock_mmap_t; > > /** > * Open & configure a raw packet socket > */ > int setup_pkt_sock(pkt_sock_t * const pkt_sock, char *netdev, > odp_buffer_pool_t pool); > + > +int setup_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock, char *netdev, > + odp_buffer_pool_t pool, int fanout); > + > /** > * Close a packet socket > */ > int close_pkt_sock(pkt_sock_t * const pkt_sock); > > +int close_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock); > + > /** > * Receive packets from the packet socket > */ > -int recv_pkt_sock(pkt_sock_t * const pkt_sock, odp_packet_t pkt_table[], > +int recv_pkt_sock_basic(pkt_sock_t * const pkt_sock, odp_packet_t > pkt_table[], > unsigned len); > + > +int recv_pkt_sock_mmsg(pkt_sock_t * const pkt_sock, odp_packet_t > pkt_table[], > + unsigned len); > + > +int recv_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock, > + odp_packet_t pkt_table[], unsigned len); > /** > * Send packets through the packet socket > */ > -int send_pkt_sock(pkt_sock_t * const pkt_sock, odp_packet_t pkt_table[], > +int send_pkt_sock_basic(pkt_sock_t * const pkt_sock, odp_packet_t > pkt_table[], > + unsigned len); > + > +int send_pkt_sock_mmsg(pkt_sock_t * const pkt_sock, odp_packet_t > pkt_table[], > unsigned len); > > +int send_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock, > + odp_packet_t pkt_table[], unsigned len); > #endif > diff --git a/platform/linux-generic/source/odp_packet_io.c > b/platform/linux-generic/source/odp_packet_io.c > index 92aed34..6c6175d 100644 > --- a/platform/linux-generic/source/odp_packet_io.c > +++ b/platform/linux-generic/source/odp_packet_io.c > @@ -117,14 +117,21 @@ static void init_pktio_entry(pktio_entry_t *entry, > odp_pktio_params_t *params) > set_taken(entry); > entry->s.inq_default = ODP_QUEUE_INVALID; > switch (params->type) { > - case ODP_PKTIO_TYPE_SOCKET: > + case ODP_PKTIO_TYPE_SOCKET_BASIC: > + case ODP_PKTIO_TYPE_SOCKET_MMSG: > + case ODP_PKTIO_TYPE_SOCKET_MMAP: > memset(&entry->s.pkt_sock, 0, sizeof(entry->s.pkt_sock)); > + memset(&entry->s.pkt_sock_mmap, 0, > + sizeof(entry->s.pkt_sock_mmap)); > break; > #ifdef ODP_HAVE_NETMAP > case ODP_PKTIO_TYPE_NETMAP: > memset(&entry->s.pkt_nm, 0, sizeof(entry->s.pkt_nm)); > break; > #endif > + default: > + ODP_ERR("Packet I/O type not supported. Please > recompile\n"); > + break; > } > /* Save pktio parameters, type is the most useful */ > memcpy(&entry->s.params, params, sizeof(*params)); > @@ -177,7 +184,9 @@ odp_pktio_t odp_pktio_open(char *dev, > odp_buffer_pool_t pool, > } > > switch (params->type) { > - case ODP_PKTIO_TYPE_SOCKET: > + case ODP_PKTIO_TYPE_SOCKET_BASIC: > + case ODP_PKTIO_TYPE_SOCKET_MMSG: > + case ODP_PKTIO_TYPE_SOCKET_MMAP: > ODP_DBG("Allocating socket pktio\n"); > break; > #ifdef ODP_HAVE_NETMAP > @@ -200,7 +209,8 @@ odp_pktio_t odp_pktio_open(char *dev, > odp_buffer_pool_t pool, > pktio_entry = get_entry(id); > > switch (params->type) { > - case ODP_PKTIO_TYPE_SOCKET: > + case ODP_PKTIO_TYPE_SOCKET_BASIC: > + case ODP_PKTIO_TYPE_SOCKET_MMSG: > res = setup_pkt_sock(&pktio_entry->s.pkt_sock, dev, pool); > if (res == -1) { > close_pkt_sock(&pktio_entry->s.pkt_sock); > @@ -208,17 +218,31 @@ odp_pktio_t odp_pktio_open(char *dev, > odp_buffer_pool_t pool, > id = ODP_PKTIO_INVALID; > } > break; > + case ODP_PKTIO_TYPE_SOCKET_MMAP: > + res = setup_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, > dev, > + pool, params->sock_params.fanout); > + if (res == -1) { > + close_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap); > + free_pktio_entry(id); > + id = ODP_PKTIO_INVALID; > + } > + break; > #ifdef ODP_HAVE_NETMAP > case ODP_PKTIO_TYPE_NETMAP: > + > res = setup_pkt_netmap(&pktio_entry->s.pkt_nm, dev, > - pool, ¶ms->nm_params); > + pool, ¶ms->nm_params); > if (res == -1) { > close_pkt_netmap(&pktio_entry->s.pkt_nm); > free_pktio_entry(id); > id = ODP_PKTIO_INVALID; > } > - break; > #endif > + default: > + free_pktio_entry(id); > + id = ODP_PKTIO_INVALID; > + ODP_ERR("This type of I/O is not supported. Please > recompile.\n"); > + break; > } > > unlock_entry(pktio_entry); > @@ -237,9 +261,13 @@ int odp_pktio_close(odp_pktio_t id) > lock_entry(entry); > if (!is_free(entry)) { > switch (entry->s.params.type) { > - case ODP_PKTIO_TYPE_SOCKET: > + case ODP_PKTIO_TYPE_SOCKET_BASIC: > + case ODP_PKTIO_TYPE_SOCKET_MMSG: > res = close_pkt_sock(&entry->s.pkt_sock); > break; > + case ODP_PKTIO_TYPE_SOCKET_MMAP: > + res = > close_pkt_sock_mmap(&entry->s.pkt_sock_mmap); > + break; > #ifdef ODP_HAVE_NETMAP > case ODP_PKTIO_TYPE_NETMAP: > res = close_pkt_netmap(&entry->s.pkt_nm); > @@ -247,7 +275,7 @@ int odp_pktio_close(odp_pktio_t id) > #endif > default: > break; > - res |= free_pktio_entry(id); > + res |= free_pktio_entry(id); > } > } > unlock_entry(entry); > @@ -279,8 +307,17 @@ int odp_pktio_recv(odp_pktio_t id, odp_packet_t > pkt_table[], unsigned len) > > lock_entry(pktio_entry); > switch (pktio_entry->s.params.type) { > - case ODP_PKTIO_TYPE_SOCKET: > - pkts = recv_pkt_sock(&pktio_entry->s.pkt_sock, pkt_table, > len); > + case ODP_PKTIO_TYPE_SOCKET_BASIC: > + pkts = recv_pkt_sock_basic(&pktio_entry->s.pkt_sock, > + pkt_table, len); > + break; > + case ODP_PKTIO_TYPE_SOCKET_MMSG: > + pkts = recv_pkt_sock_mmsg(&pktio_entry->s.pkt_sock, > + pkt_table, len); > + break; > + case ODP_PKTIO_TYPE_SOCKET_MMAP: > + pkts = recv_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, > + pkt_table, len); > break; > #ifdef ODP_HAVE_NETMAP > case ODP_PKTIO_TYPE_NETMAP: > @@ -312,12 +349,22 @@ int odp_pktio_send(odp_pktio_t id, odp_packet_t > pkt_table[], unsigned len) > > lock_entry(pktio_entry); > switch (pktio_entry->s.params.type) { > - case ODP_PKTIO_TYPE_SOCKET: > - pkts = send_pkt_sock(&pktio_entry->s.pkt_sock, pkt_table, > len); > + case ODP_PKTIO_TYPE_SOCKET_BASIC: > + pkts = send_pkt_sock_basic(&pktio_entry->s.pkt_sock, > + pkt_table, len); > + break; > + case ODP_PKTIO_TYPE_SOCKET_MMSG: > + pkts = send_pkt_sock_mmsg(&pktio_entry->s.pkt_sock, > + pkt_table, len); > + break; > + case ODP_PKTIO_TYPE_SOCKET_MMAP: > + pkts = send_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, > + pkt_table, len); > break; > #ifdef ODP_HAVE_NETMAP > case ODP_PKTIO_TYPE_NETMAP: > - pkts = send_pkt_netmap(&pktio_entry->s.pkt_nm, pkt_table, > len); > + pkts = send_pkt_netmap(&pktio_entry->s.pkt_nm, > + pkt_table, len); > break; > #endif > default: > diff --git a/platform/linux-generic/source/odp_packet_socket.c > b/platform/linux-generic/source/odp_packet_socket.c > index aaf2605..4e5803f 100644 > --- a/platform/linux-generic/source/odp_packet_socket.c > +++ b/platform/linux-generic/source/odp_packet_socket.c > @@ -63,10 +63,9 @@ static inline int ethaddrs_equal(unsigned char mac_a[], > unsigned char mac_b[]) > return !memcmp(mac_a, mac_b, ETH_ALEN); > } > > -static int set_pkt_sock_fanout(pkt_sock_t * const pkt_sock, int > sock_group_idx) > +static int set_pkt_sock_fanout_mmap(pkt_sock_mmap_t * const pkt_sock, > + int sock_group_idx) > { > -#if ODP_PACKET_SOCKET_FANOUT == 1 > - /* Use FANOUT-mode for socket */ > int sockfd = pkt_sock->sockfd; > int val; > int err; > @@ -80,16 +79,9 @@ static int set_pkt_sock_fanout(pkt_sock_t * const > pkt_sock, int sock_group_idx) > perror("set_pkt_sock_fanout() - > setsockopt(PACKET_FANOUT)"); > return -1; > } > -#else > - (void)pkt_sock; > - (void)sock_group_idx; > -#endif > - > return 0; > } > > -#if (ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_BASIC) || \ > - (ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_MMSG) > /* > * ODP_PACKET_SOCKET_BASIC: > * ODP_PACKET_SOCKET_MMSG: > @@ -163,11 +155,6 @@ int setup_pkt_sock(pkt_sock_t * const pkt_sock, char > *netdev, > return -1; > } > > - /* configure PACKET_FANOUT mode for socket (if mode enabled) */ > - err = set_pkt_sock_fanout(pkt_sock, if_idx); > - if (err != 0) > - return -1; > - > return sockfd; > } > > @@ -184,13 +171,11 @@ int close_pkt_sock(pkt_sock_t * const pkt_sock) > > return 0; > } > -#endif > > -#if ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_BASIC > /* > * ODP_PACKET_SOCKET_BASIC: > */ > -int recv_pkt_sock(pkt_sock_t *const pkt_sock, > +int recv_pkt_sock_basic(pkt_sock_t *const pkt_sock, > odp_packet_t pkt_table[], unsigned len) > { > ssize_t recv_bytes; > @@ -240,7 +225,7 @@ int recv_pkt_sock(pkt_sock_t *const pkt_sock, > /* > * ODP_PACKET_SOCKET_BASIC: > */ > -int send_pkt_sock(pkt_sock_t * const pkt_sock, > +int send_pkt_sock_basic(pkt_sock_t * const pkt_sock, > odp_packet_t pkt_table[], unsigned len) > { > odp_packet_t pkt; > @@ -281,11 +266,10 @@ int send_pkt_sock(pkt_sock_t * const pkt_sock, > return nb_tx; > } > > -#elif ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_MMSG > /* > * ODP_PACKET_SOCKET_MMSG: > */ > -int recv_pkt_sock(pkt_sock_t * const pkt_sock, > +int recv_pkt_sock_mmsg(pkt_sock_t * const pkt_sock, > odp_packet_t pkt_table[], unsigned len) > { > const int sockfd = pkt_sock->sockfd; > @@ -348,7 +332,7 @@ int recv_pkt_sock(pkt_sock_t * const pkt_sock, > /* > * ODP_PACKET_SOCKET_MMSG: > */ > -int send_pkt_sock(pkt_sock_t * const pkt_sock, > +int send_pkt_sock_mmsg(pkt_sock_t * const pkt_sock, > odp_packet_t pkt_table[], unsigned len) > { > struct mmsghdr msgvec[ODP_PACKET_SOCKET_MAX_BURST_TX]; > @@ -387,7 +371,6 @@ int send_pkt_sock(pkt_sock_t * const pkt_sock, > return len; > } > > -#elif ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_MMAP > /* > * ODP_PACKET_SOCKET_MMAP: > */ > @@ -402,7 +385,7 @@ union frame_map { > void *raw; > }; > > -static int pkt_socket(void) > +static int mmap_pkt_socket(void) > { > int ver = TPACKET_V2; > > @@ -421,23 +404,23 @@ static int pkt_socket(void) > return sock; > } > > -static inline int rx_kernel_ready(struct tpacket2_hdr *hdr) > +static inline int mmap_rx_kernel_ready(struct tpacket2_hdr *hdr) > { > return ((hdr->tp_status & TP_STATUS_USER) == TP_STATUS_USER); > } > > -static inline void rx_user_ready(struct tpacket2_hdr *hdr) > +static inline void mmap_rx_user_ready(struct tpacket2_hdr *hdr) > { > hdr->tp_status = TP_STATUS_KERNEL; > __sync_synchronize(); > } > > -static inline int tx_kernel_ready(struct tpacket2_hdr *hdr) > +static inline int mmap_tx_kernel_ready(struct tpacket2_hdr *hdr) > { > return !(hdr->tp_status & (TP_STATUS_SEND_REQUEST | > TP_STATUS_SENDING)); > } > > -static inline void tx_user_ready(struct tpacket2_hdr *hdr) > +static inline void mmap_tx_user_ready(struct tpacket2_hdr *hdr) > { > hdr->tp_status = TP_STATUS_SEND_REQUEST; > __sync_synchronize(); > @@ -462,7 +445,7 @@ static inline unsigned pkt_mmap_v2_rx(int sock, struct > ring *ring, > frame_num = ring->frame_num; > > while (i < len) { > - if (rx_kernel_ready(ring->rd[frame_num].iov_base)) { > + if (mmap_rx_kernel_ready(ring->rd[frame_num].iov_base)) { > ppd.raw = ring->rd[frame_num].iov_base; > > next_frame_num = (frame_num + 1) % ring->rd_num; > @@ -474,7 +457,7 @@ static inline unsigned pkt_mmap_v2_rx(int sock, struct > ring *ring, > eth_hdr = (struct ethhdr *)pkt_buf; > if (odp_unlikely(ethaddrs_equal(if_mac, > > eth_hdr->h_source))) { > - rx_user_ready(ppd.raw); /* drop */ > + mmap_rx_user_ready(ppd.raw); /* drop */ > continue; > } > > @@ -486,7 +469,7 @@ static inline unsigned pkt_mmap_v2_rx(int sock, struct > ring *ring, > + frame_offset; > memcpy(l2_hdr, pkt_buf, pkt_len); > > - rx_user_ready(ppd.raw); > + mmap_rx_user_ready(ppd.raw); > > /* Parse and set packet header data */ > odp_packet_parse(pkt_table[i], pkt_len, > frame_offset); > @@ -516,7 +499,7 @@ static inline unsigned pkt_mmap_v2_tx(int sock, struct > ring *ring, > frame_num = ring->frame_num; > > while (i < len) { > - if (tx_kernel_ready(ring->rd[frame_num].iov_base)) { > + if (mmap_tx_kernel_ready(ring->rd[frame_num].iov_base)) { > ppd.raw = ring->rd[frame_num].iov_base; > > next_frame_num = (frame_num + 1) % ring->rd_num; > @@ -530,7 +513,7 @@ static inline unsigned pkt_mmap_v2_tx(int sock, struct > ring *ring, > memcpy((uint8_t *)ppd.raw + TPACKET2_HDRLEN - > sizeof(struct sockaddr_ll), pkt_buf, > pkt_len); > > - tx_user_ready(ppd.raw); > + mmap_tx_user_ready(ppd.raw); > > odp_packet_free(pkt_table[i]); > frame_num = next_frame_num; > @@ -553,7 +536,7 @@ static inline unsigned pkt_mmap_v2_tx(int sock, struct > ring *ring, > return i; > } > > -static void fill_ring(struct ring *ring, unsigned blocks) > +static void mmap_fill_ring(struct ring *ring, unsigned blocks) > { > ring->req.tp_block_size = getpagesize() << 2; > ring->req.tp_frame_size = TPACKET_ALIGNMENT << 7; > @@ -567,7 +550,7 @@ static void fill_ring(struct ring *ring, unsigned > blocks) > ring->flen = ring->req.tp_frame_size; > } > > -static int set_packet_loss_discard(int sock) > +static int mmap_set_packet_loss_discard(int sock) > { > int ret, discard = 1; > > @@ -581,7 +564,7 @@ static int set_packet_loss_discard(int sock) > return 0; > } > > -static int setup_ring(int sock, struct ring *ring, int type) > +static int mmap_setup_ring(int sock, struct ring *ring, int type) > { > int ret = 0; > unsigned blocks = 256; > @@ -591,12 +574,12 @@ static int setup_ring(int sock, struct ring *ring, > int type) > ring->version = TPACKET_V2; > > if (type == PACKET_TX_RING) { > - ret = set_packet_loss_discard(sock); > + ret = mmap_set_packet_loss_discard(sock); > if (ret != 0) > return -1; > } > > - fill_ring(ring, blocks); > + mmap_fill_ring(ring, blocks); > > ret = setsockopt(sock, SOL_PACKET, type, &ring->req, > sizeof(ring->req)); > if (ret == -1) { > @@ -614,7 +597,7 @@ static int setup_ring(int sock, struct ring *ring, int > type) > return 0; > } > > -static int mmap_sock(pkt_sock_t *pkt_sock) > +static int mmap_sock(pkt_sock_mmap_t *pkt_sock) > { > int i; > int sock = pkt_sock->sockfd; > @@ -655,14 +638,14 @@ static int mmap_sock(pkt_sock_t *pkt_sock) > return 0; > } > > -static void unmap_sock(pkt_sock_t *pkt_sock) > +static void mmap_unmap_sock(pkt_sock_mmap_t *pkt_sock) > { > munmap(pkt_sock->mmap_base, pkt_sock->mmap_len); > free(pkt_sock->rx_ring.rd); > free(pkt_sock->tx_ring.rd); > } > > -static int bind_sock(pkt_sock_t *pkt_sock, char *netdev) > +static int mmap_bind_sock(pkt_sock_mmap_t *pkt_sock, char *netdev) > { > int ret; > > @@ -684,7 +667,7 @@ static int bind_sock(pkt_sock_t *pkt_sock, char > *netdev) > return 0; > } > > -static int store_hw_addr(pkt_sock_t * const pkt_sock, char *netdev) > +static int mmap_store_hw_addr(pkt_sock_mmap_t * const pkt_sock, char > *netdev) > { > struct ifreq ethreq; > int ret; > @@ -707,8 +690,8 @@ static int store_hw_addr(pkt_sock_t * const pkt_sock, > char *netdev) > /* > * ODP_PACKET_SOCKET_MMAP: > */ > -int setup_pkt_sock(pkt_sock_t * const pkt_sock, char *netdev, > - odp_buffer_pool_t pool) > +int setup_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock, char *netdev, > + odp_buffer_pool_t pool, int fanout) > { > odp_packet_t pkt; > uint8_t *pkt_buf; > @@ -733,17 +716,19 @@ int setup_pkt_sock(pkt_sock_t * const pkt_sock, char > *netdev, > odp_packet_free(pkt); > > pkt_sock->pool = pool; > - pkt_sock->sockfd = pkt_socket(); > + pkt_sock->sockfd = mmap_pkt_socket(); > > - ret = bind_sock(pkt_sock, netdev); > + ret = mmap_bind_sock(pkt_sock, netdev); > if (ret != 0) > return -1; > > - ret = setup_ring(pkt_sock->sockfd, &pkt_sock->tx_ring, > PACKET_TX_RING); > + ret = mmap_setup_ring(pkt_sock->sockfd, &pkt_sock->tx_ring, > + PACKET_TX_RING); > if (ret != 0) > return -1; > > - ret = setup_ring(pkt_sock->sockfd, &pkt_sock->rx_ring, > PACKET_RX_RING); > + ret = mmap_setup_ring(pkt_sock->sockfd, &pkt_sock->rx_ring, > + PACKET_RX_RING); > if (ret != 0) > return -1; > > @@ -751,7 +736,7 @@ int setup_pkt_sock(pkt_sock_t * const pkt_sock, char > *netdev, > if (ret != 0) > return -1; > > - ret = store_hw_addr(pkt_sock, netdev); > + ret = mmap_store_hw_addr(pkt_sock, netdev); > if (ret != 0) > return -1; > > @@ -761,9 +746,11 @@ int setup_pkt_sock(pkt_sock_t * const pkt_sock, char > *netdev, > return -1; > } > > - ret = set_pkt_sock_fanout(pkt_sock, if_idx); > - if (ret != 0) > - return -1; > + if (fanout) { > + ret = set_pkt_sock_fanout_mmap(pkt_sock, if_idx); > + if (ret != 0) > + return -1; > + } > > return pkt_sock->sockfd; > } > @@ -771,9 +758,9 @@ int setup_pkt_sock(pkt_sock_t * const pkt_sock, char > *netdev, > /* > * ODP_PACKET_SOCKET_MMAP: > */ > -int close_pkt_sock(pkt_sock_t * const pkt_sock) > +int close_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock) > { > - unmap_sock(pkt_sock); > + mmap_unmap_sock(pkt_sock); > if (close(pkt_sock->sockfd) != 0) { > perror("close_pkt_sock() - close(sockfd)"); > return -1; > @@ -785,7 +772,7 @@ int close_pkt_sock(pkt_sock_t * const pkt_sock) > /* > * ODP_PACKET_SOCKET_MMAP: > */ > -int recv_pkt_sock(pkt_sock_t * const pkt_sock, > +int recv_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock, > odp_packet_t pkt_table[], unsigned len) > { > return pkt_mmap_v2_rx(pkt_sock->rx_ring.sock, &pkt_sock->rx_ring, > @@ -796,13 +783,9 @@ int recv_pkt_sock(pkt_sock_t * const pkt_sock, > /* > * ODP_PACKET_SOCKET_MMAP: > */ > -int send_pkt_sock(pkt_sock_t * const pkt_sock, > +int send_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock, > odp_packet_t pkt_table[], unsigned len) > { > return pkt_mmap_v2_tx(pkt_sock->tx_ring.sock, &pkt_sock->tx_ring, > pkt_table, len); > } > - > -#else > -#error "Unsupported ODP_PACKET_SOCKET_MODE!" > -#endif > diff --git a/test/packet/odp_example_pktio.c > b/test/packet/odp_example_pktio.c > index 85bbdd7..1d62123 100644 > --- a/test/packet/odp_example_pktio.c > +++ b/test/packet/odp_example_pktio.c > @@ -42,6 +42,8 @@ typedef struct { > int if_count; /**< Number of interfaces to be used */ > char **if_names; /**< Array of pointers to interface names > */ > int mode; /**< Packet IO mode */ > + int type; /**< Packet IO type */ > + int fanout; /**< Packet IO fanout */ > odp_buffer_pool_t pool; /**< Buffer pool for packet IO */ > } appl_args_t; > > @@ -52,6 +54,8 @@ typedef struct { > char *pktio_dev; /**< Interface name to use */ > odp_buffer_pool_t pool; /**< Buffer pool for packet IO */ > int mode; /**< Thread mode */ > + int type; /**< Thread i/o type */ > + int fanout; /**< Thread i/o fanout */ > } thread_args_t; > > /** > @@ -111,7 +115,8 @@ static void *pktio_queue_thread(void *arg) > } > > /* Open a packet IO instance for this thread */ > - sock_params->type = ODP_PKTIO_TYPE_SOCKET; > + sock_params->type = thr_args->type; > + sock_params->fanout = thr_args->fanout; > pktio = odp_pktio_open(thr_args->pktio_dev, thr_args->pool, > ¶ms); > if (pktio == ODP_PKTIO_INVALID) { > ODP_ERR(" [%02i] Error: pktio create failed\n", thr); > @@ -223,7 +228,8 @@ static void *pktio_ifburst_thread(void *arg) > } > > /* Open a packet IO instance for this thread */ > - sock_params->type = ODP_PKTIO_TYPE_SOCKET; > + sock_params->type = thr_args->type; > + sock_params->fanout = thr_args->fanout; > pktio = odp_pktio_open(thr_args->pktio_dev, thr_args->pool, > ¶ms); > if (pktio == ODP_PKTIO_INVALID) { > ODP_ERR(" [%02i] Error: pktio create failed.\n", thr); > @@ -357,6 +363,8 @@ int main(int argc, char *argv[]) > args->thread[i].pktio_dev = args->appl.if_names[if_idx]; > args->thread[i].pool = pool; > args->thread[i].mode = args->appl.mode; > + args->thread[i].type = args->appl.type; > + args->thread[i].fanout = args->appl.fanout; > > if (args->appl.mode == APPL_MODE_PKT_BURST) > thr_run_func = pktio_ifburst_thread; > @@ -470,9 +478,11 @@ static void parse_args(int argc, char *argv[], > appl_args_t *appl_args) > }; > > appl_args->mode = -1; /* Invalid, must be changed by parsing */ > + appl_args->type = 3; /* 3: ODP_PKTIO_TYPE_SOCKET_MMAP */ > + appl_args->fanout = 1; /* turn off fanout by default for mmap */ > > while (1) { > - opt = getopt_long(argc, argv, "+c:i:m:h", > + opt = getopt_long(argc, argv, "+c:i:m:t:f:h", > longopts, &long_index); > > if (opt == -1) > @@ -533,6 +543,14 @@ static void parse_args(int argc, char *argv[], > appl_args_t *appl_args) > appl_args->mode = APPL_MODE_PKT_QUEUE; > break; > > + case 't': > + appl_args->type = atoi(optarg); > + break; > + > + case 'f': > + appl_args->type = atoi(optarg); > + break; > + > case 'h': > usage(argv[0]); > exit(EXIT_SUCCESS); > @@ -602,6 +620,12 @@ static void usage(char *progname) > " -i, --interface Eth interfaces (comma-separated, no > spaces)\n" > " -m, --mode 0: Burst send&receive packets (no > queues)\n" > " 1: Send&receive packets through ODP > queues.\n" > + " -t, --type 1: ODP_PKTIO_TYPE_SOCKET_BASIC\n" > + " 2: ODP_PKTIO_TYPE_SOCKET_MMSG\n" > + " 3: ODP_PKTIO_TYPE_SOCKET_MMAP\n" > + " 4: ODP_PKTIO_TYPE_NETMAP\n" > + " Default: 3: ODP_PKTIO_TYPE_SOCKET_MMAP\n" > + " -f, --fanout 0: off 1: on (Default 1: on)\n" > "\n" > "Optional OPTIONS\n" > " -c, --count <number> Core count.\n" > -- > 1.8.5.1.163.gd7aced9 > > -- > You received this message because you are subscribed to the Google Groups > "LNG ODP Sub-team - lng-odp@linaro.org" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to lng-odp+unsubscribe@linaro.org. > To post to this group, send email to lng-odp@linaro.org. > Visit this group at http://groups.google.com/a/linaro.org/group/lng-odp/. > To view this discussion on the web visit > https://groups.google.com/a/linaro.org/d/msgid/lng-odp/1396257768-4865-1-git-send-email-maxim.uvarov%40linaro.org > . > For more options, visit https://groups.google.com/a/linaro.org/d/optout. >
diff --git a/platform/linux-generic/include/api/odp_pktio_socket.h b/platform/linux-generic/include/api/odp_pktio_socket.h index e0211bf..deeeeed 100644 --- a/platform/linux-generic/include/api/odp_pktio_socket.h +++ b/platform/linux-generic/include/api/odp_pktio_socket.h @@ -15,6 +15,7 @@ extern "C" { typedef struct { odp_pktio_type_t type; + int fanout; } socket_params_t; #ifdef __cplusplus diff --git a/platform/linux-generic/include/api/odp_pktio_types.h b/platform/linux-generic/include/api/odp_pktio_types.h index e6b4cbf..8d195a5 100644 --- a/platform/linux-generic/include/api/odp_pktio_types.h +++ b/platform/linux-generic/include/api/odp_pktio_types.h @@ -17,10 +17,10 @@ extern "C" { */ typedef enum { - ODP_PKTIO_TYPE_SOCKET = 0x01, -#ifdef ODP_HAVE_NETMAP - ODP_PKTIO_TYPE_NETMAP = 0x02, -#endif + ODP_PKTIO_TYPE_SOCKET_BASIC = 0x1, + ODP_PKTIO_TYPE_SOCKET_MMSG, + ODP_PKTIO_TYPE_SOCKET_MMAP, + ODP_PKTIO_TYPE_NETMAP, } odp_pktio_type_t; #include <odp_pktio_socket.h> diff --git a/platform/linux-generic/include/odp_packet_io_internal.h b/platform/linux-generic/include/odp_packet_io_internal.h index ba1ee9b..3ab7fa0 100644 --- a/platform/linux-generic/include/odp_packet_io_internal.h +++ b/platform/linux-generic/include/odp_packet_io_internal.h @@ -31,6 +31,7 @@ struct pktio_entry { odp_queue_t outq_default; /**< default out queue */ odp_pktio_params_t params; /**< pktio parameters */ pkt_sock_t pkt_sock; /**< using socket API for IO */ + pkt_sock_mmap_t pkt_sock_mmap; /**< using socket mmap API for IO */ #ifdef ODP_HAVE_NETMAP pkt_netmap_t pkt_nm; /**< using netmap API for IO */ #endif diff --git a/platform/linux-generic/include/odp_packet_socket.h b/platform/linux-generic/include/odp_packet_socket.h index fe216bb..086de05 100644 --- a/platform/linux-generic/include/odp_packet_socket.h +++ b/platform/linux-generic/include/odp_packet_socket.h @@ -20,37 +20,15 @@ #include <linux/version.h> - /* * Packet socket config: */ -#define ODP_PACKET_SOCKET_BASIC 0 /** use recv()/send() */ -#define ODP_PACKET_SOCKET_MMSG 1 /** use recvmmsg()/sendmmsg() */ -#define ODP_PACKET_SOCKET_MMAP 2 /** use PACKET_MMAP */ - - -#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 1, 0) -/* PACKET_FANOUT feature not supported */ -#define ODP_PACKET_SOCKET_FANOUT 0 -#define ODP_PACKET_SOCKET_MODE (ODP_PACKET_SOCKET_BASIC) -#else -/** PACKET_FANOUT mode spreads incoming packets over multiple sockets*/ -#define ODP_PACKET_SOCKET_FANOUT 1 /* 0=Off, 1=On */ -/** Choose one from the alternatives above */ -#define ODP_PACKET_SOCKET_MODE (ODP_PACKET_SOCKET_MMAP) -#endif - /** Max receive (Rx) burst size*/ #define ODP_PACKET_SOCKET_MAX_BURST_RX 32 /** Max transmit (Tx) burst size*/ #define ODP_PACKET_SOCKET_MAX_BURST_TX 32 - - -#if (ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_BASIC) || \ - (ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_MMSG) - typedef struct { int sockfd; /**< socket descriptor */ odp_buffer_pool_t pool; /**< buffer pool to alloc packets from */ @@ -60,12 +38,6 @@ typedef struct { unsigned char if_mac[ETH_ALEN]; /**< IF eth mac addr */ } pkt_sock_t; -#elif ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_MMAP - -#if ODP_PACKET_SOCKET_FANOUT == 0 -#error "ODP_PACKET_SOCKET_MMAP requires ODP_PACKET_SOCKET_FANOUT=1" -#endif - /** packet mmap ring */ struct ring { struct iovec *rd; @@ -99,31 +71,44 @@ typedef struct { unsigned mmap_len; unsigned char if_mac[ETH_ALEN]; struct sockaddr_ll ll; -} pkt_sock_t; - -#else -#error "Unsupported ODP_PACKET_SOCKET_MODE!" -#endif +} pkt_sock_mmap_t; /** * Open & configure a raw packet socket */ int setup_pkt_sock(pkt_sock_t * const pkt_sock, char *netdev, odp_buffer_pool_t pool); + +int setup_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock, char *netdev, + odp_buffer_pool_t pool, int fanout); + /** * Close a packet socket */ int close_pkt_sock(pkt_sock_t * const pkt_sock); +int close_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock); + /** * Receive packets from the packet socket */ -int recv_pkt_sock(pkt_sock_t * const pkt_sock, odp_packet_t pkt_table[], +int recv_pkt_sock_basic(pkt_sock_t * const pkt_sock, odp_packet_t pkt_table[], unsigned len); + +int recv_pkt_sock_mmsg(pkt_sock_t * const pkt_sock, odp_packet_t pkt_table[], + unsigned len); + +int recv_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock, + odp_packet_t pkt_table[], unsigned len); /** * Send packets through the packet socket */ -int send_pkt_sock(pkt_sock_t * const pkt_sock, odp_packet_t pkt_table[], +int send_pkt_sock_basic(pkt_sock_t * const pkt_sock, odp_packet_t pkt_table[], + unsigned len); + +int send_pkt_sock_mmsg(pkt_sock_t * const pkt_sock, odp_packet_t pkt_table[], unsigned len); +int send_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock, + odp_packet_t pkt_table[], unsigned len); #endif diff --git a/platform/linux-generic/source/odp_packet_io.c b/platform/linux-generic/source/odp_packet_io.c index 92aed34..6c6175d 100644 --- a/platform/linux-generic/source/odp_packet_io.c +++ b/platform/linux-generic/source/odp_packet_io.c @@ -117,14 +117,21 @@ static void init_pktio_entry(pktio_entry_t *entry, odp_pktio_params_t *params) set_taken(entry); entry->s.inq_default = ODP_QUEUE_INVALID; switch (params->type) { - case ODP_PKTIO_TYPE_SOCKET: + case ODP_PKTIO_TYPE_SOCKET_BASIC: + case ODP_PKTIO_TYPE_SOCKET_MMSG: + case ODP_PKTIO_TYPE_SOCKET_MMAP: memset(&entry->s.pkt_sock, 0, sizeof(entry->s.pkt_sock)); + memset(&entry->s.pkt_sock_mmap, 0, + sizeof(entry->s.pkt_sock_mmap)); break; #ifdef ODP_HAVE_NETMAP case ODP_PKTIO_TYPE_NETMAP: memset(&entry->s.pkt_nm, 0, sizeof(entry->s.pkt_nm)); break; #endif + default: + ODP_ERR("Packet I/O type not supported. Please recompile\n"); + break; } /* Save pktio parameters, type is the most useful */ memcpy(&entry->s.params, params, sizeof(*params)); @@ -177,7 +184,9 @@ odp_pktio_t odp_pktio_open(char *dev, odp_buffer_pool_t pool, } switch (params->type) { - case ODP_PKTIO_TYPE_SOCKET: + case ODP_PKTIO_TYPE_SOCKET_BASIC: + case ODP_PKTIO_TYPE_SOCKET_MMSG: + case ODP_PKTIO_TYPE_SOCKET_MMAP: ODP_DBG("Allocating socket pktio\n"); break; #ifdef ODP_HAVE_NETMAP @@ -200,7 +209,8 @@ odp_pktio_t odp_pktio_open(char *dev, odp_buffer_pool_t pool, pktio_entry = get_entry(id); switch (params->type) { - case ODP_PKTIO_TYPE_SOCKET: + case ODP_PKTIO_TYPE_SOCKET_BASIC: + case ODP_PKTIO_TYPE_SOCKET_MMSG: res = setup_pkt_sock(&pktio_entry->s.pkt_sock, dev, pool); if (res == -1) { close_pkt_sock(&pktio_entry->s.pkt_sock); @@ -208,17 +218,31 @@ odp_pktio_t odp_pktio_open(char *dev, odp_buffer_pool_t pool, id = ODP_PKTIO_INVALID; } break; + case ODP_PKTIO_TYPE_SOCKET_MMAP: + res = setup_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, dev, + pool, params->sock_params.fanout); + if (res == -1) { + close_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap); + free_pktio_entry(id); + id = ODP_PKTIO_INVALID; + } + break; #ifdef ODP_HAVE_NETMAP case ODP_PKTIO_TYPE_NETMAP: + res = setup_pkt_netmap(&pktio_entry->s.pkt_nm, dev, - pool, ¶ms->nm_params); + pool, ¶ms->nm_params); if (res == -1) { close_pkt_netmap(&pktio_entry->s.pkt_nm); free_pktio_entry(id); id = ODP_PKTIO_INVALID; } - break; #endif + default: + free_pktio_entry(id); + id = ODP_PKTIO_INVALID; + ODP_ERR("This type of I/O is not supported. Please recompile.\n"); + break; } unlock_entry(pktio_entry); @@ -237,9 +261,13 @@ int odp_pktio_close(odp_pktio_t id) lock_entry(entry); if (!is_free(entry)) { switch (entry->s.params.type) { - case ODP_PKTIO_TYPE_SOCKET: + case ODP_PKTIO_TYPE_SOCKET_BASIC: + case ODP_PKTIO_TYPE_SOCKET_MMSG: res = close_pkt_sock(&entry->s.pkt_sock); break; + case ODP_PKTIO_TYPE_SOCKET_MMAP: + res = close_pkt_sock_mmap(&entry->s.pkt_sock_mmap); + break; #ifdef ODP_HAVE_NETMAP case ODP_PKTIO_TYPE_NETMAP: res = close_pkt_netmap(&entry->s.pkt_nm); @@ -247,7 +275,7 @@ int odp_pktio_close(odp_pktio_t id) #endif default: break; - res |= free_pktio_entry(id); + res |= free_pktio_entry(id); } } unlock_entry(entry); @@ -279,8 +307,17 @@ int odp_pktio_recv(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len) lock_entry(pktio_entry); switch (pktio_entry->s.params.type) { - case ODP_PKTIO_TYPE_SOCKET: - pkts = recv_pkt_sock(&pktio_entry->s.pkt_sock, pkt_table, len); + case ODP_PKTIO_TYPE_SOCKET_BASIC: + pkts = recv_pkt_sock_basic(&pktio_entry->s.pkt_sock, + pkt_table, len); + break; + case ODP_PKTIO_TYPE_SOCKET_MMSG: + pkts = recv_pkt_sock_mmsg(&pktio_entry->s.pkt_sock, + pkt_table, len); + break; + case ODP_PKTIO_TYPE_SOCKET_MMAP: + pkts = recv_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, + pkt_table, len); break; #ifdef ODP_HAVE_NETMAP case ODP_PKTIO_TYPE_NETMAP: @@ -312,12 +349,22 @@ int odp_pktio_send(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len) lock_entry(pktio_entry); switch (pktio_entry->s.params.type) { - case ODP_PKTIO_TYPE_SOCKET: - pkts = send_pkt_sock(&pktio_entry->s.pkt_sock, pkt_table, len); + case ODP_PKTIO_TYPE_SOCKET_BASIC: + pkts = send_pkt_sock_basic(&pktio_entry->s.pkt_sock, + pkt_table, len); + break; + case ODP_PKTIO_TYPE_SOCKET_MMSG: + pkts = send_pkt_sock_mmsg(&pktio_entry->s.pkt_sock, + pkt_table, len); + break; + case ODP_PKTIO_TYPE_SOCKET_MMAP: + pkts = send_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, + pkt_table, len); break; #ifdef ODP_HAVE_NETMAP case ODP_PKTIO_TYPE_NETMAP: - pkts = send_pkt_netmap(&pktio_entry->s.pkt_nm, pkt_table, len); + pkts = send_pkt_netmap(&pktio_entry->s.pkt_nm, + pkt_table, len); break; #endif default: diff --git a/platform/linux-generic/source/odp_packet_socket.c b/platform/linux-generic/source/odp_packet_socket.c index aaf2605..4e5803f 100644 --- a/platform/linux-generic/source/odp_packet_socket.c +++ b/platform/linux-generic/source/odp_packet_socket.c @@ -63,10 +63,9 @@ static inline int ethaddrs_equal(unsigned char mac_a[], unsigned char mac_b[]) return !memcmp(mac_a, mac_b, ETH_ALEN); } -static int set_pkt_sock_fanout(pkt_sock_t * const pkt_sock, int sock_group_idx) +static int set_pkt_sock_fanout_mmap(pkt_sock_mmap_t * const pkt_sock, + int sock_group_idx) { -#if ODP_PACKET_SOCKET_FANOUT == 1 - /* Use FANOUT-mode for socket */ int sockfd = pkt_sock->sockfd; int val; int err; @@ -80,16 +79,9 @@ static int set_pkt_sock_fanout(pkt_sock_t * const pkt_sock, int sock_group_idx) perror("set_pkt_sock_fanout() - setsockopt(PACKET_FANOUT)"); return -1; } -#else - (void)pkt_sock; - (void)sock_group_idx; -#endif - return 0; } -#if (ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_BASIC) || \ - (ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_MMSG) /* * ODP_PACKET_SOCKET_BASIC: * ODP_PACKET_SOCKET_MMSG: @@ -163,11 +155,6 @@ int setup_pkt_sock(pkt_sock_t * const pkt_sock, char *netdev, return -1; } - /* configure PACKET_FANOUT mode for socket (if mode enabled) */ - err = set_pkt_sock_fanout(pkt_sock, if_idx); - if (err != 0) - return -1; - return sockfd; } @@ -184,13 +171,11 @@ int close_pkt_sock(pkt_sock_t * const pkt_sock) return 0; } -#endif -#if ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_BASIC /* * ODP_PACKET_SOCKET_BASIC: */ -int recv_pkt_sock(pkt_sock_t *const pkt_sock, +int recv_pkt_sock_basic(pkt_sock_t *const pkt_sock, odp_packet_t pkt_table[], unsigned len) { ssize_t recv_bytes; @@ -240,7 +225,7 @@ int recv_pkt_sock(pkt_sock_t *const pkt_sock, /* * ODP_PACKET_SOCKET_BASIC: */ -int send_pkt_sock(pkt_sock_t * const pkt_sock, +int send_pkt_sock_basic(pkt_sock_t * const pkt_sock, odp_packet_t pkt_table[], unsigned len) { odp_packet_t pkt; @@ -281,11 +266,10 @@ int send_pkt_sock(pkt_sock_t * const pkt_sock, return nb_tx; } -#elif ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_MMSG /* * ODP_PACKET_SOCKET_MMSG: */ -int recv_pkt_sock(pkt_sock_t * const pkt_sock, +int recv_pkt_sock_mmsg(pkt_sock_t * const pkt_sock, odp_packet_t pkt_table[], unsigned len) { const int sockfd = pkt_sock->sockfd; @@ -348,7 +332,7 @@ int recv_pkt_sock(pkt_sock_t * const pkt_sock, /* * ODP_PACKET_SOCKET_MMSG: */ -int send_pkt_sock(pkt_sock_t * const pkt_sock, +int send_pkt_sock_mmsg(pkt_sock_t * const pkt_sock, odp_packet_t pkt_table[], unsigned len) { struct mmsghdr msgvec[ODP_PACKET_SOCKET_MAX_BURST_TX]; @@ -387,7 +371,6 @@ int send_pkt_sock(pkt_sock_t * const pkt_sock, return len; } -#elif ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_MMAP /* * ODP_PACKET_SOCKET_MMAP: */ @@ -402,7 +385,7 @@ union frame_map { void *raw; }; -static int pkt_socket(void) +static int mmap_pkt_socket(void) { int ver = TPACKET_V2; @@ -421,23 +404,23 @@ static int pkt_socket(void) return sock; } -static inline int rx_kernel_ready(struct tpacket2_hdr *hdr) +static inline int mmap_rx_kernel_ready(struct tpacket2_hdr *hdr) { return ((hdr->tp_status & TP_STATUS_USER) == TP_STATUS_USER); } -static inline void rx_user_ready(struct tpacket2_hdr *hdr) +static inline void mmap_rx_user_ready(struct tpacket2_hdr *hdr) { hdr->tp_status = TP_STATUS_KERNEL; __sync_synchronize(); } -static inline int tx_kernel_ready(struct tpacket2_hdr *hdr) +static inline int mmap_tx_kernel_ready(struct tpacket2_hdr *hdr) { return !(hdr->tp_status & (TP_STATUS_SEND_REQUEST | TP_STATUS_SENDING)); } -static inline void tx_user_ready(struct tpacket2_hdr *hdr) +static inline void mmap_tx_user_ready(struct tpacket2_hdr *hdr) { hdr->tp_status = TP_STATUS_SEND_REQUEST; __sync_synchronize(); @@ -462,7 +445,7 @@ static inline unsigned pkt_mmap_v2_rx(int sock, struct ring *ring, frame_num = ring->frame_num; while (i < len) { - if (rx_kernel_ready(ring->rd[frame_num].iov_base)) { + if (mmap_rx_kernel_ready(ring->rd[frame_num].iov_base)) { ppd.raw = ring->rd[frame_num].iov_base; next_frame_num = (frame_num + 1) % ring->rd_num; @@ -474,7 +457,7 @@ static inline unsigned pkt_mmap_v2_rx(int sock, struct ring *ring, eth_hdr = (struct ethhdr *)pkt_buf; if (odp_unlikely(ethaddrs_equal(if_mac, eth_hdr->h_source))) { - rx_user_ready(ppd.raw); /* drop */ + mmap_rx_user_ready(ppd.raw); /* drop */ continue; } @@ -486,7 +469,7 @@ static inline unsigned pkt_mmap_v2_rx(int sock, struct ring *ring, + frame_offset; memcpy(l2_hdr, pkt_buf, pkt_len); - rx_user_ready(ppd.raw); + mmap_rx_user_ready(ppd.raw); /* Parse and set packet header data */ odp_packet_parse(pkt_table[i], pkt_len, frame_offset); @@ -516,7 +499,7 @@ static inline unsigned pkt_mmap_v2_tx(int sock, struct ring *ring, frame_num = ring->frame_num; while (i < len) { - if (tx_kernel_ready(ring->rd[frame_num].iov_base)) { + if (mmap_tx_kernel_ready(ring->rd[frame_num].iov_base)) { ppd.raw = ring->rd[frame_num].iov_base; next_frame_num = (frame_num + 1) % ring->rd_num; @@ -530,7 +513,7 @@ static inline unsigned pkt_mmap_v2_tx(int sock, struct ring *ring, memcpy((uint8_t *)ppd.raw + TPACKET2_HDRLEN - sizeof(struct sockaddr_ll), pkt_buf, pkt_len); - tx_user_ready(ppd.raw); + mmap_tx_user_ready(ppd.raw); odp_packet_free(pkt_table[i]); frame_num = next_frame_num; @@ -553,7 +536,7 @@ static inline unsigned pkt_mmap_v2_tx(int sock, struct ring *ring, return i; } -static void fill_ring(struct ring *ring, unsigned blocks) +static void mmap_fill_ring(struct ring *ring, unsigned blocks) { ring->req.tp_block_size = getpagesize() << 2; ring->req.tp_frame_size = TPACKET_ALIGNMENT << 7; @@ -567,7 +550,7 @@ static void fill_ring(struct ring *ring, unsigned blocks) ring->flen = ring->req.tp_frame_size; } -static int set_packet_loss_discard(int sock) +static int mmap_set_packet_loss_discard(int sock) { int ret, discard = 1; @@ -581,7 +564,7 @@ static int set_packet_loss_discard(int sock) return 0; } -static int setup_ring(int sock, struct ring *ring, int type) +static int mmap_setup_ring(int sock, struct ring *ring, int type) { int ret = 0; unsigned blocks = 256; @@ -591,12 +574,12 @@ static int setup_ring(int sock, struct ring *ring, int type) ring->version = TPACKET_V2; if (type == PACKET_TX_RING) { - ret = set_packet_loss_discard(sock); + ret = mmap_set_packet_loss_discard(sock); if (ret != 0) return -1; } - fill_ring(ring, blocks); + mmap_fill_ring(ring, blocks); ret = setsockopt(sock, SOL_PACKET, type, &ring->req, sizeof(ring->req)); if (ret == -1) { @@ -614,7 +597,7 @@ static int setup_ring(int sock, struct ring *ring, int type) return 0; } -static int mmap_sock(pkt_sock_t *pkt_sock) +static int mmap_sock(pkt_sock_mmap_t *pkt_sock) { int i; int sock = pkt_sock->sockfd; @@ -655,14 +638,14 @@ static int mmap_sock(pkt_sock_t *pkt_sock) return 0; } -static void unmap_sock(pkt_sock_t *pkt_sock) +static void mmap_unmap_sock(pkt_sock_mmap_t *pkt_sock) { munmap(pkt_sock->mmap_base, pkt_sock->mmap_len); free(pkt_sock->rx_ring.rd); free(pkt_sock->tx_ring.rd); } -static int bind_sock(pkt_sock_t *pkt_sock, char *netdev) +static int mmap_bind_sock(pkt_sock_mmap_t *pkt_sock, char *netdev) { int ret; @@ -684,7 +667,7 @@ static int bind_sock(pkt_sock_t *pkt_sock, char *netdev) return 0; } -static int store_hw_addr(pkt_sock_t * const pkt_sock, char *netdev) +static int mmap_store_hw_addr(pkt_sock_mmap_t * const pkt_sock, char *netdev) { struct ifreq ethreq; int ret; @@ -707,8 +690,8 @@ static int store_hw_addr(pkt_sock_t * const pkt_sock, char *netdev) /* * ODP_PACKET_SOCKET_MMAP: */ -int setup_pkt_sock(pkt_sock_t * const pkt_sock, char *netdev, - odp_buffer_pool_t pool) +int setup_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock, char *netdev, + odp_buffer_pool_t pool, int fanout) { odp_packet_t pkt; uint8_t *pkt_buf; @@ -733,17 +716,19 @@ int setup_pkt_sock(pkt_sock_t * const pkt_sock, char *netdev, odp_packet_free(pkt); pkt_sock->pool = pool; - pkt_sock->sockfd = pkt_socket(); + pkt_sock->sockfd = mmap_pkt_socket(); - ret = bind_sock(pkt_sock, netdev); + ret = mmap_bind_sock(pkt_sock, netdev); if (ret != 0) return -1; - ret = setup_ring(pkt_sock->sockfd, &pkt_sock->tx_ring, PACKET_TX_RING); + ret = mmap_setup_ring(pkt_sock->sockfd, &pkt_sock->tx_ring, + PACKET_TX_RING); if (ret != 0) return -1; - ret = setup_ring(pkt_sock->sockfd, &pkt_sock->rx_ring, PACKET_RX_RING); + ret = mmap_setup_ring(pkt_sock->sockfd, &pkt_sock->rx_ring, + PACKET_RX_RING); if (ret != 0) return -1; @@ -751,7 +736,7 @@ int setup_pkt_sock(pkt_sock_t * const pkt_sock, char *netdev, if (ret != 0) return -1; - ret = store_hw_addr(pkt_sock, netdev); + ret = mmap_store_hw_addr(pkt_sock, netdev); if (ret != 0) return -1; @@ -761,9 +746,11 @@ int setup_pkt_sock(pkt_sock_t * const pkt_sock, char *netdev, return -1; } - ret = set_pkt_sock_fanout(pkt_sock, if_idx); - if (ret != 0) - return -1; + if (fanout) { + ret = set_pkt_sock_fanout_mmap(pkt_sock, if_idx); + if (ret != 0) + return -1; + } return pkt_sock->sockfd; } @@ -771,9 +758,9 @@ int setup_pkt_sock(pkt_sock_t * const pkt_sock, char *netdev, /* * ODP_PACKET_SOCKET_MMAP: */ -int close_pkt_sock(pkt_sock_t * const pkt_sock) +int close_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock) { - unmap_sock(pkt_sock); + mmap_unmap_sock(pkt_sock); if (close(pkt_sock->sockfd) != 0) { perror("close_pkt_sock() - close(sockfd)"); return -1; @@ -785,7 +772,7 @@ int close_pkt_sock(pkt_sock_t * const pkt_sock) /* * ODP_PACKET_SOCKET_MMAP: */ -int recv_pkt_sock(pkt_sock_t * const pkt_sock, +int recv_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock, odp_packet_t pkt_table[], unsigned len) { return pkt_mmap_v2_rx(pkt_sock->rx_ring.sock, &pkt_sock->rx_ring, @@ -796,13 +783,9 @@ int recv_pkt_sock(pkt_sock_t * const pkt_sock, /* * ODP_PACKET_SOCKET_MMAP: */ -int send_pkt_sock(pkt_sock_t * const pkt_sock, +int send_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock, odp_packet_t pkt_table[], unsigned len) { return pkt_mmap_v2_tx(pkt_sock->tx_ring.sock, &pkt_sock->tx_ring, pkt_table, len); } - -#else -#error "Unsupported ODP_PACKET_SOCKET_MODE!" -#endif diff --git a/test/packet/odp_example_pktio.c b/test/packet/odp_example_pktio.c index 85bbdd7..1d62123 100644 --- a/test/packet/odp_example_pktio.c +++ b/test/packet/odp_example_pktio.c @@ -42,6 +42,8 @@ typedef struct { int if_count; /**< Number of interfaces to be used */ char **if_names; /**< Array of pointers to interface names */ int mode; /**< Packet IO mode */ + int type; /**< Packet IO type */ + int fanout; /**< Packet IO fanout */ odp_buffer_pool_t pool; /**< Buffer pool for packet IO */ } appl_args_t; @@ -52,6 +54,8 @@ typedef struct { char *pktio_dev; /**< Interface name to use */ odp_buffer_pool_t pool; /**< Buffer pool for packet IO */ int mode; /**< Thread mode */ + int type; /**< Thread i/o type */ + int fanout; /**< Thread i/o fanout */ } thread_args_t; /** @@ -111,7 +115,8 @@ static void *pktio_queue_thread(void *arg) } /* Open a packet IO instance for this thread */ - sock_params->type = ODP_PKTIO_TYPE_SOCKET; + sock_params->type = thr_args->type; + sock_params->fanout = thr_args->fanout; pktio = odp_pktio_open(thr_args->pktio_dev, thr_args->pool, ¶ms); if (pktio == ODP_PKTIO_INVALID) { ODP_ERR(" [%02i] Error: pktio create failed\n", thr); @@ -223,7 +228,8 @@ static void *pktio_ifburst_thread(void *arg) } /* Open a packet IO instance for this thread */ - sock_params->type = ODP_PKTIO_TYPE_SOCKET; + sock_params->type = thr_args->type; + sock_params->fanout = thr_args->fanout; pktio = odp_pktio_open(thr_args->pktio_dev, thr_args->pool, ¶ms); if (pktio == ODP_PKTIO_INVALID) { ODP_ERR(" [%02i] Error: pktio create failed.\n", thr); @@ -357,6 +363,8 @@ int main(int argc, char *argv[]) args->thread[i].pktio_dev = args->appl.if_names[if_idx]; args->thread[i].pool = pool; args->thread[i].mode = args->appl.mode; + args->thread[i].type = args->appl.type; + args->thread[i].fanout = args->appl.fanout; if (args->appl.mode == APPL_MODE_PKT_BURST) thr_run_func = pktio_ifburst_thread; @@ -470,9 +478,11 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) }; appl_args->mode = -1; /* Invalid, must be changed by parsing */ + appl_args->type = 3; /* 3: ODP_PKTIO_TYPE_SOCKET_MMAP */ + appl_args->fanout = 1; /* turn off fanout by default for mmap */ while (1) { - opt = getopt_long(argc, argv, "+c:i:m:h", + opt = getopt_long(argc, argv, "+c:i:m:t:f:h", longopts, &long_index); if (opt == -1) @@ -533,6 +543,14 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) appl_args->mode = APPL_MODE_PKT_QUEUE; break; + case 't': + appl_args->type = atoi(optarg); + break; + + case 'f': + appl_args->type = atoi(optarg); + break; + case 'h': usage(argv[0]); exit(EXIT_SUCCESS); @@ -602,6 +620,12 @@ static void usage(char *progname) " -i, --interface Eth interfaces (comma-separated, no spaces)\n" " -m, --mode 0: Burst send&receive packets (no queues)\n" " 1: Send&receive packets through ODP queues.\n" + " -t, --type 1: ODP_PKTIO_TYPE_SOCKET_BASIC\n" + " 2: ODP_PKTIO_TYPE_SOCKET_MMSG\n" + " 3: ODP_PKTIO_TYPE_SOCKET_MMAP\n" + " 4: ODP_PKTIO_TYPE_NETMAP\n" + " Default: 3: ODP_PKTIO_TYPE_SOCKET_MMAP\n" + " -f, --fanout 0: off 1: on (Default 1: on)\n" "\n" "Optional OPTIONS\n" " -c, --count <number> Core count.\n"
Dynamically select type of packet I/O sock_params->type = ODP_PKTIO_TYPE_SOCKET_BASIC ODP_PKTIO_TYPE_SOCKET_MMSG ODP_PKTIO_TYPE_SOCKET_MMAP ODP_PKTIO_TYPE_NETMAP sock_params->fanout = 1; pktio = odp_pktio_open(thr_args->pktio_dev, thr_args->pool, ¶ms); v2: - remove NETMAP define in enum; - add command line parameters to odp_example_pktio for I/O selection. v3: - add default cases for switch to fix compilation. Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org> --- .../linux-generic/include/api/odp_pktio_socket.h | 1 + .../linux-generic/include/api/odp_pktio_types.h | 8 +- .../linux-generic/include/odp_packet_io_internal.h | 1 + platform/linux-generic/include/odp_packet_socket.h | 55 ++++------- platform/linux-generic/source/odp_packet_io.c | 71 +++++++++++--- platform/linux-generic/source/odp_packet_socket.c | 103 +++++++++------------ test/packet/odp_example_pktio.c | 30 +++++- 7 files changed, 155 insertions(+), 114 deletions(-)