On Wed, Nov 25, 2015 at 03:15:52PM +0200, Matias Elo wrote: > Added multi queue support to netmap pktio. > > Signed-off-by: Matias Elo <matias....@nokia.com> > --- > platform/linux-generic/include/odp_packet_netmap.h | 34 +- > platform/linux-generic/pktio/netmap.c | 426 > ++++++++++++++++++--- > 2 files changed, 406 insertions(+), 54 deletions(-) > > diff --git a/platform/linux-generic/include/odp_packet_netmap.h > b/platform/linux-generic/include/odp_packet_netmap.h > index a088d23..b38363a 100644 > --- a/platform/linux-generic/include/odp_packet_netmap.h > +++ b/platform/linux-generic/include/odp_packet_netmap.h > @@ -7,23 +7,53 @@ > #ifndef ODP_PACKET_NETMAP_H > #define ODP_PACKET_NETMAP_H > > +#include <odp/align.h> > +#include <odp/debug.h> > #include <odp/packet_io.h> > #include <odp/pool.h> > +#include <odp/ticketlock.h> > +#include <odp_align_internal.h> > > #include <linux/if_ether.h> > #include <net/if.h> > > +#define NM_MAX_DESC 32 > +#define NM_MAX_INPUT_QUEUES 32 > +#define NM_MAX_OUTPUT_QUEUES 32 > + > +/** Ring for mapping pktin/pktout queues to netmap descriptors */ > +struct netmap_ring_t { > + unsigned first; /**< Index of first netmap descriptor */ > + unsigned last; /**< Index of last netmap descriptor */ > + unsigned num; /**< Number of netmap descriptors */ > + /** Netmap metadata for the device */ > + struct nm_desc *desc[NM_MAX_DESC]; > + unsigned cur; /**< Index of current netmap descriptor */ > + odp_ticketlock_t lock; /**< Queue lock */ > +}; > + > +typedef union { > + struct netmap_ring_t s; > + uint8_t pad[ODP_CACHE_LINE_SIZE_ROUNDUP(sizeof(struct netmap_ring_t))]; > +} netmap_ring_t ODP_ALIGNED_CACHE; > + > /** Packet socket using netmap mmaped rings for both Rx and Tx */ > typedef struct { > odp_pool_t pool; /**< pool to alloc packets from */ > size_t max_frame_len; /**< buf_size - sizeof(pkt_hdr) */ > - struct nm_desc *rx_desc; /**< netmap meta-data for the device */ > - struct nm_desc *tx_desc; /**< netmap meta-data for the device */ > uint32_t if_flags; /**< interface flags */ > int sockfd; /**< control socket */ > unsigned char if_mac[ETH_ALEN]; /**< eth mac address */ > char nm_name[IF_NAMESIZE + 7]; /**< netmap:<ifname> */ > odp_pktio_capability_t capa; /**< interface capabilities */ > + unsigned num_rx_queues; /**< number of pktin queues */ > + unsigned num_tx_queues; /**< number of pktout queues */ > + odp_bool_t lockless_rx; /**< no locking for rx */ > + odp_bool_t lockless_tx; /**< no locking for tx */ > + /** mapping of pktin queues to netmap rx descriptors */ > + netmap_ring_t rx_desc_ring[NM_MAX_INPUT_QUEUES]; > + /** mapping of pktout queues to netmap tx descriptors */ > + netmap_ring_t tx_desc_ring[NM_MAX_OUTPUT_QUEUES]; > } pkt_netmap_t; > > #endif > diff --git a/platform/linux-generic/pktio/netmap.c > b/platform/linux-generic/pktio/netmap.c > index 313bcbe..236b48c 100644 > --- a/platform/linux-generic/pktio/netmap.c > +++ b/platform/linux-generic/pktio/netmap.c > @@ -75,15 +75,146 @@ done: > return err; > } > > +/** > + * Map netmap rings to pktin/pktout queues > + * > + * @param rings Array of netmap descriptor rings > + * @param num_queues Number of pktin/pktout queues > + * @param num_rings Number of matching netmap rings > + */ > +static inline void map_netmap_rings(netmap_ring_t *rings, > + unsigned num_queues, unsigned num_rings) > +{ > + struct netmap_ring_t *desc_ring; > + unsigned rings_per_queue; > + unsigned remainder; > + unsigned mapped_rings; > + unsigned i; > + unsigned desc_id = 0; > + > + rings_per_queue = num_rings / num_queues; > + remainder = num_rings % num_queues; > + > + if (remainder) > + ODP_DBG("WARNING: Netmap rings mapped unevenly to queues\n"); > + > + for (i = 0; i < num_queues; i++) { > + desc_ring = &rings[i].s; > + if (i < remainder) > + mapped_rings = rings_per_queue + 1; > + else > + mapped_rings = rings_per_queue; > + > + desc_ring->first = desc_id; > + desc_ring->cur = desc_id; > + desc_ring->last = desc_ring->first + mapped_rings - 1; > + desc_ring->num = mapped_rings; > + > + desc_id = desc_ring->last + 1; > + } > +} > + > +static int netmap_input_queues_config(pktio_entry_t *pktio_entry, > + const odp_pktio_input_queue_param_t *p) > +{ > + struct pktio_entry *pktio = &pktio_entry->s; > + pkt_netmap_t *pkt_nm = &pktio_entry->s.pkt_nm; > + odp_pktio_input_mode_t mode = pktio_entry->s.param.in_mode; > + odp_queue_t queue; > + unsigned num_queues = p->num_queues; > + unsigned i; > + > + if (mode == ODP_PKTIN_MODE_DISABLED) > + return -1; > + > + if (num_queues <= 0 || num_queues > pkt_nm->capa.max_input_queues || > + num_queues > NM_MAX_INPUT_QUEUES) { > + ODP_ERR("Invalid input queue count: %u\n", num_queues); > + return -1; > + } > + /* Map pktin queues to netmap rings */ > + map_netmap_rings(pkt_nm->rx_desc_ring, num_queues, > + pkt_nm->capa.max_input_queues); > + > + if (p->hash_enable) { > + if (rss_conf_set_fd(pktio_entry->s.pkt_nm.sockfd, > + pktio_entry->s.name, &p->hash_proto)) { > + ODP_ERR("Failed to configure input hash\n"); > + return -1;
odp_l2fwd errors out here when trying to use any interface that does not support the ETHTOOL_GRXFH ioctl, which I suspect is going to be fairly common. Also, because this failure occurs in odp_pktio_start() rather than odp_pktio_open(), it doesn't fall back to using the socket pktio. created pktio 1 (eth3) pktio/socket.c:218:get_rss_hash():get_rss_hash(): Operation not supported pktio/socket.c:218:get_rss_hash():get_rss_hash(): Operation not supported pktio/socket.c:218:get_rss_hash():get_rss_hash(): Operation not supported pktio/socket.c:218:get_rss_hash():get_rss_hash(): Operation not supported pktio/socket.c:218:get_rss_hash():get_rss_hash(): Operation not supported pktio/socket.c:218:get_rss_hash():get_rss_hash(): Operation not supported pktio/socket.c:281:set_rss_hash():set_rss_hash(): Operation not supported pktio/netmap.c:140:netmap_input_queues_config():Failed to configure input hash odp_l2fwd.c:447:create_pktio():Error: input queue config failed eth3 -- Stuart. _______________________________________________ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp