]> git.proxmox.com Git - mirror_zfs.git/blobdiff - include/sys/debug.h
Refresh links to web site
[mirror_zfs.git] / include / sys / debug.h
index 720e4136e7c732226c3a24f90f9385a51ed376df..25ff88e3ac21d5119c8fb7b791b98cdbbbb93113 100644 (file)
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+/*
+ * Available Solaris debug functions.  All of the ASSERT() macros will be
+ * compiled out when NDEBUG is defined, this is the default behavior for
+ * the SPL.  To enable assertions use the --enable-debug with configure.
+ * The VERIFY() functions are never compiled out and cannot be disabled.
+ *
+ * PANIC()     - Panic the node and print message.
+ * ASSERT()    - Assert X is true, if not panic.
+ * ASSERTF()   - Assert X is true, if not panic and print message.
+ * ASSERTV()   - Wraps a variable declaration which is only used by ASSERT().
+ * ASSERT3S()  - Assert signed X OP Y is true, if not panic.
+ * ASSERT3U()  - Assert unsigned X OP Y is true, if not panic.
+ * ASSERT3P()  - Assert pointer X OP Y is true, if not panic.
+ * VERIFY()    - Verify X is true, if not panic.
+ * VERIFY3S()  - Verify signed X OP Y is true, if not panic.
+ * VERIFY3U()  - Verify unsigned X OP Y is true, if not panic.
+ * VERIFY3P()  - Verify pointer X OP Y is true, if not panic.
+ */
+
 #ifndef _SPL_DEBUG_H
 #define _SPL_DEBUG_H
 
-#include <linux/sched.h> /* THREAD_SIZE */
-#include <linux/proc_fs.h>
-
-extern unsigned long spl_debug_mask;
-extern unsigned long spl_debug_subsys;
-
-#define S_UNDEFINED   0x00000001
-#define S_ATOMIC      0x00000002
-#define S_KOBJ        0x00000004
-#define S_VNODE       0x00000008
-#define S_TIME        0x00000010
-#define S_RWLOCK      0x00000020
-#define S_THREAD      0x00000040
-#define S_CONDVAR     0x00000080
-#define S_MUTEX       0x00000100
-#define S_RNG         0x00000200
-#define S_TASKQ       0x00000400
-#define S_KMEM        0x00000800
-#define S_DEBUG       0x00001000
-#define S_GENERIC     0x00002000
-#define S_PROC        0x00004000
-#define S_MODULE      0x00008000
-
-#define D_TRACE       0x00000001
-#define D_INFO        0x00000002
-#define D_WARNING     0x00000004
-#define D_ERROR       0x00000008
-#define D_EMERG       0x00000010
-#define D_CONSOLE     0x00000020
-#define D_IOCTL       0x00000040
-#define D_DPRINTF     0x00000080
-#define D_OTHER       0x00000100
-
-#define D_CANTMASK    (D_ERROR | D_EMERG | D_WARNING | D_CONSOLE)
-#define DEBUG_SUBSYSTEM S_UNDEFINED
-
-int debug_init(void);
-void debug_fini(void);
-int spl_debug_mask2str(char *str, int size, unsigned long mask, int is_subsys);
-int spl_debug_str2mask(unsigned long *mask, const char *str, int is_subsys);
-
-extern unsigned long spl_debug_subsys;
-extern unsigned long spl_debug_mask;
-extern unsigned long spl_debug_printk;
-extern int spl_debug_mb;
-extern unsigned int spl_debug_binary;
-extern unsigned int spl_debug_catastrophe;
-extern unsigned int spl_debug_panic_on_bug;
-extern char spl_debug_file_path[PATH_MAX];
-extern unsigned int spl_console_ratelimit;
-extern long spl_console_max_delay;
-extern long spl_console_min_delay;
-extern unsigned int spl_console_backoff;
-extern unsigned int spl_debug_stack;
-
-#define TCD_MAX_PAGES                  (5 << (20 - PAGE_SHIFT))
-#define TCD_STOCK_PAGES                        (TCD_MAX_PAGES)
-#define TRACE_CONSOLE_BUFFER_SIZE      1024
-
-#define SPL_DEFAULT_MAX_DELAY          (600 * HZ)
-#define SPL_DEFAULT_MIN_DELAY          ((HZ + 1) / 2)
-#define SPL_DEFAULT_BACKOFF            2
-
-typedef struct {
-        unsigned long cdls_next;
-        int           cdls_count;
-        long          cdls_delay;
-} spl_debug_limit_state_t;
-
-/* Three trace data types */
-typedef enum {
-        TCD_TYPE_PROC,
-        TCD_TYPE_SOFTIRQ,
-        TCD_TYPE_IRQ,
-        TCD_TYPE_MAX
-} tcd_type_t;
+#include <spl-debug.h>
 
-union trace_data_union {
-       struct trace_cpu_data {
-               /* pages with trace records not yet processed by tracefiled */
-               struct list_head        tcd_pages;
-               /* number of pages on ->tcd_pages */
-               unsigned long           tcd_cur_pages;
-               /* Max number of pages allowed on ->tcd_pages */
-               unsigned long           tcd_max_pages;
+#ifdef NDEBUG /* Debugging Disabled */
 
-               /*
-                * preallocated pages to write trace records into. Pages from
-                * ->tcd_stock_pages are moved to ->tcd_pages by spl_debug_msg().
-                *
-                * This list is necessary, because on some platforms it's
-                * impossible to perform efficient atomic page allocation in a
-                * non-blockable context.
-                *
-                * Such platforms fill ->tcd_stock_pages "on occasion", when
-                * tracing code is entered in blockable context.
-                *
-                * trace_get_tage_try() tries to get a page from
-                * ->tcd_stock_pages first and resorts to atomic page
-                * allocation only if this queue is empty. ->tcd_stock_pages
-                * is replenished when tracing code is entered in blocking
-                * context (darwin-tracefile.c:trace_get_tcd()). We try to
-                * maintain TCD_STOCK_PAGES (40 by default) pages in this
-                * queue. Atomic allocation is only required if more than
-                * TCD_STOCK_PAGES pagesful are consumed by trace records all
-                * emitted in non-blocking contexts. Which is quite unlikely.
-                */
-               struct list_head        tcd_stock_pages;
-               /* number of pages on ->tcd_stock_pages */
-               unsigned long           tcd_cur_stock_pages;
+/* Define SPL_DEBUG_STR to make clear which ASSERT definitions are used */
+#define SPL_DEBUG_STR  ""
 
-               unsigned short          tcd_shutting_down;
-               unsigned short          tcd_cpu;
-               unsigned short          tcd_type;
-               /* The factors to share debug memory. */
-               unsigned short          tcd_pages_factor;
-       } tcd;
-       char __pad[L1_CACHE_ALIGN(sizeof(struct trace_cpu_data))];
-};
-
-extern union trace_data_union (*trace_data[TCD_TYPE_MAX])[NR_CPUS];
+#define PANIC(fmt, a...)                                               \
+do {                                                                   \
+       printk(KERN_EMERG fmt, ## a);                                   \
+       spl_debug_bug(__FILE__, __FUNCTION__, __LINE__, 0);             \
+} while (0)
 
-#define tcd_for_each(tcd, i, j)                                       \
-    for (i = 0; trace_data[i] != NULL; i++)                           \
-        for (j = 0, ((tcd) = &(*trace_data[i])[j].tcd);               \
-             j < num_possible_cpus(); j++, (tcd) = &(*trace_data[i])[j].tcd)
+#define __ASSERT(x)                    ((void)0)
+#define ASSERT(x)                      ((void)0)
+#define ASSERTF(x, y, z...)            ((void)0)
+#define ASSERTV(x)
+#define VERIFY(cond)                                                   \
+do {                                                                   \
+       if (unlikely(!(cond)))                                          \
+               PANIC("VERIFY(" #cond ") failed\n");                    \
+} while (0)
 
-#define tcd_for_each_type_lock(tcd, i)                                \
-    for (i = 0; trace_data[i] &&                                      \
-         (tcd = &(*trace_data[i])[smp_processor_id()].tcd) &&         \
-         trace_lock_tcd(tcd); trace_unlock_tcd(tcd), i++)
+#define VERIFY3_IMPL(LEFT, OP, RIGHT, TYPE, FMT, CAST)                 \
+do {                                                                   \
+       if (!((TYPE)(LEFT) OP (TYPE)(RIGHT)))                           \
+               PANIC("VERIFY3(" #LEFT " " #OP " " #RIGHT ") "          \
+                   "failed (" FMT " " #OP " " FMT ")\n",               \
+                   CAST (LEFT), CAST (RIGHT));                         \
+} while (0)
 
-struct trace_page {
-       struct page *    page;    /* page itself */
-       struct list_head linkage;  /* Used by lists in trace_data_union */
-       unsigned int     used;     /* number of bytes used within this page */
-       unsigned short   cpu;      /* cpu that owns this page */
-       unsigned short   type;     /* type(context) of this page */
-};
+#define VERIFY3S(x,y,z)        VERIFY3_IMPL(x, y, z, int64_t, "%lld", (long long))
+#define VERIFY3U(x,y,z)        VERIFY3_IMPL(x, y, z, uint64_t, "%llu",         \
+                                   (unsigned long long))
+#define VERIFY3P(x,y,z)        VERIFY3_IMPL(x, y, z, uintptr_t, "%p", (void *))
 
-struct page_collection {
-        struct list_head  pc_pages;
-        spinlock_t        pc_lock;
-        int               pc_want_daemon_pages;
-};
+#define ASSERT3S(x,y,z)        ((void)0)
+#define ASSERT3U(x,y,z)        ((void)0)
+#define ASSERT3P(x,y,z)        ((void)0)
 
-#define SBUG()         spl_debug_bug(__FILE__, __FUNCTION__, __LINE__);
+#else /* Debugging Enabled */
 
-#ifdef  __ia64__
-#define CDEBUG_STACK() (THREAD_SIZE -                                   \
-                       ((unsigned long)__builtin_dwarf_cfa() &          \
-                       (THREAD_SIZE - 1)))
-#else
-#define CDEBUG_STACK() (THREAD_SIZE -                                   \
-                       ((unsigned long)__builtin_frame_address(0) &     \
-                        (THREAD_SIZE - 1)))
-# endif /* __ia64__ */
+/* Define SPL_DEBUG_STR to make clear which ASSERT definitions are used */
+#define SPL_DEBUG_STR  " (DEBUG mode)"
 
-#define __CHECK_STACK(file, func, line)                                 \
-do {                                                                    \
-        unsigned long _stack = CDEBUG_STACK();                          \
-       unsigned long _soft_limit = (9 * THREAD_SIZE) / 10;             \
-                                                                        \
-       if (unlikely(_stack > _soft_limit && _stack > spl_debug_stack)){\
-                spl_debug_stack = _stack;                               \
-               if (_stack <= THREAD_SIZE) {                            \
-                        spl_debug_msg(NULL, D_TRACE, D_WARNING,         \
-                                      file, func, line, "Warning "      \
-                                      "exceeded 90%% of maximum safe "  \
-                                     "stack size (%lu/%lu)\n",         \
-                                     _stack, THREAD_SIZE);             \
-                       spl_debug_dumpstack(NULL);                      \
-                       spl_debug_dumplog();                            \
-               } else {                                                \
-                        spl_debug_msg(NULL, D_TRACE, D_WARNING,         \
-                                      file, func, line, "Error "        \
-                                      "exceeded maximum safe stack "    \
-                                     "size (%lu/%lu)\n",               \
-                                     _stack, THREAD_SIZE);             \
-                       SBUG();                                         \
-               }                                                       \
-        }                                                               \
+#define PANIC(fmt, a...)                                               \
+do {                                                                   \
+       spl_debug_msg(NULL, 0, 0,                                       \
+            __FILE__, __FUNCTION__, __LINE__,  fmt, ## a);             \
+       spl_debug_bug(__FILE__, __FUNCTION__, __LINE__, 0);             \
 } while (0)
 
-#define CHECK_STACK()   __CHECK_STACK(__FILE__, __func__, __LINE__)
-
 /* ASSERTION that is safe to use within the debug system */
 #define __ASSERT(cond)                                                 \
 do {                                                                   \
        if (unlikely(!(cond))) {                                        \
-                printk(KERN_ERR "ASSERTION("#cond") failed");           \
-               SBUG();                                                 \
+           printk(KERN_EMERG "ASSERTION(" #cond ") failed\n");         \
+           BUG();                                                      \
        }                                                               \
 } while (0)
 
-#define __ASSERT_TAGE_INVARIANT(tage)                                  \
-do {                                                                   \
-        __ASSERT(tage != NULL);                                                \
-        __ASSERT(tage->page != NULL);                                  \
-        __ASSERT(tage->used <= PAGE_SIZE);                             \
-        __ASSERT(page_count(tage->page) > 0);                          \
-} while(0)
-
 /* ASSERTION that will debug log used outside the debug sysytem */
-#define ASSERT(cond)                                                    \
-do {                                                                    \
-       CHECK_STACK();                                                  \
-                                                                       \
-        if (unlikely(!(cond))) {                                        \
-                spl_debug_msg(NULL, DEBUG_SUBSYSTEM, D_EMERG,           \
-                              __FILE__, __FUNCTION__, __LINE__,         \
-                              "ASSERTION(" #cond ") failed\n");         \
-                spl_debug_bug(__FILE__, __FUNCTION__, __LINE__);        \
-       }                                                               \
+#define ASSERT(cond)                                                   \
+do {                                                                   \
+       if (unlikely(!(cond)))                                          \
+               PANIC("ASSERTION(" #cond ") failed\n");                 \
 } while (0)
 
-#define ASSERTF(cond, fmt, a...)                                        \
-do {                                                                    \
-       CHECK_STACK();                                                  \
-                                                                       \
-        if (unlikely(!(cond))) {                                        \
-                spl_debug_msg(NULL, DEBUG_SUBSYSTEM, D_EMERG,           \
-                              __FILE__, __FUNCTION__, __LINE__,         \
-                              "ASSERTION(" #cond ") failed:" fmt,       \
-                                 ## a);                                 \
-                spl_debug_bug(__FILE__, __FUNCTION__, __LINE__)         \
-        }                                                               \
+#define ASSERTF(cond, fmt, a...)                                       \
+do {                                                                   \
+       if (unlikely(!(cond)))                                          \
+               PANIC("ASSERTION(" #cond ") failed: " fmt, ## a);       \
 } while (0)
 
-#define VERIFY3_IMPL(LEFT, OP, RIGHT, TYPE, FMT, CAST)                  \
-do {                                                                    \
-        const TYPE __left = (TYPE)(LEFT);                               \
-        const TYPE __right = (TYPE)(RIGHT);                             \
-                                                                       \
-       CHECK_STACK();                                                  \
-                                                                       \
-        if (!(__left OP __right)) {                                     \
-                spl_debug_msg(NULL, DEBUG_SUBSYSTEM, D_EMERG,           \
-                              __FILE__, __FUNCTION__, __LINE__,         \
-                              "VERIFY3(" FMT " " #OP " " FMT ")\n",     \
-                              CAST __left,  CAST __right);              \
-                spl_debug_bug(__FILE__, __FUNCTION__, __LINE__);        \
-        }                                                               \
+#define VERIFY3_IMPL(LEFT, OP, RIGHT, TYPE, FMT, CAST)                 \
+do {                                                                   \
+       if (!((TYPE)(LEFT) OP (TYPE)(RIGHT)))                           \
+               PANIC("VERIFY3(" #LEFT " " #OP " " #RIGHT ") "          \
+                   "failed (" FMT " " #OP " " FMT ")\n",               \
+                   CAST (LEFT), CAST (RIGHT));                         \
 } while (0)
 
-#define VERIFY3S(x,y,z) VERIFY3_IMPL(x, y, z, int64_t, "%ld", (long))
-#define VERIFY3U(x,y,z) VERIFY3_IMPL(x, y, z, uint64_t, "%lu", (unsigned long))
-#define VERIFY3P(x,y,z) VERIFY3_IMPL(x, y, z, uintptr_t, "%p", (void *))
+#define VERIFY3S(x,y,z)        VERIFY3_IMPL(x, y, z, int64_t, "%lld", (long long))
+#define VERIFY3U(x,y,z)        VERIFY3_IMPL(x, y, z, uint64_t, "%llu",         \
+                                   (unsigned long long))
+#define VERIFY3P(x,y,z)        VERIFY3_IMPL(x, y, z, uintptr_t, "%p", (void *))
 
-#define ASSERT3S(x,y,z) VERIFY3S(x, y, z)
-#define ASSERT3U(x,y,z) VERIFY3U(x, y, z)
-#define ASSERT3P(x,y,z) VERIFY3P(x, y, z)
+#define ASSERT3S(x,y,z)        VERIFY3S(x, y, z)
+#define ASSERT3U(x,y,z)        VERIFY3U(x, y, z)
+#define ASSERT3P(x,y,z)        VERIFY3P(x, y, z)
 
+#define ASSERTV(x)     x
 #define VERIFY(x)      ASSERT(x)
 
-#define spl_debug_msg(cdls, subsys, mask, file, fn, line, format, a...) \
-        spl_debug_vmsg(cdls, subsys, mask, file, fn,                    \
-                       line, NULL, NULL, format, ##a)
-
-#define __CDEBUG(cdls, subsys, mask, format, a...)                      \
-do {                                                                    \
-        CHECK_STACK();                                                  \
-                                                                        \
-        if (((mask) & D_CANTMASK) != 0 ||                               \
-            ((spl_debug_mask & (mask)) != 0 &&                          \
-             (spl_debug_subsys & (subsys)) != 0))                       \
-                spl_debug_msg(cdls, subsys, mask,                       \
-                              __FILE__, __FUNCTION__, __LINE__,         \
-                              format, ## a);                            \
-} while (0)
-
-#define CDEBUG(mask, format, a...)                                      \
-        __CDEBUG(NULL, DEBUG_SUBSYSTEM, mask, format, ## a)
-
-#define __CDEBUG_LIMIT(subsys, mask, format, a...)                      \
-do {                                                                    \
-        static spl_debug_limit_state_t cdls;                            \
-                                                                        \
-        __CDEBUG(&cdls, subsys, mask, format, ## a);                    \
-} while (0)
-
-#define CDEBUG_LIMIT(mask, format, a...)                                \
-        __CDEBUG_LIMIT(DEBUG_SUBSYSTEM, mask, format, ## a)
-
-#define dprintf(fmt, a...)             CDEBUG_LIMIT(D_INFO, fmt, ## a)
-#define CWARN(fmt, a...)               CDEBUG_LIMIT(D_WARNING, fmt, ## a)
-#define CERROR(fmt, a...)              CDEBUG_LIMIT(D_ERROR, fmt, ## a)
-#define CEMERG(fmt, a...)              CDEBUG_LIMIT(D_EMERG, fmt, ## a)
-#define CONSOLE(mask, fmt, a...)       CDEBUG(D_CONSOLE | (mask), fmt, ## a)
-
-#define GOTO(label, rc)                                                 \
-do {                                                                    \
-        long GOTO__ret = (long)(rc);                                    \
-        CDEBUG(D_TRACE,"Process leaving via %s (rc=%lu : %ld : %lx)\n", \
-               #label, (unsigned long)GOTO__ret, (signed long)GOTO__ret,\
-               (signed long)GOTO__ret);                                 \
-        goto label;                                                     \
-} while (0)
-
-#define RETURN(rc)                                                      \
-do {                                                                    \
-        typeof(rc) RETURN__ret = (rc);                                  \
-        CDEBUG(D_TRACE, "Process leaving (rc=%lu : %ld : %lx)\n",       \
-               (long)RETURN__ret, (long)RETURN__ret, (long)RETURN__ret);\
-        return RETURN__ret;                                             \
-} while (0)
-
-#define ENTRY                                                           \
-do {                                                                    \
-        CDEBUG(D_TRACE, "Process entered\n");                           \
-} while (0)
-
-#define EXIT                                                            \
-do {                                                                    \
-        CDEBUG(D_TRACE, "Process leaving\n");                           \
-} while(0)
-
-extern int spl_debug_vmsg(spl_debug_limit_state_t *cdls, int subsys, int mask,
-                         const char *file, const char *fn, const int line,
-                         const char *format1, va_list args, const char *format2, ...);
-
-extern unsigned long spl_debug_set_mask(unsigned long mask);
-extern unsigned long spl_debug_get_mask(void);
-extern unsigned long spl_debug_set_subsys(unsigned long mask);
-extern unsigned long spl_debug_get_subsys(void);
-extern int spl_debug_set_mb(int mb);
-extern int spl_debug_get_mb(void);
-
-extern int spl_debug_dumplog(void);
-extern void spl_debug_dumpstack(struct task_struct *tsk);
-extern void spl_debug_bug(char *file, const char *func, const int line);
-
-extern int spl_debug_clear_buffer(void);
-extern int spl_debug_mark_buffer(char *text);
-
+#endif /* NDEBUG */
 #endif /* SPL_DEBUG_H */