resource.c 1.9 KB

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