root/fs/ocfs2/cluster/masklog.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


   1 /* SPDX-License-Identifier: GPL-2.0-or-later */
   2 /* -*- mode: c; c-basic-offset: 8; -*-
   3  * vim: noexpandtab sw=8 ts=8 sts=0:
   4  *
   5  * Copyright (C) 2005 Oracle.  All rights reserved.
   6  */
   7 
   8 #ifndef O2CLUSTER_MASKLOG_H
   9 #define O2CLUSTER_MASKLOG_H
  10 
  11 /*
  12  * For now this is a trivial wrapper around printk() that gives the critical
  13  * ability to enable sets of debugging output at run-time.  In the future this
  14  * will almost certainly be redirected to relayfs so that it can pay a
  15  * substantially lower heisenberg tax.
  16  *
  17  * Callers associate the message with a bitmask and a global bitmask is
  18  * maintained with help from /proc.  If any of the bits match the message is
  19  * output.
  20  *
  21  * We must have efficient bit tests on i386 and it seems gcc still emits crazy
  22  * code for the 64bit compare.  It emits very good code for the dual unsigned
  23  * long tests, though, completely avoiding tests that can never pass if the
  24  * caller gives a constant bitmask that fills one of the longs with all 0s.  So
  25  * the desire is to have almost all of the calls decided on by comparing just
  26  * one of the longs.  This leads to having infrequently given bits that are
  27  * frequently matched in the high bits.
  28  *
  29  * _ERROR and _NOTICE are used for messages that always go to the console and
  30  * have appropriate KERN_ prefixes.  We wrap these in our function instead of
  31  * just calling printk() so that this can eventually make its way through
  32  * relayfs along with the debugging messages.  Everything else gets KERN_DEBUG.
  33  * The inline tests and macro dance give GCC the opportunity to quite cleverly
  34  * only emit the appropriage printk() when the caller passes in a constant
  35  * mask, as is almost always the case.
  36  *
  37  * All this bitmask nonsense is managed from the files under
  38  * /sys/fs/o2cb/logmask/.  Reading the files gives a straightforward
  39  * indication of which bits are allowed (allow) or denied (off/deny).
  40  *      ENTRY deny
  41  *      EXIT deny
  42  *      TCP off
  43  *      MSG off
  44  *      SOCKET off
  45  *      ERROR allow
  46  *      NOTICE allow
  47  *
  48  * Writing changes the state of a given bit and requires a strictly formatted
  49  * single write() call:
  50  *
  51  *      write(fd, "allow", 5);
  52  *
  53  * Echoing allow/deny/off string into the logmask files can flip the bits
  54  * on or off as expected; here is the bash script for example:
  55  *
  56  * log_mask="/sys/fs/o2cb/log_mask"
  57  * for node in ENTRY EXIT TCP MSG SOCKET ERROR NOTICE; do
  58  *      echo allow >"$log_mask"/"$node"
  59  * done
  60  *
  61  * The debugfs.ocfs2 tool can also flip the bits with the -l option:
  62  *
  63  * debugfs.ocfs2 -l TCP allow
  64  */
  65 
  66 /* for task_struct */
  67 #include <linux/sched.h>
  68 
  69 /* bits that are frequently given and infrequently matched in the low word */
  70 /* NOTE: If you add a flag, you need to also update masklog.c! */
  71 #define ML_TCP          0x0000000000000001ULL /* net cluster/tcp.c */
  72 #define ML_MSG          0x0000000000000002ULL /* net network messages */
  73 #define ML_SOCKET       0x0000000000000004ULL /* net socket lifetime */
  74 #define ML_HEARTBEAT    0x0000000000000008ULL /* hb all heartbeat tracking */
  75 #define ML_HB_BIO       0x0000000000000010ULL /* hb io tracing */
  76 #define ML_DLMFS        0x0000000000000020ULL /* dlm user dlmfs */
  77 #define ML_DLM          0x0000000000000040ULL /* dlm general debugging */
  78 #define ML_DLM_DOMAIN   0x0000000000000080ULL /* dlm domain debugging */
  79 #define ML_DLM_THREAD   0x0000000000000100ULL /* dlm domain thread */
  80 #define ML_DLM_MASTER   0x0000000000000200ULL /* dlm master functions */
  81 #define ML_DLM_RECOVERY 0x0000000000000400ULL /* dlm master functions */
  82 #define ML_DLM_GLUE     0x0000000000000800ULL /* ocfs2 dlm glue layer */
  83 #define ML_VOTE         0x0000000000001000ULL /* ocfs2 node messaging  */
  84 #define ML_CONN         0x0000000000002000ULL /* net connection management */
  85 #define ML_QUORUM       0x0000000000004000ULL /* net connection quorum */
  86 #define ML_BASTS        0x0000000000008000ULL /* dlmglue asts and basts */
  87 #define ML_CLUSTER      0x0000000000010000ULL /* cluster stack */
  88 
  89 /* bits that are infrequently given and frequently matched in the high word */
  90 #define ML_ERROR        0x1000000000000000ULL /* sent to KERN_ERR */
  91 #define ML_NOTICE       0x2000000000000000ULL /* setn to KERN_NOTICE */
  92 #define ML_KTHREAD      0x4000000000000000ULL /* kernel thread activity */
  93 
  94 #define MLOG_INITIAL_AND_MASK (ML_ERROR|ML_NOTICE)
  95 #ifndef MLOG_MASK_PREFIX
  96 #define MLOG_MASK_PREFIX 0
  97 #endif
  98 
  99 /*
 100  * When logging is disabled, force the bit test to 0 for anything other
 101  * than errors and notices, allowing gcc to remove the code completely.
 102  * When enabled, allow all masks.
 103  */
 104 #if defined(CONFIG_OCFS2_DEBUG_MASKLOG)
 105 #define ML_ALLOWED_BITS ~0
 106 #else
 107 #define ML_ALLOWED_BITS (ML_ERROR|ML_NOTICE)
 108 #endif
 109 
 110 #define MLOG_MAX_BITS 64
 111 
 112 struct mlog_bits {
 113         unsigned long words[MLOG_MAX_BITS / BITS_PER_LONG];
 114 };
 115 
 116 extern struct mlog_bits mlog_and_bits, mlog_not_bits;
 117 
 118 #if BITS_PER_LONG == 32
 119 
 120 #define __mlog_test_u64(mask, bits)                     \
 121         ( (u32)(mask & 0xffffffff) & bits.words[0] ||   \
 122           ((u64)(mask) >> 32) & bits.words[1] )
 123 #define __mlog_set_u64(mask, bits) do {                 \
 124         bits.words[0] |= (u32)(mask & 0xffffffff);      \
 125         bits.words[1] |= (u64)(mask) >> 32;             \
 126 } while (0)
 127 #define __mlog_clear_u64(mask, bits) do {               \
 128         bits.words[0] &= ~((u32)(mask & 0xffffffff));   \
 129         bits.words[1] &= ~((u64)(mask) >> 32);          \
 130 } while (0)
 131 #define MLOG_BITS_RHS(mask) {                           \
 132         {                                               \
 133                 [0] = (u32)(mask & 0xffffffff),         \
 134                 [1] = (u64)(mask) >> 32,                \
 135         }                                               \
 136 }
 137 
 138 #else /* 32bit long above, 64bit long below */
 139 
 140 #define __mlog_test_u64(mask, bits)     ((mask) & bits.words[0])
 141 #define __mlog_set_u64(mask, bits) do {         \
 142         bits.words[0] |= (mask);                \
 143 } while (0)
 144 #define __mlog_clear_u64(mask, bits) do {       \
 145         bits.words[0] &= ~(mask);               \
 146 } while (0)
 147 #define MLOG_BITS_RHS(mask) { { (mask) } }
 148 
 149 #endif
 150 
 151 __printf(4, 5)
 152 void __mlog_printk(const u64 *m, const char *func, int line,
 153                    const char *fmt, ...);
 154 
 155 /*
 156  * Testing before the __mlog_printk call lets the compiler eliminate the
 157  * call completely when (m & ML_ALLOWED_BITS) is 0.
 158  */
 159 #define mlog(mask, fmt, ...)                                            \
 160 do {                                                                    \
 161         u64 _m = MLOG_MASK_PREFIX | (mask);                             \
 162         if (_m & ML_ALLOWED_BITS)                                       \
 163                 __mlog_printk(&_m, __func__, __LINE__, fmt,             \
 164                               ##__VA_ARGS__);                           \
 165 } while (0)
 166 
 167 #define mlog_ratelimited(mask, fmt, ...)                                \
 168 do {                                                                    \
 169         static DEFINE_RATELIMIT_STATE(_rs,                              \
 170                                       DEFAULT_RATELIMIT_INTERVAL,       \
 171                                       DEFAULT_RATELIMIT_BURST);         \
 172         if (__ratelimit(&_rs))                                          \
 173                 mlog(mask, fmt, ##__VA_ARGS__);                         \
 174 } while (0)
 175 
 176 #define mlog_errno(st) ({                                               \
 177         int _st = (st);                                                 \
 178         if (_st != -ERESTARTSYS && _st != -EINTR &&                     \
 179             _st != AOP_TRUNCATED_PAGE && _st != -ENOSPC &&              \
 180             _st != -EDQUOT)                                             \
 181                 mlog(ML_ERROR, "status = %lld\n", (long long)_st);      \
 182         _st;                                                            \
 183 })
 184 
 185 #define mlog_bug_on_msg(cond, fmt, args...) do {                        \
 186         if (cond) {                                                     \
 187                 mlog(ML_ERROR, "bug expression: " #cond "\n");          \
 188                 mlog(ML_ERROR, fmt, ##args);                            \
 189                 BUG();                                                  \
 190         }                                                               \
 191 } while (0)
 192 
 193 #include <linux/kobject.h>
 194 #include <linux/sysfs.h>
 195 int mlog_sys_init(struct kset *o2cb_subsys);
 196 void mlog_sys_shutdown(void);
 197 
 198 #endif /* O2CLUSTER_MASKLOG_H */

/* [<][>][^][v][top][bottom][index][help] */