1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3 * KUnit resource API for test managed resources (allocations, etc.).
4 *
5 * Copyright (C) 2022, Google LLC.
6 * Author: Daniel Latypov <dlatypov@google.com>
7 */
8
9 #ifndef _KUNIT_RESOURCE_H
10 #define _KUNIT_RESOURCE_H
11
12 #include <kunit/test.h>
13
14 #include <linux/kref.h>
15 #include <linux/list.h>
16 #include <linux/slab.h>
17 #include <linux/spinlock.h>
18 #include <linux/android_kabi.h>
19
20 struct kunit_resource;
21
22 typedef int (*kunit_resource_init_t)(struct kunit_resource *, void *);
23 typedef void (*kunit_resource_free_t)(struct kunit_resource *);
24
25 /**
26 * struct kunit_resource - represents a *test managed resource*
27 * @data: for the user to store arbitrary data.
28 * @name: optional name
29 * @free: a user supplied function to free the resource.
30 *
31 * Represents a *test managed resource*, a resource which will automatically be
32 * cleaned up at the end of a test case. This cleanup is performed by the 'free'
33 * function. The struct kunit_resource itself is freed automatically with
34 * kfree() if it was allocated by KUnit (e.g., by kunit_alloc_resource()), but
35 * must be freed by the user otherwise.
36 *
37 * Resources are reference counted so if a resource is retrieved via
38 * kunit_alloc_and_get_resource() or kunit_find_resource(), we need
39 * to call kunit_put_resource() to reduce the resource reference count
40 * when finished with it. Note that kunit_alloc_resource() does not require a
41 * kunit_resource_put() because it does not retrieve the resource itself.
42 *
43 * Example:
44 *
45 * .. code-block:: c
46 *
47 * struct kunit_kmalloc_params {
48 * size_t size;
49 * gfp_t gfp;
50 * };
51 *
52 * static int kunit_kmalloc_init(struct kunit_resource *res, void *context)
53 * {
54 * struct kunit_kmalloc_params *params = context;
55 * res->data = kmalloc(params->size, params->gfp);
56 *
57 * if (!res->data)
58 * return -ENOMEM;
59 *
60 * return 0;
61 * }
62 *
63 * static void kunit_kmalloc_free(struct kunit_resource *res)
64 * {
65 * kfree(res->data);
66 * }
67 *
68 * void *kunit_kmalloc(struct kunit *test, size_t size, gfp_t gfp)
69 * {
70 * struct kunit_kmalloc_params params;
71 *
72 * params.size = size;
73 * params.gfp = gfp;
74 *
75 * return kunit_alloc_resource(test, kunit_kmalloc_init,
76 * kunit_kmalloc_free, gfp, ¶ms);
77 * }
78 *
79 * Resources can also be named, with lookup/removal done on a name
80 * basis also. kunit_add_named_resource(), kunit_find_named_resource()
81 * and kunit_destroy_named_resource(). Resource names must be
82 * unique within the test instance.
83 */
84 struct kunit_resource {
85 void *data;
86 const char *name;
87 kunit_resource_free_t free;
88
89 /* private: internal use only. */
90 struct kref refcount;
91 struct list_head node;
92 bool should_kfree;
93
94 ANDROID_KABI_RESERVE(1);
95 };
96
97 /**
98 * kunit_get_resource() - Hold resource for use. Should not need to be used
99 * by most users as we automatically get resources
100 * retrieved by kunit_find_resource*().
101 * @res: resource
102 */
kunit_get_resource(struct kunit_resource * res)103 static inline void kunit_get_resource(struct kunit_resource *res)
104 {
105 kref_get(&res->refcount);
106 }
107
108 /*
109 * Called when refcount reaches zero via kunit_put_resource();
110 * should not be called directly.
111 */
kunit_release_resource(struct kref * kref)112 static inline void kunit_release_resource(struct kref *kref)
113 {
114 struct kunit_resource *res = container_of(kref, struct kunit_resource,
115 refcount);
116
117 if (res->free)
118 res->free(res);
119
120 /* 'res' is valid here, as if should_kfree is set, res->free may not free
121 * 'res' itself, just res->data
122 */
123 if (res->should_kfree)
124 kfree(res);
125 }
126
127 /**
128 * kunit_put_resource() - When caller is done with retrieved resource,
129 * kunit_put_resource() should be called to drop
130 * reference count. The resource list maintains
131 * a reference count on resources, so if no users
132 * are utilizing a resource and it is removed from
133 * the resource list, it will be freed via the
134 * associated free function (if any). Only
135 * needs to be used if we alloc_and_get() or
136 * find() resource.
137 * @res: resource
138 */
kunit_put_resource(struct kunit_resource * res)139 static inline void kunit_put_resource(struct kunit_resource *res)
140 {
141 kref_put(&res->refcount, kunit_release_resource);
142 }
143
144 /**
145 * __kunit_add_resource() - Internal helper to add a resource.
146 *
147 * res->should_kfree is not initialised.
148 * @test: The test context object.
149 * @init: a user-supplied function to initialize the result (if needed). If
150 * none is supplied, the resource data value is simply set to @data.
151 * If an init function is supplied, @data is passed to it instead.
152 * @free: a user-supplied function to free the resource (if needed).
153 * @res: The resource.
154 * @data: value to pass to init function or set in resource data field.
155 */
156 int __kunit_add_resource(struct kunit *test,
157 kunit_resource_init_t init,
158 kunit_resource_free_t free,
159 struct kunit_resource *res,
160 void *data);
161
162 /**
163 * kunit_add_resource() - Add a *test managed resource*.
164 * @test: The test context object.
165 * @init: a user-supplied function to initialize the result (if needed). If
166 * none is supplied, the resource data value is simply set to @data.
167 * If an init function is supplied, @data is passed to it instead.
168 * @free: a user-supplied function to free the resource (if needed).
169 * @res: The resource.
170 * @data: value to pass to init function or set in resource data field.
171 */
kunit_add_resource(struct kunit * test,kunit_resource_init_t init,kunit_resource_free_t free,struct kunit_resource * res,void * data)172 static inline int kunit_add_resource(struct kunit *test,
173 kunit_resource_init_t init,
174 kunit_resource_free_t free,
175 struct kunit_resource *res,
176 void *data)
177 {
178 res->should_kfree = false;
179 return __kunit_add_resource(test, init, free, res, data);
180 }
181
182 static inline struct kunit_resource *
183 kunit_find_named_resource(struct kunit *test, const char *name);
184
185 /**
186 * kunit_add_named_resource() - Add a named *test managed resource*.
187 * @test: The test context object.
188 * @init: a user-supplied function to initialize the resource data, if needed.
189 * @free: a user-supplied function to free the resource data, if needed.
190 * @res: The resource.
191 * @name: name to be set for resource.
192 * @data: value to pass to init function or set in resource data field.
193 */
kunit_add_named_resource(struct kunit * test,kunit_resource_init_t init,kunit_resource_free_t free,struct kunit_resource * res,const char * name,void * data)194 static inline int kunit_add_named_resource(struct kunit *test,
195 kunit_resource_init_t init,
196 kunit_resource_free_t free,
197 struct kunit_resource *res,
198 const char *name,
199 void *data)
200 {
201 struct kunit_resource *existing;
202
203 if (!name)
204 return -EINVAL;
205
206 existing = kunit_find_named_resource(test, name);
207 if (existing) {
208 kunit_put_resource(existing);
209 return -EEXIST;
210 }
211
212 res->name = name;
213 res->should_kfree = false;
214
215 return __kunit_add_resource(test, init, free, res, data);
216 }
217
218 /**
219 * kunit_alloc_and_get_resource() - Allocates and returns a *test managed resource*.
220 * @test: The test context object.
221 * @init: a user supplied function to initialize the resource.
222 * @free: a user supplied function to free the resource (if needed).
223 * @internal_gfp: gfp to use for internal allocations, if unsure, use GFP_KERNEL
224 * @context: for the user to pass in arbitrary data to the init function.
225 *
226 * Allocates a *test managed resource*, a resource which will automatically be
227 * cleaned up at the end of a test case. See &struct kunit_resource for an
228 * example.
229 *
230 * This is effectively identical to kunit_alloc_resource, but returns the
231 * struct kunit_resource pointer, not just the 'data' pointer. It therefore
232 * also increments the resource's refcount, so kunit_put_resource() should be
233 * called when you've finished with it.
234 *
235 * Note: KUnit needs to allocate memory for a kunit_resource object. You must
236 * specify an @internal_gfp that is compatible with the use context of your
237 * resource.
238 */
239 static inline struct kunit_resource *
kunit_alloc_and_get_resource(struct kunit * test,kunit_resource_init_t init,kunit_resource_free_t free,gfp_t internal_gfp,void * context)240 kunit_alloc_and_get_resource(struct kunit *test,
241 kunit_resource_init_t init,
242 kunit_resource_free_t free,
243 gfp_t internal_gfp,
244 void *context)
245 {
246 struct kunit_resource *res;
247 int ret;
248
249 res = kzalloc(sizeof(*res), internal_gfp);
250 if (!res)
251 return NULL;
252
253 res->should_kfree = true;
254
255 ret = __kunit_add_resource(test, init, free, res, context);
256 if (!ret) {
257 /*
258 * bump refcount for get; kunit_resource_put() should be called
259 * when done.
260 */
261 kunit_get_resource(res);
262 return res;
263 }
264 return NULL;
265 }
266
267 /**
268 * kunit_alloc_resource() - Allocates a *test managed resource*.
269 * @test: The test context object.
270 * @init: a user supplied function to initialize the resource.
271 * @free: a user supplied function to free the resource (if needed).
272 * @internal_gfp: gfp to use for internal allocations, if unsure, use GFP_KERNEL
273 * @context: for the user to pass in arbitrary data to the init function.
274 *
275 * Allocates a *test managed resource*, a resource which will automatically be
276 * cleaned up at the end of a test case. See &struct kunit_resource for an
277 * example.
278 *
279 * Note: KUnit needs to allocate memory for a kunit_resource object. You must
280 * specify an @internal_gfp that is compatible with the use context of your
281 * resource.
282 */
kunit_alloc_resource(struct kunit * test,kunit_resource_init_t init,kunit_resource_free_t free,gfp_t internal_gfp,void * context)283 static inline void *kunit_alloc_resource(struct kunit *test,
284 kunit_resource_init_t init,
285 kunit_resource_free_t free,
286 gfp_t internal_gfp,
287 void *context)
288 {
289 struct kunit_resource *res;
290
291 res = kzalloc(sizeof(*res), internal_gfp);
292 if (!res)
293 return NULL;
294
295 res->should_kfree = true;
296 if (!__kunit_add_resource(test, init, free, res, context))
297 return res->data;
298
299 return NULL;
300 }
301
302 typedef bool (*kunit_resource_match_t)(struct kunit *test,
303 struct kunit_resource *res,
304 void *match_data);
305
306 /**
307 * kunit_resource_name_match() - Match a resource with the same name.
308 * @test: Test case to which the resource belongs.
309 * @res: The resource.
310 * @match_name: The name to match against.
311 */
kunit_resource_name_match(struct kunit * test,struct kunit_resource * res,void * match_name)312 static inline bool kunit_resource_name_match(struct kunit *test,
313 struct kunit_resource *res,
314 void *match_name)
315 {
316 return res->name && strcmp(res->name, match_name) == 0;
317 }
318
319 /**
320 * kunit_find_resource() - Find a resource using match function/data.
321 * @test: Test case to which the resource belongs.
322 * @match: match function to be applied to resources/match data.
323 * @match_data: data to be used in matching.
324 */
325 static inline struct kunit_resource *
kunit_find_resource(struct kunit * test,kunit_resource_match_t match,void * match_data)326 kunit_find_resource(struct kunit *test,
327 kunit_resource_match_t match,
328 void *match_data)
329 {
330 struct kunit_resource *res, *found = NULL;
331 unsigned long flags;
332
333 spin_lock_irqsave(&test->lock, flags);
334
335 list_for_each_entry_reverse(res, &test->resources, node) {
336 if (match(test, res, (void *)match_data)) {
337 found = res;
338 kunit_get_resource(found);
339 break;
340 }
341 }
342
343 spin_unlock_irqrestore(&test->lock, flags);
344
345 return found;
346 }
347
348 /**
349 * kunit_find_named_resource() - Find a resource using match name.
350 * @test: Test case to which the resource belongs.
351 * @name: match name.
352 */
353 static inline struct kunit_resource *
kunit_find_named_resource(struct kunit * test,const char * name)354 kunit_find_named_resource(struct kunit *test,
355 const char *name)
356 {
357 return kunit_find_resource(test, kunit_resource_name_match,
358 (void *)name);
359 }
360
361 /**
362 * kunit_destroy_resource() - Find a kunit_resource and destroy it.
363 * @test: Test case to which the resource belongs.
364 * @match: Match function. Returns whether a given resource matches @match_data.
365 * @match_data: Data passed into @match.
366 *
367 * RETURNS:
368 * 0 if kunit_resource is found and freed, -ENOENT if not found.
369 */
370 int kunit_destroy_resource(struct kunit *test,
371 kunit_resource_match_t match,
372 void *match_data);
373
kunit_destroy_named_resource(struct kunit * test,const char * name)374 static inline int kunit_destroy_named_resource(struct kunit *test,
375 const char *name)
376 {
377 return kunit_destroy_resource(test, kunit_resource_name_match,
378 (void *)name);
379 }
380
381 /**
382 * kunit_remove_resource() - remove resource from resource list associated with
383 * test.
384 * @test: The test context object.
385 * @res: The resource to be removed.
386 *
387 * Note that the resource will not be immediately freed since it is likely
388 * the caller has a reference to it via alloc_and_get() or find();
389 * in this case a final call to kunit_put_resource() is required.
390 */
391 void kunit_remove_resource(struct kunit *test, struct kunit_resource *res);
392
393 /* A 'deferred action' function to be used with kunit_add_action. */
394 typedef void (kunit_action_t)(void *);
395
396 /**
397 * KUNIT_DEFINE_ACTION_WRAPPER() - Wrap a function for use as a deferred action.
398 *
399 * @wrapper: The name of the new wrapper function define.
400 * @orig: The original function to wrap.
401 * @arg_type: The type of the argument accepted by @orig.
402 *
403 * Defines a wrapper for a function which accepts a single, pointer-sized
404 * argument. This wrapper can then be passed to kunit_add_action() and
405 * similar. This should be used in preference to casting a function
406 * directly to kunit_action_t, as casting function pointers will break
407 * control flow integrity (CFI), leading to crashes.
408 */
409 #define KUNIT_DEFINE_ACTION_WRAPPER(wrapper, orig, arg_type) \
410 static void wrapper(void *in) \
411 { \
412 arg_type arg = (arg_type)in; \
413 orig(arg); \
414 }
415
416
417 /**
418 * kunit_add_action() - Call a function when the test ends.
419 * @test: Test case to associate the action with.
420 * @action: The function to run on test exit
421 * @ctx: Data passed into @func
422 *
423 * Defer the execution of a function until the test exits, either normally or
424 * due to a failure. @ctx is passed as additional context. All functions
425 * registered with kunit_add_action() will execute in the opposite order to that
426 * they were registered in.
427 *
428 * This is useful for cleaning up allocated memory and resources, as these
429 * functions are called even if the test aborts early due to, e.g., a failed
430 * assertion.
431 *
432 * See also: devm_add_action() for the devres equivalent.
433 *
434 * Returns:
435 * 0 on success, an error if the action could not be deferred.
436 */
437 int kunit_add_action(struct kunit *test, kunit_action_t *action, void *ctx);
438
439 /**
440 * kunit_add_action_or_reset() - Call a function when the test ends.
441 * @test: Test case to associate the action with.
442 * @action: The function to run on test exit
443 * @ctx: Data passed into @func
444 *
445 * Defer the execution of a function until the test exits, either normally or
446 * due to a failure. @ctx is passed as additional context. All functions
447 * registered with kunit_add_action() will execute in the opposite order to that
448 * they were registered in.
449 *
450 * This is useful for cleaning up allocated memory and resources, as these
451 * functions are called even if the test aborts early due to, e.g., a failed
452 * assertion.
453 *
454 * If the action cannot be created (e.g., due to the system being out of memory),
455 * then action(ctx) will be called immediately, and an error will be returned.
456 *
457 * See also: devm_add_action_or_reset() for the devres equivalent.
458 *
459 * Returns:
460 * 0 on success, an error if the action could not be deferred.
461 */
462 int kunit_add_action_or_reset(struct kunit *test, kunit_action_t *action,
463 void *ctx);
464
465 /**
466 * kunit_remove_action() - Cancel a matching deferred action.
467 * @test: Test case the action is associated with.
468 * @action: The deferred function to cancel.
469 * @ctx: The context passed to the deferred function to trigger.
470 *
471 * Prevent an action deferred via kunit_add_action() from executing when the
472 * test terminates.
473 *
474 * If the function/context pair was deferred multiple times, only the most
475 * recent one will be cancelled.
476 *
477 * See also: devm_remove_action() for the devres equivalent.
478 */
479 void kunit_remove_action(struct kunit *test,
480 kunit_action_t *action,
481 void *ctx);
482
483 /**
484 * kunit_release_action() - Run a matching action call immediately.
485 * @test: Test case the action is associated with.
486 * @action: The deferred function to trigger.
487 * @ctx: The context passed to the deferred function to trigger.
488 *
489 * Execute a function deferred via kunit_add_action()) immediately, rather than
490 * when the test ends.
491 *
492 * If the function/context pair was deferred multiple times, it will only be
493 * executed once here. The most recent deferral will no longer execute when
494 * the test ends.
495 *
496 * kunit_release_action(test, func, ctx);
497 * is equivalent to
498 * func(ctx);
499 * kunit_remove_action(test, func, ctx);
500 *
501 * See also: devm_release_action() for the devres equivalent.
502 */
503 void kunit_release_action(struct kunit *test,
504 kunit_action_t *action,
505 void *ctx);
506 #endif /* _KUNIT_RESOURCE_H */
507