|
@@ -443,6 +443,73 @@ static struct mlx5_flow_table *alloc_flow_table(int level, int max_fte,
|
|
return ft;
|
|
return ft;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/* If reverse is false, then we search for the first flow table in the
|
|
|
|
+ * root sub-tree from start(closest from right), else we search for the
|
|
|
|
+ * last flow table in the root sub-tree till start(closest from left).
|
|
|
|
+ */
|
|
|
|
+static struct mlx5_flow_table *find_closest_ft_recursive(struct fs_node *root,
|
|
|
|
+ struct list_head *start,
|
|
|
|
+ bool reverse)
|
|
|
|
+{
|
|
|
|
+#define list_advance_entry(pos, reverse) \
|
|
|
|
+ ((reverse) ? list_prev_entry(pos, list) : list_next_entry(pos, list))
|
|
|
|
+
|
|
|
|
+#define list_for_each_advance_continue(pos, head, reverse) \
|
|
|
|
+ for (pos = list_advance_entry(pos, reverse); \
|
|
|
|
+ &pos->list != (head); \
|
|
|
|
+ pos = list_advance_entry(pos, reverse))
|
|
|
|
+
|
|
|
|
+ struct fs_node *iter = list_entry(start, struct fs_node, list);
|
|
|
|
+ struct mlx5_flow_table *ft = NULL;
|
|
|
|
+
|
|
|
|
+ if (!root)
|
|
|
|
+ return NULL;
|
|
|
|
+
|
|
|
|
+ list_for_each_advance_continue(iter, &root->children, reverse) {
|
|
|
|
+ if (iter->type == FS_TYPE_FLOW_TABLE) {
|
|
|
|
+ fs_get_obj(ft, iter);
|
|
|
|
+ return ft;
|
|
|
|
+ }
|
|
|
|
+ ft = find_closest_ft_recursive(iter, &iter->children, reverse);
|
|
|
|
+ if (ft)
|
|
|
|
+ return ft;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return ft;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* If reverse if false then return the first flow table in next priority of
|
|
|
|
+ * prio in the tree, else return the last flow table in the previous priority
|
|
|
|
+ * of prio in the tree.
|
|
|
|
+ */
|
|
|
|
+static struct mlx5_flow_table *find_closest_ft(struct fs_prio *prio, bool reverse)
|
|
|
|
+{
|
|
|
|
+ struct mlx5_flow_table *ft = NULL;
|
|
|
|
+ struct fs_node *curr_node;
|
|
|
|
+ struct fs_node *parent;
|
|
|
|
+
|
|
|
|
+ parent = prio->node.parent;
|
|
|
|
+ curr_node = &prio->node;
|
|
|
|
+ while (!ft && parent) {
|
|
|
|
+ ft = find_closest_ft_recursive(parent, &curr_node->list, reverse);
|
|
|
|
+ curr_node = parent;
|
|
|
|
+ parent = curr_node->parent;
|
|
|
|
+ }
|
|
|
|
+ return ft;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* Assuming all the tree is locked by mutex chain lock */
|
|
|
|
+static struct mlx5_flow_table *find_next_chained_ft(struct fs_prio *prio)
|
|
|
|
+{
|
|
|
|
+ return find_closest_ft(prio, false);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* Assuming all the tree is locked by mutex chain lock */
|
|
|
|
+static struct mlx5_flow_table *find_prev_chained_ft(struct fs_prio *prio)
|
|
|
|
+{
|
|
|
|
+ return find_closest_ft(prio, true);
|
|
|
|
+}
|
|
|
|
+
|
|
struct mlx5_flow_table *mlx5_create_flow_table(struct mlx5_flow_namespace *ns,
|
|
struct mlx5_flow_table *mlx5_create_flow_table(struct mlx5_flow_namespace *ns,
|
|
int prio,
|
|
int prio,
|
|
int max_fte)
|
|
int max_fte)
|