Queue-based flow rules management mechanism is suitable
not only for flow rules creation/destruction, but also
for speeding up other types of Flow API management.
Indirect action object operations may be executed
asynchronously as well. Provide async versions for all
indirect action operations, namely:
rte_flow_async_action_handle_create,
rte_flow_async_action_handle_destroy and
rte_flow_async_action_handle_update.

Signed-off-by: Alexander Kozyrev <akozy...@nvidia.com>
Acked-by: Ori Kam <or...@nvidia.com>
---
 doc/guides/prog_guide/rte_flow.rst     |  50 ++++++++++++
 doc/guides/rel_notes/release_22_03.rst |   5 ++
 lib/ethdev/rte_flow.c                  |  61 ++++++++++++++
 lib/ethdev/rte_flow.h                  | 109 +++++++++++++++++++++++++
 lib/ethdev/rte_flow_driver.h           |  26 ++++++
 lib/ethdev/version.map                 |   3 +
 6 files changed, 254 insertions(+)

diff --git a/doc/guides/prog_guide/rte_flow.rst 
b/doc/guides/prog_guide/rte_flow.rst
index c6f6f0afba..8148531073 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -3861,6 +3861,56 @@ Enqueueing a flow rule destruction operation is similar 
to simple destruction.
                               void *user_data,
                               struct rte_flow_error *error);
 
+Enqueue indirect action creation operation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Asynchronous version of indirect action creation API.
+
+.. code-block:: c
+
+       struct rte_flow_action_handle *
+       rte_flow_async_action_handle_create(uint16_t port_id,
+               uint32_t queue_id,
+               const struct rte_flow_q_ops_attr *q_ops_attr,
+               const struct rte_flow_indir_action_conf *indir_action_conf,
+               const struct rte_flow_action *action,
+               void *user_data,
+               struct rte_flow_error *error);
+
+A valid handle in case of success is returned. It must be destroyed later by
+``rte_flow_async_action_handle_destroy()`` even if the rule was rejected.
+
+Enqueue indirect action destruction operation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Asynchronous version of indirect action destruction API.
+
+.. code-block:: c
+
+       int
+       rte_flow_async_action_handle_destroy(uint16_t port_id,
+               uint32_t queue_id,
+               const struct rte_flow_q_ops_attr *q_ops_attr,
+               struct rte_flow_action_handle *action_handle,
+               void *user_data,
+               struct rte_flow_error *error);
+
+Enqueue indirect action update operation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Asynchronous version of indirect action update API.
+
+.. code-block:: c
+
+       int
+       rte_flow_async_action_handle_update(uint16_t port_id,
+               uint32_t queue_id,
+               const struct rte_flow_q_ops_attr *q_ops_attr,
+               struct rte_flow_action_handle *action_handle,
+               const void *update,
+               void *user_data,
+               struct rte_flow_error *error);
+
 Push enqueued operations
 ~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_22_03.rst 
b/doc/guides/rel_notes/release_22_03.rst
index 2477f53ca6..da186315a5 100644
--- a/doc/guides/rel_notes/release_22_03.rst
+++ b/doc/guides/rel_notes/release_22_03.rst
@@ -120,6 +120,11 @@ New Features
     ``rte_flow_pull`` to poll and retrieve results of these operations and
     ``rte_flow_push`` to push all the in-flight        operations to the NIC.
 
+  * ethdev: Added asynchronous API for indirect actions management:
+    ``rte_flow_async_action_handle_create``,
+    ``rte_flow_async_action_handle_destroy`` and
+    ``rte_flow_async_action_handle_update``.
+
 * **Updated AF_XDP PMD**
 
   * Added support for libxdp >=v1.2.2.
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index c314129870..9a902da660 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -1791,3 +1791,64 @@ rte_flow_pull(uint16_t port_id,
        ret = ops->pull(dev, queue_id, res, n_res, error);
        return ret ? ret : flow_err(port_id, ret, error);
 }
+
+struct rte_flow_action_handle *
+rte_flow_async_action_handle_create(uint16_t port_id,
+               uint32_t queue_id,
+               const struct rte_flow_op_attr *op_attr,
+               const struct rte_flow_indir_action_conf *indir_action_conf,
+               const struct rte_flow_action *action,
+               void *user_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);
+       struct rte_flow_action_handle *handle;
+
+       handle = ops->async_action_handle_create(dev, queue_id, op_attr,
+                                            indir_action_conf, action, 
user_data, error);
+       if (handle == NULL)
+               flow_err(port_id, -rte_errno, error);
+       return handle;
+}
+
+int
+rte_flow_async_action_handle_destroy(uint16_t port_id,
+               uint32_t queue_id,
+               const struct rte_flow_op_attr *op_attr,
+               struct rte_flow_action_handle *action_handle,
+               void *user_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);
+       int ret;
+
+       ret = ops->async_action_handle_destroy(dev, queue_id, op_attr,
+                                          action_handle, user_data, error);
+       return flow_err(port_id, ret, error);
+}
+
+int
+rte_flow_async_action_handle_update(uint16_t port_id,
+               uint32_t queue_id,
+               const struct rte_flow_op_attr *op_attr,
+               struct rte_flow_action_handle *action_handle,
+               const void *update,
+               void *user_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);
+       int ret;
+
+       if (unlikely(!ops))
+               return -rte_errno;
+       if (unlikely(!ops->async_action_handle_update))
+               return rte_flow_error_set(error, ENOSYS,
+                                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                                         NULL, rte_strerror(ENOSYS));
+       ret = ops->async_action_handle_update(dev, queue_id, op_attr,
+                                         action_handle, update, user_data, 
error);
+       return flow_err(port_id, ret, error);
+}
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 3fb7cb03ae..d8827dd184 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -5504,6 +5504,115 @@ rte_flow_pull(uint16_t port_id,
              uint16_t n_res,
              struct rte_flow_error *error);
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Enqueue indirect action creation operation.
+ * @see rte_flow_action_handle_create
+ *
+ * @param[in] port_id
+ *   Port identifier of Ethernet device.
+ * @param[in] queue_id
+ *   Flow queue which is used to create the rule.
+ * @param[in] op_attr
+ *   Indirect action creation operation attributes.
+ * @param[in] indir_action_conf
+ *   Action configuration for the indirect action object creation.
+ * @param[in] action
+ *   Specific configuration of the indirect action object.
+ * @param[in] user_data
+ *   The user data that will be returned on the completion events.
+ * @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.
+ */
+__rte_experimental
+struct rte_flow_action_handle *
+rte_flow_async_action_handle_create(uint16_t port_id,
+               uint32_t queue_id,
+               const struct rte_flow_op_attr *op_attr,
+               const struct rte_flow_indir_action_conf *indir_action_conf,
+               const struct rte_flow_action *action,
+               void *user_data,
+               struct rte_flow_error *error);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Enqueue indirect action destruction operation.
+ * The destroy queue must be the same
+ * as the queue on which the action was created.
+ *
+ * @param[in] port_id
+ *   Port identifier of Ethernet device.
+ * @param[in] queue_id
+ *   Flow queue which is used to destroy the rule.
+ * @param[in] op_attr
+ *   Indirect action destruction operation attributes.
+ * @param[in] action_handle
+ *   Handle for the indirect action object to be destroyed.
+ * @param[in] user_data
+ *   The user data that will be returned on the completion events.
+ * @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_async_action_handle_destroy(uint16_t port_id,
+               uint32_t queue_id,
+               const struct rte_flow_op_attr *op_attr,
+               struct rte_flow_action_handle *action_handle,
+               void *user_data,
+               struct rte_flow_error *error);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Enqueue indirect action update operation.
+ * @see rte_flow_action_handle_create
+ *
+ * @param[in] port_id
+ *   Port identifier of Ethernet device.
+ * @param[in] queue_id
+ *   Flow queue which is used to update the rule.
+ * @param[in] op_attr
+ *   Indirect action update operation attributes.
+ * @param[in] action_handle
+ *   Handle for the indirect action object to be updated.
+ * @param[in] update
+ *   Update profile specification used to modify the action pointed by handle.
+ *   *update* could be with the same type of the immediate action corresponding
+ *   to the *handle* argument when creating, or a wrapper structure includes
+ *   action configuration to be updated and bit fields to indicate the member
+ *   of fields inside the action to update.
+ * @param[in] user_data
+ *   The user data that will be returned on the completion events.
+ * @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_async_action_handle_update(uint16_t port_id,
+               uint32_t queue_id,
+               const struct rte_flow_op_attr *op_attr,
+               struct rte_flow_action_handle *action_handle,
+               const void *update,
+               void *user_data,
+               struct rte_flow_error *error);
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/ethdev/rte_flow_driver.h b/lib/ethdev/rte_flow_driver.h
index 5907dd63c3..2bff732d6a 100644
--- a/lib/ethdev/rte_flow_driver.h
+++ b/lib/ethdev/rte_flow_driver.h
@@ -234,6 +234,32 @@ struct rte_flow_ops {
                 struct rte_flow_op_result res[],
                 uint16_t n_res,
                 struct rte_flow_error *error);
+       /** See rte_flow_async_action_handle_create() */
+       struct rte_flow_action_handle *(*async_action_handle_create)
+               (struct rte_eth_dev *dev,
+                uint32_t queue_id,
+                const struct rte_flow_op_attr *op_attr,
+                const struct rte_flow_indir_action_conf *indir_action_conf,
+                const struct rte_flow_action *action,
+                void *user_data,
+                struct rte_flow_error *err);
+       /** See rte_flow_async_action_handle_destroy() */
+       int (*async_action_handle_destroy)
+               (struct rte_eth_dev *dev,
+                uint32_t queue_id,
+                const struct rte_flow_op_attr *op_attr,
+                struct rte_flow_action_handle *action_handle,
+                void *user_data,
+                struct rte_flow_error *error);
+       /** See rte_flow_async_action_handle_update() */
+       int (*async_action_handle_update)
+               (struct rte_eth_dev *dev,
+                uint32_t queue_id,
+                const struct rte_flow_op_attr *op_attr,
+                struct rte_flow_action_handle *action_handle,
+                const void *update,
+                void *user_data,
+                struct rte_flow_error *error);
 };
 
 /**
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index 13c1a22118..20391ab29e 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -276,6 +276,9 @@ EXPERIMENTAL {
        rte_flow_async_destroy;
        rte_flow_push;
        rte_flow_pull;
+       rte_flow_async_action_handle_create;
+       rte_flow_async_action_handle_destroy;
+       rte_flow_async_action_handle_update;
 };
 
 INTERNAL {
-- 
2.18.2

Reply via email to