diff mbox

[ODP/PATCHv4] rework packet io selection

Message ID 1396343538-22705-1-git-send-email-maxim.uvarov@linaro.org
State Accepted
Headers show

Commit Message

Maxim Uvarov April 1, 2014, 9:12 a.m. UTC
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, &params);

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.
v4:
 - fix fanout parse in test application.

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(-)

Comments

Maxim Uvarov April 1, 2014, 9:19 a.m. UTC | #1
Interesting thing with that patch is that I started to get 54 bytes 
packets as Ciprian did with netmap:

odp_packet_parse() len 54 < 60
odp_example_pktio.c:170:pktio_queue_thread(): Drop frame - err_cnt:1
odp_packet_parse() len 54 < 60
odp_example_pktio.c:170:pktio_queue_thread(): Drop frame - err_cnt:2
odp_packet_parse() len 54 < 60
odp_example_pktio.c:170:pktio_queue_thread(): Drop frame - err_cnt:3
odp_packet_parse() len 54 < 60

I.e. recvfrom() from recv_pkt_sock_basic()  returns 54.

Maxim.

On 04/01/2014 01:12 PM, Maxim Uvarov 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, &params);
>
> 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.
> v4:
>   - fix fanout parse in test application.
>
> 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, &params->nm_params);
> +				pool, &params->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..10190a0 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, &params);
>   	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, &params);
>   	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->fanout = 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"
Anders Roxell April 1, 2014, 1:03 p.m. UTC | #2
On 1 April 2014 11:12, 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, &params);
>
> 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.
> v4:
>  - fix fanout parse in test application.
>

Cleanup the commit message to 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, &params->nm_params);
> +                               pool, &params->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..10190a0 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,
> &params);
>         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,
> &params);
>         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->fanout = 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/1396343538-22705-1-git-send-email-maxim.uvarov%40linaro.org
> .
> For more options, visit https://groups.google.com/a/linaro.org/d/optout.
>
Maxim Uvarov April 1, 2014, 1:04 p.m. UTC | #3
On 04/01/2014 05:03 PM, Anders Roxell wrote:
>
>
>
> On 1 April 2014 11:12, Maxim Uvarov <maxim.uvarov@linaro.org 
> <mailto: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, &params);
>
>     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.
>     v4:
>      - fix fanout parse in test application.
>
>
> Cleanup the commit message to just said what the patch is.
> If you need to describe what happened between different versions that 
> should go below the "---"

how to add comments below the "--" ?

Maxim.
>
> Cheers,
> Anders
>
>
>     Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org
>     <mailto: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, &params->nm_params);
>     +                               pool, &params->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..10190a0 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, &params);
>             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, &params);
>             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->fanout = 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
>     <mailto: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
>     <mailto:lng-odp%2Bunsubscribe@linaro.org>.
>     To post to this group, send email to lng-odp@linaro.org
>     <mailto: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/1396343538-22705-1-git-send-email-maxim.uvarov%40linaro.org.
>     For more options, visit
>     https://groups.google.com/a/linaro.org/d/optout.
>
>
Anders Roxell April 1, 2014, 1:26 p.m. UTC | #4
On 1 April 2014 15:04, Maxim Uvarov <maxim.uvarov@linaro.org> wrote:

> On 04/01/2014 05:03 PM, Anders Roxell wrote:
>
>
>>
>>
>> On 1 April 2014 11:12, Maxim Uvarov <maxim.uvarov@linaro.org <mailto:
>> 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, &params);
>>
>>     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.
>>     v4:
>>      - fix fanout parse in test application.
>>
>>
>> Cleanup the commit message to just said what the patch is.
>> If you need to describe what happened between different versions that
>> should go below the "---"
>>
>
> how to add comments below the "--" ?
>

open the patch file with your favorite editor and go to line "---"
insert a new line and start typing, thats how I do it... unsure if there
are other ways to do that...

Cheers,


>
> Maxim.
>
>>
>> Cheers,
>> Anders
>>
>>
>>     Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org
>>     <mailto: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, &params->nm_params);
>>     +                               pool, &params->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..10190a0 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, &params);
>>             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, &params);
>>             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->fanout = 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
>>     <mailto: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
>>     <mailto:lng-odp%2Bunsubscribe@linaro.org>.
>>
>>     To post to this group, send email to lng-odp@linaro.org
>>     <mailto: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/
>> 1396343538-22705-1-git-send-email-maxim.uvarov%40linaro.org.
>>     For more options, visit
>>     https://groups.google.com/a/linaro.org/d/optout.
>>
>>
>>
>
Maxim Uvarov April 2, 2014, 10:55 a.m. UTC | #5
I saw this only with wlan0. With eth everything works on. So I'm going 
to apply this patch.

Maxim.

On 04/01/2014 01:19 PM, Maxim Uvarov wrote:
> Interesting thing with that patch is that I started to get 54 bytes 
> packets as Ciprian did with netmap:
>
> odp_packet_parse() len 54 < 60
> odp_example_pktio.c:170:pktio_queue_thread(): Drop frame - err_cnt:1
> odp_packet_parse() len 54 < 60
> odp_example_pktio.c:170:pktio_queue_thread(): Drop frame - err_cnt:2
> odp_packet_parse() len 54 < 60
> odp_example_pktio.c:170:pktio_queue_thread(): Drop frame - err_cnt:3
> odp_packet_parse() len 54 < 60
>
> I.e. recvfrom() from recv_pkt_sock_basic()  returns 54.
>
> Maxim.
>
Ola Liljedahl April 2, 2014, 11:47 a.m. UTC | #6
Because WLAN (IEEE 802.11) is not IEEE 803.2 (a.k.a. Ethernet")?

WLAN frames have different MAC headers but you probably don't see them in
the application. Possibly 802.11 has a minimum frame size as well, it using
a CSMA/CD type of mechanism I believe. I have no idea what that minimum
frame size would be though. And why should we care?

I thought someone said that this Netmap support would only be used for
Ethernet and thus we could ensure some level of Ethernet compliance. Is
this still true?


On 2 April 2014 12:55, Maxim Uvarov <maxim.uvarov@linaro.org> wrote:

> I saw this only with wlan0. With eth everything works on. So I'm going to
> apply this patch.
>
> Maxim.
>
> On 04/01/2014 01:19 PM, Maxim Uvarov wrote:
>
>> Interesting thing with that patch is that I started to get 54 bytes
>> packets as Ciprian did with netmap:
>>
>> odp_packet_parse() len 54 < 60
>> odp_example_pktio.c:170:pktio_queue_thread(): Drop frame - err_cnt:1
>> odp_packet_parse() len 54 < 60
>> odp_example_pktio.c:170:pktio_queue_thread(): Drop frame - err_cnt:2
>> odp_packet_parse() len 54 < 60
>> odp_example_pktio.c:170:pktio_queue_thread(): Drop frame - err_cnt:3
>> odp_packet_parse() len 54 < 60
>>
>> I.e. recvfrom() from recv_pkt_sock_basic()  returns 54.
>>
>> Maxim.
>>
>>
> --
> 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/533BECA6.4040505%40linaro.org.
> For more options, visit https://groups.google.com/a/linaro.org/d/optout.
>
Maxim Uvarov April 2, 2014, 12:06 p.m. UTC | #7
On 04/02/2014 03:47 PM, Ola Liljedahl wrote:
> Because WLAN (IEEE 802.11) is not IEEE 803.2 (a.k.a. Ethernet")?
>
> WLAN frames have different MAC headers but you probably don't see them 
> in the application. Possibly 802.11 has a minimum frame size as well, 
> it using a CSMA/CD type of mechanism I believe. I have no idea what 
> that minimum frame size would be though. And why should we care?
>
> I thought someone said that this Netmap support would only be used for 
> Ethernet and thus we could ensure some level of Ethernet compliance. 
> Is this still true?
>
this patch is not for Netmap.  It is for dynamic I/O selection (raw 
socket, packet mmap, netmap and etc).

But that is good question if we are going to operate only Ethernet 
packets or not. Probably we need to add packet_parse() for WLAN frames 
as well.

Maxim.
>
> On 2 April 2014 12:55, Maxim Uvarov <maxim.uvarov@linaro.org 
> <mailto:maxim.uvarov@linaro.org>> wrote:
>
>     I saw this only with wlan0. With eth everything works on. So I'm
>     going to apply this patch.
>
>     Maxim.
>
>     On 04/01/2014 01:19 PM, Maxim Uvarov wrote:
>
>         Interesting thing with that patch is that I started to get 54
>         bytes packets as Ciprian did with netmap:
>
>         odp_packet_parse() len 54 < 60
>         odp_example_pktio.c:170:pktio_queue_thread(): Drop frame -
>         err_cnt:1
>         odp_packet_parse() len 54 < 60
>         odp_example_pktio.c:170:pktio_queue_thread(): Drop frame -
>         err_cnt:2
>         odp_packet_parse() len 54 < 60
>         odp_example_pktio.c:170:pktio_queue_thread(): Drop frame -
>         err_cnt:3
>         odp_packet_parse() len 54 < 60
>
>         I.e. recvfrom() from recv_pkt_sock_basic()  returns 54.
>
>         Maxim.
>
>
>     -- 
>     You received this message because you are subscribed to the Google
>     Groups "LNG ODP Sub-team - lng-odp@linaro.org
>     <mailto: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
>     <mailto:lng-odp%2Bunsubscribe@linaro.org>.
>     To post to this group, send email to lng-odp@linaro.org
>     <mailto: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/533BECA6.4040505%40linaro.org.
>     For more options, visit
>     https://groups.google.com/a/linaro.org/d/optout.
>
>
Ciprian Barbu April 2, 2014, 12:32 p.m. UTC | #8
On Tue, Apr 1, 2014 at 12:19 PM, Maxim Uvarov <maxim.uvarov@linaro.org>wrote:

> Interesting thing with that patch is that I started to get 54 bytes
> packets as Ciprian did with netmap:
>
> odp_packet_parse() len 54 < 60
> odp_example_pktio.c:170:pktio_queue_thread(): Drop frame - err_cnt:1
> odp_packet_parse() len 54 < 60
> odp_example_pktio.c:170:pktio_queue_thread(): Drop frame - err_cnt:2
> odp_packet_parse() len 54 < 60
> odp_example_pktio.c:170:pktio_queue_thread(): Drop frame - err_cnt:3
> odp_packet_parse() len 54 < 60
>
> I.e. recvfrom() from recv_pkt_sock_basic()  returns 54.
>

That's because the socket sniffs all packets, coming or going. In your case
as well as mine, the 54 bytes packets come from the Linux stack, all of the
packets received at the physical interface should already be padded.


>
> Maxim.
>
>
> On 04/01/2014 01:12 PM, Maxim Uvarov 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, &params);
>>
>> 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.
>> v4:
>>   - fix fanout parse in test application.
>>
>> 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, &params->nm_params);
>> +                               pool, &params->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..10190a0 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,
>> &params);
>>         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,
>> &params);
>>         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->fanout = 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"
>>
>
> --
> 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/533A84A0.5080005%40linaro.org.
>
> For more options, visit https://groups.google.com/a/linaro.org/d/optout.
>
Maxim Uvarov April 2, 2014, 12:38 p.m. UTC | #9
On 04/02/2014 04:32 PM, Ciprian Barbu wrote:
>
>
>
> On Tue, Apr 1, 2014 at 12:19 PM, Maxim Uvarov <maxim.uvarov@linaro.org 
> <mailto:maxim.uvarov@linaro.org>> wrote:
>
>     Interesting thing with that patch is that I started to get 54
>     bytes packets as Ciprian did with netmap:
>
>     odp_packet_parse() len 54 < 60
>     odp_example_pktio.c:170:pktio_queue_thread(): Drop frame - err_cnt:1
>     odp_packet_parse() len 54 < 60
>     odp_example_pktio.c:170:pktio_queue_thread(): Drop frame - err_cnt:2
>     odp_packet_parse() len 54 < 60
>     odp_example_pktio.c:170:pktio_queue_thread(): Drop frame - err_cnt:3
>     odp_packet_parse() len 54 < 60
>
>     I.e. recvfrom() from recv_pkt_sock_basic()  returns 54.
>
>
> That's because the socket sniffs all packets, coming or going. In your 
> case as well as mine, the 54 bytes packets come from the Linux stack, 
> all of the packets received at the physical interface should already 
> be padded.

So I think we need to fix that otherwise we will have questions again 
and again. Or at least add some comment to the code.

Maxim.


>
>     Maxim.
>
>
>     On 04/01/2014 01:12 PM, Maxim Uvarov 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,
>         &params);
>
>         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.
>         v4:
>           - fix fanout parse in test application.
>
>         Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org
>         <mailto: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, &params->nm_params);
>         +                               pool, &params->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..10190a0 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, &params);
>                 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, &params);
>                 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->fanout = 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"
>
>
>     -- 
>     You received this message because you are subscribed to the Google
>     Groups "LNG ODP Sub-team - lng-odp@linaro.org
>     <mailto: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
>     <mailto:lng-odp%2Bunsubscribe@linaro.org>.
>     To post to this group, send email to lng-odp@linaro.org
>     <mailto: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/533A84A0.5080005%40linaro.org.
>
>
>     For more options, visit
>     https://groups.google.com/a/linaro.org/d/optout.
>
>
Ciprian Barbu April 2, 2014, 12:44 p.m. UTC | #10
On Wed, Apr 2, 2014 at 3:38 PM, Maxim Uvarov <maxim.uvarov@linaro.org>wrote:

> On 04/02/2014 04:32 PM, Ciprian Barbu wrote:
>
>
>>
>>
>> On Tue, Apr 1, 2014 at 12:19 PM, Maxim Uvarov <maxim.uvarov@linaro.org<mailto:
>> maxim.uvarov@linaro.org>> wrote:
>>
>>     Interesting thing with that patch is that I started to get 54
>>     bytes packets as Ciprian did with netmap:
>>
>>     odp_packet_parse() len 54 < 60
>>     odp_example_pktio.c:170:pktio_queue_thread(): Drop frame - err_cnt:1
>>     odp_packet_parse() len 54 < 60
>>     odp_example_pktio.c:170:pktio_queue_thread(): Drop frame - err_cnt:2
>>     odp_packet_parse() len 54 < 60
>>     odp_example_pktio.c:170:pktio_queue_thread(): Drop frame - err_cnt:3
>>     odp_packet_parse() len 54 < 60
>>
>>     I.e. recvfrom() from recv_pkt_sock_basic()  returns 54.
>>
>>
>> That's because the socket sniffs all packets, coming or going. In your
>> case as well as mine, the 54 bytes packets come from the Linux stack, all
>> of the packets received at the physical interface should already be padded.
>>
>
> So I think we need to fix that otherwise we will have questions again and
> again. Or at least add some comment to the code.
>

Yeah, but I'm trying to reproduce it, so far it didn't happen.


>
> Maxim.
>
>
>
>>     Maxim.
>>
>>
>>     On 04/01/2014 01:12 PM, Maxim Uvarov 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,
>>         &params);
>>
>>         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.
>>         v4:
>>           - fix fanout parse in test application.
>>
>>         Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org
>>         <mailto: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, &params->nm_params);
>>         +                               pool, &params->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..10190a0 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, &params);
>>                 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, &params);
>>                 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->fanout = 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"
>>
>>
>>     --     You received this message because you are subscribed to the
>> Google
>>     Groups "LNG ODP Sub-team - lng-odp@linaro.org
>>     <mailto: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
>>     <mailto:lng-odp%2Bunsubscribe@linaro.org>.
>>
>>     To post to this group, send email to lng-odp@linaro.org
>>     <mailto: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/
>> 533A84A0.5080005%40linaro.org.
>>
>>
>>     For more options, visit
>>     https://groups.google.com/a/linaro.org/d/optout.
>>
>>
>>
>
Ciprian Barbu April 2, 2014, 12:53 p.m. UTC | #11
On Wed, Apr 2, 2014 at 3:44 PM, Ciprian Barbu <ciprian.barbu@linaro.org>wrote:

>
>
>
> On Wed, Apr 2, 2014 at 3:38 PM, Maxim Uvarov <maxim.uvarov@linaro.org>wrote:
>
>> On 04/02/2014 04:32 PM, Ciprian Barbu wrote:
>>
>>
>>>
>>>
>>> On Tue, Apr 1, 2014 at 12:19 PM, Maxim Uvarov <maxim.uvarov@linaro.org<mailto:
>>> maxim.uvarov@linaro.org>> wrote:
>>>
>>>     Interesting thing with that patch is that I started to get 54
>>>     bytes packets as Ciprian did with netmap:
>>>
>>>     odp_packet_parse() len 54 < 60
>>>     odp_example_pktio.c:170:pktio_queue_thread(): Drop frame - err_cnt:1
>>>     odp_packet_parse() len 54 < 60
>>>     odp_example_pktio.c:170:pktio_queue_thread(): Drop frame - err_cnt:2
>>>     odp_packet_parse() len 54 < 60
>>>     odp_example_pktio.c:170:pktio_queue_thread(): Drop frame - err_cnt:3
>>>     odp_packet_parse() len 54 < 60
>>>
>>>     I.e. recvfrom() from recv_pkt_sock_basic()  returns 54.
>>>
>>>
>>> That's because the socket sniffs all packets, coming or going. In your
>>> case as well as mine, the 54 bytes packets come from the Linux stack, all
>>> of the packets received at the physical interface should already be padded.
>>>
>>
>> So I think we need to fix that otherwise we will have questions again and
>> again. Or at least add some comment to the code.
>>
>
> Yeah, but I'm trying to reproduce it, so far it didn't happen.
>

Something else must have happened, I don't see packet that were sent from
the host running the odp example. Is it reprodocible on your side?

>
>
>>
>> Maxim.
>>
>>
>>
>>>     Maxim.
>>>
>>>
>>>     On 04/01/2014 01:12 PM, Maxim Uvarov 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,
>>>         &params);
>>>
>>>         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.
>>>         v4:
>>>           - fix fanout parse in test application.
>>>
>>>         Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org
>>>         <mailto: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, &params->nm_params);
>>>         +                               pool, &params->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..10190a0 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, &params);
>>>                 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, &params);
>>>                 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->fanout = 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"
>>>
>>>
>>>     --     You received this message because you are subscribed to the
>>> Google
>>>     Groups "LNG ODP Sub-team - lng-odp@linaro.org
>>>     <mailto: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
>>>     <mailto:lng-odp%2Bunsubscribe@linaro.org>.
>>>
>>>     To post to this group, send email to lng-odp@linaro.org
>>>     <mailto: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/
>>> 533A84A0.5080005%40linaro.org.
>>>
>>>
>>>     For more options, visit
>>>     https://groups.google.com/a/linaro.org/d/optout.
>>>
>>>
>>>
>>
>
Maxim Uvarov April 2, 2014, 1:28 p.m. UTC | #12
On 04/02/2014 04:53 PM, Ciprian Barbu wrote:
>
>
>
> On Wed, Apr 2, 2014 at 3:44 PM, Ciprian Barbu 
> <ciprian.barbu@linaro.org <mailto:ciprian.barbu@linaro.org>> wrote:
>
>
>
>
>     On Wed, Apr 2, 2014 at 3:38 PM, Maxim Uvarov
>     <maxim.uvarov@linaro.org <mailto:maxim.uvarov@linaro.org>> wrote:
>
>         On 04/02/2014 04:32 PM, Ciprian Barbu wrote:
>
>
>
>
>             On Tue, Apr 1, 2014 at 12:19 PM, Maxim Uvarov
>             <maxim.uvarov@linaro.org <mailto:maxim.uvarov@linaro.org>
>             <mailto:maxim.uvarov@linaro.org
>             <mailto:maxim.uvarov@linaro.org>>> wrote:
>
>                 Interesting thing with that patch is that I started to
>             get 54
>                 bytes packets as Ciprian did with netmap:
>
>                 odp_packet_parse() len 54 < 60
>                 odp_example_pktio.c:170:pktio_queue_thread(): Drop
>             frame - err_cnt:1
>                 odp_packet_parse() len 54 < 60
>                 odp_example_pktio.c:170:pktio_queue_thread(): Drop
>             frame - err_cnt:2
>                 odp_packet_parse() len 54 < 60
>                 odp_example_pktio.c:170:pktio_queue_thread(): Drop
>             frame - err_cnt:3
>                 odp_packet_parse() len 54 < 60
>
>                 I.e. recvfrom() from recv_pkt_sock_basic()  returns 54.
>
>
>             That's because the socket sniffs all packets, coming or
>             going. In your case as well as mine, the 54 bytes packets
>             come from the Linux stack, all of the packets received at
>             the physical interface should already be padded.
>
>
>         So I think we need to fix that otherwise we will have
>         questions again and again. Or at least add some comment to the
>         code.
>
>
>     Yeah, but I'm trying to reproduce it, so far it didn't happen.
>
>
> Something else must have happened, I don't see packet that were sent 
> from the host running the odp example. Is it reprodocible on your side?

yep, with:
./odp_packet -i wlan0 -m 1 -t 1 -f 0

>
>         Maxim.
>
>
>
>                 Maxim.
>
>
>                 On 04/01/2014 01:12 PM, Maxim Uvarov 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,
>                     &params);
>
>                     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.
>                     v4:
>                       - fix fanout parse in test application.
>
>                     Signed-off-by: Maxim Uvarov
>             <maxim.uvarov@linaro.org <mailto:maxim.uvarov@linaro.org>
>                     <mailto:maxim.uvarov@linaro.org
>             <mailto: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, &params->nm_params);
>                     + pool, &params->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..10190a0 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, &params);
>                             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, &params);
>                             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->fanout = 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"
>
>
>                 --     You received this message because you are
>             subscribed to the Google
>                 Groups "LNG ODP Sub-team - lng-odp@linaro.org
>             <mailto:lng-odp@linaro.org>
>                 <mailto:lng-odp@linaro.org
>             <mailto: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
>             <mailto:lng-odp%2Bunsubscribe@linaro.org>
>                 <mailto:lng-odp%2Bunsubscribe@linaro.org
>             <mailto:lng-odp%252Bunsubscribe@linaro.org>>.
>
>                 To post to this group, send email to
>             lng-odp@linaro.org <mailto:lng-odp@linaro.org>
>                 <mailto:lng-odp@linaro.org <mailto: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/533A84A0.5080005%40linaro.org.
>
>
>                 For more options, visit
>             https://groups.google.com/a/linaro.org/d/optout.
>
>
>
>
>
diff mbox

Patch

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, &params->nm_params);
+				pool, &params->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..10190a0 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, &params);
 	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, &params);
 	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->fanout = 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"