IB/mlx5: Introduce flow steering matcher uapi object
authorYishai Hadas <yishaih@mellanox.com>
Mon, 23 Jul 2018 12:25:07 +0000 (15:25 +0300)
committerJason Gunthorpe <jgg@mellanox.com>
Tue, 24 Jul 2018 19:34:37 +0000 (13:34 -0600)
Introduce flow steering matcher object and its create and destroy methods.

This matcher object holds some mlx5 specific driver properties that
matches the underlay device specification when an mlx5 flow steering group
is created.

It will be used in downstream patches to be part of mlx5 specific create
flow method.

Signed-off-by: Yishai Hadas <yishaih@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/core/uverbs_std_types_flow_action.c
drivers/infiniband/hw/mlx5/Makefile
drivers/infiniband/hw/mlx5/flow.c [new file with mode: 0644]
drivers/infiniband/hw/mlx5/mlx5_ib.h
include/rdma/uverbs_ioctl.h
include/uapi/rdma/mlx5_user_ioctl_cmds.h

index c753a34cd984d4952981f85b12acbdd744925dff..adb9209c47105e0e51d86744e166ab92014e0a38 100644 (file)
@@ -376,8 +376,7 @@ static const struct uverbs_attr_spec uverbs_flow_action_esp_keymat[] = {
 static const struct uverbs_attr_spec uverbs_flow_action_esp_replay[] = {
        [IB_UVERBS_FLOW_ACTION_ESP_REPLAY_NONE] = {
                .type = UVERBS_ATTR_TYPE_PTR_IN,
-               /* No need to specify any data */
-               UVERBS_ATTR_SIZE(0, 0),
+               UVERBS_ATTR_NO_DATA(),
        },
        [IB_UVERBS_FLOW_ACTION_ESP_REPLAY_BMP] = {
                .type = UVERBS_ATTR_TYPE_PTR_IN,
index 577e4c418baeead749632abf88f6ca86d92778ab..b8e4b15e2674b963428d137b00978b732179dffe 100644 (file)
@@ -4,3 +4,4 @@ mlx5_ib-y :=    main.o cq.o doorbell.o qp.o mem.o srq.o mr.o ah.o mad.o gsi.o ib_vi
 mlx5_ib-$(CONFIG_INFINIBAND_ON_DEMAND_PAGING) += odp.o
 mlx5_ib-$(CONFIG_MLX5_ESWITCH) += ib_rep.o
 mlx5_ib-$(CONFIG_INFINIBAND_USER_ACCESS) += devx.o
+mlx5_ib-$(CONFIG_INFINIBAND_USER_ACCESS) += flow.o
diff --git a/drivers/infiniband/hw/mlx5/flow.c b/drivers/infiniband/hw/mlx5/flow.c
new file mode 100644 (file)
index 0000000..ab4bc37
--- /dev/null
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
+/*
+ * Copyright (c) 2018, Mellanox Technologies inc.  All rights reserved.
+ */
+
+#include <rdma/ib_user_verbs.h>
+#include <rdma/ib_verbs.h>
+#include <rdma/uverbs_types.h>
+#include <rdma/uverbs_ioctl.h>
+#include <rdma/mlx5_user_ioctl_cmds.h>
+#include <rdma/ib_umem.h>
+#include <linux/mlx5/driver.h>
+#include <linux/mlx5/fs.h>
+#include "mlx5_ib.h"
+
+#define UVERBS_MODULE_NAME mlx5_ib
+#include <rdma/uverbs_named_ioctl.h>
+
+static const struct uverbs_attr_spec mlx5_ib_flow_type[] = {
+       [MLX5_IB_FLOW_TYPE_NORMAL] = {
+               .type = UVERBS_ATTR_TYPE_PTR_IN,
+               .u.ptr = {
+                       .len = sizeof(u16), /* data is priority */
+                       .min_len = sizeof(u16),
+               }
+       },
+       [MLX5_IB_FLOW_TYPE_SNIFFER] = {
+               .type = UVERBS_ATTR_TYPE_PTR_IN,
+               UVERBS_ATTR_NO_DATA(),
+       },
+       [MLX5_IB_FLOW_TYPE_ALL_DEFAULT] = {
+               .type = UVERBS_ATTR_TYPE_PTR_IN,
+               UVERBS_ATTR_NO_DATA(),
+       },
+       [MLX5_IB_FLOW_TYPE_MC_DEFAULT] = {
+               .type = UVERBS_ATTR_TYPE_PTR_IN,
+               UVERBS_ATTR_NO_DATA(),
+       },
+};
+
+static int flow_matcher_cleanup(struct ib_uobject *uobject,
+                               enum rdma_remove_reason why)
+{
+       struct mlx5_ib_flow_matcher *obj = uobject->object;
+       int ret;
+
+       ret = ib_destroy_usecnt(&obj->usecnt, why, uobject);
+       if (ret)
+               return ret;
+
+       kfree(obj);
+       return 0;
+}
+
+static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_MATCHER_CREATE)(
+       struct ib_device *ib_dev, struct ib_uverbs_file *file,
+       struct uverbs_attr_bundle *attrs)
+{
+       struct ib_uobject *uobj = uverbs_attr_get_uobject(
+               attrs, MLX5_IB_ATTR_FLOW_MATCHER_CREATE_HANDLE);
+       struct mlx5_ib_dev *dev = to_mdev(uobj->context->device);
+       struct mlx5_ib_flow_matcher *obj;
+       int err;
+
+       obj = kzalloc(sizeof(struct mlx5_ib_flow_matcher), GFP_KERNEL);
+       if (!obj)
+               return -ENOMEM;
+
+       obj->mask_len = uverbs_attr_get_len(
+               attrs, MLX5_IB_ATTR_FLOW_MATCHER_MATCH_MASK);
+       err = uverbs_copy_from(&obj->matcher_mask,
+                              attrs,
+                              MLX5_IB_ATTR_FLOW_MATCHER_MATCH_MASK);
+       if (err)
+               goto end;
+
+       obj->flow_type = uverbs_attr_get_enum_id(
+               attrs, MLX5_IB_ATTR_FLOW_MATCHER_FLOW_TYPE);
+
+       if (obj->flow_type == MLX5_IB_FLOW_TYPE_NORMAL) {
+               err = uverbs_copy_from(&obj->priority,
+                                      attrs,
+                                      MLX5_IB_ATTR_FLOW_MATCHER_FLOW_TYPE);
+               if (err)
+                       goto end;
+       }
+
+       err = uverbs_copy_from(&obj->match_criteria_enable,
+                              attrs,
+                              MLX5_IB_ATTR_FLOW_MATCHER_MATCH_CRITERIA);
+       if (err)
+               goto end;
+
+       uobj->object = obj;
+       obj->mdev = dev->mdev;
+       atomic_set(&obj->usecnt, 0);
+       return 0;
+
+end:
+       kfree(obj);
+       return err;
+}
+
+DECLARE_UVERBS_NAMED_METHOD(
+       MLX5_IB_METHOD_FLOW_MATCHER_CREATE,
+       UVERBS_ATTR_IDR(MLX5_IB_ATTR_FLOW_MATCHER_CREATE_HANDLE,
+                       MLX5_IB_OBJECT_FLOW_MATCHER,
+                       UVERBS_ACCESS_NEW,
+                       UA_MANDATORY),
+       UVERBS_ATTR_PTR_IN(
+               MLX5_IB_ATTR_FLOW_MATCHER_MATCH_MASK,
+               UVERBS_ATTR_SIZE(1, sizeof(struct mlx5_ib_match_params)),
+               UA_MANDATORY),
+       UVERBS_ATTR_ENUM_IN(MLX5_IB_ATTR_FLOW_MATCHER_FLOW_TYPE,
+                           mlx5_ib_flow_type,
+                           UA_MANDATORY),
+       UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_FLOW_MATCHER_MATCH_CRITERIA,
+                          UVERBS_ATTR_TYPE(u8),
+                          UA_MANDATORY));
+
+DECLARE_UVERBS_NAMED_METHOD_DESTROY(
+       MLX5_IB_METHOD_FLOW_MATCHER_DESTROY,
+       UVERBS_ATTR_IDR(MLX5_IB_ATTR_FLOW_MATCHER_DESTROY_HANDLE,
+                       MLX5_IB_OBJECT_FLOW_MATCHER,
+                       UVERBS_ACCESS_DESTROY,
+                       UA_MANDATORY));
+
+DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_FLOW_MATCHER,
+                           UVERBS_TYPE_ALLOC_IDR(flow_matcher_cleanup),
+                           &UVERBS_METHOD(MLX5_IB_METHOD_FLOW_MATCHER_CREATE),
+                           &UVERBS_METHOD(MLX5_IB_METHOD_FLOW_MATCHER_DESTROY));
+
+DECLARE_UVERBS_OBJECT_TREE(flow_objects,
+                          &UVERBS_OBJECT(MLX5_IB_OBJECT_FLOW_MATCHER));
index 04a5d82c9cf3593bdae43e2bbc74ea2f089768dc..c556b00bf4f7fdbb64b63a80ad9aa53d4098324b 100644 (file)
@@ -46,6 +46,7 @@
 #include <rdma/ib_user_verbs.h>
 #include <rdma/mlx5-abi.h>
 #include <rdma/uverbs_ioctl.h>
+#include <rdma/mlx5_user_ioctl_cmds.h>
 
 #define mlx5_ib_dbg(dev, format, arg...)                               \
 pr_debug("%s:%s:%d:(pid %d): " format, (dev)->ib_dev.name, __func__,   \
@@ -173,6 +174,16 @@ struct mlx5_ib_flow_handler {
        struct ib_counters              *ibcounters;
 };
 
+struct mlx5_ib_flow_matcher {
+       struct mlx5_ib_match_params matcher_mask;
+       int                     mask_len;
+       enum mlx5_ib_flow_type  flow_type;
+       u16                     priority;
+       struct mlx5_core_dev    *mdev;
+       atomic_t                usecnt;
+       u8                      match_criteria_enable;
+};
+
 struct mlx5_ib_flow_db {
        struct mlx5_ib_flow_prio        prios[MLX5_IB_NUM_FLOW_FT];
        struct mlx5_ib_flow_prio        sniffer[MLX5_IB_NUM_SNIFFER_FTS];
index 017ccf75890ce7e1b866fc1d68585d1c2584c94e..7f230d1ec2b8b2fed2e0958137043d1e22ca4385 100644 (file)
@@ -204,6 +204,8 @@ struct uverbs_object_tree_def {
 #define UVERBS_ATTR_SIZE(_min_len, _len)                       \
        .u.ptr.min_len = _min_len, .u.ptr.len = _len
 
+#define UVERBS_ATTR_NO_DATA() UVERBS_ATTR_SIZE(0, 0)
+
 /*
  * Specifies a uapi structure that cannot be extended. The user must always
  * supply the whole structure and nothing more. The structure must be declared
index 1a05bb4b0b342942ab0d8a7d83e3c9a287b7c8b8..233d5d1401799a1f710b456c36a3f233d2219d8a 100644 (file)
@@ -33,6 +33,7 @@
 #ifndef MLX5_USER_IOCTL_CMDS_H
 #define MLX5_USER_IOCTL_CMDS_H
 
+#include <linux/types.h>
 #include <rdma/ib_user_ioctl_cmds.h>
 
 enum mlx5_ib_create_flow_action_attrs {
@@ -112,10 +113,40 @@ enum mlx5_ib_devx_umem_methods {
        MLX5_IB_METHOD_DEVX_UMEM_DEREG,
 };
 
-enum mlx5_ib_devx_objects {
+enum mlx5_ib_objects {
        MLX5_IB_OBJECT_DEVX = (1U << UVERBS_ID_NS_SHIFT),
        MLX5_IB_OBJECT_DEVX_OBJ,
        MLX5_IB_OBJECT_DEVX_UMEM,
+       MLX5_IB_OBJECT_FLOW_MATCHER,
+};
+
+enum mlx5_ib_flow_matcher_create_attrs {
+       MLX5_IB_ATTR_FLOW_MATCHER_CREATE_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
+       MLX5_IB_ATTR_FLOW_MATCHER_MATCH_MASK,
+       MLX5_IB_ATTR_FLOW_MATCHER_FLOW_TYPE,
+       MLX5_IB_ATTR_FLOW_MATCHER_MATCH_CRITERIA,
+};
+
+enum mlx5_ib_flow_matcher_destroy_attrs {
+       MLX5_IB_ATTR_FLOW_MATCHER_DESTROY_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
+};
+
+enum mlx5_ib_flow_matcher_methods {
+       MLX5_IB_METHOD_FLOW_MATCHER_CREATE = (1U << UVERBS_ID_NS_SHIFT),
+       MLX5_IB_METHOD_FLOW_MATCHER_DESTROY,
+};
+
+#define MLX5_IB_DW_MATCH_PARAM 0x80
+
+struct mlx5_ib_match_params {
+       __u32   match_params[MLX5_IB_DW_MATCH_PARAM];
+};
+
+enum mlx5_ib_flow_type {
+       MLX5_IB_FLOW_TYPE_NORMAL,
+       MLX5_IB_FLOW_TYPE_SNIFFER,
+       MLX5_IB_FLOW_TYPE_ALL_DEFAULT,
+       MLX5_IB_FLOW_TYPE_MC_DEFAULT,
 };
 
 #endif