From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 7D91AA0526; Wed, 15 Jul 2020 11:01:01 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 2A3161BFB9; Wed, 15 Jul 2020 11:01:01 +0200 (CEST) Received: from dispatch1-us1.ppe-hosted.com (dispatch1-us1.ppe-hosted.com [148.163.129.52]) by dpdk.org (Postfix) with ESMTP id A05B21BFB8 for ; Wed, 15 Jul 2020 11:00:59 +0200 (CEST) Received: from mx1-us1.ppe-hosted.com (unknown [10.7.65.60]) by dispatch1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTP id 1DBCA60084; Wed, 15 Jul 2020 09:00:59 +0000 (UTC) Received: from us4-mdac16-14.ut7.mdlocal (unknown [10.7.65.238]) by mx1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTP id 1C3132009A; Wed, 15 Jul 2020 09:00:59 +0000 (UTC) X-Virus-Scanned: Proofpoint Essentials engine Received: from mx1-us1.ppe-hosted.com (unknown [10.7.66.33]) by mx1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTPS id 72BC11C004F; Wed, 15 Jul 2020 09:00:57 +0000 (UTC) Received: from webmail.solarflare.com (uk.solarflare.com [193.34.186.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by mx1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTPS id A61C3A8006D; Wed, 15 Jul 2020 09:00:56 +0000 (UTC) Received: from [192.168.38.17] (10.17.10.39) by ukex01.SolarFlarecom.com (10.17.10.4) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 15 Jul 2020 10:00:45 +0100 To: Andrey Vesnovaty , Neil Horman , Thomas Monjalon , Ferruh Yigit , Ori Kam CC: "Kinsella, Ray" , , , , , , References: <20200708204015.24429-2-andreyv@mellanox.com> From: Andrew Rybchenko Autocrypt: addr=arybchenko@solarflare.com; keydata= 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 Znk9 Message-ID: Date: Wed, 15 Jul 2020 12:00:42 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.9.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset="utf-8" Content-Language: en-US Content-Transfer-Encoding: 7bit X-Originating-IP: [10.17.10.39] X-ClientProxiedBy: ocex03.SolarFlarecom.com (10.20.40.36) To ukex01.SolarFlarecom.com (10.17.10.4) X-TM-AS-Product-Ver: SMEX-12.5.0.1300-8.6.1012-25542.003 X-TM-AS-Result: No-17.528500-8.000000-10 X-TMASE-MatchedRID: IeZYkn8zfFp0nsJmoztmWKJVTu7sjgg1rkGhd90/DD7c9KE2iwgwHr+H BMNMGUuYB8MPcT5elBWNRQDuzd4go1T3aqamtlji52cbj4/WmPsbQ57RP6lOUeTWTJAOkSPwKPn doQHmoMs4Vc7EZt/mtzfKqTJds80FdJuZwx6Jqk11BumBmrnKW3dYbPDVqm8dzVgwP7ZMYf+O9R uvjhocOhvNXgElSjKuItGxsLYa0heM7bPqUIhn2pU7Bltw5qVLwCx/VTlAePrI9EDAP/dptqyAQ bvPfXXm5DtE0VFtf//02fCVoFgpMqZuRTwZTaXdJmbrB1j4XwoTcSAXT4xW4P/rgj9ncWz9bwDL MAk7T7Hz9DpdH+Od4q28ztnoMfpdvLGmW0LFNCf0VCHd+VQiHgokziiS8fle92kzZlokyR5nLmO IseD6Cm/BEyK8abarjJBZomd1S35B1lmEI6imBY4VSIjAMorOTxL5U2EWalt646N1/Xvgx3JS81 mqB724cZutroCkFkV3CBchuiW/I/fuVpATnjcHUeavKZUnS5ATA7ACF0jdA23D6f6IpbLItdA9A fZ7l9PTo34KsilbM//obOPM9tlrd9BoZPg3+rObbGl0ztMpl+vcTjVWUqx9V7MQTbTl02/g9z9x 7gUJva8NRe/Drk9OlRiYrL8iS6VUioY0zUhrN/qifdI85BZhq3MsQB4M7MKrZHMcVOhFSNyu749 IyF6P4aBLis6itivS/BAcn1sAYrBAQLqGlKivUrViw6AaT1FKgIbix5+XxMl8NQ3m2sq+PmWb5U MEjgSp3LSx4kfWR+2B2q+XxKfstLD+nJjWKTieAiCmPx4NwLTrdaH1ZWqC1B0Hk1Q1KyLgfCfWl nNb/1cppCzPq+1UOwBXM346/+yWg051ex1kn3K2hzOuNiANrFZVz7CuGm3daRM5lGtbZC124ISq cYwt X-TM-AS-User-Approved-Sender: Yes X-TM-AS-User-Blocked-Sender: No X-TMASE-Result: 10--17.528500-8.000000 X-TMASE-Version: SMEX-12.5.0.1300-8.6.1012-25542.003 X-MDID: 1594803657-BcXXLvlZGd99 Subject: Re: [dpdk-dev] [PATCH v2 1/6] ethdev: add flow shared action API X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" I'm sorry for a duplicate of my message from July, 13. The problem is that I've not found my reply in patchwork and mail thread. Now I found out that I'm replying to Ray's mail and the mail is not in the thread since has invalid message headers. Andrew. On 7/15/20 11:54 AM, Andrew Rybchenko wrote: > On 7/13/20 11:04 AM, Kinsella, Ray wrote: >> >> >> On 08/07/2020 21:40, Andrey Vesnovaty wrote: >>> From: Andrey Vesnovaty >>> >>> This commit introduces extension of DPDK flow action API enabling >>> sharing of single rte_flow_action in multiple flows. The API intended for >>> PMDs where multiple HW offloaded flows can reuse the same HW >>> essence/object representing flow action and modification of such an >>> essence/object effects all the rules using it. >>> >>> Motivation and example >>> === >>> Adding or removing one or more queues to RSS used by multiple flow rules >>> imposes per rule toll for current DPDK flow API; the scenario requires >>> for each flow sharing cloned RSS action: >>> - call `rte_flow_destroy()` >>> - call `rte_flow_create()` with modified RSS action >>> >>> API for sharing action and its in-place update benefits: >>> - reduce the overhead of multiple RSS flow rules reconfiguration > > It *allows* to reduce the overhead of multiple RSS flow rules > reconfiguration. I.e. it is not mandatory. PMD may do it in SW, > if HW does not support it. I see no problem to allow it. > Even if it is done in PMD, it is already an optimization since > applications have unified interface and internally it should > be cheaper to do it. > I'd consider to implement generic SW helper API for PMDs which > cannot have shared actions in HW, but would like to simulate it > in SW. It would allow to avoid the fallback in applications. > >>> - optimize resource utilization by sharing action across of multiple >>> flows >>> >>> Change description >>> === >>> >>> Shared action >>> === >>> In order to represent flow action shared by multiple flows new action >>> type RTE_FLOW_ACTION_TYPE_SHARED is introduced (see `enum >>> rte_flow_action_type`). >>> Actually the introduced API decouples action from any specific flow and >>> enables sharing of single action by its handle across multiple flows. >>> >>> Shared action create/use/destroy >>> === >>> Shared action may be reused by some or none flow rules at any given >>> moment, i.e. shared action reside outside of the context of any flow. >>> Shared action represent HW resources/objects used for action offloading >>> implementation. >>> API for shared action create (see `rte_flow_shared_action_create()`): >>> - should allocate HW resources and make related initializations required >>> for shared action implementation. >>> - make necessary preparations to maintain shared access to >>> the action resources, configuration and state. >>> API for shared action destroy (see `rte_flow_shared_action_destroy()`) >>> should release HW resources and make related cleanups required for shared >>> action implementation. >>> >>> In order to share some flow action reuse the handle of type >>> `struct rte_flow_shared_action` returned by >>> rte_flow_shared_action_create() as a `conf` field of >>> `struct rte_flow_action` (see "example" section). >>> >>> If some shared action not used by any flow rule all resources allocated >>> by the shared action can be released by rte_flow_shared_action_destroy() >>> (see "example" section). The shared action handle passed as argument to >>> destroy API should not be used any further i.e. result of the usage is >>> undefined. > > May be it makes sense to implement housekeeping in ethdev > layer? I.e. guarantee consequency using reference counters etc. > Will applications benefit from it? > >>> >>> Shared action re-configuration >>> === >>> Shared action behavior defined by its configuration can be updated via >>> rte_flow_shared_action_update() (see "example" section). The shared >>> action update operation modifies HW related resources/objects allocated >>> on the action creation. The number of operations performed by the update >>> operation should not be dependent on number of flows sharing the related >>> action. On return of shared action update API action behavior should be >>> according to updated configuration for all flows sharing the action. > > If shared action is simulated in SW, number of operations to do > reconfiguration will depend on a number of flow rules using it. > I think it is not a problem. So, *should not* used above is OK. > > Consider: > "should not be dependent on" -> "should not depend on" > >>> >>> Shared action query >>> === >>> Provide separate API to query shared action sate (see > > sate -> state > >>> rte_flow_shared_action_update()). Taking a counter as an example: query >>> returns value aggregating all counter increments across all flow rules >>> sharing the counter. >>> >>> PMD support >>> === >>> The support of introduced API is pure PMD specific design and >>> responsibility for each action type (see struct rte_flow_ops). >>> >>> testpmd >>> === >>> In order to utilize introduced API testpmd cli may implement following >>> extension >>> create/update/destroy/query shared action accordingly >>> >>> flow shared_action create {port_id} [index] {action} >>> flow shared_action update {port_id} {index} {action} >>> flow shared_action destroy {port_id} {index} >>> flow shared_action query {port_id} {index} >>> >>> testpmd example >>> === >>> >>> configure rss to queues 1 & 2 >>> >>> testpmd> flow shared_action create 0 100 rss 1 2 >>> >>> create flow rule utilizing shared action >>> >>> testpmd> flow create 0 ingress \ >>> pattern eth dst is 0c:42:a1:15:fd:ac / ipv6 / tcp / end \ >>> actions shared 100 end / end >>> >>> add 2 more queues >>> >>> testpmd> flow shared_action modify 0 100 rss 1 2 3 4 >>> >>> example >>> === >>> >>> struct rte_flow_action actions[2]; >>> struct rte_flow_action action; >>> /* skipped: initialize action */ >>> struct rte_flow_shared_action *handle = rte_flow_shared_action_create( >>> port_id, &action, &error); > > It should be possible to have many actions in shared action. > I.e. similar to below, it should be an array terminated by > RTE_FLOW_ACTION_TYPE_END. It is unclear from the example > above. > >>> actions[0].type = RTE_FLOW_ACTION_TYPE_SHARED; >>> actions[0].conf = handle; >>> actions[1].type = RTE_FLOW_ACTION_TYPE_END; >>> /* skipped: init attr0 & pattern0 args */ >>> struct rte_flow *flow0 = rte_flow_create(port_id, &attr0, pattern0, >>> actions, error); >>> /* create more rules reusing shared action */ >>> struct rte_flow *flow1 = rte_flow_create(port_id, &attr1, pattern1, >>> actions, error); >>> /* skipped: for flows 2 till N */ >>> struct rte_flow *flowN = rte_flow_create(port_id, &attrN, patternN, >>> actions, error); >>> /* update shared action */ >>> struct rte_flow_action updated_action; >>> /* >>> * skipped: initialize updated_action according to desired action >>> * configuration change >>> */ >>> rte_flow_shared_action_update(port_id, handle, &updated_action, error); >>> /* >>> * from now on all flows 1 till N will act according to configuration of >>> * updated_action >>> */ >>> /* skipped: destroy all flows 1 till N */ >>> rte_flow_shared_action_destroy(port_id, handle, error); >>> >>> Signed-off-by: Andrey Vesnovaty >>> --- >>> lib/librte_ethdev/rte_ethdev_version.map | 6 + >>> lib/librte_ethdev/rte_flow.c | 81 +++++++++++++ >>> lib/librte_ethdev/rte_flow.h | 148 ++++++++++++++++++++++- >>> lib/librte_ethdev/rte_flow_driver.h | 22 ++++ >>> 4 files changed, 256 insertions(+), 1 deletion(-) >>> >>> diff --git a/lib/librte_ethdev/rte_ethdev_version.map >>> b/lib/librte_ethdev/rte_ethdev_version.map >>> index 7155056045..119d84976a 100644 >>> --- a/lib/librte_ethdev/rte_ethdev_version.map >>> +++ b/lib/librte_ethdev/rte_ethdev_version.map >>> @@ -241,4 +241,10 @@ EXPERIMENTAL { >>> __rte_ethdev_trace_rx_burst; >>> __rte_ethdev_trace_tx_burst; >>> rte_flow_get_aged_flows; >>> + >>> + # added in 20.08 >>> + rte_flow_shared_action_create; >>> + rte_flow_shared_action_destroy; >>> + rte_flow_shared_action_update; >>> + rte_flow_shared_action_query; >>> }; >>> diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c >>> index 1685be5f73..0ac4d31a13 100644 >>> --- a/lib/librte_ethdev/rte_flow.c >>> +++ b/lib/librte_ethdev/rte_flow.c >>> @@ -1250,3 +1250,84 @@ rte_flow_get_aged_flows(uint16_t port_id, void >>> **contexts, >>> RTE_FLOW_ERROR_TYPE_UNSPECIFIED, >>> NULL, rte_strerror(ENOTSUP)); >>> } >>> + >>> +struct rte_flow_shared_action * >>> +rte_flow_shared_action_create(uint16_t port_id, >>> + const struct rte_flow_action *action, >>> + struct rte_flow_error *error) >>> +{ >>> + struct rte_eth_dev *dev = &rte_eth_devices[port_id]; >>> + struct rte_flow_shared_action *shared_action; >>> + const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error); >>> + >>> + if (unlikely(!ops)) >>> + return NULL; >>> + if (likely(!!ops->shared_action_create)) { >>> + shared_action = ops->shared_action_create(dev, action, error); >>> + if (shared_action == NULL) >>> + flow_err(port_id, -rte_errno, error); >>> + return shared_action; >>> + } >>> + rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, >>> + NULL, rte_strerror(ENOSYS)); >>> + return NULL; >>> +} >>> + >>> +int >>> +rte_flow_shared_action_destroy(uint16_t port_id, >>> + struct rte_flow_shared_action *action, >>> + struct rte_flow_error *error) >>> +{ >>> + struct rte_eth_dev *dev = &rte_eth_devices[port_id]; >>> + const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error); >>> + >>> + if (unlikely(!ops)) >>> + return -rte_errno; >>> + if (likely(!!ops->shared_action_destroy)) >>> + return flow_err(port_id, >>> + ops->shared_action_destroy(dev, action, error), >>> + error); >>> + return rte_flow_error_set(error, ENOSYS, >>> + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, >>> + NULL, rte_strerror(ENOSYS)); >>> +} >>> + >>> +int >>> +rte_flow_shared_action_update(uint16_t port_id, >>> + struct rte_flow_shared_action *action, >>> + const struct rte_flow_action *update, >>> + struct rte_flow_error *error) >>> +{ >>> + struct rte_eth_dev *dev = &rte_eth_devices[port_id]; >>> + const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error); >>> + >>> + if (unlikely(!ops)) >>> + return -rte_errno; >>> + if (likely(!!ops->shared_action_update)) >>> + return flow_err(port_id, ops->shared_action_update(dev, action, >>> + update, error), >>> + error); >>> + return rte_flow_error_set(error, ENOSYS, >>> + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, >>> + NULL, rte_strerror(ENOSYS)); >>> +} >>> + >>> +int >>> +rte_flow_shared_action_query(uint16_t port_id, >>> + const struct rte_flow_shared_action *action, >>> + void *data, >>> + struct rte_flow_error *error) >>> +{ >>> + struct rte_eth_dev *dev = &rte_eth_devices[port_id]; >>> + const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error); >>> + >>> + if (unlikely(!ops)) >>> + return -rte_errno; >>> + if (likely(!!ops->shared_action_query)) >>> + return flow_err(port_id, ops->shared_action_query(dev, action, >>> + data, error), >>> + error); >>> + return rte_flow_error_set(error, ENOSYS, >>> + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, >>> + NULL, rte_strerror(ENOSYS)); >>> +} >>> diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h >>> index b0e4199192..257456b14a 100644 >>> --- a/lib/librte_ethdev/rte_flow.h >>> +++ b/lib/librte_ethdev/rte_flow.h >>> @@ -1681,7 +1681,8 @@ enum rte_flow_action_type { >>> /** >>> * Enables counters for this flow rule. >>> * >>> - * These counters can be retrieved and reset through rte_flow_query(), >>> + * These counters can be retrieved and reset through rte_flow_query() or >>> + * rte_flow_shared_action_query() if the action provided via handle, >>> * see struct rte_flow_query_count. >>> * >>> * See struct rte_flow_action_count. >>> @@ -2099,6 +2100,14 @@ enum rte_flow_action_type { >>> * see enum RTE_ETH_EVENT_FLOW_AGED >>> */ >>> RTE_FLOW_ACTION_TYPE_AGE, >>> + >>> + /** >>> + * Describes action shared a cross multiple flow rules. > > Both options are possible, but I'd propose to stick to: > Describes -> Describe > > Or even: > Use actions shared across multiple flow rules. > >>> + * >>> + * Enables multiple rules reference the same action by handle (see > > Enables -> Allow > >>> + * struct rte_flow_shared_action). >>> + */ >>> + RTE_FLOW_ACTION_TYPE_SHARED, >>> }; >>> /** >>> @@ -2660,6 +2669,20 @@ struct rte_flow_action_set_dscp { >>> uint8_t dscp; >>> }; >>> + >>> +/** >>> + * RTE_FLOW_ACTION_TYPE_SHARED >>> + * >>> + * Opaque type returned after successfully creating a shared action. >>> + * >>> + * This handle can be used to manage and query the related action: >>> + * - share it a cross multiple flow rules >>> + * - update action configuration >>> + * - query action data >>> + * - destroy action >>> + */ >>> +struct rte_flow_shared_action; >>> + >>> /* Mbuf dynamic field offset for metadata. */ >>> extern int32_t rte_flow_dynf_metadata_offs; >>> @@ -3324,6 +3347,129 @@ int >>> rte_flow_get_aged_flows(uint16_t port_id, void **contexts, >>> uint32_t nb_contexts, struct rte_flow_error *error); >>> +/** >>> + * @warning >>> + * @b EXPERIMENTAL: this API may change without prior notice. >>> + * >>> + * Create shared action for reuse in multiple flow rules. >>> + * >>> + * @param[in] port_id >>> + * The port identifier of the Ethernet device. >>> + * @param[in] action >>> + * Action configuration for shared action creation. >>> + * @param[out] error >>> + * Perform verbose error reporting if not NULL. PMDs initialize this >>> + * structure in case of error only. >>> + * @return >>> + * A valid handle in case of success, NULL otherwise and rte_errno >>> is set >>> + * to one of the error codes defined: >>> + * - (ENOSYS) if underlying device does not support this functionality. >>> + * - (EIO) if underlying device is removed. >>> + * - (EINVAL) if *action* invalid. >>> + * - (ENOTSUP) if *action* valid but unsupported. >>> + */ >>> +__rte_experimental >>> +struct rte_flow_shared_action * >>> +rte_flow_shared_action_create(uint16_t port_id, >>> + const struct rte_flow_action *action, >>> + struct rte_flow_error *error); >>> + >>> +/** >>> + * @warning >>> + * @b EXPERIMENTAL: this API may change without prior notice. >>> + * >>> + * Destroys the shared action by handle. > > Destroys -> Destroy > >>> + * >>> + * @param[in] port_id >>> + * The port identifier of the Ethernet device. >>> + * @param[in] action >>> + * Handle for the shared action to be destroyed. >>> + * @param[out] error >>> + * Perform verbose error reporting if not NULL. PMDs initialize this >>> + * structure in case of error only. >>> + * @return >>> + * - (0) if success. >>> + * - (-ENOSYS) if underlying device does not support this functionality. >>> + * - (-EIO) if underlying device is removed. >>> + * - (-ENOENT) if action pointed by *action* handle was not found. >>> + * - (-ETOOMANYREFS) if action pointed by *action* handle still used >>> by one or >>> + * more rules >>> + * rte_errno is also set. >>> + */ >>> +__rte_experimental >>> +int >>> +rte_flow_shared_action_destroy(uint16_t port_id, >>> + struct rte_flow_shared_action *action, >>> + struct rte_flow_error *error); >>> + >>> +/** >>> + * @warning >>> + * @b EXPERIMENTAL: this API may change without prior notice. >>> + * >>> + * Updates inplace the shared action configuration pointed by >>> *action* handle > > Updates -> Update > inplace -> in-place > >>> + * with the configuration provided as *update* argument. >>> + * The update of the shared action configuration effects all flow >>> rules reusing > > May be: reusing -> using > >>> + * the action via handle. > > The interesting question what to do, if some rule cannot have a > new action (i.e. new action is invalid for a rule). > May be it is better to highlight it. > >>> + * >>> + * @param[in] port_id >>> + * The port identifier of the Ethernet device. >>> + * @param[in] action >>> + * Handle for the shared action to be updated. >>> + * @param[in] update >>> + * Action specification used to modify the action pointed by handle. >>> + * *update* should be of same type with the action pointed by the >>> *action* >>> + * handle argument, otherwise considered as invalid. > > Why? If it is a generic rule, it should be checked on a generic > ethdev layer, but I would not impose the limitation. If PMD > may change it, why generic interface specification should > restrict it. > >>> + * @param[out] error >>> + * Perform verbose error reporting if not NULL. PMDs initialize this >>> + * structure in case of error only. >>> + * @return >>> + * - (0) if success. >>> + * - (-ENOSYS) if underlying device does not support this functionality. >>> + * - (-EIO) if underlying device is removed. >>> + * - (-EINVAL) if *update* invalid. >>> + * - (-ENOTSUP) if *update* valid but unsupported. >>> + * - (-ENOENT) if action pointed by *ctx* was not found. >>> + * rte_errno is also set. >>> + */ >>> +__rte_experimental >>> +int >>> +rte_flow_shared_action_update(uint16_t port_id, >>> + struct rte_flow_shared_action *action, >>> + const struct rte_flow_action *update, >>> + struct rte_flow_error *error); >>> + >>> +/** >>> + * @warning >>> + * @b EXPERIMENTAL: this API may change without prior notice. >>> + * >>> + * Query the shared action by handle. >>> + * >>> + * This function allows retrieving action-specific data such as >>> counters. > > "This function allows retrieving" -> Retrieve or Get or Query > >>> + * Data is gathered by special action which may be present/referenced in >>> + * more than one flow rule definition. >>> + * >>> + * \see RTE_FLOW_ACTION_TYPE_COUNT >>> + * >>> + * @param port_id >>> + * Port identifier of Ethernet device. >>> + * @param[in] action >>> + * Handle for the shared action to query. >>> + * @param[in, out] data >>> + * Pointer to storage for the associated query data type. >>> + * @param[out] error >>> + * Perform verbose error reporting if not NULL. PMDs initialize this >>> + * structure in case of error only. >>> + * >>> + * @return >>> + * 0 on success, a negative errno value otherwise and rte_errno is set. >>> + */ >>> +__rte_experimental >>> +int >>> +rte_flow_shared_action_query(uint16_t port_id, >>> + const struct rte_flow_shared_action *action, >>> + void *data, >>> + struct rte_flow_error *error); >>> + >>> #ifdef __cplusplus >>> } >>> #endif >>> diff --git a/lib/librte_ethdev/rte_flow_driver.h >>> b/lib/librte_ethdev/rte_flow_driver.h >>> index 881cc469b7..a2cae1b53c 100644 >>> --- a/lib/librte_ethdev/rte_flow_driver.h >>> +++ b/lib/librte_ethdev/rte_flow_driver.h >>> @@ -107,6 +107,28 @@ struct rte_flow_ops { >>> void **context, >>> uint32_t nb_contexts, >>> struct rte_flow_error *err); >>> + /** See rte_flow_shared_action_create() */ >>> + struct rte_flow_shared_action *(*shared_action_create) >>> + (struct rte_eth_dev *dev, >>> + const struct rte_flow_action *action, >>> + struct rte_flow_error *error); >>> + /** See rte_flow_shared_action_destroy() */ >>> + int (*shared_action_destroy) >>> + (struct rte_eth_dev *dev, >>> + struct rte_flow_shared_action *shared_action, >>> + struct rte_flow_error *error); >>> + /** See rte_flow_shared_action_update() */ >>> + int (*shared_action_update) >>> + (struct rte_eth_dev *dev, >>> + struct rte_flow_shared_action *shared_action, >>> + const struct rte_flow_action *update, >>> + struct rte_flow_error *error); >>> + /** See rte_flow_shared_action_query() */ >>> + int (*shared_action_query) >>> + (struct rte_eth_dev *dev, >>> + const struct rte_flow_shared_action *shared_action, >>> + void *data, >>> + struct rte_flow_error *error); >>> }; >>> /** >>> >> >> The modification of "struct rte_flow_ops", looks fine. >> Acked-by: Ray Kinsella >> >