Date: Thu, 12 Nov 2015 18:42:07 +0000 (UTC) From: "Conrad E. Meyer" <cem@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r290724 - head/share/man/man9 Message-ID: <201511121842.tACIg7hu028513@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: cem Date: Thu Nov 12 18:42:06 2015 New Revision: 290724 URL: https://svnweb.freebsd.org/changeset/base/290724 Log: kern_testfrwk.9: Clean up manual page style Igor has many less complaints now. I think the two remaining are bogus, but I am also not sure why Igor is producing them. The page still needs more work. Sponsored by: EMC / Isilon Storage Division Modified: head/share/man/man9/kern_testfrwk.9 Modified: head/share/man/man9/kern_testfrwk.9 ============================================================================== --- head/share/man/man9/kern_testfrwk.9 Thu Nov 12 18:10:34 2015 (r290723) +++ head/share/man/man9/kern_testfrwk.9 Thu Nov 12 18:42:06 2015 (r290724) @@ -24,45 +24,46 @@ .\" .\" $FreeBSD$ .\" -.Dd Novmember 10, 2015 -.Dt KERN_TESTFRWK +.Dd November 12, 2015 +.Dt KERN_TESTFRWK 9 .Os .Sh NAME .Nm kern_testfrwk +.Nd A kernel testing framework .Sh SYNOPSIS kld_load kern_testfrwk .Sh DESCRIPTION +.\" This whole section is not written in manual page style and should be ripped +.\" out and replaced. -CEM So what is this sys/tests directory in the kernel all about? .Pp -Have you ever wanted to test a part of the FreeBSD kernel in -some way and you have 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? -.Pp -If so then the kernel test framework is just what you are -looking for. Its designed to help you create the situation -you want. -.Pp -There are two components to the system, the test-framework -and your-test. This document will talk about both components -and use the one test submitted with the initial commit of -this code to discuss the test (callout_test). All of the -tests become kernel loadable modules. The test you write -should have a dependancy on the test-framework, that way -it will be loaded automatically with your test. You can see -how to do this in the bottom of the callout_test.c in -sys/tests/callout_test/callout_test.c (thats the example test). -.Pp -The framework itself is in sys/tests/framework/kern_testfrwk.c. Its -job is to manage the test's that are loaded, yes more than -one can be loaded. The idea is pretty simple, you load -the test framework and then load your test. -.Pp -So when your test loads, you register your tests with the -kernel-test framework. You do that through a call to -.Fn kern_testframework_register -.Pp +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? +.Pp +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. +.Pp +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 +.Xr ( 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 +.Pa sys/tests/callout_test/callout_test.c . +.Pp +The framework itself is in +.Pa 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. +.Pp +When your test loads, you register your tests with the kernel test framework. +You do that through a call to +.Fn kern_testframework_register . Usually this is done at the module load event as shown below: .Pp .Bd -literal -offset indent @@ -72,51 +73,54 @@ Usually this is done at the module load run_callout_test); .Ed .Pp -Here the test is "callout_test" and is registered to run the function +Here the test is "callout_test" and it is registered to run the function .Fn run_callout_test passing it a -.Fa struct kern_test *ptr -The kern_test structure is -a structure as defined in kern_testfrwk.h +.Fa struct kern_test *ptr . +The +.Vt kern_test +structure is defined in +.Pa kern_testfrwk.h . .Bd -literal -offset indent struct kern_test { char name[TEST_NAME_LEN]; - int num_threads; /* Fill in how many threads you want */ - int tot_threads_running; /* For framework */ + int num_threads; /* Fill in how many threads you want */ + int tot_threads_running; /* Private to framework */ uint8_t test_options[TEST_OPTION_SPACE]; }; .Ed .Pp -The user sends this structure down via a sysctl to start your -test running he or she places the same name you registered, "callout_test" -in our example, in the -.Fa name -field. The user can also set the -number of threads to run by putting that in -.Fa num_threads. -.Pp -The framework will start that many kernel threads all running your test -at the same time. The user does not specify anything in -.Fa tot_threads_running -(the framework uses that). As the framework calls each one of -your tests it will set the -.Fa tot_threads_running -to the index -of the thread that your call is made from. So for example if the user -sets -.Fa num_threads -to two, then the function run_callout_test() will -be called once with -.Fa tot_threads_running +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 +.Va name +field. +The user can also set the number of threads to run with +.Va num_threads . +.Pp +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 +.Va tot_threads_running ; +it is private to the framework. +As the framework calls each of your tests, it will set the +.Va tot_threads_running +to the index of the thread that your call is made from. +For example, if the user sets +.Va num_threads +to 2, then the function +.Fn run_callout_test +will be called once with +.Va tot_threads_running to 0, and a second time with -.Fa tot_threads_running +.Va tot_threads_running set to 1. .Pp The -.Fa test_options -field is a test-specific set of information that -is an opaque glob that is passed in from user space (a max of 256 bytes) -that you reshape to what input your test wants. +.Va 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: .Pp .Bd -literal -offset indent @@ -127,11 +131,11 @@ struct callout_test { .Ed .Pp So the first lines of -.Fn run_callout_test() +.Fn run_callout_test does the following to get at the user specific data: .Pp +.\" This is a bad example and violates strict aliasing. It should be replaced. .Bd -literal -offset indent -{ struct callout_test *u; size_t sz; int i; @@ -142,47 +146,52 @@ does the following to get at the user sp .Ed .Pp That way it can access: -.Bd -literal - u->test_number (there are two types of tests provided with this test) +.Va u->test_number +(there are two types of tests provided with this test) and - u->number_of_callouts (how many simultaneous callouts to run). -.Ed +.Va u->number_of_callouts +(how many simultaneous callouts to run). .Pp -Your test can of course do anything it wants with these bytes, they -may not even use them (they are optional). So the callout_test in -question wants to create a situation where multiple callouts are -all run, thats the -.Fa number_of_callouts -, and it try's to cancel -the callout with the new -.Fn callout_async_drain -feature. The threads do -this by the test executor getting the lock in question, and then -starting each of the callouts waiting for the callouts to -all go off (the executor spins waits). This forces the situation that -the callout's have expired and are all waiting on the lock that -the executor holds. After the callouts are all -blocked, the executor then calls the new function +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 +.Va number_of_callouts , +and it tries to cancel the callout with the new +.Fn 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 .Fn callout_async_drain -on each callout and then releases the lock. +on each callout and releases the lock. .Pp +.\" callout_test(4) specific documentation should probably be moved to its own +.\" page. After all the callouts are done, a total status is printed -showing the results via printf. The human tester then can run dmesg -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 then -only one callout_drain function would have been called. And -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 CPU's. So that the number of zero_returns will -again match the number of drain calls made which matches the number -of CPU's that were put in use. +showing the results via +.Xr printf 9 . +The human tester can run +.Xr 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. .Pp -More than one thread can be used with this test, though in the -example case its probably not necessary. +More than one thread can be used with this test, though in the example case it +is probably not necessary. .Pp -You should not need to change the framework -just add tests and register them after loading. +You should not need to change the framework. +Just add tests and register them after loading. .Sh AUTHORS -The kernel test framework was written by Randall Stewart rrs@freebsd.org -with help from John Mark Gurney jmg@freebsd.org +The kernel test framework was written by +.An Randall Stewart Aq Mt rrs@FreeBSD.org +with help from +.An John Mark Gurney Aq Mt jmg@FreeBSD.org .
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201511121842.tACIg7hu028513>