On Friday 22 September 2017 02:47 AM, Nikhil Rao wrote:
> Add common APIs for configuring packet transfer from ethernet Rx
> queues to event devices across HW & SW packet transfer mechanisms.
> A detailed description of the adapter is contained in the header's
> comments.
>
> The adapter implementation uses eventdev PMDs to configure the packet
> transfer if HW support is available and if not, it uses an EAL service
> function that reads packets from ethernet Rx queues and injects these
> as events into the event device.
>
> Signed-off-by: Nikhil Rao <nikhil....@intel.com>
> Signed-off-by: Gage Eads <gage.e...@intel.com>
> Signed-off-by: Abhinandan Gujjar <abhinandan.guj...@intel.com>
> ---
>  lib/librte_eventdev/rte_event_eth_rx_adapter.h |  384 ++++++++
>  lib/librte_eventdev/rte_event_eth_rx_adapter.c | 1238 
> ++++++++++++++++++++++++
>  lib/Makefile                                   |    2 +-
>  lib/librte_eventdev/Makefile                   |    2 +
>  lib/librte_eventdev/rte_eventdev_version.map   |   11 +-
>  5 files changed, 1635 insertions(+), 2 deletions(-)
>  create mode 100644 lib/librte_eventdev/rte_event_eth_rx_adapter.h
>  create mode 100644 lib/librte_eventdev/rte_event_eth_rx_adapter.c
>
> diff --git a/lib/librte_eventdev/rte_event_eth_rx_adapter.h 
> b/lib/librte_eventdev/rte_event_eth_rx_adapter.h
> new file mode 100644
> index 000000000..c3849ec31
> --- /dev/null
> +++ b/lib/librte_eventdev/rte_event_eth_rx_adapter.h
> @@ -0,0 +1,384 @@
> +/*
> + *   Copyright(c) 2017 Intel Corporation. All rights reserved.
> + *   All rights reserved.
> + *
> + *   Redistribution and use in source and binary forms, with or without
> + *   modification, are permitted provided that the following conditions
> + *   are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyright
> + *       notice, this list of conditions and the following disclaimer in
> + *       the documentation and/or other materials provided with the
> + *       distribution.
> + *     * Neither the name of Intel Corporation nor the names of its
> + *       contributors may be used to endorse or promote products derived
> + *       from this software without specific prior written permission.
> + *
> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#ifndef _RTE_EVENT_ETH_RX_ADAPTER_
> +#define _RTE_EVENT_ETH_RX_ADAPTER_
> +
> +/**
> + * @file
> + *
> + * RTE Event Ethernet Rx Adapter
> + *
> + * An eventdev-based packet processing application enqueues/dequeues mbufs
> + * to/from the event device. The application uses the adapter APIs to 
> configure
> + * the packet flow between the ethernet devices and event devices. Depending 
> on
> + * on the capabilties of the eventdev PMD, the adapter may use a EAL service
> + * core function for packet transfer or use internal PMD functions to 
> configure
> + * the packet transfer between the ethernet device and the event device.
> + *
> + * The ethernet Rx event adapter's functions are:
> + *  - rte_event_eth_rx_adapter_create_ext()
> + *  - rte_event_eth_rx_adapter_create()/free()
> + *  - rte_event_eth_rx_adapter_queue_add()/del()
> + *  - rte_event_eth_rx_adapter_start()/stop()
> + *  - rte_event_eth_rx_adapter_stats_get()/reset()
> + *
> + * The applicaton creates an event to ethernet adapter using
> + * rte_event_eth_rx_adapter_create_ext() or rte_event_eth_rx_adapter_create()
> + * functions.
> + * The adapter needs to know which ethernet rx queues to poll for mbufs as 
> well
> + * as event device parameters such as the event queue identifier, event
> + * priority and scheduling type that the adapter should use when constructing
> + * events. The rte_event_eth_rx_adapter_queue_add() function is provided for
> + * this purpose.
> + * The servicing weight parameter in the rte_event_eth_rx_adapter_queue_conf
> + * is applicable when the Rx adapter uses a service core function and is
> + * intended to provide application control of the polling frequency of 
> ethernet
> + * device receive queues, for example, the application may want to poll 
> higher
> + * priority queues with a higher frequency but at the same time not starve
> + * lower priority queues completely. If this parameter is zero and the 
> receive
> + * interrupt is enabled when configuring the device, the receive queue is
> + * interrupt driven; else, the queue is assigned a servicing weight of one.
> + *
> + * If the adapter uses a rte_service function, then the application is also
> + * required to assign a core to the service function and control the service
> + * core using the rte_service APIs. The 
> rte_event_eth_rx_adapter_service_id_get
> + * function can be used to retrieve the service function ID of the adapter in
> + * this case.
> + *
> + * Note: Interrupt driven receive queues are currentely unimplemented.
> + */
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#include <stdint.h>
> +#include <rte_service.h>
> +
> +#include "rte_eventdev.h"
> +
> +#define RTE_MAX_EVENT_ETH_RX_ADAPTER_INSTANCE 32
> +
> +/* struct rte_event_eth_rx_adapter_queue_conf flags definitions */
> +#define RTE_EVENT_ETH_RX_ADAPTER_QUEUE_FLOW_ID_VALID 0x1
> +/**< This flag indicates the flow identifier is valid
> + * @see rte_event_eth_rx_adapter_queue_conf
> + */
> +
> +struct rte_event_eth_rx_adapter_conf {
> +     uint8_t event_port_id;
> +     /**< Event port identifier, the adapter enqueues mbuf events to this
> +      * port
> +      */
> +     uint32_t max_nb_rx;
> +     /**< The adapter can return early if it has processed at least
> +      * max_nb_rx mbufs. This isn't treated as a requirement; batching may
> +      * cause the adapter to process more than max_nb_rx mbufs
> +      */
> +};
> +
> +/**
> + * Function type used for adapter configuration callback. The callback is
> + * used to fill in members of the struct rte_event_eth_rx_adapter_conf, this
> + * callback is invoked when creating a SW service for packet transfer from
> + * ethdev queues to the event device. The SW service is created within the
> + * rte_event_eth_rx_adapter_queue_add() function if packet required.
> + *
> + * @param id
> + *  Adapter identifier.
> + *
> + * @param dev_id
> + *  Event device identifier.
> + *
> + * @conf
> + *  Structure that needs to be populated by this callback.
> + *
> + * @arg
> + *  Argument to the callback. This is the same as the conf_arg passed to the
> + *  rte_event_eth_rx_adapter_create_ext()
> + */
> +typedef int (*rx_adapter_conf_cb) (uint8_t id, uint8_t dev_id,
> +                     struct rte_event_eth_rx_adapter_conf *conf,
> +                     void *arg);
> +
> +/** Rx queue configuration structure */
> +struct rte_event_eth_rx_adapter_queue_conf {
> +     uint32_t rx_queue_flags;
> +      /**< Flags for handling received packets
> +       * @see RTE_EVENT_ETH_RX_ADAPTER_QUEUE_FLOW_ID_VALID
> +       */
> +     uint16_t servicing_weight;
> +     /**< Relative polling frequency of ethernet receive queue, if this
> +      * is set to zero, the Rx queue is interrupt driven (unless rx queue
> +      * interrupts are not enabled for the ethernet device)
> +      */
> +     struct rte_event ev;
> +     /**<
> +      *  The values from the following event fields will be used when
> +      *  enqueuing mbuf events:
> +      *   - event_queue_id: Targeted event queue ID for received packets.
> +      *   - event_priority: Event priority of packets from this Rx queue in
> +      *                     the event queue relative to other events.
> +      *   - sched_type: Scheduling type for packets from this Rx queue.
> +      *   - flow_id: If the RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID bit
> +      *              is set in rx_queue_flags, this flow_id is used for all
> +      *              packets received from this queue. Otherwise the flow ID
> +      *              is set to the RSS hash of the src and dst IPv4/6
> +      *              address.
> +      *
> +      * The event adapter sets ev.event_type to RTE_EVENT_TYPE_ETHDEV in the
> +      * enqueued event
> +      */
> +};
> +
> +struct rte_event_eth_rx_adapter_stats {
> +     uint64_t rx_poll_count;
> +     /**< Receive queue poll count */
> +     uint64_t rx_packets;
> +     /**< Received packet count */
> +     uint64_t rx_enq_count;
> +     /**< Eventdev enqueue count */
> +     uint64_t rx_enq_retry;
> +     /**< Eventdev enqueue retry count */
> +     uint64_t rx_enq_start_ts;
> +     /**< Rx enqueue start timestamp */
> +     uint64_t rx_enq_block_cycles;
> +     /**< Cycles for which the service is blocked by the event device,
> +      * i.e, the service fails to enqueue to the event device.
> +      */
> +     uint64_t rx_enq_end_ts;
> +     /**< Latest timestamp at which the service is unblocked
> +      * by the event device. The start, end timestamps and
> +      * block cycles can be used to compute the percentage of
> +      * cycles the service is blocked by the event device.
> +      */
> +};
> +
> +/**
> + * Create a new ethernet Rx event adapter with the specified identifier.
> + *
> + * @param id
> + *  The identifier of the ethernet Rx event adapter.
> + *
> + * @dev_id
> + *  The identifier of the device to configure.
> + *
> + * @eth_port_id
> + *  The identifier of the ethernet device.
> + *
> + * @param conf_cb
> + *  Callback function that fills in members of a
> + *  struct rte_event_eth_rx_adapter_conf struct passed into
> + *  it.
> + *
> + * @param conf_arg
> + *  Argument that is passed to the conf_cb function.
> + *
> + * @return
> + *   - 0: Success
> + *   - <0: Error code on failure
> + */
> +int rte_event_eth_rx_adapter_create_ext(uint8_t id, uint8_t dev_id,
> +                                     rx_adapter_conf_cb conf_cb,
> +                                     void *conf_arg);
> +
> +/**
> + * Create a new ethernet Rx event adapter with the specified identifier.
> + * This function uses an internal configuration function that creates an 
> event
> + * port. This default function reconfigures the event device with an
> + * additional event port and setups up the event port using the port_config
> + * parameter passed into this function. In case the application needs more
> + * control in configuration of the service, it should use the
> + * rte_event_eth_rx_adapter_create_ext() version.
> + *
> + * @param id
> + *  The identifier of the ethernet Rx event adapter.
> + *
> + * @dev_id
> + *  The identifier of the device to configure.
> + *
> + * @eth_port_id
> + *  The identifier of the ethernet device.
> + *
> + * @param conf_cb
> + *  Callback function that fills in members of a
> + *  struct rte_event_eth_rx_adapter_conf struct passed into
> + *  it.
> + *
> + * @param conf_arg
> + *  Argument of type *rte_event_port_conf* that is passed to the conf_cb
> + *  function.
> + *
> + * @return
> + *   - 0: Success
> + *   - <0: Error code on failure
> + */
> +int rte_event_eth_rx_adapter_create(uint8_t id, uint8_t dev_id,
> +                             struct rte_event_port_conf *port_config);
> +
> +/**
> + * Free an event adapter
> + *
> + * @param id
> + *  Adapter identifier.
> + *
> + * @return
> + *   - 0: Success
> + *   - <0: Error code on failure, If the adapter still has Rx queues
> + *      added to it, the function returns -EBUSY.
> + */
> +int rte_event_eth_rx_adapter_free(uint8_t id);
> +
> +/**
> + * Add receive queue to an event adapter. After a queue has been
> + * added to the event adapter, the result of the application calling
> + * rte_eth_rx_burst(eth_dev_id, rx_queue_id, ..) is undefined.
> + *
> + * @param id
> + *  Adapter identifier.
> + *
> + * @param eth_dev_id
> + *  Port identifier of Ethernet device.
> + *
> + * @param rx_queue_id
> + *  Ethernet device receive queue index.
> + *  If rx_queue_id is -1, then all Rx queues configured for
> + *  the device are added. If the ethdev Rx queues can only be
> + *  connected to a single event queue then rx_queue_id is
> + *  required to be -1.
> + *
> + * @param conf
> + *  Additonal configuration structure of type *rte_event_eth_rx_adapte_conf*
> + *
> + * @see
> + * @return
> + *  - 0: Success, Receive queue added correctly.
> + *  - <0: Error code on failure.
> + */
> +int rte_event_eth_rx_adapter_queue_add(uint8_t id,
> +                     uint8_t eth_dev_id,
> +                     int32_t rx_queue_id,
> +                     const struct rte_event_eth_rx_adapter_queue_conf *conf);
> +
> +/**
> + * Delete receive queue from an event adapter.
> + *
> + * @param id
> + *  Adapter identifier.
> + *
> + * @param eth_dev_id
> + *  Port identifier of Ethernet device.
> + *
> + * @param rx_queue_id
> + *  Ethernet device receive queue index.
> + *  If rx_queue_id is -1, then all Rx queues configured for
> + *  the device are deleted. If the ethdev Rx queues can only be
> + *  connected to a single event queue then rx_queue_id is
> + *  required to be -1.
> + *
> + * @return
> + *  - 0: Success, Receive queue deleted correctly.
> + *  - <0: Error code on failure.
> + */
> +int rte_event_eth_rx_adapter_queue_del(uint8_t id, uint8_t eth_dev_id,
> +                                    int32_t rx_queue_id);
> +
> +/**
> + * Start  ethernet Rx event adapter
> + *
> + * @param id
> + *  Adapter identifier.
> + *
> + * @return
> + *  - 0: Success, Adapter started correctly.
> + *  - <0: Error code on failure.
> + */
> +int rte_event_eth_rx_adapter_start(uint8_t id);
> +
> +/**
> + * Stop  ethernet Rx event adapter
> + *
> + * @param id
> + *  Adapter identifier.
> + *
> + * @return
> + *  - 0: Success, Adapter started correctly.
> + *  - <0: Error code on failure.
> + */
> +int rte_event_eth_rx_adapter_stop(uint8_t id);
> +
> +/**
> + * Retrieve statistics for an adapter
> + *
> + * @param id
> + *  Adapter identifier.
> + *
> + * @param stats
> + *  A pointer to structure used to retrieve statistics for an adapter.
> + *
> + * @return
> + *  - 0: Success, retrieved successfully.
> + *  - <0: Error code on failure.
> + */
> +int rte_event_eth_rx_adapter_stats_get(uint8_t id,
> +                             struct rte_event_eth_rx_adapter_stats *stats);
> +
> +/**
> + * Reset statistics for an adapter
> + *
> + * @param id
> + *  Adapter identifier.
> + *
> + * @return
> + *  - 0: Success, statistics reset successfully.
> + *  - <0: Error code on failure.
> + */
> +int rte_event_eth_rx_adapter_stats_reset(uint8_t id);
> +
> +/**
> + * Retrieve the service ID of an adapter. If the adapter doesn't use
> + * a rte_service function, this function returns -ESRCH
> + *
> + * @param id
> + *  Adapter identifier.
> + *
> + * @return
> + *  - 0: Success, statistics reset successfully.
> + *  - <0: Error code on failure, if the adapter doesn't use a rte_service
> + * function, this function returns -ESRCH.
> + */
> +int rte_event_eth_rx_adapter_service_id_get(uint8_t id, uint32_t 
> *service_id);
> +

In general api comment: Fix missing param definition like *service_id* above
and pl. remove other unnecessary params description from api above.

> +#ifdef __cplusplus
> +}
> +#endif
> +#endif       /* _RTE_EVENT_ETH_RX_ADAPTER_ */
> diff --git a/lib/librte_eventdev/rte_event_eth_rx_adapter.c 
> b/lib/librte_eventdev/rte_event_eth_rx_adapter.c
> new file mode 100644
> index 000000000..d5b655dae
> --- /dev/null
> +++ b/lib/librte_eventdev/rte_event_eth_rx_adapter.c
> @@ -0,0 +1,1238 @@
> +#include <rte_cycles.h>
> +#include <rte_common.h>
> +#include <rte_dev.h>
> +#include <rte_errno.h>
> +#include <rte_ethdev.h>
> +#include <rte_log.h>
> +#include <rte_malloc.h>
> +#include <rte_service_component.h>
> +#include <rte_thash.h>
> +
> +#include "rte_eventdev.h"
> +#include "rte_eventdev_pmd.h"
> +#include "rte_event_eth_rx_adapter.h"
> +
> +#define BATCH_SIZE           32
> +#define BLOCK_CNT_THRESHOLD  10
> +#define ETH_EVENT_BUFFER_SIZE        (4*BATCH_SIZE)
> +
> +#define ETH_RX_ADAPTER_SERVICE_NAME_LEN      32
> +#define ETH_RX_ADAPTER_MEM_NAME_LEN  32
> +
> +/*
> + * There is an instance of this struct per polled Rx queue added to the
> + * adapter
> + */
> +struct eth_rx_poll_entry {
> +     /* eth port to poll */
> +     uint8_t eth_dev_id;
> +     /* eth rx queue to poll */
> +     uint16_t eth_rx_qid;
> +};
> +
> +/* Instance per adapter */
> +struct rte_eth_event_enqueue_buffer {
> +     /* Count of events in this buffer */
> +     uint16_t count;
> +     /* Array of events in this buffer */
> +     struct rte_event events[ETH_EVENT_BUFFER_SIZE];
> +};
> +
> +struct rte_event_eth_rx_adapter {
> +     /* event device identifier */
> +     uint8_t eventdev_id;
> +     /* per ethernet device structure */
> +     struct eth_device_info *eth_devices;
> +     /* malloc name */
> +     char mem_name[ETH_RX_ADAPTER_MEM_NAME_LEN];
> +     /* socket identifier cached from eventdev */
> +     int socket_id;
> +
> +     /* elements below are used by SW service */
> +
> +     /* event port identifier */
> +     uint8_t event_port_id;
> +     /* per adapter EAL service */
> +     uint32_t service_id;
> +     /* lock to serialize config updates with service function */
> +     rte_spinlock_t rx_lock;
> +     /* max mbufs processed in any service function invocation */
> +     uint32_t max_nb_rx;
> +     /* Receive queues that need to be polled */
> +     struct eth_rx_poll_entry *eth_rx_poll;
> +     /* size of the eth_rx_poll array */
> +     uint16_t num_rx_polled;
> +     /* Weighted round robin schedule */
> +     uint32_t *wrr_sched;
> +     /* wrr_sched[] size */
> +     uint32_t wrr_len;
> +     /* Next entry in wrr[] to begin polling */
> +     uint32_t wrr_pos;
> +     /* Event burst buffer */
> +     struct rte_eth_event_enqueue_buffer event_enqueue_buffer;
> +     /* per adapter stats */
> +     struct rte_event_eth_rx_adapter_stats stats;
> +     /* Block count, counts upto BLOCK_CNT_THRESHOLD */
> +     uint16_t enq_block_count;
> +     /* Block start ts */
> +     uint64_t rx_enq_block_start_ts;
> +     /* Configuration callback for rte_service configuration */
> +     rx_adapter_conf_cb conf_cb;
> +     /* Configuration callback argument */
> +     void *conf_arg;
> +     /* Service initialization state */
> +     uint8_t service_inited;
> +     /* Total count of Rx queues in adapter */
> +     uint32_t nb_queues;
> +} __rte_cache_aligned;
> +
> +/* Per eth device */
> +struct eth_device_info {
> +     struct rte_eth_dev *dev;
> +     struct eth_rx_queue_info *rx_queue;
> +     /* Set if ethdev->eventdev packet transfer uses a
> +      * hardware mechanism
> +      */
> +     uint8_t internal_event_port;
> +     /* set if the adapter is processing rx queues for
> +      * this eth device and packet processing has been
> +      * started, allows for the code to know if the PMD
> +      * rx_adapter_stop callback needs to be invoked
> +      */
> +     uint8_t dev_rx_started;
> +     /* if nb_dev_queues > 0, the start callback will
> +      * be invoked if not already invoked
> +      */
> +     uint16_t nb_dev_queues;
> +};
> +
> +/* Per Rx queue */
> +struct eth_rx_queue_info {
> +     int queue_enabled;      /* true if added */
> +     uint16_t wt;            /* polling weight */
> +     uint8_t event_queue_id; /* Event queue to enqueue packets to */
> +     uint8_t sched_type;     /* sched type for events */
> +     uint8_t priority;       /* event priority */
> +     uint32_t flow_id;       /* app provided flow identifier */
> +     uint32_t flow_id_mask;  /* Set to ~0 if app provides flow id else 0 */
> +};
> +
> +static struct rte_event_eth_rx_adapter **rte_event_eth_rx_adapter;
> +static struct rte_event_port_conf
> +             create_port_conf[RTE_MAX_EVENT_ETH_RX_ADAPTER_INSTANCE];
> +
> +static uint8_t default_rss_key[] = {
> +     0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2,
> +     0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0,
> +     0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4,
> +     0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c,
> +     0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa,
> +};
> +static uint8_t *rss_key_be;
> +
> +static inline int
> +valid_id(uint8_t id)
> +{
> +     return id < RTE_MAX_EVENT_ETH_RX_ADAPTER_INSTANCE;
> +}
> +
> +#define RTE_EVENT_ETH_RX_ADAPTER_ID_VALID_OR_ERR_RET(id, retval) do { \
> +     if (!valid_id(id)) { \
> +             RTE_EDEV_LOG_ERR("Invalid eth Rx adapter id = %d\n", id); \
> +             return retval; \
> +     } \
> +} while (0)
> +

Worth, moving this macro to rte_eventdev_pmd.h
Or How about reusing existing one ie.. RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET?

> +static inline int
> +sw_rx_adapter_queue_count(struct rte_event_eth_rx_adapter *rx_adapter)
> +{
> +     return rx_adapter->num_rx_polled;
> +}
> +
> +/* Greatest common divisor */
> +static uint16_t gcd_u16(uint16_t a, uint16_t b)
> +{
> +     uint16_t r = a % b;
> +
> +     return r ? gcd_u16(b, r) : b;
> +}
> +
> +/* Returns the next queue in the polling sequence
> + *
> + * http://kb.linuxvirtualserver.org/wiki/Weighted_Round-Robin_Scheduling
> + */
> +static int
> +wrr_next(struct rte_event_eth_rx_adapter *rx_adapter,
> +      unsigned int n, int *cw,
> +      struct eth_rx_poll_entry *eth_rx_poll, uint16_t max_wt,
> +      uint16_t gcd, int prev)
> +{
> +     int i = prev;
> +     uint16_t w;
> +
> +     while (1) {
> +             uint16_t q;
> +             uint8_t d;
> +
> +             i = (i + 1) % n;
> +             if (i == 0) {
> +                     *cw = *cw - gcd;
> +                     if (*cw <= 0)
> +                             *cw = max_wt;
> +             }
> +
> +             q = eth_rx_poll[i].eth_rx_qid;
> +             d = eth_rx_poll[i].eth_dev_id;
> +             w = rx_adapter->eth_devices[d].rx_queue[q].wt;
> +
> +             if ((int)w >= *cw)
> +                     return i;
> +     }
> +}
> +
> +/* Precalculate WRR polling sequence for all queues in rx_adapter */
> +static int
> +eth_poll_wrr_calc(struct rte_event_eth_rx_adapter *rx_adapter)
> +{
> +     uint8_t d;
> +     uint16_t q;
> +     unsigned int i;
> +
> +     /* Initialize variables for calculaton of wrr schedule */
> +     uint16_t max_wrr_pos = 0;
> +     unsigned int poll_q = 0;
> +     uint16_t max_wt = 0;
> +     uint16_t gcd = 0;
> +
> +     struct eth_rx_poll_entry *rx_poll = NULL;
> +     uint32_t *rx_wrr = NULL;
> +
> +     if (rx_adapter->num_rx_polled) {
> +             size_t len = RTE_ALIGN(rx_adapter->num_rx_polled *
> +                             sizeof(*rx_adapter->eth_rx_poll),
> +                             RTE_CACHE_LINE_SIZE);
> +             rx_poll = rte_zmalloc_socket(rx_adapter->mem_name,
> +                                          len,
> +                                          RTE_CACHE_LINE_SIZE,
> +                                          rx_adapter->socket_id);
> +             if (!rx_poll)
> +                     return -ENOMEM;
> +
> +             /* Generate array of all queues to poll, the size of this
> +              * array is poll_q
> +              */
> +             for (d = 0; d < rte_eth_dev_count(); d++) {
> +                     uint16_t nb_rx_queues;
> +                     struct eth_device_info *dev_info =
> +                                     &rx_adapter->eth_devices[d];
> +                     nb_rx_queues = dev_info->dev->data->nb_rx_queues;
> +                     if (!dev_info->rx_queue)
> +                             continue;
> +                     for (q = 0; q < nb_rx_queues; q++) {
> +                             struct eth_rx_queue_info *queue_info =
> +                                     &dev_info->rx_queue[q];
> +                             if (!queue_info->queue_enabled)
> +                                     continue;
> +
> +                             uint16_t wt = queue_info->wt;
> +                             rx_poll[poll_q].eth_dev_id = d;
> +                             rx_poll[poll_q].eth_rx_qid = q;
> +                             max_wrr_pos += wt;
> +                             max_wt = RTE_MAX(max_wt, wt);
> +                             gcd = (gcd) ? gcd_u16(gcd, wt) : wt;
> +                             poll_q++;
> +                     }
> +             }
> +
> +             len = RTE_ALIGN(max_wrr_pos * sizeof(*rx_wrr),
> +                             RTE_CACHE_LINE_SIZE);
> +             rx_wrr = rte_zmalloc_socket(rx_adapter->mem_name,
> +                                         len,
> +                                         RTE_CACHE_LINE_SIZE,
> +                                         rx_adapter->socket_id);
> +             if (!rx_wrr) {
> +                     rte_free(rx_poll);
> +                     return -ENOMEM;
> +             }
> +
> +             /* Generate polling sequence based on weights */
> +             int prev = -1;
> +             int cw = -1;
> +             for (i = 0; i < max_wrr_pos; i++) {
> +                     rx_wrr[i] = wrr_next(rx_adapter, poll_q, &cw,
> +                                          rx_poll, max_wt, gcd, prev);
> +                     prev = rx_wrr[i];
> +             }
> +     }
> +
> +     rte_free(rx_adapter->eth_rx_poll);
> +     rte_free(rx_adapter->wrr_sched);
> +
> +     rx_adapter->eth_rx_poll = rx_poll;
> +     rx_adapter->wrr_sched = rx_wrr;
> +     rx_adapter->wrr_len = max_wrr_pos;
> +
> +     return 0;
> +}
> +
> +static inline void
> +mtoip(struct rte_mbuf *m, struct ipv4_hdr **ipv4_hdr,
> +     struct ipv6_hdr **ipv6_hdr)
> +{

mtoip(), imo is more of global api, likely other modules may use in future..
perhaps move to rte_io.h Or more correct place.. thought?

Thanks.

Reply via email to