Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * KUnit resource API for test managed resources (allocations, etc.).
0004  *
0005  * Copyright (C) 2022, Google LLC.
0006  * Author: Daniel Latypov <dlatypov@google.com>
0007  */
0008 
0009 #include <kunit/resource.h>
0010 #include <kunit/test.h>
0011 #include <linux/kref.h>
0012 
0013 /*
0014  * Used for static resources and when a kunit_resource * has been created by
0015  * kunit_alloc_resource().  When an init function is supplied, @data is passed
0016  * into the init function; otherwise, we simply set the resource data field to
0017  * the data value passed in. Doesn't initialize res->should_kfree.
0018  */
0019 int __kunit_add_resource(struct kunit *test,
0020              kunit_resource_init_t init,
0021              kunit_resource_free_t free,
0022              struct kunit_resource *res,
0023              void *data)
0024 {
0025     int ret = 0;
0026     unsigned long flags;
0027 
0028     res->free = free;
0029     kref_init(&res->refcount);
0030 
0031     if (init) {
0032         ret = init(res, data);
0033         if (ret)
0034             return ret;
0035     } else {
0036         res->data = data;
0037     }
0038 
0039     spin_lock_irqsave(&test->lock, flags);
0040     list_add_tail(&res->node, &test->resources);
0041     /* refcount for list is established by kref_init() */
0042     spin_unlock_irqrestore(&test->lock, flags);
0043 
0044     return ret;
0045 }
0046 EXPORT_SYMBOL_GPL(__kunit_add_resource);
0047 
0048 void kunit_remove_resource(struct kunit *test, struct kunit_resource *res)
0049 {
0050     unsigned long flags;
0051     bool was_linked;
0052 
0053     spin_lock_irqsave(&test->lock, flags);
0054     was_linked = !list_empty(&res->node);
0055     list_del_init(&res->node);
0056     spin_unlock_irqrestore(&test->lock, flags);
0057 
0058     if (was_linked)
0059         kunit_put_resource(res);
0060 }
0061 EXPORT_SYMBOL_GPL(kunit_remove_resource);
0062 
0063 int kunit_destroy_resource(struct kunit *test, kunit_resource_match_t match,
0064                void *match_data)
0065 {
0066     struct kunit_resource *res = kunit_find_resource(test, match,
0067                              match_data);
0068 
0069     if (!res)
0070         return -ENOENT;
0071 
0072     kunit_remove_resource(test, res);
0073 
0074     /* We have a reference also via _find(); drop it. */
0075     kunit_put_resource(res);
0076 
0077     return 0;
0078 }
0079 EXPORT_SYMBOL_GPL(kunit_destroy_resource);