[dpdk-dev] [PATCH 1/2] ethdev: add capability control API

Dumitrescu, Cristian cristian.dumitrescu at intel.com
Mon Feb 13 12:32:08 CET 2017



> -----Original Message-----
> From: Wiles, Keith
> Sent: Saturday, February 11, 2017 1:07 PM
> To: Jerin Jacob <jerin.jacob at caviumnetworks.com>
> Cc: Dumitrescu, Cristian <cristian.dumitrescu at intel.com>; dev at dpdk.org;
> thomas.monjalon at 6wind.com; hemant.agrawal at nxp.com
> Subject: Re: [dpdk-dev] [PATCH 1/2] ethdev: add capability control API
> 
> 
> > On Feb 11, 2017, at 12:38 AM, Jerin Jacob
> <jerin.jacob at caviumnetworks.com> wrote:
> >
> > On Fri, Feb 10, 2017 at 02:05:49PM +0000, Cristian Dumitrescu wrote:
> >> The rte_flow feature breaks the current monolithic approach for ethdev
> and
> >> introduces the new generic flow API to ethdev using a plugin-like
> approach.
> >>
> >> Basically, the rte_flow API is still logically part of ethdev:
> >> - It extends the ethdev functionality: rte_flow is a new feature/capability
> >>  of ethdev;
> >> - all its functions work on an Ethernet device: the first parameter of the
> >>  rte_flow functions is Ethernet device port ID.
> >>
> >> At the same time, the rte_flow API is a sort of capability plugin for ethdev:
> >> - the rte_flow API functions have their own name space: they are called
> >>  rte_flow_operationXYZ() as opposed to
> rte_eth_dev_flow_operationXYZ());
> >> - the rte_flow API functions are placed in separate files in the same
> >>  librte_ether folder as opposed to rte_ethdev.[hc].
> >>
> >> The way it works is by using the existing ethdev API function
> >> rte_eth_dev_filter_ctrl() to query the current Ethernet device port ID for
> the
> >> support of the rte_flow capability and return the pointer to the
> >> rte_flow operations when supported and NULL otherwise:
> >>
> >> struct rte_flow_ops *eth_flow_ops;
> >> int rte = rte_eth_dev_filter_ctrl(eth_port_id,
> >> 	RTE_ETH_FILTER_GENERIC, RTE_ETH_FILTER_GET, &eth_flow_ops);
> >>
> >> Unfortunately, the rte_flow opportunistically uses the
> rte_eth_dev_filter_ctrl()
> >> API function, which is applicable just to RX-side filters as opposed to
> >> introducing a mechanism that could be used by any capability in a generic
> way.
> >>
> >> This is the gap that addressed by the current patch. This mechanism is
> intended
> >> to be used to introduce new capabilities into ethdev in a modular plugin-
> like
> >> approach, such as hierarchical scheduler. Over time, if agreed, it can also
> be
> >> used for exposing the existing Ethernet device capabilities in a modular
> way,
> >> such as: xstats, filters, multicast, mirroring, tunnels, time stamping,
> eeprom,
> >> bypass, etc.
> >>
> >> Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu at intel.com>
> >> ---
> >> lib/librte_ether/rte_ethdev.c          | 13 +++++++++++++
> >> lib/librte_ether/rte_ethdev.h          | 29
> +++++++++++++++++++++++++++++
> >> lib/librte_ether/rte_ether_version.map |  7 +++++++
> >> 3 files changed, 49 insertions(+)
> >>
> >> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> >> index eb0a94a..ae187c4 100644
> >> --- a/lib/librte_ether/rte_ethdev.c
> >> +++ b/lib/librte_ether/rte_ethdev.c
> >> @@ -2802,6 +2802,19 @@ rte_eth_dev_filter_ctrl(uint8_t port_id, enum
> rte_filter_type filter_type,
> >> 	return (*dev->dev_ops->filter_ctrl)(dev, filter_type, filter_op, arg);
> >> }
> >>
> >> +int
> >> +rte_eth_dev_capability_control(uint8_t port_id, enum
> rte_eth_capability cap,
> >> +	void *arg)
> >> +{
> >> +	struct rte_eth_dev *dev;
> >> +
> >> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> >> +
> >> +	dev = &rte_eth_devices[port_id];
> >> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->cap_ctrl, -
> ENOTSUP);
> >> +	return (*dev->dev_ops->cap_ctrl)(dev, cap, arg);
> >> +}
> >> +
> >> void *
> >> rte_eth_add_rx_callback(uint8_t port_id, uint16_t queue_id,
> >> 		rte_rx_callback_fn fn, void *user_param)
> >> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> >> index c17bbda..43ffb9e 100644
> >> --- a/lib/librte_ether/rte_ethdev.h
> >> +++ b/lib/librte_ether/rte_ethdev.h
> >> @@ -1073,6 +1073,12 @@ TAILQ_HEAD(rte_eth_dev_cb_list,
> rte_eth_dev_callback);
> >>  * structure associated with an Ethernet device.
> >>  */
> >>
> >> +enum rte_eth_capability {
> >> +	RTE_ETH_CAPABILITY_FLOW = 0, /**< Flow */
> >> +	RTE_ETH_CAPABILITY_SCHED, /**< Hierarchical Scheduler */
> >> +	RTE_ETH_CAPABILITY_MAX
> >> +};
> >
> > Shouldn't it be the FLAG?. Meaning, To represent ethdev port can have
> both.
> 
> The current API is requesting if the PMD supports the given feature and then
> returns the void * to the structure of function pointers or NULL similar to the
> rte_flow design. The developer would need to ask multiple times to
> understand if all of the features are supported by the PMD. I guess one of
> the options could be to return a list of features the PMD supports. The void *
> would point to the PMD capability list, which would need to be a const of
> some type to prevent someone from modifying the PMD capability list.
> 
> enum rte_eth_capability {
> 	RTE_ETH_CAPABILITY_LIST = 0,
> 	RTE_ETH_CAPABILITY_FLOW = 1,
> 	RTE_ETH_CAPABILITY_SCHED = 2,
> 	RTE_ETH_CAPABILITY_SCHED = 4,
> 	RTE_ETH_CAPABILITY_MAX		/* This one does not make
> sense in a bitmap set of enums */
> };
> 
> The RTE_ETH_CAPABILITY_LIST could return the (void *) as a uint64_t listing
> the feature bits. The problem I think is the uint64_t is limiting us to 63
> features (which maybe a big number, but maybe not) would be the only
> concern here. The PMD could return a pointer to a uint8_t array of feature
> values, were 0 is used as a no-op then we can have any number of features
> with the enum just being a number between 1-255 or uint16_t 1-65535.
> 
> Anyway just an option, we could have a different API for the feature list.
> 

Yes, the purpose of the proposed rte_eth_dev_capability_control() function is to check if a specific capability/feature is supported and get its ops structure when supported.

If required, somebody can easily build up the list of capabilities by calling this function in for loop  0 .. (RTE_ETH_CAPABILITY_MAX - 1), any issues with this approach?

> >
> >> +
> 
> Regards,
> Keith



More information about the dev mailing list