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