]> granicus.if.org Git - zfs/commitdiff
Rate limit debugging stack traces
authorBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 16 Jul 2014 21:00:57 +0000 (14:00 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 22 Jul 2014 16:47:24 +0000 (09:47 -0700)
There have been issues in the past where excessive debug logging
to the console has resulted in significant performance impacts.
In the vast majority of these cases only a few stack traces are
required to diagnose the issue.  Therefore, stack traces dumped to
the console will now we limited to 5 every 60s.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Prakash Surya <surya1@llnl.gov>
Closes #374

module/spl/spl-debug.c
module/spl/spl-kmem.c

index 93c3f31b8a2604327584be855eaec0977a0c3ba6..6c4e043f05da70b0d872fab1fa840d0448f696c4 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/proc_compat.h>
 #include <linux/file_compat.h>
 #include <linux/swap.h>
+#include <linux/ratelimit.h>
 #include <sys/sysmacros.h>
 #include <sys/thread.h>
 #include <spl-debug.h>
@@ -1073,15 +1074,22 @@ spl_debug_get_mb(void)
 }
 EXPORT_SYMBOL(spl_debug_get_mb);
 
-void spl_debug_dumpstack(struct task_struct *tsk)
-{
-        extern void show_task(struct task_struct *);
+/*
+ * Limit the number of stack traces dumped to not more than 5 every
+ * 60 seconds to prevent denial-of-service attacks from debug code.
+ */
+DEFINE_RATELIMIT_STATE(dumpstack_ratelimit_state, 60 * HZ, 5);
 
-        if (tsk == NULL)
-                tsk = current;
+void
+spl_debug_dumpstack(struct task_struct *tsk)
+{
+       if (__ratelimit(&dumpstack_ratelimit_state)) {
+               if (tsk == NULL)
+                       tsk = current;
 
-        printk("SPL: Showing stack for process %d\n", tsk->pid);
-        dump_stack();
+               printk("SPL: Showing stack for process %d\n", tsk->pid);
+               dump_stack();
+       }
 }
 EXPORT_SYMBOL(spl_debug_dumpstack);
 
index e458c202013143d5fdf570007539adc9e55f542d..6389dc5aaba76086cc368d844df216b95c942533 100644 (file)
@@ -725,7 +725,7 @@ kmem_alloc_debug(size_t size, int flags, const char *func, int line,
                    "large kmem_alloc(%llu, 0x%x) at %s:%d (%lld/%llu)\n",
                    (unsigned long long) size, flags, func, line,
                    kmem_alloc_used_read(), kmem_alloc_max);
-               dump_stack();
+               spl_debug_dumpstack(NULL);
        }
 
        /* Use the correct allocator */