Commit | Line | Data |
---|---|---|
cdebea69 DL |
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 | #include <kunit/resource.h> | |
10 | #include <kunit/test.h> | |
11 | #include <linux/kref.h> | |
12 | ||
13 | /* | |
14 | * Used for static resources and when a kunit_resource * has been created by | |
15 | * kunit_alloc_resource(). When an init function is supplied, @data is passed | |
16 | * into the init function; otherwise, we simply set the resource data field to | |
ad69172e | 17 | * the data value passed in. Doesn't initialize res->should_kfree. |
cdebea69 | 18 | */ |
ad69172e DG |
19 | int __kunit_add_resource(struct kunit *test, |
20 | kunit_resource_init_t init, | |
21 | kunit_resource_free_t free, | |
22 | struct kunit_resource *res, | |
23 | void *data) | |
cdebea69 DL |
24 | { |
25 | int ret = 0; | |
26 | unsigned long flags; | |
27 | ||
28 | res->free = free; | |
29 | kref_init(&res->refcount); | |
30 | ||
31 | if (init) { | |
32 | ret = init(res, data); | |
33 | if (ret) | |
34 | return ret; | |
35 | } else { | |
36 | res->data = data; | |
37 | } | |
38 | ||
39 | spin_lock_irqsave(&test->lock, flags); | |
40 | list_add_tail(&res->node, &test->resources); | |
41 | /* refcount for list is established by kref_init() */ | |
42 | spin_unlock_irqrestore(&test->lock, flags); | |
43 | ||
44 | return ret; | |
45 | } | |
ad69172e | 46 | EXPORT_SYMBOL_GPL(__kunit_add_resource); |
cdebea69 DL |
47 | |
48 | void kunit_remove_resource(struct kunit *test, struct kunit_resource *res) | |
49 | { | |
50 | unsigned long flags; | |
59729170 | 51 | bool was_linked; |
cdebea69 DL |
52 | |
53 | spin_lock_irqsave(&test->lock, flags); | |
59729170 DG |
54 | was_linked = !list_empty(&res->node); |
55 | list_del_init(&res->node); | |
cdebea69 | 56 | spin_unlock_irqrestore(&test->lock, flags); |
59729170 DG |
57 | |
58 | if (was_linked) | |
59 | kunit_put_resource(res); | |
cdebea69 DL |
60 | } |
61 | EXPORT_SYMBOL_GPL(kunit_remove_resource); | |
62 | ||
63 | int kunit_destroy_resource(struct kunit *test, kunit_resource_match_t match, | |
64 | void *match_data) | |
65 | { | |
66 | struct kunit_resource *res = kunit_find_resource(test, match, | |
67 | match_data); | |
68 | ||
69 | if (!res) | |
70 | return -ENOENT; | |
71 | ||
72 | kunit_remove_resource(test, res); | |
73 | ||
74 | /* We have a reference also via _find(); drop it. */ | |
75 | kunit_put_resource(res); | |
76 | ||
77 | return 0; | |
78 | } | |
79 | EXPORT_SYMBOL_GPL(kunit_destroy_resource); |