tle_memtank.h revision 703faabf
1/*
2 * Copyright (c) 2019  Intel Corporation.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef _TLE_MEMTANK_H_
17#define _TLE_MEMTANK_H_
18
19#include <string.h>
20
21#include <rte_common.h>
22#include <rte_memory.h>
23#include <rte_atomic.h>
24#include <rte_spinlock.h>
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30/**
31 * @file
32 * TLE memtank
33 *
34 * Same a s mempool it allows to alloc/free objects of fixed size
35 * in a lightweight manner (probably not as lightweight as mempool,
36 * but hopefully close enough).
37 * But in addition it can grow/shrink dynamically plus provides extra
38 * additional API for higher flexibility:
39 *	- manual grow()/shrink() functions
40 *	- different alloc/free policies
41 *        (can be specified by user via flags parameter).
42 * Internally it consists of:
43 *	- LIFO queue (fast allocator/deallocator)
44 *	- lists of memchunks (USED, FREE).
45 *
46 * For perfomance reasons memtank tries to allocate memory in
47 * relatively big chunks (memchunks) and then split each memchunk
48 * in dozens (or hundreds) of objects.
49 * There are two thresholds:
50 *	- min_free (grow threshold)
51 *	- max_free (shrink threshold)
52 */
53
54struct tle_memtank;
55
56/** generic memtank behavior flags */
57enum {
58	TLE_MTANK_OBJ_DBG = 1,
59};
60
61struct tle_memtank_prm {
62	/** min number of free objs in the ring (grow threshold). */
63	uint32_t min_free;
64	uint32_t max_free;  /**< max number of free objs (empty threshold) */
65	uint32_t max_obj; /**< max number of objs (grow limit) */
66	uint32_t obj_size;  /**< size of each mem object */
67	uint32_t obj_align;  /**< alignment of each mem object */
68	uint32_t nb_obj_chunk; /**< number of objects per chunk */
69	uint32_t flags; /**< behavior flags */
70	/** user provided function to alloc chunk of memory */
71	void * (*alloc)(size_t, void *);
72	/** user provided function to free chunk of memory */
73	void (*free)(void *, void *);
74	/** user provided function to initialiaze an object */
75	void (*init)(void *[], uint32_t, void *);
76	void *udata;        /**< opaque user data for alloc/free/init */
77};
78
79/**
80 * Allocate and intitialize new memtank instance, based on the
81 * parameters provided. Note that it uses user-provided *alloc()* function
82 * to allocate space for the memtank metadata.
83 * @param prm
84 *   Parameters used to create and initialise new memtank.
85 * @return
86 *   - Pointer to new memtank insteance created, if operation completed
87 *     successfully.
88 *   - NULL on error with rte_errno set appropriately.
89 */
90struct tle_memtank *
91tle_memtank_create(const struct tle_memtank_prm *prm);
92
93/**
94 * Destroy the memtank and free all memory referenced by the memtank.
95 * The objects must not be used by other cores as they will be freed.
96 *
97 * @param t
98 *   A pointer to the memtank instance.
99 */
100void
101tle_memtank_destroy(struct tle_memtank *t);
102
103
104/** alloc flags */
105enum {
106	TLE_MTANK_ALLOC_CHUNK = 1,
107	TLE_MTANK_ALLOC_GROW = 2,
108};
109
110/**
111 * Allocate up to requested number of objects from the memtank.
112 * Note that depending on *alloc* behavior (flags) some new memory chunks
113 * can be allocated from the underlying memory subsystem.
114 *
115 * @param t
116 *   A pointer to the memtank instance.
117 * @param obj
118 *   An array of void * pointers (objects) that will be filled.
119 * @param num
120 *   Number of objects to allocate from the memtank.
121 * @param flags
122 *   Flags that control allocation behavior.
123 * @return
124 *   Number of allocated objects.
125 */
126static inline uint32_t
127tle_memtank_alloc(struct tle_memtank *t, void *obj[], uint32_t num,
128		uint32_t flags);
129
130/**
131 * Allocate up to requested number of objects from the memtank.
132 * Note that this function bypasses *free* cache(s) and tries to allocate
133 * objects straight from the memory chunks.
134 * Note that depending on *alloc* behavior (flags) some new memory chunks
135 * can be allocated from the underlying memory subsystem.
136 *
137 * @param t
138 *   A pointer to the memtank instance.
139 * @param obj
140 *   An array of void * pointers (objects) that will be filled.
141 * @param nb_obj
142 *   Number of objects to allocate from the memtank.
143 * @param flags
144 *   Flags that control allocation behavior.
145 * @return
146 *   Number of allocated objects.
147 */
148uint32_t
149tle_memtank_chunk_alloc(struct tle_memtank *t, void *obj[], uint32_t nb_obj,
150		uint32_t flags);
151
152/** free flags */
153enum {
154	TLE_MTANK_FREE_SHRINK = 1,
155};
156
157/**
158 * Free (put) provided objects back to the memtank.
159 * Note that depending on *free* behavior (flags) some memory chunks can be
160 * returned (freed) to the underlying memory subsystem.
161 *
162 * @param t
163 *   A pointer to the memtank instance.
164 * @param obj
165 *   An array of object pointers to be freed.
166 * @param num
167 *   Number of objects to free.
168 * @param flags
169 *   Flags that control free behavior.
170 */
171static inline void
172tle_memtank_free(struct tle_memtank *t, void * const obj[],  uint32_t num,
173		uint32_t flags);
174
175/**
176 * Free (put) provided objects back to the memtank.
177 * Note that this function bypasses *free* cache(s) and tries to put
178 * objects straight to the memory chunks.
179 * Note that depending on *free* behavior (flags) some memory chunks can be
180 * returned (freed) to the underlying memory subsystem.
181 *
182 * @param t
183 *   A pointer to the memtank instance.
184 * @param obj
185 *   An array of object pointers to be freed.
186 * @param nb_obj
187 *   Number of objects to allocate from the memtank.
188 * @param flags
189 *   Flags that control allocation behavior.
190 */
191void
192tle_memtank_chunk_free(struct tle_memtank *t, void * const obj[],
193		uint32_t nb_obj, uint32_t flags);
194
195/**
196 * Check does number of objects in *free* cache is below memtank grow
197 * threshold (min_free). If yes, then tries to allocate memory for new
198 * objects from the underlying memory subsystem.
199 *
200 * @param t
201 *   A pointer to the memtank instance.
202 * @return
203 *   Number of newly allocated memory chunks.
204 */
205int
206tle_memtank_grow(struct tle_memtank *t);
207
208/**
209 * Check does number of objects in *free* cache have reached memtank shrink
210 * threshold (max_free). If yes, then tries to return excessive memory to
211 * the the underlying memory subsystem.
212 *
213 * @param t
214 *   A pointer to the memtank instance.
215 * @return
216 *   Number of freed memory chunks.
217 */
218int
219tle_memtank_shrink(struct tle_memtank *t);
220
221/* dump flags */
222enum {
223	TLE_MTANK_DUMP_FREE_STAT = 1,
224	TLE_MTANK_DUMP_CHUNK_STAT = 2,
225	TLE_MTANK_DUMP_CHUNK = 4,
226	/* first not used power of two */
227	TLE_MTANK_DUMP_END,
228
229	/* dump all stats */
230	TLE_MTANK_DUMP_STAT =
231		(TLE_MTANK_DUMP_FREE_STAT | TLE_MTANK_DUMP_CHUNK_STAT),
232	/* dump everything */
233	TLE_MTANK_DUMP_ALL = TLE_MTANK_DUMP_END - 1,
234};
235
236/**
237 * Dump information about the memtank to the file.
238 * Note that depending of *flags* value it might cause some internal locks
239 * grabbing, and might affect perfomance of others threads that
240 * concurently use same memtank.
241 *
242 * @param f
243 *   A pinter to the file.
244 * @param t
245 *   A pointer to the memtank instance.
246 * @param flags
247 *   Flags that control dump behavior.
248 */
249void
250tle_memtank_dump(FILE *f, const struct tle_memtank *t, uint32_t flags);
251
252/**
253 * Check the consistency of the given memtank instance.
254 * Dumps error messages to the RTE log subsystem, if some inconsitency
255 * is detected.
256 *
257 * @param t
258 *   A pointer to the memtank instance.
259 * @param ct
260 *   Value greater then zero, if some other threads do concurently use
261 *   that memtank.
262 * @return
263 *   Zero on success, or negaive value otherwise.
264 */
265int
266tle_memtank_sanity_check(const struct tle_memtank *t, int32_t ct);
267
268#ifdef __cplusplus
269}
270#endif
271
272#include <tle_memtank_pub.h>
273
274#endif /* _TLE_MEMTANK_H_ */
275