Implemented multi-queue API with dummy single queue support. Enables testing the API and provides stubbs for actual multi-queue implementations. Not optimized.
Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com> --- .../include/odp/plat/packet_io_types.h | 14 +- .../linux-generic/include/odp_packet_io_internal.h | 46 ++++ platform/linux-generic/odp_packet_io.c | 280 +++++++++++++++++++++ platform/linux-generic/pktio/loop.c | 10 +- platform/linux-generic/pktio/netmap.c | 10 +- platform/linux-generic/pktio/pcap.c | 10 +- platform/linux-generic/pktio/socket.c | 10 +- platform/linux-generic/pktio/socket_mmap.c | 10 +- 8 files changed, 382 insertions(+), 8 deletions(-) diff --git a/platform/linux-generic/include/odp/plat/packet_io_types.h b/platform/linux-generic/include/odp/plat/packet_io_types.h index 1086463..25f7151 100644 --- a/platform/linux-generic/include/odp/plat/packet_io_types.h +++ b/platform/linux-generic/include/odp/plat/packet_io_types.h @@ -21,16 +21,24 @@ extern "C" { #include <odp/std_types.h> #include <odp/plat/strong_types.h> -/** @addtogroup odp_packet_io ODP PACKET IO +/** @addtogroup odp_packet_io * Operations on a packet. * @{ */ typedef ODP_HANDLE_T(odp_pktio_t); -typedef ODP_HANDLE_T(odp_pktin_queue_t); +/** @internal */ +typedef struct odp_pktin_queue_t { + odp_pktio_t pktio; /**< @internal pktio handle */ + int index; /**< @internal pktio queue index */ +} odp_pktin_queue_t; -typedef ODP_HANDLE_T(odp_pktout_queue_t); +/** @internal */ +typedef struct odp_pktout_queue_t { + odp_pktio_t pktio; /**< @internal pktio handle */ + int index; /**< @internal pktio queue index */ +} odp_pktout_queue_t; #define ODP_PKTIO_INVALID _odp_cast_scalar(odp_pktio_t, 0) diff --git a/platform/linux-generic/include/odp_packet_io_internal.h b/platform/linux-generic/include/odp_packet_io_internal.h index a46c6fe..2b6d116 100644 --- a/platform/linux-generic/include/odp_packet_io_internal.h +++ b/platform/linux-generic/include/odp_packet_io_internal.h @@ -32,6 +32,8 @@ extern "C" { #define PKTIO_NAME_LEN 256 +#define PKTIO_MAX_QUEUES 64 + /** Determine if a socket read/write error should be reported. Transient errors * that simply require the caller to retry are ignored, the _send/_recv APIs * are non-blocking and it is the caller's responsibility to retry if the @@ -87,6 +89,17 @@ struct pktio_entry { char name[PKTIO_NAME_LEN]; /**< name of pktio provided to pktio_open() */ odp_pktio_param_t param; + + /* Storage for queue handles + * Multi-queue support is pktio driver specific */ + struct { + odp_queue_t queue; + odp_pktin_queue_t pktin; + } in_queue[PKTIO_MAX_QUEUES]; + + struct { + odp_pktout_queue_t pktout; + } out_queue[PKTIO_MAX_QUEUES]; }; typedef union { @@ -116,6 +129,21 @@ typedef struct pktio_if_ops { int (*promisc_mode_set)(pktio_entry_t *pktio_entry, int enable); int (*promisc_mode_get)(pktio_entry_t *pktio_entry); int (*mac_get)(pktio_entry_t *pktio_entry, void *mac_addr); + int (*capability)(pktio_entry_t *pktio_entry, + odp_pktio_capability_t *capa); + int (*input_queues_config)(pktio_entry_t *pktio_entry, + const odp_pktio_input_queue_param_t *param); + int (*output_queues_config)(pktio_entry_t *pktio_entry, + const odp_pktio_output_queue_param_t *p); + int (*in_queues)(pktio_entry_t *entry, odp_queue_t queues[], int num); + int (*pktin_queues)(pktio_entry_t *entry, odp_pktin_queue_t queues[], + int num); + int (*pktout_queues)(pktio_entry_t *entry, odp_pktout_queue_t queues[], + int num); + int (*recv_queue)(pktio_entry_t *entry, int index, + odp_packet_t packets[], int num); + int (*send_queue)(pktio_entry_t *entry, int index, + odp_packet_t packets[], int num); } pktio_if_ops_t; extern void *pktio_entry_ptr[]; @@ -151,6 +179,24 @@ static inline void pktio_cls_enabled_set(pktio_entry_t *entry, int ena) int pktin_poll(pktio_entry_t *entry); +/* + * Dummy single queue implementations of multi-queue API + */ +int single_capability(odp_pktio_capability_t *capa); +int single_input_queues_config(pktio_entry_t *entry, + const odp_pktio_input_queue_param_t *param); +int single_output_queues_config(pktio_entry_t *entry, + const odp_pktio_output_queue_param_t *param); +int single_in_queues(pktio_entry_t *entry, odp_queue_t queues[], int num); +int single_pktin_queues(pktio_entry_t *entry, odp_pktin_queue_t queues[], + int num); +int single_pktout_queues(pktio_entry_t *entry, odp_pktout_queue_t queues[], + int num); +int single_recv_queue(pktio_entry_t *entry, int index, odp_packet_t packets[], + int num); +int single_send_queue(pktio_entry_t *entry, int index, odp_packet_t packets[], + int num); + extern const pktio_if_ops_t netmap_pktio_ops; extern const pktio_if_ops_t sock_mmsg_pktio_ops; extern const pktio_if_ops_t sock_mmap_pktio_ops; diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c index 14fb0c5..b6b009d 100644 --- a/platform/linux-generic/odp_packet_io.c +++ b/platform/linux-generic/odp_packet_io.c @@ -817,6 +817,16 @@ void odp_pktio_param_init(odp_pktio_param_t *params) memset(params, 0, sizeof(odp_pktio_param_t)); } +void odp_pktio_input_queue_param_init(odp_pktio_input_queue_param_t *param) +{ + memset(param, 0, sizeof(odp_pktio_input_queue_param_t)); +} + +void odp_pktio_output_queue_param_init(odp_pktio_output_queue_param_t *param) +{ + memset(param, 0, sizeof(odp_pktio_output_queue_param_t)); +} + void odp_pktio_print(odp_pktio_t id) { pktio_entry_t *entry; @@ -905,3 +915,273 @@ int odp_pktio_term_global(void) return ret; } + +int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa) +{ + pktio_entry_t *entry; + + entry = get_pktio_entry(pktio); + if (entry == NULL) { + ODP_DBG("pktio entry %d does not exist\n", pktio); + return -1; + } + + if (entry->s.ops->capability) + return entry->s.ops->capability(entry, capa); + + return single_capability(capa); +} + +int odp_pktio_input_queues_config(odp_pktio_t pktio, + const odp_pktio_input_queue_param_t *param) +{ + pktio_entry_t *entry; + + if (param == NULL) + return -1; + + entry = get_pktio_entry(pktio); + if (entry == NULL) { + ODP_DBG("pktio entry %d does not exist\n", pktio); + return -1; + } + + if (entry->s.ops->input_queues_config) + return entry->s.ops->input_queues_config(entry, param); + + return single_input_queues_config(entry, param); +} + +int odp_pktio_output_queues_config(odp_pktio_t pktio, + const odp_pktio_output_queue_param_t *param) +{ + pktio_entry_t *entry; + odp_pktio_output_mode_t mode; + + if (param == NULL) + return -1; + + entry = get_pktio_entry(pktio); + if (entry == NULL) { + ODP_DBG("pktio entry %d does not exist\n", pktio); + return -1; + } + + mode = entry->s.param.out_mode; + + if (mode != ODP_PKTOUT_MODE_SEND) + return -1; + + if (entry->s.ops->output_queues_config) + return entry->s.ops->output_queues_config(entry, param); + + return single_output_queues_config(entry, param); +} + +int odp_pktio_in_queues(odp_pktio_t pktio, odp_queue_t queues[], int num) +{ + pktio_entry_t *entry; + odp_pktio_input_mode_t mode; + + entry = get_pktio_entry(pktio); + if (entry == NULL) { + ODP_DBG("pktio entry %d does not exist\n", pktio); + return -1; + } + + mode = entry->s.param.in_mode; + + if (mode != ODP_PKTIN_MODE_POLL && + mode != ODP_PKTIN_MODE_SCHED) + return -1; + + if (entry->s.ops->in_queues) + return entry->s.ops->in_queues(entry, queues, num); + + return single_in_queues(entry, queues, num); +} + +int odp_pktio_pktin_queues(odp_pktio_t pktio, odp_pktin_queue_t queues[], + int num) +{ + pktio_entry_t *entry; + odp_pktio_input_mode_t mode; + + entry = get_pktio_entry(pktio); + if (entry == NULL) { + ODP_DBG("pktio entry %d does not exist\n", pktio); + return -1; + } + + mode = entry->s.param.in_mode; + + if (mode != ODP_PKTIN_MODE_RECV) + return -1; + + if (entry->s.ops->pktin_queues) + return entry->s.ops->pktin_queues(entry, queues, num); + + return single_pktin_queues(entry, queues, num); +} + +int odp_pktio_pktout_queues(odp_pktio_t pktio, odp_pktout_queue_t queues[], + int num) +{ + pktio_entry_t *entry; + odp_pktio_output_mode_t mode; + + entry = get_pktio_entry(pktio); + if (entry == NULL) { + ODP_DBG("pktio entry %d does not exist\n", pktio); + return -1; + } + + mode = entry->s.param.out_mode; + + if (mode != ODP_PKTOUT_MODE_SEND) + return -1; + + if (entry->s.ops->pktout_queues) + return entry->s.ops->pktout_queues(entry, queues, num); + + return single_pktout_queues(entry, queues, num); +} + +int odp_pktio_recv_queue(odp_pktin_queue_t queue, odp_packet_t packets[], + int num) +{ + pktio_entry_t *entry; + odp_pktio_t pktio = queue.pktio; + + entry = get_pktio_entry(pktio); + if (entry == NULL) { + ODP_DBG("pktio entry %d does not exist\n", pktio); + return -1; + } + + if (entry->s.ops->recv_queue) + return entry->s.ops->recv_queue(entry, queue.index, + packets, num); + + return single_recv_queue(entry, queue.index, packets, num); +} + +int odp_pktio_send_queue(odp_pktout_queue_t queue, odp_packet_t packets[], + int num) +{ + pktio_entry_t *entry; + odp_pktio_t pktio = queue.pktio; + + entry = get_pktio_entry(pktio); + if (entry == NULL) { + ODP_DBG("pktio entry %d does not exist\n", pktio); + return -1; + } + + if (entry->s.ops->send_queue) + return entry->s.ops->send_queue(entry, queue.index, + packets, num); + + return single_send_queue(entry, queue.index, packets, num); +} + +int single_capability(odp_pktio_capability_t *capa) +{ + memset(capa, 0, sizeof(odp_pktio_capability_t)); + capa->max_input_queues = 1; + capa->max_output_queues = 1; + + return 0; +} + +int single_input_queues_config(pktio_entry_t *entry, + const odp_pktio_input_queue_param_t *param) +{ + odp_queue_t queue; + odp_pktio_input_mode_t mode; + + mode = entry->s.param.in_mode; + + if (param->num_queues != 1) + return -1; + + if (mode == ODP_PKTIN_MODE_DISABLED) + return -1; + + if (mode == ODP_PKTIN_MODE_POLL || + mode == ODP_PKTIN_MODE_SCHED) { + odp_queue_type_t type = ODP_QUEUE_TYPE_POLL; + + if (mode == ODP_PKTIN_MODE_SCHED) + type = ODP_QUEUE_TYPE_SCHED; + + /* cast needed since queue_param is not defined as const in + * in odp_queue_create() */ + queue = odp_queue_create("pktio_in", type, + (odp_queue_param_t *) + ¶m->queue_param); + + if (queue == ODP_QUEUE_INVALID) + return -1; + + entry->s.in_queue[0].queue = queue; + } else { + entry->s.in_queue[0].queue = ODP_QUEUE_INVALID; + entry->s.in_queue[0].pktin.pktio = entry->s.handle; + entry->s.in_queue[0].pktin.index = 0; + } + + return 0; +} + +int single_output_queues_config(pktio_entry_t *entry, + const odp_pktio_output_queue_param_t *param) +{ + if (param->num_queues != 1) + return -1; + + entry->s.out_queue[0].pktout.pktio = entry->s.handle; + entry->s.out_queue[0].pktout.index = 0; + + return 0; +} + +int single_in_queues(pktio_entry_t *entry, odp_queue_t queues[], int num) +{ + if (queues && num > 0) + queues[0] = entry->s.in_queue[0].queue; + + return 1; +} + +int single_pktin_queues(pktio_entry_t *entry, odp_pktin_queue_t queues[], + int num) +{ + if (queues && num > 0) + queues[0] = entry->s.in_queue[0].pktin; + + return 1; +} + +int single_pktout_queues(pktio_entry_t *entry, odp_pktout_queue_t queues[], + int num) +{ + if (queues && num > 0) + queues[0] = entry->s.out_queue[0].pktout; + + return 1; +} + +int single_recv_queue(pktio_entry_t *entry, int index, odp_packet_t packets[], + int num) +{ + (void)index; + return odp_pktio_recv(entry->s.handle, packets, num); +} + +int single_send_queue(pktio_entry_t *entry, int index, odp_packet_t packets[], + int num) +{ + (void)index; + return odp_pktio_send(entry->s.handle, packets, num); +} diff --git a/platform/linux-generic/pktio/loop.c b/platform/linux-generic/pktio/loop.c index 44da917..47a42ff 100644 --- a/platform/linux-generic/pktio/loop.c +++ b/platform/linux-generic/pktio/loop.c @@ -120,5 +120,13 @@ const pktio_if_ops_t loopback_pktio_ops = { .mtu_get = loopback_mtu_get, .promisc_mode_set = loopback_promisc_mode_set, .promisc_mode_get = loopback_promisc_mode_get, - .mac_get = loopback_mac_addr_get + .mac_get = loopback_mac_addr_get, + .capability = NULL, + .input_queues_config = NULL, + .output_queues_config = NULL, + .in_queues = NULL, + .pktin_queues = NULL, + .pktout_queues = NULL, + .recv_queue = NULL, + .send_queue = NULL }; diff --git a/platform/linux-generic/pktio/netmap.c b/platform/linux-generic/pktio/netmap.c index 20a144d..c4db4b5 100644 --- a/platform/linux-generic/pktio/netmap.c +++ b/platform/linux-generic/pktio/netmap.c @@ -347,7 +347,15 @@ const pktio_if_ops_t netmap_pktio_ops = { .mtu_get = netmap_mtu_get, .promisc_mode_set = netmap_promisc_mode_set, .promisc_mode_get = netmap_promisc_mode_get, - .mac_get = netmap_mac_addr_get + .mac_get = netmap_mac_addr_get, + .capability = NULL, + .input_queues_config = NULL, + .output_queues_config = NULL, + .in_queues = NULL, + .pktin_queues = NULL, + .pktout_queues = NULL, + .recv_queue = NULL, + .send_queue = NULL }; #endif /* ODP_NETMAP */ diff --git a/platform/linux-generic/pktio/pcap.c b/platform/linux-generic/pktio/pcap.c index 94b506d..d1ac1b0 100644 --- a/platform/linux-generic/pktio/pcap.c +++ b/platform/linux-generic/pktio/pcap.c @@ -378,5 +378,13 @@ const pktio_if_ops_t pcap_pktio_ops = { .mtu_get = pcapif_mtu_get, .promisc_mode_set = pcapif_promisc_mode_set, .promisc_mode_get = pcapif_promisc_mode_get, - .mac_get = pcapif_mac_addr_get + .mac_get = pcapif_mac_addr_get, + .capability = NULL, + .input_queues_config = NULL, + .output_queues_config = NULL, + .in_queues = NULL, + .pktin_queues = NULL, + .pktout_queues = NULL, + .recv_queue = NULL, + .send_queue = NULL }; diff --git a/platform/linux-generic/pktio/socket.c b/platform/linux-generic/pktio/socket.c index 56b0a8b..d9baca3 100644 --- a/platform/linux-generic/pktio/socket.c +++ b/platform/linux-generic/pktio/socket.c @@ -480,5 +480,13 @@ const pktio_if_ops_t sock_mmsg_pktio_ops = { .mtu_get = sock_mtu_get, .promisc_mode_set = sock_promisc_mode_set, .promisc_mode_get = sock_promisc_mode_get, - .mac_get = sock_mac_addr_get + .mac_get = sock_mac_addr_get, + .capability = NULL, + .input_queues_config = NULL, + .output_queues_config = NULL, + .in_queues = NULL, + .pktin_queues = NULL, + .pktout_queues = NULL, + .recv_queue = NULL, + .send_queue = NULL }; diff --git a/platform/linux-generic/pktio/socket_mmap.c b/platform/linux-generic/pktio/socket_mmap.c index 6bbe525..b2adfa6 100644 --- a/platform/linux-generic/pktio/socket_mmap.c +++ b/platform/linux-generic/pktio/socket_mmap.c @@ -554,5 +554,13 @@ const pktio_if_ops_t sock_mmap_pktio_ops = { .mtu_get = sock_mmap_mtu_get, .promisc_mode_set = sock_mmap_promisc_mode_set, .promisc_mode_get = sock_mmap_promisc_mode_get, - .mac_get = sock_mmap_mac_addr_get + .mac_get = sock_mmap_mac_addr_get, + .capability = NULL, + .input_queues_config = NULL, + .output_queues_config = NULL, + .in_queues = NULL, + .pktin_queues = NULL, + .pktout_queues = NULL, + .recv_queue = NULL, + .send_queue = NULL }; -- 2.6.2 _______________________________________________ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp