LCOV - code coverage report
Current view: top level - lib/kunit - resource.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 23 39 59.0 %
Date: 2022-12-09 01:23:36 Functions: 3 5 60.0 %

          Line data    Source code
       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
      17             :  * the data value passed in.
      18             :  */
      19         271 : 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)
      24             : {
      25         271 :         int ret = 0;
      26             :         unsigned long flags;
      27             : 
      28         271 :         res->free = free;
      29         542 :         kref_init(&res->refcount);
      30             : 
      31         271 :         if (init) {
      32         271 :                 ret = init(res, data);
      33         271 :                 if (ret)
      34             :                         return ret;
      35             :         } else {
      36           0 :                 res->data = data;
      37             :         }
      38             : 
      39         271 :         spin_lock_irqsave(&test->lock, flags);
      40         542 :         list_add_tail(&res->node, &test->resources);
      41             :         /* refcount for list is established by kref_init() */
      42         542 :         spin_unlock_irqrestore(&test->lock, flags);
      43             : 
      44         271 :         return ret;
      45             : }
      46             : EXPORT_SYMBOL_GPL(kunit_add_resource);
      47             : 
      48           0 : int kunit_add_named_resource(struct kunit *test,
      49             :                              kunit_resource_init_t init,
      50             :                              kunit_resource_free_t free,
      51             :                              struct kunit_resource *res,
      52             :                              const char *name,
      53             :                              void *data)
      54             : {
      55             :         struct kunit_resource *existing;
      56             : 
      57           0 :         if (!name)
      58             :                 return -EINVAL;
      59             : 
      60           0 :         existing = kunit_find_named_resource(test, name);
      61           0 :         if (existing) {
      62           0 :                 kunit_put_resource(existing);
      63           0 :                 return -EEXIST;
      64             :         }
      65             : 
      66           0 :         res->name = name;
      67             : 
      68           0 :         return kunit_add_resource(test, init, free, res, data);
      69             : }
      70             : EXPORT_SYMBOL_GPL(kunit_add_named_resource);
      71             : 
      72           0 : struct kunit_resource *kunit_alloc_and_get_resource(struct kunit *test,
      73             :                                                     kunit_resource_init_t init,
      74             :                                                     kunit_resource_free_t free,
      75             :                                                     gfp_t internal_gfp,
      76             :                                                     void *data)
      77             : {
      78             :         struct kunit_resource *res;
      79             :         int ret;
      80             : 
      81           0 :         res = kzalloc(sizeof(*res), internal_gfp);
      82           0 :         if (!res)
      83             :                 return NULL;
      84             : 
      85           0 :         ret = kunit_add_resource(test, init, free, res, data);
      86           0 :         if (!ret) {
      87             :                 /*
      88             :                  * bump refcount for get; kunit_resource_put() should be called
      89             :                  * when done.
      90             :                  */
      91           0 :                 kunit_get_resource(res);
      92           0 :                 return res;
      93             :         }
      94             :         return NULL;
      95             : }
      96             : EXPORT_SYMBOL_GPL(kunit_alloc_and_get_resource);
      97             : 
      98         271 : void kunit_remove_resource(struct kunit *test, struct kunit_resource *res)
      99             : {
     100             :         unsigned long flags;
     101             : 
     102         271 :         spin_lock_irqsave(&test->lock, flags);
     103         542 :         list_del(&res->node);
     104         542 :         spin_unlock_irqrestore(&test->lock, flags);
     105         271 :         kunit_put_resource(res);
     106         271 : }
     107             : EXPORT_SYMBOL_GPL(kunit_remove_resource);
     108             : 
     109          50 : int kunit_destroy_resource(struct kunit *test, kunit_resource_match_t match,
     110             :                            void *match_data)
     111             : {
     112          50 :         struct kunit_resource *res = kunit_find_resource(test, match,
     113             :                                                          match_data);
     114             : 
     115          50 :         if (!res)
     116             :                 return -ENOENT;
     117             : 
     118          50 :         kunit_remove_resource(test, res);
     119             : 
     120             :         /* We have a reference also via _find(); drop it. */
     121          50 :         kunit_put_resource(res);
     122             : 
     123          50 :         return 0;
     124             : }
     125             : EXPORT_SYMBOL_GPL(kunit_destroy_resource);

Generated by: LCOV version 1.14