From: Akinobu Mita <akinobu.mita@gmail.com>
To: linux-kernel@vger.kernel.org
Cc: ak@suse.de, akpm@osdl.org, Don Mullis <dwm@meer.net>,
Valdis.Kletnieks@vt.edu
Subject: [patch 7/7] stacktrace filtering for fault-injection capabilities
Date: Thu, 12 Oct 2006 16:43:12 +0900 [thread overview]
Message-ID: <452df23e.44ca1e09.1a7f.780f@mx.google.com> (raw)
In-Reply-To: 20061012074305.047696736@gmail.com
[-- Attachment #1: module-filter.patch --]
[-- Type: text/plain, Size: 6112 bytes --]
From: Akinobu Mita <akinobu.mita@gmail.com>
This patch provides stacktrace filtering feature.
The stacktrace filter allows failing only for the caller you are
interested in.
stacktrace filter is enabled by setting the value of
/debugfs/*/stacktrace-depth more than 0.
and specify the range of the virtual address
by the /debugfs/*/address-start and /debugfs/*/address-end
Please see the example that demostrates how to inject slab allocation
failures only for a specific module
in Documentation/fault-injection/fault-injection.txt
Cc: Valdis.Kletnieks@vt.edu
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Signed-off-by: Don Mullis <dwm@meer.net>
include/linux/fault-inject.h | 7 ++
lib/Kconfig.debug | 2
lib/fault-inject.c | 111 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 120 insertions(+)
Index: work-fault-inject/lib/fault-inject.c
===================================================================
--- work-fault-inject.orig/lib/fault-inject.c
+++ work-fault-inject/lib/fault-inject.c
@@ -6,6 +6,9 @@
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/interrupt.h>
+#include <linux/unwind.h>
+#include <linux/stacktrace.h>
+#include <linux/kallsyms.h>
#include <linux/fault-inject.h>
int setup_fault_attr(struct fault_attr *attr, char *str)
@@ -64,6 +67,82 @@ static int fail_task(struct fault_attr *
return !in_interrupt() && task->make_it_fail;
}
+static int fail_any_address(struct fault_attr *attr)
+{
+ return (attr->address_start == 0 && attr->address_end == ULONG_MAX);
+}
+
+#ifdef CONFIG_STACK_UNWIND
+
+static asmlinkage int fail_stacktrace_callback(struct unwind_frame_info *info,
+ void *arg)
+{
+ int depth;
+ struct fault_attr *attr = arg;
+
+ for (depth = 0; depth < attr->stacktrace_depth
+ && unwind(info) == 0 && UNW_PC(info); depth++) {
+ if (arch_unw_user_mode(info))
+ break;
+ if (attr->address_start <= UNW_PC(info) &&
+ UNW_PC(info) < attr->address_end)
+ return 1;
+ }
+ return 0;
+}
+
+static int fail_stacktrace(struct fault_attr *attr)
+{
+ struct unwind_frame_info info;
+
+ return unwind_init_running(&info, fail_stacktrace_callback, attr);
+}
+
+#elif defined(CONFIG_STACKTRACE)
+
+#define MAX_STACK_TRACE_DEPTH 10
+
+static int fail_stacktrace(struct fault_attr *attr)
+{
+ struct stack_trace trace;
+ int depth = attr->stacktrace_depth;
+ unsigned long entries[MAX_STACK_TRACE_DEPTH];
+ int n;
+
+ if (depth == 0)
+ return 0;
+
+ trace.nr_entries = 0;
+ trace.entries = entries;
+ trace.max_entries = (depth < MAX_STACK_TRACE_DEPTH) ?
+ depth : MAX_STACK_TRACE_DEPTH;
+ trace.skip = 1;
+ trace.all_contexts = 0;
+
+ save_stack_trace(&trace, NULL);
+ for (n = 0; n < trace.nr_entries; n++)
+ if (attr->address_start <= entries[n] &&
+ entries[n] < attr->address_end)
+ return 1;
+ return 0;
+}
+
+#else
+
+static inline int fail_stacktrace(struct fault_attr *attr)
+{
+ static int firsttime = 1;
+
+ if (firsttime) {
+ printk(KERN_WARNING
+ "This architecture does not implement save_stack_trace()"\n");
+ firsttime = 0;
+ }
+ return 0;
+}
+
+#endif
+
/*
* This code is stolen from failmalloc-1.0
* http://www.nongnu.org/failmalloc/
@@ -74,6 +153,9 @@ int should_fail(struct fault_attr *attr,
if (attr->task_filter && !fail_task(attr, current))
return 0;
+ if (!fail_any_address(attr) && !fail_stacktrace(attr))
+ return 0;
+
if (atomic_read(&max_failures(attr)) == 0)
return 0;
@@ -168,6 +250,18 @@ void cleanup_fault_attr_entries(struct f
debugfs_remove(attr->entries.task_filter_file);
attr->entries.task_filter_file = NULL;
}
+ if (attr->entries.stacktrace_depth_file) {
+ debugfs_remove(attr->entries.stacktrace_depth_file);
+ attr->entries.stacktrace_depth_file = NULL;
+ }
+ if (attr->entries.address_start_file) {
+ debugfs_remove(attr->entries.address_start_file);
+ attr->entries.address_start_file = NULL;
+ }
+ if (attr->entries.address_end_file) {
+ debugfs_remove(attr->entries.address_end_file);
+ attr->entries.address_end_file = NULL;
+ }
debugfs_remove(attr->entries.dir);
attr->entries.dir = NULL;
}
@@ -217,6 +311,23 @@ int init_fault_attr_entries(struct fault
goto fail;
attr->entries.task_filter_file = file;
+ file = debugfs_create_ul("stacktrace-depth", mode, dir,
+ &attr->stacktrace_depth);
+ if (!file)
+ goto fail;
+ attr->entries.stacktrace_depth_file = file;
+
+ file = debugfs_create_ul("address-start", mode, dir,
+ &attr->address_start);
+ if (!file)
+ goto fail;
+ attr->entries.address_start_file = file;
+
+ file = debugfs_create_ul("address-end", mode, dir, &attr->address_end);
+ if (!file)
+ goto fail;
+ attr->entries.address_end_file = file;
+
return 0;
fail:
cleanup_fault_attr_entries(attr);
Index: work-fault-inject/include/linux/fault-inject.h
===================================================================
--- work-fault-inject.orig/include/linux/fault-inject.h
+++ work-fault-inject/include/linux/fault-inject.h
@@ -18,6 +18,9 @@ struct fault_attr {
atomic_t space;
unsigned long verbose;
u32 task_filter;
+ unsigned long stacktrace_depth;
+ unsigned long address_start;
+ unsigned long address_end;
unsigned long count;
@@ -32,6 +35,9 @@ struct fault_attr {
struct dentry *space_file;
struct dentry *verbose_file;
struct dentry *task_filter_file;
+ struct dentry *stacktrace_depth_file;
+ struct dentry *address_start_file;
+ struct dentry *address_end_file;
} entries;
#endif
@@ -41,6 +47,7 @@ struct fault_attr {
struct fault_attr name = { \
.interval = 1, \
.times = ATOMIC_INIT(1), \
+ .address_end = ULONG_MAX, \
}
int setup_fault_attr(struct fault_attr *attr, char *str);
Index: work-fault-inject/lib/Kconfig.debug
===================================================================
--- work-fault-inject.orig/lib/Kconfig.debug
+++ work-fault-inject/lib/Kconfig.debug
@@ -472,6 +472,8 @@ config LKDTM
config FAULT_INJECTION
bool
+ select STACKTRACE
+ select FRAME_POINTER
config FAILSLAB
bool "fault-injection capabilitiy for kmalloc"
--
next prev parent reply other threads:[~2006-10-12 7:44 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20061012074305.047696736@gmail.com>
2006-10-12 7:43 ` [patch 1/7] documentation and scripts Akinobu Mita
2006-10-12 21:37 ` Andrew Morton
2006-10-13 17:47 ` Akinobu Mita
2006-10-13 19:01 ` Andrew Morton
2006-10-12 7:43 ` [patch 2/7] fault-injection capabilities infrastructure Akinobu Mita
2006-10-12 21:03 ` Andrew Morton
2006-10-12 7:43 ` [patch 3/7] fault-injection capability for kmalloc Akinobu Mita
2006-10-12 8:08 ` Pekka Enberg
2006-10-12 7:43 ` [patch 4/7] fault-injection capability for alloc_pages() Akinobu Mita
2006-10-12 21:40 ` Andrew Morton
2006-10-13 17:51 ` Akinobu Mita
2006-10-12 7:43 ` [patch 5/7] fault-injection capability for disk IO Akinobu Mita
2006-10-12 21:08 ` Andrew Morton
2006-10-13 7:03 ` Jens Axboe
2006-10-12 7:43 ` [patch 6/7] process filtering for fault-injection capabilities Akinobu Mita
2006-10-13 17:28 ` Don Mullis
2006-10-13 18:52 ` Andrew Morton
2006-10-12 7:43 ` Akinobu Mita [this message]
2006-10-12 21:20 ` [patch 7/7] stacktrace " Andrew Morton
2006-10-13 18:00 ` Akinobu Mita
2006-10-13 18:12 ` Akinobu Mita
2006-10-13 19:06 ` Andrew Morton
2006-10-13 19:03 ` Andrew Morton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=452df23e.44ca1e09.1a7f.780f@mx.google.com \
--to=akinobu.mita@gmail.com \
--cc=Valdis.Kletnieks@vt.edu \
--cc=ak@suse.de \
--cc=akpm@osdl.org \
--cc=dwm@meer.net \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.