net/mlx5: add flow query abstraction interface
authorMoti Haimovsky <motih@mellanox.com>
Thu, 18 Oct 2018 18:29:22 +0000 (21:29 +0300)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 26 Oct 2018 20:14:05 +0000 (22:14 +0200)
Flow engine now supports multiple driver paths with each having
its own flow query implantation routine.
This patch adds an abstraction to the flow query routine in accordance
to commit 0c76d1c9a18d ("net/mlx5: add abstraction for multiple flow
drivers") done by Yongseok Koh.

Signed-off-by: Moti Haimovsky <motih@mellanox.com>
drivers/net/mlx5/mlx5_flow.c
drivers/net/mlx5/mlx5_flow.h
drivers/net/mlx5/mlx5_flow_dv.c
drivers/net/mlx5/mlx5_flow_tcf.c
drivers/net/mlx5/mlx5_flow_verbs.c

index bd70fce..fcabab0 100644 (file)
@@ -1653,6 +1653,17 @@ flow_null_destroy(struct rte_eth_dev *dev __rte_unused,
 {
 }
 
+static int
+flow_null_query(struct rte_eth_dev *dev __rte_unused,
+               struct rte_flow *flow __rte_unused,
+               const struct rte_flow_action *actions __rte_unused,
+               void *data __rte_unused,
+               struct rte_flow_error *error __rte_unused)
+{
+       rte_errno = ENOTSUP;
+       return -rte_errno;
+}
+
 /* Void driver to protect from null pointer reference. */
 const struct mlx5_flow_driver_ops mlx5_flow_null_drv_ops = {
        .validate = flow_null_validate,
@@ -1661,6 +1672,7 @@ const struct mlx5_flow_driver_ops mlx5_flow_null_drv_ops = {
        .apply = flow_null_apply,
        .remove = flow_null_remove,
        .destroy = flow_null_destroy,
+       .query = flow_null_query,
 };
 
 /**
@@ -2344,92 +2356,45 @@ mlx5_flow_isolate(struct rte_eth_dev *dev,
 }
 
 /**
- * Query flow counter.
- *
- * @param flow
- *   Pointer to the flow.
+ * Query a flow.
  *
- * @return
- *   0 on success, a negative errno value otherwise and rte_errno is set.
+ * @see rte_flow_query()
+ * @see rte_flow_ops
  */
 static int
-mlx5_flow_query_count(struct rte_flow *flow __rte_unused,
-                     void *data __rte_unused,
-                     struct rte_flow_error *error)
+flow_drv_query(struct rte_eth_dev *dev,
+              struct rte_flow *flow,
+              const struct rte_flow_action *actions,
+              void *data,
+              struct rte_flow_error *error)
 {
-#ifdef HAVE_IBV_DEVICE_COUNTERS_SET_SUPPORT
-       if (flow->actions & MLX5_FLOW_ACTION_COUNT) {
-               struct rte_flow_query_count *qc = data;
-               uint64_t counters[2] = {0, 0};
-               struct ibv_query_counter_set_attr query_cs_attr = {
-                       .cs = flow->counter->cs,
-                       .query_flags = IBV_COUNTER_SET_FORCE_UPDATE,
-               };
-               struct ibv_counter_set_data query_out = {
-                       .out = counters,
-                       .outlen = 2 * sizeof(uint64_t),
-               };
-               int err = mlx5_glue->query_counter_set(&query_cs_attr,
-                                                      &query_out);
+       const struct mlx5_flow_driver_ops *fops;
+       enum mlx5_flow_drv_type ftype = flow->drv_type;
 
-               if (err)
-                       return rte_flow_error_set
-                               (error, err,
-                                RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-                                NULL,
-                                "cannot read counter");
-               qc->hits_set = 1;
-               qc->bytes_set = 1;
-               qc->hits = counters[0] - flow->counter->hits;
-               qc->bytes = counters[1] - flow->counter->bytes;
-               if (qc->reset) {
-                       flow->counter->hits = counters[0];
-                       flow->counter->bytes = counters[1];
-               }
-               return 0;
-       }
-       return rte_flow_error_set(error, EINVAL,
-                                 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-                                 NULL,
-                                 "flow does not have counter");
-#endif
-       return rte_flow_error_set(error, ENOTSUP,
-                                 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-                                 NULL,
-                                 "counters are not available");
+       assert(ftype > MLX5_FLOW_TYPE_MIN && ftype < MLX5_FLOW_TYPE_MAX);
+       fops = flow_get_drv_ops(ftype);
+
+       return fops->query(dev, flow, actions, data, error);
 }
 
 /**
- * Query a flows.
+ * Query a flow.
  *
  * @see rte_flow_query()
  * @see rte_flow_ops
  */
 int
-mlx5_flow_query(struct rte_eth_dev *dev __rte_unused,
+mlx5_flow_query(struct rte_eth_dev *dev,
                struct rte_flow *flow,
                const struct rte_flow_action *actions,
                void *data,
                struct rte_flow_error *error)
 {
-       int ret = 0;
+       int ret;
 
-       for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
-               switch (actions->type) {
-               case RTE_FLOW_ACTION_TYPE_VOID:
-                       break;
-               case RTE_FLOW_ACTION_TYPE_COUNT:
-                       ret = mlx5_flow_query_count(flow, data, error);
-                       break;
-               default:
-                       return rte_flow_error_set(error, ENOTSUP,
-                                                 RTE_FLOW_ERROR_TYPE_ACTION,
-                                                 actions,
-                                                 "action not supported");
-               }
-               if (ret < 0)
-                       return ret;
-       }
+       ret = flow_drv_query(dev, flow, actions, data, error);
+       if (ret < 0)
+               return ret;
        return 0;
 }
 
index ee75a80..af0a125 100644 (file)
@@ -268,6 +268,11 @@ typedef void (*mlx5_flow_remove_t)(struct rte_eth_dev *dev,
                                   struct rte_flow *flow);
 typedef void (*mlx5_flow_destroy_t)(struct rte_eth_dev *dev,
                                    struct rte_flow *flow);
+typedef int (*mlx5_flow_query_t)(struct rte_eth_dev *dev,
+                                struct rte_flow *flow,
+                                const struct rte_flow_action *actions,
+                                void *data,
+                                struct rte_flow_error *error);
 struct mlx5_flow_driver_ops {
        mlx5_flow_validate_t validate;
        mlx5_flow_prepare_t prepare;
@@ -275,6 +280,7 @@ struct mlx5_flow_driver_ops {
        mlx5_flow_apply_t apply;
        mlx5_flow_remove_t remove;
        mlx5_flow_destroy_t destroy;
+       mlx5_flow_query_t query;
 };
 
 /* mlx5_flow.c */
index becbc57..58e3c33 100644 (file)
@@ -1363,6 +1363,24 @@ flow_dv_destroy(struct rte_eth_dev *dev, struct rte_flow *flow)
        }
 }
 
+/**
+ * Query a flow.
+ *
+ * @see rte_flow_query()
+ * @see rte_flow_ops
+ */
+static int
+flow_dv_query(struct rte_eth_dev *dev __rte_unused,
+             struct rte_flow *flow __rte_unused,
+             const struct rte_flow_action *actions __rte_unused,
+             void *data __rte_unused,
+             struct rte_flow_error *error __rte_unused)
+{
+       rte_errno = ENOTSUP;
+       return -rte_errno;
+}
+
+
 const struct mlx5_flow_driver_ops mlx5_flow_dv_drv_ops = {
        .validate = flow_dv_validate,
        .prepare = flow_dv_prepare,
@@ -1370,6 +1388,7 @@ const struct mlx5_flow_driver_ops mlx5_flow_dv_drv_ops = {
        .apply = flow_dv_apply,
        .remove = flow_dv_remove,
        .destroy = flow_dv_destroy,
+       .query = flow_dv_query,
 };
 
 #endif /* HAVE_IBV_FLOW_DV_SUPPORT */
index b890aa2..6b19b2a 100644 (file)
@@ -2238,6 +2238,23 @@ flow_tcf_destroy(struct rte_eth_dev *dev, struct rte_flow *flow)
        rte_free(dev_flow);
 }
 
+/**
+ * Query a flow.
+ *
+ * @see rte_flow_query()
+ * @see rte_flow_ops
+ */
+static int
+flow_tcf_query(struct rte_eth_dev *dev __rte_unused,
+              struct rte_flow *flow __rte_unused,
+              const struct rte_flow_action *actions __rte_unused,
+              void *data __rte_unused,
+              struct rte_flow_error *error __rte_unused)
+{
+       rte_errno = ENOTSUP;
+       return -rte_errno;
+}
+
 const struct mlx5_flow_driver_ops mlx5_flow_tcf_drv_ops = {
        .validate = flow_tcf_validate,
        .prepare = flow_tcf_prepare,
@@ -2245,6 +2262,7 @@ const struct mlx5_flow_driver_ops mlx5_flow_tcf_drv_ops = {
        .apply = flow_tcf_apply,
        .remove = flow_tcf_remove,
        .destroy = flow_tcf_destroy,
+       .query = flow_tcf_query,
 };
 
 /**
index 65c849c..4ae974b 100644 (file)
@@ -1651,6 +1651,92 @@ error:
        return -rte_errno;
 }
 
+/**
+ * Query a flows.
+ *
+ * @see rte_flow_query()
+ * @see rte_flow_ops
+ */
+static int
+flow_verbs_query_count(struct rte_eth_dev *dev __rte_unused,
+                      struct rte_flow *flow __rte_unused,
+                      void *data __rte_unused,
+                      struct rte_flow_error *error)
+{
+#ifdef HAVE_IBV_DEVICE_COUNTERS_SET_SUPPORT
+       if (flow->actions & MLX5_FLOW_ACTION_COUNT) {
+               struct rte_flow_query_count *qc = data;
+               uint64_t counters[2] = {0, 0};
+               struct ibv_query_counter_set_attr query_cs_attr = {
+                       .cs = flow->counter->cs,
+                       .query_flags = IBV_COUNTER_SET_FORCE_UPDATE,
+               };
+               struct ibv_counter_set_data query_out = {
+                       .out = counters,
+                       .outlen = 2 * sizeof(uint64_t),
+               };
+               int err = mlx5_glue->query_counter_set(&query_cs_attr,
+                                                      &query_out);
+
+               if (err)
+                       return rte_flow_error_set
+                               (error, err,
+                                RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                                NULL,
+                                "cannot read counter");
+               qc->hits_set = 1;
+               qc->bytes_set = 1;
+               qc->hits = counters[0] - flow->counter->hits;
+               qc->bytes = counters[1] - flow->counter->bytes;
+               if (qc->reset) {
+                       flow->counter->hits = counters[0];
+                       flow->counter->bytes = counters[1];
+               }
+               return 0;
+       }
+       return rte_flow_error_set(error, EINVAL,
+                                 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                                 NULL,
+                                 "flow does not have counter");
+#endif
+       return rte_flow_error_set(error, ENOTSUP,
+                                 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                                 NULL,
+                                 "counters are not available");
+}
+
+/**
+ * Query a flow.
+ *
+ * @see rte_flow_query()
+ * @see rte_flow_ops
+ */
+static int
+flow_verbs_query(struct rte_eth_dev *dev,
+                struct rte_flow *flow,
+                const struct rte_flow_action *actions,
+                void *data,
+                struct rte_flow_error *error)
+{
+       int ret = -EINVAL;
+
+       for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
+               switch (actions->type) {
+               case RTE_FLOW_ACTION_TYPE_VOID:
+                       break;
+               case RTE_FLOW_ACTION_TYPE_COUNT:
+                       ret = flow_verbs_query_count(dev, flow, data, error);
+                       break;
+               default:
+                       return rte_flow_error_set(error, ENOTSUP,
+                                                 RTE_FLOW_ERROR_TYPE_ACTION,
+                                                 actions,
+                                                 "action not supported");
+               }
+       }
+       return ret;
+}
+
 const struct mlx5_flow_driver_ops mlx5_flow_verbs_drv_ops = {
        .validate = flow_verbs_validate,
        .prepare = flow_verbs_prepare,
@@ -1658,4 +1744,5 @@ const struct mlx5_flow_driver_ops mlx5_flow_verbs_drv_ops = {
        .apply = flow_verbs_apply,
        .remove = flow_verbs_remove,
        .destroy = flow_verbs_destroy,
+       .query = flow_verbs_query,
 };