/*************************************************************************** * * Copyright (C) 2001 International Business Machines * All rights reserved. * * This file is part of the GPFS mmfslinux kernel module. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *************************************************************************** */ /* @(#)02 1.23.1.1 src/avs/fs/mmfs/ts/kernext/ibm-kxi/Trace.h, mmfs, avs_rgpfs24, rgpfs24s007a 10/8/06 03:17:47 */ /* * Definition of macros and symbols to control trace generation. Define * the symbol NTRACE at compile time to remove all trace code. * * Conventions for assigning trace levels: * - Trace levels are always non-negative. * - Larger trace levels produce more trace output * - Trace level == 0 produces no output. * - Trace level == 1 produces one line of output for the operation * being traced, usually just a description of what is being called * and its arguments. * - Trace level >= 10 are for testing only; they are disabled * in the product code (controlled by VERBOSETRACE define). * */ #ifndef _h_Trace #define _h_Trace /* Include the code generated by the mktrace utility to marshall trace arguments for all traces in this source directory */ #include /* Include the platform-specific trace macros */ #include /* Define macros to build xxx_ToString calls. Used within xxx_id2name macros. */ #ifdef GPFS_PRINTF # define I2N(n,i) n##ToString((int)i) # define E2N(n,i) n##ToString(i) #else # define I2N(n,i) ((int)(i)) # define E2N(n,i) ((int)(i)) #endif /* Trace categories */ #define TRACE_ALLOC 0 /* Disk space allocation */ #define TRACE_ALLOCMGR 1 /* Allocation manager trace */ #define TRACE_BASIC 2 /* "basic" classes */ #define TRACE_BRL 3 /* byte range locks */ #define TRACE_CLEANUP 4 /* cleanup routines */ #define TRACE_CMD 5 /* TS commands */ #define TRACE_DEFRAG 6 /* defragmentation */ #define TRACE_DFS 7 /* DFS Export interaction */ #define TRACE_DISK 8 /* physical disk I/O */ #define TRACE_DMAPI 9 /* Data Management */ #define TRACE_DS 10 /* data shipping */ #define TRACE_ERRLOG 11 /* error logging */ #define TRACE_FS 12 /* file system */ #define TRACE_FSCK 13 /* online multinode fsck */ #define TRACE_ENTRYEXIT 14 /* routine entry/exit tracing */ #define TRACE_IO 15 /* physical I/O (formerly TRACE_RTPERF) */ #define TRACE_KLOCKL 16 /* low-level locks in VFS code */ #define TRACE_KSVFS 17 /* generic VFS kernel stuff */ #define TRACE_LOCK 18 /* interprocess locking */ #define TRACE_LOG 19 /* recovery log */ #define TRACE_MALLOC 20 /* MemoryPool alloc and dealloc */ #define TRACE_MB 21 /* mailbox message handling */ #define TRACE_MEMMGR 22 /* memory manager traces */ #define TRACE_MNODE 23 /* metanode operations */ #define TRACE_MSG 24 /* calls to routines in SharkMsg.h */ #define TRACE_MUTEX 25 /* mutexes and condition variables */ #define TRACE_PERFMON 26 /* trace performance monitor code */ #define TRACE_PGALLOC 27 /* page allocator tracing */ #define TRACE_PIN 28 /* pinning to real memory */ #define TRACE_PIT 29 /* Parallel Inode Traversal */ #define TRACE_QUOTA 30 /* quota management */ #define TRACE_SP 31 /* SP message handling */ #define TRACE_TASKING 32 /* tasking system but not Thread operations */ #define TRACE_THREAD 33 /* operations in Thread class */ #define TRACE_TSTM 34 /* token manager (formerly TRACE_CETM) */ #define TRACE_TS 35 /* Tiger Shark specific code. */ #define TRACE_USER1 36 /* Used for miscellaneous tracing and */ #define TRACE_USER2 37 /* debugging purposes. */ #define TRACE_VNODE 38 /* vnode layer of VFS kernel support */ #define TRACE_VNOP 39 /* one line per VNOP with all important info */ #define TRACE_BOPS 40 /* block_operations */ #define TRACE_DOPS 41 /* dentry_operations */ #define TRACE_IALLOC 42 /* inode allocation */ #define TRACE_FOPS 43 /* file_operations */ #define TRACE_SOPS 44 /* super_operations */ #define TRACE_SHARED 45 /* shared memory */ #define TRACE_NSD 46 /* network shared disk */ #define TRACE_DLEASE 47 /* disk lease */ #define TRACE_SMB 48 /* SMB Open and Op Locks */ #define TRACE_EEXP 49 /* events exporter. */ #define TRACE_SEC 50 /* Cluster Security Specific Trace */ #define TRACE_SANERGY 51 /* SANergy */ #define TRACE_KERNEL 52 /* kernel */ #define TRACE_MMPMON 53 /* mmpmon. */ /* Add new trace classes above here. When adding new trace classes, be sure to update the table below containing character string names for the trace classes. The maximum number of trace classes is given by MAX_TRACE_CLASSES. */ /* Table of trace class names, indexed by TRACE_... constants above. The generation of this table is controlled by the #define variable DEFINE_TRACE_CLASS_NAME_TABLE, which is generally only set in the module that parses commands to change trace settings. */ struct TraceNameTableEntry { char *name; char *desc; }; #ifndef _KERNEL extern const struct TraceNameTableEntry TraceNamesP[MAX_TRACE_CLASSES + 1]; # ifdef DEFINE_TRACE_CLASS_NAME_TABLE const TraceNameTableEntry TraceNamesP[MAX_TRACE_CLASSES + 1] = { /* 0 */ { "alloc", "disk space allocation" }, /* 1 */ { "allocmgr", "allocation manager" }, /* 2 */ { "basic", "'basic' classes" }, /* 3 */ { "brl", "byte range locks" }, /* 4 */ { "cleanup", "cleanup routines" }, /* 5 */ { "cmd", "TS commands" }, /* 6 */ { "defrag", "defragmentation" }, /* 7 */ { "dfs", "DFS export" }, /* 8 */ { "disk", "physical disk I/O" }, /* 9 */ { "dmapi", "data management" }, /* 10 */ { "ds", "data shipping" }, /* 11 */ { "errlog", "error logging" }, /* 12 */ { "fs", "file system" }, /* 13 */ { "fsck", "online multinode fsck" }, /* 14 */ { "entryexit", "routine entry/exit" }, /* 15 */ { "io", "physical I/O" }, /* 16 */ { "klockl", "low-level VFS locking" }, /* 17 */ { "ksvfs", "generic kernel VFS stuff" }, /* 18 */ { "lock", "interprocess locking" }, /* 19 */ { "log", "recovery log" }, /* 20 */ { "malloc", "malloc/free in shared segment" }, /* 21 */ { "mb", "mailbox message handling" }, /* 22 */ { "memmgr", "memory manager" }, /* 23 */ { "mnode", "mnode operations" }, /* 24 */ { "msg", "calls to routines in SharkMsg.h" }, /* 25 */ { "mutex", "mutexes and condition variables" }, /* 26 */ { "perfmon", "performance monitors" }, /* 27 */ { "pgalloc", "page allocator tracing" }, /* 28 */ { "pin", "pinning to real memory" }, /* 29 */ { "pit", "parallel inode traversal" }, /* 30 */ { "quota", "quota management" }, /* 31 */ { "sp", "SP message handling" }, /* 32 */ { "tasking", "tasking system but not Thread operations" }, /* 33 */ { "thread", "operations in Thread class" }, /* 34 */ { "tm", "token manager" }, /* 35 */ { "ts", "Tiger Shark specific code" }, /* 36 */ { "user1", "Used for miscellaneous tracing and" }, /* 37 */ { "user2", "debugging purposes" }, /* 38 */ { "vnode", "vnode layer of VFS kernel support" }, /* 39 */ { "vnop", "concise vnop description" }, /* 40 */ { "block", "block_operations" }, /* 41 */ { "dentry", "dentry_operations" }, /* 42 */ { "ialloc", "inode allocation" }, /* 43 */ { "file", "file_operations" }, /* 44 */ { "super", "super_operations" }, /* 45 */ { "shared", "shared memory" }, /* 46 */ { "nsd", "network shared disk"}, /* 47 */ { "disklease", "disk lease"}, /* 48 */ { "smb", "SMB Locks"}, /* 49 */ { "eventsExporter", "Events Exporter"}, /* 50 */ { "sec", "Cluster Security Specific Trace"}, /* 51 */ { "sanergy", "SANergy"}, /* 52 */ { "kernel", "kernel"}, /* 53 */ { "mmpmon", "mmpmon"}, /* Add new trace class names above here. */ /* DO NOT ifdef TRACE CLASS DEFINITIONS! */ { 0, 0 } }; # endif /* of ifdef DEFINE_TRACE_CLASS_NAME_TABLE */ #endif /* not _KERNEL */ /* Define the TRCOPTCODE and/or KTRCOPTCODE macro here to temporarily insert debugging code into each enabled TRACE macro expansion. TRCOPTCODE is inserted into code that is compiled with _KERNEL *not* defined, while KTRCOPTCODE is inserted into code compiled with -D_KERNEL */ #define TRCOPTCODE #define KTRCOPTCODE /* Define a macro that does nothing. Used for dummy else clauses. */ #ifndef NOOP # define NOOP ((void)0) #endif /* Define SHARKHOOKID word. GPFS default hookid is 307, but we use a different hookid in certain directories, as defined in DirIds.h. */ #if LOCAL_BASE == DIR_ID_TM # define SHARKHOOKID 0x30600000 #elif LOCAL_BASE == DIR_ID_TASKING # define SHARKHOOKID 0x30800000 #elif LOCAL_BASE == DIR_ID_KERNEXT # define SHARKHOOKID 0x30900000 #else # define SHARKHOOKID 0x30700000 #endif /* Convert the id of a particular trace to the hookword stored in the trace buffer */ #define _HOOKWORD(_id) ((_id) | SHARKHOOKID) /* Define the routines that handle traces that include strings (_STrace) and arbitrary traces (_XTrace) */ #ifdef __cplusplus extern "C" { #endif void _STrace(int hookword, int nArgs, int pos, ...); void _XTrace(int hookword, char *fmt, ...); #ifdef GPFS_AIX /* AIX doesn't have nor need non blocking trace calls */ #define _STraceNB _STrace #define _XTraceNB _XTrace #else void _STraceNB(int hookword, int nArgs, int pos, ...); void _XTraceNB(int hookword, char *fmt, ...); #endif #ifdef __cplusplus } #endif #ifdef NTRACE /* disable all traces */ # define _TRACE_MACRO(_c, _l, _ktrc) NOOP # define _TRACE_IS_ON(_c, _l) (0) #else /* not NTRACE */ /* Define the test to check whether tracing for given level is enabled. Unless VERBOSETRACE is defined, tracing is always disabled for trace calls with trace level 10 or higher. */ # ifdef VERBOSETRACE # define _TRACE_IS_ON(_c,_l) (_GBL_TRC_IS_ON && (signed char)TraceFlagsP[_c] >= (_l)) # else # define _TRACE_IS_ON(_c,_l) (_GBL_TRC_IS_ON && (_l)<10 && \ (signed char) TraceFlagsP[_c] >= (_l)) # endif /* Define _TRACE_MACRO(_c, _l, _ktrc) macro. Used to define the actual TRACExx macros. Macro parameters: _c trace class _l trace level _ktrc code to execute if kernel tracing is selected */ # ifndef _KERNEL # define _TRACE_MACRO(_c, _l, _ktrc) \ if (_TRACE_IS_ON(_c, _l)) \ { _TR_BEFORE; _ktrc; TRCOPTCODE; _TR_AFTER; } else NOOP # else /* _KERNEL */ # define _TRACE_MACRO(_c, _l, _ktrc) \ if (_TRACE_IS_ON(_c, _l)) \ { _TR_BEFORE; _ktrc; KTRCOPTCODE; _TR_AFTER; } else NOOP # endif /* KERNEL */ #endif /* not NTRACE */ /* Non blocking versions of trace calls. The succeeding 'N' is * significant to mktrcid only and thus these versions are merely * redefined to be the real macro. */ #define TRACE0N TRACE0 #define TRACE1N TRACE1 #define TRACE2N TRACE2 #define TRACE3N TRACE3 #define TRACE4N TRACE4 #define TRACE5N TRACE5 #define TRACE6N TRACE6 #define TRACE7N TRACE7 #define TRACE8N TRACE8 #define TRACE9N TRACE9 #define TRACE10N TRACE10 #define TRACE11N TRACE11 #define TRACE12N TRACE12 /* General trace macros */ #ifndef GPFS_PRINTF #define TRACE0(_c, _l, id, fmt) \ _TRACE_MACRO(_c, _l, TRACE_##id##_CALL) #define TRACE1(_c, _l, id, fmt, a1) \ _TRACE_MACRO(_c, _l, TRACE_##id##_CALL) #define TRACE2(_c, _l, id, fmt, a1, a2) \ _TRACE_MACRO(_c, _l, TRACE_##id##_CALL) #define TRACE3(_c, _l, id, fmt, a1, a2, a3) \ _TRACE_MACRO(_c, _l, TRACE_##id##_CALL) #define TRACE4(_c, _l, id, fmt, a1, a2, a3, a4) \ _TRACE_MACRO(_c, _l, TRACE_##id##_CALL) #define TRACE5(_c, _l, id, fmt, a1, a2, a3, a4, a5) \ _TRACE_MACRO(_c, _l, TRACE_##id##_CALL) #define TRACE6(_c, _l, id, fmt, a1, a2, a3, a4, a5, a6) \ _TRACE_MACRO(_c, _l, TRACE_##id##_CALL) #define TRACE7(_c, _l, id, fmt, a1, a2, a3, a4, a5, a6, a7) \ _TRACE_MACRO(_c, _l, TRACE_##id##_CALL) #define TRACE8(_c, _l, id, fmt, a1, a2, a3, a4, a5, a6, a7, a8) \ _TRACE_MACRO(_c, _l, TRACE_##id##_CALL) #define TRACE9(_c, _l, id, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9) \ _TRACE_MACRO(_c, _l, TRACE_##id##_CALL) #define TRACE10(_c, _l, id, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) \ _TRACE_MACRO(_c, _l, TRACE_##id##_CALL) #define TRACE11(_c, _l, id, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) \ _TRACE_MACRO(_c, _l, TRACE_##id##_CALL) #define TRACE12(_c, _l, id, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) \ _TRACE_MACRO(_c, _l, TRACE_##id##_CALL) #else /* GPFS_PRINTF */ #define TRACE0(_c,_l,_id,_fmt) \ PDEBUG((_c),(_l),_fmt,1) #define TRACE1(_c,_l,_id,_fmt,a1) \ PDEBUG((_c),(_l),_fmt,a1) #define TRACE2(_c,_l,_id,_fmt,a1,a2) \ PDEBUG((_c),(_l),_fmt,a1,a2) #define TRACE3(_c,_l,_id,_fmt,a1,a2,a3) \ PDEBUG((_c),(_l),_fmt,a1,a2,a3) #define TRACE4(_c,_l,_id,_fmt,a1,a2,a3,a4) \ PDEBUG((_c),(_l),_fmt,a1,a2,a3,a4) #define TRACE5(_c,_l,_id,_fmt,a1,a2,a3,a4,a5) \ PDEBUG((_c),(_l),_fmt,a1,a2,a3,a4,a5) #define TRACE6(_c,_l,_id,_fmt,a1,a2,a3,a4,a5,a6) \ PDEBUG((_c),(_l),_fmt,a1,a2,a3,a4,a5,a6) #define TRACE7(_c,_l,_id,_fmt,a1,a2,a3,a4,a5,a6,a7) \ PDEBUG((_c),(_l),_fmt,a1,a2,a3,a4,a5,a6,a7) #define TRACE8(_c,_l,_id,_fmt,a1,a2,a3,a4,a5,a6,a7,a8) \ PDEBUG((_c),(_l),_fmt,a1,a2,a3,a4,a5,a6,a7,a8) #define TRACE9(_c,_l,_id,_fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9) \ PDEBUG((_c),(_l),_fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9) #define TRACE10(_c,_l,_id,_fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) \ PDEBUG((_c),(_l),_fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) #define TRACE11(_c,_l,_id,_fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) \ PDEBUG((_c),(_l),_fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) #define TRACE12(_c,_l,_id,_fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) \ PDEBUG((_c),(_l),_fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) #endif /* GPFS_PRINTF */ /* Subroutine for setting traces given a string of trace names and values */ extern int traceCommand(char *args); /* Routine entry/exit tracing: In C code, place the macro ENTER(level) at the point of the first executable statement of the routine. This will generate a call to cxiTraceEntry that will trace the call by function name and source line if TRACE_ENTEREXIT is set high enough. Optionally, place the macro EXIT(level) at exits from the routine. In C++ code, place the macro ENTER(level) as the first declaration in the routine. This will create an object of type EntryExitTracer, whose constructor will call cxiTraceEntry to trace routine entry, and whose destructor will call cxiTraceExit to trace routine exit. The EXIT macro may appear, but will be ignored. The trace levels that appear in the ENTER and EXIT macros are interpreted relative to a base trace level. Setting the TRACE_ENTEREXIT level < BASE_ENTEREXIT_LEVEL disables all enter/exit tracing. To see enter/exit traces from daemon code, set the TRACE_ENTEREXIT level to at least BASE_ENTEREXIT_LEVEL+DAEMON_ENTEREXIT_TRACING. Kernel stack depth checking is only supported on Linux, since we do not know how to compute the current stack usage on AIX. */ #ifdef KSTACK_CHECK # ifndef GPFS_LINUX # error "KSTACK_CHECK is only supported on Linux" # endif #endif #if defined(ENTRYEXIT_TRACE) || defined(KSTACK_CHECK) # define BASE_ENTEREXIT_LEVEL 6 # define DAEMON_ENTEREXIT_TRACING 2 # ifdef __cplusplus extern "C" void cxiTraceEntry(int level, const char * funcnameP, const char * filenameP, int lineNum); extern "C" void cxiTraceExit(int level, const char * funcnameP); extern "C" void cxiTraceExitRC(int level, const char * funcnameP, int rc); class EntryExitTracer { private: /* Trace level */ int level; /* Pointer to routine name */ const char * funcnameP; public: /* Constructor: trace routine entry and remember trace level and routine name */ inline EntryExitTracer(int level, const char * funcnameP, const char * filenameP, int lineNum) { cxiTraceEntry(level, funcnameP, filenameP, lineNum); this->level = level; this->funcnameP = funcnameP; } /* Destructor: trace routine exit */ inline ~EntryExitTracer() { cxiTraceExit(level, funcnameP); } }; # define ENTER(_level) \ EntryExitTracer _eet(_level, __FUNCTION__, __FILE__, __LINE__) # define EXIT(_level) # define EXIT_RC(_level, rc) # else extern void cxiTraceEntry(int level, const char * funcnameP, const char * filenameP, int lineNum); extern void cxiTraceExit(int level, const char * funcnameP); extern void cxiTraceExitRC(int level, const char * funcnameP, int rc); # define ENTER(_level) cxiTraceEntry(_level, __FUNCTION__, __FILE__, __LINE__) # define EXIT(_level) cxiTraceExit(_level, __FUNCTION__) # define EXIT_RC(_level, rc) cxiTraceExitRC(_level, __FUNCTION__, rc) # endif /* __cplusplus */ #else /* ENTRYEXIT_TRACE and KSTACK_CHECK disabled */ # define ENTER(_level) # define EXIT(_level) # define EXIT_RC(_level, rc) #endif /* defined(ENTRYEXIT_TRACE) || defined(KSTACK_CHECK) */ #endif /* _h_Trace */