1f5206d3fSRandall Stewart.\" 252467047SWarner Losh.\" Copyright (c) 2015 Netflix, Inc. 3f5206d3fSRandall Stewart.\" 4f5206d3fSRandall Stewart.\" Redistribution and use in source and binary forms, with or without 5f5206d3fSRandall Stewart.\" modification, are permitted provided that the following conditions 6f5206d3fSRandall Stewart.\" are met: 7f5206d3fSRandall Stewart.\" 1. Redistributions of source code must retain the above copyright 8f5206d3fSRandall Stewart.\" notice, this list of conditions and the following disclaimer. 9f5206d3fSRandall Stewart.\" 2. Redistributions in binary form must reproduce the above copyright 10f5206d3fSRandall Stewart.\" notice, this list of conditions and the following disclaimer in the 11f5206d3fSRandall Stewart.\" documentation and/or other materials provided with the distribution. 12f5206d3fSRandall Stewart.\" 13f5206d3fSRandall Stewart.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR 14f5206d3fSRandall Stewart.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15f5206d3fSRandall Stewart.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16f5206d3fSRandall Stewart.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, 17f5206d3fSRandall Stewart.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18f5206d3fSRandall Stewart.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19f5206d3fSRandall Stewart.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20f5206d3fSRandall Stewart.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21f5206d3fSRandall Stewart.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22f5206d3fSRandall Stewart.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23f5206d3fSRandall Stewart.\" 241d63d4c8SConrad Meyer.Dd November 12, 2015 251d63d4c8SConrad Meyer.Dt KERN_TESTFRWK 9 26f5206d3fSRandall Stewart.Os 27f5206d3fSRandall Stewart.Sh NAME 28f5206d3fSRandall Stewart.Nm kern_testfrwk 291d63d4c8SConrad Meyer.Nd A kernel testing framework 30f5206d3fSRandall Stewart.Sh SYNOPSIS 31*ca93db79SNavdeep Parharkldload kern_testfrwk 32f5206d3fSRandall Stewart.Sh DESCRIPTION 331d63d4c8SConrad Meyer.\" This whole section is not written in manual page style and should be ripped 341d63d4c8SConrad Meyer.\" out and replaced. -CEM 35f5206d3fSRandall StewartSo what is this sys/tests directory in the kernel all about? 36f5206d3fSRandall Stewart.Pp 3755ed6718SBenedict ReuschlingHave you ever wanted to test a part of the 3855ed6718SBenedict Reuschling.Fx 3955ed6718SBenedict Reuschlingkernel in some way and you 401d63d4c8SConrad Meyerhad no real way from user-land to make what you want to occur happen? 411d63d4c8SConrad MeyerSay an error path or situation where locking occurs in a particular manner that 421d63d4c8SConrad Meyerhappens only once in a blue moon? 43f5206d3fSRandall Stewart.Pp 441d63d4c8SConrad MeyerIf so, then the kernel test framework is just what you are looking for. 451d63d4c8SConrad MeyerIt is designed to help you create the situation you want. 46f5206d3fSRandall Stewart.Pp 471d63d4c8SConrad MeyerThere are two components to the system: the test framework and your test. 481d63d4c8SConrad MeyerThis document will describe both components and use the test submitted with the 491d63d4c8SConrad Meyerinitial commit of this code to discuss the test 501d63d4c8SConrad Meyer.Xr ( callout_test 4 ) . 511d63d4c8SConrad MeyerAll of the tests become kernel loadable modules. 521d63d4c8SConrad MeyerThe test you write should have a dependency on the test framework. 531d63d4c8SConrad MeyerThat way it will be loaded automatically with your test. 541d63d4c8SConrad MeyerFor example, you can see how to do this in the bottom of callout_test.c in 551d63d4c8SConrad Meyer.Pa sys/tests/callout_test/callout_test.c . 56f5206d3fSRandall Stewart.Pp 571d63d4c8SConrad MeyerThe framework itself is in 581d63d4c8SConrad Meyer.Pa sys/tests/framework/kern_testfrwk.c . 591d63d4c8SConrad MeyerIts job is to manage the tests that are loaded. 601d63d4c8SConrad Meyer(More than one can be loaded.) 611d63d4c8SConrad MeyerThe idea is pretty simple; you load the test framework and then load your test. 62f5206d3fSRandall Stewart.Pp 631d63d4c8SConrad MeyerWhen your test loads, you register your tests with the kernel test framework. 641d63d4c8SConrad MeyerYou do that through a call to 651d63d4c8SConrad Meyer.Fn kern_testframework_register . 66f5206d3fSRandall StewartUsually this is done at the module load event as shown below: 67f5206d3fSRandall Stewart.Bd -literal -offset indent 68f5206d3fSRandall Stewart switch (type) { 69f5206d3fSRandall Stewart case MOD_LOAD: 70f5206d3fSRandall Stewart err = kern_testframework_register("callout_test", 71f5206d3fSRandall Stewart run_callout_test); 72f5206d3fSRandall Stewart.Ed 73f5206d3fSRandall Stewart.Pp 741d63d4c8SConrad MeyerHere the test is "callout_test" and it is registered to run the function 75f5206d3fSRandall Stewart.Fn run_callout_test 76f5206d3fSRandall Stewartpassing it a 771d63d4c8SConrad Meyer.Fa struct kern_test *ptr . 781d63d4c8SConrad MeyerThe 791d63d4c8SConrad Meyer.Vt kern_test 801d63d4c8SConrad Meyerstructure is defined in 811d63d4c8SConrad Meyer.Pa kern_testfrwk.h . 82f5206d3fSRandall Stewart.Bd -literal -offset indent 83f5206d3fSRandall Stewartstruct kern_test { 84f5206d3fSRandall Stewart char name[TEST_NAME_LEN]; 85f5206d3fSRandall Stewart int num_threads; /* Fill in how many threads you want */ 861d63d4c8SConrad Meyer int tot_threads_running; /* Private to framework */ 87f5206d3fSRandall Stewart uint8_t test_options[TEST_OPTION_SPACE]; 88f5206d3fSRandall Stewart}; 89f5206d3fSRandall Stewart.Ed 90f5206d3fSRandall Stewart.Pp 911d63d4c8SConrad MeyerThe user sends this structure down via a sysctl to start your test. 921d63d4c8SConrad MeyerHe or she places the same name you registered ("callout_test" 931d63d4c8SConrad Meyerin our example) in the 941d63d4c8SConrad Meyer.Va name 951d63d4c8SConrad Meyerfield. 961d63d4c8SConrad MeyerThe user can also set the number of threads to run with 971d63d4c8SConrad Meyer.Va num_threads . 98f5206d3fSRandall Stewart.Pp 991d63d4c8SConrad MeyerThe framework will start the requested number of kernel threads, all running 1001d63d4c8SConrad Meyeryour test at the same time. 1011d63d4c8SConrad MeyerThe user does not specify anything in 1021d63d4c8SConrad Meyer.Va tot_threads_running ; 1031d63d4c8SConrad Meyerit is private to the framework. 1041d63d4c8SConrad MeyerAs the framework calls each of your tests, it will set the 1051d63d4c8SConrad Meyer.Va tot_threads_running 1061d63d4c8SConrad Meyerto the index of the thread that your call is made from. 1071d63d4c8SConrad MeyerFor example, if the user sets 1081d63d4c8SConrad Meyer.Va num_threads 1091d63d4c8SConrad Meyerto 2, then the function 1101d63d4c8SConrad Meyer.Fn run_callout_test 1111d63d4c8SConrad Meyerwill be called once with 1121d63d4c8SConrad Meyer.Va tot_threads_running 113f5206d3fSRandall Stewartto 0, and a second time with 1141d63d4c8SConrad Meyer.Va tot_threads_running 115f5206d3fSRandall Stewartset to 1. 116f5206d3fSRandall Stewart.Pp 117f5206d3fSRandall StewartThe 1181d63d4c8SConrad Meyer.Va test_options 1191d63d4c8SConrad Meyerfield is a test-specific set of information that is an opaque blob. 1201d63d4c8SConrad MeyerIt is passed in from user space and has a maximum size of 256 bytes. 1211d63d4c8SConrad MeyerYou can pass arbitrary test input in the space. 122f5206d3fSRandall StewartIn the case of callout_test we reshape that to: 123f5206d3fSRandall Stewart.Bd -literal -offset indent 124f5206d3fSRandall Stewartstruct callout_test { 125f5206d3fSRandall Stewart int number_of_callouts; 126f5206d3fSRandall Stewart int test_number; 127f5206d3fSRandall Stewart}; 128f5206d3fSRandall Stewart.Ed 129f5206d3fSRandall Stewart.Pp 130f5206d3fSRandall StewartSo the first lines of 1311d63d4c8SConrad Meyer.Fn run_callout_test 132f5206d3fSRandall Stewartdoes the following to get at the user specific data: 1331d63d4c8SConrad Meyer.\" This is a bad example and violates strict aliasing. It should be replaced. 134f5206d3fSRandall Stewart.Bd -literal -offset indent 135f5206d3fSRandall Stewart struct callout_test *u; 136f5206d3fSRandall Stewart size_t sz; 137f5206d3fSRandall Stewart int i; 138f5206d3fSRandall Stewart struct callout_run *rn; 139f5206d3fSRandall Stewart int index = test->tot_threads_running; 140f5206d3fSRandall Stewart 141f5206d3fSRandall Stewart u = (struct callout_test *)test->test_options; 142f5206d3fSRandall Stewart.Ed 143f5206d3fSRandall Stewart.Pp 144f5206d3fSRandall StewartThat way it can access: 1451d63d4c8SConrad Meyer.Va u->test_number 1461d63d4c8SConrad Meyer(there are two types of tests provided with this test) 147f5206d3fSRandall Stewartand 1481d63d4c8SConrad Meyer.Va u->number_of_callouts 1491d63d4c8SConrad Meyer(how many simultaneous callouts to run). 150f5206d3fSRandall Stewart.Pp 1511d63d4c8SConrad MeyerYour test can do anything with these bytes. 1521d63d4c8SConrad MeyerSo the callout_test in question wants to create a situation where multiple 1531d63d4c8SConrad Meyercallouts are all run, that is the 1541d63d4c8SConrad Meyer.Va number_of_callouts , 1551d63d4c8SConrad Meyerand it tries to cancel the callout with the new 1561d63d4c8SConrad Meyer.Fn callout_async_drain . 1571d63d4c8SConrad MeyerThe threads do this by acquiring the lock in question, and then 1581d63d4c8SConrad Meyerstarting each of the callouts. 1591d63d4c8SConrad MeyerIt waits for the callouts to all go off (the executor spins waits). 1601d63d4c8SConrad MeyerThis forces the situation that the callouts have expired and are all waiting on 1611d63d4c8SConrad Meyerthe lock that the executor holds. 1621d63d4c8SConrad MeyerAfter the callouts are all blocked, the executor calls 163f5206d3fSRandall Stewart.Fn callout_async_drain 1641d63d4c8SConrad Meyeron each callout and releases the lock. 165f5206d3fSRandall Stewart.Pp 1661d63d4c8SConrad Meyer.\" callout_test(4) specific documentation should probably be moved to its own 1671d63d4c8SConrad Meyer.\" page. 168f5206d3fSRandall StewartAfter all the callouts are done, a total status is printed 1691d63d4c8SConrad Meyershowing the results via 1701d63d4c8SConrad Meyer.Xr printf 9 . 1711d63d4c8SConrad MeyerThe human tester can run 1721d63d4c8SConrad Meyer.Xr dmesg 8 1731d63d4c8SConrad Meyerto see the results. 1741d63d4c8SConrad MeyerIn this case it is expected that if you are running test 0, all the callouts 1751d63d4c8SConrad Meyerexpire on the same CPU so only one callout_drain function would have been 1761d63d4c8SConrad Meyercalled. 1771d63d4c8SConrad Meyerthe number of zero_returns should match the number of callout_drains that were 1781d63d4c8SConrad Meyercalled, i.e., 1. 1791d63d4c8SConrad MeyerThe one_returns should be the remainder of the callouts. 1801d63d4c8SConrad MeyerIf the test number was 1, the callouts were spread across all CPUs. 1811d63d4c8SConrad MeyerThe number of zero_returns will again match the number of drain calls made 1821d63d4c8SConrad Meyerwhich matches the number of CPUs that were put in use. 183f5206d3fSRandall Stewart.Pp 1841d63d4c8SConrad MeyerMore than one thread can be used with this test, though in the example case it 1851d63d4c8SConrad Meyeris probably not necessary. 186f5206d3fSRandall Stewart.Pp 1871d63d4c8SConrad MeyerYou should not need to change the framework. 1881d63d4c8SConrad MeyerJust add tests and register them after loading. 189f5206d3fSRandall Stewart.Sh AUTHORS 1901d63d4c8SConrad MeyerThe kernel test framework was written by 1911d63d4c8SConrad Meyer.An Randall Stewart Aq Mt rrs@FreeBSD.org 1921d63d4c8SConrad Meyerwith help from 1931d63d4c8SConrad Meyer.An John Mark Gurney Aq Mt jmg@FreeBSD.org . 194