RDMA/mlx5: Add NIC TX namespace when getting a flow table
authorMark Bloch <markb@mellanox.com>
Thu, 6 Sep 2018 14:27:07 +0000 (17:27 +0300)
committerJason Gunthorpe <jgg@mellanox.com>
Tue, 11 Sep 2018 15:28:07 +0000 (09:28 -0600)
Add the ability to get a NIC TX flow table when using _get_flow_table().
This will allow to create a matcher and a flow rule on the NIC TX path.

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/flow.c
drivers/infiniband/hw/mlx5/main.c
drivers/infiniband/hw/mlx5/mlx5_ib.h

index ce9276a..16e677c 100644 (file)
@@ -189,6 +189,7 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_MATCHER_CREATE)(
        if (!obj)
                return -ENOMEM;
 
+       obj->ns_type = MLX5_FLOW_NAMESPACE_BYPASS;
        obj->mask_len = uverbs_attr_get_len(
                attrs, MLX5_IB_ATTR_FLOW_MATCHER_MATCH_MASK);
        err = uverbs_copy_from(&obj->matcher_mask,
index b258a6e..e311b6f 100644 (file)
@@ -3719,34 +3719,54 @@ free_ucmd:
        return ERR_PTR(err);
 }
 
-static struct mlx5_ib_flow_prio *_get_flow_table(struct mlx5_ib_dev *dev,
-                                                int priority, bool mcast)
+static struct mlx5_ib_flow_prio *
+_get_flow_table(struct mlx5_ib_dev *dev,
+               struct mlx5_ib_flow_matcher *fs_matcher,
+               bool mcast)
 {
-       int max_table_size;
        struct mlx5_flow_namespace *ns = NULL;
        struct mlx5_ib_flow_prio *prio;
+       int max_table_size;
+       u32 flags = 0;
+       int priority;
+
+       if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_BYPASS) {
+               max_table_size = BIT(MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev,
+                                       log_max_ft_size));
+               if (MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev, decap))
+                       flags |= MLX5_FLOW_TABLE_TUNNEL_EN_DECAP;
+               if (MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev,
+                                             reformat_l3_tunnel_to_l2))
+                       flags |= MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT;
+       } else { /* Can only be MLX5_FLOW_NAMESPACE_EGRESS */
+               max_table_size = BIT(MLX5_CAP_FLOWTABLE_NIC_TX(dev->mdev,
+                                       log_max_ft_size));
+               if (MLX5_CAP_FLOWTABLE_NIC_TX(dev->mdev, reformat))
+                       flags |= MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT;
+       }
 
-       max_table_size = BIT(MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev,
-                            log_max_ft_size));
        if (max_table_size < MLX5_FS_MAX_ENTRIES)
                return ERR_PTR(-ENOMEM);
 
        if (mcast)
                priority = MLX5_IB_FLOW_MCAST_PRIO;
        else
-               priority = ib_prio_to_core_prio(priority, false);
+               priority = ib_prio_to_core_prio(fs_matcher->priority, false);
 
-       ns = mlx5_get_flow_namespace(dev->mdev, MLX5_FLOW_NAMESPACE_BYPASS);
+       ns = mlx5_get_flow_namespace(dev->mdev, fs_matcher->ns_type);
        if (!ns)
                return ERR_PTR(-ENOTSUPP);
 
-       prio = &dev->flow_db->prios[priority];
+       if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_BYPASS)
+               prio = &dev->flow_db->prios[priority];
+       else
+               prio = &dev->flow_db->egress_prios[priority];
 
        if (prio->flow_table)
                return prio;
 
        return _get_prio(ns, prio, priority, MLX5_FS_MAX_ENTRIES,
-                        MLX5_FS_MAX_TYPES, 0);
+                        MLX5_FS_MAX_TYPES, flags);
 }
 
 static struct mlx5_ib_flow_handler *
@@ -3845,7 +3865,6 @@ mlx5_ib_raw_fs_rule_add(struct mlx5_ib_dev *dev,
 {
        struct mlx5_flow_destination *dst;
        struct mlx5_ib_flow_prio *ft_prio;
-       int priority = fs_matcher->priority;
        struct mlx5_ib_flow_handler *handler;
        bool mcast;
        int err;
@@ -3863,7 +3882,7 @@ mlx5_ib_raw_fs_rule_add(struct mlx5_ib_dev *dev,
        mcast = raw_fs_is_multicast(fs_matcher, cmd_in);
        mutex_lock(&dev->flow_db->lock);
 
-       ft_prio = _get_flow_table(dev, priority, mcast);
+       ft_prio = _get_flow_table(dev, fs_matcher, mcast);
        if (IS_ERR(ft_prio)) {
                err = PTR_ERR(ft_prio);
                goto unlock;
index c667a6c..6c57872 100644 (file)
@@ -190,6 +190,7 @@ struct mlx5_ib_flow_matcher {
        struct mlx5_ib_match_params matcher_mask;
        int                     mask_len;
        enum mlx5_ib_flow_type  flow_type;
+       enum mlx5_flow_namespace_type ns_type;
        u16                     priority;
        struct mlx5_core_dev    *mdev;
        atomic_t                usecnt;