OSDN Git Service

RDMA/mlx5: Attach a DEVX counter via raw flow creation
authorMark Bloch <markb@mellanox.com>
Tue, 20 Nov 2018 18:31:08 +0000 (20:31 +0200)
committerJason Gunthorpe <jgg@mellanox.com>
Thu, 29 Nov 2018 23:51:33 +0000 (16:51 -0700)
Allow a user to attach a DEVX counter via mlx5 raw flow creation. In order
to attach a counter we introduce a new attribute:

MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX

A counter can be attached to multiple flow steering rules.

Signed-off-by: Mark Bloch <markb@mellanox.com>
Reviewed-by: Yishai Hadas <yishaih@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/hw/mlx5/devx.c
drivers/infiniband/hw/mlx5/flow.c
drivers/infiniband/hw/mlx5/main.c
drivers/infiniband/hw/mlx5/mlx5_ib.h
include/uapi/rdma/mlx5_user_ioctl_cmds.h

index 9dfc859..0aa2ee7 100644 (file)
@@ -107,6 +107,21 @@ bool mlx5_ib_devx_is_flow_dest(void *obj, int *dest_id, int *dest_type)
        }
 }
 
+bool mlx5_ib_devx_is_flow_counter(void *obj, u32 *counter_id)
+{
+       struct devx_obj *devx_obj = obj;
+       u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, devx_obj->dinbox, opcode);
+
+       if (opcode == MLX5_CMD_OP_DEALLOC_FLOW_COUNTER) {
+               *counter_id = MLX5_GET(dealloc_flow_counter_in,
+                                      devx_obj->dinbox,
+                                      flow_counter_id);
+               return true;
+       }
+
+       return false;
+}
+
 /*
  * As the obj_id in the firmware is not globally unique the object type
  * must be considered upon checking for a valid object id.
index 0144ac5..793afa4 100644 (file)
@@ -77,6 +77,7 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
                uverbs_attr_get_uobject(attrs, MLX5_IB_ATTR_CREATE_FLOW_HANDLE);
        struct mlx5_ib_dev *dev = to_mdev(uobj->context->device);
        int len, ret, i;
+       u32 counter_id = 0;
 
        if (!capable(CAP_NET_RAW))
                return -EPERM;
@@ -128,6 +129,15 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
                dest_type = MLX5_FLOW_DESTINATION_TYPE_PORT;
        }
 
+       len = uverbs_attr_get_uobjs_arr(attrs,
+               MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX, &arr_flow_actions);
+       if (len) {
+               devx_obj = arr_flow_actions[0]->object;
+
+               if (!mlx5_ib_devx_is_flow_counter(devx_obj, &counter_id))
+                       return -EINVAL;
+               flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_COUNT;
+       }
        if (dev->rep)
                return -ENOTSUPP;
 
@@ -164,6 +174,7 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
        }
 
        flow_handler = mlx5_ib_raw_fs_rule_add(dev, fs_matcher, &flow_act,
+                                              counter_id,
                                               cmd_in, inlen,
                                               dest_id, dest_type);
        if (IS_ERR(flow_handler)) {
@@ -524,7 +535,11 @@ DECLARE_UVERBS_NAMED_METHOD(
                             UA_OPTIONAL),
        UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_CREATE_FLOW_TAG,
                           UVERBS_ATTR_TYPE(u32),
-                          UA_OPTIONAL));
+                          UA_OPTIONAL),
+       UVERBS_ATTR_IDRS_ARR(MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX,
+                            MLX5_IB_OBJECT_DEVX_OBJ,
+                            UVERBS_ACCESS_READ, 1, 1,
+                            UA_OPTIONAL));
 
 DECLARE_UVERBS_NAMED_METHOD_DESTROY(
        MLX5_IB_METHOD_DESTROY_FLOW,
index 0707ede..5236169 100644 (file)
@@ -3713,7 +3713,8 @@ _create_raw_flow_rule(struct mlx5_ib_dev *dev,
                      struct mlx5_flow_destination *dst,
                      struct mlx5_ib_flow_matcher  *fs_matcher,
                      struct mlx5_flow_act *flow_act,
-                     void *cmd_in, int inlen)
+                     void *cmd_in, int inlen,
+                     int dst_num)
 {
        struct mlx5_ib_flow_handler *handler;
        struct mlx5_flow_spec *spec;
@@ -3735,7 +3736,7 @@ _create_raw_flow_rule(struct mlx5_ib_dev *dev,
        spec->match_criteria_enable = fs_matcher->match_criteria_enable;
 
        handler->rule = mlx5_add_flow_rules(ft, spec,
-                                           flow_act, dst, 1);
+                                           flow_act, dst, dst_num);
 
        if (IS_ERR(handler->rule)) {
                err = PTR_ERR(handler->rule);
@@ -3798,12 +3799,14 @@ struct mlx5_ib_flow_handler *
 mlx5_ib_raw_fs_rule_add(struct mlx5_ib_dev *dev,
                        struct mlx5_ib_flow_matcher *fs_matcher,
                        struct mlx5_flow_act *flow_act,
+                       u32 counter_id,
                        void *cmd_in, int inlen, int dest_id,
                        int dest_type)
 {
        struct mlx5_flow_destination *dst;
        struct mlx5_ib_flow_prio *ft_prio;
        struct mlx5_ib_flow_handler *handler;
+       int dst_num = 0;
        bool mcast;
        int err;
 
@@ -3813,7 +3816,7 @@ mlx5_ib_raw_fs_rule_add(struct mlx5_ib_dev *dev,
        if (fs_matcher->priority > MLX5_IB_FLOW_LAST_PRIO)
                return ERR_PTR(-ENOMEM);
 
-       dst = kzalloc(sizeof(*dst), GFP_KERNEL);
+       dst = kzalloc(sizeof(*dst) * 2, GFP_KERNEL);
        if (!dst)
                return ERR_PTR(-ENOMEM);
 
@@ -3827,20 +3830,28 @@ mlx5_ib_raw_fs_rule_add(struct mlx5_ib_dev *dev,
        }
 
        if (dest_type == MLX5_FLOW_DESTINATION_TYPE_TIR) {
-               dst->type = dest_type;
-               dst->tir_num = dest_id;
+               dst[dst_num].type = dest_type;
+               dst[dst_num].tir_num = dest_id;
                flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
        } else if (dest_type == MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE) {
-               dst->type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE_NUM;
-               dst->ft_num = dest_id;
+               dst[dst_num].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE_NUM;
+               dst[dst_num].ft_num = dest_id;
                flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
        } else {
-               dst->type = MLX5_FLOW_DESTINATION_TYPE_PORT;
+               dst[dst_num].type = MLX5_FLOW_DESTINATION_TYPE_PORT;
                flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_ALLOW;
        }
 
+       dst_num++;
+
+       if (flow_act->action & MLX5_FLOW_CONTEXT_ACTION_COUNT) {
+               dst[dst_num].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
+               dst[dst_num].counter_id = counter_id;
+               dst_num++;
+       }
+
        handler = _create_raw_flow_rule(dev, ft_prio, dst, fs_matcher, flow_act,
-                                       cmd_in, inlen);
+                                       cmd_in, inlen, dst_num);
 
        if (IS_ERR(handler)) {
                err = PTR_ERR(handler);
index 9b43424..a2b35a1 100644 (file)
@@ -1266,9 +1266,11 @@ extern const struct uapi_definition mlx5_ib_devx_defs[];
 extern const struct uapi_definition mlx5_ib_flow_defs[];
 struct mlx5_ib_flow_handler *mlx5_ib_raw_fs_rule_add(
        struct mlx5_ib_dev *dev, struct mlx5_ib_flow_matcher *fs_matcher,
-       struct mlx5_flow_act *flow_act, void *cmd_in, int inlen,
-       int dest_id, int dest_type);
+       struct mlx5_flow_act *flow_act, u32 counter_id,
+       void *cmd_in, int inlen, int dest_id, int dest_type);
 bool mlx5_ib_devx_is_flow_dest(void *obj, int *dest_id, int *dest_type);
+bool mlx5_ib_devx_is_flow_counter(void *obj, u32 *counter_id);
+int mlx5_ib_get_flow_trees(const struct uverbs_object_tree_def **root);
 void mlx5_ib_destroy_flow_action_raw(struct mlx5_ib_flow_action *maction);
 #else
 static inline int
index 408e220..b8d121d 100644 (file)
@@ -158,6 +158,7 @@ enum mlx5_ib_create_flow_attrs {
        MLX5_IB_ATTR_CREATE_FLOW_MATCHER,
        MLX5_IB_ATTR_CREATE_FLOW_ARR_FLOW_ACTIONS,
        MLX5_IB_ATTR_CREATE_FLOW_TAG,
+       MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX,
 };
 
 enum mlx5_ib_destoy_flow_attrs {