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