net/mlx5: Allow creating autogroups with reserved entries
authorPaul Blakey <paulb@mellanox.com>
Thu, 14 Nov 2019 15:02:59 +0000 (17:02 +0200)
committerSaeed Mahameed <saeedm@mellanox.com>
Thu, 16 Jan 2020 23:48:58 +0000 (15:48 -0800)
Exclude the last n entries for an autogrouped flow table.

Reserving entries at the end of the FT will ensure that this FG will be
the last to be evaluated. This will be used in the next patch to create
a miss group enabling custom actions on FT miss.

Signed-off-by: Paul Blakey <paulb@mellanox.com>
Reviewed-by: Roi Dayan <roid@mellanox.com>
Reviewed-by: Oz Shlomo <ozsh@mellanox.com>
Reviewed-by: Mark Bloch <markb@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
drivers/net/ethernet/mellanox/mlx5/core/fs_core.h
include/linux/mlx5/fs.h

index 355a424f45061f415ca4cf68b3c821b086686c3e..c7a16ae05fa83bde2be1ce221910af92f23677ff 100644 (file)
@@ -579,7 +579,9 @@ static void del_sw_flow_group(struct fs_node *node)
 
        rhashtable_destroy(&fg->ftes_hash);
        ida_destroy(&fg->fte_allocator);
-       if (ft->autogroup.active && fg->max_ftes == ft->autogroup.group_size)
+       if (ft->autogroup.active &&
+           fg->max_ftes == ft->autogroup.group_size &&
+           fg->start_index < ft->autogroup.max_fte)
                ft->autogroup.num_groups--;
        err = rhltable_remove(&ft->fgs_hash,
                              &fg->hash,
@@ -1121,9 +1123,14 @@ struct mlx5_flow_table*
 mlx5_create_auto_grouped_flow_table(struct mlx5_flow_namespace *ns,
                                    struct mlx5_flow_table_attr *ft_attr)
 {
+       int num_reserved_entries = ft_attr->autogroup.num_reserved_entries;
+       int autogroups_max_fte = ft_attr->max_fte - num_reserved_entries;
+       int max_num_groups = ft_attr->autogroup.max_num_groups;
        struct mlx5_flow_table *ft;
 
-       if (ft_attr->autogroup.max_num_groups > ft_attr->max_fte)
+       if (max_num_groups > autogroups_max_fte)
+               return ERR_PTR(-EINVAL);
+       if (num_reserved_entries > ft_attr->max_fte)
                return ERR_PTR(-EINVAL);
 
        ft = mlx5_create_flow_table(ns, ft_attr);
@@ -1131,10 +1138,10 @@ mlx5_create_auto_grouped_flow_table(struct mlx5_flow_namespace *ns,
                return ft;
 
        ft->autogroup.active = true;
-       ft->autogroup.required_groups = ft_attr->autogroup.max_num_groups;
+       ft->autogroup.required_groups = max_num_groups;
+       ft->autogroup.max_fte = autogroups_max_fte;
        /* We save place for flow groups in addition to max types */
-       ft->autogroup.group_size = ft->max_fte /
-                                  (ft->autogroup.required_groups + 1);
+       ft->autogroup.group_size = autogroups_max_fte / (max_num_groups + 1);
 
        return ft;
 }
@@ -1156,7 +1163,7 @@ struct mlx5_flow_group *mlx5_create_flow_group(struct mlx5_flow_table *ft,
        struct mlx5_flow_group *fg;
        int err;
 
-       if (ft->autogroup.active)
+       if (ft->autogroup.active && start_index < ft->autogroup.max_fte)
                return ERR_PTR(-EPERM);
 
        down_write_ref_node(&ft->node, false);
@@ -1329,9 +1336,10 @@ static struct mlx5_flow_group *alloc_auto_flow_group(struct mlx5_flow_table  *ft
                                                     const struct mlx5_flow_spec *spec)
 {
        struct list_head *prev = &ft->node.children;
-       struct mlx5_flow_group *fg;
+       u32 max_fte = ft->autogroup.max_fte;
        unsigned int candidate_index = 0;
        unsigned int group_size = 0;
+       struct mlx5_flow_group *fg;
 
        if (!ft->autogroup.active)
                return ERR_PTR(-ENOENT);
@@ -1339,7 +1347,7 @@ static struct mlx5_flow_group *alloc_auto_flow_group(struct mlx5_flow_table  *ft
        if (ft->autogroup.num_groups < ft->autogroup.required_groups)
                group_size = ft->autogroup.group_size;
 
-       /*  ft->max_fte == ft->autogroup.max_types */
+       /*  max_fte == ft->autogroup.max_types */
        if (group_size == 0)
                group_size = 1;
 
@@ -1352,7 +1360,7 @@ static struct mlx5_flow_group *alloc_auto_flow_group(struct mlx5_flow_table  *ft
                prev = &fg->node.list;
        }
 
-       if (candidate_index + group_size > ft->max_fte)
+       if (candidate_index + group_size > max_fte)
                return ERR_PTR(-ENOSPC);
 
        fg = alloc_insert_flow_group(ft,
index c2621b9115633b53fe21d738bcd909f53d1bf108..be5f5e32c1e8a835d8f1404512eb3e18eedc02cc 100644 (file)
@@ -164,6 +164,7 @@ struct mlx5_flow_table {
                unsigned int            required_groups;
                unsigned int            group_size;
                unsigned int            num_groups;
+               unsigned int            max_fte;
        } autogroup;
        /* Protect fwd_rules */
        struct mutex                    lock;
index 81f393fb7d9635a3e6b7fb3c7cea9a93d41ec80e..4cae16016b2bdd9c05d72577207b16fdbde887f1 100644 (file)
@@ -155,6 +155,7 @@ struct mlx5_flow_table_attr {
 
        struct {
                int max_num_groups;
+               int num_reserved_entries;
        } autogroup;
 };