1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
/* Copyright (c) 2024 NVIDIA Corporation & Affiliates */

#ifndef MLX5HWS_POOL_H_
#define MLX5HWS_POOL_H_

#define MLX5HWS_POOL_STC_LOG_SZ 15

#define MLX5HWS_POOL_RESOURCE_ARR_SZ 100

enum mlx5hws_pool_type {
	MLX5HWS_POOL_TYPE_STE,
	MLX5HWS_POOL_TYPE_STC,
};

struct mlx5hws_pool_chunk {
	u32 resource_idx;
	/* Internal offset, relative to base index */
	int offset;
	int order;
};

struct mlx5hws_pool_resource {
	struct mlx5hws_pool *pool;
	u32 base_id;
	u32 range;
};

enum mlx5hws_pool_flags {
	/* Only a one resource in that pool */
	MLX5HWS_POOL_FLAGS_ONE_RESOURCE = 1 << 0,
	MLX5HWS_POOL_FLAGS_RELEASE_FREE_RESOURCE = 1 << 1,
	/* No sharing resources between chunks */
	MLX5HWS_POOL_FLAGS_RESOURCE_PER_CHUNK = 1 << 2,
	/* All objects are in the same size */
	MLX5HWS_POOL_FLAGS_FIXED_SIZE_OBJECTS = 1 << 3,
	/* Managed by buddy allocator */
	MLX5HWS_POOL_FLAGS_BUDDY_MANAGED = 1 << 4,
	/* Allocate pool_type memory on pool creation */
	MLX5HWS_POOL_FLAGS_ALLOC_MEM_ON_CREATE = 1 << 5,

	/* These values should be used by the caller */
	MLX5HWS_POOL_FLAGS_FOR_STC_POOL =
		MLX5HWS_POOL_FLAGS_ONE_RESOURCE |
		MLX5HWS_POOL_FLAGS_FIXED_SIZE_OBJECTS,
	MLX5HWS_POOL_FLAGS_FOR_MATCHER_STE_POOL =
		MLX5HWS_POOL_FLAGS_RELEASE_FREE_RESOURCE |
		MLX5HWS_POOL_FLAGS_RESOURCE_PER_CHUNK,
	MLX5HWS_POOL_FLAGS_FOR_STE_ACTION_POOL =
		MLX5HWS_POOL_FLAGS_ONE_RESOURCE |
		MLX5HWS_POOL_FLAGS_BUDDY_MANAGED |
		MLX5HWS_POOL_FLAGS_ALLOC_MEM_ON_CREATE,
};

enum mlx5hws_pool_optimize {
	MLX5HWS_POOL_OPTIMIZE_NONE = 0x0,
	MLX5HWS_POOL_OPTIMIZE_ORIG = 0x1,
	MLX5HWS_POOL_OPTIMIZE_MIRROR = 0x2,
};

struct mlx5hws_pool_attr {
	enum mlx5hws_pool_type pool_type;
	enum mlx5hws_table_type table_type;
	enum mlx5hws_pool_flags flags;
	enum mlx5hws_pool_optimize opt_type;
	/* Allocation size once memory is depleted */
	size_t alloc_log_sz;
};

enum mlx5hws_db_type {
	/* Uses for allocating chunk of big memory, each element has its own resource in the FW*/
	MLX5HWS_POOL_DB_TYPE_GENERAL_SIZE,
	/* One resource only, all the elements are with same one size */
	MLX5HWS_POOL_DB_TYPE_ONE_SIZE_RESOURCE,
	/* Many resources, the memory allocated with buddy mechanism */
	MLX5HWS_POOL_DB_TYPE_BUDDY,
};

struct mlx5hws_buddy_manager {
	struct mlx5hws_buddy_mem *buddies[MLX5HWS_POOL_RESOURCE_ARR_SZ];
};

struct mlx5hws_pool_elements {
	u32 num_of_elements;
	unsigned long *bitmap;
	u32 log_size;
	bool is_full;
};

struct mlx5hws_element_manager {
	struct mlx5hws_pool_elements *elements[MLX5HWS_POOL_RESOURCE_ARR_SZ];
};

struct mlx5hws_pool_db {
	enum mlx5hws_db_type type;
	union {
		struct mlx5hws_element_manager *element_manager;
		struct mlx5hws_buddy_manager *buddy_manager;
	};
};

typedef int (*mlx5hws_pool_db_get_chunk)(struct mlx5hws_pool *pool,
					struct mlx5hws_pool_chunk *chunk);
typedef void (*mlx5hws_pool_db_put_chunk)(struct mlx5hws_pool *pool,
					 struct mlx5hws_pool_chunk *chunk);
typedef void (*mlx5hws_pool_unint_db)(struct mlx5hws_pool *pool);

struct mlx5hws_pool {
	struct mlx5hws_context *ctx;
	enum mlx5hws_pool_type type;
	enum mlx5hws_pool_flags flags;
	struct mutex lock; /* protect the pool */
	size_t alloc_log_sz;
	enum mlx5hws_table_type tbl_type;
	enum mlx5hws_pool_optimize opt_type;
	struct mlx5hws_pool_resource *resource[MLX5HWS_POOL_RESOURCE_ARR_SZ];
	struct mlx5hws_pool_resource *mirror_resource[MLX5HWS_POOL_RESOURCE_ARR_SZ];
	/* DB */
	struct mlx5hws_pool_db db;
	/* Functions */
	mlx5hws_pool_unint_db p_db_uninit;
	mlx5hws_pool_db_get_chunk p_get_chunk;
	mlx5hws_pool_db_put_chunk p_put_chunk;
};

struct mlx5hws_pool *
mlx5hws_pool_create(struct mlx5hws_context *ctx,
		    struct mlx5hws_pool_attr *pool_attr);

int mlx5hws_pool_destroy(struct mlx5hws_pool *pool);

int mlx5hws_pool_chunk_alloc(struct mlx5hws_pool *pool,
			     struct mlx5hws_pool_chunk *chunk);

void mlx5hws_pool_chunk_free(struct mlx5hws_pool *pool,
			     struct mlx5hws_pool_chunk *chunk);

static inline u32
mlx5hws_pool_chunk_get_base_id(struct mlx5hws_pool *pool,
			       struct mlx5hws_pool_chunk *chunk)
{
	return pool->resource[chunk->resource_idx]->base_id;
}

static inline u32
mlx5hws_pool_chunk_get_base_mirror_id(struct mlx5hws_pool *pool,
				      struct mlx5hws_pool_chunk *chunk)
{
	return pool->mirror_resource[chunk->resource_idx]->base_id;
}
#endif /* MLX5HWS_POOL_H_ */
前天看到了小兔,昨天是小鹿,今天是你