2019-09-23 12:02:31 +03:00
// SPDX-License-Identifier: GPL-2.0
/*
* Base unit test ( KUnit ) API .
*
* Copyright ( C ) 2019 , Google LLC .
* Author : Brendan Higgins < brendanhiggins @ google . com >
*/
# include <kunit/test.h>
2019-09-23 12:02:39 +03:00
# include <kunit/try-catch.h>
2019-09-23 12:02:31 +03:00
# include <linux/kernel.h>
2019-09-23 12:02:39 +03:00
# include <linux/sched/debug.h>
2019-09-23 12:02:31 +03:00
2020-01-07 01:28:18 +03:00
# include "string-stream.h"
2019-09-23 12:02:31 +03:00
static void kunit_set_failure ( struct kunit * test )
{
WRITE_ONCE ( test - > success , false ) ;
}
static void kunit_print_tap_version ( void )
{
static bool kunit_has_printed_tap_version ;
if ( ! kunit_has_printed_tap_version ) {
kunit: fix failure to build without printk
Previously KUnit assumed that printk would always be present, which is
not a valid assumption to make. Fix that by removing call to
vprintk_emit, and calling printk directly.
This fixes a build error[1] reported by Randy.
For context this change comes after much discussion. My first stab[2] at
this was just to make the KUnit logging code compile out; however, it
was agreed that if we were going to use vprintk_emit, then vprintk_emit
should provide a no-op stub, which lead to my second attempt[3]. In
response to me trying to stub out vprintk_emit, Sergey Senozhatsky
suggested a way for me to remove our usage of vprintk_emit, which led to
my third attempt at solving this[4].
In my third version of this patch[4], I completely removed vprintk_emit,
as suggested by Sergey; however, there was a bit of debate over whether
Sergey's solution was the best. The debate arose due to Sergey's version
resulting in a checkpatch warning, which resulted in a debate over
correct printk usage. Joe Perches offered an alternative fix which was
somewhat less far reaching than what Sergey had suggested and
importantly relied on continuing to use %pV. Much of the debated
centered around whether %pV should be widely used, and whether Sergey's
version would result in object size bloat. Ultimately, we decided to go
with Sergey's version.
Reported-by: Randy Dunlap <rdunlap@infradead.org>
Link[1]: https://lore.kernel.org/linux-kselftest/c7229254-0d90-d90e-f3df-5b6d6fc0b51f@infradead.org/
Link[2]: https://lore.kernel.org/linux-kselftest/20190827174932.44177-1-brendanhiggins@google.com/
Link[3]: https://lore.kernel.org/linux-kselftest/20190827234835.234473-1-brendanhiggins@google.com/
Link[4]: https://lore.kernel.org/linux-kselftest/20190828093143.163302-1-brendanhiggins@google.com/
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
Cc: Joe Perches <joe@perches.com>
Cc: Tim.Bird@sony.com
Signed-off-by: Brendan Higgins <brendanhiggins@google.com>
Acked-by: Randy Dunlap <rdunlap@infradead.org> # build-tested
Reviewed-by: Petr Mladek <pmladek@suse.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2019-09-23 12:02:49 +03:00
pr_info ( " TAP version 14 \n " ) ;
2019-09-23 12:02:31 +03:00
kunit_has_printed_tap_version = true ;
}
}
static size_t kunit_test_cases_len ( struct kunit_case * test_cases )
{
struct kunit_case * test_case ;
size_t len = 0 ;
for ( test_case = test_cases ; test_case - > run_case ; test_case + + )
len + + ;
return len ;
}
static void kunit_print_subtest_start ( struct kunit_suite * suite )
{
kunit_print_tap_version ( ) ;
kunit: fix failure to build without printk
Previously KUnit assumed that printk would always be present, which is
not a valid assumption to make. Fix that by removing call to
vprintk_emit, and calling printk directly.
This fixes a build error[1] reported by Randy.
For context this change comes after much discussion. My first stab[2] at
this was just to make the KUnit logging code compile out; however, it
was agreed that if we were going to use vprintk_emit, then vprintk_emit
should provide a no-op stub, which lead to my second attempt[3]. In
response to me trying to stub out vprintk_emit, Sergey Senozhatsky
suggested a way for me to remove our usage of vprintk_emit, which led to
my third attempt at solving this[4].
In my third version of this patch[4], I completely removed vprintk_emit,
as suggested by Sergey; however, there was a bit of debate over whether
Sergey's solution was the best. The debate arose due to Sergey's version
resulting in a checkpatch warning, which resulted in a debate over
correct printk usage. Joe Perches offered an alternative fix which was
somewhat less far reaching than what Sergey had suggested and
importantly relied on continuing to use %pV. Much of the debated
centered around whether %pV should be widely used, and whether Sergey's
version would result in object size bloat. Ultimately, we decided to go
with Sergey's version.
Reported-by: Randy Dunlap <rdunlap@infradead.org>
Link[1]: https://lore.kernel.org/linux-kselftest/c7229254-0d90-d90e-f3df-5b6d6fc0b51f@infradead.org/
Link[2]: https://lore.kernel.org/linux-kselftest/20190827174932.44177-1-brendanhiggins@google.com/
Link[3]: https://lore.kernel.org/linux-kselftest/20190827234835.234473-1-brendanhiggins@google.com/
Link[4]: https://lore.kernel.org/linux-kselftest/20190828093143.163302-1-brendanhiggins@google.com/
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
Cc: Joe Perches <joe@perches.com>
Cc: Tim.Bird@sony.com
Signed-off-by: Brendan Higgins <brendanhiggins@google.com>
Acked-by: Randy Dunlap <rdunlap@infradead.org> # build-tested
Reviewed-by: Petr Mladek <pmladek@suse.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2019-09-23 12:02:49 +03:00
pr_info ( " \t # Subtest: %s \n " , suite - > name ) ;
pr_info ( " \t 1..%zd \n " , kunit_test_cases_len ( suite - > test_cases ) ) ;
2019-09-23 12:02:31 +03:00
}
static void kunit_print_ok_not_ok ( bool should_indent ,
bool is_ok ,
size_t test_number ,
const char * description )
{
const char * indent , * ok_not_ok ;
if ( should_indent )
indent = " \t " ;
else
indent = " " ;
if ( is_ok )
ok_not_ok = " ok " ;
else
ok_not_ok = " not ok " ;
kunit: fix failure to build without printk
Previously KUnit assumed that printk would always be present, which is
not a valid assumption to make. Fix that by removing call to
vprintk_emit, and calling printk directly.
This fixes a build error[1] reported by Randy.
For context this change comes after much discussion. My first stab[2] at
this was just to make the KUnit logging code compile out; however, it
was agreed that if we were going to use vprintk_emit, then vprintk_emit
should provide a no-op stub, which lead to my second attempt[3]. In
response to me trying to stub out vprintk_emit, Sergey Senozhatsky
suggested a way for me to remove our usage of vprintk_emit, which led to
my third attempt at solving this[4].
In my third version of this patch[4], I completely removed vprintk_emit,
as suggested by Sergey; however, there was a bit of debate over whether
Sergey's solution was the best. The debate arose due to Sergey's version
resulting in a checkpatch warning, which resulted in a debate over
correct printk usage. Joe Perches offered an alternative fix which was
somewhat less far reaching than what Sergey had suggested and
importantly relied on continuing to use %pV. Much of the debated
centered around whether %pV should be widely used, and whether Sergey's
version would result in object size bloat. Ultimately, we decided to go
with Sergey's version.
Reported-by: Randy Dunlap <rdunlap@infradead.org>
Link[1]: https://lore.kernel.org/linux-kselftest/c7229254-0d90-d90e-f3df-5b6d6fc0b51f@infradead.org/
Link[2]: https://lore.kernel.org/linux-kselftest/20190827174932.44177-1-brendanhiggins@google.com/
Link[3]: https://lore.kernel.org/linux-kselftest/20190827234835.234473-1-brendanhiggins@google.com/
Link[4]: https://lore.kernel.org/linux-kselftest/20190828093143.163302-1-brendanhiggins@google.com/
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
Cc: Joe Perches <joe@perches.com>
Cc: Tim.Bird@sony.com
Signed-off-by: Brendan Higgins <brendanhiggins@google.com>
Acked-by: Randy Dunlap <rdunlap@infradead.org> # build-tested
Reviewed-by: Petr Mladek <pmladek@suse.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2019-09-23 12:02:49 +03:00
pr_info ( " %s%s %zd - %s \n " , indent , ok_not_ok , test_number , description ) ;
2019-09-23 12:02:31 +03:00
}
static bool kunit_suite_has_succeeded ( struct kunit_suite * suite )
{
const struct kunit_case * test_case ;
for ( test_case = suite - > test_cases ; test_case - > run_case ; test_case + + )
if ( ! test_case - > success )
return false ;
return true ;
}
static void kunit_print_subtest_end ( struct kunit_suite * suite )
{
static size_t kunit_suite_counter = 1 ;
kunit_print_ok_not_ok ( false ,
kunit_suite_has_succeeded ( suite ) ,
kunit_suite_counter + + ,
suite - > name ) ;
}
static void kunit_print_test_case_ok_not_ok ( struct kunit_case * test_case ,
size_t test_number )
{
kunit_print_ok_not_ok ( true ,
test_case - > success ,
test_number ,
test_case - > name ) ;
}
2019-09-23 12:02:35 +03:00
static void kunit_print_string_stream ( struct kunit * test ,
struct string_stream * stream )
{
struct string_stream_fragment * fragment ;
char * buf ;
buf = string_stream_get_string ( stream ) ;
if ( ! buf ) {
kunit_err ( test ,
" Could not allocate buffer, dumping stream: \n " ) ;
list_for_each_entry ( fragment , & stream - > fragments , node ) {
kunit: fix failure to build without printk
Previously KUnit assumed that printk would always be present, which is
not a valid assumption to make. Fix that by removing call to
vprintk_emit, and calling printk directly.
This fixes a build error[1] reported by Randy.
For context this change comes after much discussion. My first stab[2] at
this was just to make the KUnit logging code compile out; however, it
was agreed that if we were going to use vprintk_emit, then vprintk_emit
should provide a no-op stub, which lead to my second attempt[3]. In
response to me trying to stub out vprintk_emit, Sergey Senozhatsky
suggested a way for me to remove our usage of vprintk_emit, which led to
my third attempt at solving this[4].
In my third version of this patch[4], I completely removed vprintk_emit,
as suggested by Sergey; however, there was a bit of debate over whether
Sergey's solution was the best. The debate arose due to Sergey's version
resulting in a checkpatch warning, which resulted in a debate over
correct printk usage. Joe Perches offered an alternative fix which was
somewhat less far reaching than what Sergey had suggested and
importantly relied on continuing to use %pV. Much of the debated
centered around whether %pV should be widely used, and whether Sergey's
version would result in object size bloat. Ultimately, we decided to go
with Sergey's version.
Reported-by: Randy Dunlap <rdunlap@infradead.org>
Link[1]: https://lore.kernel.org/linux-kselftest/c7229254-0d90-d90e-f3df-5b6d6fc0b51f@infradead.org/
Link[2]: https://lore.kernel.org/linux-kselftest/20190827174932.44177-1-brendanhiggins@google.com/
Link[3]: https://lore.kernel.org/linux-kselftest/20190827234835.234473-1-brendanhiggins@google.com/
Link[4]: https://lore.kernel.org/linux-kselftest/20190828093143.163302-1-brendanhiggins@google.com/
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
Cc: Joe Perches <joe@perches.com>
Cc: Tim.Bird@sony.com
Signed-off-by: Brendan Higgins <brendanhiggins@google.com>
Acked-by: Randy Dunlap <rdunlap@infradead.org> # build-tested
Reviewed-by: Petr Mladek <pmladek@suse.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2019-09-23 12:02:49 +03:00
kunit_err ( test , " %s " , fragment - > fragment ) ;
2019-09-23 12:02:35 +03:00
}
kunit_err ( test , " \n " ) ;
} else {
kunit: fix failure to build without printk
Previously KUnit assumed that printk would always be present, which is
not a valid assumption to make. Fix that by removing call to
vprintk_emit, and calling printk directly.
This fixes a build error[1] reported by Randy.
For context this change comes after much discussion. My first stab[2] at
this was just to make the KUnit logging code compile out; however, it
was agreed that if we were going to use vprintk_emit, then vprintk_emit
should provide a no-op stub, which lead to my second attempt[3]. In
response to me trying to stub out vprintk_emit, Sergey Senozhatsky
suggested a way for me to remove our usage of vprintk_emit, which led to
my third attempt at solving this[4].
In my third version of this patch[4], I completely removed vprintk_emit,
as suggested by Sergey; however, there was a bit of debate over whether
Sergey's solution was the best. The debate arose due to Sergey's version
resulting in a checkpatch warning, which resulted in a debate over
correct printk usage. Joe Perches offered an alternative fix which was
somewhat less far reaching than what Sergey had suggested and
importantly relied on continuing to use %pV. Much of the debated
centered around whether %pV should be widely used, and whether Sergey's
version would result in object size bloat. Ultimately, we decided to go
with Sergey's version.
Reported-by: Randy Dunlap <rdunlap@infradead.org>
Link[1]: https://lore.kernel.org/linux-kselftest/c7229254-0d90-d90e-f3df-5b6d6fc0b51f@infradead.org/
Link[2]: https://lore.kernel.org/linux-kselftest/20190827174932.44177-1-brendanhiggins@google.com/
Link[3]: https://lore.kernel.org/linux-kselftest/20190827234835.234473-1-brendanhiggins@google.com/
Link[4]: https://lore.kernel.org/linux-kselftest/20190828093143.163302-1-brendanhiggins@google.com/
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
Cc: Joe Perches <joe@perches.com>
Cc: Tim.Bird@sony.com
Signed-off-by: Brendan Higgins <brendanhiggins@google.com>
Acked-by: Randy Dunlap <rdunlap@infradead.org> # build-tested
Reviewed-by: Petr Mladek <pmladek@suse.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2019-09-23 12:02:49 +03:00
kunit_err ( test , " %s " , buf ) ;
2019-09-23 12:02:35 +03:00
kunit_kfree ( test , buf ) ;
}
}
static void kunit_fail ( struct kunit * test , struct kunit_assert * assert )
{
struct string_stream * stream ;
kunit_set_failure ( test ) ;
stream = alloc_string_stream ( test , GFP_KERNEL ) ;
if ( ! stream ) {
WARN ( true ,
" Could not allocate stream to print failed assertion in %s:%d \n " ,
assert - > file ,
assert - > line ) ;
return ;
}
assert - > format ( assert , stream ) ;
kunit_print_string_stream ( test , stream ) ;
WARN_ON ( string_stream_destroy ( stream ) ) ;
}
2019-09-23 12:02:39 +03:00
static void __noreturn kunit_abort ( struct kunit * test )
{
kunit_try_catch_throw ( & test - > try_catch ) ; /* Does not return. */
/*
* Throw could not abort from test .
*
* XXX : we should never reach this line ! As kunit_try_catch_throw is
* marked __noreturn .
*/
WARN_ONCE ( true , " Throw could not abort from test! \n " ) ;
}
2019-09-23 12:02:35 +03:00
void kunit_do_assertion ( struct kunit * test ,
struct kunit_assert * assert ,
bool pass ,
const char * fmt , . . . )
{
va_list args ;
if ( pass )
return ;
va_start ( args , fmt ) ;
assert - > message . fmt = fmt ;
assert - > message . va = & args ;
kunit_fail ( test , assert ) ;
va_end ( args ) ;
2019-09-23 12:02:39 +03:00
if ( assert - > type = = KUNIT_ASSERTION )
kunit_abort ( test ) ;
2019-09-23 12:02:35 +03:00
}
2019-09-23 12:02:31 +03:00
void kunit_init_test ( struct kunit * test , const char * name )
{
2019-09-23 12:02:32 +03:00
spin_lock_init ( & test - > lock ) ;
INIT_LIST_HEAD ( & test - > resources ) ;
2019-09-23 12:02:31 +03:00
test - > name = name ;
test - > success = true ;
}
/*
2019-09-23 12:02:39 +03:00
* Initializes and runs test case . Does not clean up or do post validations .
2019-09-23 12:02:31 +03:00
*/
2019-09-23 12:02:39 +03:00
static void kunit_run_case_internal ( struct kunit * test ,
struct kunit_suite * suite ,
struct kunit_case * test_case )
2019-09-23 12:02:31 +03:00
{
if ( suite - > init ) {
int ret ;
2019-09-23 12:02:39 +03:00
ret = suite - > init ( test ) ;
2019-09-23 12:02:31 +03:00
if ( ret ) {
2019-09-23 12:02:39 +03:00
kunit_err ( test , " failed to initialize: %d \n " , ret ) ;
kunit_set_failure ( test ) ;
2019-09-23 12:02:31 +03:00
return ;
}
}
2019-09-23 12:02:39 +03:00
test_case - > run_case ( test ) ;
}
static void kunit_case_internal_cleanup ( struct kunit * test )
{
kunit_cleanup ( test ) ;
}
2019-09-23 12:02:31 +03:00
2019-09-23 12:02:39 +03:00
/*
* Performs post validations and cleanup after a test case was run .
* XXX : Should ONLY BE CALLED AFTER kunit_run_case_internal !
*/
static void kunit_run_case_cleanup ( struct kunit * test ,
struct kunit_suite * suite )
{
2019-09-23 12:02:31 +03:00
if ( suite - > exit )
2019-09-23 12:02:39 +03:00
suite - > exit ( test ) ;
kunit_case_internal_cleanup ( test ) ;
}
struct kunit_try_catch_context {
struct kunit * test ;
struct kunit_suite * suite ;
struct kunit_case * test_case ;
} ;
static void kunit_try_run_case ( void * data )
{
struct kunit_try_catch_context * ctx = data ;
struct kunit * test = ctx - > test ;
struct kunit_suite * suite = ctx - > suite ;
struct kunit_case * test_case = ctx - > test_case ;
/*
* kunit_run_case_internal may encounter a fatal error ; if it does ,
* abort will be called , this thread will exit , and finally the parent
* thread will resume control and handle any necessary clean up .
*/
kunit_run_case_internal ( test , suite , test_case ) ;
/* This line may never be reached. */
kunit_run_case_cleanup ( test , suite ) ;
}
static void kunit_catch_run_case ( void * data )
{
struct kunit_try_catch_context * ctx = data ;
struct kunit * test = ctx - > test ;
struct kunit_suite * suite = ctx - > suite ;
int try_exit_code = kunit_try_catch_get_result ( & test - > try_catch ) ;
if ( try_exit_code ) {
kunit_set_failure ( test ) ;
/*
* Test case could not finish , we have no idea what state it is
* in , so don ' t do clean up .
*/
if ( try_exit_code = = - ETIMEDOUT ) {
kunit_err ( test , " test case timed out \n " ) ;
/*
* Unknown internal error occurred preventing test case from
* running , so there is nothing to clean up .
*/
} else {
kunit_err ( test , " internal error occurred preventing test case from running: %d \n " ,
try_exit_code ) ;
}
return ;
}
/*
* Test case was run , but aborted . It is the test case ' s business as to
* whether it failed or not , we just need to clean up .
*/
kunit_run_case_cleanup ( test , suite ) ;
}
/*
* Performs all logic to run a test case . It also catches most errors that
* occur in a test case and reports them as failures .
*/
static void kunit_run_case_catch_errors ( struct kunit_suite * suite ,
struct kunit_case * test_case )
{
struct kunit_try_catch_context context ;
struct kunit_try_catch * try_catch ;
struct kunit test ;
kunit_init_test ( & test , test_case - > name ) ;
try_catch = & test . try_catch ;
2019-09-23 12:02:31 +03:00
2019-09-23 12:02:39 +03:00
kunit_try_catch_init ( try_catch ,
& test ,
kunit_try_run_case ,
kunit_catch_run_case ) ;
context . test = & test ;
context . suite = suite ;
context . test_case = test_case ;
kunit_try_catch_run ( try_catch , & context ) ;
2019-09-23 12:02:32 +03:00
2019-09-23 12:02:31 +03:00
test_case - > success = test . success ;
}
int kunit_run_tests ( struct kunit_suite * suite )
{
struct kunit_case * test_case ;
size_t test_case_count = 1 ;
kunit_print_subtest_start ( suite ) ;
for ( test_case = suite - > test_cases ; test_case - > run_case ; test_case + + ) {
2019-09-23 12:02:39 +03:00
kunit_run_case_catch_errors ( suite , test_case ) ;
2019-09-23 12:02:31 +03:00
kunit_print_test_case_ok_not_ok ( test_case , test_case_count + + ) ;
}
kunit_print_subtest_end ( suite ) ;
return 0 ;
}
2019-09-23 12:02:32 +03:00
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 )
{
struct kunit_resource * res ;
int ret ;
res = kzalloc ( sizeof ( * res ) , internal_gfp ) ;
if ( ! res )
return NULL ;
ret = init ( res , context ) ;
if ( ret )
return NULL ;
res - > free = free ;
spin_lock ( & test - > lock ) ;
list_add_tail ( & res - > node , & test - > resources ) ;
spin_unlock ( & test - > lock ) ;
return res ;
}
static void kunit_resource_free ( struct kunit * test , struct kunit_resource * res )
{
res - > free ( res ) ;
kfree ( res ) ;
}
static struct kunit_resource * kunit_resource_find ( struct kunit * test ,
kunit_resource_match_t match ,
kunit_resource_free_t free ,
void * match_data )
{
struct kunit_resource * resource ;
lockdep_assert_held ( & test - > lock ) ;
list_for_each_entry_reverse ( resource , & test - > resources , node ) {
if ( resource - > free ! = free )
continue ;
if ( match ( test , resource - > allocation , match_data ) )
return resource ;
}
return NULL ;
}
static struct kunit_resource * kunit_resource_remove (
struct kunit * test ,
kunit_resource_match_t match ,
kunit_resource_free_t free ,
void * match_data )
{
struct kunit_resource * resource ;
spin_lock ( & test - > lock ) ;
resource = kunit_resource_find ( test , match , free , match_data ) ;
if ( resource )
list_del ( & resource - > node ) ;
spin_unlock ( & test - > lock ) ;
return resource ;
}
int kunit_resource_destroy ( struct kunit * test ,
kunit_resource_match_t match ,
kunit_resource_free_t free ,
void * match_data )
{
struct kunit_resource * resource ;
resource = kunit_resource_remove ( test , match , free , match_data ) ;
if ( ! resource )
return - ENOENT ;
kunit_resource_free ( test , resource ) ;
return 0 ;
}
struct kunit_kmalloc_params {
size_t size ;
gfp_t gfp ;
} ;
static int kunit_kmalloc_init ( struct kunit_resource * res , void * context )
{
struct kunit_kmalloc_params * params = context ;
res - > allocation = kmalloc ( params - > size , params - > gfp ) ;
if ( ! res - > allocation )
return - ENOMEM ;
return 0 ;
}
static void kunit_kmalloc_free ( struct kunit_resource * res )
{
kfree ( res - > allocation ) ;
}
void * kunit_kmalloc ( struct kunit * test , size_t size , gfp_t gfp )
{
struct kunit_kmalloc_params params = {
. size = size ,
. gfp = gfp
} ;
return kunit_alloc_resource ( test ,
kunit_kmalloc_init ,
kunit_kmalloc_free ,
gfp ,
& params ) ;
}
void kunit_kfree ( struct kunit * test , const void * ptr )
{
int rc ;
rc = kunit_resource_destroy ( test ,
kunit_resource_instance_match ,
kunit_kmalloc_free ,
( void * ) ptr ) ;
WARN_ON ( rc ) ;
}
void kunit_cleanup ( struct kunit * test )
{
struct kunit_resource * resource ;
/*
* test - > resources is a stack - each allocation must be freed in the
* reverse order from which it was added since one resource may depend
* on another for its entire lifetime .
* Also , we cannot use the normal list_for_each constructs , even the
* safe ones because * arbitrary * nodes may be deleted when
* kunit_resource_free is called ; the list_for_each_safe variants only
* protect against the current node being deleted , not the next .
*/
while ( true ) {
spin_lock ( & test - > lock ) ;
if ( list_empty ( & test - > resources ) ) {
spin_unlock ( & test - > lock ) ;
break ;
}
resource = list_last_entry ( & test - > resources ,
struct kunit_resource ,
node ) ;
list_del ( & resource - > node ) ;
spin_unlock ( & test - > lock ) ;
kunit_resource_free ( test , resource ) ;
}
}