1 /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
2 /* Copyright (c) 2024 NVIDIA Corporation & Affiliates */
3
4 #ifndef MLX5HWS_POOL_H_
5 #define MLX5HWS_POOL_H_
6
7 #define MLX5HWS_POOL_STC_LOG_SZ 15
8
9 enum mlx5hws_pool_type {
10 MLX5HWS_POOL_TYPE_STE,
11 MLX5HWS_POOL_TYPE_STC,
12 };
13
14 struct mlx5hws_pool_chunk {
15 int offset;
16 int order;
17 };
18
19 struct mlx5hws_pool_resource {
20 struct mlx5hws_pool *pool;
21 u32 base_id;
22 u32 range;
23 };
24
25 enum mlx5hws_pool_flags {
26 /* Managed by a buddy allocator. If this is not set only allocations of
27 * order 0 are supported.
28 */
29 MLX5HWS_POOL_FLAG_BUDDY = BIT(0),
30 };
31
32 enum mlx5hws_pool_optimize {
33 MLX5HWS_POOL_OPTIMIZE_NONE = 0x0,
34 MLX5HWS_POOL_OPTIMIZE_ORIG = 0x1,
35 MLX5HWS_POOL_OPTIMIZE_MIRROR = 0x2,
36 MLX5HWS_POOL_OPTIMIZE_MAX = 0x3,
37 };
38
39 struct mlx5hws_pool_attr {
40 enum mlx5hws_pool_type pool_type;
41 enum mlx5hws_table_type table_type;
42 enum mlx5hws_pool_flags flags;
43 enum mlx5hws_pool_optimize opt_type;
44 /* Allocation size once memory is depleted */
45 size_t alloc_log_sz;
46 };
47
48 enum mlx5hws_db_type {
49 /* Uses a bitmap, supports only allocations of order 0. */
50 MLX5HWS_POOL_DB_TYPE_BITMAP,
51 /* Entries are managed using a buddy mechanism. */
52 MLX5HWS_POOL_DB_TYPE_BUDDY,
53 };
54
55 struct mlx5hws_pool_db {
56 enum mlx5hws_db_type type;
57 union {
58 unsigned long *bitmap;
59 struct mlx5hws_buddy_mem *buddy;
60 };
61 };
62
63 typedef int (*mlx5hws_pool_db_get_chunk)(struct mlx5hws_pool *pool,
64 struct mlx5hws_pool_chunk *chunk);
65 typedef void (*mlx5hws_pool_db_put_chunk)(struct mlx5hws_pool *pool,
66 struct mlx5hws_pool_chunk *chunk);
67 typedef void (*mlx5hws_pool_unint_db)(struct mlx5hws_pool *pool);
68
69 struct mlx5hws_pool {
70 struct mlx5hws_context *ctx;
71 enum mlx5hws_pool_type type;
72 enum mlx5hws_pool_flags flags;
73 struct mutex lock; /* protect the pool */
74 size_t alloc_log_sz;
75 size_t available_elems;
76 enum mlx5hws_table_type tbl_type;
77 enum mlx5hws_pool_optimize opt_type;
78 struct mlx5hws_pool_resource *resource;
79 struct mlx5hws_pool_resource *mirror_resource;
80 struct mlx5hws_pool_db db;
81 /* Functions */
82 mlx5hws_pool_unint_db p_db_uninit;
83 mlx5hws_pool_db_get_chunk p_get_chunk;
84 mlx5hws_pool_db_put_chunk p_put_chunk;
85 };
86
87 struct mlx5hws_pool *
88 mlx5hws_pool_create(struct mlx5hws_context *ctx,
89 struct mlx5hws_pool_attr *pool_attr);
90
91 void mlx5hws_pool_destroy(struct mlx5hws_pool *pool);
92
93 int mlx5hws_pool_chunk_alloc(struct mlx5hws_pool *pool,
94 struct mlx5hws_pool_chunk *chunk);
95
96 void mlx5hws_pool_chunk_free(struct mlx5hws_pool *pool,
97 struct mlx5hws_pool_chunk *chunk);
98
mlx5hws_pool_get_base_id(struct mlx5hws_pool * pool)99 static inline u32 mlx5hws_pool_get_base_id(struct mlx5hws_pool *pool)
100 {
101 return pool->resource->base_id;
102 }
103
mlx5hws_pool_get_base_mirror_id(struct mlx5hws_pool * pool)104 static inline u32 mlx5hws_pool_get_base_mirror_id(struct mlx5hws_pool *pool)
105 {
106 return pool->mirror_resource->base_id;
107 }
108
109 static inline bool
mlx5hws_pool_empty(struct mlx5hws_pool * pool)110 mlx5hws_pool_empty(struct mlx5hws_pool *pool)
111 {
112 bool ret;
113
114 mutex_lock(&pool->lock);
115 ret = pool->available_elems == 0;
116 mutex_unlock(&pool->lock);
117
118 return ret;
119 }
120
121 static inline bool
mlx5hws_pool_full(struct mlx5hws_pool * pool)122 mlx5hws_pool_full(struct mlx5hws_pool *pool)
123 {
124 bool ret;
125
126 mutex_lock(&pool->lock);
127 ret = pool->available_elems == (1 << pool->alloc_log_sz);
128 mutex_unlock(&pool->lock);
129
130 return ret;
131 }
132 #endif /* MLX5HWS_POOL_H_ */
133