1*37002bc6SCosta Shulyupin================== 2*37002bc6SCosta ShulyupinS390 Debug Feature 3*37002bc6SCosta Shulyupin================== 4*37002bc6SCosta Shulyupin 5*37002bc6SCosta Shulyupinfiles: 6*37002bc6SCosta Shulyupin - arch/s390/kernel/debug.c 7*37002bc6SCosta Shulyupin - arch/s390/include/asm/debug.h 8*37002bc6SCosta Shulyupin 9*37002bc6SCosta ShulyupinDescription: 10*37002bc6SCosta Shulyupin------------ 11*37002bc6SCosta ShulyupinThe goal of this feature is to provide a kernel debug logging API 12*37002bc6SCosta Shulyupinwhere log records can be stored efficiently in memory, where each component 13*37002bc6SCosta Shulyupin(e.g. device drivers) can have one separate debug log. 14*37002bc6SCosta ShulyupinOne purpose of this is to inspect the debug logs after a production system crash 15*37002bc6SCosta Shulyupinin order to analyze the reason for the crash. 16*37002bc6SCosta Shulyupin 17*37002bc6SCosta ShulyupinIf the system still runs but only a subcomponent which uses dbf fails, 18*37002bc6SCosta Shulyupinit is possible to look at the debug logs on a live system via the Linux 19*37002bc6SCosta Shulyupindebugfs filesystem. 20*37002bc6SCosta Shulyupin 21*37002bc6SCosta ShulyupinThe debug feature may also very useful for kernel and driver development. 22*37002bc6SCosta Shulyupin 23*37002bc6SCosta ShulyupinDesign: 24*37002bc6SCosta Shulyupin------- 25*37002bc6SCosta ShulyupinKernel components (e.g. device drivers) can register themselves at the debug 26*37002bc6SCosta Shulyupinfeature with the function call :c:func:`debug_register()`. 27*37002bc6SCosta ShulyupinThis function initializes a 28*37002bc6SCosta Shulyupindebug log for the caller. For each debug log exists a number of debug areas 29*37002bc6SCosta Shulyupinwhere exactly one is active at one time. Each debug area consists of contiguous 30*37002bc6SCosta Shulyupinpages in memory. In the debug areas there are stored debug entries (log records) 31*37002bc6SCosta Shulyupinwhich are written by event- and exception-calls. 32*37002bc6SCosta Shulyupin 33*37002bc6SCosta ShulyupinAn event-call writes the specified debug entry to the active debug 34*37002bc6SCosta Shulyupinarea and updates the log pointer for the active area. If the end 35*37002bc6SCosta Shulyupinof the active debug area is reached, a wrap around is done (ring buffer) 36*37002bc6SCosta Shulyupinand the next debug entry will be written at the beginning of the active 37*37002bc6SCosta Shulyupindebug area. 38*37002bc6SCosta Shulyupin 39*37002bc6SCosta ShulyupinAn exception-call writes the specified debug entry to the log and 40*37002bc6SCosta Shulyupinswitches to the next debug area. This is done in order to be sure 41*37002bc6SCosta Shulyupinthat the records which describe the origin of the exception are not 42*37002bc6SCosta Shulyupinoverwritten when a wrap around for the current area occurs. 43*37002bc6SCosta Shulyupin 44*37002bc6SCosta ShulyupinThe debug areas themselves are also ordered in form of a ring buffer. 45*37002bc6SCosta ShulyupinWhen an exception is thrown in the last debug area, the following debug 46*37002bc6SCosta Shulyupinentries are then written again in the very first area. 47*37002bc6SCosta Shulyupin 48*37002bc6SCosta ShulyupinThere are four versions for the event- and exception-calls: One for 49*37002bc6SCosta Shulyupinlogging raw data, one for text, one for numbers (unsigned int and long), 50*37002bc6SCosta Shulyupinand one for sprintf-like formatted strings. 51*37002bc6SCosta Shulyupin 52*37002bc6SCosta ShulyupinEach debug entry contains the following data: 53*37002bc6SCosta Shulyupin 54*37002bc6SCosta Shulyupin- Timestamp 55*37002bc6SCosta Shulyupin- Cpu-Number of calling task 56*37002bc6SCosta Shulyupin- Level of debug entry (0...6) 57*37002bc6SCosta Shulyupin- Return Address to caller 58*37002bc6SCosta Shulyupin- Flag, if entry is an exception or not 59*37002bc6SCosta Shulyupin 60*37002bc6SCosta ShulyupinThe debug logs can be inspected in a live system through entries in 61*37002bc6SCosta Shulyupinthe debugfs-filesystem. Under the toplevel directory "``s390dbf``" there is 62*37002bc6SCosta Shulyupina directory for each registered component, which is named like the 63*37002bc6SCosta Shulyupincorresponding component. The debugfs normally should be mounted to 64*37002bc6SCosta Shulyupin``/sys/kernel/debug`` therefore the debug feature can be accessed under 65*37002bc6SCosta Shulyupin``/sys/kernel/debug/s390dbf``. 66*37002bc6SCosta Shulyupin 67*37002bc6SCosta ShulyupinThe content of the directories are files which represent different views 68*37002bc6SCosta Shulyupinto the debug log. Each component can decide which views should be 69*37002bc6SCosta Shulyupinused through registering them with the function :c:func:`debug_register_view()`. 70*37002bc6SCosta ShulyupinPredefined views for hex/ascii and sprintf data are provided. 71*37002bc6SCosta ShulyupinIt is also possible to define other views. The content of 72*37002bc6SCosta Shulyupina view can be inspected simply by reading the corresponding debugfs file. 73*37002bc6SCosta Shulyupin 74*37002bc6SCosta ShulyupinAll debug logs have an actual debug level (range from 0 to 6). 75*37002bc6SCosta ShulyupinThe default level is 3. Event and Exception functions have a :c:data:`level` 76*37002bc6SCosta Shulyupinparameter. Only debug entries with a level that is lower or equal 77*37002bc6SCosta Shulyupinthan the actual level are written to the log. This means, when 78*37002bc6SCosta Shulyupinwriting events, high priority log entries should have a low level 79*37002bc6SCosta Shulyupinvalue whereas low priority entries should have a high one. 80*37002bc6SCosta ShulyupinThe actual debug level can be changed with the help of the debugfs-filesystem 81*37002bc6SCosta Shulyupinthrough writing a number string "x" to the ``level`` debugfs file which is 82*37002bc6SCosta Shulyupinprovided for every debug log. Debugging can be switched off completely 83*37002bc6SCosta Shulyupinby using "-" on the ``level`` debugfs file. 84*37002bc6SCosta Shulyupin 85*37002bc6SCosta ShulyupinExample:: 86*37002bc6SCosta Shulyupin 87*37002bc6SCosta Shulyupin > echo "-" > /sys/kernel/debug/s390dbf/dasd/level 88*37002bc6SCosta Shulyupin 89*37002bc6SCosta ShulyupinIt is also possible to deactivate the debug feature globally for every 90*37002bc6SCosta Shulyupindebug log. You can change the behavior using 2 sysctl parameters in 91*37002bc6SCosta Shulyupin``/proc/sys/s390dbf``: 92*37002bc6SCosta Shulyupin 93*37002bc6SCosta ShulyupinThere are currently 2 possible triggers, which stop the debug feature 94*37002bc6SCosta Shulyupinglobally. The first possibility is to use the ``debug_active`` sysctl. If 95*37002bc6SCosta Shulyupinset to 1 the debug feature is running. If ``debug_active`` is set to 0 the 96*37002bc6SCosta Shulyupindebug feature is turned off. 97*37002bc6SCosta Shulyupin 98*37002bc6SCosta ShulyupinThe second trigger which stops the debug feature is a kernel oops. 99*37002bc6SCosta ShulyupinThat prevents the debug feature from overwriting debug information that 100*37002bc6SCosta Shulyupinhappened before the oops. After an oops you can reactivate the debug feature 101*37002bc6SCosta Shulyupinby piping 1 to ``/proc/sys/s390dbf/debug_active``. Nevertheless, it's not 102*37002bc6SCosta Shulyupinsuggested to use an oopsed kernel in a production environment. 103*37002bc6SCosta Shulyupin 104*37002bc6SCosta ShulyupinIf you want to disallow the deactivation of the debug feature, you can use 105*37002bc6SCosta Shulyupinthe ``debug_stoppable`` sysctl. If you set ``debug_stoppable`` to 0 the debug 106*37002bc6SCosta Shulyupinfeature cannot be stopped. If the debug feature is already stopped, it 107*37002bc6SCosta Shulyupinwill stay deactivated. 108*37002bc6SCosta Shulyupin 109*37002bc6SCosta ShulyupinKernel Interfaces: 110*37002bc6SCosta Shulyupin------------------ 111*37002bc6SCosta Shulyupin 112*37002bc6SCosta Shulyupin.. kernel-doc:: arch/s390/kernel/debug.c 113*37002bc6SCosta Shulyupin.. kernel-doc:: arch/s390/include/asm/debug.h 114*37002bc6SCosta Shulyupin 115*37002bc6SCosta ShulyupinPredefined views: 116*37002bc6SCosta Shulyupin----------------- 117*37002bc6SCosta Shulyupin 118*37002bc6SCosta Shulyupin.. code-block:: c 119*37002bc6SCosta Shulyupin 120*37002bc6SCosta Shulyupin extern struct debug_view debug_hex_ascii_view; 121*37002bc6SCosta Shulyupin 122*37002bc6SCosta Shulyupin extern struct debug_view debug_sprintf_view; 123*37002bc6SCosta Shulyupin 124*37002bc6SCosta ShulyupinExamples 125*37002bc6SCosta Shulyupin-------- 126*37002bc6SCosta Shulyupin 127*37002bc6SCosta Shulyupin.. code-block:: c 128*37002bc6SCosta Shulyupin 129*37002bc6SCosta Shulyupin /* 130*37002bc6SCosta Shulyupin * hex_ascii-view Example 131*37002bc6SCosta Shulyupin */ 132*37002bc6SCosta Shulyupin 133*37002bc6SCosta Shulyupin #include <linux/init.h> 134*37002bc6SCosta Shulyupin #include <asm/debug.h> 135*37002bc6SCosta Shulyupin 136*37002bc6SCosta Shulyupin static debug_info_t *debug_info; 137*37002bc6SCosta Shulyupin 138*37002bc6SCosta Shulyupin static int init(void) 139*37002bc6SCosta Shulyupin { 140*37002bc6SCosta Shulyupin /* register 4 debug areas with one page each and 4 byte data field */ 141*37002bc6SCosta Shulyupin 142*37002bc6SCosta Shulyupin debug_info = debug_register("test", 1, 4, 4 ); 143*37002bc6SCosta Shulyupin debug_register_view(debug_info, &debug_hex_ascii_view); 144*37002bc6SCosta Shulyupin 145*37002bc6SCosta Shulyupin debug_text_event(debug_info, 4 , "one "); 146*37002bc6SCosta Shulyupin debug_int_exception(debug_info, 4, 4711); 147*37002bc6SCosta Shulyupin debug_event(debug_info, 3, &debug_info, 4); 148*37002bc6SCosta Shulyupin 149*37002bc6SCosta Shulyupin return 0; 150*37002bc6SCosta Shulyupin } 151*37002bc6SCosta Shulyupin 152*37002bc6SCosta Shulyupin static void cleanup(void) 153*37002bc6SCosta Shulyupin { 154*37002bc6SCosta Shulyupin debug_unregister(debug_info); 155*37002bc6SCosta Shulyupin } 156*37002bc6SCosta Shulyupin 157*37002bc6SCosta Shulyupin module_init(init); 158*37002bc6SCosta Shulyupin module_exit(cleanup); 159*37002bc6SCosta Shulyupin 160*37002bc6SCosta Shulyupin.. code-block:: c 161*37002bc6SCosta Shulyupin 162*37002bc6SCosta Shulyupin /* 163*37002bc6SCosta Shulyupin * sprintf-view Example 164*37002bc6SCosta Shulyupin */ 165*37002bc6SCosta Shulyupin 166*37002bc6SCosta Shulyupin #include <linux/init.h> 167*37002bc6SCosta Shulyupin #include <asm/debug.h> 168*37002bc6SCosta Shulyupin 169*37002bc6SCosta Shulyupin static debug_info_t *debug_info; 170*37002bc6SCosta Shulyupin 171*37002bc6SCosta Shulyupin static int init(void) 172*37002bc6SCosta Shulyupin { 173*37002bc6SCosta Shulyupin /* register 4 debug areas with one page each and data field for */ 174*37002bc6SCosta Shulyupin /* format string pointer + 2 varargs (= 3 * sizeof(long)) */ 175*37002bc6SCosta Shulyupin 176*37002bc6SCosta Shulyupin debug_info = debug_register("test", 1, 4, sizeof(long) * 3); 177*37002bc6SCosta Shulyupin debug_register_view(debug_info, &debug_sprintf_view); 178*37002bc6SCosta Shulyupin 179*37002bc6SCosta Shulyupin debug_sprintf_event(debug_info, 2 , "first event in %s:%i\n",__FILE__,__LINE__); 180*37002bc6SCosta Shulyupin debug_sprintf_exception(debug_info, 1, "pointer to debug info: %p\n",&debug_info); 181*37002bc6SCosta Shulyupin 182*37002bc6SCosta Shulyupin return 0; 183*37002bc6SCosta Shulyupin } 184*37002bc6SCosta Shulyupin 185*37002bc6SCosta Shulyupin static void cleanup(void) 186*37002bc6SCosta Shulyupin { 187*37002bc6SCosta Shulyupin debug_unregister(debug_info); 188*37002bc6SCosta Shulyupin } 189*37002bc6SCosta Shulyupin 190*37002bc6SCosta Shulyupin module_init(init); 191*37002bc6SCosta Shulyupin module_exit(cleanup); 192*37002bc6SCosta Shulyupin 193*37002bc6SCosta ShulyupinDebugfs Interface 194*37002bc6SCosta Shulyupin----------------- 195*37002bc6SCosta ShulyupinViews to the debug logs can be investigated through reading the corresponding 196*37002bc6SCosta Shulyupindebugfs-files: 197*37002bc6SCosta Shulyupin 198*37002bc6SCosta ShulyupinExample:: 199*37002bc6SCosta Shulyupin 200*37002bc6SCosta Shulyupin > ls /sys/kernel/debug/s390dbf/dasd 201*37002bc6SCosta Shulyupin flush hex_ascii level pages 202*37002bc6SCosta Shulyupin > cat /sys/kernel/debug/s390dbf/dasd/hex_ascii | sort -k2,2 -s 203*37002bc6SCosta Shulyupin 00 00974733272:680099 2 - 02 0006ad7e 07 ea 4a 90 | .... 204*37002bc6SCosta Shulyupin 00 00974733272:682210 2 - 02 0006ade6 46 52 45 45 | FREE 205*37002bc6SCosta Shulyupin 00 00974733272:682213 2 - 02 0006adf6 07 ea 4a 90 | .... 206*37002bc6SCosta Shulyupin 00 00974733272:682281 1 * 02 0006ab08 41 4c 4c 43 | EXCP 207*37002bc6SCosta Shulyupin 01 00974733272:682284 2 - 02 0006ab16 45 43 4b 44 | ECKD 208*37002bc6SCosta Shulyupin 01 00974733272:682287 2 - 02 0006ab28 00 00 00 04 | .... 209*37002bc6SCosta Shulyupin 01 00974733272:682289 2 - 02 0006ab3e 00 00 00 20 | ... 210*37002bc6SCosta Shulyupin 01 00974733272:682297 2 - 02 0006ad7e 07 ea 4a 90 | .... 211*37002bc6SCosta Shulyupin 01 00974733272:684384 2 - 00 0006ade6 46 52 45 45 | FREE 212*37002bc6SCosta Shulyupin 01 00974733272:684388 2 - 00 0006adf6 07 ea 4a 90 | .... 213*37002bc6SCosta Shulyupin 214*37002bc6SCosta ShulyupinSee section about predefined views for explanation of the above output! 215*37002bc6SCosta Shulyupin 216*37002bc6SCosta ShulyupinChanging the debug level 217*37002bc6SCosta Shulyupin------------------------ 218*37002bc6SCosta Shulyupin 219*37002bc6SCosta ShulyupinExample:: 220*37002bc6SCosta Shulyupin 221*37002bc6SCosta Shulyupin 222*37002bc6SCosta Shulyupin > cat /sys/kernel/debug/s390dbf/dasd/level 223*37002bc6SCosta Shulyupin 3 224*37002bc6SCosta Shulyupin > echo "5" > /sys/kernel/debug/s390dbf/dasd/level 225*37002bc6SCosta Shulyupin > cat /sys/kernel/debug/s390dbf/dasd/level 226*37002bc6SCosta Shulyupin 5 227*37002bc6SCosta Shulyupin 228*37002bc6SCosta ShulyupinFlushing debug areas 229*37002bc6SCosta Shulyupin-------------------- 230*37002bc6SCosta ShulyupinDebug areas can be flushed with piping the number of the desired 231*37002bc6SCosta Shulyupinarea (0...n) to the debugfs file "flush". When using "-" all debug areas 232*37002bc6SCosta Shulyupinare flushed. 233*37002bc6SCosta Shulyupin 234*37002bc6SCosta ShulyupinExamples: 235*37002bc6SCosta Shulyupin 236*37002bc6SCosta Shulyupin1. Flush debug area 0:: 237*37002bc6SCosta Shulyupin 238*37002bc6SCosta Shulyupin > echo "0" > /sys/kernel/debug/s390dbf/dasd/flush 239*37002bc6SCosta Shulyupin 240*37002bc6SCosta Shulyupin2. Flush all debug areas:: 241*37002bc6SCosta Shulyupin 242*37002bc6SCosta Shulyupin > echo "-" > /sys/kernel/debug/s390dbf/dasd/flush 243*37002bc6SCosta Shulyupin 244*37002bc6SCosta ShulyupinChanging the size of debug areas 245*37002bc6SCosta Shulyupin------------------------------------ 246*37002bc6SCosta ShulyupinIt is possible the change the size of debug areas through piping 247*37002bc6SCosta Shulyupinthe number of pages to the debugfs file "pages". The resize request will 248*37002bc6SCosta Shulyupinalso flush the debug areas. 249*37002bc6SCosta Shulyupin 250*37002bc6SCosta ShulyupinExample: 251*37002bc6SCosta Shulyupin 252*37002bc6SCosta ShulyupinDefine 4 pages for the debug areas of debug feature "dasd":: 253*37002bc6SCosta Shulyupin 254*37002bc6SCosta Shulyupin > echo "4" > /sys/kernel/debug/s390dbf/dasd/pages 255*37002bc6SCosta Shulyupin 256*37002bc6SCosta ShulyupinStopping the debug feature 257*37002bc6SCosta Shulyupin-------------------------- 258*37002bc6SCosta ShulyupinExample: 259*37002bc6SCosta Shulyupin 260*37002bc6SCosta Shulyupin1. Check if stopping is allowed:: 261*37002bc6SCosta Shulyupin 262*37002bc6SCosta Shulyupin > cat /proc/sys/s390dbf/debug_stoppable 263*37002bc6SCosta Shulyupin 264*37002bc6SCosta Shulyupin2. Stop debug feature:: 265*37002bc6SCosta Shulyupin 266*37002bc6SCosta Shulyupin > echo 0 > /proc/sys/s390dbf/debug_active 267*37002bc6SCosta Shulyupin 268*37002bc6SCosta Shulyupincrash Interface 269*37002bc6SCosta Shulyupin---------------- 270*37002bc6SCosta ShulyupinThe ``crash`` tool since v5.1.0 has a built-in command 271*37002bc6SCosta Shulyupin``s390dbf`` to display all the debug logs or export them to the file system. 272*37002bc6SCosta ShulyupinWith this tool it is possible 273*37002bc6SCosta Shulyupinto investigate the debug logs on a live system and with a memory dump after 274*37002bc6SCosta Shulyupina system crash. 275*37002bc6SCosta Shulyupin 276*37002bc6SCosta ShulyupinInvestigating raw memory 277*37002bc6SCosta Shulyupin------------------------ 278*37002bc6SCosta ShulyupinOne last possibility to investigate the debug logs at a live 279*37002bc6SCosta Shulyupinsystem and after a system crash is to look at the raw memory 280*37002bc6SCosta Shulyupinunder VM or at the Service Element. 281*37002bc6SCosta ShulyupinIt is possible to find the anchor of the debug-logs through 282*37002bc6SCosta Shulyupinthe ``debug_area_first`` symbol in the System map. Then one has 283*37002bc6SCosta Shulyupinto follow the correct pointers of the data-structures defined 284*37002bc6SCosta Shulyupinin debug.h and find the debug-areas in memory. 285*37002bc6SCosta ShulyupinNormally modules which use the debug feature will also have 286*37002bc6SCosta Shulyupina global variable with the pointer to the debug-logs. Following 287*37002bc6SCosta Shulyupinthis pointer it will also be possible to find the debug logs in 288*37002bc6SCosta Shulyupinmemory. 289*37002bc6SCosta Shulyupin 290*37002bc6SCosta ShulyupinFor this method it is recommended to use '16 * x + 4' byte (x = 0..n) 291*37002bc6SCosta Shulyupinfor the length of the data field in :c:func:`debug_register()` in 292*37002bc6SCosta Shulyupinorder to see the debug entries well formatted. 293*37002bc6SCosta Shulyupin 294*37002bc6SCosta Shulyupin 295*37002bc6SCosta ShulyupinPredefined Views 296*37002bc6SCosta Shulyupin---------------- 297*37002bc6SCosta Shulyupin 298*37002bc6SCosta ShulyupinThere are two predefined views: hex_ascii and sprintf. 299*37002bc6SCosta ShulyupinThe hex_ascii view shows the data field in hex and ascii representation 300*37002bc6SCosta Shulyupin(e.g. ``45 43 4b 44 | ECKD``). 301*37002bc6SCosta Shulyupin 302*37002bc6SCosta ShulyupinThe sprintf view formats the debug entries in the same way as the sprintf 303*37002bc6SCosta Shulyupinfunction would do. The sprintf event/exception functions write to the 304*37002bc6SCosta Shulyupindebug entry a pointer to the format string (size = sizeof(long)) 305*37002bc6SCosta Shulyupinand for each vararg a long value. So e.g. for a debug entry with a format 306*37002bc6SCosta Shulyupinstring plus two varargs one would need to allocate a (3 * sizeof(long)) 307*37002bc6SCosta Shulyupinbyte data area in the debug_register() function. 308*37002bc6SCosta Shulyupin 309*37002bc6SCosta ShulyupinIMPORTANT: 310*37002bc6SCosta Shulyupin Using "%s" in sprintf event functions is dangerous. You can only 311*37002bc6SCosta Shulyupin use "%s" in the sprintf event functions, if the memory for the passed string 312*37002bc6SCosta Shulyupin is available as long as the debug feature exists. The reason behind this is 313*37002bc6SCosta Shulyupin that due to performance considerations only a pointer to the string is stored 314*37002bc6SCosta Shulyupin in the debug feature. If you log a string that is freed afterwards, you will 315*37002bc6SCosta Shulyupin get an OOPS when inspecting the debug feature, because then the debug feature 316*37002bc6SCosta Shulyupin will access the already freed memory. 317*37002bc6SCosta Shulyupin 318*37002bc6SCosta ShulyupinNOTE: 319*37002bc6SCosta Shulyupin If using the sprintf view do NOT use other event/exception functions 320*37002bc6SCosta Shulyupin than the sprintf-event and -exception functions. 321*37002bc6SCosta Shulyupin 322*37002bc6SCosta ShulyupinThe format of the hex_ascii and sprintf view is as follows: 323*37002bc6SCosta Shulyupin 324*37002bc6SCosta Shulyupin- Number of area 325*37002bc6SCosta Shulyupin- Timestamp (formatted as seconds and microseconds since 00:00:00 Coordinated 326*37002bc6SCosta Shulyupin Universal Time (UTC), January 1, 1970) 327*37002bc6SCosta Shulyupin- level of debug entry 328*37002bc6SCosta Shulyupin- Exception flag (* = Exception) 329*37002bc6SCosta Shulyupin- Cpu-Number of calling task 330*37002bc6SCosta Shulyupin- Return Address to caller 331*37002bc6SCosta Shulyupin- data field 332*37002bc6SCosta Shulyupin 333*37002bc6SCosta ShulyupinA typical line of the hex_ascii view will look like the following (first line 334*37002bc6SCosta Shulyupinis only for explanation and will not be displayed when 'cating' the view):: 335*37002bc6SCosta Shulyupin 336*37002bc6SCosta Shulyupin area time level exception cpu caller data (hex + ascii) 337*37002bc6SCosta Shulyupin -------------------------------------------------------------------------- 338*37002bc6SCosta Shulyupin 00 00964419409:440690 1 - 00 88023fe 339*37002bc6SCosta Shulyupin 340*37002bc6SCosta Shulyupin 341*37002bc6SCosta ShulyupinDefining views 342*37002bc6SCosta Shulyupin-------------- 343*37002bc6SCosta Shulyupin 344*37002bc6SCosta ShulyupinViews are specified with the 'debug_view' structure. There are defined 345*37002bc6SCosta Shulyupincallback functions which are used for reading and writing the debugfs files: 346*37002bc6SCosta Shulyupin 347*37002bc6SCosta Shulyupin.. code-block:: c 348*37002bc6SCosta Shulyupin 349*37002bc6SCosta Shulyupin struct debug_view { 350*37002bc6SCosta Shulyupin char name[DEBUG_MAX_PROCF_LEN]; 351*37002bc6SCosta Shulyupin debug_prolog_proc_t* prolog_proc; 352*37002bc6SCosta Shulyupin debug_header_proc_t* header_proc; 353*37002bc6SCosta Shulyupin debug_format_proc_t* format_proc; 354*37002bc6SCosta Shulyupin debug_input_proc_t* input_proc; 355*37002bc6SCosta Shulyupin void* private_data; 356*37002bc6SCosta Shulyupin }; 357*37002bc6SCosta Shulyupin 358*37002bc6SCosta Shulyupinwhere: 359*37002bc6SCosta Shulyupin 360*37002bc6SCosta Shulyupin.. code-block:: c 361*37002bc6SCosta Shulyupin 362*37002bc6SCosta Shulyupin typedef int (debug_header_proc_t) (debug_info_t* id, 363*37002bc6SCosta Shulyupin struct debug_view* view, 364*37002bc6SCosta Shulyupin int area, 365*37002bc6SCosta Shulyupin debug_entry_t* entry, 366*37002bc6SCosta Shulyupin char* out_buf); 367*37002bc6SCosta Shulyupin 368*37002bc6SCosta Shulyupin typedef int (debug_format_proc_t) (debug_info_t* id, 369*37002bc6SCosta Shulyupin struct debug_view* view, char* out_buf, 370*37002bc6SCosta Shulyupin const char* in_buf); 371*37002bc6SCosta Shulyupin typedef int (debug_prolog_proc_t) (debug_info_t* id, 372*37002bc6SCosta Shulyupin struct debug_view* view, 373*37002bc6SCosta Shulyupin char* out_buf); 374*37002bc6SCosta Shulyupin typedef int (debug_input_proc_t) (debug_info_t* id, 375*37002bc6SCosta Shulyupin struct debug_view* view, 376*37002bc6SCosta Shulyupin struct file* file, const char* user_buf, 377*37002bc6SCosta Shulyupin size_t in_buf_size, loff_t* offset); 378*37002bc6SCosta Shulyupin 379*37002bc6SCosta Shulyupin 380*37002bc6SCosta ShulyupinThe "private_data" member can be used as pointer to view specific data. 381*37002bc6SCosta ShulyupinIt is not used by the debug feature itself. 382*37002bc6SCosta Shulyupin 383*37002bc6SCosta ShulyupinThe output when reading a debugfs file is structured like this:: 384*37002bc6SCosta Shulyupin 385*37002bc6SCosta Shulyupin "prolog_proc output" 386*37002bc6SCosta Shulyupin 387*37002bc6SCosta Shulyupin "header_proc output 1" "format_proc output 1" 388*37002bc6SCosta Shulyupin "header_proc output 2" "format_proc output 2" 389*37002bc6SCosta Shulyupin "header_proc output 3" "format_proc output 3" 390*37002bc6SCosta Shulyupin ... 391*37002bc6SCosta Shulyupin 392*37002bc6SCosta ShulyupinWhen a view is read from the debugfs, the Debug Feature calls the 393*37002bc6SCosta Shulyupin'prolog_proc' once for writing the prolog. 394*37002bc6SCosta ShulyupinThen 'header_proc' and 'format_proc' are called for each 395*37002bc6SCosta Shulyupinexisting debug entry. 396*37002bc6SCosta Shulyupin 397*37002bc6SCosta ShulyupinThe input_proc can be used to implement functionality when it is written to 398*37002bc6SCosta Shulyupinthe view (e.g. like with ``echo "0" > /sys/kernel/debug/s390dbf/dasd/level``). 399*37002bc6SCosta Shulyupin 400*37002bc6SCosta ShulyupinFor header_proc there can be used the default function 401*37002bc6SCosta Shulyupin:c:func:`debug_dflt_header_fn()` which is defined in debug.h. 402*37002bc6SCosta Shulyupinand which produces the same header output as the predefined views. 403*37002bc6SCosta ShulyupinE.g:: 404*37002bc6SCosta Shulyupin 405*37002bc6SCosta Shulyupin 00 00964419409:440761 2 - 00 88023ec 406*37002bc6SCosta Shulyupin 407*37002bc6SCosta ShulyupinIn order to see how to use the callback functions check the implementation 408*37002bc6SCosta Shulyupinof the default views! 409*37002bc6SCosta Shulyupin 410*37002bc6SCosta ShulyupinExample: 411*37002bc6SCosta Shulyupin 412*37002bc6SCosta Shulyupin.. code-block:: c 413*37002bc6SCosta Shulyupin 414*37002bc6SCosta Shulyupin #include <asm/debug.h> 415*37002bc6SCosta Shulyupin 416*37002bc6SCosta Shulyupin #define UNKNOWNSTR "data: %08x" 417*37002bc6SCosta Shulyupin 418*37002bc6SCosta Shulyupin const char* messages[] = 419*37002bc6SCosta Shulyupin {"This error...........\n", 420*37002bc6SCosta Shulyupin "That error...........\n", 421*37002bc6SCosta Shulyupin "Problem..............\n", 422*37002bc6SCosta Shulyupin "Something went wrong.\n", 423*37002bc6SCosta Shulyupin "Everything ok........\n", 424*37002bc6SCosta Shulyupin NULL 425*37002bc6SCosta Shulyupin }; 426*37002bc6SCosta Shulyupin 427*37002bc6SCosta Shulyupin static int debug_test_format_fn( 428*37002bc6SCosta Shulyupin debug_info_t *id, struct debug_view *view, 429*37002bc6SCosta Shulyupin char *out_buf, const char *in_buf 430*37002bc6SCosta Shulyupin ) 431*37002bc6SCosta Shulyupin { 432*37002bc6SCosta Shulyupin int i, rc = 0; 433*37002bc6SCosta Shulyupin 434*37002bc6SCosta Shulyupin if (id->buf_size >= 4) { 435*37002bc6SCosta Shulyupin int msg_nr = *((int*)in_buf); 436*37002bc6SCosta Shulyupin if (msg_nr < sizeof(messages) / sizeof(char*) - 1) 437*37002bc6SCosta Shulyupin rc += sprintf(out_buf, "%s", messages[msg_nr]); 438*37002bc6SCosta Shulyupin else 439*37002bc6SCosta Shulyupin rc += sprintf(out_buf, UNKNOWNSTR, msg_nr); 440*37002bc6SCosta Shulyupin } 441*37002bc6SCosta Shulyupin return rc; 442*37002bc6SCosta Shulyupin } 443*37002bc6SCosta Shulyupin 444*37002bc6SCosta Shulyupin struct debug_view debug_test_view = { 445*37002bc6SCosta Shulyupin "myview", /* name of view */ 446*37002bc6SCosta Shulyupin NULL, /* no prolog */ 447*37002bc6SCosta Shulyupin &debug_dflt_header_fn, /* default header for each entry */ 448*37002bc6SCosta Shulyupin &debug_test_format_fn, /* our own format function */ 449*37002bc6SCosta Shulyupin NULL, /* no input function */ 450*37002bc6SCosta Shulyupin NULL /* no private data */ 451*37002bc6SCosta Shulyupin }; 452*37002bc6SCosta Shulyupin 453*37002bc6SCosta Shulyupintest: 454*37002bc6SCosta Shulyupin===== 455*37002bc6SCosta Shulyupin 456*37002bc6SCosta Shulyupin.. code-block:: c 457*37002bc6SCosta Shulyupin 458*37002bc6SCosta Shulyupin debug_info_t *debug_info; 459*37002bc6SCosta Shulyupin int i; 460*37002bc6SCosta Shulyupin ... 461*37002bc6SCosta Shulyupin debug_info = debug_register("test", 0, 4, 4); 462*37002bc6SCosta Shulyupin debug_register_view(debug_info, &debug_test_view); 463*37002bc6SCosta Shulyupin for (i = 0; i < 10; i ++) 464*37002bc6SCosta Shulyupin debug_int_event(debug_info, 1, i); 465*37002bc6SCosta Shulyupin 466*37002bc6SCosta Shulyupin:: 467*37002bc6SCosta Shulyupin 468*37002bc6SCosta Shulyupin > cat /sys/kernel/debug/s390dbf/test/myview 469*37002bc6SCosta Shulyupin 00 00964419734:611402 1 - 00 88042ca This error........... 470*37002bc6SCosta Shulyupin 00 00964419734:611405 1 - 00 88042ca That error........... 471*37002bc6SCosta Shulyupin 00 00964419734:611408 1 - 00 88042ca Problem.............. 472*37002bc6SCosta Shulyupin 00 00964419734:611411 1 - 00 88042ca Something went wrong. 473*37002bc6SCosta Shulyupin 00 00964419734:611414 1 - 00 88042ca Everything ok........ 474*37002bc6SCosta Shulyupin 00 00964419734:611417 1 - 00 88042ca data: 00000005 475*37002bc6SCosta Shulyupin 00 00964419734:611419 1 - 00 88042ca data: 00000006 476*37002bc6SCosta Shulyupin 00 00964419734:611422 1 - 00 88042ca data: 00000007 477*37002bc6SCosta Shulyupin 00 00964419734:611425 1 - 00 88042ca data: 00000008 478*37002bc6SCosta Shulyupin 00 00964419734:611428 1 - 00 88042ca data: 00000009 479