Provided by: freebsd-manpages_12.2-1_all bug

NAME

       kern_testfrwk — A kernel testing framework

SYNOPSIS

       kld_load kern_testfrwk

DESCRIPTION

       So what is this sys/tests directory in the kernel all about?

       Have  you ever wanted to test a part of the FreeBSD kernel in some way and you had no real way from user-
       land to make what you want to occur happen?  Say an error path or situation where  locking  occurs  in  a
       particular manner that happens only once in a blue moon?

       If  so,  then  the  kernel  test  framework is just what you are looking for.  It is designed to help you
       create the situation you want.

       There are two components to the system: the test framework and your test.  This  document  will  describe
       both  components  and  use  the  test  submitted with the initial commit of this code to discuss the test
       (callout_test(4)).  All of the tests become kernel loadable modules.  The test you write  should  have  a
       dependency on the test framework.  That way it will be loaded automatically with your test.  For example,
       you can see how to do this in the bottom of callout_test.c in sys/tests/callout_test/callout_test.c.

       The  framework itself is in sys/tests/framework/kern_testfrwk.c.  Its job is to manage the tests that are
       loaded.  (More than one can be loaded.)  The idea is pretty simple; you load the test framework and  then
       load your test.

       When your test loads, you register your tests with the kernel test framework.  You do that through a call
       to kern_testframework_register().  Usually this is done at the module load event as shown below:

                     switch (type) {
                     case MOD_LOAD:
                             err = kern_testframework_register("callout_test",
                                 run_callout_test);

       Here  the test is "callout_test" and it is registered to run the function run_callout_test() passing it a
       struct kern_test *ptr.  The kern_test structure is defined in kern_testfrwk.h.

             struct kern_test {
                     char name[TEST_NAME_LEN];
                     int num_threads;  /* Fill in how many threads you want */
                     int tot_threads_running;       /* Private to framework */
                     uint8_t test_options[TEST_OPTION_SPACE];
             };

       The user sends this structure down via a sysctl to start your test.  He or she places the same  name  you
       registered  ("callout_test"  in  our  example)  in  the  name field.  The user can also set the number of
       threads to run with num_threads.

       The framework will start the requested number of kernel threads, all running your test at the same  time.
       The  user  does  not  specify  anything  in  tot_threads_running; it is private to the framework.  As the
       framework calls each of your tests, it will set the tot_threads_running to the index of the  thread  that
       your  call  is  made  from.   For  example,  if  the  user  sets  num_threads  to  2,  then  the function
       run_callout_test()  will  be  called  once  with  tot_threads_running  to  0,  and  a  second  time  with
       tot_threads_running set to 1.

       The  test_options  field  is  a test-specific set of information that is an opaque blob.  It is passed in
       from user space and has a maximum size of 256 bytes.  You can pass arbitrary test input in the space.  In
       the case of callout_test we reshape that to:

             struct callout_test {
                     int number_of_callouts;
                     int test_number;
             };

       So the first lines of run_callout_test() does the following to get at the user specific data:

                     struct callout_test *u;
                     size_t sz;
                     int i;
                     struct callout_run *rn;
                     int index = test->tot_threads_running;

                     u = (struct callout_test *)test->test_options;

       That way it can access: u->test_number (there are two  types  of  tests  provided  with  this  test)  and
       u->number_of_callouts (how many simultaneous callouts to run).

       Your  test can do anything with these bytes.  So the callout_test in question wants to create a situation
       where multiple callouts are all run, that is the number_of_callouts, and it tries to cancel  the  callout
       with  the  new  callout_async_drain().   The  threads do this by acquiring the lock in question, and then
       starting each of the callouts.  It waits for the callouts to all go off (the executor spins waits).  This
       forces the situation that the callouts have expired and are all waiting on the  lock  that  the  executor
       holds.   After the callouts are all blocked, the executor calls callout_async_drain() on each callout and
       releases the lock.

       After all the callouts are done, a total status is printed showing the results via printf(9).  The  human
       tester  can run dmesg(8) to see the results.  In this case it is expected that if you are running test 0,
       all the callouts expire on the same CPU so only one callout_drain function would have been  called.   the
       number  of  zero_returns  should  match  the  number  of  callout_drains  that were called, i.e., 1.  The
       one_returns should be the remainder of the callouts.  If the test number was 1, the callouts were  spread
       across  all  CPUs.   The  number  of  zero_returns  will again match the number of drain calls made which
       matches the number of CPUs that were put in use.

       More than one thread can be used with this test, though in the example case it is probably not necessary.

       You should not need to change the framework.  Just add tests and register them after loading.

AUTHORS

       The kernel test framework was written by Randall Stewart <rrs@FreeBSD.org> with help from
       John Mark Gurney <jmg@FreeBSD.org>.

Debian                                          November 12, 2015                               KERN_TESTFRWK(9)