diff options
-rw-r--r-- | config/odp-linux-generic.conf | 9 | ||||
-rw-r--r-- | platform/linux-generic/include/odp_packet_netmap.h | 7 | ||||
-rw-r--r-- | platform/linux-generic/pktio/netmap.c | 63 |
3 files changed, 79 insertions, 0 deletions
diff --git a/config/odp-linux-generic.conf b/config/odp-linux-generic.conf index 0034c64ba..f5f21b45f 100644 --- a/config/odp-linux-generic.conf +++ b/config/odp-linux-generic.conf @@ -31,6 +31,15 @@ pktio_dpdk: { } } +# netmap pktio options +pktio_netmap: { + # Interface specific options + virt: { + nr_rx_slots = 0 + nr_tx_slots = 0 + } +} + queue_basic: { # Maximum queue size. Value must be a power of two. max_queue_size = 8192 diff --git a/platform/linux-generic/include/odp_packet_netmap.h b/platform/linux-generic/include/odp_packet_netmap.h index bb81f5f85..bd3efdcf5 100644 --- a/platform/linux-generic/include/odp_packet_netmap.h +++ b/platform/linux-generic/include/odp_packet_netmap.h @@ -19,6 +19,12 @@ #define NM_MAX_DESC 64 +/** netmap runtime configuration options */ +typedef struct { + int nr_rx_slots; + int nr_tx_slots; +} netmap_opt_t; + /** Ring for mapping pktin/pktout queues to netmap descriptors */ struct netmap_ring_t { unsigned first; /**< Index of first netmap descriptor */ @@ -61,6 +67,7 @@ typedef struct { netmap_ring_t rx_desc_ring[PKTIO_MAX_QUEUES]; /** mapping of pktout queues to netmap tx descriptors */ netmap_ring_t tx_desc_ring[PKTIO_MAX_QUEUES]; + netmap_opt_t opt; /**< options */ } pkt_netmap_t; #endif diff --git a/platform/linux-generic/pktio/netmap.c b/platform/linux-generic/pktio/netmap.c index 4276d4bc1..835d81ebb 100644 --- a/platform/linux-generic/pktio/netmap.c +++ b/platform/linux-generic/pktio/netmap.c @@ -27,6 +27,8 @@ #include <odp_classification_datamodel.h> #include <odp_classification_inlines.h> #include <odp_classification_internal.h> +#include <odp_libconfig_internal.h> + #include <inttypes.h> @@ -46,6 +48,49 @@ static int disable_pktio; /** !0 this pktio disabled, 0 enabled */ static int netmap_stats_reset(pktio_entry_t *pktio_entry); +static int lookup_opt(const char *opt_name, const char *drv_name, int *val) +{ + const char *base = "pktio_netmap"; + int ret; + + ret = _odp_libconfig_lookup_ext_int(base, drv_name, opt_name, val); + if (ret == 0) + ODP_ERR("Unable to find netmap configuration option: %s\n", + opt_name); + + return ret; +} + +static int init_options(pktio_entry_t *pktio_entry) +{ + netmap_opt_t *opt = &pktio_entry->s.pkt_nm.opt; + + if (!lookup_opt("nr_rx_slots", "virt", + &opt->nr_rx_slots)) + return -1; + if (opt->nr_rx_slots < 0 || + opt->nr_rx_slots > 4096) { + ODP_ERR("Invalid number of RX slots\n"); + return -1; + } + + if (!lookup_opt("nr_tx_slots", "virt", + &opt->nr_tx_slots)) + return -1; + if (opt->nr_tx_slots < 0 || + opt->nr_tx_slots > 4096) { + ODP_ERR("Invalid number of TX slots\n"); + return -1; + } + + ODP_PRINT("netmap interface: %s\n", + pktio_entry->s.pkt_nm.if_name); + ODP_PRINT(" num_rx_desc: %d\n", opt->nr_rx_slots); + ODP_PRINT(" num_tx_desc: %d\n", opt->nr_tx_slots); + + return 0; +} + static int netmap_do_ioctl(pktio_entry_t *pktio_entry, unsigned long cmd, int subcmd) { @@ -363,6 +408,12 @@ static int netmap_open(odp_pktio_t id ODP_UNUSED, pktio_entry_t *pktio_entry, netdev); snprintf(pkt_nm->if_name, sizeof(pkt_nm->if_name), "%s", netdev); + /* Initialize runtime options */ + if (init_options(pktio_entry)) { + ODP_ERR("Initializing runtime options failed\n"); + return -1; + } + /* Dummy open here to check if netmap module is available and to read * capability info. */ desc = nm_open(pkt_nm->nm_name, NULL, 0, NULL); @@ -526,6 +577,12 @@ static int netmap_start(pktio_entry_t *pktio_entry) base_desc.self = &base_desc; base_desc.mem = NULL; + if (pktio_entry->s.pkt_nm.is_virtual) { + base_desc.req.nr_rx_slots = + pktio_entry->s.pkt_nm.opt.nr_rx_slots; + base_desc.req.nr_tx_slots = + pktio_entry->s.pkt_nm.opt.nr_tx_slots; + } base_desc.req.nr_ringid = 0; if ((base_desc.req.nr_flags & NR_REG_MASK) == NR_REG_ALL_NIC || (base_desc.req.nr_flags & NR_REG_MASK) == NR_REG_ONE_NIC) { @@ -539,6 +596,8 @@ static int netmap_start(pktio_entry_t *pktio_entry) /* Only the first rx descriptor does mmap */ desc_ring = pkt_nm->rx_desc_ring; flags = NM_OPEN_IFNAME | NETMAP_NO_TX_POLL; + if (pktio_entry->s.pkt_nm.is_virtual) + flags |= NM_OPEN_RING_CFG; desc_ring[0].s.desc[0] = nm_open(pkt_nm->nm_name, NULL, flags, &base_desc); if (desc_ring[0].s.desc[0] == NULL) { @@ -547,6 +606,8 @@ static int netmap_start(pktio_entry_t *pktio_entry) } /* Open rest of the rx descriptors (one per netmap ring) */ flags = NM_OPEN_IFNAME | NETMAP_NO_TX_POLL | NM_OPEN_NO_MMAP; + if (pktio_entry->s.pkt_nm.is_virtual) + flags |= NM_OPEN_RING_CFG; for (i = 0; i < pktio_entry->s.num_in_queue; i++) { for (j = desc_ring[i].s.first; j <= desc_ring[i].s.last; j++) { if (i == 0 && j == 0) { /* First already opened */ @@ -568,6 +629,8 @@ static int netmap_start(pktio_entry_t *pktio_entry) /* Open tx descriptors */ desc_ring = pkt_nm->tx_desc_ring; flags = NM_OPEN_IFNAME | NM_OPEN_NO_MMAP; + if (pktio_entry->s.pkt_nm.is_virtual) + flags |= NM_OPEN_RING_CFG; if ((base_desc.req.nr_flags & NR_REG_MASK) == NR_REG_ALL_NIC) { base_desc.req.nr_flags &= ~NR_REG_ALL_NIC; |