All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] eventdev: add event adapter for ethernet Rx queues
@ 2017-05-09 20:38 Gage Eads
  2017-05-11 16:38 ` Jerin Jacob
  0 siblings, 1 reply; 41+ messages in thread
From: Gage Eads @ 2017-05-09 20:38 UTC (permalink / raw)
  To: dev
  Cc: nikhil.rao, jerin.jacob, thomas, bruce.richardson,
	harry.van.haaren, hemant.agrawal, nipun.gupta, narender.vangati

From: Nikhil Rao <nikhil.rao@intel.com>

Eventdev-based networking applications require a component to dequeue
packets from NIC Rx queues and inject them into eventdev queues[1]. While
some platforms (e.g. Cavium Octeontx) do this operation in hardware, other
platforms use software.

This RFC introduces an ethernet Rx event adapter and a proposed header
file. This adapter service dequeues packets from ethernet devices and
enqueues them to event devices.

The adapter is designed to work with the EAL service core proposal[2]. If
an application determines that the adapter is required, it can register and
launch it on a service core. Alternatively, this adapter can serve as a
template for applications to design customer ethernet Rx event adapters
better suited to their needs.

The adapter can service multiple ethernet devices and queues. Each queue is
configured with a servicing weight to control the relative frequency with
which the adapter polls the queue, and the event fields to use when
constructing packet events. The adapter has two modes for programming an
event's flow ID: use a static per-queue user-specified value or use the RSS
hash.

A detailed description of the adapter is contained in the header's
comments.

[1] http://dpdk.org/ml/archives/dev/2017-May/065341.html
[2] http://dpdk.org/ml/archives/dev/2017-May/065207.html

Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
Signed-off-by: Gage Eads <gage.eads@intel.com>
---
 lib/librte_eventdev/rte_eth_rx_event_adapter.h | 285 +++++++++++++++++++++++++
 lib/librte_eventdev/rte_eventdev_version.map   |  14 ++
 2 files changed, 299 insertions(+)
 create mode 100644 lib/librte_eventdev/rte_eth_rx_event_adapter.h

diff --git a/lib/librte_eventdev/rte_eth_rx_event_adapter.h b/lib/librte_eventdev/rte_eth_rx_event_adapter.h
new file mode 100644
index 0000000..b54927d
--- /dev/null
+++ b/lib/librte_eventdev/rte_eth_rx_event_adapter.h
@@ -0,0 +1,285 @@
+/*
+ *   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_ETH_RX_EVENT_ADAPTER_
+#define _RTE_ETH_RX_EVENT_ADAPTER_
+
+/**
+ * @file
+ *
+ * RTE Ethernet Rx Adapter for Eventdev
+ *
+ * An eventdev-based packet processing application enqueues/dequeues mbufs
+ * to/from the event device. The ethernet Rx event adapter's role is to transfer
+ * mbufs from the ethernet receive queues managed by DPDK to an event device.
+ * The application uses the adapter APIs to configure the packet flow between
+ * the ethernet devices and event devices. The adapter is designed to work with
+ * the EAL service cores. The adapter's work can be parallelized by dividing the
+ * NIC Rx queues among multiple adapter services that run in parallel.
+ *
+ * Before using the adapter, the application needs to enumerate and configure
+ * the ethernet devices that it wishes to use. This is typically done using the
+ * following DPDK ethdev functions:
+ *  - rte_eth_dev_configure()
+ *  - rte_eth_tx_queue_setup()
+ *  - rte_eth_rx_queue_setup()
+ *  - rte_eth_dev_start()
+ *
+ * The application also configures an event device and creates event ports
+ * to interface with the event device. In addition to the event ports used by
+ * its packet processing functions, the application creates an event port
+ * to be used by this adapter.
+ *
+ * The ethernet Rx event adapter's functions are:
+ *  - rte_eth_rx_event_adapter_create()
+ *  - rte_eth_rx_event_adapter_free()
+ *  - rte_eth_rx_event_adapter_dev_add()
+ *  - rte_eth_rx_event_adapter_dev_del()
+ *  - rte_eth_rx_event_adapter_queue_add()
+ *  - rte_eth_rx_event_adapter_run()
+ *  - rte_eth_rx_event_adapter_stats_get()
+ *  - rte_eth_rx_event_adapter_stats_reset()
+ *
+ * The applicaton creates an event to ethernet adapter using
+ * rte_eth_rx_event_adapter_create(). The event device and event port
+ * identifiers are passed to this function. Next, the application adds ethernet
+ * devices to this adapter using rte_eth_rx_event_adapter_dev_add().
+ *
+ * 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_eth_rx_event_adapter_queue_add() function is provided for
+ * this purpose.
+ *
+ * At the time of adding an ethernet device receive queue, the application can
+ * also specify a static event flow id and set the
+ * RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID bit of the rx_queue_flags
+ * member of the rte_eth_rx_event_adapter_queue_config structure. If the
+ * RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID isn't set, the flow id is
+ * assigned the value of the RSS hash. The adapter generates the RSS hash if it
+ * hasn't been already computed by the NIC, based on source and destination
+ * IPv4/6 addresses, using the rte_softrss_be() routine included in the DPDK.
+ *
+ * The servicing weight parameter in the rte_eth_rx_event_adapter_queue_config
+ * 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.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <rte_mbuf.h>
+#include <rte_eventdev.h>
+
+/* struct rte_eth_rx_event_adapter_queue_config flags definitions */
+#define RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID	0x1
+/*< This flag indicates the flow identifier is valid */
+
+struct rte_eth_rx_event_adapter_config {
+	uint8_t event_dev_id;
+	/**< Event device identifier */
+	uint8_t rx_event_port_id;
+	/**< Event port identifier, the adapter enqueues mbuf events to this
+	 * port
+	 */
+};
+
+struct rte_eth_rx_event_adapter_queue_config {
+	uint32_t rx_queue_flags;
+	 /**< Flags for handling received packets */
+	uint16_t servicing_weight;
+	/**< Relative polling frequency of ethernet receive queue, if this
+	 * is set to zero, the Rx queue is interrupt driven
+	 */
+	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.
+	 */
+};
+
+struct rte_eth_rx_event_adapter_run_args {
+	uint8_t id;
+	/**< Adapter identifier */
+	unsigned int 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.
+	 */
+};
+
+struct rte_eth_rx_event_adapter_stats {
+	uint64_t rx_poll_count;
+	/**< Receive queue poll count across both polled and interrupt mode
+	 * queues
+	 */
+	uint64_t rx_packets;
+	/**< Received packet count */
+	uint64_t rx_enq_fail;
+	/**< Eventdev enqueue failed count */
+	uint64_t rx_enq_retry;
+	/**< Eventdev enqueue retry count */
+};
+
+/**
+ * Create a new ethernet Rx event adapter with the specified identifier.
+ *
+ * @param adapter_id
+ *   Event adapter identifier.
+ * @param config
+ *   Event adapter config parameters.
+ * @return
+ *   - 0: Success
+ *   - <0: Error code on failure
+ */
+int rte_eth_rx_event_adapter_create(
+	uint8_t id,
+	const struct rte_eth_rx_event_adapter_config *config);
+
+/**
+ * Free an event adapter
+ *
+ * @param id
+ *   Adapter identifier.
+ * @return
+ *   - 0: Success
+ *   - <0: Error code on failure
+ */
+int rte_eth_rx_event_adapter_free(uint8_t id);
+
+/**
+ * Add eth device to the event adapter
+ *
+ * @param id
+ *   Adapter identifier.
+ * @param eth_dev_id
+ *  Port identifier of the Ethernet device.
+ * @return
+ *   - 0: Success
+ *   - <0: Error code on failure
+ */
+int rte_eth_rx_event_adapter_dev_add(uint8_t id, uint8_t eth_dev_id);
+
+/**
+ * Delete eth device from an event adapter
+ *
+ * @param id
+ *   Adapter identifier.
+ * @param eth_dev_id
+ *  Port identifier of the Ethernet device.
+ * @return
+ *   - 0: Success
+ *   - <0: Error code on failure
+ */
+int rte_eth_rx_event_adapter_dev_del(uint8_t id, uint8_t eth_dev_id);
+
+/**
+ * Add receive queue to event adapter
+ *
+ * @param id
+ *   Adapter identifier.
+ * @param eth_dev_id
+ *  Port identifier of Ethernet device.
+ * @param rx_queue_id
+ *  Ethernet device receive queue index.
+ * @param config
+ *  Additonal configuration structure.
+ * @return
+ *  - 0: Success, Receive queue added correctly.
+ *  - <0: Error code on failure.
+ */
+int rte_eth_event_rx_queue_add(
+	uint8_t id,
+	uint8_t eth_dev_id,
+	uint16_t rx_queue_id,
+	const struct rte_eth_rx_event_adapter_queue_config *config);
+
+/**
+ * Service core run function. The receive function dequeues mbufs from the
+ * ethernet device receive queues associated with the adapter and enqueues
+ * mbuf events to the adapter's receive event port.
+ *
+ * @param args
+ *  A pointer to a struct rte_eth_rx_event_adapter_run_args. This is a void*
+ *  to match the service core run function prototype.
+ * @return
+ *  - 0: Success.
+ *  - <0: Error code on failure.
+ */
+int rte_eth_rx_event_adapter_run(void *args);
+
+
+/**
+ * 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_eth_rx_event_adapter_stats_get(uint8_t id,
+			       struct rte_eth_rx_event_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_eth_rx_event_adapter_stats_reset(uint8_t id);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_ETH_RX_EVENT_ADAPTER_ */
diff --git a/lib/librte_eventdev/rte_eventdev_version.map b/lib/librte_eventdev/rte_eventdev_version.map
index 1fa6b33..8dfc611 100644
--- a/lib/librte_eventdev/rte_eventdev_version.map
+++ b/lib/librte_eventdev/rte_eventdev_version.map
@@ -42,3 +42,17 @@ DPDK_17.05 {
 
 	local: *;
 };
+
+DPDK_17.08 {
+	global:
+
+	rte_eth_rx_event_adapter_create;
+	rte_eth_rx_event_adapter_free;
+	rte_eth_rx_event_adapter_dev_add;
+	rte_eth_rx_event_adapter_dev_del;
+	rte_eth_rx_event_adapter_queue_add;
+	rte_eth_rx_event_adapter_run;
+	rte_eth_rx_event_adapter_stats_get;
+	rte_eth_rx_event_adapter_stats_reset;
+
+} DPDK_17.05;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [RFC] eventdev: add event adapter for ethernet Rx queues
  2017-05-09 20:38 [RFC] eventdev: add event adapter for ethernet Rx queues Gage Eads
@ 2017-05-11 16:38 ` Jerin Jacob
  2017-05-16 20:51   ` Thomas Monjalon
  2017-05-24  4:30   ` Rao, Nikhil
  0 siblings, 2 replies; 41+ messages in thread
From: Jerin Jacob @ 2017-05-11 16:38 UTC (permalink / raw)
  To: Gage Eads
  Cc: dev, nikhil.rao, thomas, bruce.richardson, harry.van.haaren,
	hemant.agrawal, nipun.gupta, narender.vangati

-----Original Message-----
> Date: Tue, 9 May 2017 15:38:46 -0500
> From: Gage Eads <gage.eads@intel.com>
> To: dev@dpdk.org
> CC: nikhil.rao@intel.com, jerin.jacob@caviumnetworks.com,
>  thomas@monjalon.net, bruce.richardson@intel.com,
>  harry.van.haaren@intel.com, hemant.agrawal@nxp.com, nipun.gupta@nxp.com,
>  narender.vangati@intel.com
> Subject: [RFC] eventdev: add event adapter for ethernet Rx queues
> X-Mailer: git-send-email 2.7.4
> 
> From: Nikhil Rao <nikhil.rao@intel.com>

Hi Nikhil and Gage,

Thanks for the RFC. A few questions and comments below.
Looks like SW has more constraints on event producer side, after we
finalize on this RFC(I guess only a few minor changes are only required).
I will align other[1] RFC based on _your_ RFC as we need to
converge on name space and we can't duplicate configs like struct
rte_event_dev_producer_conf etc

[1]
http://dpdk.org/ml/archives/dev/2017-May/065341.html

> 
> Eventdev-based networking applications require a component to dequeue
> packets from NIC Rx queues and inject them into eventdev queues[1]. While
> some platforms (e.g. Cavium Octeontx) do this operation in hardware, other
> platforms use software.
> 
> This RFC introduces an ethernet Rx event adapter and a proposed header
> file. This adapter service dequeues packets from ethernet devices and
> enqueues them to event devices.
> 
> The adapter is designed to work with the EAL service core proposal[2]. If
> an application determines that the adapter is required, it can register and
> launch it on a service core. Alternatively, this adapter can serve as a
> template for applications to design customer ethernet Rx event adapters
> better suited to their needs.
> 
> The adapter can service multiple ethernet devices and queues. Each queue is
> configured with a servicing weight to control the relative frequency with
> which the adapter polls the queue, and the event fields to use when
> constructing packet events. The adapter has two modes for programming an
> event's flow ID: use a static per-queue user-specified value or use the RSS
> hash.
> 
> A detailed description of the adapter is contained in the header's
> comments.
> 
> [1] http://dpdk.org/ml/archives/dev/2017-May/065341.html
> [2] http://dpdk.org/ml/archives/dev/2017-May/065207.html
> 
> Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
> Signed-off-by: Gage Eads <gage.eads@intel.com>
> ---
> +
> +/**
> + * @file
> + *
> + * RTE Ethernet Rx Adapter for Eventdev
> + *
> + * An eventdev-based packet processing application enqueues/dequeues mbufs
> + * to/from the event device. The ethernet Rx event adapter's role is to transfer
> + * mbufs from the ethernet receive queues managed by DPDK to an event device.
> + * The application uses the adapter APIs to configure the packet flow between
> + * the ethernet devices and event devices. The adapter is designed to work with
> + * the EAL service cores. The adapter's work can be parallelized by dividing the
> + * NIC Rx queues among multiple adapter services that run in parallel.
> + *
> + * Before using the adapter, the application needs to enumerate and configure
> + * the ethernet devices that it wishes to use. This is typically done using the
> + * following DPDK ethdev functions:
> + *  - rte_eth_dev_configure()
> + *  - rte_eth_tx_queue_setup()
> + *  - rte_eth_rx_queue_setup()
> + *  - rte_eth_dev_start()
> + *
> + * The application also configures an event device and creates event ports
> + * to interface with the event device. In addition to the event ports used by
> + * its packet processing functions, the application creates an event port
> + * to be used by this adapter.
> + *
> + * The ethernet Rx event adapter's functions are:
> + *  - rte_eth_rx_event_adapter_create()
> + *  - rte_eth_rx_event_adapter_free()
> + *  - rte_eth_rx_event_adapter_dev_add()
> + *  - rte_eth_rx_event_adapter_dev_del()
> + *  - rte_eth_rx_event_adapter_queue_add()
> + *  - rte_eth_rx_event_adapter_run()
> + *  - rte_eth_rx_event_adapter_stats_get()
> + *  - rte_eth_rx_event_adapter_stats_reset()
> + *
> + * The applicaton creates an event to ethernet adapter using
> + * rte_eth_rx_event_adapter_create(). The event device and event port
> + * identifiers are passed to this function. Next, the application adds ethernet
> + * devices to this adapter using rte_eth_rx_event_adapter_dev_add().
> + *
> + * 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_eth_rx_event_adapter_queue_add() function is provided for
> + * this purpose.
> + *
> + * At the time of adding an ethernet device receive queue, the application can
> + * also specify a static event flow id and set the
> + * RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID bit of the rx_queue_flags
> + * member of the rte_eth_rx_event_adapter_queue_config structure. If the
> + * RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID isn't set, the flow id is
> + * assigned the value of the RSS hash. The adapter generates the RSS hash if it
> + * hasn't been already computed by the NIC, based on source and destination
> + * IPv4/6 addresses, using the rte_softrss_be() routine included in the DPDK.
> + *
> + * The servicing weight parameter in the rte_eth_rx_event_adapter_queue_config
> + * 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.

Looks good.

> + */
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#include <stdint.h>
> +#include <rte_mbuf.h>
> +#include <rte_eventdev.h>
> +
> +/* struct rte_eth_rx_event_adapter_queue_config flags definitions */
> +#define RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID	0x1
> +/*< This flag indicates the flow identifier is valid */
> +
> +struct rte_eth_rx_event_adapter_config {

Since this code is going to be at lib/librte_eventdev, We must start all
public symbols and file name with rte_event_*.

example:
May be this structure can be changed as rte_event_eth_rx_adapter_config


> +	uint8_t event_dev_id;
> +	/**< Event device identifier */
> +	uint8_t rx_event_port_id;
> +	/**< Event port identifier, the adapter enqueues mbuf events to this
> +	 * port
> +	 */
> +};
> +
> +struct rte_eth_rx_event_adapter_queue_config {
> +	uint32_t rx_queue_flags;
> +	 /**< Flags for handling received packets */

Better to add references with @see
example:
	@see RTE_ETH_RX_EVENT_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
> +	 */
> +	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.

This scheme is good. I was duplicating the elements in "struct
rte_event_dev_producer_conf"

IMO, We need to set ev.event_type == RTE_EVENT_TYPE_ETHDEV implicitly in
library.
You can mention that here as a info.

> +	 */
> +};
> +
> +struct rte_eth_rx_event_adapter_run_args {
> +	uint8_t id;
> +	/**< Adapter identifier */
> +	unsigned int 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.
> +	 */
> +};
> +
> +struct rte_eth_rx_event_adapter_stats {
> +	uint64_t rx_poll_count;
> +	/**< Receive queue poll count across both polled and interrupt mode
> +	 * queues
> +	 */
> +	uint64_t rx_packets;
> +	/**< Received packet count */
> +	uint64_t rx_enq_fail;
> +	/**< Eventdev enqueue failed count */
> +	uint64_t rx_enq_retry;
> +	/**< Eventdev enqueue retry count */
> +};
> +
> +/**
> + * Create a new ethernet Rx event adapter with the specified identifier.
> + *
> + * @param adapter_id
> + *   Event adapter identifier.
> + * @param config
> + *   Event adapter config parameters.
> + * @return
> + *   - 0: Success
> + *   - <0: Error code on failure
> + */
> +int rte_eth_rx_event_adapter_create(
> +	uint8_t id,
> +	const struct rte_eth_rx_event_adapter_config *config);
> +

One adapter creates one service function. right?
It is good to mention the mapping.It is missing in the doc.

> +/**
> + * Free an event adapter
> + *
> + * @param id
> + *   Adapter identifier.
> + * @return
> + *   - 0: Success
> + *   - <0: Error code on failure
> + */
> +int rte_eth_rx_event_adapter_free(uint8_t id);
> +
> +/**
> + * Add eth device to the event adapter
> + *
> + * @param id
> + *   Adapter identifier.
> + * @param eth_dev_id
> + *  Port identifier of the Ethernet device.
> + * @return
> + *   - 0: Success
> + *   - <0: Error code on failure
> + */
> +int rte_eth_rx_event_adapter_dev_add(uint8_t id, uint8_t eth_dev_id);

rte_eth_event_rx_queue_add() also have eth_dev_id.What is the
significance of eth_dev_id here. Looks like eth_dev_id is a duplicate info.

if it is duplicate or it can be avoided then I propose to reduce the number
of APIs for easiness of application programming(i.e removing rte_eth_rx_event_adapter_dev_add,
rte_eth_rx_event_adapter_dev_del)

You can also mention the following for better clarify. If following is
true.If not, What do you think about, co-existence of poll and event mode?

The rte_eth_rx_burst() result is undefined if application invokes on
bounded ethdev_port and rx_queue_id.

> +
> +/**
> + * Delete eth device from an event adapter
> + *
> + * @param id
> + *   Adapter identifier.
> + * @param eth_dev_id
> + *  Port identifier of the Ethernet device.
> + * @return
> + *   - 0: Success
> + *   - <0: Error code on failure
> + */
> +int rte_eth_rx_event_adapter_dev_del(uint8_t id, uint8_t eth_dev_id);
> +
> +/**
> + * Add receive queue to event adapter
> + *
> + * @param id
> + *   Adapter identifier.
> + * @param eth_dev_id
> + *  Port identifier of Ethernet device.
> + * @param rx_queue_id
> + *  Ethernet device receive queue index.
> + * @param config
> + *  Additonal configuration structure.
> + * @return
> + *  - 0: Success, Receive queue added correctly.
> + *  - <0: Error code on failure.
> + */
> +int rte_eth_event_rx_queue_add(
> +	uint8_t id,
> +	uint8_t eth_dev_id,
> +	uint16_t rx_queue_id,

How about changing it as int32_t rx_queue_id and -1 to denote all Rx
queues configured for given eth_dev_id are added. This will avoid the
case where application needs to call this API one by one when application
interested in all the queues.

> +	const struct rte_eth_rx_event_adapter_queue_config *config);
> +

Don't we need rte_eth_event_rx_queue_del() for tear down?

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] eventdev: add event adapter for ethernet Rx queues
  2017-05-11 16:38 ` Jerin Jacob
@ 2017-05-16 20:51   ` Thomas Monjalon
  2017-05-24  4:30   ` Rao, Nikhil
  1 sibling, 0 replies; 41+ messages in thread
From: Thomas Monjalon @ 2017-05-16 20:51 UTC (permalink / raw)
  To: Gage Eads, nikhil.rao
  Cc: dev, Jerin Jacob, bruce.richardson, harry.van.haaren,
	hemant.agrawal, nipun.gupta, narender.vangati

11/05/2017 18:38, Jerin Jacob:
> > +struct rte_eth_rx_event_adapter_config {
> 
> Since this code is going to be at lib/librte_eventdev, We must start all
> public symbols and file name with rte_event_*.

+1, please do not mix the namespaces

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] eventdev: add event adapter for ethernet Rx queues
  2017-05-11 16:38 ` Jerin Jacob
  2017-05-16 20:51   ` Thomas Monjalon
@ 2017-05-24  4:30   ` Rao, Nikhil
  2017-06-19 10:05     ` Jerin Jacob
  1 sibling, 1 reply; 41+ messages in thread
From: Rao, Nikhil @ 2017-05-24  4:30 UTC (permalink / raw)
  To: Jerin Jacob, Gage Eads
  Cc: dev, thomas, bruce.richardson, harry.van.haaren, hemant.agrawal,
	nipun.gupta, narender.vangati, nikhil.rao

Hi Jerin,

Comments inline.

Also, another function needed is
bool rte_event_eth_rx_adapter_multithread_capable(void). 

This would be used to set the "multithread_capable" service core 
configuration parameter. 

Thanks,
Nikhil

On 5/11/2017 10:08 PM, Jerin Jacob wrote:
> -----Original Message-----
>> Date: Tue, 9 May 2017 15:38:46 -0500
>> From: Gage Eads <gage.eads@intel.com>
>> To: dev@dpdk.org
>> CC: nikhil.rao@intel.com, jerin.jacob@caviumnetworks.com,
>>  thomas@monjalon.net, bruce.richardson@intel.com,
>>  harry.van.haaren@intel.com, hemant.agrawal@nxp.com, nipun.gupta@nxp.com,
>>  narender.vangati@intel.com
>> Subject: [RFC] eventdev: add event adapter for ethernet Rx queues
>> X-Mailer: git-send-email 2.7.4
>>
>> From: Nikhil Rao <nikhil.rao@intel.com>
> 
> Hi Nikhil and Gage,
> 
> Thanks for the RFC. A few questions and comments below.
> Looks like SW has more constraints on event producer side, after we
> finalize on this RFC(I guess only a few minor changes are only required).
> I will align other[1] RFC based on _your_ RFC as we need to
> converge on name space and we can't duplicate configs like struct
> rte_event_dev_producer_conf etc
> 
> [1]
> http://dpdk.org/ml/archives/dev/2017-May/065341.html
> 
>
> 
>> + */
>> +
>> +#ifdef __cplusplus
>> +extern "C" {
>> +#endif
>> +
>> +#include <stdint.h>
>> +#include <rte_mbuf.h>
>> +#include <rte_eventdev.h>
>> +
>> +/* struct rte_eth_rx_event_adapter_queue_config flags definitions */
>> +#define RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID	0x1
>> +/*< This flag indicates the flow identifier is valid */
>> +
>> +struct rte_eth_rx_event_adapter_config {
> 
> Since this code is going to be at lib/librte_eventdev, We must start all
> public symbols and file name with rte_event_*.
> 
> example:
> May be this structure can be changed as rte_event_eth_rx_adapter_config

OK.

> 
> 
>> +	uint8_t event_dev_id;
>> +	/**< Event device identifier */
>> +	uint8_t rx_event_port_id;
>> +	/**< Event port identifier, the adapter enqueues mbuf events to this
>> +	 * port
>> +	 */
>> +};
>> +
>> +struct rte_eth_rx_event_adapter_queue_config {
>> +	uint32_t rx_queue_flags;
>> +	 /**< Flags for handling received packets */
> 
> Better to add references with @see
> example:
> 	@see RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID

OK.

> 
>> +	uint16_t servicing_weight;
>> +	/**< Relative polling frequency of ethernet receive queue, if this
>> +	 * is set to zero, the Rx queue is interrupt driven
>> +	 */
>> +	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.
> 
> This scheme is good. I was duplicating the elements in "struct
> rte_event_dev_producer_conf"
> 
> IMO, We need to set ev.event_type == RTE_EVENT_TYPE_ETHDEV implicitly in
> library.
> You can mention that here as a info.
OK.

> 
>> +	 */
>> +};
>> +
>> +struct rte_eth_rx_event_adapter_run_args {
>> +	uint8_t id;
>> +	/**< Adapter identifier */
>> +	unsigned int 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.
>> +	 */
>> +};
>> +
>> +struct rte_eth_rx_event_adapter_stats {
>> +	uint64_t rx_poll_count;
>> +	/**< Receive queue poll count across both polled and interrupt mode
>> +	 * queues
>> +	 */
>> +	uint64_t rx_packets;
>> +	/**< Received packet count */
>> +	uint64_t rx_enq_fail;
>> +	/**< Eventdev enqueue failed count */
>> +	uint64_t rx_enq_retry;
>> +	/**< Eventdev enqueue retry count */
>> +};
>> +
>> +/**
>> + * Create a new ethernet Rx event adapter with the specified identifier.
>> + *
>> + * @param adapter_id
>> + *   Event adapter identifier.
>> + * @param config
>> + *   Event adapter config parameters.
>> + * @return
>> + *   - 0: Success
>> + *   - <0: Error code on failure
>> + */
>> +int rte_eth_rx_event_adapter_create(
>> +	uint8_t id,
>> +	const struct rte_eth_rx_event_adapter_config *config);
>> +
> 
> One adapter creates one service function. right?
> It is good to mention the mapping.It is missing in the doc.

Yes, in this case, the application creates a service per adapter, it may create multiple
Rx event adapters with each adapter handling a subset of Rx queues. As per Harry's
patch, only DPDK internal components are expected to request service cores, once Harry posts
an updated patch, I will make any necesssary changes and post the next version of this
patch.

>> +/**
>> + * Free an event adapter
>> + *
>> + * @param id
>> + *   Adapter identifier.
>> + * @return
>> + *   - 0: Success
>> + *   - <0: Error code on failure
>> + */
>> +int rte_eth_rx_event_adapter_free(uint8_t id);
>> +
>> +/**
>> + * Add eth device to the event adapter
>> + *
>> + * @param id
>> + *   Adapter identifier.
>> + * @param eth_dev_id
>> + *  Port identifier of the Ethernet device.
>> + * @return
>> + *   - 0: Success
>> + *   - <0: Error code on failure
>> + */
>> +int rte_eth_rx_event_adapter_dev_add(uint8_t id, uint8_t eth_dev_id);
> 
> rte_eth_event_rx_queue_add() also have eth_dev_id.What is the
> significance of eth_dev_id here. Looks like eth_dev_id is a duplicate info.
> 
> if it is duplicate or it can be avoided then I propose to reduce the number
> of APIs for easiness of application programming(i.e removing rte_eth_rx_event_adapter_dev_add,
> rte_eth_rx_event_adapter_dev_del)
OK.

> 
> You can also mention the following for better clarify. If following is
> true.If not, What do you think about, co-existence of poll and event mode?

Yes, its true.

> The rte_eth_rx_burst() result is undefined if application invokes on
> bounded ethdev_port and rx_queue_id.
> 
>> +
>> +/**
>> + * Delete eth device from an event adapter
>> + *
>> + * @param id
>> + *   Adapter identifier.
>> + * @param eth_dev_id
>> + *  Port identifier of the Ethernet device.
>> + * @return
>> + *   - 0: Success
>> + *   - <0: Error code on failure
>> + */
>> +int rte_eth_rx_event_adapter_dev_del(uint8_t id, uint8_t eth_dev_id);
>> +
>> +/**
>> + * Add receive queue to event adapter
>> + *
>> + * @param id
>> + *   Adapter identifier.
>> + * @param eth_dev_id
>> + *  Port identifier of Ethernet device.
>> + * @param rx_queue_id
>> + *  Ethernet device receive queue index.
>> + * @param config
>> + *  Additonal configuration structure.
>> + * @return
>> + *  - 0: Success, Receive queue added correctly.
>> + *  - <0: Error code on failure.
>> + */
>> +int rte_eth_event_rx_queue_add(
>> +	uint8_t id,
>> +	uint8_t eth_dev_id,
>> +	uint16_t rx_queue_id,
> 
> How about changing it as int32_t rx_queue_id and -1 to denote all Rx
> queues configured for given eth_dev_id are added. This will avoid the
> case where application needs to call this API one by one when application
> interested in all the queues.

Sounds good.
 
>> +	const struct rte_eth_rx_event_adapter_queue_config *config);
>> +
> 
> Don't we need rte_eth_event_rx_queue_del() for tear down?
> 
Yes.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] eventdev: add event adapter for ethernet Rx queues
  2017-05-24  4:30   ` Rao, Nikhil
@ 2017-06-19 10:05     ` Jerin Jacob
  2017-06-26 13:19       ` Jerin Jacob
  0 siblings, 1 reply; 41+ messages in thread
From: Jerin Jacob @ 2017-06-19 10:05 UTC (permalink / raw)
  To: Rao, Nikhil
  Cc: Gage Eads, dev, thomas, bruce.richardson, harry.van.haaren,
	hemant.agrawal, nipun.gupta, narender.vangati

-----Original Message-----
> Date: Wed, 24 May 2017 10:00:22 +0530
> From: "Rao, Nikhil" <nikhil.rao@intel.com>
> To: Jerin Jacob <jerin.jacob@caviumnetworks.com>, Gage Eads
>  <gage.eads@intel.com>
> CC: dev@dpdk.org, thomas@monjalon.net, bruce.richardson@intel.com,
>  harry.van.haaren@intel.com, hemant.agrawal@nxp.com, nipun.gupta@nxp.com,
>  narender.vangati@intel.com, nikhil.rao@intel.com
> Subject: Re: [RFC] eventdev: add event adapter for ethernet Rx queues
> User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:38.0) Gecko/20100101
>  Thunderbird/38.7.2
> 
> Hi Jerin,

Hi Nikhil,

> 
> Comments inline.
> 
> Also, another function needed is
> bool rte_event_eth_rx_adapter_multithread_capable(void). 
> 
> This would be used to set the "multithread_capable" service core 
> configuration parameter. 

OK.

I was thinking like, in order to effectively use adapter scheme, it should
use ops scheme like rte_flow or rte_tm[1] where the same API can be
can be used for both HW and SW. If we see, Both RFC[2], We have a lot of
similarities. I think, We can base the eth_rx_adapter model based on your SW
requirement RFC and introduce capability wherever it is not applicable for HW or
vice versa.

See below as a example[3]. Can you take of the same in v1 of this
series? if you don't have the bandwidth then I can try. Let me know.
Thoughts?

[1]
http://dpdk.org/dev/patchwork/patch/25275/
http://dpdk.org/dev/patchwork/patch/25276/

[2]
http://dpdk.org/ml/archives/dev/2017-May/065341.html


/* adapter has inbuilt port, no need to create producer port */
#define RTE_EVENT_ETHDEV_CAP_INBUILT_PORT  (1ULL << 0)
/* adapter does not need service function */
#define RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC (1ULL << 1)

struct rte_event_eth_rx_adap_info {
	char name[32];
        uint32_t adapter_cap;
        /**< Ethdev RX adapter capabilities(RTE_EVENT_ETHDEV_CAP_)*/
}


struct rte_event_eth_rx_adap_cfg {
	uint8_t rx_event_port_id;
       /**< Event port identifier, the adapter enqueues mbuf events to this
        * port, Ignored when RTE_EVENT_ETHDEV_CAP_INBUILT_PORT
        */

}

struct rte_eth_rx_event_adapter_queue_config {
       uint32_t rx_queue_flags;
        /**< Flags for handling received packets */
       uint16_t servicing_weight;
       /**< Relative polling frequency of ethernet receive queue, if this
        * is set to zero, the Rx queue is interrupt driven
        * Ignored if RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC set
        */
       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.
        */
};

int rte_event_eth_rx_adapter_create(uint8_t id, uint8_t dev_id, uint8_t eth_port_id);
int rte_event_eth_rx_adapter_get_info(uint8_t id, struct rte_event_eth_rx_adap_info *info);
int rte_event_eth_rx_adapter_configure(uint8_t id, struct rte_event_eth_rx_adap_config *cfg);
int rte_event_eth_rx_adapter_queue_add(uint8_t id, int32_t rx_queue_id, const struct rte_eth_rx_event_adapter_queue_config *config);
int rte_event_eth_rx_adapter_queue_del(uint8_t id, int32_t rx_queue_id)
int rte_event_eth_rx_adapter_run();
int rte_event_eth_rx_adapter_free(uint8_t id);



> 
> Thanks,
> Nikhil
> 
> On 5/11/2017 10:08 PM, Jerin Jacob wrote:
> > -----Original Message-----
> >> Date: Tue, 9 May 2017 15:38:46 -0500
> >> From: Gage Eads <gage.eads@intel.com>
> >> To: dev@dpdk.org
> >> CC: nikhil.rao@intel.com, jerin.jacob@caviumnetworks.com,
> >>  thomas@monjalon.net, bruce.richardson@intel.com,
> >>  harry.van.haaren@intel.com, hemant.agrawal@nxp.com, nipun.gupta@nxp.com,
> >>  narender.vangati@intel.com
> >> Subject: [RFC] eventdev: add event adapter for ethernet Rx queues
> >> X-Mailer: git-send-email 2.7.4
> >>
> >> From: Nikhil Rao <nikhil.rao@intel.com>
> > 
> > Hi Nikhil and Gage,
> > 
> > Thanks for the RFC. A few questions and comments below.
> > Looks like SW has more constraints on event producer side, after we
> > finalize on this RFC(I guess only a few minor changes are only required).
> > I will align other[1] RFC based on _your_ RFC as we need to
> > converge on name space and we can't duplicate configs like struct
> > rte_event_dev_producer_conf etc
> > 
> > [1]
> > http://dpdk.org/ml/archives/dev/2017-May/065341.html
> > 
> >
> > 
> >> + */
> >> +
> >> +#ifdef __cplusplus
> >> +extern "C" {
> >> +#endif
> >> +
> >> +#include <stdint.h>
> >> +#include <rte_mbuf.h>
> >> +#include <rte_eventdev.h>
> >> +
> >> +/* struct rte_eth_rx_event_adapter_queue_config flags definitions */
> >> +#define RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID	0x1
> >> +/*< This flag indicates the flow identifier is valid */
> >> +
> >> +struct rte_eth_rx_event_adapter_config {
> > 
> > Since this code is going to be at lib/librte_eventdev, We must start all
> > public symbols and file name with rte_event_*.
> > 
> > example:
> > May be this structure can be changed as rte_event_eth_rx_adapter_config
> 
> OK.
> 
> > 
> > 
> >> +	uint8_t event_dev_id;
> >> +	/**< Event device identifier */
> >> +	uint8_t rx_event_port_id;
> >> +	/**< Event port identifier, the adapter enqueues mbuf events to this
> >> +	 * port
> >> +	 */
> >> +};
> >> +
> >> +struct rte_eth_rx_event_adapter_queue_config {
> >> +	uint32_t rx_queue_flags;
> >> +	 /**< Flags for handling received packets */
> > 
> > Better to add references with @see
> > example:
> > 	@see RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID
> 
> OK.
> 
> > 
> >> +	uint16_t servicing_weight;
> >> +	/**< Relative polling frequency of ethernet receive queue, if this
> >> +	 * is set to zero, the Rx queue is interrupt driven
> >> +	 */
> >> +	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.
> > 
> > This scheme is good. I was duplicating the elements in "struct
> > rte_event_dev_producer_conf"
> > 
> > IMO, We need to set ev.event_type == RTE_EVENT_TYPE_ETHDEV implicitly in
> > library.
> > You can mention that here as a info.
> OK.
> 
> > 
> >> +	 */
> >> +};
> >> +
> >> +struct rte_eth_rx_event_adapter_run_args {
> >> +	uint8_t id;
> >> +	/**< Adapter identifier */
> >> +	unsigned int 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.
> >> +	 */
> >> +};
> >> +
> >> +struct rte_eth_rx_event_adapter_stats {
> >> +	uint64_t rx_poll_count;
> >> +	/**< Receive queue poll count across both polled and interrupt mode
> >> +	 * queues
> >> +	 */
> >> +	uint64_t rx_packets;
> >> +	/**< Received packet count */
> >> +	uint64_t rx_enq_fail;
> >> +	/**< Eventdev enqueue failed count */
> >> +	uint64_t rx_enq_retry;
> >> +	/**< Eventdev enqueue retry count */
> >> +};
> >> +
> >> +/**
> >> + * Create a new ethernet Rx event adapter with the specified identifier.
> >> + *
> >> + * @param adapter_id
> >> + *   Event adapter identifier.
> >> + * @param config
> >> + *   Event adapter config parameters.
> >> + * @return
> >> + *   - 0: Success
> >> + *   - <0: Error code on failure
> >> + */
> >> +int rte_eth_rx_event_adapter_create(
> >> +	uint8_t id,
> >> +	const struct rte_eth_rx_event_adapter_config *config);
> >> +
> > 
> > One adapter creates one service function. right?
> > It is good to mention the mapping.It is missing in the doc.
> 
> Yes, in this case, the application creates a service per adapter, it may create multiple
> Rx event adapters with each adapter handling a subset of Rx queues. As per Harry's
> patch, only DPDK internal components are expected to request service cores, once Harry posts
> an updated patch, I will make any necesssary changes and post the next version of this
> patch.
> 
> >> +/**
> >> + * Free an event adapter
> >> + *
> >> + * @param id
> >> + *   Adapter identifier.
> >> + * @return
> >> + *   - 0: Success
> >> + *   - <0: Error code on failure
> >> + */
> >> +int rte_eth_rx_event_adapter_free(uint8_t id);
> >> +
> >> +/**
> >> + * Add eth device to the event adapter
> >> + *
> >> + * @param id
> >> + *   Adapter identifier.
> >> + * @param eth_dev_id
> >> + *  Port identifier of the Ethernet device.
> >> + * @return
> >> + *   - 0: Success
> >> + *   - <0: Error code on failure
> >> + */
> >> +int rte_eth_rx_event_adapter_dev_add(uint8_t id, uint8_t eth_dev_id);
> > 
> > rte_eth_event_rx_queue_add() also have eth_dev_id.What is the
> > significance of eth_dev_id here. Looks like eth_dev_id is a duplicate info.
> > 
> > if it is duplicate or it can be avoided then I propose to reduce the number
> > of APIs for easiness of application programming(i.e removing rte_eth_rx_event_adapter_dev_add,
> > rte_eth_rx_event_adapter_dev_del)
> OK.
> 
> > 
> > You can also mention the following for better clarify. If following is
> > true.If not, What do you think about, co-existence of poll and event mode?
> 
> Yes, its true.
> 
> > The rte_eth_rx_burst() result is undefined if application invokes on
> > bounded ethdev_port and rx_queue_id.
> > 
> >> +
> >> +/**
> >> + * Delete eth device from an event adapter
> >> + *
> >> + * @param id
> >> + *   Adapter identifier.
> >> + * @param eth_dev_id
> >> + *  Port identifier of the Ethernet device.
> >> + * @return
> >> + *   - 0: Success
> >> + *   - <0: Error code on failure
> >> + */
> >> +int rte_eth_rx_event_adapter_dev_del(uint8_t id, uint8_t eth_dev_id);
> >> +
> >> +/**
> >> + * Add receive queue to event adapter
> >> + *
> >> + * @param id
> >> + *   Adapter identifier.
> >> + * @param eth_dev_id
> >> + *  Port identifier of Ethernet device.
> >> + * @param rx_queue_id
> >> + *  Ethernet device receive queue index.
> >> + * @param config
> >> + *  Additonal configuration structure.
> >> + * @return
> >> + *  - 0: Success, Receive queue added correctly.
> >> + *  - <0: Error code on failure.
> >> + */
> >> +int rte_eth_event_rx_queue_add(
> >> +	uint8_t id,
> >> +	uint8_t eth_dev_id,
> >> +	uint16_t rx_queue_id,
> > 
> > How about changing it as int32_t rx_queue_id and -1 to denote all Rx
> > queues configured for given eth_dev_id are added. This will avoid the
> > case where application needs to call this API one by one when application
> > interested in all the queues.
> 
> Sounds good.
>  
> >> +	const struct rte_eth_rx_event_adapter_queue_config *config);
> >> +
> > 
> > Don't we need rte_eth_event_rx_queue_del() for tear down?
> > 
> Yes.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] eventdev: add event adapter for ethernet Rx queues
  2017-06-19 10:05     ` Jerin Jacob
@ 2017-06-26 13:19       ` Jerin Jacob
  2017-06-28  6:47         ` Rao, Nikhil
  0 siblings, 1 reply; 41+ messages in thread
From: Jerin Jacob @ 2017-06-26 13:19 UTC (permalink / raw)
  To: Rao, Nikhil
  Cc: Gage Eads, dev, thomas, bruce.richardson, harry.van.haaren,
	hemant.agrawal, nipun.gupta, narender.vangati

-----Original Message-----
> Date: Mon, 19 Jun 2017 15:35:22 +0530
> From: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> To: "Rao, Nikhil" <nikhil.rao@intel.com>
> CC: Gage Eads <gage.eads@intel.com>, dev@dpdk.org, thomas@monjalon.net,
>  bruce.richardson@intel.com, harry.van.haaren@intel.com,
>  hemant.agrawal@nxp.com, nipun.gupta@nxp.com, narender.vangati@intel.com
> Subject: Re: [dpdk-dev] [RFC] eventdev: add event adapter for ethernet Rx
>  queues
> User-Agent: Mutt/1.8.3 (2017-05-23)
> 
> -----Original Message-----
> > Date: Wed, 24 May 2017 10:00:22 +0530
> > From: "Rao, Nikhil" <nikhil.rao@intel.com>
> > To: Jerin Jacob <jerin.jacob@caviumnetworks.com>, Gage Eads
> >  <gage.eads@intel.com>
> > CC: dev@dpdk.org, thomas@monjalon.net, bruce.richardson@intel.com,
> >  harry.van.haaren@intel.com, hemant.agrawal@nxp.com, nipun.gupta@nxp.com,
> >  narender.vangati@intel.com, nikhil.rao@intel.com
> > Subject: Re: [RFC] eventdev: add event adapter for ethernet Rx queues
> > User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:38.0) Gecko/20100101
> >  Thunderbird/38.7.2
> > 
> > Hi Jerin,
> 
> Hi Nikhil,
> 
> > 
> > Comments inline.
> > 
> > Also, another function needed is
> > bool rte_event_eth_rx_adapter_multithread_capable(void). 
> > 
> > This would be used to set the "multithread_capable" service core 
> > configuration parameter. 
> 
> OK.
> 
> I was thinking like, in order to effectively use adapter scheme, it should
> use ops scheme like rte_flow or rte_tm[1] where the same API can be
> can be used for both HW and SW. If we see, Both RFC[2], We have a lot of
> similarities. I think, We can base the eth_rx_adapter model based on your SW
> requirement RFC and introduce capability wherever it is not applicable for HW or
> vice versa.
> 
> See below as a example[3]. Can you take of the same in v1 of this
> series? if you don't have the bandwidth then I can try. Let me know.

Nikhil,

Now that Harry send first version of service core patch? Are you
planning for new version with above comments?

> Thoughts?
> 
> [1]
> http://dpdk.org/dev/patchwork/patch/25275/
> http://dpdk.org/dev/patchwork/patch/25276/
> 
> [2]
> http://dpdk.org/ml/archives/dev/2017-May/065341.html
> 
> 
> /* adapter has inbuilt port, no need to create producer port */
> #define RTE_EVENT_ETHDEV_CAP_INBUILT_PORT  (1ULL << 0)
> /* adapter does not need service function */
> #define RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC (1ULL << 1)
> 
> struct rte_event_eth_rx_adap_info {
> 	char name[32];
>         uint32_t adapter_cap;
>         /**< Ethdev RX adapter capabilities(RTE_EVENT_ETHDEV_CAP_)*/
> }
> 
> 
> struct rte_event_eth_rx_adap_cfg {
> 	uint8_t rx_event_port_id;
>        /**< Event port identifier, the adapter enqueues mbuf events to this
>         * port, Ignored when RTE_EVENT_ETHDEV_CAP_INBUILT_PORT
>         */
> 
> }
> 
> struct rte_eth_rx_event_adapter_queue_config {
>        uint32_t rx_queue_flags;
>         /**< Flags for handling received packets */
>        uint16_t servicing_weight;
>        /**< Relative polling frequency of ethernet receive queue, if this
>         * is set to zero, the Rx queue is interrupt driven
>         * Ignored if RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC set
>         */
>        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.
>         */
> };
> 
> int rte_event_eth_rx_adapter_create(uint8_t id, uint8_t dev_id, uint8_t eth_port_id);
> int rte_event_eth_rx_adapter_get_info(uint8_t id, struct rte_event_eth_rx_adap_info *info);
> int rte_event_eth_rx_adapter_configure(uint8_t id, struct rte_event_eth_rx_adap_config *cfg);
> int rte_event_eth_rx_adapter_queue_add(uint8_t id, int32_t rx_queue_id, const struct rte_eth_rx_event_adapter_queue_config *config);
> int rte_event_eth_rx_adapter_queue_del(uint8_t id, int32_t rx_queue_id)
> int rte_event_eth_rx_adapter_run();
> int rte_event_eth_rx_adapter_free(uint8_t id);
> 
> 
> 
> > 
> > Thanks,
> > Nikhil
> > 
> > On 5/11/2017 10:08 PM, Jerin Jacob wrote:
> > > -----Original Message-----
> > >> Date: Tue, 9 May 2017 15:38:46 -0500
> > >> From: Gage Eads <gage.eads@intel.com>
> > >> To: dev@dpdk.org
> > >> CC: nikhil.rao@intel.com, jerin.jacob@caviumnetworks.com,
> > >>  thomas@monjalon.net, bruce.richardson@intel.com,
> > >>  harry.van.haaren@intel.com, hemant.agrawal@nxp.com, nipun.gupta@nxp.com,
> > >>  narender.vangati@intel.com
> > >> Subject: [RFC] eventdev: add event adapter for ethernet Rx queues
> > >> X-Mailer: git-send-email 2.7.4
> > >>
> > >> From: Nikhil Rao <nikhil.rao@intel.com>
> > > 
> > > Hi Nikhil and Gage,
> > > 
> > > Thanks for the RFC. A few questions and comments below.
> > > Looks like SW has more constraints on event producer side, after we
> > > finalize on this RFC(I guess only a few minor changes are only required).
> > > I will align other[1] RFC based on _your_ RFC as we need to
> > > converge on name space and we can't duplicate configs like struct
> > > rte_event_dev_producer_conf etc
> > > 
> > > [1]
> > > http://dpdk.org/ml/archives/dev/2017-May/065341.html
> > > 
> > >
> > > 
> > >> + */
> > >> +
> > >> +#ifdef __cplusplus
> > >> +extern "C" {
> > >> +#endif
> > >> +
> > >> +#include <stdint.h>
> > >> +#include <rte_mbuf.h>
> > >> +#include <rte_eventdev.h>
> > >> +
> > >> +/* struct rte_eth_rx_event_adapter_queue_config flags definitions */
> > >> +#define RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID	0x1
> > >> +/*< This flag indicates the flow identifier is valid */
> > >> +
> > >> +struct rte_eth_rx_event_adapter_config {
> > > 
> > > Since this code is going to be at lib/librte_eventdev, We must start all
> > > public symbols and file name with rte_event_*.
> > > 
> > > example:
> > > May be this structure can be changed as rte_event_eth_rx_adapter_config
> > 
> > OK.
> > 
> > > 
> > > 
> > >> +	uint8_t event_dev_id;
> > >> +	/**< Event device identifier */
> > >> +	uint8_t rx_event_port_id;
> > >> +	/**< Event port identifier, the adapter enqueues mbuf events to this
> > >> +	 * port
> > >> +	 */
> > >> +};
> > >> +
> > >> +struct rte_eth_rx_event_adapter_queue_config {
> > >> +	uint32_t rx_queue_flags;
> > >> +	 /**< Flags for handling received packets */
> > > 
> > > Better to add references with @see
> > > example:
> > > 	@see RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID
> > 
> > OK.
> > 
> > > 
> > >> +	uint16_t servicing_weight;
> > >> +	/**< Relative polling frequency of ethernet receive queue, if this
> > >> +	 * is set to zero, the Rx queue is interrupt driven
> > >> +	 */
> > >> +	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.
> > > 
> > > This scheme is good. I was duplicating the elements in "struct
> > > rte_event_dev_producer_conf"
> > > 
> > > IMO, We need to set ev.event_type == RTE_EVENT_TYPE_ETHDEV implicitly in
> > > library.
> > > You can mention that here as a info.
> > OK.
> > 
> > > 
> > >> +	 */
> > >> +};
> > >> +
> > >> +struct rte_eth_rx_event_adapter_run_args {
> > >> +	uint8_t id;
> > >> +	/**< Adapter identifier */
> > >> +	unsigned int 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.
> > >> +	 */
> > >> +};
> > >> +
> > >> +struct rte_eth_rx_event_adapter_stats {
> > >> +	uint64_t rx_poll_count;
> > >> +	/**< Receive queue poll count across both polled and interrupt mode
> > >> +	 * queues
> > >> +	 */
> > >> +	uint64_t rx_packets;
> > >> +	/**< Received packet count */
> > >> +	uint64_t rx_enq_fail;
> > >> +	/**< Eventdev enqueue failed count */
> > >> +	uint64_t rx_enq_retry;
> > >> +	/**< Eventdev enqueue retry count */
> > >> +};
> > >> +
> > >> +/**
> > >> + * Create a new ethernet Rx event adapter with the specified identifier.
> > >> + *
> > >> + * @param adapter_id
> > >> + *   Event adapter identifier.
> > >> + * @param config
> > >> + *   Event adapter config parameters.
> > >> + * @return
> > >> + *   - 0: Success
> > >> + *   - <0: Error code on failure
> > >> + */
> > >> +int rte_eth_rx_event_adapter_create(
> > >> +	uint8_t id,
> > >> +	const struct rte_eth_rx_event_adapter_config *config);
> > >> +
> > > 
> > > One adapter creates one service function. right?
> > > It is good to mention the mapping.It is missing in the doc.
> > 
> > Yes, in this case, the application creates a service per adapter, it may create multiple
> > Rx event adapters with each adapter handling a subset of Rx queues. As per Harry's
> > patch, only DPDK internal components are expected to request service cores, once Harry posts
> > an updated patch, I will make any necesssary changes and post the next version of this
> > patch.
> > 
> > >> +/**
> > >> + * Free an event adapter
> > >> + *
> > >> + * @param id
> > >> + *   Adapter identifier.
> > >> + * @return
> > >> + *   - 0: Success
> > >> + *   - <0: Error code on failure
> > >> + */
> > >> +int rte_eth_rx_event_adapter_free(uint8_t id);
> > >> +
> > >> +/**
> > >> + * Add eth device to the event adapter
> > >> + *
> > >> + * @param id
> > >> + *   Adapter identifier.
> > >> + * @param eth_dev_id
> > >> + *  Port identifier of the Ethernet device.
> > >> + * @return
> > >> + *   - 0: Success
> > >> + *   - <0: Error code on failure
> > >> + */
> > >> +int rte_eth_rx_event_adapter_dev_add(uint8_t id, uint8_t eth_dev_id);
> > > 
> > > rte_eth_event_rx_queue_add() also have eth_dev_id.What is the
> > > significance of eth_dev_id here. Looks like eth_dev_id is a duplicate info.
> > > 
> > > if it is duplicate or it can be avoided then I propose to reduce the number
> > > of APIs for easiness of application programming(i.e removing rte_eth_rx_event_adapter_dev_add,
> > > rte_eth_rx_event_adapter_dev_del)
> > OK.
> > 
> > > 
> > > You can also mention the following for better clarify. If following is
> > > true.If not, What do you think about, co-existence of poll and event mode?
> > 
> > Yes, its true.
> > 
> > > The rte_eth_rx_burst() result is undefined if application invokes on
> > > bounded ethdev_port and rx_queue_id.
> > > 
> > >> +
> > >> +/**
> > >> + * Delete eth device from an event adapter
> > >> + *
> > >> + * @param id
> > >> + *   Adapter identifier.
> > >> + * @param eth_dev_id
> > >> + *  Port identifier of the Ethernet device.
> > >> + * @return
> > >> + *   - 0: Success
> > >> + *   - <0: Error code on failure
> > >> + */
> > >> +int rte_eth_rx_event_adapter_dev_del(uint8_t id, uint8_t eth_dev_id);
> > >> +
> > >> +/**
> > >> + * Add receive queue to event adapter
> > >> + *
> > >> + * @param id
> > >> + *   Adapter identifier.
> > >> + * @param eth_dev_id
> > >> + *  Port identifier of Ethernet device.
> > >> + * @param rx_queue_id
> > >> + *  Ethernet device receive queue index.
> > >> + * @param config
> > >> + *  Additonal configuration structure.
> > >> + * @return
> > >> + *  - 0: Success, Receive queue added correctly.
> > >> + *  - <0: Error code on failure.
> > >> + */
> > >> +int rte_eth_event_rx_queue_add(
> > >> +	uint8_t id,
> > >> +	uint8_t eth_dev_id,
> > >> +	uint16_t rx_queue_id,
> > > 
> > > How about changing it as int32_t rx_queue_id and -1 to denote all Rx
> > > queues configured for given eth_dev_id are added. This will avoid the
> > > case where application needs to call this API one by one when application
> > > interested in all the queues.
> > 
> > Sounds good.
> >  
> > >> +	const struct rte_eth_rx_event_adapter_queue_config *config);
> > >> +
> > > 
> > > Don't we need rte_eth_event_rx_queue_del() for tear down?
> > > 
> > Yes.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] eventdev: add event adapter for ethernet Rx queues
  2017-06-26 13:19       ` Jerin Jacob
@ 2017-06-28  6:47         ` Rao, Nikhil
  2017-07-06 21:52           ` [PATCH 1/2] " Nikhil Rao
  0 siblings, 1 reply; 41+ messages in thread
From: Rao, Nikhil @ 2017-06-28  6:47 UTC (permalink / raw)
  To: Jerin Jacob
  Cc: Gage Eads, dev, thomas, bruce.richardson, harry.van.haaren,
	hemant.agrawal, nipun.gupta, narender.vangati

On 6/26/2017 6:49 PM, Jerin Jacob wrote:
>
> 
> Nikhil,
> 
> Now that Harry send first version of service core patch? Are you
> planning for new version with above comments?
> 

Yes. I will post a new version.

Thanks,
Nikhil

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-07-06 21:52           ` [PATCH 1/2] " Nikhil Rao
@ 2017-07-06 14:18             ` Jerin Jacob
  2017-07-07  6:21               ` Rao, Nikhil
  2017-07-06 21:52             ` [PATCH 2/2] eventdev: add event eth rx adapter unit tests Nikhil Rao
  2017-07-24 10:10             ` [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues Nipun Gupta
  2 siblings, 1 reply; 41+ messages in thread
From: Jerin Jacob @ 2017-07-06 14:18 UTC (permalink / raw)
  To: Nikhil Rao
  Cc: gage.eads, dev, thomas, bruce.richardson, harry.van.haaren,
	hemant.agrawal, nipun.gupta, narender.vangati, Abhinandan Gujjar

-----Original Message-----
> Date: Fri, 7 Jul 2017 03:22:31 +0530
> From: Nikhil Rao <nikhil.rao@intel.com>
> To: jerin.jacob@caviumnetworks.com
> CC: gage.eads@intel.com, dev@dpdk.org, thomas@monjalon.net,
>  bruce.richardson@intel.com, harry.van.haaren@intel.com,
>  hemant.agrawal@nxp.com, nipun.gupta@nxp.com, narender.vangati@intel.com,
>  Nikhil Rao <nikhil.rao@intel.com>, Abhinandan Gujjar
>  <abhinandan.gujjar@intel.com>
> Subject: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> X-Mailer: git-send-email 2.7.4
> 
> Eventdev-based networking applications require a component to dequeue
> packets from NIC Rx queues and inject them into eventdev queues[1]. While
> some platforms (e.g. Cavium Octeontx) do this operation in hardware, other
> platforms use software.
> 
> This patchset introduces an ethernet Rx event adapter that dequeues packets
> from ethernet devices and enqueues them to event devices. It is based on
> a previous RFC[2].
> 
> The adapter is designed to work with the EAL service core[3]. If
> an application determines that the adapter is required, it can register and
> launch it on a service core. Alternatively, this adapter can serve as a
> template for applications to design customer ethernet Rx event adapters
> better suited to their needs.
> 
> The adapter can service multiple ethernet devices and queues. Each queue is
> configured with a servicing weight to control the relative frequency with
> which the adapter polls the queue, and the event fields to use when
> constructing packet events. The adapter has two modes for programming an
> event's flow ID: use a static per-queue user-specified value or use the RSS
> hash.
> 
> A detailed description of the adapter is contained in the header's
> comments.
> 
> [1] http://dpdk.org/ml/archives/dev/2017-May/065341.html
> [2] http://dpdk.org/ml/archives/dev/2017-May/065539.html
> [3] http://dpdk.org/ml/archives/dev/2017-July/069782.html
> 
> Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
> Signed-off-by: Gage Eads <gage.eads@intel.com>
> Signed-off-by: Abhinandan Gujjar <abhinandan.gujjar@intel.com>
> ---


Thanks Nikhil for the patch.

Looks like you missed this email?
http://dpdk.org/ml/archives/dev/2017-June/068142.html

Can we make it as function pointer based approach(keeping all adapter functions
function prototype required for SW PMD) so that each PMD
can register the ops for adapter_create etc so that same API can be used
for software and hardware PMDs(the scheme like rte_flow() or rte_tm()
approach)

Can discuss more on that to finalize the approach?
> 
> v2:
> Thanks Jerin for review - below is a list of changes you
> suggested.
> 
> - all public symbols are started with rte_event_.
> - Add Doxygen reference with @see.
> - Mention setting of ev.event_type.
> - Mention adapter to service function mapping.
> - Remove rte_eth_rx_event_adapter_dev_add/del().
> - Change rx_queuee_id to int32_t and use -1 to denote all Rx queues.
> - Add rte_eth_event_rx_queue_del().
> 
> Other changes
> - Remove adapter's run function (rte_event_eth_rx_adapter_run()) from
>   the public interface. The adapter internally uses it to create a
>   service.
> - Add a blocked cycle count to stats. Further description is contained
>   in the header.
> - Minor struct renames rte_event_eth_rx_adapter_config -> .._conf
> ---

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-06-28  6:47         ` Rao, Nikhil
@ 2017-07-06 21:52           ` Nikhil Rao
  2017-07-06 14:18             ` Jerin Jacob
                               ` (2 more replies)
  0 siblings, 3 replies; 41+ messages in thread
From: Nikhil Rao @ 2017-07-06 21:52 UTC (permalink / raw)
  To: jerin.jacob
  Cc: gage.eads, dev, thomas, bruce.richardson, harry.van.haaren,
	hemant.agrawal, nipun.gupta, narender.vangati, Nikhil Rao,
	Abhinandan Gujjar

Eventdev-based networking applications require a component to dequeue
packets from NIC Rx queues and inject them into eventdev queues[1]. While
some platforms (e.g. Cavium Octeontx) do this operation in hardware, other
platforms use software.

This patchset introduces an ethernet Rx event adapter that dequeues packets
from ethernet devices and enqueues them to event devices. It is based on
a previous RFC[2].

The adapter is designed to work with the EAL service core[3]. If
an application determines that the adapter is required, it can register and
launch it on a service core. Alternatively, this adapter can serve as a
template for applications to design customer ethernet Rx event adapters
better suited to their needs.

The adapter can service multiple ethernet devices and queues. Each queue is
configured with a servicing weight to control the relative frequency with
which the adapter polls the queue, and the event fields to use when
constructing packet events. The adapter has two modes for programming an
event's flow ID: use a static per-queue user-specified value or use the RSS
hash.

A detailed description of the adapter is contained in the header's
comments.

[1] http://dpdk.org/ml/archives/dev/2017-May/065341.html
[2] http://dpdk.org/ml/archives/dev/2017-May/065539.html
[3] http://dpdk.org/ml/archives/dev/2017-July/069782.html

Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
Signed-off-by: Gage Eads <gage.eads@intel.com>
Signed-off-by: Abhinandan Gujjar <abhinandan.gujjar@intel.com>
---

v2:
Thanks Jerin for review - below is a list of changes you
suggested.

- all public symbols are started with rte_event_.
- Add Doxygen reference with @see.
- Mention setting of ev.event_type.
- Mention adapter to service function mapping.
- Remove rte_eth_rx_event_adapter_dev_add/del().
- Change rx_queuee_id to int32_t and use -1 to denote all Rx queues.
- Add rte_eth_event_rx_queue_del().

Other changes
- Remove adapter's run function (rte_event_eth_rx_adapter_run()) from
  the public interface. The adapter internally uses it to create a
  service.
- Add a blocked cycle count to stats. Further description is contained
  in the header.
- Minor struct renames rte_event_eth_rx_adapter_config -> .._conf
---
 lib/librte_eventdev/rte_event_eth_rx_adapter.h | 301 +++++++++
 lib/librte_eventdev/rte_event_eth_rx_adapter.c | 825 +++++++++++++++++++++++++
 lib/librte_eventdev/rte_eventdev_version.map   |  13 +
 lib/Makefile                                   |   2 +-
 lib/librte_eventdev/Makefile                   |   2 +
 5 files changed, 1142 insertions(+), 1 deletion(-)
 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..5ccd0bd24
--- /dev/null
+++ b/lib/librte_eventdev/rte_event_eth_rx_adapter.h
@@ -0,0 +1,301 @@
+/*
+ *   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 ethernet Rx event adapter's role is to transfer
+ * mbufs from the ethernet receive queues managed by DPDK to an event device.
+ * The application uses the adapter APIs to configure the packet flow between
+ * the ethernet devices and event devices. The adapter is designed to work with
+ * the EAL service cores. The adapter's work can be parallelized by dividing the
+ * NIC Rx queues among multiple adapter services that run in parallel.
+ *
+ * Before using the adapter, the application needs to enumerate and configure
+ * the ethernet devices that it wishes to use. This is typically done using the
+ * following DPDK ethdev functions:
+ *  - rte_eth_dev_configure()
+ *  - rte_eth_tx_queue_setup()
+ *  - rte_eth_rx_queue_setup()
+ *  - rte_eth_dev_start()
+ *
+ * The application also configures an event device and creates event ports
+ * to interface with the event device. In addition to the event ports used by
+ * its packet processing functions, the application creates an event port
+ * to be used by this adapter.
+ *
+ * The ethernet Rx event adapter's functions are:
+ *  - rte_event_eth_rx_adapter_create()
+ *  - rte_event_eth_rx_adapter_free()
+ *  - rte_event_eth_rx_adapter_queue_add()
+ *  - rte_event_eth_rx_adapter_queue_del()
+ *  - rte_event_eth_rx_adapter_stats_get()
+ *  - rte_event_eth_rx_adapter_stats_reset()
+ *
+ * The applicaton creates an event to ethernet adapter using
+ * rte_event_eth_rx_adapter_create(). The event device and event port
+ * identifiers are passed to this function.
+ *
+ * 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.
+ *
+ * At the time of adding an ethernet device receive queue, the application can
+ * also specify a static event flow id and set the
+ * RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID bit of the rx_queue_flags
+ * member of the rte_event_eth_rx_adapter_queue_conf structure. If the
+ * RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID isn't set, the flow id is
+ * assigned the value of the RSS hash. The adapter generates the RSS hash if it
+ * hasn't been already computed by the NIC, based on source and destination
+ * IPv4/6 addresses, using the rte_softrss_be() routine included in the DPDK.
+ *
+ * The servicing weight parameter in the rte_event_eth_rx_adapter_queue_conf
+ * 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.
+ *
+ * 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 {
+	char service_name[RTE_SERVICE_NAME_MAX];
+	/**< Service name of the adapter instance, the rx adapter
+	 * launches a service core function with this name
+	 */
+	uint8_t eventdev_id;
+	/**< Event device identifier */
+	uint8_t rx_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
+	 */
+	int socket_id;
+	/**< Identifier of the NUMA socket on which the service
+	 * functions are invoked
+	 */
+};
+
+/** 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.
+	 */
+};
+
+/**
+ * Initializes the event adapter for ethernet
+ * receive. Applications are required to call this function
+ * before calling any eth receive event adapter functions
+ *
+ * @return
+ *   - 0: Success
+ *   - <0: Error code on failure
+ */
+int rte_event_eth_rx_adapter_init(void);
+
+
+/**
+ * Create a new ethernet Rx event adapter with the specified identifier.
+ * Internally this API registers a service function using the
+ * rte_service_register() API.
+ *
+ * @param adapter_id
+ *   Event adapter identifier.
+ * @param conf
+ *   Event adapter config parameters.
+ * @return
+ *   - 0: Success
+ *   - <0: Error code on failure
+ */
+int rte_event_eth_rx_adapter_create(uint8_t id,
+				    const struct rte_event_eth_rx_adapter_conf *conf);
+
+/**
+ * Free an event adapter
+ *
+ * @param id
+ *   Adapter identifier.
+ * @return
+ *   - 0: Success
+ *   - <0: Error code on failure
+ */
+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.
+ * @param conf
+ *  Additonal configuration structure.
+ * @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.
+ * @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);
+
+/**
+ * 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);
+
+#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..f7dec9ea8
--- /dev/null
+++ b/lib/librte_eventdev/rte_event_eth_rx_adapter.c
@@ -0,0 +1,825 @@
+#include <stdbool.h>
+#include <rte_cycles.h>
+#include <rte_common.h>
+#include <rte_errno.h>
+#include <rte_ethdev.h>
+#include <rte_malloc.h>
+#include <rte_service.h>
+#include <rte_service_private.h>
+#include <rte_thash.h>
+
+#include "rte_eventdev.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)
+
+/*
+ * There is an instance of this struct per polled Rx queue added to the
+ * adapter
+ */
+struct eth_rx_poll_entry {
+	uint8_t eth_dev_id;
+	uint16_t eth_rx_qid;
+};
+
+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 {
+	/* per adapter EAL service */
+	struct rte_service_spec *service;
+	/* lock to serialize config updates with service function */
+	rte_spinlock_t rx_lock;
+	/* event device identifier */
+	uint8_t eventdev_id;
+	/* event port identifier */
+	uint8_t event_port_id;
+	/* max mbufs processed in any service function invocation */
+	uint32_t max_nb_rx;
+	/* socket identifier */
+	int socket_id;
+	/** 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;
+	/** per ethernet device structure */
+	struct eth_device_info *eth_devices;
+	/* Weighted round robin schedule */
+	uint32_t *wrr_sched;
+	/* Size of wrr[] */
+	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;
+} __rte_cache_aligned;
+
+
+/* Per eth device */
+struct eth_device_info {
+	struct rte_eth_dev *dev;
+	struct eth_rx_queue_info *rx_queue;
+};
+
+/* Per Rx queue */
+struct eth_rx_queue_info {
+	bool 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 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;
+}
+
+/* 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("eth_rx_poll",
+					     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;
+
+			nb_rx_queues =
+			    rx_adapter->eth_devices[d].dev->data->nb_rx_queues;
+			for (q = 0; q < nb_rx_queues; q++) {
+				struct eth_rx_queue_info *queue_info;
+				queue_info = &rx_adapter->eth_devices[d].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("eth_rx_wrr",
+					    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;
+}
+
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+#define BE_16(x)	(uint16_t)((x) >> 8 | (x) << 8)
+#else
+#define BE_16(x)	(x)
+#endif
+
+#define NETWORK_ORDER(x) BE_16(x)
+
+static inline void
+mtoip(struct rte_mbuf *m, struct ipv4_hdr **ipv4_hdr,
+	struct ipv6_hdr **ipv6_hdr)
+{
+	struct ether_hdr *eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+	struct vlan_hdr *vlan_hdr;
+
+	*ipv4_hdr = NULL;
+	*ipv6_hdr = NULL;
+
+	switch (eth_hdr->ether_type) {
+	case NETWORK_ORDER(ETHER_TYPE_IPv4):
+		*ipv4_hdr = (struct ipv4_hdr *)(eth_hdr + 1);
+		break;
+
+	case NETWORK_ORDER(ETHER_TYPE_IPv6):
+		*ipv6_hdr = (struct ipv6_hdr *)(eth_hdr + 1);
+		break;
+
+	case NETWORK_ORDER(ETHER_TYPE_VLAN):
+		vlan_hdr = (struct vlan_hdr *)(eth_hdr + 1);
+		switch (vlan_hdr->eth_proto) {
+		case NETWORK_ORDER(ETHER_TYPE_IPv4):
+			*ipv4_hdr = (struct ipv4_hdr *)(vlan_hdr + 1);
+			break;
+		case NETWORK_ORDER(ETHER_TYPE_IPv6):
+			*ipv6_hdr = (struct ipv6_hdr *)(vlan_hdr + 1);
+			break;
+		default:
+			break;
+		}
+		break;
+
+	default:
+		break;
+	}
+}
+
+/* Calculate RSS hash for IPv4/6 */
+static inline uint32_t
+do_softrss(struct rte_mbuf *m)
+{
+	uint32_t input_len;
+	void *tuple;
+	struct rte_ipv4_tuple ipv4_tuple;
+	struct rte_ipv6_tuple ipv6_tuple;
+	struct ipv4_hdr *ipv4_hdr;
+	struct ipv6_hdr *ipv6_hdr;
+
+	mtoip(m, &ipv4_hdr, &ipv6_hdr);
+
+	if (ipv4_hdr) {
+		ipv4_tuple.src_addr = rte_be_to_cpu_32(ipv4_hdr->src_addr);
+		ipv4_tuple.dst_addr = rte_be_to_cpu_32(ipv4_hdr->dst_addr);
+		tuple = &ipv4_tuple;
+		input_len = RTE_THASH_V4_L3_LEN;
+	} else if (ipv6_hdr) {
+		rte_thash_load_v6_addrs(ipv6_hdr,
+					(union rte_thash_tuple *)&ipv6_tuple);
+		tuple = &ipv6_tuple;
+		input_len = RTE_THASH_V6_L3_LEN;
+	} else
+		return 0;
+
+	return rte_softrss_be(tuple, input_len, rss_key_be);
+}
+
+static inline bool
+rx_enq_blocked(struct rte_event_eth_rx_adapter *rx_adapter)
+{
+	return !!rx_adapter->enq_block_count;
+}
+
+static inline void
+rx_enq_block_start_ts(struct rte_event_eth_rx_adapter *rx_adapter)
+{
+	if (rx_adapter->rx_enq_block_start_ts)
+		return;
+
+	rx_adapter->enq_block_count++;
+	if (rx_adapter->enq_block_count < BLOCK_CNT_THRESHOLD)
+		return;
+
+	rx_adapter->rx_enq_block_start_ts = rte_get_tsc_cycles();
+}
+
+static inline void
+rx_enq_block_end_ts(struct rte_event_eth_rx_adapter *rx_adapter,
+		    struct rte_event_eth_rx_adapter_stats *stats)
+{
+	if (unlikely(!stats->rx_enq_start_ts))
+		stats->rx_enq_start_ts = rte_get_tsc_cycles();
+
+	if (likely(!rx_enq_blocked(rx_adapter)))
+		return;
+
+	rx_adapter->enq_block_count = 0;
+	if (rx_adapter->rx_enq_block_start_ts) {
+		stats->rx_enq_end_ts = rte_get_tsc_cycles();
+		stats->rx_enq_block_cycles += stats->rx_enq_end_ts -
+		    rx_adapter->rx_enq_block_start_ts;
+		rx_adapter->rx_enq_block_start_ts = 0;
+	}
+}
+
+/* Add event to buffer, free space check is done prior to calling
+ * this function
+ */
+static inline void
+buf_event_enqueue(struct rte_event_eth_rx_adapter *rx_adapter,
+		  struct rte_event *ev)
+{
+	struct rte_eth_event_enqueue_buffer *buf =
+	    &rx_adapter->event_enqueue_buffer;
+	rte_memcpy(&buf->events[buf->count++], ev, sizeof(struct rte_event));
+}
+
+/* Enqueue buffered events to event device */
+static inline int
+flush_event_buffer(uint8_t id)
+{
+	struct rte_event_eth_rx_adapter *rx_adapter =
+	    rte_event_eth_rx_adapter[id];
+	struct rte_eth_event_enqueue_buffer *buf =
+	    &rx_adapter->event_enqueue_buffer;
+	struct rte_event_eth_rx_adapter_stats *stats = &rx_adapter->stats;
+
+	int n = rte_event_enqueue_burst(rx_adapter->eventdev_id,
+					rx_adapter->event_port_id,
+					buf->events,
+					buf->count);
+
+	if (n != buf->count) {
+		memmove(buf->events,
+			&buf->events[n],
+			(buf->count - n) * sizeof(struct rte_event));
+		stats->rx_enq_retry++;
+	}
+	buf->count -= n;
+	stats->rx_enq_count += n;
+
+	return n;
+}
+
+static inline void
+fill_event_buffer(uint8_t id, uint8_t dev_id,
+		  uint16_t rx_queue_id, struct rte_mbuf **mbufs, uint16_t num)
+{
+	uint32_t i;
+	struct rte_event_eth_rx_adapter *rx_adapter =
+	    rte_event_eth_rx_adapter[id];
+	struct eth_device_info *eth_device_info =
+	    &rx_adapter->eth_devices[dev_id];
+	struct eth_rx_queue_info *eth_rx_queue_info =
+	    &eth_device_info->rx_queue[rx_queue_id];
+
+	int32_t qid = eth_rx_queue_info->event_queue_id;
+	uint8_t sched_type = eth_rx_queue_info->sched_type;
+	uint8_t priority = eth_rx_queue_info->priority;
+	uint32_t flow_id;
+	struct rte_event events[BATCH_SIZE];
+	struct rte_mbuf *m = mbufs[0];
+	uint32_t rss_mask;
+	uint32_t rss;
+	int do_rss;
+
+	/* 0xffff ffff if PKT_RX_RSS_HASH is set, otherwise 0 */
+	rss_mask = ~(((m->ol_flags & PKT_RX_RSS_HASH) != 0) - 1);
+	do_rss = !rss_mask && !eth_rx_queue_info->flow_id_mask;
+
+	for (i = 0; i < num; i++) {
+		m = mbufs[i];
+		struct rte_event *ev = &events[i];
+
+		rss = do_rss ? do_softrss(m) : m->hash.rss;
+		flow_id =
+		    eth_rx_queue_info->flow_id &
+				eth_rx_queue_info->flow_id_mask;
+		flow_id |= rss & ~eth_rx_queue_info->flow_id_mask;
+
+		ev->flow_id = flow_id;
+		ev->op = RTE_EVENT_OP_NEW;
+		ev->sched_type = sched_type;
+		ev->queue_id = qid;
+		ev->event_type = RTE_EVENT_TYPE_ETHDEV;
+		ev->sub_event_type = 0;
+		ev->priority = priority;
+		ev->mbuf = m;
+
+		buf_event_enqueue(rx_adapter, ev);
+	}
+}
+
+/*
+ * Polls receive queues added to the event adapter and enqueues received
+ * packets to the event device.
+ *
+ * The receive code enqueues initially to a temporary buffer, the
+ * temporary buffer is drained anytime it holds >= BATCH_SIZE packets
+ *
+ * If there isn't space available in the temporary buffer, packets from the
+ * Rx queue arent dequeued from the eth device, this backpressures the
+ * eth device, in virtual device enviroments this backpressure is relayed to the
+ * hypervisor's switching layer where adjustments can be made to deal with
+ * it.
+ */
+static inline unsigned int
+eth_rx_poll(uint8_t id)
+{
+	unsigned int num_queue;
+	uint16_t n;
+	unsigned int nb_rx = 0;
+	struct rte_mbuf *mbufs[BATCH_SIZE];
+	struct rte_event_eth_rx_adapter *rx_adapter;
+	struct rte_eth_event_enqueue_buffer *buf;
+	unsigned int wrr_pos;
+	unsigned int max_nb_rx;
+
+	rx_adapter = rte_event_eth_rx_adapter[id];
+	wrr_pos = rx_adapter->wrr_pos;
+	max_nb_rx = rx_adapter->max_nb_rx;
+	buf = &rx_adapter->event_enqueue_buffer;
+	struct rte_event_eth_rx_adapter_stats *stats = &rx_adapter->stats;
+
+	/* Iterate through a WRR sequence */
+	for (num_queue = 0; num_queue < rx_adapter->wrr_len; num_queue++) {
+		unsigned int poll_idx = rx_adapter->wrr_sched[wrr_pos];
+		uint16_t qid = rx_adapter->eth_rx_poll[poll_idx].eth_rx_qid;
+		uint8_t d = rx_adapter->eth_rx_poll[poll_idx].eth_dev_id;
+
+		/* Don't do a batch dequeue from the rx queue if there isn't
+		 * enough space in the enqueue buffer.
+		 */
+		if (buf->count >= BATCH_SIZE)
+			flush_event_buffer(id);
+		if (BATCH_SIZE > (ETH_EVENT_BUFFER_SIZE - buf->count))
+			break;
+
+		stats->rx_poll_count++;
+		n = rte_eth_rx_burst(d, qid, mbufs, BATCH_SIZE);
+
+		if (n) {
+			stats->rx_packets += n;
+			/* The check before rte_eth_rx_burst() ensures that
+			 * all n mbufs can be buffered
+			 */
+			fill_event_buffer(id, d, qid, mbufs, n);
+			nb_rx += n;
+			if (nb_rx > max_nb_rx) {
+				rx_adapter->wrr_pos =
+				    (wrr_pos + 1) % rx_adapter->wrr_len;
+				return nb_rx;
+			}
+		}
+
+		if (++wrr_pos == rx_adapter->wrr_len)
+			wrr_pos = 0;
+	}
+
+	return nb_rx;
+}
+
+static int
+event_eth_rx_adapter_service_func(void *args)
+{
+	uint8_t id = (uint8_t) (uintptr_t) args;
+	struct rte_event_eth_rx_adapter *rx_adapter;
+	struct rte_eth_event_enqueue_buffer *buf;
+	unsigned int nb_rx;
+
+	rx_adapter = rte_event_eth_rx_adapter[id];
+	buf = &rx_adapter->event_enqueue_buffer;
+	if (!rte_spinlock_trylock(&rx_adapter->rx_lock))
+		return 0;
+
+	nb_rx = eth_rx_poll(id);
+
+	if (!nb_rx && buf->count)
+		flush_event_buffer(id);
+	rte_spinlock_unlock(&rx_adapter->rx_lock);
+
+	return 0;
+}
+
+int rte_event_eth_rx_adapter_init(void)
+{
+	const char *name = "rte_event_eth_rx_adapter_array";
+	unsigned sz;
+	const struct rte_memzone *mz;
+
+	sz = sizeof(*rte_event_eth_rx_adapter) *
+	    RTE_MAX_EVENT_ETH_RX_ADAPTER_INSTANCE;
+	sz = RTE_ALIGN(sz, RTE_CACHE_LINE_SIZE);
+	sz += RTE_ALIGN(sizeof(default_rss_key), RTE_CACHE_LINE_SIZE);
+
+	if (rte_eal_process_type() == RTE_PROC_SECONDARY)
+		mz = rte_memzone_lookup(name);
+	else {
+		mz = rte_memzone_reserve_aligned(name, sz, rte_socket_id(), 0,
+						 RTE_CACHE_LINE_SIZE);
+		if (mz)
+			memset(mz->addr, 0, sz);
+	}
+
+	if (!mz) {
+		RTE_LOG(ERR, EVENTDEV, "%s() failed to reserve memzeone err = %d\n",
+			__func__, rte_errno);
+		return -rte_errno;
+	}
+
+	rte_event_eth_rx_adapter = mz->addr;
+	rss_key_be = (void *)&rte_event_eth_rx_adapter[RTE_MAX_EVENT_ETH_RX_ADAPTER_INSTANCE];
+	rss_key_be = RTE_PTR_ALIGN(rss_key_be, RTE_CACHE_LINE_SIZE);
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_convert_rss_key((uint32_t *)default_rss_key,
+				    (uint32_t *)rss_key_be,
+				    RTE_DIM(default_rss_key));
+	return 0;
+}
+
+int rte_event_eth_rx_adapter_create(uint8_t id,
+				    const struct rte_event_eth_rx_adapter_conf *conf)
+{
+	struct rte_event_eth_rx_adapter *rx_adapter;
+	uint8_t i;
+	int ret;
+
+	rx_adapter = rte_event_eth_rx_adapter[id];
+
+	if (!valid_id(id) || !conf)
+		return -EINVAL;
+	if (rte_event_eth_rx_adapter[id]) {
+		return -EEXIST;
+	}
+
+	const int socket_id = conf->socket_id;
+	rx_adapter = rte_zmalloc_socket("eth_devices", sizeof(*rx_adapter),
+					RTE_CACHE_LINE_SIZE, socket_id);
+	if (!rx_adapter)
+		return -ENOMEM;
+
+	memset(rx_adapter, 0, sizeof(struct rte_event_eth_rx_adapter));
+	rx_adapter->eventdev_id = conf->eventdev_id;
+	rx_adapter->event_port_id = conf->rx_event_port_id;
+	rx_adapter->max_nb_rx = conf->max_nb_rx;
+	rx_adapter->socket_id = socket_id;
+	rx_adapter->eth_devices = rte_zmalloc_socket("eth_devices",
+						     rte_eth_dev_count() *
+						     sizeof(struct
+							    eth_device_info), 0,
+						     socket_id);
+	if (!rx_adapter->eth_devices) {
+		rte_free(rx_adapter);
+		return -ENOMEM;
+	}
+	rte_spinlock_init(&rx_adapter->rx_lock);
+
+	for (i = 0; i < rte_eth_dev_count(); i++) {
+		rx_adapter->eth_devices[i].dev = &rte_eth_devices[i];
+		rx_adapter->eth_devices[i].rx_queue =
+		    rte_zmalloc_socket("eth_devices",
+				       rte_eth_devices[i].data->nb_rx_queues *
+				       sizeof(struct eth_rx_queue_info), 0,
+				       socket_id);
+		if (!rx_adapter->eth_devices[i].rx_queue) {
+			ret = -ENOMEM;
+			goto done;
+		}
+	}
+
+	struct rte_service_spec service;
+	memset(&service, 0, sizeof(service));
+	snprintf(service.name, RTE_SERVICE_NAME_MAX, "%s", conf->service_name);
+	service.socket_id = socket_id;
+	service.callback = event_eth_rx_adapter_service_func;
+	service.callback_userdata = (void *)(uintptr_t) id;
+	/* Service function handles locking for queue add/del updates */
+	service.capabilities = RTE_SERVICE_CAP_MT_SAFE;
+	ret = rte_service_register(&service);
+	if (!ret) {
+		rx_adapter->service = rte_service_get_by_name(service.name);
+		rte_event_eth_rx_adapter[id] = rx_adapter;
+	}
+
+ done:
+	if (ret && rx_adapter->eth_devices) {
+		uint8_t j;
+		for (j = 0; j < i; j++)
+			rte_free(rx_adapter->eth_devices[j].rx_queue);
+		rte_free(rx_adapter->eth_devices);
+		rx_adapter->eth_devices = NULL;
+	}
+
+	return ret;
+}
+
+int rte_event_eth_rx_adapter_free(uint8_t id)
+{
+	struct rte_event_eth_rx_adapter *rx_adapter;
+	uint32_t i;
+	int ret;
+
+	rx_adapter = rte_event_eth_rx_adapter[id];
+	if (!valid_id(id) || !rte_event_eth_rx_adapter || !rx_adapter)
+		return -EINVAL;
+
+	ret = rte_service_unregister(rx_adapter->service);
+	if (!ret) {
+		RTE_LOG(ERR, EVENTDEV, "%s() failed to unregister service err = %d\n",
+			__func__, ret);
+	}
+
+	for (i = 0; i < rte_eth_dev_count(); i++)
+			rte_free(rx_adapter->eth_devices[i].rx_queue);
+
+	rte_free(rx_adapter->eth_rx_poll);
+	rte_free(rx_adapter->wrr_sched);
+	rte_free(rx_adapter->eth_devices);
+	rte_free(rx_adapter);
+	rte_event_eth_rx_adapter[id] = NULL;
+
+	return ret;
+}
+
+static int
+_rte_event_eth_rx_adapter_queue_del(struct rte_event_eth_rx_adapter *rx_adapter,
+				    struct eth_device_info *dev_info,
+				    uint16_t rx_queue_id)
+{
+	struct eth_rx_queue_info *queue_info;
+
+	queue_info = &dev_info->rx_queue[rx_queue_id];
+	if (rx_queue_id >= dev_info->dev->data->nb_rx_queues ||
+	    !queue_info->queue_enabled)
+		return -EINVAL;
+
+	rx_adapter->num_rx_polled--;
+	queue_info->queue_enabled = false;
+
+	return 0;
+}
+
+static int
+_rte_event_eth_rx_adapter_queue_add(struct rte_event_eth_rx_adapter *rx_adapter,
+				    struct eth_device_info *dev_info,
+				    uint16_t rx_queue_id,
+				    const struct rte_event_eth_rx_adapter_queue_conf *conf)
+{
+	int ret;
+	struct eth_rx_queue_info *queue_info;
+	const struct rte_event *ev;
+
+	if (rx_queue_id >= dev_info->dev->data->nb_rx_queues)
+		return -EINVAL;
+
+	queue_info = &dev_info->rx_queue[rx_queue_id];
+	if (queue_info->queue_enabled)
+		return -EEXIST;
+
+	ev = &conf->ev;
+	memset(queue_info, 0, sizeof(*queue_info));
+	queue_info->event_queue_id = ev->queue_id;
+	queue_info->sched_type = ev->sched_type;
+	queue_info->priority = ev->priority;
+	queue_info->wt = conf->servicing_weight;
+
+	if (queue_info->wt == 0) {
+		struct rte_eth_dev_data *data = dev_info->dev->data;
+
+		/* If Rx interrupts are disabled set wt = 1 */
+		queue_info->wt = !data->dev_conf.intr_conf.rxq;
+	}
+
+	if (conf->
+	    rx_queue_flags & RTE_EVENT_ETH_RX_ADAPTER_QUEUE_FLOW_ID_VALID) {
+		queue_info->flow_id = ev->flow_id;
+		queue_info->flow_id_mask = ~0;
+	}
+
+	queue_info->queue_enabled = true;
+	rx_adapter->num_rx_polled++;
+	ret = eth_poll_wrr_calc(rx_adapter);
+	if (ret) {
+		rx_adapter->num_rx_polled--;
+		queue_info->queue_enabled = false;
+		return ret;
+	}
+
+	return 0;
+}
+
+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)
+{
+	int ret = 0;
+	struct rte_event_eth_rx_adapter *rx_adapter;
+	struct eth_device_info *dev_info;
+	uint32_t i, j;
+
+	rx_adapter = rte_event_eth_rx_adapter[id];
+	if (!valid_id(id) || !rte_event_eth_rx_adapter || !rx_adapter ||
+	    eth_dev_id >= rte_eth_dev_count() || !conf)
+		return -EINVAL;
+
+	rte_spinlock_lock(&rx_adapter->rx_lock);
+
+	dev_info = &rx_adapter->eth_devices[eth_dev_id];
+	if (rx_queue_id == -1) {
+		for (i = 0; i < dev_info->dev->data->nb_rx_queues; i++) {
+			ret =
+			    _rte_event_eth_rx_adapter_queue_add(rx_adapter, dev_info, i,
+								conf);
+			if (ret) {
+				for (j = 0; j < i; j++)
+					_rte_event_eth_rx_adapter_queue_del(rx_adapter,
+									    dev_info,
+									    j);
+			}
+		}
+
+	} else {
+		ret = _rte_event_eth_rx_adapter_queue_add(rx_adapter, dev_info,
+							  (uint16_t)rx_queue_id,
+							  conf);
+	}
+
+	rte_spinlock_unlock(&rx_adapter->rx_lock);
+
+	return ret;
+}
+
+int rte_event_eth_rx_adapter_queue_del(uint8_t id, uint8_t eth_dev_id,
+				       int32_t rx_queue_id)
+{
+	int ret = 0;
+	struct rte_event_eth_rx_adapter *rx_adapter;
+	struct eth_device_info *dev_info;
+	unsigned int i;
+
+	rx_adapter = rte_event_eth_rx_adapter[id];
+	if (!valid_id(id) || !rte_event_eth_rx_adapter || !rx_adapter ||
+	    eth_dev_id >= rte_eth_dev_count())
+		return -EINVAL;
+
+	rte_spinlock_lock(&rx_adapter->rx_lock);
+
+	dev_info = &rx_adapter->eth_devices[eth_dev_id];
+	if (rx_queue_id == -1) {
+		for (i = 0; i < dev_info->dev->data->nb_rx_queues; i++) {
+			ret =
+			    _rte_event_eth_rx_adapter_queue_del(rx_adapter, dev_info,
+								i);
+			if (ret)
+				break;
+		}
+	} else {
+		ret = _rte_event_eth_rx_adapter_queue_del(rx_adapter, dev_info,
+							  (uint16_t)rx_queue_id);
+	}
+
+	rte_spinlock_unlock(&rx_adapter->rx_lock);
+
+	return ret;
+}
+
+int rte_event_eth_rx_adapter_stats_get(uint8_t id,
+				       struct rte_event_eth_rx_adapter_stats *stats)
+{
+	struct rte_event_eth_rx_adapter *rx_adapter;
+
+	rx_adapter = rte_event_eth_rx_adapter[id];
+	if (!valid_id(id) || !rte_event_eth_rx_adapter || !rx_adapter || !stats)
+		return -EINVAL;
+	*stats = rx_adapter->stats;
+	return 0;
+}
+
+int rte_event_eth_rx_adapter_stats_reset(uint8_t id)
+{
+	struct rte_event_eth_rx_adapter *rx_adapter;
+
+	rx_adapter = rte_event_eth_rx_adapter[id];
+	if (!valid_id(id) || !rte_event_eth_rx_adapter || !rx_adapter)
+		return -EINVAL;
+	memset(&rx_adapter->stats, 0, sizeof(rx_adapter->stats));
+	return 0;
+}
diff --git a/lib/librte_eventdev/rte_eventdev_version.map b/lib/librte_eventdev/rte_eventdev_version.map
index 1fa6b333f..5008264ac 100644
--- a/lib/librte_eventdev/rte_eventdev_version.map
+++ b/lib/librte_eventdev/rte_eventdev_version.map
@@ -42,3 +42,16 @@ DPDK_17.05 {
 
 	local: *;
 };
+
+DPDK_17.08 {
+	global:
+
+	rte_event_eth_rx_adapter_init;
+	rte_event_eth_rx_adapter_create;
+	rte_event_eth_rx_adapter_free;
+	rte_event_eth_rx_adapter_queue_add;
+	rte_event_eth_rx_adapter_queue_del;
+	rte_event_eth_rx_adapter_stats_get;
+	rte_event_eth_rx_adapter_stats_reset;
+
+} DPDK_17.05;
diff --git a/lib/Makefile b/lib/Makefile
index 07e1fd0c5..c39c8b16d 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -52,7 +52,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += librte_cryptodev
 DEPDIRS-librte_cryptodev := librte_eal librte_mempool librte_ring librte_mbuf
 DEPDIRS-librte_cryptodev += librte_kvargs
 DIRS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += librte_eventdev
-DEPDIRS-librte_eventdev := librte_eal
+DEPDIRS-librte_eventdev := librte_eal librte_hash librte_ether
 DIRS-$(CONFIG_RTE_LIBRTE_VHOST) += librte_vhost
 DEPDIRS-librte_vhost := librte_eal librte_mempool librte_mbuf librte_ether
 DIRS-$(CONFIG_RTE_LIBRTE_HASH) += librte_hash
diff --git a/lib/librte_eventdev/Makefile b/lib/librte_eventdev/Makefile
index 629069ad6..496bd73b1 100644
--- a/lib/librte_eventdev/Makefile
+++ b/lib/librte_eventdev/Makefile
@@ -42,12 +42,14 @@ CFLAGS += $(WERROR_FLAGS)
 
 # library source files
 SRCS-y += rte_eventdev.c
+SRCS-y += rte_event_eth_rx_adapter.c
 
 # export include files
 SYMLINK-y-include += rte_eventdev.h
 SYMLINK-y-include += rte_eventdev_pmd.h
 SYMLINK-y-include += rte_eventdev_pmd_pci.h
 SYMLINK-y-include += rte_eventdev_pmd_vdev.h
+SYMLINK-y-include += rte_event_eth_rx_adapter.h
 
 # versioning export map
 EXPORT_MAP := rte_eventdev_version.map
-- 
2.11.0.rc1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 2/2] eventdev: add event eth rx adapter unit tests
  2017-07-06 21:52           ` [PATCH 1/2] " Nikhil Rao
  2017-07-06 14:18             ` Jerin Jacob
@ 2017-07-06 21:52             ` Nikhil Rao
  2017-07-24 10:10             ` [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues Nipun Gupta
  2 siblings, 0 replies; 41+ messages in thread
From: Nikhil Rao @ 2017-07-06 21:52 UTC (permalink / raw)
  To: jerin.jacob
  Cc: gage.eads, dev, thomas, bruce.richardson, harry.van.haaren,
	hemant.agrawal, nipun.gupta, narender.vangati, Nikhil Rao

Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
---
 test/test/test_event_eth_rx_adapter.c | 276 ++++++++++++++++++++++++++++++++++
 test/test/Makefile                    |   1 +
 2 files changed, 277 insertions(+)
 create mode 100644 test/test/test_event_eth_rx_adapter.c

diff --git a/test/test/test_event_eth_rx_adapter.c b/test/test/test_event_eth_rx_adapter.c
new file mode 100644
index 000000000..881313240
--- /dev/null
+++ b/test/test/test_event_eth_rx_adapter.c
@@ -0,0 +1,276 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. 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.
+ */
+#include <string.h>
+#include <rte_common.h>
+#include <rte_mempool.h>
+#include <rte_mbuf.h>
+#include <rte_ethdev.h>
+#include <rte_eventdev.h>
+
+#include <rte_event_eth_rx_adapter.h>
+
+#include "test.h"
+
+struct rte_mempool *mp;
+
+static inline int
+port_init(uint8_t port, struct rte_mempool *mp)
+{
+	static const struct rte_eth_conf port_conf_default = {
+		.rxmode = {
+			.mq_mode = ETH_MQ_RX_RSS,
+			.max_rx_pkt_len = ETHER_MAX_LEN
+		},
+		.rx_adv_conf = {
+			.rss_conf = {
+				.rss_hf = ETH_RSS_IP |
+					  ETH_RSS_TCP |
+					  ETH_RSS_UDP,
+			}
+		}
+	};
+	const uint16_t rx_rings = 1, tx_rings = 1;
+	const uint16_t rx_ring_size = 512, tx_ring_size = 512;
+	struct rte_eth_conf port_conf = port_conf_default;
+	int retval;
+	uint16_t q;
+
+	if (port >= rte_eth_dev_count())
+		return -1;
+
+	/* Configure the Ethernet device. */
+	retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
+	if (retval != 0)
+		return retval;
+
+	/* Allocate and set up 1 RX queue per Ethernet port. */
+	for (q = 0; q < rx_rings; q++) {
+		retval = rte_eth_rx_queue_setup(port, q, rx_ring_size,
+				rte_eth_dev_socket_id(port), NULL, mp);
+		if (retval < 0)
+			return retval;
+	}
+
+	/* Allocate and set up 1 TX queue per Ethernet port. */
+	for (q = 0; q < tx_rings; q++) {
+		retval = rte_eth_tx_queue_setup(port, q, tx_ring_size,
+				rte_eth_dev_socket_id(port), NULL);
+		if (retval < 0)
+			return retval;
+	}
+
+	/* Start the Ethernet port. */
+	retval = rte_eth_dev_start(port);
+	if (retval < 0)
+		return retval;
+
+	/* Display the port MAC address. */
+	struct ether_addr addr;
+	rte_eth_macaddr_get(port, &addr);
+	printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8
+			   " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n",
+			(unsigned int)port,
+			addr.addr_bytes[0], addr.addr_bytes[1],
+			addr.addr_bytes[2], addr.addr_bytes[3],
+			addr.addr_bytes[4], addr.addr_bytes[5]);
+
+	/* Enable RX in promiscuous mode for the Ethernet device. */
+	rte_eth_promiscuous_enable(port);
+
+	return 0;
+}
+
+static int
+init_ports(int num_ports)
+{
+	uint8_t portid;
+
+	mp = rte_pktmbuf_pool_create("packet_pool",
+			/* mbufs */ 16384 * num_ports,
+			/* cache_size */ 512,
+			/* priv_size*/ 0,
+			/* data_room_size */ RTE_MBUF_DEFAULT_BUF_SIZE,
+			rte_socket_id());
+
+	for (portid = 0; portid < num_ports; portid++)
+		if (port_init(portid, mp) != 0)
+			rte_exit(EXIT_FAILURE, "Cannot init port %"PRIu8 "\n",
+				portid);
+
+	return 0;
+}
+
+static int
+testsuite_setup(void)
+{
+	int err;
+	err = init_ports(rte_eth_dev_count());
+	TEST_ASSERT(err == 0, "Port initialization failed err %d\n", err);
+	err = rte_event_eth_rx_adapter_init();
+	TEST_ASSERT(err == 0, "Event adapter initalization failed err %d\n", err);
+	return TEST_SUCCESS;
+}
+
+static void
+testsuite_teardown(void)
+{
+	uint32_t i;
+	rte_mempool_free(mp);
+	for (i = 0; i < rte_eth_dev_count(); i++)
+		rte_eth_dev_stop(i);
+}
+
+static int adapter_create(void)
+{
+	struct rte_event_eth_rx_adapter_conf config = {
+		.eventdev_id = 0,
+		.rx_event_port_id = 0,
+		.max_nb_rx = 128,
+		.socket_id = 0
+	};
+
+	snprintf(config.service_name, RTE_SERVICE_NAME_MAX, "%s", "rx_adapter");
+	int err = rte_event_eth_rx_adapter_create(0, &config);
+	TEST_ASSERT(err == 0, "Expected 0 got %d", err);
+
+	return err;
+}
+
+static void adapter_free(void)
+{
+	rte_event_eth_rx_adapter_free(0);
+}
+
+static int
+adapter_create_free(void)
+{
+	int err;
+	struct rte_event_eth_rx_adapter_conf config = {
+		.eventdev_id = 0,
+		.rx_event_port_id = 0,
+		.max_nb_rx = 128,
+		.socket_id = 0
+	};
+
+	snprintf(config.service_name, RTE_SERVICE_NAME_MAX, "%s", "rx_adapter");
+	err = rte_event_eth_rx_adapter_create(0, NULL);
+	TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err);
+
+	err = rte_event_eth_rx_adapter_create(0, &config);
+	TEST_ASSERT(err == 0, "Expected 0 got %d", err);
+
+	err = rte_event_eth_rx_adapter_create(0, &config);
+	TEST_ASSERT(err == -EEXIST, "Expected -EEXIST %d got %d", -EEXIST, err);
+
+	err = rte_event_eth_rx_adapter_free(0);
+	TEST_ASSERT(err == 0, "Expected 0 got %d", err);
+
+	err = rte_event_eth_rx_adapter_free(0);
+	TEST_ASSERT(err == -EINVAL, "Expected -EINVAL %d got %d", -EINVAL, err);
+
+	err = rte_event_eth_rx_adapter_free(1);
+	TEST_ASSERT(err == -EINVAL, "Expected -EINVAL %d got %d", -EINVAL, err);
+
+	return TEST_SUCCESS;
+}
+
+static int
+adapter_queue_add_del(void)
+{
+	int err;
+	struct rte_event ev;
+
+	ev.queue_id = 0;
+	ev.sched_type = RTE_SCHED_TYPE_ATOMIC;
+	ev.priority = 0;
+
+	struct rte_event_eth_rx_adapter_queue_conf queue_config;
+
+	queue_config.ev = ev;
+	queue_config.rx_queue_flags = 0;
+	queue_config.servicing_weight = 1;
+
+	err = rte_event_eth_rx_adapter_queue_add(0, 0, -1, &queue_config);
+	TEST_ASSERT(err == 0, "Expected 0 got %d", err);
+
+	err = rte_event_eth_rx_adapter_queue_add(0, 0, -1, &queue_config);
+	TEST_ASSERT(err == -EEXIST, "Expected -EEXIST got %d", err);
+
+	err = rte_event_eth_rx_adapter_queue_add(0, 0, 0, &queue_config);
+	TEST_ASSERT(err == -EEXIST, "Expected -EEXIST got %d", err);
+
+	err = rte_event_eth_rx_adapter_queue_del(0, 0, -1);
+	TEST_ASSERT(err == 0, "Expected 0 got %d", err);
+
+	err = rte_event_eth_rx_adapter_queue_del(0, 0, -1);
+	TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err);
+
+	return TEST_SUCCESS;
+}
+
+static int
+adapter_stats(void)
+{
+	int err;
+	struct rte_event_eth_rx_adapter_stats stats;
+
+	err = rte_event_eth_rx_adapter_stats_get(0, NULL);
+	TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err);
+
+	err = rte_event_eth_rx_adapter_stats_get(0, &stats);
+	TEST_ASSERT(err == 0, "Expected 0 got %d", err);
+
+	err = rte_event_eth_rx_adapter_stats_get(1, &stats);
+	TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err);
+
+	return TEST_SUCCESS;
+}
+
+static struct unit_test_suite service_tests  = {
+	.suite_name = "rx event eth adapter test suite",
+	.setup = testsuite_setup,
+	.teardown = testsuite_teardown,
+	.unit_test_cases = {
+		TEST_CASE_ST(NULL, NULL, adapter_create_free),
+		TEST_CASE_ST(adapter_create, adapter_free, adapter_queue_add_del),
+		TEST_CASE_ST(adapter_create, adapter_free, adapter_stats),
+		TEST_CASES_END() /**< NULL terminate unit test array */
+	}
+};
+
+static int
+test_event_eth_rx_adapter_common(void)
+{
+	return unit_test_suite_runner(&service_tests);
+}
+
+REGISTER_TEST_COMMAND(event_eth_rx_adapter_autotest, test_event_eth_rx_adapter_common);
diff --git a/test/test/Makefile b/test/test/Makefile
index 61e296b69..15bd648c0 100644
--- a/test/test/Makefile
+++ b/test/test/Makefile
@@ -203,6 +203,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev.c
 
 ifeq ($(CONFIG_RTE_LIBRTE_EVENTDEV),y)
 SRCS-y += test_eventdev.c
+SRCS-y += test_event_eth_rx_adapter.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += test_eventdev_sw.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_OCTEONTX_SSOVF) += test_eventdev_octeontx.c
 endif
-- 
2.11.0.rc1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-07-06 14:18             ` Jerin Jacob
@ 2017-07-07  6:21               ` Rao, Nikhil
  2017-07-07 15:03                 ` Jerin Jacob
  0 siblings, 1 reply; 41+ messages in thread
From: Rao, Nikhil @ 2017-07-07  6:21 UTC (permalink / raw)
  To: Jerin Jacob
  Cc: gage.eads, dev, thomas, bruce.richardson, harry.van.haaren,
	hemant.agrawal, nipun.gupta, narender.vangati, Abhinandan Gujjar

On 7/6/2017 7:48 PM, Jerin Jacob wrote:
> -----Original Message-----
>> Date: Fri, 7 Jul 2017 03:22:31 +0530
>> From: Nikhil Rao <nikhil.rao@intel.com>
>> To: jerin.jacob@caviumnetworks.com
>> CC: gage.eads@intel.com, dev@dpdk.org, thomas@monjalon.net,
>>   bruce.richardson@intel.com, harry.van.haaren@intel.com,
>>   hemant.agrawal@nxp.com, nipun.gupta@nxp.com, narender.vangati@intel.com,
>>   Nikhil Rao <nikhil.rao@intel.com>, Abhinandan Gujjar
>>   <abhinandan.gujjar@intel.com>
>> Subject: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
>> X-Mailer: git-send-email 2.7.4
>>
>> Signed-off-by: Abhinandan Gujjar <abhinandan.gujjar@intel.com>
>> ---
<sniped>
> 
> Thanks Nikhil for the patch.
> 
> Looks like you missed this email?
> http://dpdk.org/ml/archives/dev/2017-June/068142.html
> 
> Can we make it as function pointer based approach(keeping all adapter functions
> function prototype required for SW PMD) so that each PMD
> can register the ops for adapter_create etc so that same API can be used
> for software and hardware PMDs(the scheme like rte_flow() or rte_tm()
> approach)
> 
> Can discuss more on that to finalize the approach?
>>Yes, I did miss that email :-( (I am including the relevant extract below)

 >
 > /* adapter has inbuilt port, no need to create producer port */
 > #define RTE_EVENT_ETHDEV_CAP_INBUILT_PORT  (1ULL << 0)
 > /* adapter does not need service function */
 > #define RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC (1ULL << 1)
 >
 > struct rte_event_eth_rx_adap_info {
 > 	char name[32];
 >          uint32_t adapter_cap;
 >          /**< Ethdev RX adapter capabilities(RTE_EVENT_ETHDEV_CAP_)*/
 > }
 >
 >
 > struct rte_event_eth_rx_adap_cfg {
 > 	uint8_t rx_event_port_id;
 >         /**< Event port identifier, the adapter enqueues mbuf events 
to this
 >          * port, Ignored when RTE_EVENT_ETHDEV_CAP_INBUILT_PORT
 >          */
 >
 > }
 >
 > struct rte_eth_rx_event_adapter_queue_config {
 >         uint32_t rx_queue_flags;
 >          /**< Flags for handling received packets */
 >         uint16_t servicing_weight;
 >         /**< Relative polling frequency of ethernet receive queue, if 
this
 >          * is set to zero, the Rx queue is interrupt driven
 >          * Ignored if RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC set
 >          */
 >         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.
 >          */
 > };
 >
 > int rte_event_eth_rx_adapter_create(uint8_t id, uint8_t dev_id, 
uint8_t eth_port_id);

 > int rte_event_eth_rx_adapter_get_info(uint8_t id, struct 
rte_event_eth_rx_adap_info *info);
 > int rte_event_eth_rx_adapter_configure(uint8_t id, struct 
rte_event_eth_rx_adap_config *cfg);
 > int rte_event_eth_rx_adapter_queue_add(uint8_t id, int32_t 
rx_queue_id, const struct rte_eth_rx_event_adapter_queue_config *config);
 > int rte_event_eth_rx_adapter_queue_del(uint8_t id, int32_t rx_queue_id)
 > int rte_event_eth_rx_adapter_run();
 > int rte_event_eth_rx_adapter_free(uint8_t id);
 >

If I understood your idea, the function pointer struct would look 
something like this.

struct rte_eventdev_rx_adapter_ops {
	rx_adapter_create_t 	create,
	rx_adapter_get_info_t	info,
	rx_adapter_configure_t	configure,
	rx_adapter_queue_add_t  queue_add,
	rx_adapter_queue_del_t	queue_del,
	rx_adapter_queue_free_t	queue_free,
         rx_adapter_free_t	free
};

struct rte_eventdev {
        ..
        const struct rte_eventdev_rx_adapter_ops *rx_adapter_ops;
        ..
};

int rte_event_eth_rx_adapter_create(uint8_t id, uint8_t dev_id, uint8_t 
eth_port_id) {
	eventdev_ops = ... /* access through dev_id */
   	void *priv;
	uint64_t cap;

	if (eventdev_ops->rx_adapter_ops) {
		rc =   	
  		eventdev_ops->rx_adapter_ops->rx_adapter_create(dev,
					&priv, eth_port_id, &caps))
	}

	if (!rc) {
		/* eventdev adapter for eth_port_id -> dev_id */
		rx_adapter[id].info.adapter_cap =           	
                          RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC | caps ;
         } else  {
		/* create SW adapter for eth_port_id->dev_id */
		rx_adapter[id].info.adapter_cap = 0;
	}
}

According to the code above rx_adapter_get_info should be able to fill 
in RTE_EVENT_ETHDEV_CAP_INBUILT_PORT after rx_adapter_create, so that 
info() can retrieve it.

But from previous emails (see struct rte_event_dev_producer_conf below), 
it appears that the rx queue id and event information would be needed to 
create the adapter that enqueues from the ethdev queue id to the event 
pmd, however that information is available only at queue add time - 
thoughts ?

+struct rte_event_dev_producer_conf {
+	uint32_t event_type:4;
+	/**< Event type to classify the event source.
+	 * @see RTE_EVENT_TYPE_ETHDEV, (RTE_EVENT_TYPE_*)
+	 */
+	uint8_t sched_type:2;
+	/**< Scheduler synchronization type (RTE_SCHED_TYPE_*)
+	 * associated with flow id on a given event queue for the enqueue
+	 * operation.
+	 */
+	uint8_t priority;
+	/**< Event priority relative to other events in the
+	 * event queue. The requested priority should in the
+	 * range of  [RTE_EVENT_DEV_PRIORITY_HIGHEST,
+	 * RTE_EVENT_DEV_PRIORITY_LOWEST].
+	 * The implementation shall normalize the requested
+	 * priority to supported priority value.
+	 * Valid when the device has
+	 * RTE_EVENT_DEV_CAP_EVENT_QOS capability.
+	 */
+	union {
+		struct rte_event_ethdev_producer {
+			uint16_t ethdev_port;
+			/**< The port identifier of the Ethernet device */
+			int32_t rx_queue_id;
+			/**< The index of the receive queue from which to
+			 * retrieve the input packets and inject to eventdev.
+			 * The value -1 denotes all the Rx queues configured
+			 * for the given ethdev_port are selected for retrieving
+			 * the input packets and then injecting the
+			 * events/packets to eventdev.
+			 * The rte_eth_rx_burst() result is undefined
+			 * if application invokes on bounded ethdev_port and
+			 * rx_queue_id.
+			 */
+		} ethdev; /* RTE_EVENT_TYPE_ETHDEV */
+		/**< Valid when event_type == RTE_EVENT_TYPE_ETHDEV.
+		 * Implementation may use mbuff's rss->hash value as
+		 * flow_id for the enqueue operation.
+		 */
+	};
+};

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-07-07  6:21               ` Rao, Nikhil
@ 2017-07-07 15:03                 ` Jerin Jacob
  2017-07-07 15:57                   ` Jerin Jacob
  0 siblings, 1 reply; 41+ messages in thread
From: Jerin Jacob @ 2017-07-07 15:03 UTC (permalink / raw)
  To: Rao, Nikhil
  Cc: gage.eads, dev, thomas, bruce.richardson, harry.van.haaren,
	hemant.agrawal, nipun.gupta, narender.vangati, Abhinandan Gujjar

-----Original Message-----
> Date: Fri, 7 Jul 2017 11:51:01 +0530
> From: "Rao, Nikhil" <nikhil.rao@intel.com>
> To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> CC: gage.eads@intel.com, dev@dpdk.org, thomas@monjalon.net,
>  bruce.richardson@intel.com, harry.van.haaren@intel.com,
>  hemant.agrawal@nxp.com, nipun.gupta@nxp.com, narender.vangati@intel.com,
>  Abhinandan Gujjar <abhinandan.gujjar@intel.com>
> Subject: Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101
>  Thunderbird/52.2.1
> 
> On 7/6/2017 7:48 PM, Jerin Jacob wrote:
> > -----Original Message-----
> > > Date: Fri, 7 Jul 2017 03:22:31 +0530
> > > From: Nikhil Rao <nikhil.rao@intel.com>
> > > To: jerin.jacob@caviumnetworks.com
> > > CC: gage.eads@intel.com, dev@dpdk.org, thomas@monjalon.net,
> > >   bruce.richardson@intel.com, harry.van.haaren@intel.com,
> > >   hemant.agrawal@nxp.com, nipun.gupta@nxp.com, narender.vangati@intel.com,
> > >   Nikhil Rao <nikhil.rao@intel.com>, Abhinandan Gujjar
> > >   <abhinandan.gujjar@intel.com>
> > > Subject: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> > > X-Mailer: git-send-email 2.7.4
> > > 
> > > Signed-off-by: Abhinandan Gujjar <abhinandan.gujjar@intel.com>
> > > ---
> <sniped>
> > 
> > Thanks Nikhil for the patch.
> > 
> > Looks like you missed this email?
> > http://dpdk.org/ml/archives/dev/2017-June/068142.html
> > 
> > Can we make it as function pointer based approach(keeping all adapter functions
> > function prototype required for SW PMD) so that each PMD
> > can register the ops for adapter_create etc so that same API can be used
> > for software and hardware PMDs(the scheme like rte_flow() or rte_tm()
> > approach)
> > 
> > Can discuss more on that to finalize the approach?
> > > Yes, I did miss that email :-( (I am including the relevant extract below)

OK.

> 
> >
> > /* adapter has inbuilt port, no need to create producer port */
> > #define RTE_EVENT_ETHDEV_CAP_INBUILT_PORT  (1ULL << 0)
> > /* adapter does not need service function */
> > #define RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC (1ULL << 1)

I just provided a name to share the view. You can choose better name.

> >
> > struct rte_event_eth_rx_adap_info {
> > 	char name[32];
> >          uint32_t adapter_cap;
> >          /**< Ethdev RX adapter capabilities(RTE_EVENT_ETHDEV_CAP_)*/
> > }
> >
> >
> > struct rte_event_eth_rx_adap_cfg {
> > 	uint8_t rx_event_port_id;
> >         /**< Event port identifier, the adapter enqueues mbuf events to
> this
> >          * port, Ignored when RTE_EVENT_ETHDEV_CAP_INBUILT_PORT
> >          */
> >
> > }
> >
> > struct rte_eth_rx_event_adapter_queue_config {
> >         uint32_t rx_queue_flags;
> >          /**< Flags for handling received packets */
> >         uint16_t servicing_weight;
> >         /**< Relative polling frequency of ethernet receive queue, if this
> >          * is set to zero, the Rx queue is interrupt driven
> >          * Ignored if RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC set
> >          */
> >         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.
> >          */
> > };
> >
> > int rte_event_eth_rx_adapter_create(uint8_t id, uint8_t dev_id, uint8_t
> eth_port_id);
> 
> > int rte_event_eth_rx_adapter_get_info(uint8_t id, struct
> rte_event_eth_rx_adap_info *info);
> > int rte_event_eth_rx_adapter_configure(uint8_t id, struct
> rte_event_eth_rx_adap_config *cfg);
> > int rte_event_eth_rx_adapter_queue_add(uint8_t id, int32_t rx_queue_id,
> const struct rte_eth_rx_event_adapter_queue_config *config);
> > int rte_event_eth_rx_adapter_queue_del(uint8_t id, int32_t rx_queue_id)
> > int rte_event_eth_rx_adapter_run();
> > int rte_event_eth_rx_adapter_free(uint8_t id);
> >
> 
> If I understood your idea, the function pointer struct would look something
> like this.
> 
> struct rte_eventdev_rx_adapter_ops {
> 	rx_adapter_create_t 	create,
> 	rx_adapter_get_info_t	info,
> 	rx_adapter_configure_t	configure,
> 	rx_adapter_queue_add_t  queue_add,
> 	rx_adapter_queue_del_t	queue_del,
> 	rx_adapter_queue_free_t	queue_free,
>       rx_adapter_free_t	free
> };

Yes. But, I think, adapter create and free goes in struct rte_eventdev_op .
See below.


> 
> struct rte_eventdev {
>        ..
>        const struct rte_eventdev_rx_adapter_ops *rx_adapter_ops;
>        ..
> };

An eventdev instance can have N adapters not just one. So this will be
pointer to pointer, indexed through adapter_id.

In SW PMD case, the eventdev may have only one adapter.
In HW PMD cases, There will more than one. example,
- if octeontx eventdev dev_id + any external PCI n/w card like i40e or
nicvf case an adapter with similar adapter ops as SW PMD
- if octeontx eventdev dev_id + octeontx ethdev dev_id case another
adapter that does not need service cores to inject event to octeontx
eventdev

- Your generic Rx adapter we will make it as common code so that both SW PMD and
octeontx PMD in service core mode as use the functions and register the
ops.


I was thinking like this

int rte_event_eth_rx_adapter_create(uint8_t id, uint8_t dev_id, uint8_t eth_port_id)
{
	eventdev_ops = ... /* access through dev_id */

	/* common code to get ops memory from adapter id */
	struct rte_eventdev_rx_adapter_ops* ops = rte_event_pmd_adapter_allocate(id);

	/* Fill in adapter ops from driver */
	eventdev_ops->create_adapter(ops, dev_id, eth_port_id)

}

int rte_event_eth_rx_adapter_get_info(uint8_t id, struct rte_event_eth_rx_adap_info *info)
{
	eventdev_ops = ... /* access through dev_id */

	struct rte_eventdev_rx_adapter_ops* ops = eventdev_ops->rx_adapter_ops[id];

	/* adapter specific info ops)
	ops->info(ops,....);

}


> 
> But from previous emails (see struct rte_event_dev_producer_conf below), it
> appears that the rx queue id and event information would be needed to create
> the adapter that enqueues from the ethdev queue id to the event pmd, however
> that information is available only at queue add time - thoughts ?

Just eventdev_id and ethdev_id is enough to create adapter.
Free feel to change the name of API or flag name etc.
Let me know if I have missed something?

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-07-07 15:03                 ` Jerin Jacob
@ 2017-07-07 15:57                   ` Jerin Jacob
  2017-07-10  6:14                     ` Rao, Nikhil
  0 siblings, 1 reply; 41+ messages in thread
From: Jerin Jacob @ 2017-07-07 15:57 UTC (permalink / raw)
  To: Rao, Nikhil
  Cc: gage.eads, dev, thomas, bruce.richardson, harry.van.haaren,
	hemant.agrawal, nipun.gupta, narender.vangati, Abhinandan Gujjar

-----Original Message-----
> Date: Fri, 7 Jul 2017 20:33:19 +0530
> From: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> To: "Rao, Nikhil" <nikhil.rao@intel.com>
> CC: gage.eads@intel.com, dev@dpdk.org, thomas@monjalon.net,
>  bruce.richardson@intel.com, harry.van.haaren@intel.com,
>  hemant.agrawal@nxp.com, nipun.gupta@nxp.com, narender.vangati@intel.com,
>  Abhinandan Gujjar <abhinandan.gujjar@intel.com>
> Subject: Re: [dpdk-dev] [PATCH 1/2] eventdev: add event adapter for
>  ethernet Rx queues
> User-Agent: Mutt/1.8.3 (2017-05-23)
> 
> -----Original Message-----
> > Date: Fri, 7 Jul 2017 11:51:01 +0530
> > From: "Rao, Nikhil" <nikhil.rao@intel.com>
> > To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> > CC: gage.eads@intel.com, dev@dpdk.org, thomas@monjalon.net,
> >  bruce.richardson@intel.com, harry.van.haaren@intel.com,
> >  hemant.agrawal@nxp.com, nipun.gupta@nxp.com, narender.vangati@intel.com,
> >  Abhinandan Gujjar <abhinandan.gujjar@intel.com>
> > Subject: Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> > User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101
> >  Thunderbird/52.2.1
> > 
> > On 7/6/2017 7:48 PM, Jerin Jacob wrote:
> > > -----Original Message-----
> > > > Date: Fri, 7 Jul 2017 03:22:31 +0530
> > > > From: Nikhil Rao <nikhil.rao@intel.com>
> > > > To: jerin.jacob@caviumnetworks.com
> > > > CC: gage.eads@intel.com, dev@dpdk.org, thomas@monjalon.net,
> > > >   bruce.richardson@intel.com, harry.van.haaren@intel.com,
> > > >   hemant.agrawal@nxp.com, nipun.gupta@nxp.com, narender.vangati@intel.com,
> > > >   Nikhil Rao <nikhil.rao@intel.com>, Abhinandan Gujjar
> > > >   <abhinandan.gujjar@intel.com>
> > > > Subject: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> > > > X-Mailer: git-send-email 2.7.4
> > > > 
> > > > Signed-off-by: Abhinandan Gujjar <abhinandan.gujjar@intel.com>
> > > > ---
> > <sniped>
> > > 
> > > Thanks Nikhil for the patch.
> > > 
> > > Looks like you missed this email?
> > > http://dpdk.org/ml/archives/dev/2017-June/068142.html
> > > 
> > > Can we make it as function pointer based approach(keeping all adapter functions
> > > function prototype required for SW PMD) so that each PMD
> > > can register the ops for adapter_create etc so that same API can be used
> > > for software and hardware PMDs(the scheme like rte_flow() or rte_tm()
> > > approach)
> > > 
> > > Can discuss more on that to finalize the approach?
> > > > Yes, I did miss that email :-( (I am including the relevant extract below)
> 
> OK.
> 
> > 
> > >
> > > /* adapter has inbuilt port, no need to create producer port */
> > > #define RTE_EVENT_ETHDEV_CAP_INBUILT_PORT  (1ULL << 0)
> > > /* adapter does not need service function */
> > > #define RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC (1ULL << 1)
> 
> I just provided a name to share the view. You can choose better name.
> 
> > >
> > > struct rte_event_eth_rx_adap_info {
> > > 	char name[32];
> > >          uint32_t adapter_cap;
> > >          /**< Ethdev RX adapter capabilities(RTE_EVENT_ETHDEV_CAP_)*/
> > > }
> > >
> > >
> > > struct rte_event_eth_rx_adap_cfg {
> > > 	uint8_t rx_event_port_id;
> > >         /**< Event port identifier, the adapter enqueues mbuf events to
> > this
> > >          * port, Ignored when RTE_EVENT_ETHDEV_CAP_INBUILT_PORT
> > >          */
> > >
> > > }
> > >
> > > struct rte_eth_rx_event_adapter_queue_config {
> > >         uint32_t rx_queue_flags;
> > >          /**< Flags for handling received packets */
> > >         uint16_t servicing_weight;
> > >         /**< Relative polling frequency of ethernet receive queue, if this
> > >          * is set to zero, the Rx queue is interrupt driven
> > >          * Ignored if RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC set
> > >          */
> > >         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.
> > >          */
> > > };
> > >
> > > int rte_event_eth_rx_adapter_create(uint8_t id, uint8_t dev_id, uint8_t
> > eth_port_id);
> > 
> > > int rte_event_eth_rx_adapter_get_info(uint8_t id, struct
> > rte_event_eth_rx_adap_info *info);
> > > int rte_event_eth_rx_adapter_configure(uint8_t id, struct
> > rte_event_eth_rx_adap_config *cfg);
> > > int rte_event_eth_rx_adapter_queue_add(uint8_t id, int32_t rx_queue_id,
> > const struct rte_eth_rx_event_adapter_queue_config *config);
> > > int rte_event_eth_rx_adapter_queue_del(uint8_t id, int32_t rx_queue_id)
> > > int rte_event_eth_rx_adapter_run();
> > > int rte_event_eth_rx_adapter_free(uint8_t id);
> > >
> > 
> > If I understood your idea, the function pointer struct would look something
> > like this.
> > 
> > struct rte_eventdev_rx_adapter_ops {
> > 	rx_adapter_create_t 	create,
> > 	rx_adapter_get_info_t	info,
> > 	rx_adapter_configure_t	configure,
> > 	rx_adapter_queue_add_t  queue_add,
> > 	rx_adapter_queue_del_t	queue_del,
> > 	rx_adapter_queue_free_t	queue_free,
> >       rx_adapter_free_t	free
> > };
> 
> Yes. But, I think, adapter create and free goes in struct rte_eventdev_op .
> See below.
> 
> 
> > 
> > struct rte_eventdev {
> >        ..
> >        const struct rte_eventdev_rx_adapter_ops *rx_adapter_ops;
> >        ..
> > };
> 
> An eventdev instance can have N adapters not just one. So this will be
> pointer to pointer, indexed through adapter_id.
> 
> In SW PMD case, the eventdev may have only one adapter.
> In HW PMD cases, There will more than one. example,
> - if octeontx eventdev dev_id + any external PCI n/w card like i40e or
> nicvf case an adapter with similar adapter ops as SW PMD
> - if octeontx eventdev dev_id + octeontx ethdev dev_id case another
> adapter that does not need service cores to inject event to octeontx
> eventdev
> 
> - Your generic Rx adapter we will make it as common code so that both SW PMD and
> octeontx PMD in service core mode as use the functions and register the
> ops.
> 
> 
> I was thinking like this
> 
> int rte_event_eth_rx_adapter_create(uint8_t id, uint8_t dev_id, uint8_t eth_port_id)
> {
> 	eventdev_ops = ... /* access through dev_id */
> 
> 	/* common code to get ops memory from adapter id */
> 	struct rte_eventdev_rx_adapter_ops* ops = rte_event_pmd_adapter_allocate(id);
> 
> 	/* Fill in adapter ops from driver */
> 	eventdev_ops->create_adapter(ops, dev_id, eth_port_id)
> 
> }
> 
> int rte_event_eth_rx_adapter_get_info(uint8_t id, struct rte_event_eth_rx_adap_info *info)
> {
> 	eventdev_ops = ... /* access through dev_id */
> 
> 	struct rte_eventdev_rx_adapter_ops* ops = eventdev_ops->rx_adapter_ops[id];
> 
> 	/* adapter specific info ops)
> 	ops->info(ops,....);
> 
> }

IMO, the mapping with your current proposal may go like this.

- rte_event_eth_rx_adapter_create() // Will just fill the adapter ops from driver, probably
  your existing rte_event_eth_rx_adapter_init() can go here
- exiting rte_event_eth_rx_adapter_create() will be more of
proposed rte_event_eth_rx_adapter_configure() on the given adapter.
- existing rte_event_eth_rx_adapter_queue_add() maps 1:1. But you can
  remove eth_dev_id as it is provided proposed rte_event_eth_rx_adapter_create()
- same applies to rte_event_eth_rx_adapter_queue_del()
- exiting rte_event_eth_rx_adapter_stats_get() can be changed to
  "xstat"(more like eventdev xstat scheme) so based on the adapter
capability application can get stats)


flow shall be:
1) application calls rte_event_eth_rx_adapter_create(id, eventdev_id,
ethdev_id) to create the adapter.(Drivers fills the adapter ops based on
eventdev_id + ethdev_id capabilities)
2) application calls rte_event_eth_rx_adapter_info_get() to get the
capability and other information of the adapter.
3) application calls rte_event_eth_rx_adapter_configure() to configure
based on the application need and the adapter capability.
4) application calls rte_event_eth_rx_adapter_queue_add() to link ethdev queues to 
eventdev queues. On this call, The driver creates the service functions or programs the HW registers
based on the adapter capability to take the events from ethdev and inject to eventdev.

> 
> 
> > 
> > But from previous emails (see struct rte_event_dev_producer_conf below), it
> > appears that the rx queue id and event information would be needed to create
> > the adapter that enqueues from the ethdev queue id to the event pmd, however
> > that information is available only at queue add time - thoughts ?
> 
> Just eventdev_id and ethdev_id is enough to create adapter.
> Free feel to change the name of API or flag name etc.
> Let me know if I have missed something?

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-07-07 15:57                   ` Jerin Jacob
@ 2017-07-10  6:14                     ` Rao, Nikhil
  2017-07-10 10:41                       ` Jerin Jacob
  0 siblings, 1 reply; 41+ messages in thread
From: Rao, Nikhil @ 2017-07-10  6:14 UTC (permalink / raw)
  To: Jerin Jacob
  Cc: gage.eads, dev, thomas, bruce.richardson, harry.van.haaren,
	hemant.agrawal, nipun.gupta, narender.vangati, Abhinandan Gujjar

Hi Jerin,

thanks for your feedback, further comments below.

On 7/7/2017 9:27 PM, Jerin Jacob wrote:
> -----Original Message-----
>> Date: Fri, 7 Jul 2017 20:33:19 +0530
>> From: Jerin Jacob <jerin.jacob@caviumnetworks.com>
>>>> /* adapter has inbuilt port, no need to create producer port */
>>>> #define RTE_EVENT_ETHDEV_CAP_INBUILT_PORT  (1ULL << 0)
>>>> /* adapter does not need service function */
>>>> #define RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC (1ULL << 1)
>>
>> I just provided a name to share the view. You can choose better name.
>>
OK.

>>>> int rte_event_eth_rx_adapter_create(uint8_t id, uint8_t dev_id, uint8_t
>>> eth_port_id);
>>>

I also think that the application should be able to call create() with > 
1 ports. This would allow a single service to poll multiple NICs with 
WRR priority.

The side effect of is that the queue add/del APIs would need to specify 
the port_id as well.

>>>> int rte_event_eth_rx_adapter_get_info(uint8_t id, struct
>>> rte_event_eth_rx_adap_info *info);
>>>> int rte_event_eth_rx_adapter_configure(uint8_t id, struct
>>> rte_event_eth_rx_adap_config *cfg);
>>>> int rte_event_eth_rx_adapter_queue_add(uint8_t id, int32_t rx_queue_id,
>>> const struct rte_eth_rx_event_adapter_queue_config *config);
>>>> int rte_event_eth_rx_adapter_queue_del(uint8_t id, int32_t rx_queue_id)

>>>> int rte_event_eth_rx_adapter_run();

The adapter's run function is not part of the public interface, agree ?
>>>> int rte_event_eth_rx_adapter_free(uint8_t id);
>>>>
>>>
>>> If I understood your idea, the function pointer struct would look something
>>> like this.
>>>
>>> struct rte_eventdev_rx_adapter_ops {
>>> 	rx_adapter_create_t 	create,
>>> 	rx_adapter_get_info_t	info,
>>> 	rx_adapter_configure_t	configure,
>>> 	rx_adapter_queue_add_t  queue_add,
>>> 	rx_adapter_queue_del_t	queue_del,
>>> 	rx_adapter_queue_free_t	queue_free,
>>>        rx_adapter_free_t	free
>>> };
>>
>> Yes. But, I think, adapter create and free goes in struct rte_eventdev_op .
>> See below.
>>
>>
>>>
>>> struct rte_eventdev {
>>>         ..
>>>         const struct rte_eventdev_rx_adapter_ops *rx_adapter_ops;
>>>         ..
>>> };
>>
>> An eventdev instance can have N adapters not just one. So this will be
>> pointer to pointer, indexed through adapter_id.
>>
>> In SW PMD case, the eventdev may have only one adapter.
>> In HW PMD cases, There will more than one. example,
>> - if octeontx eventdev dev_id + any external PCI n/w card like i40e or
>> nicvf case an adapter with similar adapter ops as SW PMD
>> - if octeontx eventdev dev_id + octeontx ethdev dev_id case another
>> adapter that does not need service cores to inject event to octeontx
>> eventdev
>>
>> - Your generic Rx adapter we will make it as common code so that both SW PMD and
>> octeontx PMD in service core mode as use the functions and register the
>> ops.

OK.
>>
>>
>> I was thinking like this
>>
>> int rte_event_eth_rx_adapter_create(uint8_t id, uint8_t dev_id, uint8_t eth_port_id)
>> {
>> 	eventdev_ops = ... /* access through dev_id */
>>
>> 	/* common code to get ops memory from adapter id */
>> 	struct rte_eventdev_rx_adapter_ops* ops = rte_event_pmd_adapter_allocate(id);
>>
>> 	/* Fill in adapter ops from driver */
>> 	eventdev_ops->create_adapter(ops, dev_id, eth_port_id)

As an implementation detail, the function pointer setup needs to account 
for DPDK primary/secondary processes, i.e, function addresses could be 
different in the 2 processes.

>>
>> }
>>
>> int rte_event_eth_rx_adapter_get_info(uint8_t id, struct rte_event_eth_rx_adap_info *info)
>> {

Argument list is missing the dev_id (as are the 
configure/queue_add/queue_del) functions.

>> 	eventdev_ops = ... /* access through dev_id */
>>
>> 	struct rte_eventdev_rx_adapter_ops* ops = eventdev_ops->rx_adapter_ops[id];
>>
>> 	/* adapter specific info ops)
>> 	ops->info(ops,....);
>>
>> }
> 
> IMO, the mapping with your current proposal may go like this.
> 
> - rte_event_eth_rx_adapter_create() // Will just fill the adapter ops from driver, probably
>    your existing rte_event_eth_rx_adapter_init() can go here
> - exiting rte_event_eth_rx_adapter_create() will be more of
> proposed rte_event_eth_rx_adapter_configure() on the given adapter.
> - existing rte_event_eth_rx_adapter_queue_add() maps 1:1. But you can
>    remove eth_dev_id as it is provided proposed rte_event_eth_rx_adapter_create()

See above for the case where the application could call create() with 2 
different ports.

> - same applies to rte_event_eth_rx_adapter_queue_del()
> - exiting rte_event_eth_rx_adapter_stats_get() can be changed to
>    "xstat"(more like eventdev xstat scheme) so based on the adapter
> capability application can get stats)
> 
> 
> flow shall be:
> 1) application calls rte_event_eth_rx_adapter_create(id, eventdev_id,
> ethdev_id) to create the adapter.(Drivers fills the adapter ops based on
> eventdev_id + ethdev_id capabilities)
> 2) application calls rte_event_eth_rx_adapter_info_get() to get the
> capability and other information of the adapter.
> 3) application calls rte_event_eth_rx_adapter_configure() to configure
> based on the application need and the adapter capability.
> 4) application calls rte_event_eth_rx_adapter_queue_add() to link ethdev queues to
> eventdev queues. On this call, The driver creates the service functions or programs the HW registers
> based on the adapter capability to take the events from ethdev and inject to eventdev.
>

The flow looks good to me.

>>
>>
>>>
>>> But from previous emails (see struct rte_event_dev_producer_conf below), it
>>> appears that the rx queue id and event information would be needed to create
>>> the adapter that enqueues from the ethdev queue id to the event pmd, however
>>> that information is available only at queue add time - thoughts ?
>>
>> Just eventdev_id and ethdev_id is enough to create adapter.

OK.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-07-10  6:14                     ` Rao, Nikhil
@ 2017-07-10 10:41                       ` Jerin Jacob
  2017-07-13  3:26                         ` Rao, Nikhil
  0 siblings, 1 reply; 41+ messages in thread
From: Jerin Jacob @ 2017-07-10 10:41 UTC (permalink / raw)
  To: Rao, Nikhil
  Cc: gage.eads, dev, thomas, bruce.richardson, harry.van.haaren,
	hemant.agrawal, nipun.gupta, narender.vangati, Abhinandan Gujjar

-----Original Message-----
> Date: Mon, 10 Jul 2017 11:44:10 +0530
> From: "Rao, Nikhil" <nikhil.rao@intel.com>
> To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> CC: gage.eads@intel.com, dev@dpdk.org, thomas@monjalon.net,
>  bruce.richardson@intel.com, harry.van.haaren@intel.com,
>  hemant.agrawal@nxp.com, nipun.gupta@nxp.com, narender.vangati@intel.com,
>  Abhinandan Gujjar <abhinandan.gujjar@intel.com>
> Subject: Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101
>  Thunderbird/52.2.1
> 
> Hi Jerin,

Hi Nikhil,

> 
> thanks for your feedback, further comments below.
> 
> On 7/7/2017 9:27 PM, Jerin Jacob wrote:
> > -----Original Message-----
> > > Date: Fri, 7 Jul 2017 20:33:19 +0530
> > > From: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> > > > > /* adapter has inbuilt port, no need to create producer port */
> > > > > #define RTE_EVENT_ETHDEV_CAP_INBUILT_PORT  (1ULL << 0)
> > > > > /* adapter does not need service function */
> > > > > #define RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC (1ULL << 1)
> > > 
> > > I just provided a name to share the view. You can choose better name.
> > > 
> OK.
> 
> > > > > int rte_event_eth_rx_adapter_create(uint8_t id, uint8_t dev_id, uint8_t
> > > > eth_port_id);
> > > > 
> 
> I also think that the application should be able to call create() with > 1
> ports. This would allow a single service to poll multiple NICs with WRR
> priority.

Good point.

Can we realize the same use case like below?
- Instead of applying WRR over multiple NIC ports and adding the logic in Rx
  adapter, How about applying the WRR over multiple service function and
  move the WRR logic to service function layer.

i.e
one adapter is
- one service function(adapter_queue_add() will be used to add more
  queues)
- one constant set of ops.

Advantages:
- WRR over service functions will be useful as other service functions
can utilize it as it is not strictly specific to Rx adapter.
- In order to work with, below mentioned use cases, RX adapter ops needs
  to be constant and it will decided on the _adapter_create where "eth_port_id"
and "dev_id" specified.

1) Ethdev HW is not capable of injecting the packets and SW eventdev
driver(All existing ethdev PMD + drivers/event/sw PMD combination)
2) Ethdev HW is not capable of injecting the packets and not compatible
HW eventdev driver(All existing ethdev PMD + driver/event/octeontx PMD
combination)
3) Ethdev HW is capable of injecting the packet to compatible
HW eventdev driver.

- it will remove the below side effect(queue add/del API needs port_id)

Thoughts?

> 
> The side effect of is that the queue add/del APIs would need to specify the
> port_id as well.
> 
> > > > > int rte_event_eth_rx_adapter_get_info(uint8_t id, struct
> > > > rte_event_eth_rx_adap_info *info);
> > > > > int rte_event_eth_rx_adapter_configure(uint8_t id, struct
> > > > rte_event_eth_rx_adap_config *cfg);
> > > > > int rte_event_eth_rx_adapter_queue_add(uint8_t id, int32_t rx_queue_id,
> > > > const struct rte_eth_rx_event_adapter_queue_config *config);
> > > > > int rte_event_eth_rx_adapter_queue_del(uint8_t id, int32_t rx_queue_id)
> 
> > > > > int rte_event_eth_rx_adapter_run();
> 
> The adapter's run function is not part of the public interface, agree ?

Agree.

> > > > > int rte_event_eth_rx_adapter_free(uint8_t id);
> > > > > 
> > > > 
> > > > If I understood your idea, the function pointer struct would look something
> > > > like this.
> > > > 
> > > > struct rte_eventdev_rx_adapter_ops {
> > > > 	rx_adapter_create_t 	create,
> > > > 	rx_adapter_get_info_t	info,
> > > > 	rx_adapter_configure_t	configure,
> > > > 	rx_adapter_queue_add_t  queue_add,
> > > > 	rx_adapter_queue_del_t	queue_del,
> > > > 	rx_adapter_queue_free_t	queue_free,
> > > >        rx_adapter_free_t	free
> > > > };
> > > 
> > > Yes. But, I think, adapter create and free goes in struct rte_eventdev_op .
> > > See below.
> > > 
> > > 
> > > > 
> > > > struct rte_eventdev {
> > > >         ..
> > > >         const struct rte_eventdev_rx_adapter_ops *rx_adapter_ops;
> > > >         ..
> > > > };
> > > 
> > > An eventdev instance can have N adapters not just one. So this will be
> > > pointer to pointer, indexed through adapter_id.
> > > 
> > > In SW PMD case, the eventdev may have only one adapter.
> > > In HW PMD cases, There will more than one. example,
> > > - if octeontx eventdev dev_id + any external PCI n/w card like i40e or
> > > nicvf case an adapter with similar adapter ops as SW PMD
> > > - if octeontx eventdev dev_id + octeontx ethdev dev_id case another
> > > adapter that does not need service cores to inject event to octeontx
> > > eventdev
> > > 
> > > - Your generic Rx adapter we will make it as common code so that both SW PMD and
> > > octeontx PMD in service core mode as use the functions and register the
> > > ops.
> 
> OK.
> > > 
> > > 
> > > I was thinking like this
> > > 
> > > int rte_event_eth_rx_adapter_create(uint8_t id, uint8_t dev_id, uint8_t eth_port_id)
> > > {
> > > 	eventdev_ops = ... /* access through dev_id */
> > > 
> > > 	/* common code to get ops memory from adapter id */
> > > 	struct rte_eventdev_rx_adapter_ops* ops = rte_event_pmd_adapter_allocate(id);
> > > 
> > > 	/* Fill in adapter ops from driver */
> > > 	eventdev_ops->create_adapter(ops, dev_id, eth_port_id)
> 
> As an implementation detail, the function pointer setup needs to account for
> DPDK primary/secondary processes, i.e, function addresses could be different
> in the 2 processes.

Yes

> 
> > > 
> > > }
> > > 
> > > int rte_event_eth_rx_adapter_get_info(uint8_t id, struct rte_event_eth_rx_adap_info *info)
> > > {
> 
> Argument list is missing the dev_id (as are the
> configure/queue_add/queue_del) functions.

Yes


> > > 	eventdev_ops = ... /* access through dev_id */
> > > 
> > > 	struct rte_eventdev_rx_adapter_ops* ops = eventdev_ops->rx_adapter_ops[id];
> > > 
> > > 	/* adapter specific info ops)
> > > 	ops->info(ops,....);
> > > 
> > > }
> > 
> > IMO, the mapping with your current proposal may go like this.
> > 
> > - rte_event_eth_rx_adapter_create() // Will just fill the adapter ops from driver, probably
> >    your existing rte_event_eth_rx_adapter_init() can go here
> > - exiting rte_event_eth_rx_adapter_create() will be more of
> > proposed rte_event_eth_rx_adapter_configure() on the given adapter.
> > - existing rte_event_eth_rx_adapter_queue_add() maps 1:1. But you can
> >    remove eth_dev_id as it is provided proposed rte_event_eth_rx_adapter_create()
> 
> See above for the case where the application could call create() with 2
> different ports.
> 
> > - same applies to rte_event_eth_rx_adapter_queue_del()
> > - exiting rte_event_eth_rx_adapter_stats_get() can be changed to
> >    "xstat"(more like eventdev xstat scheme) so based on the adapter
> > capability application can get stats)
> > 
> > 
> > flow shall be:
> > 1) application calls rte_event_eth_rx_adapter_create(id, eventdev_id,
> > ethdev_id) to create the adapter.(Drivers fills the adapter ops based on
> > eventdev_id + ethdev_id capabilities)
> > 2) application calls rte_event_eth_rx_adapter_info_get() to get the
> > capability and other information of the adapter.
> > 3) application calls rte_event_eth_rx_adapter_configure() to configure
> > based on the application need and the adapter capability.
> > 4) application calls rte_event_eth_rx_adapter_queue_add() to link ethdev queues to
> > eventdev queues. On this call, The driver creates the service functions or programs the HW registers
> > based on the adapter capability to take the events from ethdev and inject to eventdev.
> > 
> 
> The flow looks good to me.

Great!!

> 
> > > 
> > > 
> > > > 
> > > > But from previous emails (see struct rte_event_dev_producer_conf below), it
> > > > appears that the rx queue id and event information would be needed to create
> > > > the adapter that enqueues from the ethdev queue id to the event pmd, however
> > > > that information is available only at queue add time - thoughts ?
> > > 
> > > Just eventdev_id and ethdev_id is enough to create adapter.
> 
> OK.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-07-10 10:41                       ` Jerin Jacob
@ 2017-07-13  3:26                         ` Rao, Nikhil
  2017-07-13 18:45                           ` Jerin Jacob
  0 siblings, 1 reply; 41+ messages in thread
From: Rao, Nikhil @ 2017-07-13  3:26 UTC (permalink / raw)
  To: Jerin Jacob
  Cc: gage.eads, dev, thomas, bruce.richardson, harry.van.haaren,
	hemant.agrawal, nipun.gupta, narender.vangati, Abhinandan Gujjar,
	nikhil.rao

On 7/10/2017 4:11 PM, Jerin Jacob wrote:
> -----Original Message-----
>>
>> I also think that the application should be able to call create() with > 1
>> ports. This would allow a single service to poll multiple NICs with WRR
>> priority.
> 
> Good point.
> 
> Can we realize the same use case like below?
> - Instead of applying WRR over multiple NIC ports and adding the logic in Rx
>    adapter, How about applying the WRR over multiple service function and
>    move the WRR logic to service function layer.
> 
> i.e
> one adapter is
> - one service function(adapter_queue_add() will be used to add more
>    queues)
> - one constant set of ops.
> 
> Advantages:
> - WRR over service functions will be useful as other service functions
> can utilize it as it is not strictly specific to Rx adapter.
> - In order to work with, below mentioned use cases, RX adapter ops needs
>    to be constant and it will decided on the _adapter_create where "eth_port_id"
> and "dev_id" specified.
> 
> 1) Ethdev HW is not capable of injecting the packets and SW eventdev
> driver(All existing ethdev PMD + drivers/event/sw PMD combination)
> 2) Ethdev HW is not capable of injecting the packets and not compatible
> HW eventdev driver(All existing ethdev PMD + driver/event/octeontx PMD
> combination)
> 3) Ethdev HW is capable of injecting the packet to compatible
> HW eventdev driver.
> 
> - it will remove the below side effect(queue add/del API needs port_id)
> 
> Thoughts?

Re: Multiple ports within a adapter

1) 	1:N adapter:port can work if the op is constant across all the
	ports (_adapter_create() gets to determine that)

	WRR is specified on a per queue basis - The polling sequence
	built from the weights of all queues in the adapter (across all
	ports)


	struct rte_event_eth_rx_adapter_queue_conf {
	...
	 	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)
	 */
	...
	}

         The downside is that a port needs to be specified when 	
	add/deleting a queue. Another thought is to do away with
	the concept of an adapter ID, and only use port IDs, but there
	is a possibility for  2 Rx queues of the same port to be
	associated with 2 different adapter IDs. from an API perspective
	you could specify any of ports[i] in the info/conf() APIs and
	that seems a bit odd.

	In summary, I agree, lets drop this idea.


2) 	Re: Service function implementation of WRR

	Within a service like the Rx adapter the notion of WRR is 	
	relative polling frequency of the ethernet receive queue,
	polling a tap interface may be more heavy weight than the a HW
	NIC PMD poll, so WRR for the Rx adapter  may not correlate with
	CPU utilization i.e, if that is a metric for some other service.
	If WRR is based on different metrics across services, I am not
	sure how we would able to specify WRR across services. Perhaps
	as services get more use, we maybe able to come up
	some common requirements.

How about if multiple adapters can specify the same service, 	
function in the _configure() call. A service can run multiple
adapters with WRR across all queues in the service ?

Nikhil

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-07-13  3:26                         ` Rao, Nikhil
@ 2017-07-13 18:45                           ` Jerin Jacob
  2017-07-27 10:58                             ` Rao, Nikhil
  0 siblings, 1 reply; 41+ messages in thread
From: Jerin Jacob @ 2017-07-13 18:45 UTC (permalink / raw)
  To: Rao, Nikhil
  Cc: gage.eads, dev, thomas, bruce.richardson, harry.van.haaren,
	hemant.agrawal, nipun.gupta, narender.vangati, Abhinandan Gujjar

-----Original Message-----
> Date: Thu, 13 Jul 2017 08:56:48 +0530
> From: "Rao, Nikhil" <nikhil.rao@intel.com>
> To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> CC: gage.eads@intel.com, dev@dpdk.org, thomas@monjalon.net,
>  bruce.richardson@intel.com, harry.van.haaren@intel.com,
>  hemant.agrawal@nxp.com, nipun.gupta@nxp.com, narender.vangati@intel.com,
>  Abhinandan Gujjar <abhinandan.gujjar@intel.com>, nikhil.rao@intel.com
> Subject: Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101
>  Thunderbird/52.2.1
> 
> On 7/10/2017 4:11 PM, Jerin Jacob wrote:
> > -----Original Message-----
> > > 
> > > I also think that the application should be able to call create() with > 1
> > > ports. This would allow a single service to poll multiple NICs with WRR
> > > priority.
> > 
> > Good point.
> > 
> > Can we realize the same use case like below?
> > - Instead of applying WRR over multiple NIC ports and adding the logic in Rx
> >    adapter, How about applying the WRR over multiple service function and
> >    move the WRR logic to service function layer.
> > 
> > i.e
> > one adapter is
> > - one service function(adapter_queue_add() will be used to add more
> >    queues)
> > - one constant set of ops.
> > 
> > Advantages:
> > - WRR over service functions will be useful as other service functions
> > can utilize it as it is not strictly specific to Rx adapter.
> > - In order to work with, below mentioned use cases, RX adapter ops needs
> >    to be constant and it will decided on the _adapter_create where "eth_port_id"
> > and "dev_id" specified.
> > 
> > 1) Ethdev HW is not capable of injecting the packets and SW eventdev
> > driver(All existing ethdev PMD + drivers/event/sw PMD combination)
> > 2) Ethdev HW is not capable of injecting the packets and not compatible
> > HW eventdev driver(All existing ethdev PMD + driver/event/octeontx PMD
> > combination)
> > 3) Ethdev HW is capable of injecting the packet to compatible
> > HW eventdev driver.
> > 
> > - it will remove the below side effect(queue add/del API needs port_id)
> > 
> > Thoughts?
> 
> Re: Multiple ports within a adapter
> 
> 1) 	1:N adapter:port can work if the op is constant across all the
> 	ports (_adapter_create() gets to determine that)

Yes. But ops may not be constant, if we consider the above three models.

> 
> 	WRR is specified on a per queue basis - The polling sequence
> 	built from the weights of all queues in the adapter (across all
> 	ports)
> 
> 
> 	struct rte_event_eth_rx_adapter_queue_conf {
> 	...
> 	 	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)
> 	 */
> 	...
> 	}
> 
>         The downside is that a port needs to be specified when 	
> 	add/deleting a queue. Another thought is to do away with
> 	the concept of an adapter ID, and only use port IDs, but there
> 	is a possibility for  2 Rx queues of the same port to be
> 	associated with 2 different adapter IDs. from an API perspective
> 	you could specify any of ports[i] in the info/conf() APIs and
> 	that seems a bit odd.
> 
> 	In summary, I agree, lets drop this idea.

OK. Great.

> 
> 
> 2) 	Re: Service function implementation of WRR
> 
> 	Within a service like the Rx adapter the notion of WRR is 	
> 	relative polling frequency of the ethernet receive queue,
> 	polling a tap interface may be more heavy weight than the a HW
> 	NIC PMD poll, so WRR for the Rx adapter  may not correlate with
> 	CPU utilization i.e, if that is a metric for some other service.
> 	If WRR is based on different metrics across services, I am not
> 	sure how we would able to specify WRR across services. Perhaps
> 	as services get more use, we maybe able to come up
> 	some common requirements.
> 
> How about if multiple adapters can specify the same service, 	
> function in the _configure() call. A service can run multiple
> adapters with WRR across all queues in the service ?

Yes, It make sense. With ops scheme, multiple adapter can have same
service. But, I am not sure, what you really meant by "in _configure()"
call. But in any case, We can model around whatever scheme that works for SW PMD.
HW scheme will have constrain on "Multiple ports within a adapter",
Except that constraint, everything else we can model around SW PMD
requirements.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-07-06 21:52           ` [PATCH 1/2] " Nikhil Rao
  2017-07-06 14:18             ` Jerin Jacob
  2017-07-06 21:52             ` [PATCH 2/2] eventdev: add event eth rx adapter unit tests Nikhil Rao
@ 2017-07-24 10:10             ` Nipun Gupta
  2017-07-24 10:24               ` Jerin Jacob
  2017-07-24 10:32               ` Van Haaren, Harry
  2 siblings, 2 replies; 41+ messages in thread
From: Nipun Gupta @ 2017-07-24 10:10 UTC (permalink / raw)
  To: Nikhil Rao, jerin.jacob
  Cc: gage.eads, dev, thomas, bruce.richardson, harry.van.haaren,
	Hemant Agrawal, narender.vangati, Abhinandan Gujjar

Hi Nikhil/Edas,

> -----Original Message-----
> From: Nikhil Rao [mailto:nikhil.rao@intel.com]
> Sent: Friday, July 07, 2017 3:23
> To: jerin.jacob@caviumnetworks.com
> Cc: gage.eads@intel.com; dev@dpdk.org; thomas@monjalon.net;
> bruce.richardson@intel.com; harry.van.haaren@intel.com; Hemant Agrawal
> <hemant.agrawal@nxp.com>; Nipun Gupta <nipun.gupta@nxp.com>;
> narender.vangati@intel.com; Nikhil Rao <nikhil.rao@intel.com>; Abhinandan
> Gujjar <abhinandan.gujjar@intel.com>
> Subject: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> 
> Eventdev-based networking applications require a component to dequeue
> packets from NIC Rx queues and inject them into eventdev queues[1]. While
> some platforms (e.g. Cavium Octeontx) do this operation in hardware, other
> platforms use software.
> 
> This patchset introduces an ethernet Rx event adapter that dequeues packets
> from ethernet devices and enqueues them to event devices. It is based on
> a previous RFC[2].
> 
> The adapter is designed to work with the EAL service core[3]. If
> an application determines that the adapter is required, it can register and
> launch it on a service core. Alternatively, this adapter can serve as a
> template for applications to design customer ethernet Rx event adapters
> better suited to their needs.
> 
> The adapter can service multiple ethernet devices and queues. Each queue is
> configured with a servicing weight to control the relative frequency with
> which the adapter polls the queue, and the event fields to use when
> constructing packet events. The adapter has two modes for programming an
> event's flow ID: use a static per-queue user-specified value or use the RSS
> hash.
> 
> A detailed description of the adapter is contained in the header's
> comments.
> 
> [1] http://dpdk.org/ml/archives/dev/2017-May/065341.html
> [2] http://dpdk.org/ml/archives/dev/2017-May/065539.html
> [3] http://dpdk.org/ml/archives/dev/2017-July/069782.html
> 
> Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
> Signed-off-by: Gage Eads <gage.eads@intel.com>
> Signed-off-by: Abhinandan Gujjar <abhinandan.gujjar@intel.com>
> ---
> 
> v2:
> Thanks Jerin for review - below is a list of changes you
> suggested.
> 
> - all public symbols are started with rte_event_.
> - Add Doxygen reference with @see.
> - Mention setting of ev.event_type.
> - Mention adapter to service function mapping.
> - Remove rte_eth_rx_event_adapter_dev_add/del().
> - Change rx_queuee_id to int32_t and use -1 to denote all Rx queues.
> - Add rte_eth_event_rx_queue_del().
> 
> Other changes
> - Remove adapter's run function (rte_event_eth_rx_adapter_run()) from
>   the public interface. The adapter internally uses it to create a
>   service.
> - Add a blocked cycle count to stats. Further description is contained
>   in the header.
> - Minor struct renames rte_event_eth_rx_adapter_config -> .._conf
> ---
>  lib/librte_eventdev/rte_event_eth_rx_adapter.h | 301 +++++++++
>  lib/librte_eventdev/rte_event_eth_rx_adapter.c | 825
> +++++++++++++++++++++++++
>  lib/librte_eventdev/rte_eventdev_version.map   |  13 +
>  lib/Makefile                                   |   2 +-
>  lib/librte_eventdev/Makefile                   |   2 +
>  5 files changed, 1142 insertions(+), 1 deletion(-)
>  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..5ccd0bd24
> --- /dev/null
> +++ b/lib/librte_eventdev/rte_event_eth_rx_adapter.h
> @@ -0,0 +1,301 @@
> +/*
> + *   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 ethernet Rx event adapter's role is to transfer
> + * mbufs from the ethernet receive queues managed by DPDK to an event
> device.
> + * The application uses the adapter APIs to configure the packet flow between
> + * the ethernet devices and event devices. The adapter is designed to work with
> + * the EAL service cores. The adapter's work can be parallelized by dividing the
> + * NIC Rx queues among multiple adapter services that run in parallel.

First of all, apologies for commenting late on this. I am going through this patchset and have some concerns over this.
It is mentioned that "The adapter is designed to work with * the EAL service cores"
Does this mean that the adapter cannot function without service core?
In the case where Ethdev HW is capable of injecting the packet to compatible HW eventdev driver, there is no service
required. It seems this patchset does not take care of this use-case or maybe I am missing something here?

> + *
> + * Before using the adapter, the application needs to enumerate and configure
> + * the ethernet devices that it wishes to use. This is typically done using the
> + * following DPDK ethdev functions:
> + *  - rte_eth_dev_configure()
> + *  - rte_eth_tx_queue_setup()
> + *  - rte_eth_rx_queue_setup()
> + *  - rte_eth_dev_start()
> + *
> + * The application also configures an event device and creates event ports
> + * to interface with the event device. In addition to the event ports used by
> + * its packet processing functions, the application creates an event port
> + * to be used by this adapter.
> + *
> + * The ethernet Rx event adapter's functions are:
> + *  - rte_event_eth_rx_adapter_create()
> + *  - rte_event_eth_rx_adapter_free()
> + *  - rte_event_eth_rx_adapter_queue_add()
> + *  - rte_event_eth_rx_adapter_queue_del()
> + *  - rte_event_eth_rx_adapter_stats_get()
> + *  - rte_event_eth_rx_adapter_stats_reset()
> + *
> + * The applicaton creates an event to ethernet adapter using
> + * rte_event_eth_rx_adapter_create(). The event device and event port
> + * identifiers are passed to this function.
> + *
> + * 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.
> + *
> + * At the time of adding an ethernet device receive queue, the application can
> + * also specify a static event flow id and set the
> + * RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID bit of the
> rx_queue_flags
> + * member of the rte_event_eth_rx_adapter_queue_conf structure. If the
> + * RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID isn't set, the flow
> id is
> + * assigned the value of the RSS hash. The adapter generates the RSS hash if it
> + * hasn't been already computed by the NIC, based on source and destination
> + * IPv4/6 addresses, using the rte_softrss_be() routine included in the DPDK.
> + *
> + * The servicing weight parameter in the
> rte_event_eth_rx_adapter_queue_conf
> + * 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.
> + *
> + * 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
> + */

<snip>

> +
> +static int
> +_rte_event_eth_rx_adapter_queue_add(struct rte_event_eth_rx_adapter
> *rx_adapter,
> +				    struct eth_device_info *dev_info,
> +				    uint16_t rx_queue_id,
> +				    const struct
> rte_event_eth_rx_adapter_queue_conf *conf)
> +{
> +	int ret;
> +	struct eth_rx_queue_info *queue_info;
> +	const struct rte_event *ev;
> +
> +	if (rx_queue_id >= dev_info->dev->data->nb_rx_queues)
> +		return -EINVAL;
> +
> +	queue_info = &dev_info->rx_queue[rx_queue_id];
> +	if (queue_info->queue_enabled)
> +		return -EEXIST;
> +
> +	ev = &conf->ev;
> +	memset(queue_info, 0, sizeof(*queue_info));
> +	queue_info->event_queue_id = ev->queue_id;
> +	queue_info->sched_type = ev->sched_type;
> +	queue_info->priority = ev->priority;
> +	queue_info->wt = conf->servicing_weight;
> +
> +	if (queue_info->wt == 0) {
> +		struct rte_eth_dev_data *data = dev_info->dev->data;
> +
> +		/* If Rx interrupts are disabled set wt = 1 */
> +		queue_info->wt = !data->dev_conf.intr_conf.rxq;
> +	}
> +
> +	if (conf->
> +	    rx_queue_flags &
> RTE_EVENT_ETH_RX_ADAPTER_QUEUE_FLOW_ID_VALID) {
> +		queue_info->flow_id = ev->flow_id;
> +		queue_info->flow_id_mask = ~0;
> +	}
> +
> +	queue_info->queue_enabled = true;
> +	rx_adapter->num_rx_polled++;
> +	ret = eth_poll_wrr_calc(rx_adapter);
> +	if (ret) {
> +		rx_adapter->num_rx_polled--;
> +		queue_info->queue_enabled = false;
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +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)
> +{
> +	int ret = 0;
> +	struct rte_event_eth_rx_adapter *rx_adapter;
> +	struct eth_device_info *dev_info;
> +	uint32_t i, j;
> +
> +	rx_adapter = rte_event_eth_rx_adapter[id];
> +	if (!valid_id(id) || !rte_event_eth_rx_adapter || !rx_adapter ||
> +	    eth_dev_id >= rte_eth_dev_count() || !conf)
> +		return -EINVAL;
> +
> +	rte_spinlock_lock(&rx_adapter->rx_lock);
> +
> +	dev_info = &rx_adapter->eth_devices[eth_dev_id];
> +	if (rx_queue_id == -1) {
> +		for (i = 0; i < dev_info->dev->data->nb_rx_queues; i++) {
> +			ret =
> +			    _rte_event_eth_rx_adapter_queue_add(rx_adapter,
> dev_info, i,
> +								conf);
> +			if (ret) {
> +				for (j = 0; j < i; j++)
> +
> 	_rte_event_eth_rx_adapter_queue_del(rx_adapter,
> +
> dev_info,
> +									    j);
> +			}
> +		}
> +
> +	} else {
> +		ret = _rte_event_eth_rx_adapter_queue_add(rx_adapter,
> dev_info,
> +
> (uint16_t)rx_queue_id,
> +							  conf);
> +	}
> +
> +	rte_spinlock_unlock(&rx_adapter->rx_lock);
> +
> +	return ret;
> +}

Looking at the rte_event_eth_rx_adapter_queue_add & event_eth_rx_adapter_service_func
it seems that this indeed will not fit with the cases where ethdev is capable of enqueing packets
to the eventdev (as was mentioned in Jerin's first RFC).

In case of hardware based eventdev and queues, these function should also invoke respective PMD
HW configs. e.g. In queue case - rte_eventdev and rte_ethdev - both PMDs at hw level shall be configured.

A typical eventdev hardware will require queues of eth devices will be configured to directly attach to
eventdev in the hardware.

Mapping it to NXP eventdev, enabling this functionality requires some configuration where dev private
information of both the devices (event dev and eth dev) is required at the same time,
and the final configuration is provided via eth device to H/W. So, this require inter device communication in DPDK.

Jerin,

I have an impression that Cavium hardware has H/W capability to inject packets from Ethernet
devices to event devices? If yes, how do you plan to support it?

Thanks,
Nipun

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-07-24 10:10             ` [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues Nipun Gupta
@ 2017-07-24 10:24               ` Jerin Jacob
  2017-07-24 11:37                 ` Nipun Gupta
  2017-07-24 10:32               ` Van Haaren, Harry
  1 sibling, 1 reply; 41+ messages in thread
From: Jerin Jacob @ 2017-07-24 10:24 UTC (permalink / raw)
  To: Nipun Gupta
  Cc: Nikhil Rao, gage.eads, dev, thomas, bruce.richardson,
	harry.van.haaren, Hemant Agrawal, narender.vangati,
	Abhinandan Gujjar

-----Original Message-----
> Date: Mon, 24 Jul 2017 10:10:50 +0000
> From: Nipun Gupta <nipun.gupta@nxp.com>
> To: Nikhil Rao <nikhil.rao@intel.com>, "jerin.jacob@caviumnetworks.com"
>  <jerin.jacob@caviumnetworks.com>
> CC: "gage.eads@intel.com" <gage.eads@intel.com>, "dev@dpdk.org"
>  <dev@dpdk.org>, "thomas@monjalon.net" <thomas@monjalon.net>,
>  "bruce.richardson@intel.com" <bruce.richardson@intel.com>,
>  "harry.van.haaren@intel.com" <harry.van.haaren@intel.com>, Hemant Agrawal
>  <hemant.agrawal@nxp.com>, "narender.vangati@intel.com"
>  <narender.vangati@intel.com>, Abhinandan Gujjar
>  <abhinandan.gujjar@intel.com>
> Subject: RE: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> 
> Looking at the rte_event_eth_rx_adapter_queue_add & event_eth_rx_adapter_service_func
> it seems that this indeed will not fit with the cases where ethdev is capable of enqueing packets
> to the eventdev (as was mentioned in Jerin's first RFC).
> 
> In case of hardware based eventdev and queues, these function should also invoke respective PMD
> HW configs. e.g. In queue case - rte_eventdev and rte_ethdev - both PMDs at hw level shall be configured.
> 
> A typical eventdev hardware will require queues of eth devices will be configured to directly attach to
> eventdev in the hardware.
> 
> Mapping it to NXP eventdev, enabling this functionality requires some configuration where dev private
> information of both the devices (event dev and eth dev) is required at the same time,
> and the final configuration is provided via eth device to H/W. So, this require inter device communication in DPDK.

Just like dpaa2 bus layer functions used in another subsystems. You
can export a function from ethdev dpaa2 to eventdev dpaa2 for ethdev rx queue
to eventdev queue connection.

> 
> Jerin,
> 
> I have an impression that Cavium hardware has H/W capability to inject packets from Ethernet
> devices to event devices? If yes, how do you plan to support it?

Please check the latest review comments on this patch set
http://dpdk.org/dev/patchwork/patch/26534/.

Nikhil is changing ops(function pointer) based approach. With that HW
support can be added.

> 
> Thanks,
> Nipun
> 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-07-24 10:10             ` [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues Nipun Gupta
  2017-07-24 10:24               ` Jerin Jacob
@ 2017-07-24 10:32               ` Van Haaren, Harry
  2017-07-24 13:06                 ` Nipun Gupta
  1 sibling, 1 reply; 41+ messages in thread
From: Van Haaren, Harry @ 2017-07-24 10:32 UTC (permalink / raw)
  To: Nipun Gupta, Rao, Nikhil, jerin.jacob
  Cc: Eads, Gage, dev, thomas, Richardson, Bruce, Hemant Agrawal,
	Vangati, Narender, Gujjar, Abhinandan S

> From: Nipun Gupta [mailto:nipun.gupta@nxp.com]
> Sent: Monday, July 24, 2017 11:11 AM
> To: Rao, Nikhil <nikhil.rao@intel.com>; jerin.jacob@caviumnetworks.com
> Cc: Eads, Gage <gage.eads@intel.com>; dev@dpdk.org; thomas@monjalon.net; Richardson, Bruce
> <bruce.richardson@intel.com>; Van Haaren, Harry <harry.van.haaren@intel.com>; Hemant
> Agrawal <hemant.agrawal@nxp.com>; Vangati, Narender <narender.vangati@intel.com>; Gujjar,
> Abhinandan S <abhinandan.gujjar@intel.com>
> Subject: RE: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> 
> Hi Nikhil/Edas,

Hi All,

I'll reply on the service-cores topic, and leave the config to those more involved and familiar with them than I :)

> > -----Original Message-----
> > From: Nikhil Rao [mailto:nikhil.rao@intel.com]
> > Sent: Friday, July 07, 2017 3:23
> > To: jerin.jacob@caviumnetworks.com
> > Cc: gage.eads@intel.com; dev@dpdk.org; thomas@monjalon.net;
> > bruce.richardson@intel.com; harry.van.haaren@intel.com; Hemant Agrawal
> > <hemant.agrawal@nxp.com>; Nipun Gupta <nipun.gupta@nxp.com>;
> > narender.vangati@intel.com; Nikhil Rao <nikhil.rao@intel.com>; Abhinandan
> > Gujjar <abhinandan.gujjar@intel.com>
> > Subject: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> >
> > Eventdev-based networking applications require a component to dequeue
> > packets from NIC Rx queues and inject them into eventdev queues[1]. While
> > some platforms (e.g. Cavium Octeontx) do this operation in hardware, other
> > platforms use software.
> >
> > This patchset introduces an ethernet Rx event adapter that dequeues packets
> > from ethernet devices and enqueues them to event devices. It is based on
> > a previous RFC[2].
> >
> > The adapter is designed to work with the EAL service core[3]. If
> > an application determines that the adapter is required, it can register and
> > launch it on a service core. Alternatively, this adapter can serve as a
> > template for applications to design customer ethernet Rx event adapters
> > better suited to their needs.
> >
> > The adapter can service multiple ethernet devices and queues. Each queue is
> > configured with a servicing weight to control the relative frequency with
> > which the adapter polls the queue, and the event fields to use when
> > constructing packet events. The adapter has two modes for programming an
> > event's flow ID: use a static per-queue user-specified value or use the RSS
> > hash.
> >
> > A detailed description of the adapter is contained in the header's
> > comments.
> >
> > [1] http://dpdk.org/ml/archives/dev/2017-May/065341.html
> > [2] http://dpdk.org/ml/archives/dev/2017-May/065539.html
> > [3] http://dpdk.org/ml/archives/dev/2017-July/069782.html
> >
> > Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
> > Signed-off-by: Gage Eads <gage.eads@intel.com>
> > Signed-off-by: Abhinandan Gujjar <abhinandan.gujjar@intel.com>
> > ---
> >
> > v2:
> > Thanks Jerin for review - below is a list of changes you
> > suggested.
> >
> > - all public symbols are started with rte_event_.
> > - Add Doxygen reference with @see.
> > - Mention setting of ev.event_type.
> > - Mention adapter to service function mapping.
> > - Remove rte_eth_rx_event_adapter_dev_add/del().
> > - Change rx_queuee_id to int32_t and use -1 to denote all Rx queues.
> > - Add rte_eth_event_rx_queue_del().
> >
> > Other changes
> > - Remove adapter's run function (rte_event_eth_rx_adapter_run()) from
> >   the public interface. The adapter internally uses it to create a
> >   service.
> > - Add a blocked cycle count to stats. Further description is contained
> >   in the header.
> > - Minor struct renames rte_event_eth_rx_adapter_config -> .._conf
> > ---
> >  lib/librte_eventdev/rte_event_eth_rx_adapter.h | 301 +++++++++
> >  lib/librte_eventdev/rte_event_eth_rx_adapter.c | 825
> > +++++++++++++++++++++++++
> >  lib/librte_eventdev/rte_eventdev_version.map   |  13 +
> >  lib/Makefile                                   |   2 +-
> >  lib/librte_eventdev/Makefile                   |   2 +
> >  5 files changed, 1142 insertions(+), 1 deletion(-)
> >  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..5ccd0bd24
> > --- /dev/null
> > +++ b/lib/librte_eventdev/rte_event_eth_rx_adapter.h
> > @@ -0,0 +1,301 @@
> > +/*
> > + *   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 ethernet Rx event adapter's role is to transfer
> > + * mbufs from the ethernet receive queues managed by DPDK to an event
> > device.
> > + * The application uses the adapter APIs to configure the packet flow between
> > + * the ethernet devices and event devices. The adapter is designed to work with
> > + * the EAL service cores. The adapter's work can be parallelized by dividing the
> > + * NIC Rx queues among multiple adapter services that run in parallel.
> 
> First of all, apologies for commenting late on this. I am going through this patchset and
> have some concerns over this.
> It is mentioned that "The adapter is designed to work with * the EAL service cores"
> Does this mean that the adapter cannot function without service core?
> In the case where Ethdev HW is capable of injecting the packet to compatible HW eventdev
> driver, there is no service
> required. It seems this patchset does not take care of this use-case or maybe I am missing
> something here?


The "service cores" is a method of abstracting lcore requirements. In short, with a SW PMD, a service core is required to perform the event scheduling. With the HW use case as you describe, no core is required. So in the HW case, no service cores are allocated in DPDK, and as a result, all your cores are available to the application.

If I understand correctly, the generic "Event Ethernet RX Adapter" will register a service which needs to be run (by a service core) in order to perform SW polling of the NIC, and enqueue to the eventdev.

In order to support the hardware use-case, no service is registered and no service lcores required. The HW is allowed to perform the Ethdev -> Eventdev enqueue.

Hope that makes sense! -Harry


> > + *
> > + * Before using the adapter, the application needs to enumerate and configure
> > + * the ethernet devices that it wishes to use. This is typically done using the
> > + * following DPDK ethdev functions:
> > + *  - rte_eth_dev_configure()
> > + *  - rte_eth_tx_queue_setup()
> > + *  - rte_eth_rx_queue_setup()
> > + *  - rte_eth_dev_start()
> > + *
> > + * The application also configures an event device and creates event ports
> > + * to interface with the event device. In addition to the event ports used by
> > + * its packet processing functions, the application creates an event port
> > + * to be used by this adapter.
> > + *
> > + * The ethernet Rx event adapter's functions are:
> > + *  - rte_event_eth_rx_adapter_create()
> > + *  - rte_event_eth_rx_adapter_free()
> > + *  - rte_event_eth_rx_adapter_queue_add()
> > + *  - rte_event_eth_rx_adapter_queue_del()
> > + *  - rte_event_eth_rx_adapter_stats_get()
> > + *  - rte_event_eth_rx_adapter_stats_reset()
> > + *
> > + * The applicaton creates an event to ethernet adapter using
> > + * rte_event_eth_rx_adapter_create(). The event device and event port
> > + * identifiers are passed to this function.
> > + *
> > + * 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.
> > + *
> > + * At the time of adding an ethernet device receive queue, the application can
> > + * also specify a static event flow id and set the
> > + * RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID bit of the
> > rx_queue_flags
> > + * member of the rte_event_eth_rx_adapter_queue_conf structure. If the
> > + * RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID isn't set, the flow
> > id is
> > + * assigned the value of the RSS hash. The adapter generates the RSS hash if it
> > + * hasn't been already computed by the NIC, based on source and destination
> > + * IPv4/6 addresses, using the rte_softrss_be() routine included in the DPDK.
> > + *
> > + * The servicing weight parameter in the
> > rte_event_eth_rx_adapter_queue_conf
> > + * 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.
> > + *
> > + * 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
> > + */
> 
> <snip>
> 
> > +
> > +static int
> > +_rte_event_eth_rx_adapter_queue_add(struct rte_event_eth_rx_adapter
> > *rx_adapter,
> > +				    struct eth_device_info *dev_info,
> > +				    uint16_t rx_queue_id,
> > +				    const struct
> > rte_event_eth_rx_adapter_queue_conf *conf)
> > +{
> > +	int ret;
> > +	struct eth_rx_queue_info *queue_info;
> > +	const struct rte_event *ev;
> > +
> > +	if (rx_queue_id >= dev_info->dev->data->nb_rx_queues)
> > +		return -EINVAL;
> > +
> > +	queue_info = &dev_info->rx_queue[rx_queue_id];
> > +	if (queue_info->queue_enabled)
> > +		return -EEXIST;
> > +
> > +	ev = &conf->ev;
> > +	memset(queue_info, 0, sizeof(*queue_info));
> > +	queue_info->event_queue_id = ev->queue_id;
> > +	queue_info->sched_type = ev->sched_type;
> > +	queue_info->priority = ev->priority;
> > +	queue_info->wt = conf->servicing_weight;
> > +
> > +	if (queue_info->wt == 0) {
> > +		struct rte_eth_dev_data *data = dev_info->dev->data;
> > +
> > +		/* If Rx interrupts are disabled set wt = 1 */
> > +		queue_info->wt = !data->dev_conf.intr_conf.rxq;
> > +	}
> > +
> > +	if (conf->
> > +	    rx_queue_flags &
> > RTE_EVENT_ETH_RX_ADAPTER_QUEUE_FLOW_ID_VALID) {
> > +		queue_info->flow_id = ev->flow_id;
> > +		queue_info->flow_id_mask = ~0;
> > +	}
> > +
> > +	queue_info->queue_enabled = true;
> > +	rx_adapter->num_rx_polled++;
> > +	ret = eth_poll_wrr_calc(rx_adapter);
> > +	if (ret) {
> > +		rx_adapter->num_rx_polled--;
> > +		queue_info->queue_enabled = false;
> > +		return ret;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +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)
> > +{
> > +	int ret = 0;
> > +	struct rte_event_eth_rx_adapter *rx_adapter;
> > +	struct eth_device_info *dev_info;
> > +	uint32_t i, j;
> > +
> > +	rx_adapter = rte_event_eth_rx_adapter[id];
> > +	if (!valid_id(id) || !rte_event_eth_rx_adapter || !rx_adapter ||
> > +	    eth_dev_id >= rte_eth_dev_count() || !conf)
> > +		return -EINVAL;
> > +
> > +	rte_spinlock_lock(&rx_adapter->rx_lock);
> > +
> > +	dev_info = &rx_adapter->eth_devices[eth_dev_id];
> > +	if (rx_queue_id == -1) {
> > +		for (i = 0; i < dev_info->dev->data->nb_rx_queues; i++) {
> > +			ret =
> > +			    _rte_event_eth_rx_adapter_queue_add(rx_adapter,
> > dev_info, i,
> > +								conf);
> > +			if (ret) {
> > +				for (j = 0; j < i; j++)
> > +
> > 	_rte_event_eth_rx_adapter_queue_del(rx_adapter,
> > +
> > dev_info,
> > +									    j);
> > +			}
> > +		}
> > +
> > +	} else {
> > +		ret = _rte_event_eth_rx_adapter_queue_add(rx_adapter,
> > dev_info,
> > +
> > (uint16_t)rx_queue_id,
> > +							  conf);
> > +	}
> > +
> > +	rte_spinlock_unlock(&rx_adapter->rx_lock);
> > +
> > +	return ret;
> > +}
> 
> Looking at the rte_event_eth_rx_adapter_queue_add & event_eth_rx_adapter_service_func
> it seems that this indeed will not fit with the cases where ethdev is capable of enqueing
> packets
> to the eventdev (as was mentioned in Jerin's first RFC).
> 
> In case of hardware based eventdev and queues, these function should also invoke
> respective PMD
> HW configs. e.g. In queue case - rte_eventdev and rte_ethdev - both PMDs at hw level shall
> be configured.
> 
> A typical eventdev hardware will require queues of eth devices will be configured to
> directly attach to
> eventdev in the hardware.
> 
> Mapping it to NXP eventdev, enabling this functionality requires some configuration where
> dev private
> information of both the devices (event dev and eth dev) is required at the same time,
> and the final configuration is provided via eth device to H/W. So, this require inter
> device communication in DPDK.
> 
> Jerin,
> 
> I have an impression that Cavium hardware has H/W capability to inject packets from
> Ethernet
> devices to event devices? If yes, how do you plan to support it?
> 
> Thanks,
> Nipun

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-07-24 10:24               ` Jerin Jacob
@ 2017-07-24 11:37                 ` Nipun Gupta
  0 siblings, 0 replies; 41+ messages in thread
From: Nipun Gupta @ 2017-07-24 11:37 UTC (permalink / raw)
  To: Jerin Jacob
  Cc: Nikhil Rao, gage.eads, dev, thomas, bruce.richardson,
	harry.van.haaren, Hemant Agrawal, narender.vangati,
	Abhinandan Gujjar



> -----Original Message-----
> From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> Sent: Monday, July 24, 2017 15:54
> To: Nipun Gupta <nipun.gupta@nxp.com>
> Cc: Nikhil Rao <nikhil.rao@intel.com>; gage.eads@intel.com; dev@dpdk.org;
> thomas@monjalon.net; bruce.richardson@intel.com;
> harry.van.haaren@intel.com; Hemant Agrawal <hemant.agrawal@nxp.com>;
> narender.vangati@intel.com; Abhinandan Gujjar
> <abhinandan.gujjar@intel.com>
> Subject: Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> 
> -----Original Message-----
> > Date: Mon, 24 Jul 2017 10:10:50 +0000
> > From: Nipun Gupta <nipun.gupta@nxp.com>
> > To: Nikhil Rao <nikhil.rao@intel.com>, "jerin.jacob@caviumnetworks.com"
> >  <jerin.jacob@caviumnetworks.com>
> > CC: "gage.eads@intel.com" <gage.eads@intel.com>, "dev@dpdk.org"
> >  <dev@dpdk.org>, "thomas@monjalon.net" <thomas@monjalon.net>,
> >  "bruce.richardson@intel.com" <bruce.richardson@intel.com>,
> >  "harry.van.haaren@intel.com" <harry.van.haaren@intel.com>, Hemant
> Agrawal
> >  <hemant.agrawal@nxp.com>, "narender.vangati@intel.com"
> >  <narender.vangati@intel.com>, Abhinandan Gujjar
> >  <abhinandan.gujjar@intel.com>
> > Subject: RE: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> >
> > Looking at the rte_event_eth_rx_adapter_queue_add &
> event_eth_rx_adapter_service_func
> > it seems that this indeed will not fit with the cases where ethdev is capable of
> enqueing packets
> > to the eventdev (as was mentioned in Jerin's first RFC).
> >
> > In case of hardware based eventdev and queues, these function should also
> invoke respective PMD
> > HW configs. e.g. In queue case - rte_eventdev and rte_ethdev - both PMDs at
> hw level shall be configured.
> >
> > A typical eventdev hardware will require queues of eth devices will be
> configured to directly attach to
> > eventdev in the hardware.
> >
> > Mapping it to NXP eventdev, enabling this functionality requires some
> configuration where dev private
> > information of both the devices (event dev and eth dev) is required at the same
> time,
> > and the final configuration is provided via eth device to H/W. So, this require
> inter device communication in DPDK.
> 
> Just like dpaa2 bus layer functions used in another subsystems. You
> can export a function from ethdev dpaa2 to eventdev dpaa2 for ethdev rx queue
> to eventdev queue connection.

Yes! That could be done to resolve PMD interdependencies.

> 
> >
> > Jerin,
> >
> > I have an impression that Cavium hardware has H/W capability to inject
> packets from Ethernet
> > devices to event devices? If yes, how do you plan to support it?
> 
> Please check the latest review comments on this patch set
> http://dpdk.org/dev/patchwork/patch/26534/.
> 
> Nikhil is changing ops(function pointer) based approach. With that HW
> support can be added.

This looks great :). Somehow missed them.

Thanks,
Nipun

> 
> >
> > Thanks,
> > Nipun
> >

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-07-24 10:32               ` Van Haaren, Harry
@ 2017-07-24 13:06                 ` Nipun Gupta
  2017-07-24 13:33                   ` Van Haaren, Harry
  0 siblings, 1 reply; 41+ messages in thread
From: Nipun Gupta @ 2017-07-24 13:06 UTC (permalink / raw)
  To: Van Haaren, Harry, Rao, Nikhil, jerin.jacob
  Cc: Eads, Gage, dev, thomas, Richardson, Bruce, Hemant Agrawal,
	Vangati, Narender, Gujjar, Abhinandan S



> -----Original Message-----
> From: Van Haaren, Harry [mailto:harry.van.haaren@intel.com]
> Sent: Monday, July 24, 2017 16:03
> To: Nipun Gupta <nipun.gupta@nxp.com>; Rao, Nikhil <nikhil.rao@intel.com>;
> jerin.jacob@caviumnetworks.com
> Cc: Eads, Gage <gage.eads@intel.com>; dev@dpdk.org;
> thomas@monjalon.net; Richardson, Bruce <bruce.richardson@intel.com>;
> Hemant Agrawal <hemant.agrawal@nxp.com>; Vangati, Narender
> <narender.vangati@intel.com>; Gujjar, Abhinandan S
> <abhinandan.gujjar@intel.com>
> Subject: RE: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> 
> > From: Nipun Gupta [mailto:nipun.gupta@nxp.com]
> > Sent: Monday, July 24, 2017 11:11 AM
> > To: Rao, Nikhil <nikhil.rao@intel.com>; jerin.jacob@caviumnetworks.com
> > Cc: Eads, Gage <gage.eads@intel.com>; dev@dpdk.org;
> thomas@monjalon.net; Richardson, Bruce
> > <bruce.richardson@intel.com>; Van Haaren, Harry
> <harry.van.haaren@intel.com>; Hemant
> > Agrawal <hemant.agrawal@nxp.com>; Vangati, Narender
> <narender.vangati@intel.com>; Gujjar,
> > Abhinandan S <abhinandan.gujjar@intel.com>
> > Subject: RE: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> >
> > Hi Nikhil/Edas,
> 
> Hi All,
> 
> I'll reply on the service-cores topic, and leave the config to those more involved
> and familiar with them than I :)
> 
> > > -----Original Message-----
> > > From: Nikhil Rao [mailto:nikhil.rao@intel.com]
> > > Sent: Friday, July 07, 2017 3:23
> > > To: jerin.jacob@caviumnetworks.com
> > > Cc: gage.eads@intel.com; dev@dpdk.org; thomas@monjalon.net;
> > > bruce.richardson@intel.com; harry.van.haaren@intel.com; Hemant Agrawal
> > > <hemant.agrawal@nxp.com>; Nipun Gupta <nipun.gupta@nxp.com>;
> > > narender.vangati@intel.com; Nikhil Rao <nikhil.rao@intel.com>;
> Abhinandan
> > > Gujjar <abhinandan.gujjar@intel.com>
> > > Subject: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> > >
> > > Eventdev-based networking applications require a component to dequeue
> > > packets from NIC Rx queues and inject them into eventdev queues[1]. While
> > > some platforms (e.g. Cavium Octeontx) do this operation in hardware, other
> > > platforms use software.
> > >
> > > This patchset introduces an ethernet Rx event adapter that dequeues packets
> > > from ethernet devices and enqueues them to event devices. It is based on
> > > a previous RFC[2].
> > >
> > > The adapter is designed to work with the EAL service core[3]. If
> > > an application determines that the adapter is required, it can register and
> > > launch it on a service core. Alternatively, this adapter can serve as a
> > > template for applications to design customer ethernet Rx event adapters
> > > better suited to their needs.
> > >
> > > The adapter can service multiple ethernet devices and queues. Each queue is
> > > configured with a servicing weight to control the relative frequency with
> > > which the adapter polls the queue, and the event fields to use when
> > > constructing packet events. The adapter has two modes for programming an
> > > event's flow ID: use a static per-queue user-specified value or use the RSS
> > > hash.
> > >
> > > A detailed description of the adapter is contained in the header's
> > > comments.
> > >
> > > [1] http://dpdk.org/ml/archives/dev/2017-May/065341.html
> > > [2] http://dpdk.org/ml/archives/dev/2017-May/065539.html
> > > [3] http://dpdk.org/ml/archives/dev/2017-July/069782.html
> > >
> > > Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
> > > Signed-off-by: Gage Eads <gage.eads@intel.com>
> > > Signed-off-by: Abhinandan Gujjar <abhinandan.gujjar@intel.com>
> > > ---
> > >
> > > v2:
> > > Thanks Jerin for review - below is a list of changes you
> > > suggested.
> > >
> > > - all public symbols are started with rte_event_.
> > > - Add Doxygen reference with @see.
> > > - Mention setting of ev.event_type.
> > > - Mention adapter to service function mapping.
> > > - Remove rte_eth_rx_event_adapter_dev_add/del().
> > > - Change rx_queuee_id to int32_t and use -1 to denote all Rx queues.
> > > - Add rte_eth_event_rx_queue_del().
> > >
> > > Other changes
> > > - Remove adapter's run function (rte_event_eth_rx_adapter_run()) from
> > >   the public interface. The adapter internally uses it to create a
> > >   service.
> > > - Add a blocked cycle count to stats. Further description is contained
> > >   in the header.
> > > - Minor struct renames rte_event_eth_rx_adapter_config -> .._conf
> > > ---
> > >  lib/librte_eventdev/rte_event_eth_rx_adapter.h | 301 +++++++++
> > >  lib/librte_eventdev/rte_event_eth_rx_adapter.c | 825
> > > +++++++++++++++++++++++++
> > >  lib/librte_eventdev/rte_eventdev_version.map   |  13 +
> > >  lib/Makefile                                   |   2 +-
> > >  lib/librte_eventdev/Makefile                   |   2 +
> > >  5 files changed, 1142 insertions(+), 1 deletion(-)
> > >  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..5ccd0bd24
> > > --- /dev/null
> > > +++ b/lib/librte_eventdev/rte_event_eth_rx_adapter.h
> > > @@ -0,0 +1,301 @@
> > > +/*
> > > + *   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 ethernet Rx event adapter's role is to
> transfer
> > > + * mbufs from the ethernet receive queues managed by DPDK to an event
> > > device.
> > > + * The application uses the adapter APIs to configure the packet flow
> between
> > > + * the ethernet devices and event devices. The adapter is designed to work
> with
> > > + * the EAL service cores. The adapter's work can be parallelized by dividing
> the
> > > + * NIC Rx queues among multiple adapter services that run in parallel.
> >
> > First of all, apologies for commenting late on this. I am going through this
> patchset and
> > have some concerns over this.
> > It is mentioned that "The adapter is designed to work with * the EAL service
> cores"
> > Does this mean that the adapter cannot function without service core?
> > In the case where Ethdev HW is capable of injecting the packet to compatible
> HW eventdev
> > driver, there is no service
> > required. It seems this patchset does not take care of this use-case or maybe I
> am missing
> > something here?
> 
> 
> The "service cores" is a method of abstracting lcore requirements. In short, with
> a SW PMD, a service core is required to perform the event scheduling. With the
> HW use case as you describe, no core is required. So in the HW case, no service
> cores are allocated in DPDK, and as a result, all your cores are available to the
> application.
> 
> If I understand correctly, the generic "Event Ethernet RX Adapter" will register a
> service which needs to be run (by a service core) in order to perform SW polling
> of the NIC, and enqueue to the eventdev.
> 
> In order to support the hardware use-case, no service is registered and no
> service lcores required. The HW is allowed to perform the Ethdev -> Eventdev
> enqueue.
> 
> Hope that makes sense! -Harry

With function pointer based approach the adapter calls will be propagated to eventdev PMD so
here won't this way the event driver will be responsible for registering the service? I don't think the
generic 'Event ethernet Rx adapter' would register a service with this model.

Thanks,
Nipun

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-07-24 13:06                 ` Nipun Gupta
@ 2017-07-24 13:33                   ` Van Haaren, Harry
  0 siblings, 0 replies; 41+ messages in thread
From: Van Haaren, Harry @ 2017-07-24 13:33 UTC (permalink / raw)
  To: Nipun Gupta, Rao, Nikhil, jerin.jacob
  Cc: Eads, Gage, dev, thomas, Richardson, Bruce, Hemant Agrawal,
	Vangati, Narender, Gujjar, Abhinandan S

> From: Nipun Gupta [mailto:nipun.gupta@nxp.com]
> Sent: Monday, July 24, 2017 2:07 PM
> To: Van Haaren, Harry <harry.van.haaren@intel.com>; Rao, Nikhil <nikhil.rao@intel.com>;
> jerin.jacob@caviumnetworks.com
> Cc: Eads, Gage <gage.eads@intel.com>; dev@dpdk.org; thomas@monjalon.net; Richardson, Bruce
> <bruce.richardson@intel.com>; Hemant Agrawal <hemant.agrawal@nxp.com>; Vangati, Narender
> <narender.vangati@intel.com>; Gujjar, Abhinandan S <abhinandan.gujjar@intel.com>
> Subject: RE: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> 
> 
> 
> > -----Original Message-----
> > From: Van Haaren, Harry [mailto:harry.van.haaren@intel.com]
> > Sent: Monday, July 24, 2017 16:03
> > To: Nipun Gupta <nipun.gupta@nxp.com>; Rao, Nikhil <nikhil.rao@intel.com>;
> > jerin.jacob@caviumnetworks.com
> > Cc: Eads, Gage <gage.eads@intel.com>; dev@dpdk.org;
> > thomas@monjalon.net; Richardson, Bruce <bruce.richardson@intel.com>;
> > Hemant Agrawal <hemant.agrawal@nxp.com>; Vangati, Narender
> > <narender.vangati@intel.com>; Gujjar, Abhinandan S
> > <abhinandan.gujjar@intel.com>
> > Subject: RE: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> >
> > > From: Nipun Gupta [mailto:nipun.gupta@nxp.com]
> > > Sent: Monday, July 24, 2017 11:11 AM
> > > To: Rao, Nikhil <nikhil.rao@intel.com>; jerin.jacob@caviumnetworks.com
> > > Cc: Eads, Gage <gage.eads@intel.com>; dev@dpdk.org;
> > thomas@monjalon.net; Richardson, Bruce
> > > <bruce.richardson@intel.com>; Van Haaren, Harry
> > <harry.van.haaren@intel.com>; Hemant
> > > Agrawal <hemant.agrawal@nxp.com>; Vangati, Narender
> > <narender.vangati@intel.com>; Gujjar,
> > > Abhinandan S <abhinandan.gujjar@intel.com>
> > > Subject: RE: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> > >
> > > Hi Nikhil/Edas,
> >
> > Hi All,
> >
> > I'll reply on the service-cores topic, and leave the config to those more involved
> > and familiar with them than I :)
> >
> > > > -----Original Message-----
> > > > From: Nikhil Rao [mailto:nikhil.rao@intel.com]
> > > > Sent: Friday, July 07, 2017 3:23
> > > > To: jerin.jacob@caviumnetworks.com
> > > > Cc: gage.eads@intel.com; dev@dpdk.org; thomas@monjalon.net;
> > > > bruce.richardson@intel.com; harry.van.haaren@intel.com; Hemant Agrawal
> > > > <hemant.agrawal@nxp.com>; Nipun Gupta <nipun.gupta@nxp.com>;
> > > > narender.vangati@intel.com; Nikhil Rao <nikhil.rao@intel.com>;
> > Abhinandan
> > > > Gujjar <abhinandan.gujjar@intel.com>
> > > > Subject: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> > > >
> > > > Eventdev-based networking applications require a component to dequeue
> > > > packets from NIC Rx queues and inject them into eventdev queues[1]. While
> > > > some platforms (e.g. Cavium Octeontx) do this operation in hardware, other
> > > > platforms use software.
> > > >
> > > > This patchset introduces an ethernet Rx event adapter that dequeues packets
> > > > from ethernet devices and enqueues them to event devices. It is based on
> > > > a previous RFC[2].
> > > >
> > > > The adapter is designed to work with the EAL service core[3]. If
> > > > an application determines that the adapter is required, it can register and
> > > > launch it on a service core. Alternatively, this adapter can serve as a
> > > > template for applications to design customer ethernet Rx event adapters
> > > > better suited to their needs.
> > > >
> > > > The adapter can service multiple ethernet devices and queues. Each queue is
> > > > configured with a servicing weight to control the relative frequency with
> > > > which the adapter polls the queue, and the event fields to use when
> > > > constructing packet events. The adapter has two modes for programming an
> > > > event's flow ID: use a static per-queue user-specified value or use the RSS
> > > > hash.
> > > >
> > > > A detailed description of the adapter is contained in the header's
> > > > comments.
> > > >
> > > > [1] http://dpdk.org/ml/archives/dev/2017-May/065341.html
> > > > [2] http://dpdk.org/ml/archives/dev/2017-May/065539.html
> > > > [3] http://dpdk.org/ml/archives/dev/2017-July/069782.html
> > > >
> > > > Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
> > > > Signed-off-by: Gage Eads <gage.eads@intel.com>
> > > > Signed-off-by: Abhinandan Gujjar <abhinandan.gujjar@intel.com>
> > > > ---
> > > >
> > > > v2:
> > > > Thanks Jerin for review - below is a list of changes you
> > > > suggested.
> > > >
> > > > - all public symbols are started with rte_event_.
> > > > - Add Doxygen reference with @see.
> > > > - Mention setting of ev.event_type.
> > > > - Mention adapter to service function mapping.
> > > > - Remove rte_eth_rx_event_adapter_dev_add/del().
> > > > - Change rx_queuee_id to int32_t and use -1 to denote all Rx queues.
> > > > - Add rte_eth_event_rx_queue_del().
> > > >
> > > > Other changes
> > > > - Remove adapter's run function (rte_event_eth_rx_adapter_run()) from
> > > >   the public interface. The adapter internally uses it to create a
> > > >   service.
> > > > - Add a blocked cycle count to stats. Further description is contained
> > > >   in the header.
> > > > - Minor struct renames rte_event_eth_rx_adapter_config -> .._conf
> > > > ---
> > > >  lib/librte_eventdev/rte_event_eth_rx_adapter.h | 301 +++++++++
> > > >  lib/librte_eventdev/rte_event_eth_rx_adapter.c | 825
> > > > +++++++++++++++++++++++++
> > > >  lib/librte_eventdev/rte_eventdev_version.map   |  13 +
> > > >  lib/Makefile                                   |   2 +-
> > > >  lib/librte_eventdev/Makefile                   |   2 +
> > > >  5 files changed, 1142 insertions(+), 1 deletion(-)
> > > >  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..5ccd0bd24
> > > > --- /dev/null
> > > > +++ b/lib/librte_eventdev/rte_event_eth_rx_adapter.h
> > > > @@ -0,0 +1,301 @@
> > > > +/*
> > > > + *   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 ethernet Rx event adapter's role is to
> > transfer
> > > > + * mbufs from the ethernet receive queues managed by DPDK to an event
> > > > device.
> > > > + * The application uses the adapter APIs to configure the packet flow
> > between
> > > > + * the ethernet devices and event devices. The adapter is designed to work
> > with
> > > > + * the EAL service cores. The adapter's work can be parallelized by dividing
> > the
> > > > + * NIC Rx queues among multiple adapter services that run in parallel.
> > >
> > > First of all, apologies for commenting late on this. I am going through this
> > patchset and
> > > have some concerns over this.
> > > It is mentioned that "The adapter is designed to work with * the EAL service
> > cores"
> > > Does this mean that the adapter cannot function without service core?
> > > In the case where Ethdev HW is capable of injecting the packet to compatible
> > HW eventdev
> > > driver, there is no service
> > > required. It seems this patchset does not take care of this use-case or maybe I
> > am missing
> > > something here?
> >
> >
> > The "service cores" is a method of abstracting lcore requirements. In short, with
> > a SW PMD, a service core is required to perform the event scheduling. With the
> > HW use case as you describe, no core is required. So in the HW case, no service
> > cores are allocated in DPDK, and as a result, all your cores are available to the
> > application.
> >
> > If I understand correctly, the generic "Event Ethernet RX Adapter" will register a
> > service which needs to be run (by a service core) in order to perform SW polling
> > of the NIC, and enqueue to the eventdev.
> >
> > In order to support the hardware use-case, no service is registered and no
> > service lcores required. The HW is allowed to perform the Ethdev -> Eventdev
> > enqueue.
> >
> > Hope that makes sense! -Harry
> 
> With function pointer based approach the adapter calls will be propagated to eventdev PMD
> so
> here won't this way the event driver will be responsible for registering the service? I
> don't think the
> generic 'Event ethernet Rx adapter' would register a service with this model.

Good point - I should dig into code before replying. Yes, with the function-pointer / PMD model allows the PMD to decide if it requires a service.

Thanks for the correction!


> Thanks,
> Nipun

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-07-13 18:45                           ` Jerin Jacob
@ 2017-07-27 10:58                             ` Rao, Nikhil
  2017-07-29 15:12                               ` Jerin Jacob
  0 siblings, 1 reply; 41+ messages in thread
From: Rao, Nikhil @ 2017-07-27 10:58 UTC (permalink / raw)
  To: Jerin Jacob
  Cc: gage.eads, dev, thomas, bruce.richardson, harry.van.haaren,
	hemant.agrawal, nipun.gupta, narender.vangati, Abhinandan Gujjar,
	nikhil.rao


Hi Jerin and all,

There are a few inconsistencies/complexities that I ran into with the 
implementation of the SW Rx event adapter, I have first summarized this 
email thread bringing together details scattered across various 
exchanges then I want to check if there are changes possible that would 
simplify the implementation of the SW Rx event adapter.

</start summary>
The Rx event adapter needs to support the following scenarios:

1) Ethdev HW is not capable of injecting the packets and SW eventdev
driver(All existing ethdev PMD + drivers/event/sw PMD combination)
2) Ethdev HW is not capable of injecting the packets and not compatible
HW eventdev driver(All existing ethdev PMD + driver/event/octeontx PMD
combination)
3) Ethdev HW is capable of injecting the packet to compatible
HW eventdev driver.

cases 1) and 2) above are not different. In both cases we need a SW 
thread that will inject packets from the ethdev PMD to an event dev PMD.

The APIs proposed are:

int rte_event_eth_rx_adapter_create(uint8_t dev_id,
         uint8_t eth_port_id, uint8_t id /* adapter ID */);

An adapter created above has an ops struct, where the ops
struct provides implementations for the functions below.
The ops struct chosen for the adapter depends on the <dev_id, 
eth_port_id> combination.

struct rte_event_eth_rx_adap_info {
         uint32_t cap;

/* adapter has inbuilt port, no need to create producer port */
#define RTE_EVENT_ETHDEV_CAP_INBUILT_PORT  (1ULL << 0)
/* adapter does not need service function */
#define RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC (1ULL << 1)

}
int rte_event_eth_rx_adapter_get_info(uint8_t dev_id, uint8_t id,
             struct rte_event_eth_rx_adap_info *info);

struct rte_event_eth_rx_adapter_conf {
	/* Application specified service function name */
	char service_name[];
	uint8_t rx_event_port_id;
          /**< Event port identifier, the adapter enqueues mbuf
        * events to this
            * port, Ignored when RTE_EVENT_ETHDEV_CAP_INBUILT_PORT
            */
  }
int rte_event_eth_rx_adapter_configure(uint8_t dev_id, uint8_t id
             struct rte_event_eth_rx_adapter_conf *cfg);

  struct rte_event_eth_rx_adapter_queue_conf {
     ... event info ...
          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)
      */
     ...
  }
int rte_event_eth_rx_adapter_queue_add(uint8_t dev_id,
             uint8_t id, int32_t rx_queue_id,
     const struct rte_eth_rx_event_adapter_queue_conf *config);

int rte_event_eth_rx_adapter_queue_del(uint8_t dev_id,
             uint8_t id, int32_t rx_queue_id)

</end summary>

In the case of a SW thread we would like to use the servicing weight 
specified in the queue to do WRR across <ports, queues[]>, in keeping 
with the adaper per <eventdev, eth port> model, one way to do this is to 
use the same cfg.service_name in the 
rte_event_eth_rx_adapter_configure() call.

However this creates a few difficulties/inconsistencies:

1)Service has the notion of a socket id. Multiple event dev IDs can be 
included in the same service, each event dev has a socket ID -> this 
seems to be an inconsistency that shouldn’t be allowed by design.

2)Say, the Rx event adapter doesn’t drop packets (could be 
configurable), i.e,  if events cannot be enqueued into the event device, 
these remain in a buffer, when the buffer fills up packets aren’t 
dequeued from the eth device.

In the simplest case the Rx event adapter service has a single <event 
device, event port> across multiple eth ports, it dequeues from the 
wrr[] and buffers events, bulk enqueues BATCH_SIZE events into the 
<event device, event port>.

With adapters having different <event device, event port> code can be 
optimized so that adapters that have a common <event device, event port> 
can be made to refer to a common enqueue buffer { event dev, event port, 
buffer } structure but this adds more book keeping in the code.

3)Every adapter can be configured with max_nb_rx ( a max nb of packets 
that it can process in any invocation) – but the max_nb_rx seems like a 
service level parameter instead of it being a summation across adapters.

1 & 3 could be solved by restricting the adapters to the same (as in the 
first rte_event_eth_rx_adapter_configure() call) socket ID, and perhaps 
using the max value of max_nb_rx or using the same value of max_nb_rx 
across adapters. #2 is doable but has a bit of code complexity to handle 
the generic case.

Before we go there, I wanted to check if there is an alternative 
possible that would remove the difficulties above. Essentially allow 
multiple ports within an adapter but avoid the problem of the 
inconsistent <eventdev, port> combinations when using multiple ports 
with a single eventdev.

Instead of
==
rte_event_eth_rx_adapter_create()
rte_event_eth_rx_adapter_get_info();
rte_event_eth_rx_adapter_configure();
rte_event_eth_rx_adapter_queue_add();
==

How about ?
==

rte_event_eth_rx_adapter_get_info(uint8_t dev_id, uint8_t eth_port_id,
         struct rte_event_eth_rx_adap_info *info);

struct rte_event_eth_rx_adap_info {
         uint32_t cap;

/* adapter has inbuilt port, no need to create producer port */
#define RTE_EVENT_ETHDEV_CAP_INBUILT_PORT  (1ULL << 0)
/* adapter does not need service function */
#define RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC (1ULL << 1)

}

rte_event_eth_rx_adapter_conf cfg;
cfg.event_port = event_port;
cfg.service_name = “rx_adapter_service”;

// all ports in eth_port_id[] have cap = 
//!RTE_EVENT_ETHDEV_CAP_INBUILT_PORT
// && ! RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC
rte_event_eth_rx_adapter_create(dev_id, eth_port_id[], N, id, &cfg);
===
int rte_event_eth_rx_adapter_queue_add() would need a port id in the N>1 
port case, that can be ignored if the adapter doesn’t need it (N=1).

thanks for reading the long email, thoughts ?

Nikhil

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-07-27 10:58                             ` Rao, Nikhil
@ 2017-07-29 15:12                               ` Jerin Jacob
  2017-07-31  3:57                                 ` Nipun Gupta
  2017-08-01  8:40                                 ` Rao, Nikhil
  0 siblings, 2 replies; 41+ messages in thread
From: Jerin Jacob @ 2017-07-29 15:12 UTC (permalink / raw)
  To: Rao, Nikhil
  Cc: gage.eads, dev, thomas, bruce.richardson, harry.van.haaren,
	hemant.agrawal, nipun.gupta, narender.vangati, Abhinandan Gujjar

-----Original Message-----
> Date: Thu, 27 Jul 2017 16:28:29 +0530
> From: "Rao, Nikhil" <nikhil.rao@intel.com>
> To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> CC: gage.eads@intel.com, dev@dpdk.org, thomas@monjalon.net,
>  bruce.richardson@intel.com, harry.van.haaren@intel.com,
>  hemant.agrawal@nxp.com, nipun.gupta@nxp.com, narender.vangati@intel.com,
>  Abhinandan Gujjar <abhinandan.gujjar@intel.com>, nikhil.rao@intel.com
> Subject: Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101
>  Thunderbird/52.2.1
> 
> 
> 
> In the case of a SW thread we would like to use the servicing weight
> specified in the queue to do WRR across <ports, queues[]>, in keeping with

OK, then lets work together to address in transparent manner where it
works for HW and SW.

> the adaper per <eventdev, eth port> model, one way to do this is to use the
> same cfg.service_name in the rte_event_eth_rx_adapter_configure() call.
> 
> However this creates a few difficulties/inconsistencies:

I agree. If we are thinking about WRR across <ports,queues[]> then above
proposal implementation creates inconsistencies. On the other side, it create challenges
with HW implementation to have unified adapter API works for both HW and SW.

> 
> 1)Service has the notion of a socket id. Multiple event dev IDs can be
> included in the same service, each event dev has a socket ID -> this seems
> to be an inconsistency that shouldn’t be allowed by design.
> 
> 2)Say, the Rx event adapter doesn’t drop packets (could be configurable),
> i.e,  if events cannot be enqueued into the event device, these remain in a
> buffer, when the buffer fills up packets aren’t dequeued from the eth
> device.
> 
> In the simplest case the Rx event adapter service has a single <event
> device, event port> across multiple eth ports, it dequeues from the wrr[]
> and buffers events, bulk enqueues BATCH_SIZE events into the <event device,
> event port>.
> 
> With adapters having different <event device, event port> code can be
> optimized so that adapters that have a common <event device, event port> can
> be made to refer to a common enqueue buffer { event dev, event port, buffer
> } structure but this adds more book keeping in the code.
> 
> 3)Every adapter can be configured with max_nb_rx ( a max nb of packets that
> it can process in any invocation) – but the max_nb_rx seems like a service
> level parameter instead of it being a summation across adapters.
> 
> 1 & 3 could be solved by restricting the adapters to the same (as in the
> first rte_event_eth_rx_adapter_configure() call) socket ID, and perhaps
> using the max value of max_nb_rx or using the same value of max_nb_rx across
> adapters. #2 is doable but has a bit of code complexity to handle the
> generic case.
> 
> Before we go there, I wanted to check if there is an alternative possible
> that would remove the difficulties above. Essentially allow multiple ports
> within an adapter but avoid the problem of the inconsistent <eventdev, port>
> combinations when using multiple ports with a single eventdev.
> 
> Instead of
> ==
> rte_event_eth_rx_adapter_create()
> rte_event_eth_rx_adapter_get_info();
> rte_event_eth_rx_adapter_configure();
> rte_event_eth_rx_adapter_queue_add();
> ==
> 
> How about ?
> ==
> 
> rte_event_eth_rx_adapter_get_info(uint8_t dev_id, uint8_t eth_port_id,
>         struct rte_event_eth_rx_adap_info *info);
> 
> struct rte_event_eth_rx_adap_info {
>         uint32_t cap;
> 
> /* adapter has inbuilt port, no need to create producer port */
> #define RTE_EVENT_ETHDEV_CAP_INBUILT_PORT  (1ULL << 0)
> /* adapter does not need service function */
> #define RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC (1ULL << 1)
> 
> }
> 
> rte_event_eth_rx_adapter_conf cfg;
> cfg.event_port = event_port;
> cfg.service_name = “rx_adapter_service”;

Does application need to specify the service name? IMO, it better a
component(rx_adapter) defines it name and format and expose in rte_event_eth_rx_adapter.h

> 
> // all ports in eth_port_id[] have cap =
> //!RTE_EVENT_ETHDEV_CAP_INBUILT_PORT
> // && ! RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC
> rte_event_eth_rx_adapter_create(dev_id, eth_port_id[], N, id, &cfg);

The downside might be:
- application has different flow based on based on the capability.
Listing down a few capabilities/limitation below.

> ===
> int rte_event_eth_rx_adapter_queue_add() would need a port id in the N>1
> port case, that can be ignored if the adapter doesn’t need it (N=1).
> 
> thanks for reading the long email, thoughts ?

I have bit another thought to solve the above mentioned downside.

- Theme is based on your original rx adapter proposal but with eventpmd
  ops(not adapter ops).i.e Reuse as much of your existing Rx adapter
implementation as common code and add hooks for HW based adapters. For
example, before you add  <ethdev, queue_id> to "rx_poll" in eth_poll_wrr_calc(),
Check for eventdev PMD ops is available adding it HW. If yes, Don't add in "rx_poll"

adapter_api
------------
int rte_event_eth_rx_adapter_create(id, rte_event_eth_rx_adapter_conf *conf)
int rte_event_eth_rx_adapter_queue_add(uint8_t id, uint8_t eth_dev_id, int32_t rx_queue_id, rte_event_eth_rx_adapter_queue_conf *conf);

eventdev PMD op api(not as adapter PMD as discussed earlier)
-------------------

1) typedef uint64_t (*eventdev_rx_adap_capa)(struct rte_eventdev *dev,  uint8_t ethdev_id)

Return the adapter capability of a given eventdev when it needs to
connected to a specific ethdev_id

Possible capability values based on my understating for existing SW and Cavium
HW PMD. NXP folks can add new ones.

- RX_ADAPTER_CAP_INBUILT_PORT - /* adapter has inbuilt port, no need to create producer port by common code */
- RX_ADAPTER_CAP_SET_FLOW_ID  - /* adapter capable of setting RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID */
- RX_ADAPTER_CAP_ADD_QUEUE /* adapter capable of adding any specific
ethdev rx queue to any eventdev queue. Some eventdev PMD has a limitation
that once a < ethdev_id , queue_id> connected to specific eventdev queue,
all the all queues_id under the same ethdev_id need to be connected to
same eventdev queue. aka works only on the rte_event_eth_rx_adapter_queue_conf.rx_queue_id == -1 mode, */


2) typedef int (*eventdev_rx_adap_add)(struct rte_eventdev *dev,  uint8_t ethdev_id, int queue_id, rte_event_eth_rx_adapter_queue_conf *conf));
-- if implemented by eventdev PMD and returns zero then COMMON code does not need to poll */


3) typedef int (*eventdev_rx_adap_del)(struct rte_eventdev *dev,  uint8_t ethdev_id, int queue_id)
-- remove previously added


*** Haven't spend a lot of time on API/macro name.Please use better naming conversion.


Another notes based on your existing implementation  + eventdev ops scheme

1) rte_event_eth_rx_adapter_creates() registers service function by
default. It should be delayed to when common adapter code find a device
with !RX_ADAPTER_CAP_INBUILT_PORT cap on rte_event_eth_rx_adapter_queue_add()

2) Do we need rx_adapter start/stop functions?

3) If it happens to be case where rte_event_eth_rx_adapter_queue_add()
use only RX_ADAPTER_CAP_INBUILT_PORT then common code should not
create any service.

4) If adapter uses one port with service core and other one with HW
adapter. rte_event_eth_rx_adapter_stats.rx_packets will be not updated
correctly, We need eventdev PMD ops to get those stats. If we agree
overall PMD ops + adapter API partitioning then we can refine additionally
eventpmd for stats etc or xstat based scheme etc.

5) specifying rte_event_eth_rx_adapter_conf.rx_event_port_id on
rte_event_eth_rx_adapter_create() would waste one HW eventdev port if its
happen to be used RX_ADAPTER_CAP_INBUILT_PORT on rte_event_eth_rx_adapter_queue_add().
unlike SW eventdev port, HW eventdev ports are costly so I think, We
need to have another eventdev PMD ops to create service/producer ports.
Or any other scheme that creates rte_event_eth_rx_adapter_conf.rx_event_port_id
on demand by common code.

Thoughts?

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-07-29 15:12                               ` Jerin Jacob
@ 2017-07-31  3:57                                 ` Nipun Gupta
  2017-07-31 15:31                                   ` Jerin Jacob
  2017-08-01  8:40                                 ` Rao, Nikhil
  1 sibling, 1 reply; 41+ messages in thread
From: Nipun Gupta @ 2017-07-31  3:57 UTC (permalink / raw)
  To: Jerin Jacob, Rao, Nikhil
  Cc: gage.eads, dev, thomas, bruce.richardson, harry.van.haaren,
	Hemant Agrawal, narender.vangati, Abhinandan Gujjar



> -----Original Message-----
> From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> Sent: Saturday, July 29, 2017 20:43
> To: Rao, Nikhil <nikhil.rao@intel.com>
> Cc: gage.eads@intel.com; dev@dpdk.org; thomas@monjalon.net;
> bruce.richardson@intel.com; harry.van.haaren@intel.com; Hemant Agrawal
> <hemant.agrawal@nxp.com>; Nipun Gupta <nipun.gupta@nxp.com>;
> narender.vangati@intel.com; Abhinandan Gujjar
> <abhinandan.gujjar@intel.com>
> Subject: Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> 
> -----Original Message-----
> > Date: Thu, 27 Jul 2017 16:28:29 +0530
> > From: "Rao, Nikhil" <nikhil.rao@intel.com>
> > To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> > CC: gage.eads@intel.com, dev@dpdk.org, thomas@monjalon.net,
> >  bruce.richardson@intel.com, harry.van.haaren@intel.com,
> >  hemant.agrawal@nxp.com, nipun.gupta@nxp.com,
> narender.vangati@intel.com,
> >  Abhinandan Gujjar <abhinandan.gujjar@intel.com>, nikhil.rao@intel.com
> > Subject: Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> > User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0)
> Gecko/20100101
> >  Thunderbird/52.2.1
> >
> >
> >
> > In the case of a SW thread we would like to use the servicing weight
> > specified in the queue to do WRR across <ports, queues[]>, in keeping with
> 
> OK, then lets work together to address in transparent manner where it
> works for HW and SW.
> 
> > the adaper per <eventdev, eth port> model, one way to do this is to use the
> > same cfg.service_name in the rte_event_eth_rx_adapter_configure() call.
> >
> > However this creates a few difficulties/inconsistencies:
> 
> I agree. If we are thinking about WRR across <ports,queues[]> then above
> proposal implementation creates inconsistencies. On the other side, it create
> challenges
> with HW implementation to have unified adapter API works for both HW and
> SW.
> 
> >
> > 1)Service has the notion of a socket id. Multiple event dev IDs can be
> > included in the same service, each event dev has a socket ID -> this seems
> > to be an inconsistency that shouldn’t be allowed by design.
> >
> > 2)Say, the Rx event adapter doesn’t drop packets (could be configurable),
> > i.e,  if events cannot be enqueued into the event device, these remain in a
> > buffer, when the buffer fills up packets aren’t dequeued from the eth
> > device.
> >
> > In the simplest case the Rx event adapter service has a single <event
> > device, event port> across multiple eth ports, it dequeues from the wrr[]
> > and buffers events, bulk enqueues BATCH_SIZE events into the <event device,
> > event port>.
> >
> > With adapters having different <event device, event port> code can be
> > optimized so that adapters that have a common <event device, event port>
> can
> > be made to refer to a common enqueue buffer { event dev, event port, buffer
> > } structure but this adds more book keeping in the code.
> >
> > 3)Every adapter can be configured with max_nb_rx ( a max nb of packets that
> > it can process in any invocation) – but the max_nb_rx seems like a service
> > level parameter instead of it being a summation across adapters.
> >
> > 1 & 3 could be solved by restricting the adapters to the same (as in the
> > first rte_event_eth_rx_adapter_configure() call) socket ID, and perhaps
> > using the max value of max_nb_rx or using the same value of max_nb_rx
> across
> > adapters. #2 is doable but has a bit of code complexity to handle the
> > generic case.
> >
> > Before we go there, I wanted to check if there is an alternative possible
> > that would remove the difficulties above. Essentially allow multiple ports
> > within an adapter but avoid the problem of the inconsistent <eventdev, port>
> > combinations when using multiple ports with a single eventdev.
> >
> > Instead of
> > ==
> > rte_event_eth_rx_adapter_create()
> > rte_event_eth_rx_adapter_get_info();
> > rte_event_eth_rx_adapter_configure();
> > rte_event_eth_rx_adapter_queue_add();
> > ==
> >
> > How about ?
> > ==
> >
> > rte_event_eth_rx_adapter_get_info(uint8_t dev_id, uint8_t eth_port_id,
> >         struct rte_event_eth_rx_adap_info *info);
> >
> > struct rte_event_eth_rx_adap_info {
> >         uint32_t cap;
> >
> > /* adapter has inbuilt port, no need to create producer port */
> > #define RTE_EVENT_ETHDEV_CAP_INBUILT_PORT  (1ULL << 0)
> > /* adapter does not need service function */
> > #define RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC (1ULL << 1)
> >
> > }
> >
> > rte_event_eth_rx_adapter_conf cfg;
> > cfg.event_port = event_port;
> > cfg.service_name = “rx_adapter_service”;
> 
> Does application need to specify the service name? IMO, it better a
> component(rx_adapter) defines it name and format and expose in
> rte_event_eth_rx_adapter.h
> 
> >
> > // all ports in eth_port_id[] have cap =
> > //!RTE_EVENT_ETHDEV_CAP_INBUILT_PORT
> > // && ! RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC
> > rte_event_eth_rx_adapter_create(dev_id, eth_port_id[], N, id, &cfg);
> 
> The downside might be:
> - application has different flow based on based on the capability.
> Listing down a few capabilities/limitation below.
> 
> > ===
> > int rte_event_eth_rx_adapter_queue_add() would need a port id in the N>1
> > port case, that can be ignored if the adapter doesn’t need it (N=1).
> >
> > thanks for reading the long email, thoughts ?
> 
> I have bit another thought to solve the above mentioned downside.
> 
> - Theme is based on your original rx adapter proposal but with eventpmd
>   ops(not adapter ops).i.e Reuse as much of your existing Rx adapter
> implementation as common code and add hooks for HW based adapters. For
> example, before you add  <ethdev, queue_id> to "rx_poll" in
> eth_poll_wrr_calc(),
> Check for eventdev PMD ops is available adding it HW. If yes, Don't add in
> "rx_poll"

This seems better approach. Infact we were also thinking on similar approach while
reviewing the initial patch. This will also avoid redundant code for creation of services
by separate event PMD's.

> 
> adapter_api
> ------------
> int rte_event_eth_rx_adapter_create(id, rte_event_eth_rx_adapter_conf *conf)
> int rte_event_eth_rx_adapter_queue_add(uint8_t id, uint8_t eth_dev_id, int32_t
> rx_queue_id, rte_event_eth_rx_adapter_queue_conf *conf);

Just wanted to know your opinion on adding other adapters such as for crypto devices.

One way is to create separate adapter for crypto devices (or any other devices which may
be linked with event devices). But this would again cause redundancy in service creations.

In my opinion these API's can be independent of "_eth" suffix and have an enum of "device
type" in adapter_capablity, queue_add and queue_delete API, so that the model is not
limited for one type of device. For this series only ethernet type be supported but having
possibility of adding other devices in future.

Views on this?

> 
> eventdev PMD op api(not as adapter PMD as discussed earlier)
> -------------------
> 
> 1) typedef uint64_t (*eventdev_rx_adap_capa)(struct rte_eventdev *dev,
> uint8_t ethdev_id)
> 
> Return the adapter capability of a given eventdev when it needs to
> connected to a specific ethdev_id
> 
> Possible capability values based on my understating for existing SW and Cavium
> HW PMD. NXP folks can add new ones.
> 
> - RX_ADAPTER_CAP_INBUILT_PORT - /* adapter has inbuilt port, no need to
> create producer port by common code */
> - RX_ADAPTER_CAP_SET_FLOW_ID  - /* adapter capable of setting
> RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID */
> - RX_ADAPTER_CAP_ADD_QUEUE /* adapter capable of adding any specific
> ethdev rx queue to any eventdev queue. Some eventdev PMD has a limitation
> that once a < ethdev_id , queue_id> connected to specific eventdev queue,
> all the all queues_id under the same ethdev_id need to be connected to
> same eventdev queue. aka works only on the
> rte_event_eth_rx_adapter_queue_conf.rx_queue_id == -1 mode, */

These are more than sufficient for NXP's PMD's :)

> 
> 
> 2) typedef int (*eventdev_rx_adap_add)(struct rte_eventdev *dev,  uint8_t
> ethdev_id, int queue_id, rte_event_eth_rx_adapter_queue_conf *conf));
> -- if implemented by eventdev PMD and returns zero then COMMON code does
> not need to poll */
> 
> 
> 3) typedef int (*eventdev_rx_adap_del)(struct rte_eventdev *dev,  uint8_t
> ethdev_id, int queue_id)
> -- remove previously added
> 
> 
> *** Haven't spend a lot of time on API/macro name.Please use better naming
> conversion.
> 
> 
> Another notes based on your existing implementation  + eventdev ops scheme
> 
> 1) rte_event_eth_rx_adapter_creates() registers service function by
> default. It should be delayed to when common adapter code find a device
> with !RX_ADAPTER_CAP_INBUILT_PORT cap on
> rte_event_eth_rx_adapter_queue_add()
> 
> 2) Do we need rx_adapter start/stop functions?
> 
> 3) If it happens to be case where rte_event_eth_rx_adapter_queue_add()
> use only RX_ADAPTER_CAP_INBUILT_PORT then common code should not
> create any service.
> 
> 4) If adapter uses one port with service core and other one with HW
> adapter. rte_event_eth_rx_adapter_stats.rx_packets will be not updated
> correctly, We need eventdev PMD ops to get those stats. If we agree
> overall PMD ops + adapter API partitioning then we can refine additionally
> eventpmd for stats etc or xstat based scheme etc.

Can't the stats be summed up from the eventdev (if ops is implemented) and from 
the service running for this. Agree that xstats would be more beneficial.

Thanks,
Nipun

> 
> 5) specifying rte_event_eth_rx_adapter_conf.rx_event_port_id on
> rte_event_eth_rx_adapter_create() would waste one HW eventdev port if its
> happen to be used RX_ADAPTER_CAP_INBUILT_PORT on
> rte_event_eth_rx_adapter_queue_add().
> unlike SW eventdev port, HW eventdev ports are costly so I think, We
> need to have another eventdev PMD ops to create service/producer ports.
> Or any other scheme that creates
> rte_event_eth_rx_adapter_conf.rx_event_port_id
> on demand by common code.
> 
> Thoughts?


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-07-31  3:57                                 ` Nipun Gupta
@ 2017-07-31 15:31                                   ` Jerin Jacob
  0 siblings, 0 replies; 41+ messages in thread
From: Jerin Jacob @ 2017-07-31 15:31 UTC (permalink / raw)
  To: Nipun Gupta
  Cc: Rao, Nikhil, gage.eads, dev, thomas, bruce.richardson,
	harry.van.haaren, Hemant Agrawal, narender.vangati,
	Abhinandan Gujjar

> > - Theme is based on your original rx adapter proposal but with eventpmd
> >   ops(not adapter ops).i.e Reuse as much of your existing Rx adapter
> > implementation as common code and add hooks for HW based adapters. For
> > example, before you add  <ethdev, queue_id> to "rx_poll" in
> > eth_poll_wrr_calc(),
> > Check for eventdev PMD ops is available adding it HW. If yes, Don't add in
> > "rx_poll"
> 
> This seems better approach. Infact we were also thinking on similar approach while
> reviewing the initial patch. This will also avoid redundant code for creation of services
> by separate event PMD's.
> 
> > 
> > adapter_api
> > ------------
> > int rte_event_eth_rx_adapter_create(id, rte_event_eth_rx_adapter_conf *conf)
> > int rte_event_eth_rx_adapter_queue_add(uint8_t id, uint8_t eth_dev_id, int32_t
> > rx_queue_id, rte_event_eth_rx_adapter_queue_conf *conf);
> 
> Just wanted to know your opinion on adding other adapters such as for crypto devices.
> 
> One way is to create separate adapter for crypto devices (or any other devices which may
> be linked with event devices). But this would again cause redundancy in service creations.
> 
> In my opinion these API's can be independent of "_eth" suffix and have an enum of "device
> type" in adapter_capablity, queue_add and queue_delete API, so that the model is not
> limited for one type of device. For this series only ethernet type be supported but having
> possibility of adding other devices in future.
> 
> Views on this?

For timer adapter, we will have fastpath API like , "arming" and "canceling"
the timers. IMO, semantically which will be different from eth_rx or
crypto adapter for the creation side.So may it be worth to have separate
adapter API for each subsystem to address the specific
requirements.(timer adapter may have resolution, max timeout etc
configuration parameters on adapter create())




> 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-07-29 15:12                               ` Jerin Jacob
  2017-07-31  3:57                                 ` Nipun Gupta
@ 2017-08-01  8:40                                 ` Rao, Nikhil
  2017-08-01 16:42                                   ` Jerin Jacob
  1 sibling, 1 reply; 41+ messages in thread
From: Rao, Nikhil @ 2017-08-01  8:40 UTC (permalink / raw)
  To: Jerin Jacob
  Cc: gage.eads, dev, thomas, bruce.richardson, harry.van.haaren,
	hemant.agrawal, nipun.gupta, narender.vangati, Abhinandan Gujjar

On 7/29/2017 8:42 PM, Jerin Jacob wrote:
> -----Original Message-----
>> Date: Thu, 27 Jul 2017 16:28:29 +0530
>> From: "Rao, Nikhil" <nikhil.rao@intel.com>
>> To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
>> CC: gage.eads@intel.com, dev@dpdk.org, thomas@monjalon.net,
>>   bruce.richardson@intel.com, harry.van.haaren@intel.com,
>>   hemant.agrawal@nxp.com, nipun.gupta@nxp.com, narender.vangati@intel.com,
>>   Abhinandan Gujjar <abhinandan.gujjar@intel.com>, nikhil.rao@intel.com
>> Subject: Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
>> User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101
>>   Thunderbird/52.2.1
>>
>>
>>
>> In the case of a SW thread we would like to use the servicing weight
>> specified in the queue to do WRR across <ports, queues[]>, in keeping with
> 
> OK, then lets work together to address in transparent manner where it
> works for HW and SW.
> 
>> the adaper per <eventdev, eth port> model, one way to do this is to use the
>> same cfg.service_name in the rte_event_eth_rx_adapter_configure() call.
>>
>> However this creates a few difficulties/inconsistencies:
> 
> I agree. If we are thinking about WRR across <ports,queues[]> then above
> proposal implementation creates inconsistencies. On the other side, it create challenges
> with HW implementation to have unified adapter API works for both HW and SW.
> 
>>
>> 1)Service has the notion of a socket id. Multiple event dev IDs can be
>> included in the same service, each event dev has a socket ID -> this seems
>> to be an inconsistency that shouldn’t be allowed by design.
>>
>> 2)Say, the Rx event adapter doesn’t drop packets (could be configurable),
>> i.e,  if events cannot be enqueued into the event device, these remain in a
>> buffer, when the buffer fills up packets aren’t dequeued from the eth
>> device.
>>
>> In the simplest case the Rx event adapter service has a single <event
>> device, event port> across multiple eth ports, it dequeues from the wrr[]
>> and buffers events, bulk enqueues BATCH_SIZE events into the <event device,
>> event port>.
>>
>> With adapters having different <event device, event port> code can be
>> optimized so that adapters that have a common <event device, event port> can
>> be made to refer to a common enqueue buffer { event dev, event port, buffer
>> } structure but this adds more book keeping in the code.
>>
>> 3)Every adapter can be configured with max_nb_rx ( a max nb of packets that
>> it can process in any invocation) – but the max_nb_rx seems like a service
>> level parameter instead of it being a summation across adapters.
>>
>> 1 & 3 could be solved by restricting the adapters to the same (as in the
>> first rte_event_eth_rx_adapter_configure() call) socket ID, and perhaps
>> using the max value of max_nb_rx or using the same value of max_nb_rx across
>> adapters. #2 is doable but has a bit of code complexity to handle the
>> generic case.
>>
>> Before we go there, I wanted to check if there is an alternative possible
>> that would remove the difficulties above. Essentially allow multiple ports
>> within an adapter but avoid the problem of the inconsistent <eventdev, port>
>> combinations when using multiple ports with a single eventdev.
>>
>> Instead of
>> ==
>> rte_event_eth_rx_adapter_create()
>> rte_event_eth_rx_adapter_get_info();
>> rte_event_eth_rx_adapter_configure();
>> rte_event_eth_rx_adapter_queue_add();
>> ==
>>
>> How about ?
>> ==
>>
>> rte_event_eth_rx_adapter_get_info(uint8_t dev_id, uint8_t eth_port_id,
>>          struct rte_event_eth_rx_adap_info *info);
>>
>> struct rte_event_eth_rx_adap_info {
>>          uint32_t cap;
>>
>> /* adapter has inbuilt port, no need to create producer port */
>> #define RTE_EVENT_ETHDEV_CAP_INBUILT_PORT  (1ULL << 0)
>> /* adapter does not need service function */
>> #define RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC (1ULL << 1)
>>
>> }
>>
>> rte_event_eth_rx_adapter_conf cfg;
>> cfg.event_port = event_port;
>> cfg.service_name = “rx_adapter_service”;
> 
> Does application need to specify the service name? IMO, it better a
> component(rx_adapter) defines it name and format and expose in rte_event_eth_rx_adapter.h
> 

I have had the application specify the name. so that it can call

struct rte_service_spec *rte_service_get_by_name(const char *name);

followed by
int32_t rte_service_enable_on_lcore(struct rte_service_spec *service,
                                    uint32_t lcore);

given that the application knows the socket id of the event device 
associated with the adapter.

>>
>> // all ports in eth_port_id[] have cap =
>> //!RTE_EVENT_ETHDEV_CAP_INBUILT_PORT
>> // && ! RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC
>> rte_event_eth_rx_adapter_create(dev_id, eth_port_id[], N, id, &cfg);
> 
> The downside might be:
> - application has different flow based on based on the capability.
> Listing down a few capabilities/limitation below.
> 
>> ===
>> int rte_event_eth_rx_adapter_queue_add() would need a port id in the N>1
>> port case, that can be ignored if the adapter doesn’t need it (N=1).
>>
>> thanks for reading the long email, thoughts ?
> 
> I have bit another thought to solve the above mentioned downside.
> 
> - Theme is based on your original rx adapter proposal but with eventpmd
>    ops(not adapter ops).i.e Reuse as much of your existing Rx adapter
> implementation as common code and add hooks for HW based adapters. For
> example, before you add  <ethdev, queue_id> to "rx_poll" in eth_poll_wrr_calc(),
> Check for eventdev PMD ops is available adding it HW. If yes, Don't add in "rx_poll"
> 
> adapter_api
> ------------
> int rte_event_eth_rx_adapter_create(id, rte_event_eth_rx_adapter_conf *conf)
> int rte_event_eth_rx_adapter_queue_add(uint8_t id, uint8_t eth_dev_id, int32_t rx_queue_id, rte_event_eth_rx_adapter_queue_conf *conf);
> 
> eventdev PMD op api(not as adapter PMD as discussed earlier)
> -------------------
> 
> 1) typedef uint64_t (*eventdev_rx_adap_capa)(struct rte_eventdev *dev,  uint8_t ethdev_id)
> 
> Return the adapter capability of a given eventdev when it needs to
> connected to a specific ethdev_id
> 

Doesn't the capability of a <eventdev, ethdev> also need to be made 
available to the application as an adapter API ?

for e.g., so the application can call 
rte_event_eth_rx_adapter_queue_add() with rx_queue_id = -1 if 
RX_ADAPTER_CAP_ADD_QUEUE is not set.

In the same manner, if I understand RX_ADAPTER_CAP_SET_FLOW_ID, the 
application would have provide a flow ID in 
rte_event_eth_rx_adapter_queue_add(), if RX_ADAPTER_CAP_SET_FLOW_ID is 
not set.

Also if a given <eventdev, ethdev> are connected in HW then is the 
servicing weight of a queue applicable ?

> Possible capability values based on my understating for existing SW and Cavium
> HW PMD. NXP folks can add new ones.
> 
> - RX_ADAPTER_CAP_INBUILT_PORT - /* adapter has inbuilt port, no need to create producer port by common code */
> - RX_ADAPTER_CAP_SET_FLOW_ID  - /* adapter capable of setting RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID */
> - RX_ADAPTER_CAP_ADD_QUEUE /* adapter capable of adding any specific
> ethdev rx queue to any eventdev queue. Some eventdev PMD has a limitation
> that once a < ethdev_id , queue_id> connected to specific eventdev queue,
> all the all queues_id under the same ethdev_id need to be connected to
> same eventdev queue. aka works only on the rte_event_eth_rx_adapter_queue_conf.rx_queue_id == -1 mode, */
> 
> 
> 2) typedef int (*eventdev_rx_adap_add)(struct rte_eventdev *dev,  uint8_t ethdev_id, int queue_id, rte_event_eth_rx_adapter_queue_conf *conf));
> -- if implemented by eventdev PMD and returns zero then COMMON code does not need to poll */
> 
> 
> 3) typedef int (*eventdev_rx_adap_del)(struct rte_eventdev *dev,  uint8_t ethdev_id, int queue_id)
> -- remove previously added
> 
> 
> *** Haven't spend a lot of time on API/macro name.Please use better naming conversion.
> 
> 
> Another notes based on your existing implementation  + eventdev ops scheme
> 
> 1) rte_event_eth_rx_adapter_creates() registers service function by
> default. It should be delayed to when common adapter code find a device
> with !RX_ADAPTER_CAP_INBUILT_PORT cap on rte_event_eth_rx_adapter_queue_add()
> 
> 2) Do we need rx_adapter start/stop functions?

Yes.

> 
> 3) If it happens to be case where rte_event_eth_rx_adapter_queue_add()
> use only RX_ADAPTER_CAP_INBUILT_PORT then common code should not
> create any service.

Yes.
> 
> 4) If adapter uses one port with service core and other one with HW
> adapter. rte_event_eth_rx_adapter_stats.rx_packets will be not updated
> correctly, We need eventdev PMD ops to get those stats. If we agree
> overall PMD ops + adapter API partitioning then we can refine additionally
> eventpmd for stats etc or xstat based scheme etc.

Wouldnt the rx_packets be the sum of the service core thread packet 
count and the count provided by the eventdev pmd ops and be obtained 
from a call to

rte_event_eth_rx_adapter_stats_get(uint8_t id,
	struct rte_event_eth_rx_adapter_stats *stats);

> 
> 5) specifying rte_event_eth_rx_adapter_conf.rx_event_port_id on
> rte_event_eth_rx_adapter_create() would waste one HW eventdev port if its
> happen to be used RX_ADAPTER_CAP_INBUILT_PORT on rte_event_eth_rx_adapter_queue_add().
> unlike SW eventdev port, HW eventdev ports are costly so I think, We
> need to have another eventdev PMD ops to create service/producer ports.
> Or any other scheme that creates rte_event_eth_rx_adapter_conf.rx_event_port_id
> on demand by common code.
> 

One solution is:

struct rte_event_eth_rx_adapter_conf {
     uint8_t dev_id;

     int (*conf_cb)(uint8_t id, uint8_t port_id, uint32_t flags, struct 
rte_event_eth_rx_adapter_conf *conf);

     unsigned int max_nb_rx;

     int event_port_id;

     char service_name[];
}

Where dev_id and conf_cb have to be specified in the create call, but 
event_port_id and service_name will be filled in when conf_cb() is 
invoked if required. flags will specify what parameters of conf need to 
be filled in. The conf parameter can be separated into a different

struct rte_event_eth_rx_adapter_ext_conf {
     unsigned int max_nb_rx;

     int event_port_id;

     char service_name[];
}

Nikhil

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-08-01  8:40                                 ` Rao, Nikhil
@ 2017-08-01 16:42                                   ` Jerin Jacob
  2017-08-02 19:19                                     ` Eads, Gage
  2017-08-11  5:25                                     ` Rao, Nikhil
  0 siblings, 2 replies; 41+ messages in thread
From: Jerin Jacob @ 2017-08-01 16:42 UTC (permalink / raw)
  To: Rao, Nikhil
  Cc: gage.eads, dev, thomas, bruce.richardson, harry.van.haaren,
	hemant.agrawal, nipun.gupta, narender.vangati, Abhinandan Gujjar

> > > 
> > > Instead of
> > > ==
> > > rte_event_eth_rx_adapter_create()
> > > rte_event_eth_rx_adapter_get_info();
> > > rte_event_eth_rx_adapter_configure();
> > > rte_event_eth_rx_adapter_queue_add();
> > > ==
> > > 
> > > How about ?
> > > ==
> > > 
> > > rte_event_eth_rx_adapter_get_info(uint8_t dev_id, uint8_t eth_port_id,
> > >          struct rte_event_eth_rx_adap_info *info);
> > > 
> > > struct rte_event_eth_rx_adap_info {
> > >          uint32_t cap;
> > > 
> > > /* adapter has inbuilt port, no need to create producer port */
> > > #define RTE_EVENT_ETHDEV_CAP_INBUILT_PORT  (1ULL << 0)
> > > /* adapter does not need service function */
> > > #define RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC (1ULL << 1)
> > > 
> > > }
> > > 
> > > rte_event_eth_rx_adapter_conf cfg;
> > > cfg.event_port = event_port;
> > > cfg.service_name = “rx_adapter_service”;
> > 
> > Does application need to specify the service name? IMO, it better a
> > component(rx_adapter) defines it name and format and expose in rte_event_eth_rx_adapter.h
> > 
> 
> I have had the application specify the name. so that it can call
> 
> struct rte_service_spec *rte_service_get_by_name(const char *name);

OK. I was thinking like there will be fixed name for the rx_adapter
service like "eth_rx_adapter_%d"(%d for adapter id) which be exposed in
rte_event_eth_rx_adapter.h.
It can help in removing cfg.service_name. I am fine with either way.

> 
> followed by
> int32_t rte_service_enable_on_lcore(struct rte_service_spec *service,
>                                    uint32_t lcore);
> 
> given that the application knows the socket id of the event device
> associated with the adapter.
> 
> > > 
> > > // all ports in eth_port_id[] have cap =
> > > //!RTE_EVENT_ETHDEV_CAP_INBUILT_PORT
> > > // && ! RTE_EVENT_ETHDEV_CAP_NO_SERVICE_FUNC
> > > rte_event_eth_rx_adapter_create(dev_id, eth_port_id[], N, id, &cfg);
> > 
> > The downside might be:
> > - application has different flow based on based on the capability.
> > Listing down a few capabilities/limitation below.
> > 
> > > ===
> > > int rte_event_eth_rx_adapter_queue_add() would need a port id in the N>1
> > > port case, that can be ignored if the adapter doesn’t need it (N=1).
> > > 
> > > thanks for reading the long email, thoughts ?
> > 
> > I have bit another thought to solve the above mentioned downside.
> > 
> > - Theme is based on your original rx adapter proposal but with eventpmd
> >    ops(not adapter ops).i.e Reuse as much of your existing Rx adapter
> > implementation as common code and add hooks for HW based adapters. For
> > example, before you add  <ethdev, queue_id> to "rx_poll" in eth_poll_wrr_calc(),
> > Check for eventdev PMD ops is available adding it HW. If yes, Don't add in "rx_poll"
> > 
> > adapter_api
> > ------------
> > int rte_event_eth_rx_adapter_create(id, rte_event_eth_rx_adapter_conf *conf)
> > int rte_event_eth_rx_adapter_queue_add(uint8_t id, uint8_t eth_dev_id, int32_t rx_queue_id, rte_event_eth_rx_adapter_queue_conf *conf);
> > 
> > eventdev PMD op api(not as adapter PMD as discussed earlier)
> > -------------------
> > 
> > 1) typedef uint64_t (*eventdev_rx_adap_capa)(struct rte_eventdev *dev,  uint8_t ethdev_id)
> > 
> > Return the adapter capability of a given eventdev when it needs to
> > connected to a specific ethdev_id
> > 
> 
> Doesn't the capability of a <eventdev, ethdev> also need to be made
> available to the application as an adapter API ?

Yes. Make sense to expose as adapter API also.

> 
> for e.g., so the application can call rte_event_eth_rx_adapter_queue_add()
> with rx_queue_id = -1 if RX_ADAPTER_CAP_ADD_QUEUE is not set.
> 
> In the same manner, if I understand RX_ADAPTER_CAP_SET_FLOW_ID, the
> application would have provide a flow ID in
> rte_event_eth_rx_adapter_queue_add(), if RX_ADAPTER_CAP_SET_FLOW_ID is not
> set.
> 
> Also if a given <eventdev, ethdev> are connected in HW then is the servicing
> weight of a queue applicable ?

It is not applicable. If it connected in HW, We can ignore it.

> 
> > Possible capability values based on my understating for existing SW and Cavium
> > HW PMD. NXP folks can add new ones.
> > 
> > - RX_ADAPTER_CAP_INBUILT_PORT - /* adapter has inbuilt port, no need to create producer port by common code */
> > - RX_ADAPTER_CAP_SET_FLOW_ID  - /* adapter capable of setting RTE_ETH_RX_EVENT_ADAPTER_QUEUE_FLOW_ID_VALID */
> > - RX_ADAPTER_CAP_ADD_QUEUE /* adapter capable of adding any specific
> > ethdev rx queue to any eventdev queue. Some eventdev PMD has a limitation
> > that once a < ethdev_id , queue_id> connected to specific eventdev queue,
> > all the all queues_id under the same ethdev_id need to be connected to
> > same eventdev queue. aka works only on the rte_event_eth_rx_adapter_queue_conf.rx_queue_id == -1 mode, */
> > 
> > 
> > 2) typedef int (*eventdev_rx_adap_add)(struct rte_eventdev *dev,  uint8_t ethdev_id, int queue_id, rte_event_eth_rx_adapter_queue_conf *conf));
> > -- if implemented by eventdev PMD and returns zero then COMMON code does not need to poll */
> > 
> > 
> > 3) typedef int (*eventdev_rx_adap_del)(struct rte_eventdev *dev,  uint8_t ethdev_id, int queue_id)
> > -- remove previously added
> > 
> > 
> > *** Haven't spend a lot of time on API/macro name.Please use better naming conversion.
> > 
> > 
> > Another notes based on your existing implementation  + eventdev ops scheme
> > 
> > 1) rte_event_eth_rx_adapter_creates() registers service function by
> > default. It should be delayed to when common adapter code find a device
> > with !RX_ADAPTER_CAP_INBUILT_PORT cap on rte_event_eth_rx_adapter_queue_add()
> > 
> > 2) Do we need rx_adapter start/stop functions?
> 
> Yes.
> 
> > 
> > 3) If it happens to be case where rte_event_eth_rx_adapter_queue_add()
> > use only RX_ADAPTER_CAP_INBUILT_PORT then common code should not
> > create any service.
> 
> Yes.
> > 
> > 4) If adapter uses one port with service core and other one with HW
> > adapter. rte_event_eth_rx_adapter_stats.rx_packets will be not updated
> > correctly, We need eventdev PMD ops to get those stats. If we agree
> > overall PMD ops + adapter API partitioning then we can refine additionally
> > eventpmd for stats etc or xstat based scheme etc.
> 
> Wouldnt the rx_packets be the sum of the service core thread packet count
> and the count provided by the eventdev pmd ops and be obtained from a call
> to

Yes.

> 
> rte_event_eth_rx_adapter_stats_get(uint8_t id,
> 	struct rte_event_eth_rx_adapter_stats *stats);
> 
> > 
> > 5) specifying rte_event_eth_rx_adapter_conf.rx_event_port_id on
> > rte_event_eth_rx_adapter_create() would waste one HW eventdev port if its
> > happen to be used RX_ADAPTER_CAP_INBUILT_PORT on rte_event_eth_rx_adapter_queue_add().
> > unlike SW eventdev port, HW eventdev ports are costly so I think, We
> > need to have another eventdev PMD ops to create service/producer ports.
> > Or any other scheme that creates rte_event_eth_rx_adapter_conf.rx_event_port_id
> > on demand by common code.
> > 
> 
> One solution is:
> 
> struct rte_event_eth_rx_adapter_conf {
>     uint8_t dev_id;
> 
>     int (*conf_cb)(uint8_t id, uint8_t port_id, uint32_t flags, struct
> rte_event_eth_rx_adapter_conf *conf);
> 
>     unsigned int max_nb_rx;
> 
>     int event_port_id;
> 
>     char service_name[];
> }
> 
> Where dev_id and conf_cb have to be specified in the create call, but
> event_port_id and service_name will be filled in when conf_cb() is invoked

I was thinking like event_port_id will be rte_event_port_count() + 1.
ie When adapter needs the additional port, It can
- stop the eventdev
- reconfigure with rte_event_queue_count() , rte_event_port_count() + 1
- start the eventdev.

The only problem with callback is that all the application needs to
implement it. If you think, application need more control then we can
expose callback and if it is NULL then default handler can be called in
common code.


> if required. flags will specify what parameters of conf need to be filled
> in. The conf parameter can be separated into a different
> 
> struct rte_event_eth_rx_adapter_ext_conf {
>     unsigned int max_nb_rx;
> 
>     int event_port_id;
> 
>     char service_name[];
> }
> 
> Nikhil
> 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-08-01 16:42                                   ` Jerin Jacob
@ 2017-08-02 19:19                                     ` Eads, Gage
  2017-08-03  6:23                                       ` Jerin Jacob
  2017-08-11  5:25                                     ` Rao, Nikhil
  1 sibling, 1 reply; 41+ messages in thread
From: Eads, Gage @ 2017-08-02 19:19 UTC (permalink / raw)
  To: Jerin Jacob, Rao, Nikhil
  Cc: dev, thomas, Richardson, Bruce, Van Haaren, Harry,
	hemant.agrawal, nipun.gupta, Vangati, Narender, Gujjar,
	Abhinandan S


<snip>

> > >
> > > 5) specifying rte_event_eth_rx_adapter_conf.rx_event_port_id on
> > > rte_event_eth_rx_adapter_create() would waste one HW eventdev port
> > > if its happen to be used RX_ADAPTER_CAP_INBUILT_PORT on
> rte_event_eth_rx_adapter_queue_add().
> > > unlike SW eventdev port, HW eventdev ports are costly so I think, We
> > > need to have another eventdev PMD ops to create service/producer ports.
> > > Or any other scheme that creates
> > > rte_event_eth_rx_adapter_conf.rx_event_port_id
> > > on demand by common code.
> > >
> >
> > One solution is:
> >
> > struct rte_event_eth_rx_adapter_conf {
> >     uint8_t dev_id;
> >
> >     int (*conf_cb)(uint8_t id, uint8_t port_id, uint32_t flags, struct
> > rte_event_eth_rx_adapter_conf *conf);
> >
> >     unsigned int max_nb_rx;
> >
> >     int event_port_id;
> >
> >     char service_name[];
> > }
> >
> > Where dev_id and conf_cb have to be specified in the create call, but
> > event_port_id and service_name will be filled in when conf_cb() is
> > invoked
> 
> I was thinking like event_port_id will be rte_event_port_count() + 1.
> ie When adapter needs the additional port, It can
> - stop the eventdev
> - reconfigure with rte_event_queue_count() , rte_event_port_count() + 1
> - start the eventdev.
> 
> The only problem with callback is that all the application needs to implement it.
> If you think, application need more control then we can expose callback and if it
> is NULL then default handler can be called in common code.
> 

I don't think we can rely on there being another port available -- a user may have configured the sw eventdev with all 64 ports, for instance. What if the user is required to calculate cfg.nb_event_ports as a function of the RX_ADAPTER_CAP_INBUILT_PORT capability (i.e. add a port if the capability is not set), such that a reconfigure is not required?

As for application control: that would be a useful option in the conf_cb scheme. Some apps will want to configure the adapter's port (its new_event_threshold, its queue depths) differently from the default.

Thanks,
Gage

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-08-02 19:19                                     ` Eads, Gage
@ 2017-08-03  6:23                                       ` Jerin Jacob
  2017-08-09  2:23                                         ` Eads, Gage
  0 siblings, 1 reply; 41+ messages in thread
From: Jerin Jacob @ 2017-08-03  6:23 UTC (permalink / raw)
  To: Eads, Gage
  Cc: Rao, Nikhil, dev, thomas, Richardson, Bruce, Van Haaren, Harry,
	hemant.agrawal, nipun.gupta, Vangati, Narender, Gujjar,
	Abhinandan S

-----Original Message-----
> Date: Wed, 2 Aug 2017 19:19:32 +0000
> From: "Eads, Gage" <gage.eads@intel.com>
> To: Jerin Jacob <jerin.jacob@caviumnetworks.com>, "Rao, Nikhil"
>  <nikhil.rao@intel.com>
> CC: "dev@dpdk.org" <dev@dpdk.org>, "thomas@monjalon.net"
>  <thomas@monjalon.net>, "Richardson, Bruce" <bruce.richardson@intel.com>,
>  "Van Haaren, Harry" <harry.van.haaren@intel.com>, "hemant.agrawal@nxp.com"
>  <hemant.agrawal@nxp.com>, "nipun.gupta@nxp.com" <nipun.gupta@nxp.com>,
>  "Vangati, Narender" <narender.vangati@intel.com>, "Gujjar, Abhinandan S"
>  <abhinandan.gujjar@intel.com>
> Subject: RE: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> 
> 
> <snip>
> 
> > > >
> > > > 5) specifying rte_event_eth_rx_adapter_conf.rx_event_port_id on
> > > > rte_event_eth_rx_adapter_create() would waste one HW eventdev port
> > > > if its happen to be used RX_ADAPTER_CAP_INBUILT_PORT on
> > rte_event_eth_rx_adapter_queue_add().
> > > > unlike SW eventdev port, HW eventdev ports are costly so I think, We
> > > > need to have another eventdev PMD ops to create service/producer ports.
> > > > Or any other scheme that creates
> > > > rte_event_eth_rx_adapter_conf.rx_event_port_id
> > > > on demand by common code.
> > > >
> > >
> > > One solution is:
> > >
> > > struct rte_event_eth_rx_adapter_conf {
> > >     uint8_t dev_id;
> > >
> > >     int (*conf_cb)(uint8_t id, uint8_t port_id, uint32_t flags, struct
> > > rte_event_eth_rx_adapter_conf *conf);
> > >
> > >     unsigned int max_nb_rx;
> > >
> > >     int event_port_id;
> > >
> > >     char service_name[];
> > > }
> > >
> > > Where dev_id and conf_cb have to be specified in the create call, but
> > > event_port_id and service_name will be filled in when conf_cb() is
> > > invoked
> > 
> > I was thinking like event_port_id will be rte_event_port_count() + 1.
> > ie When adapter needs the additional port, It can
> > - stop the eventdev
> > - reconfigure with rte_event_queue_count() , rte_event_port_count() + 1
> > - start the eventdev.
> > 
> > The only problem with callback is that all the application needs to implement it.
> > If you think, application need more control then we can expose callback and if it
> > is NULL then default handler can be called in common code.
> > 
> 
> I don't think we can rely on there being another port available -- a user may have configured the sw eventdev with all 64 ports, for instance.

On that case, irrespective any scheme(callback vs non callback) the
adapter creation would fail. Right?

> What if the user is required to calculate cfg.nb_event_ports as a function of the RX_ADAPTER_CAP_INBUILT_PORT capability (i.e. add a port if the capability is not set), such that a reconfigure is not required?

We have only one NON INBUILT eventdev port per adapter. Right? i.e in the v1 spec it was rte_event_eth_rx_adapter_conf.event_port_id,
How about it can be rte_event_port_count() + 1 ? Since we are NOT
linking this port, the context call be kept in adapter itself. Right?
> 
> As for application control: that would be a useful option in the conf_cb scheme. Some apps will want to configure the adapter's port (its new_event_threshold, its queue depths) differently from the default.

struct rte_event_port_conf * can be passed on the adapter create if
application needs more control.

> 
> Thanks,
> Gage

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-08-03  6:23                                       ` Jerin Jacob
@ 2017-08-09  2:23                                         ` Eads, Gage
  2017-08-09 16:19                                           ` Jerin Jacob
  0 siblings, 1 reply; 41+ messages in thread
From: Eads, Gage @ 2017-08-09  2:23 UTC (permalink / raw)
  To: Jerin Jacob
  Cc: Rao, Nikhil, dev, thomas, Richardson, Bruce, Van Haaren, Harry,
	hemant.agrawal, nipun.gupta, Vangati, Narender, Gujjar,
	Abhinandan S



> -----Original Message-----
> From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> Sent: Thursday, August 3, 2017 1:23 AM
> To: Eads, Gage <gage.eads@intel.com>
> Cc: Rao, Nikhil <nikhil.rao@intel.com>; dev@dpdk.org; thomas@monjalon.net;
> Richardson, Bruce <bruce.richardson@intel.com>; Van Haaren, Harry
> <harry.van.haaren@intel.com>; hemant.agrawal@nxp.com;
> nipun.gupta@nxp.com; Vangati, Narender <narender.vangati@intel.com>;
> Gujjar, Abhinandan S <abhinandan.gujjar@intel.com>
> Subject: Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> 
> -----Original Message-----
> > Date: Wed, 2 Aug 2017 19:19:32 +0000
> > From: "Eads, Gage" <gage.eads@intel.com>
> > To: Jerin Jacob <jerin.jacob@caviumnetworks.com>, "Rao, Nikhil"
> >  <nikhil.rao@intel.com>
> > CC: "dev@dpdk.org" <dev@dpdk.org>, "thomas@monjalon.net"
> >  <thomas@monjalon.net>, "Richardson, Bruce"
> > <bruce.richardson@intel.com>,  "Van Haaren, Harry"
> <harry.van.haaren@intel.com>, "hemant.agrawal@nxp.com"
> >  <hemant.agrawal@nxp.com>, "nipun.gupta@nxp.com"
> > <nipun.gupta@nxp.com>,  "Vangati, Narender"
> <narender.vangati@intel.com>, "Gujjar, Abhinandan S"
> >  <abhinandan.gujjar@intel.com>
> > Subject: RE: [PATCH 1/2] eventdev: add event adapter for ethernet Rx
> > queues
> >
> >
> > <snip>
> >
> > > > >
> > > > > 5) specifying rte_event_eth_rx_adapter_conf.rx_event_port_id on
> > > > > rte_event_eth_rx_adapter_create() would waste one HW eventdev
> > > > > port if its happen to be used RX_ADAPTER_CAP_INBUILT_PORT on
> > > rte_event_eth_rx_adapter_queue_add().
> > > > > unlike SW eventdev port, HW eventdev ports are costly so I
> > > > > think, We need to have another eventdev PMD ops to create
> service/producer ports.
> > > > > Or any other scheme that creates
> > > > > rte_event_eth_rx_adapter_conf.rx_event_port_id
> > > > > on demand by common code.
> > > > >
> > > >
> > > > One solution is:
> > > >
> > > > struct rte_event_eth_rx_adapter_conf {
> > > >     uint8_t dev_id;
> > > >
> > > >     int (*conf_cb)(uint8_t id, uint8_t port_id, uint32_t flags,
> > > > struct rte_event_eth_rx_adapter_conf *conf);
> > > >
> > > >     unsigned int max_nb_rx;
> > > >
> > > >     int event_port_id;
> > > >
> > > >     char service_name[];
> > > > }
> > > >
> > > > Where dev_id and conf_cb have to be specified in the create call,
> > > > but event_port_id and service_name will be filled in when
> > > > conf_cb() is invoked
> > >
> > > I was thinking like event_port_id will be rte_event_port_count() + 1.
> > > ie When adapter needs the additional port, It can
> > > - stop the eventdev
> > > - reconfigure with rte_event_queue_count() , rte_event_port_count()
> > > + 1
> > > - start the eventdev.
> > >
> > > The only problem with callback is that all the application needs to implement
> it.
> > > If you think, application need more control then we can expose
> > > callback and if it is NULL then default handler can be called in common code.
> > >
> >
> > I don't think we can rely on there being another port available -- a user may
> have configured the sw eventdev with all 64 ports, for instance.
> 
> On that case, irrespective any scheme(callback vs non callback) the adapter
> creation would fail. Right?
> 
> > What if the user is required to calculate cfg.nb_event_ports as a function of
> the RX_ADAPTER_CAP_INBUILT_PORT capability (i.e. add a port if the capability
> is not set), such that a reconfigure is not required?
> 
> We have only one NON INBUILT eventdev port per adapter. Right? i.e in the v1
> spec it was rte_event_eth_rx_adapter_conf.event_port_id,
> How about it can be rte_event_port_count() + 1 ? Since we are NOT linking this
> port, the context call be kept in adapter itself. Right?

It could be. Thinking on it some more, I'm a little concerned about doing configuration without the application's knowledge. Possible issues that could arise:
- The user later reconfigures the event device with fewer ports and the adapter's port becomes invalid, or reconfigures it with more ports and begins using the port the adapter is using
- rte_event_port_count() + 1 extends beyond the PMD's capabilities (the sw PMD is hard-coded to support a max of 64 ports, for example)

Having the user be responsible for the port configuration could avoid these problems. Since the user needs to check the <eventdev, ethdev> pair's capabilities for the CAP_ADD_QUEUE anyway, they could also check for INBUILT_PORT and decide whether or not to request an additional port at eventdev configure time -- thereby ensuring they don't waste a port when using hardware with inbuilt ports. And this keeps the configuration code in one place (the app), rather than spread across the app, adapter, and potentially the conf_cb.

Besides these concerns, I think the transparent configuration approach (plus conf_cb when necessary to override) would work, but could have issues in the aforementioned edge cases.

> >
> > As for application control: that would be a useful option in the conf_cb
> scheme. Some apps will want to configure the adapter's port (its
> new_event_threshold, its queue depths) differently from the default.
> 
> struct rte_event_port_conf * can be passed on the adapter create if application
> needs more control.
> 
> >
> > Thanks,
> > Gage

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-08-09  2:23                                         ` Eads, Gage
@ 2017-08-09 16:19                                           ` Jerin Jacob
  2017-08-09 19:24                                             ` Eads, Gage
  0 siblings, 1 reply; 41+ messages in thread
From: Jerin Jacob @ 2017-08-09 16:19 UTC (permalink / raw)
  To: Eads, Gage
  Cc: Rao, Nikhil, dev, thomas, Richardson, Bruce, Van Haaren, Harry,
	hemant.agrawal, nipun.gupta, Vangati, Narender, Gujjar,
	Abhinandan S

-----Original Message-----
> Date: Wed, 9 Aug 2017 02:23:15 +0000
> From: "Eads, Gage" <gage.eads@intel.com>
> To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> CC: "Rao, Nikhil" <nikhil.rao@intel.com>, "dev@dpdk.org" <dev@dpdk.org>,
>  "thomas@monjalon.net" <thomas@monjalon.net>, "Richardson, Bruce"
>  <bruce.richardson@intel.com>, "Van Haaren, Harry"
>  <harry.van.haaren@intel.com>, "hemant.agrawal@nxp.com"
>  <hemant.agrawal@nxp.com>, "nipun.gupta@nxp.com" <nipun.gupta@nxp.com>,
>  "Vangati, Narender" <narender.vangati@intel.com>, "Gujjar, Abhinandan S"
>  <abhinandan.gujjar@intel.com>
> Subject: RE: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> 
> 
> 
> > -----Original Message-----
> > From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> > Sent: Thursday, August 3, 2017 1:23 AM
> > To: Eads, Gage <gage.eads@intel.com>
> > Cc: Rao, Nikhil <nikhil.rao@intel.com>; dev@dpdk.org; thomas@monjalon.net;
> > Richardson, Bruce <bruce.richardson@intel.com>; Van Haaren, Harry
> > <harry.van.haaren@intel.com>; hemant.agrawal@nxp.com;
> > nipun.gupta@nxp.com; Vangati, Narender <narender.vangati@intel.com>;
> > Gujjar, Abhinandan S <abhinandan.gujjar@intel.com>
> > Subject: Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> > 
> > -----Original Message-----
> > > Date: Wed, 2 Aug 2017 19:19:32 +0000
> > > From: "Eads, Gage" <gage.eads@intel.com>
> > > To: Jerin Jacob <jerin.jacob@caviumnetworks.com>, "Rao, Nikhil"
> > >  <nikhil.rao@intel.com>
> > > CC: "dev@dpdk.org" <dev@dpdk.org>, "thomas@monjalon.net"
> > >  <thomas@monjalon.net>, "Richardson, Bruce"
> > > <bruce.richardson@intel.com>,  "Van Haaren, Harry"
> > <harry.van.haaren@intel.com>, "hemant.agrawal@nxp.com"
> > >  <hemant.agrawal@nxp.com>, "nipun.gupta@nxp.com"
> > > <nipun.gupta@nxp.com>,  "Vangati, Narender"
> > <narender.vangati@intel.com>, "Gujjar, Abhinandan S"
> > >  <abhinandan.gujjar@intel.com>
> > > Subject: RE: [PATCH 1/2] eventdev: add event adapter for ethernet Rx
> > > queues
> > >
> > >
> > > <snip>
> > >
> > > > > >
> > > > > > 5) specifying rte_event_eth_rx_adapter_conf.rx_event_port_id on
> > > > > > rte_event_eth_rx_adapter_create() would waste one HW eventdev
> > > > > > port if its happen to be used RX_ADAPTER_CAP_INBUILT_PORT on
> > > > rte_event_eth_rx_adapter_queue_add().
> > > > > > unlike SW eventdev port, HW eventdev ports are costly so I
> > > > > > think, We need to have another eventdev PMD ops to create
> > service/producer ports.
> > > > > > Or any other scheme that creates
> > > > > > rte_event_eth_rx_adapter_conf.rx_event_port_id
> > > > > > on demand by common code.
> > > > > >
> > > > >
> > > > > One solution is:
> > > > >
> > > > > struct rte_event_eth_rx_adapter_conf {
> > > > >     uint8_t dev_id;
> > > > >
> > > > >     int (*conf_cb)(uint8_t id, uint8_t port_id, uint32_t flags,
> > > > > struct rte_event_eth_rx_adapter_conf *conf);
> > > > >
> > > > >     unsigned int max_nb_rx;
> > > > >
> > > > >     int event_port_id;
> > > > >
> > > > >     char service_name[];
> > > > > }
> > > > >
> > > > > Where dev_id and conf_cb have to be specified in the create call,
> > > > > but event_port_id and service_name will be filled in when
> > > > > conf_cb() is invoked
> > > >
> > > > I was thinking like event_port_id will be rte_event_port_count() + 1.
> > > > ie When adapter needs the additional port, It can
> > > > - stop the eventdev
> > > > - reconfigure with rte_event_queue_count() , rte_event_port_count()
> > > > + 1
> > > > - start the eventdev.
> > > >
> > > > The only problem with callback is that all the application needs to implement
> > it.
> > > > If you think, application need more control then we can expose
> > > > callback and if it is NULL then default handler can be called in common code.
> > > >
> > >
> > > I don't think we can rely on there being another port available -- a user may
> > have configured the sw eventdev with all 64 ports, for instance.
> > 
> > On that case, irrespective any scheme(callback vs non callback) the adapter
> > creation would fail. Right?
> > 
> > > What if the user is required to calculate cfg.nb_event_ports as a function of
> > the RX_ADAPTER_CAP_INBUILT_PORT capability (i.e. add a port if the capability
> > is not set), such that a reconfigure is not required?
> > 
> > We have only one NON INBUILT eventdev port per adapter. Right? i.e in the v1
> > spec it was rte_event_eth_rx_adapter_conf.event_port_id,
> > How about it can be rte_event_port_count() + 1 ? Since we are NOT linking this
> > port, the context call be kept in adapter itself. Right?
> 
> It could be. Thinking on it some more, I'm a little concerned about doing configuration without the application's knowledge. Possible issues that could arise:
> - The user later reconfigures the event device with fewer ports and the adapter's port becomes invalid, or reconfigures it with more ports and begins using the port the adapter is using
> - rte_event_port_count() + 1 extends beyond the PMD's capabilities (the sw PMD is hard-coded to support a max of 64 ports, for example)
> 
> Having the user be responsible for the port configuration could avoid these problems. Since the user needs to check the <eventdev, ethdev> pair's capabilities for the CAP_ADD_QUEUE anyway, they could also check for INBUILT_PORT and decide whether or not to request an additional port at eventdev configure time -- thereby ensuring they don't waste a port when using hardware with inbuilt ports. And this keeps the configuration code in one place (the app), rather than spread across the app, adapter, and potentially the conf_cb.

OK.Sounds reasonable.May be we can push the responsibility to application.We could have a
helper function using the proposed adapter API. That helper function
would create the adapter based on the capability for the _default_ case.
Applications free to use the raw adapter API to get more control if required.
Otherwise we will duplicate the code in all the applications.

> 
> Besides these concerns, I think the transparent configuration approach (plus conf_cb when necessary to override) would work, but could have issues in the aforementioned edge cases.
> 
> > >
> > > As for application control: that would be a useful option in the conf_cb
> > scheme. Some apps will want to configure the adapter's port (its
> > new_event_threshold, its queue depths) differently from the default.
> > 
> > struct rte_event_port_conf * can be passed on the adapter create if application
> > needs more control.
> > 
> > >
> > > Thanks,
> > > Gage

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-08-09 16:19                                           ` Jerin Jacob
@ 2017-08-09 19:24                                             ` Eads, Gage
  2017-08-10 16:53                                               ` Jerin Jacob
  0 siblings, 1 reply; 41+ messages in thread
From: Eads, Gage @ 2017-08-09 19:24 UTC (permalink / raw)
  To: Jerin Jacob
  Cc: Rao, Nikhil, dev, thomas, Richardson, Bruce, Van Haaren, Harry,
	hemant.agrawal, nipun.gupta, Vangati, Narender, Gujjar,
	Abhinandan S



> -----Original Message-----
> From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> Sent: Wednesday, August 9, 2017 11:20 AM
> To: Eads, Gage <gage.eads@intel.com>
> Cc: Rao, Nikhil <nikhil.rao@intel.com>; dev@dpdk.org; thomas@monjalon.net;
> Richardson, Bruce <bruce.richardson@intel.com>; Van Haaren, Harry
> <harry.van.haaren@intel.com>; hemant.agrawal@nxp.com;
> nipun.gupta@nxp.com; Vangati, Narender <narender.vangati@intel.com>;
> Gujjar, Abhinandan S <abhinandan.gujjar@intel.com>
> Subject: Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> 
> -----Original Message-----
> > Date: Wed, 9 Aug 2017 02:23:15 +0000
> > From: "Eads, Gage" <gage.eads@intel.com>
> > To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> > CC: "Rao, Nikhil" <nikhil.rao@intel.com>, "dev@dpdk.org"
> > <dev@dpdk.org>,  "thomas@monjalon.net" <thomas@monjalon.net>,
> "Richardson, Bruce"
> >  <bruce.richardson@intel.com>, "Van Haaren, Harry"
> >  <harry.van.haaren@intel.com>, "hemant.agrawal@nxp.com"
> >  <hemant.agrawal@nxp.com>, "nipun.gupta@nxp.com"
> > <nipun.gupta@nxp.com>,  "Vangati, Narender"
> <narender.vangati@intel.com>, "Gujjar, Abhinandan S"
> >  <abhinandan.gujjar@intel.com>
> > Subject: RE: [PATCH 1/2] eventdev: add event adapter for ethernet Rx
> > queues
> >
> >
> >
> > > -----Original Message-----
> > > From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> > > Sent: Thursday, August 3, 2017 1:23 AM
> > > To: Eads, Gage <gage.eads@intel.com>
> > > Cc: Rao, Nikhil <nikhil.rao@intel.com>; dev@dpdk.org;
> > > thomas@monjalon.net; Richardson, Bruce <bruce.richardson@intel.com>;
> > > Van Haaren, Harry <harry.van.haaren@intel.com>;
> > > hemant.agrawal@nxp.com; nipun.gupta@nxp.com; Vangati, Narender
> > > <narender.vangati@intel.com>; Gujjar, Abhinandan S
> > > <abhinandan.gujjar@intel.com>
> > > Subject: Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx
> > > queues
> > >
> > > -----Original Message-----
> > > > Date: Wed, 2 Aug 2017 19:19:32 +0000
> > > > From: "Eads, Gage" <gage.eads@intel.com>
> > > > To: Jerin Jacob <jerin.jacob@caviumnetworks.com>, "Rao, Nikhil"
> > > >  <nikhil.rao@intel.com>
> > > > CC: "dev@dpdk.org" <dev@dpdk.org>, "thomas@monjalon.net"
> > > >  <thomas@monjalon.net>, "Richardson, Bruce"
> > > > <bruce.richardson@intel.com>,  "Van Haaren, Harry"
> > > <harry.van.haaren@intel.com>, "hemant.agrawal@nxp.com"
> > > >  <hemant.agrawal@nxp.com>, "nipun.gupta@nxp.com"
> > > > <nipun.gupta@nxp.com>,  "Vangati, Narender"
> > > <narender.vangati@intel.com>, "Gujjar, Abhinandan S"
> > > >  <abhinandan.gujjar@intel.com>
> > > > Subject: RE: [PATCH 1/2] eventdev: add event adapter for ethernet
> > > > Rx queues
> > > >
> > > >
> > > > <snip>
> > > >
> > > > > > >
> > > > > > > 5) specifying rte_event_eth_rx_adapter_conf.rx_event_port_id
> > > > > > > on
> > > > > > > rte_event_eth_rx_adapter_create() would waste one HW
> > > > > > > eventdev port if its happen to be used
> > > > > > > RX_ADAPTER_CAP_INBUILT_PORT on
> > > > > rte_event_eth_rx_adapter_queue_add().
> > > > > > > unlike SW eventdev port, HW eventdev ports are costly so I
> > > > > > > think, We need to have another eventdev PMD ops to create
> > > service/producer ports.
> > > > > > > Or any other scheme that creates
> > > > > > > rte_event_eth_rx_adapter_conf.rx_event_port_id
> > > > > > > on demand by common code.
> > > > > > >
> > > > > >
> > > > > > One solution is:
> > > > > >
> > > > > > struct rte_event_eth_rx_adapter_conf {
> > > > > >     uint8_t dev_id;
> > > > > >
> > > > > >     int (*conf_cb)(uint8_t id, uint8_t port_id, uint32_t
> > > > > > flags, struct rte_event_eth_rx_adapter_conf *conf);
> > > > > >
> > > > > >     unsigned int max_nb_rx;
> > > > > >
> > > > > >     int event_port_id;
> > > > > >
> > > > > >     char service_name[];
> > > > > > }
> > > > > >
> > > > > > Where dev_id and conf_cb have to be specified in the create
> > > > > > call, but event_port_id and service_name will be filled in
> > > > > > when
> > > > > > conf_cb() is invoked
> > > > >
> > > > > I was thinking like event_port_id will be rte_event_port_count() + 1.
> > > > > ie When adapter needs the additional port, It can
> > > > > - stop the eventdev
> > > > > - reconfigure with rte_event_queue_count() ,
> > > > > rte_event_port_count()
> > > > > + 1
> > > > > - start the eventdev.
> > > > >
> > > > > The only problem with callback is that all the application needs
> > > > > to implement
> > > it.
> > > > > If you think, application need more control then we can expose
> > > > > callback and if it is NULL then default handler can be called in common
> code.
> > > > >
> > > >
> > > > I don't think we can rely on there being another port available --
> > > > a user may
> > > have configured the sw eventdev with all 64 ports, for instance.
> > >
> > > On that case, irrespective any scheme(callback vs non callback) the
> > > adapter creation would fail. Right?
> > >
> > > > What if the user is required to calculate cfg.nb_event_ports as a
> > > > function of
> > > the RX_ADAPTER_CAP_INBUILT_PORT capability (i.e. add a port if the
> > > capability is not set), such that a reconfigure is not required?
> > >
> > > We have only one NON INBUILT eventdev port per adapter. Right? i.e
> > > in the v1 spec it was rte_event_eth_rx_adapter_conf.event_port_id,
> > > How about it can be rte_event_port_count() + 1 ? Since we are NOT
> > > linking this port, the context call be kept in adapter itself. Right?
> >
> > It could be. Thinking on it some more, I'm a little concerned about doing
> configuration without the application's knowledge. Possible issues that could
> arise:
> > - The user later reconfigures the event device with fewer ports and
> > the adapter's port becomes invalid, or reconfigures it with more ports
> > and begins using the port the adapter is using
> > - rte_event_port_count() + 1 extends beyond the PMD's capabilities
> > (the sw PMD is hard-coded to support a max of 64 ports, for example)
> >
> > Having the user be responsible for the port configuration could avoid these
> problems. Since the user needs to check the <eventdev, ethdev> pair's
> capabilities for the CAP_ADD_QUEUE anyway, they could also check for
> INBUILT_PORT and decide whether or not to request an additional port at
> eventdev configure time -- thereby ensuring they don't waste a port when using
> hardware with inbuilt ports. And this keeps the configuration code in one place
> (the app), rather than spread across the app, adapter, and potentially the
> conf_cb.
> 
> OK.Sounds reasonable.May be we can push the responsibility to application.We
> could have a helper function using the proposed adapter API. That helper
> function would create the adapter based on the capability for the _default_
> case.
> Applications free to use the raw adapter API to get more control if required.
> Otherwise we will duplicate the code in all the applications.
>

Makes sense. Are you thinking the helper function would do stop + reconfig with additional port + start + setup port, or just setup the port with an ID the app supplies (only when a port is required, of course)? The second one could be done with little additional code -- the app just needs to check if an additional port is needed when configuring the eventdev, and another helper function could take a list of <eventdev, ethdev> pairs and return true if any don't have an inbuilt port.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-08-09 19:24                                             ` Eads, Gage
@ 2017-08-10 16:53                                               ` Jerin Jacob
  2017-08-14  8:48                                                 ` Rao, Nikhil
  0 siblings, 1 reply; 41+ messages in thread
From: Jerin Jacob @ 2017-08-10 16:53 UTC (permalink / raw)
  To: Eads, Gage
  Cc: Rao, Nikhil, dev, thomas, Richardson, Bruce, Van Haaren, Harry,
	hemant.agrawal, nipun.gupta, Vangati, Narender, Gujjar,
	Abhinandan S

-----Original Message-----
> Date: Wed, 9 Aug 2017 19:24:30 +0000
> From: "Eads, Gage" <gage.eads@intel.com>
> To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> CC: "Rao, Nikhil" <nikhil.rao@intel.com>, "dev@dpdk.org" <dev@dpdk.org>,
>  "thomas@monjalon.net" <thomas@monjalon.net>, "Richardson, Bruce"
>  <bruce.richardson@intel.com>, "Van Haaren, Harry"
>  <harry.van.haaren@intel.com>, "hemant.agrawal@nxp.com"
>  <hemant.agrawal@nxp.com>, "nipun.gupta@nxp.com" <nipun.gupta@nxp.com>,
>  "Vangati, Narender" <narender.vangati@intel.com>, "Gujjar, Abhinandan S"
>  <abhinandan.gujjar@intel.com>
> Subject: RE: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> > > > > >
> > > > >
> > > > > I don't think we can rely on there being another port available --
> > > > > a user may
> > > > have configured the sw eventdev with all 64 ports, for instance.
> > > >
> > > > On that case, irrespective any scheme(callback vs non callback) the
> > > > adapter creation would fail. Right?
> > > >
> > > > > What if the user is required to calculate cfg.nb_event_ports as a
> > > > > function of
> > > > the RX_ADAPTER_CAP_INBUILT_PORT capability (i.e. add a port if the
> > > > capability is not set), such that a reconfigure is not required?
> > > >
> > > > We have only one NON INBUILT eventdev port per adapter. Right? i.e
> > > > in the v1 spec it was rte_event_eth_rx_adapter_conf.event_port_id,
> > > > How about it can be rte_event_port_count() + 1 ? Since we are NOT
> > > > linking this port, the context call be kept in adapter itself. Right?
> > >
> > > It could be. Thinking on it some more, I'm a little concerned about doing
> > configuration without the application's knowledge. Possible issues that could
> > arise:
> > > - The user later reconfigures the event device with fewer ports and
> > > the adapter's port becomes invalid, or reconfigures it with more ports
> > > and begins using the port the adapter is using
> > > - rte_event_port_count() + 1 extends beyond the PMD's capabilities
> > > (the sw PMD is hard-coded to support a max of 64 ports, for example)
> > >
> > > Having the user be responsible for the port configuration could avoid these
> > problems. Since the user needs to check the <eventdev, ethdev> pair's
> > capabilities for the CAP_ADD_QUEUE anyway, they could also check for
> > INBUILT_PORT and decide whether or not to request an additional port at
> > eventdev configure time -- thereby ensuring they don't waste a port when using
> > hardware with inbuilt ports. And this keeps the configuration code in one place
> > (the app), rather than spread across the app, adapter, and potentially the
> > conf_cb.
> > 
> > OK.Sounds reasonable.May be we can push the responsibility to application.We
> > could have a helper function using the proposed adapter API. That helper
> > function would create the adapter based on the capability for the _default_
> > case.
> > Applications free to use the raw adapter API to get more control if required.
> > Otherwise we will duplicate the code in all the applications.
> >
> 
> Makes sense. Are you thinking the helper function would do stop + reconfig with additional port + start + setup port, or just setup the port with an ID the app supplies (only when a port is required, of course)? The second one could be done with little additional code -- the app just needs to check if an additional port is needed when configuring the eventdev, and another helper function could take a list of <eventdev, ethdev> pairs and return true if any don't have an inbuilt port.

I am in favor adding more logic in helper function(I believe, first one ) so that it will help
application reuse the helper functions for the normal case.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-08-01 16:42                                   ` Jerin Jacob
  2017-08-02 19:19                                     ` Eads, Gage
@ 2017-08-11  5:25                                     ` Rao, Nikhil
  2017-08-11  9:49                                       ` Jerin Jacob
  2017-09-04  6:37                                       ` Jerin Jacob
  1 sibling, 2 replies; 41+ messages in thread
From: Rao, Nikhil @ 2017-08-11  5:25 UTC (permalink / raw)
  To: Jerin Jacob
  Cc: gage.eads, dev, thomas, bruce.richardson, harry.van.haaren,
	hemant.agrawal, nipun.gupta, narender.vangati, Abhinandan Gujjar

On 8/1/2017 10:12 PM, Jerin Jacob wrote:
>> I have had the application specify the name. so that it can call
>>
>> struct rte_service_spec *rte_service_get_by_name(const char *name);
> 
> OK. I was thinking like there will be fixed name for the rx_adapter
> service like "eth_rx_adapter_%d"(%d for adapter id) which be exposed in
> rte_event_eth_rx_adapter.h.
> It can help in removing cfg.service_name. I am fine with either way.
>

OK, I will use a fixed name.

>>> eventdev PMD op api(not as adapter PMD as discussed earlier)
>>> -------------------
>>>
>>> 1) typedef uint64_t (*eventdev_rx_adap_capa)(struct rte_eventdev *dev,  uint8_t ethdev_id)
>>>
>>> Return the adapter capability of a given eventdev when it needs to
>>> connected to a specific ethdev_id
>>>
>>
>> Doesn't the capability of a <eventdev, ethdev> also need to be made
>> available to the application as an adapter API ?
> 
> Yes. Make sense to expose as adapter API also.
>

Correcting myself, Isn't this really an eventdev API ? An adapter API 
would take an adapter id argument which is unnecessary in this case.

Nikhil

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-08-11  5:25                                     ` Rao, Nikhil
@ 2017-08-11  9:49                                       ` Jerin Jacob
  2017-09-04  6:37                                       ` Jerin Jacob
  1 sibling, 0 replies; 41+ messages in thread
From: Jerin Jacob @ 2017-08-11  9:49 UTC (permalink / raw)
  To: Rao, Nikhil
  Cc: gage.eads, dev, thomas, bruce.richardson, harry.van.haaren,
	hemant.agrawal, nipun.gupta, narender.vangati, Abhinandan Gujjar

-----Original Message-----
> Date: Fri, 11 Aug 2017 10:55:38 +0530
> From: "Rao, Nikhil" <nikhil.rao@intel.com>
> To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> CC: gage.eads@intel.com, dev@dpdk.org, thomas@monjalon.net,
>  bruce.richardson@intel.com, harry.van.haaren@intel.com,
>  hemant.agrawal@nxp.com, nipun.gupta@nxp.com, narender.vangati@intel.com,
>  Abhinandan Gujjar <abhinandan.gujjar@intel.com>
> Subject: Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101
>  Thunderbird/52.2.1
> 
> On 8/1/2017 10:12 PM, Jerin Jacob wrote:
> > > I have had the application specify the name. so that it can call
> > > 
> > > struct rte_service_spec *rte_service_get_by_name(const char *name);
> > 
> > OK. I was thinking like there will be fixed name for the rx_adapter
> > service like "eth_rx_adapter_%d"(%d for adapter id) which be exposed in
> > rte_event_eth_rx_adapter.h.
> > It can help in removing cfg.service_name. I am fine with either way.
> > 
> 
> OK, I will use a fixed name.
> 
> > > > eventdev PMD op api(not as adapter PMD as discussed earlier)
> > > > -------------------
> > > > 
> > > > 1) typedef uint64_t (*eventdev_rx_adap_capa)(struct rte_eventdev *dev,  uint8_t ethdev_id)
> > > > 
> > > > Return the adapter capability of a given eventdev when it needs to
> > > > connected to a specific ethdev_id
> > > > 
> > > 
> > > Doesn't the capability of a <eventdev, ethdev> also need to be made
> > > available to the application as an adapter API ?
> > 
> > Yes. Make sense to expose as adapter API also.
> > 
> 
> Correcting myself, Isn't this really an eventdev API ? An adapter API would
> take an adapter id argument which is unnecessary in this case.

Yes, it is eventdev API.

> 
> Nikhil

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-08-10 16:53                                               ` Jerin Jacob
@ 2017-08-14  8:48                                                 ` Rao, Nikhil
  2017-08-14 11:11                                                   ` Jerin Jacob
  0 siblings, 1 reply; 41+ messages in thread
From: Rao, Nikhil @ 2017-08-14  8:48 UTC (permalink / raw)
  To: Jerin Jacob, Eads, Gage
  Cc: dev, thomas, Richardson, Bruce, Van Haaren, Harry,
	hemant.agrawal, nipun.gupta, Vangati, Narender, Gujjar,
	Abhinandan S

On 8/10/2017 10:23 PM, Jerin Jacob wrote:
> -----Original Message-----
>> Date: Wed, 9 Aug 2017 19:24:30 +0000
>> From: "Eads, Gage" <gage.eads@intel.com>
>> Makes sense. Are you thinking the helper function would do stop + reconfig with additional port + start + setup port, or just setup the port with an ID the app supplies (only when a port is required, of course)? The second one could be done with little additional code -- the app just needs to check if an additional port is needed when configuring the eventdev, and another helper function could take a list of <eventdev, ethdev> pairs and return true if any don't have an inbuilt port.
> 
> I am in favor adding more logic in helper function(I believe, first one ) so that it will help
> application reuse the helper functions for the normal case.
> 

Hi Jerin,

My understanding of the discussion above is that the simple API adapter 
creation API is

int rte_event_eth_rx_adapter_create(id, eventdev_id)

And the raw API is

typedef int (*rx_adapter_conf_cb) (id, eventdev_id,
	struct rte_event_eth_rx_adapter_conf *conf, void *arg);

struct rte_event_eth_rx_adapter_conf {
	uint8_t rx_event_port_id;
	uint32_t max_nb_rx;
};

int rte_event_eth_rx_adapter_create_ext(id, eventdev_id, conf_cb,
					conf_arg)

The conf_cb is invoked if the rte_event_eth_rx_adapter_conf struct needs 
to be filled out. the _create_ext() API is used internally by 
rte_event_eth_rx_adapter_create()

Does that look OK to you ?

Nikhil

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-08-14  8:48                                                 ` Rao, Nikhil
@ 2017-08-14 11:11                                                   ` Jerin Jacob
  2017-08-16  5:06                                                     ` Rao, Nikhil
  0 siblings, 1 reply; 41+ messages in thread
From: Jerin Jacob @ 2017-08-14 11:11 UTC (permalink / raw)
  To: Rao, Nikhil
  Cc: Eads, Gage, dev, thomas, Richardson, Bruce, Van Haaren, Harry,
	hemant.agrawal, nipun.gupta, Vangati, Narender, Gujjar,
	Abhinandan S

-----Original Message-----
> Date: Mon, 14 Aug 2017 14:18:15 +0530
> From: "Rao, Nikhil" <nikhil.rao@intel.com>
> To: Jerin Jacob <jerin.jacob@caviumnetworks.com>, "Eads, Gage"
>  <gage.eads@intel.com>
> CC: "dev@dpdk.org" <dev@dpdk.org>, "thomas@monjalon.net"
>  <thomas@monjalon.net>, "Richardson, Bruce" <bruce.richardson@intel.com>,
>  "Van Haaren, Harry" <harry.van.haaren@intel.com>, "hemant.agrawal@nxp.com"
>  <hemant.agrawal@nxp.com>, "nipun.gupta@nxp.com" <nipun.gupta@nxp.com>,
>  "Vangati, Narender" <narender.vangati@intel.com>, "Gujjar, Abhinandan S"
>  <abhinandan.gujjar@intel.com>
> Subject: Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101
>  Thunderbird/52.2.1
> 
> On 8/10/2017 10:23 PM, Jerin Jacob wrote:
> > -----Original Message-----
> > > Date: Wed, 9 Aug 2017 19:24:30 +0000
> > > From: "Eads, Gage" <gage.eads@intel.com>
> > > Makes sense. Are you thinking the helper function would do stop + reconfig with additional port + start + setup port, or just setup the port with an ID the app supplies (only when a port is required, of course)? The second one could be done with little additional code -- the app just needs to check if an additional port is needed when configuring the eventdev, and another helper function could take a list of <eventdev, ethdev> pairs and return true if any don't have an inbuilt port.
> > 
> > I am in favor adding more logic in helper function(I believe, first one ) so that it will help
> > application reuse the helper functions for the normal case.
> > 
> 
> Hi Jerin,

Hi Nikhil,

> 
> My understanding of the discussion above is that the simple API adapter
> creation API is
> 
> int rte_event_eth_rx_adapter_create(id, eventdev_id)
> 
> And the raw API is
> 
> typedef int (*rx_adapter_conf_cb) (id, eventdev_id,
> 	struct rte_event_eth_rx_adapter_conf *conf, void *arg);
> 
> struct rte_event_eth_rx_adapter_conf {
> 	uint8_t rx_event_port_id;
> 	uint32_t max_nb_rx;
> };
> 
> int rte_event_eth_rx_adapter_create_ext(id, eventdev_id, conf_cb,
> 					conf_arg)
> 
> The conf_cb is invoked if the rte_event_eth_rx_adapter_conf struct needs to
> be filled out. the _create_ext() API is used internally by
> rte_event_eth_rx_adapter_create()
> 
> Does that look OK to you ?

Just elaborating with additional detail. Let me know my understating is correct
or not?

default_cb(id, eventdev_id, conf)
{

	conf->rx_event_port_id = rte_event_port() + 1;
	conf->max_nb_rx = ...;
	....
}

rte_event_eth_rx_adapter_create(id, eventdev_id)
{
	struct rte_event_eth_rx_adapter_conf default_conf_arg;

	rte_event_eth_rx_adapter_create_ext(id, eventdev_id,
			default_cb, &default_conf_arg);
}

Application is free to use rte_event_eth_rx_adapter_create() or
rte_event_eth_rx_adapter_create_ext(). rte_event_eth_rx_adapter_create_ext()
will be used by application when "default_cb" handler is not enough for
the use cases.


> 
> Nikhil
> 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-08-14 11:11                                                   ` Jerin Jacob
@ 2017-08-16  5:06                                                     ` Rao, Nikhil
  0 siblings, 0 replies; 41+ messages in thread
From: Rao, Nikhil @ 2017-08-16  5:06 UTC (permalink / raw)
  To: Jerin Jacob
  Cc: Eads, Gage, dev, thomas, Richardson, Bruce, Van Haaren, Harry,
	hemant.agrawal, nipun.gupta, Vangati, Narender, Gujjar,
	Abhinandan S

On 8/14/2017 4:41 PM, Jerin Jacob wrote:
> -----Original Message-----
>> Date: Mon, 14 Aug 2017 14:18:15 +0530
>> From: "Rao, Nikhil" <nikhil.rao@intel.com>
>> To: Jerin Jacob <jerin.jacob@caviumnetworks.com>, "Eads, Gage"
>>   <gage.eads@intel.com>
>> CC: "dev@dpdk.org" <dev@dpdk.org>, "thomas@monjalon.net"
>>   <thomas@monjalon.net>, "Richardson, Bruce" <bruce.richardson@intel.com>,
>>   "Van Haaren, Harry" <harry.van.haaren@intel.com>, "hemant.agrawal@nxp.com"
>>   <hemant.agrawal@nxp.com>, "nipun.gupta@nxp.com" <nipun.gupta@nxp.com>,
>>   "Vangati, Narender" <narender.vangati@intel.com>, "Gujjar, Abhinandan S"
>>   <abhinandan.gujjar@intel.com>
>> Subject: Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
>> User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101
>>   Thunderbird/52.2.1
>>
>> On 8/10/2017 10:23 PM, Jerin Jacob wrote:
>>> -----Original Message-----
>>>> Date: Wed, 9 Aug 2017 19:24:30 +0000
>>>> From: "Eads, Gage" <gage.eads@intel.com>
>>>> Makes sense. Are you thinking the helper function would do stop + reconfig with additional port + start + setup port, or just setup the port with an ID the app supplies (only when a port is required, of course)? The second one could be done with little additional code -- the app just needs to check if an additional port is needed when configuring the eventdev, and another helper function could take a list of <eventdev, ethdev> pairs and return true if any don't have an inbuilt port.
>>>
>>> I am in favor adding more logic in helper function(I believe, first one ) so that it will help
>>> application reuse the helper functions for the normal case.
>>>
>>
>> Hi Jerin,
> 
> Hi Nikhil,
> 
>>
>> My understanding of the discussion above is that the simple API adapter
>> creation API is
>>
>> int rte_event_eth_rx_adapter_create(id, eventdev_id)
>>
>> And the raw API is
>>
>> typedef int (*rx_adapter_conf_cb) (id, eventdev_id,
>> 	struct rte_event_eth_rx_adapter_conf *conf, void *arg);
>>
>> struct rte_event_eth_rx_adapter_conf {
>> 	uint8_t rx_event_port_id;
>> 	uint32_t max_nb_rx;
>> };
>>
>> int rte_event_eth_rx_adapter_create_ext(id, eventdev_id, conf_cb,
>> 					conf_arg)
>>
>> The conf_cb is invoked if the rte_event_eth_rx_adapter_conf struct needs to
>> be filled out. the _create_ext() API is used internally by
>> rte_event_eth_rx_adapter_create()
>>
>> Does that look OK to you ?
> 
> Just elaborating with additional detail. Let me know my understating is correct
> or not?

Yes. Thanks for the clarification.

> 
> default_cb(id, eventdev_id, conf)
> {
> 
> 	conf->rx_event_port_id = rte_event_port() + 1;
> 	conf->max_nb_rx = ...;
> 	....
> }
> 
> rte_event_eth_rx_adapter_create(id, eventdev_id)
> {
> 	struct rte_event_eth_rx_adapter_conf default_conf_arg;
> 
> 	rte_event_eth_rx_adapter_create_ext(id, eventdev_id,
> 			default_cb, &default_conf_arg);
> }
> 
> Application is free to use rte_event_eth_rx_adapter_create() or
> rte_event_eth_rx_adapter_create_ext(). rte_event_eth_rx_adapter_create_ext()
> will be used by application when "default_cb" handler is not enough for
> the use cases.
> 
> 
>>
>> Nikhil
>>
> 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
  2017-08-11  5:25                                     ` Rao, Nikhil
  2017-08-11  9:49                                       ` Jerin Jacob
@ 2017-09-04  6:37                                       ` Jerin Jacob
  1 sibling, 0 replies; 41+ messages in thread
From: Jerin Jacob @ 2017-09-04  6:37 UTC (permalink / raw)
  To: Rao, Nikhil
  Cc: gage.eads, dev, thomas, bruce.richardson, harry.van.haaren,
	hemant.agrawal, nipun.gupta, narender.vangati, Abhinandan Gujjar

-----Original Message-----
> Date: Fri, 11 Aug 2017 10:55:38 +0530
> From: "Rao, Nikhil" <nikhil.rao@intel.com>
> To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> CC: gage.eads@intel.com, dev@dpdk.org, thomas@monjalon.net,
>  bruce.richardson@intel.com, harry.van.haaren@intel.com,
>  hemant.agrawal@nxp.com, nipun.gupta@nxp.com, narender.vangati@intel.com,
>  Abhinandan Gujjar <abhinandan.gujjar@intel.com>
> Subject: Re: [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues
> User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101
>  Thunderbird/52.2.1
> 
> On 8/1/2017 10:12 PM, Jerin Jacob wrote:
> > > I have had the application specify the name. so that it can call
> > > 
> > > struct rte_service_spec *rte_service_get_by_name(const char *name);
> > 
> > OK. I was thinking like there will be fixed name for the rx_adapter
> > service like "eth_rx_adapter_%d"(%d for adapter id) which be exposed in
> > rte_event_eth_rx_adapter.h.
> > It can help in removing cfg.service_name. I am fine with either way.
> > 
> 
> OK, I will use a fixed name.
> 
> > > > eventdev PMD op api(not as adapter PMD as discussed earlier)
> > > > -------------------
> > > > 
> > > > 1) typedef uint64_t (*eventdev_rx_adap_capa)(struct rte_eventdev *dev,  uint8_t ethdev_id)
> > > > 
> > > > Return the adapter capability of a given eventdev when it needs to
> > > > connected to a specific ethdev_id
> > > > 
> > > 
> > > Doesn't the capability of a <eventdev, ethdev> also need to be made
> > > available to the application as an adapter API ?
> > 
> > Yes. Make sense to expose as adapter API also.
> > 
> 
> Correcting myself, Isn't this really an eventdev API ? An adapter API would
> take an adapter id argument which is unnecessary in this case.
> 
> Nikhil

Nikhil,

Are you planning to send the updated version? I would like this get
merged in v17.11 to remove eventdev's EXPERIMENTAL status.

^ permalink raw reply	[flat|nested] 41+ messages in thread

end of thread, other threads:[~2017-09-04  6:38 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-09 20:38 [RFC] eventdev: add event adapter for ethernet Rx queues Gage Eads
2017-05-11 16:38 ` Jerin Jacob
2017-05-16 20:51   ` Thomas Monjalon
2017-05-24  4:30   ` Rao, Nikhil
2017-06-19 10:05     ` Jerin Jacob
2017-06-26 13:19       ` Jerin Jacob
2017-06-28  6:47         ` Rao, Nikhil
2017-07-06 21:52           ` [PATCH 1/2] " Nikhil Rao
2017-07-06 14:18             ` Jerin Jacob
2017-07-07  6:21               ` Rao, Nikhil
2017-07-07 15:03                 ` Jerin Jacob
2017-07-07 15:57                   ` Jerin Jacob
2017-07-10  6:14                     ` Rao, Nikhil
2017-07-10 10:41                       ` Jerin Jacob
2017-07-13  3:26                         ` Rao, Nikhil
2017-07-13 18:45                           ` Jerin Jacob
2017-07-27 10:58                             ` Rao, Nikhil
2017-07-29 15:12                               ` Jerin Jacob
2017-07-31  3:57                                 ` Nipun Gupta
2017-07-31 15:31                                   ` Jerin Jacob
2017-08-01  8:40                                 ` Rao, Nikhil
2017-08-01 16:42                                   ` Jerin Jacob
2017-08-02 19:19                                     ` Eads, Gage
2017-08-03  6:23                                       ` Jerin Jacob
2017-08-09  2:23                                         ` Eads, Gage
2017-08-09 16:19                                           ` Jerin Jacob
2017-08-09 19:24                                             ` Eads, Gage
2017-08-10 16:53                                               ` Jerin Jacob
2017-08-14  8:48                                                 ` Rao, Nikhil
2017-08-14 11:11                                                   ` Jerin Jacob
2017-08-16  5:06                                                     ` Rao, Nikhil
2017-08-11  5:25                                     ` Rao, Nikhil
2017-08-11  9:49                                       ` Jerin Jacob
2017-09-04  6:37                                       ` Jerin Jacob
2017-07-06 21:52             ` [PATCH 2/2] eventdev: add event eth rx adapter unit tests Nikhil Rao
2017-07-24 10:10             ` [PATCH 1/2] eventdev: add event adapter for ethernet Rx queues Nipun Gupta
2017-07-24 10:24               ` Jerin Jacob
2017-07-24 11:37                 ` Nipun Gupta
2017-07-24 10:32               ` Van Haaren, Harry
2017-07-24 13:06                 ` Nipun Gupta
2017-07-24 13:33                   ` Van Haaren, Harry

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.