err = mlx5_cmd_destroy_flow_table(dev, ft);
if (err)
mlx5_core_warn(dev, "flow steering can't destroy ft\n");
+ ida_destroy(&ft->fte_allocator);
fs_get_obj(prio, ft->node.parent);
prio->num_ft--;
}
"flow steering can't delete fte in index %d of flow group id %d\n",
fte->index, fg->id);
+ ida_simple_remove(&ft->fte_allocator, fte->index);
fte->status = 0;
- fg->num_ftes--;
}
static void del_flow_group(struct fs_node *node)
ft->flags = flags;
INIT_LIST_HEAD(&ft->fwd_rules);
mutex_init(&ft->lock);
+ ida_init(&ft->fte_allocator);
return ft;
}
destroy_ft:
mlx5_cmd_destroy_flow_table(root->dev, ft);
free_ft:
+ ida_destroy(&ft->fte_allocator);
kfree(ft);
unlock_root:
mutex_unlock(&root->chain_lock);
return ERR_PTR(err);
}
-/* Assumed fg is locked */
-static unsigned int get_free_fte_index(struct mlx5_flow_group *fg,
- struct list_head **prev)
-{
- struct fs_fte *fte;
- unsigned int start = fg->start_index;
-
- if (prev)
- *prev = &fg->node.children;
-
- /* assumed list is sorted by index */
- fs_for_each_fte(fte, fg) {
- if (fte->index != start)
- return start;
- start++;
- if (prev)
- *prev = &fte->node.list;
- }
-
- return start;
-}
-
-/* prev is output, prev->next = new_fte */
static struct fs_fte *create_fte(struct mlx5_flow_group *fg,
u32 *match_value,
- struct mlx5_flow_act *flow_act,
- struct list_head **prev)
+ struct mlx5_flow_act *flow_act)
{
+ struct mlx5_flow_table *ft;
struct fs_fte *fte;
int index;
- index = get_free_fte_index(fg, prev);
+ fs_get_obj(ft, fg->node.parent);
+ index = ida_simple_get(&ft->fte_allocator, fg->start_index,
+ fg->start_index + fg->max_ftes,
+ GFP_KERNEL);
+ if (index < 0)
+ return ERR_PTR(index);
+
fte = alloc_fte(flow_act, match_value, index);
- if (IS_ERR(fte))
+ if (IS_ERR(fte)) {
+ ida_simple_remove(&ft->fte_allocator, index);
return fte;
+ }
return fte;
}
{
struct mlx5_flow_handle *handle;
struct mlx5_flow_table *ft;
- struct list_head *prev;
struct fs_fte *fte;
int i;
unlock_ref_node(&fte->node);
}
fs_get_obj(ft, fg->node.parent);
- if (fg->num_ftes >= fg->max_ftes) {
- handle = ERR_PTR(-ENOSPC);
- goto unlock_fg;
- }
- fte = create_fte(fg, match_value, flow_act, &prev);
+ fte = create_fte(fg, match_value, flow_act);
if (IS_ERR(fte)) {
handle = (void *)fte;
goto unlock_fg;
goto unlock_fg;
}
- fg->num_ftes++;
-
tree_add_node(&fte->node, &fg->node);
- list_add(&fte->node.list, prev);
+ /* fte list isn't sorted */
+ list_add_tail(&fte->node.list, &fg->node.children);
add_rules:
for (i = 0; i < handle->num_rules; i++) {
if (atomic_read(&handle->rule[i]->node.refcount) == 1)