Commit 140ce421 authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller
Browse files

mlxsw: core: Convert fwd_entry_ref list to be generic per-block resource list



Since the resource list needs to be used also for other entries different
to fwd_entry_ref, make the list generic. For that purpose, introduce a
resource structure with couple of helpers that the code which need to
store a per-block resource should use.

Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Reviewed-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4c6b7f63
Loading
Loading
Loading
Loading
+49 −26
Original line number Diff line number Diff line
@@ -310,9 +310,33 @@ struct mlxsw_afa_block {
	struct mlxsw_afa_set *first_set;
	struct mlxsw_afa_set *cur_set;
	unsigned int cur_act_index; /* In current set. */
	struct list_head fwd_entry_ref_list;
	struct list_head resource_list; /* List of resources held by actions
					 * in this block.
					 */
};

struct mlxsw_afa_resource {
	struct list_head list;
	void (*destructor)(struct mlxsw_afa_block *block,
			   struct mlxsw_afa_resource *resource);
};

static void mlxsw_afa_resource_add(struct mlxsw_afa_block *block,
				   struct mlxsw_afa_resource *resource)
{
	list_add(&resource->list, &block->resource_list);
}

static void mlxsw_afa_resources_destroy(struct mlxsw_afa_block *block)
{
	struct mlxsw_afa_resource *resource, *tmp;

	list_for_each_entry_safe(resource, tmp, &block->resource_list, list) {
		list_del(&resource->list);
		resource->destructor(block, resource);
	}
}

struct mlxsw_afa_block *mlxsw_afa_block_create(struct mlxsw_afa *mlxsw_afa)
{
	struct mlxsw_afa_block *block;
@@ -320,7 +344,7 @@ struct mlxsw_afa_block *mlxsw_afa_block_create(struct mlxsw_afa *mlxsw_afa)
	block = kzalloc(sizeof(*block), GFP_KERNEL);
	if (!block)
		return NULL;
	INIT_LIST_HEAD(&block->fwd_entry_ref_list);
	INIT_LIST_HEAD(&block->resource_list);
	block->afa = mlxsw_afa;

	/* At least one action set is always present, so just create it here */
@@ -336,8 +360,6 @@ err_first_set_create:
}
EXPORT_SYMBOL(mlxsw_afa_block_create);

static void mlxsw_afa_fwd_entry_refs_destroy(struct mlxsw_afa_block *block);

void mlxsw_afa_block_destroy(struct mlxsw_afa_block *block)
{
	struct mlxsw_afa_set *set = block->first_set;
@@ -348,7 +370,7 @@ void mlxsw_afa_block_destroy(struct mlxsw_afa_block *block)
		mlxsw_afa_set_put(block->afa, set);
		set = next_set;
	} while (set);
	mlxsw_afa_fwd_entry_refs_destroy(block);
	mlxsw_afa_resources_destroy(block);
	kfree(block);
}
EXPORT_SYMBOL(mlxsw_afa_block_destroy);
@@ -489,10 +511,29 @@ static void mlxsw_afa_fwd_entry_put(struct mlxsw_afa *mlxsw_afa,
}

struct mlxsw_afa_fwd_entry_ref {
	struct list_head list;
	struct mlxsw_afa_resource resource;
	struct mlxsw_afa_fwd_entry *fwd_entry;
};

static void
mlxsw_afa_fwd_entry_ref_destroy(struct mlxsw_afa_block *block,
				struct mlxsw_afa_fwd_entry_ref *fwd_entry_ref)
{
	mlxsw_afa_fwd_entry_put(block->afa, fwd_entry_ref->fwd_entry);
	kfree(fwd_entry_ref);
}

static void
mlxsw_afa_fwd_entry_ref_destructor(struct mlxsw_afa_block *block,
				   struct mlxsw_afa_resource *resource)
{
	struct mlxsw_afa_fwd_entry_ref *fwd_entry_ref;

	fwd_entry_ref = container_of(resource, struct mlxsw_afa_fwd_entry_ref,
				     resource);
	mlxsw_afa_fwd_entry_ref_destroy(block, fwd_entry_ref);
}

static struct mlxsw_afa_fwd_entry_ref *
mlxsw_afa_fwd_entry_ref_create(struct mlxsw_afa_block *block, u8 local_port)
{
@@ -509,7 +550,8 @@ mlxsw_afa_fwd_entry_ref_create(struct mlxsw_afa_block *block, u8 local_port)
		goto err_fwd_entry_get;
	}
	fwd_entry_ref->fwd_entry = fwd_entry;
	list_add(&fwd_entry_ref->list, &block->fwd_entry_ref_list);
	fwd_entry_ref->resource.destructor = mlxsw_afa_fwd_entry_ref_destructor;
	mlxsw_afa_resource_add(block, &fwd_entry_ref->resource);
	return fwd_entry_ref;

err_fwd_entry_get:
@@ -517,25 +559,6 @@ err_fwd_entry_get:
	return ERR_PTR(err);
}

static void
mlxsw_afa_fwd_entry_ref_destroy(struct mlxsw_afa_block *block,
				struct mlxsw_afa_fwd_entry_ref *fwd_entry_ref)
{
	list_del(&fwd_entry_ref->list);
	mlxsw_afa_fwd_entry_put(block->afa, fwd_entry_ref->fwd_entry);
	kfree(fwd_entry_ref);
}

static void mlxsw_afa_fwd_entry_refs_destroy(struct mlxsw_afa_block *block)
{
	struct mlxsw_afa_fwd_entry_ref *fwd_entry_ref;
	struct mlxsw_afa_fwd_entry_ref *tmp;

	list_for_each_entry_safe(fwd_entry_ref, tmp,
				 &block->fwd_entry_ref_list, list)
		mlxsw_afa_fwd_entry_ref_destroy(block, fwd_entry_ref);
}

#define MLXSW_AFA_ONE_ACTION_LEN 32
#define MLXSW_AFA_PAYLOAD_OFFSET 4