Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1300884 > unrolled thread
| Started by | Will Deacon <will.deacon@arm.com> |
|---|---|
| First post | 2016-01-04 18:00 +0100 |
| Last post | 2016-01-05 11:10 +0100 |
| Articles | 13 — 5 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: [PATCH v2] arm64: Store breakpoint single step state into pstate Will Deacon <will.deacon@arm.com> - 2016-01-04 18:00 +0100
Re: [PATCH v2] arm64: Store breakpoint single step state into pstate "Wangnan (F)" <wangnan0@huawei.com> - 2016-01-05 02:50 +0100
[RFC PATCH] arm64: perf test: Improbe bp_signal Wang Nan <wangnan0@huawei.com> - 2016-01-05 06:10 +0100
Re: [RFC PATCH] arm64: perf test: Improbe bp_signal "Wangnan (F)" <wangnan0@huawei.com> - 2016-01-05 06:20 +0100
Re: [RFC PATCH] arm64: perf test: Improbe bp_signal Jiri Olsa <jolsa@redhat.com> - 2016-01-05 10:00 +0100
Re: [RFC PATCH] arm64: perf test: Improbe bp_signal Jiri Olsa <jolsa@redhat.com> - 2016-01-05 10:10 +0100
Re: [RFC PATCH] arm64: perf test: Improbe bp_signal Jiri Olsa <jolsa@redhat.com> - 2016-01-05 10:10 +0100
Re: [RFC PATCH] arm64: perf test: Improbe bp_signal Jiri Olsa <jolsa@redhat.com> - 2016-01-05 10:10 +0100
Re: [PATCH v2] arm64: Store breakpoint single step state into pstate "Wangnan (F)" <wangnan0@huawei.com> - 2016-01-05 06:10 +0100
Re: [PATCH v2] arm64: Store breakpoint single step state into pstate Will Deacon <will.deacon@arm.com> - 2016-01-12 18:10 +0100
Re: [PATCH v2] arm64: Store breakpoint single step state into pstate xiakaixu <xiakaixu@huawei.com> - 2016-01-15 09:30 +0100
[RFC PATCH v2] perf test: Improve bp_signal Wang Nan <wangnan0@huawei.com> - 2016-01-05 11:00 +0100
Re: [RFC PATCH v2] perf test: Improve bp_signal Jiri Olsa <jolsa@redhat.com> - 2016-01-05 11:10 +0100
| From | Will Deacon <will.deacon@arm.com> |
|---|---|
| Date | 2016-01-04 18:00 +0100 |
| Subject | Re: [PATCH v2] arm64: Store breakpoint single step state into pstate |
| Message-ID | <qNgEa-609-13@gated-at.bofh.it> |
Hello,
On Thu, Dec 24, 2015 at 01:42:42AM +0000, Wang Nan wrote:
> Two 'perf test' fail on arm64:
>
> # perf test overflow
> 17: Test breakpoint overflow signal handler : FAILED!
> 18: Test breakpoint overflow sampling : FAILED!
>
> When breakpoint raises, after perf_bp_event, breakpoint_handler()
> temporary disables breakpoint and enables single step. Then in
> single_step_handler(), reenable breakpoint. Without doing this
> the breakpoint would be triggered again.
>
> However, if there's a pending signal and it have signal handler,
> control would be transfer to signal handler, so single step handler
> would be applied to the first instruction of signal handler. After
> the handler return, the instruction triggered the breakpoint would be
> executed again. At this time the breakpoint is enabled, so the
> breakpoint is triggered again.
Whilst I appreciate that you're just trying to get those tests passing
on arm64, I really don't think its a good idea for us to try and emulate
the x86 debug semantics here. This doesn't happen for ptrace, and I think
we're likely to break more than we fix if we try to do it for perf too.
The problem seems to be that we take the debug exception before the
breakpointed instruction has been executed and call perf_bp_event at
that moment, so when we single-step the faulting instruction we actually
step into the SIGIO handler and end up getting stuck.
Your fix doesn't really address this afaict, in that you don't (can't?)
handle:
* A longjmp out of a signal handler
* A watchpoint and a breakpoint that fire on the same instruction
* User-controlled single-step from a signal handler that enables a
breakpoint explicitly
* Nested signals
so I'd really rather leave the code as-is.
Will
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | "Wangnan (F)" <wangnan0@huawei.com> |
|---|---|
| Date | 2016-01-05 02:50 +0100 |
| Message-ID | <qNoV3-3ix-1@gated-at.bofh.it> |
| In reply to | #1300884 |
On 2016/1/5 0:55, Will Deacon wrote: > Hello, > > On Thu, Dec 24, 2015 at 01:42:42AM +0000, Wang Nan wrote: >> Two 'perf test' fail on arm64: >> >> # perf test overflow >> 17: Test breakpoint overflow signal handler : FAILED! >> 18: Test breakpoint overflow sampling : FAILED! >> >> When breakpoint raises, after perf_bp_event, breakpoint_handler() >> temporary disables breakpoint and enables single step. Then in >> single_step_handler(), reenable breakpoint. Without doing this >> the breakpoint would be triggered again. >> >> However, if there's a pending signal and it have signal handler, >> control would be transfer to signal handler, so single step handler >> would be applied to the first instruction of signal handler. After >> the handler return, the instruction triggered the breakpoint would be >> executed again. At this time the breakpoint is enabled, so the >> breakpoint is triggered again. > Whilst I appreciate that you're just trying to get those tests passing > on arm64, I really don't think its a good idea for us to try and emulate > the x86 debug semantics here. This doesn't happen for ptrace, and I think > we're likely to break more than we fix if we try to do it for perf too. > > The problem seems to be that we take the debug exception before the > breakpointed instruction has been executed and call perf_bp_event at > that moment, so when we single-step the faulting instruction we actually > step into the SIGIO handler and end up getting stuck. Understand. > Your fix doesn't really address this afaict, I don't think so. After applying my patch, the entry of signal handler won't be single-stepped. Please have a look at signal_toggle_single_step(): when signal arises, single step handler is turned off, so signal handler won't be stepped. I thing the following 4 cases you mentioned should not causes error in theory: > in that you don't (can't?) > handle: > > * A longjmp out of a signal handler The signal frame is dropped so stepping is omitted. > * A watchpoint and a breakpoint that fire on the same instruction Watchpoints and breakpoints are controlled separatly. In this case it would generated twp nested signals. I will try this. > * User-controlled single-step from a signal handler that enables a > breakpoint explicitly debug_info->suspended_step controls this. > * Nested signals I think nested signals can be dealt correctly because we save state in signal frame. However I'll try the above cases you mentioned above. Thank you. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Wang Nan <wangnan0@huawei.com> |
|---|---|
| Date | 2016-01-05 06:10 +0100 |
| Subject | [RFC PATCH] arm64: perf test: Improbe bp_signal |
| Message-ID | <qNs2C-5ze-7@gated-at.bofh.it> |
| In reply to | #1300884 |
Will Deacon [1] has some question on patch [2]. This patch improves
test__bp_signal so we can test:
1. A watchpoint and a breakpoint that fire on the same instruction
2. Nested signals
For detail of this patch see the comment in patch body.
Test result:
On both x86_64:
# ./perf test -v signal
17: Test breakpoint overflow signal handler :
--- start ---
test child forked, pid 10213
count1 1, count2 3, count3 2, overflow 3, overflows_2 3
test child finished with 0
---- end ----
Test breakpoint overflow signal handler: Ok
So at least 2 cases Will doubted are handled correctly.
[1] http://lkml.kernel.org/g/20160104165535.GI1616@arm.com
[2] http://lkml.kernel.org/g/1450921362-198371-1-git-send-email-wangnan0@huawei.com
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/tests/bp_signal.c | 114 ++++++++++++++++++++++++++++++++++++++-----
1 file changed, 101 insertions(+), 13 deletions(-)
diff --git a/tools/perf/tests/bp_signal.c b/tools/perf/tests/bp_signal.c
index fb80c9e..0bc4f76 100644
--- a/tools/perf/tests/bp_signal.c
+++ b/tools/perf/tests/bp_signal.c
@@ -29,14 +29,55 @@
static int fd1;
static int fd2;
+static int fd3;
static int overflows;
+static int overflows_2;
+
+volatile long the_var;
+
+
+#if defined (__x86_64__)
+extern void __test_function(volatile long *ptr);
+asm (
+ ".globl __test_function\n"
+ "__test_function:\n"
+ "incq (%rdi)\n"
+ "ret\n");
+#elif defined (__aarch64__)
+extern void __test_function(volatile long *ptr);
+asm (
+ ".globl __test_function\n"
+ "__test_function:\n"
+ "str x30, [x0]\n"
+ "ret\n");
+
+#else
+static void __test_function(volatile long *ptr)
+{
+ *ptr++;
+}
+#endif
__attribute__ ((noinline))
static int test_function(void)
{
+ __test_function(&the_var);
+ the_var++;
return time(NULL);
}
+static void sig_handler_2(int signum __maybe_unused,
+ siginfo_t *oh __maybe_unused,
+ void *uc __maybe_unused)
+{
+ overflows_2++;
+ if (overflows_2 > 10) {
+ ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0);
+ ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0);
+ ioctl(fd3, PERF_EVENT_IOC_DISABLE, 0);
+ }
+}
+
static void sig_handler(int signum __maybe_unused,
siginfo_t *oh __maybe_unused,
void *uc __maybe_unused)
@@ -54,10 +95,11 @@ static void sig_handler(int signum __maybe_unused,
*/
ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0);
ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0);
+ ioctl(fd3, PERF_EVENT_IOC_DISABLE, 0);
}
}
-static int bp_event(void *fn, int setup_signal)
+static int __xp_event(bool is_bp, void *addr, int setup_signal, int signal)
{
struct perf_event_attr pe;
int fd;
@@ -67,8 +109,8 @@ static int bp_event(void *fn, int setup_signal)
pe.size = sizeof(struct perf_event_attr);
pe.config = 0;
- pe.bp_type = HW_BREAKPOINT_X;
- pe.bp_addr = (unsigned long) fn;
+ pe.bp_type = is_bp ? HW_BREAKPOINT_X : HW_BREAKPOINT_W;
+ pe.bp_addr = (unsigned long) addr;
pe.bp_len = sizeof(long);
pe.sample_period = 1;
@@ -88,7 +130,7 @@ static int bp_event(void *fn, int setup_signal)
if (setup_signal) {
fcntl(fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC);
- fcntl(fd, F_SETSIG, SIGIO);
+ fcntl(fd, F_SETSIG, signal);
fcntl(fd, F_SETOWN, getpid());
}
@@ -97,6 +139,16 @@ static int bp_event(void *fn, int setup_signal)
return fd;
}
+static int bp_event(void *addr, int setup_signal)
+{
+ return __xp_event(true, addr, setup_signal, SIGIO);
+}
+
+static int wp_event(void *addr, int setup_signal)
+{
+ return __xp_event(false, addr, setup_signal, SIGIO);
+}
+
static long long bp_count(int fd)
{
long long count;
@@ -114,7 +166,7 @@ static long long bp_count(int fd)
int test__bp_signal(int subtest __maybe_unused)
{
struct sigaction sa;
- long long count1, count2;
+ long long count1, count2, count3;
/* setup SIGIO signal handler */
memset(&sa, 0, sizeof(struct sigaction));
@@ -126,6 +178,12 @@ int test__bp_signal(int subtest __maybe_unused)
return TEST_FAIL;
}
+ sa.sa_sigaction = (void *) sig_handler_2;
+ if (sigaction(SIGUSR1, &sa, NULL) < 0) {
+ pr_debug("failed setting up signal handler 2\n");
+ return TEST_FAIL;
+ }
+
/*
* We create following events:
*
@@ -133,7 +191,11 @@ int test__bp_signal(int subtest __maybe_unused)
* signal configured. We should get signal
* notification each time the breakpoint is hit
*
- * fd2 - breakpoint event on sig_handler without SIGIO
+ * fd2 - breakpoint event on sig_handler with SIGUSR1
+ * configured. We should get SIGUSR1 each time when
+ * breakpoint is hit
+ *
+ * fd3 - watchpoint event on test_function with SIGIO
* configured.
*
* Following processing should happen:
@@ -141,6 +203,21 @@ int test__bp_signal(int subtest __maybe_unused)
* - fd1 event breakpoint hit -> count1 == 1
* - SIGIO is delivered -> overflows == 1
* - fd2 event breakpoint hit -> count2 == 1
+ * - SIGUSR1 is delivered -> overflows_2 == 1 (nested signal)
+ * - sig_handler_2 return
+ * - sig_handler return
+ * - fd3 event watchpoint hit -> count3 == 1 (wp and bp in one insn)
+ * - SIGIO is delivered -> overflows == 2
+ * - fd2 event breakpoint hit -> count2 == 2
+ * - SIGUSR1 is delivered -> overflows_2 == 2
+ * - sig_handler_2 return
+ * - sig_handler return
+ * - fd3 event watchpoint hit -> count3 == 2 (standalone wp)
+ * - SIGIO is delivered -> overflows = 3
+ * - fd2 event breakpoint hit -> count2 == 3
+ * - SIGUSR1 is delivered -> overflows_2 == 3
+ * - sig_handler_2 return
+ * - sig_handler return
*
* The test case check following error conditions:
* - we get stuck in signal handler because of debug
@@ -152,11 +229,13 @@ int test__bp_signal(int subtest __maybe_unused)
*
*/
- fd1 = bp_event(test_function, 1);
- fd2 = bp_event(sig_handler, 0);
+ fd1 = bp_event(__test_function, 1);
+ fd2 = __xp_event(true, sig_handler, 1, SIGUSR1);
+ fd3 = wp_event((void *)&the_var, 1);
ioctl(fd1, PERF_EVENT_IOC_ENABLE, 0);
ioctl(fd2, PERF_EVENT_IOC_ENABLE, 0);
+ ioctl(fd3, PERF_EVENT_IOC_ENABLE, 0);
/*
* Kick off the test by trigering 'fd1'
@@ -166,15 +245,18 @@ int test__bp_signal(int subtest __maybe_unused)
ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0);
ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0);
+ ioctl(fd3, PERF_EVENT_IOC_DISABLE, 0);
count1 = bp_count(fd1);
count2 = bp_count(fd2);
+ count3 = bp_count(fd3);
close(fd1);
close(fd2);
+ close(fd3);
- pr_debug("count1 %lld, count2 %lld, overflow %d\n",
- count1, count2, overflows);
+ pr_debug("count1 %lld, count2 %lld, count3 %lld, overflow %d, overflows_2 %d\n",
+ count1, count2, count3, overflows, overflows_2);
if (count1 != 1) {
if (count1 == 11)
@@ -183,12 +265,18 @@ int test__bp_signal(int subtest __maybe_unused)
pr_debug("failed: wrong count for bp1%lld\n", count1);
}
- if (overflows != 1)
+ if (overflows != 3)
pr_debug("failed: wrong overflow hit\n");
- if (count2 != 1)
+ if (overflows_2 != 3)
+ pr_debug("failed: wrong overflow_2 hit\n");
+
+ if (count2 != 3)
pr_debug("failed: wrong count for bp2\n");
- return count1 == 1 && overflows == 1 && count2 == 1 ?
+ if (count3 != 2)
+ pr_debug("failed: wrong count for bp3\n");
+
+ return count1 == 1 && overflows == 3 && count2 == 3 && overflows_2 == 3 && count3 == 2 ?
TEST_OK : TEST_FAIL;
}
--
1.8.3.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | "Wangnan (F)" <wangnan0@huawei.com> |
|---|---|
| Date | 2016-01-05 06:20 +0100 |
| Subject | Re: [RFC PATCH] arm64: perf test: Improbe bp_signal |
| Message-ID | <qNsch-5Co-1@gated-at.bofh.it> |
| In reply to | #1301274 |
On 2016/1/5 12:58, Wang Nan wrote: > Will Deacon [1] has some question on patch [2]. This patch improves > test__bp_signal so we can test: > > 1. A watchpoint and a breakpoint that fire on the same instruction > 2. Nested signals > > For detail of this patch see the comment in patch body. > > Test result: > > On both x86_64: On x86_64 and arm64. Sorry. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Jiri Olsa <jolsa@redhat.com> |
|---|---|
| Date | 2016-01-05 10:00 +0100 |
| Subject | Re: [RFC PATCH] arm64: perf test: Improbe bp_signal |
| Message-ID | <qNvDc-84L-19@gated-at.bofh.it> |
| In reply to | #1301274 |
On Tue, Jan 05, 2016 at 04:58:00AM +0000, Wang Nan wrote:
SNIP
> diff --git a/tools/perf/tests/bp_signal.c b/tools/perf/tests/bp_signal.c
> index fb80c9e..0bc4f76 100644
> --- a/tools/perf/tests/bp_signal.c
> +++ b/tools/perf/tests/bp_signal.c
> @@ -29,14 +29,55 @@
>
> static int fd1;
> static int fd2;
> +static int fd3;
> static int overflows;
> +static int overflows_2;
> +
> +volatile long the_var;
> +
> +
please put comment in here explaning the assembly is used
to have watchpoint and breakpoint on single instruction
IIUC ;-)
thanks,
jirka
> +#if defined (__x86_64__)
> +extern void __test_function(volatile long *ptr);
> +asm (
> + ".globl __test_function\n"
> + "__test_function:\n"
> + "incq (%rdi)\n"
> + "ret\n");
> +#elif defined (__aarch64__)
> +extern void __test_function(volatile long *ptr);
> +asm (
> + ".globl __test_function\n"
> + "__test_function:\n"
> + "str x30, [x0]\n"
> + "ret\n");
> +
> +#else
> +static void __test_function(volatile long *ptr)
> +{
> + *ptr++;
> +}
> +#endif
>
> __attribute__ ((noinline))
> static int test_function(void)
> {
> + __test_function(&the_var);
> + the_var++;
> return time(NULL);
> }
SNIP
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Jiri Olsa <jolsa@redhat.com> |
|---|---|
| Date | 2016-01-05 10:10 +0100 |
| Subject | Re: [RFC PATCH] arm64: perf test: Improbe bp_signal |
| Message-ID | <qNvMS-8om-7@gated-at.bofh.it> |
| In reply to | #1301274 |
On Tue, Jan 05, 2016 at 04:58:00AM +0000, Wang Nan wrote:
SNIP
> + * - SIGUSR1 is delivered -> overflows_2 == 1 (nested signal)
> + * - sig_handler_2 return
> + * - sig_handler return
> + * - fd3 event watchpoint hit -> count3 == 1 (wp and bp in one insn)
> + * - SIGIO is delivered -> overflows == 2
> + * - fd2 event breakpoint hit -> count2 == 2
> + * - SIGUSR1 is delivered -> overflows_2 == 2
> + * - sig_handler_2 return
> + * - sig_handler return
> + * - fd3 event watchpoint hit -> count3 == 2 (standalone wp)
> + * - SIGIO is delivered -> overflows = 3
> + * - fd2 event breakpoint hit -> count2 == 3
> + * - SIGUSR1 is delivered -> overflows_2 == 3
> + * - sig_handler_2 return
> + * - sig_handler return
> *
> * The test case check following error conditions:
> * - we get stuck in signal handler because of debug
> @@ -152,11 +229,13 @@ int test__bp_signal(int subtest __maybe_unused)
> *
> */
>
> - fd1 = bp_event(test_function, 1);
> - fd2 = bp_event(sig_handler, 0);
> + fd1 = bp_event(__test_function, 1);
> + fd2 = __xp_event(true, sig_handler, 1, SIGUSR1);
> + fd3 = wp_event((void *)&the_var, 1);
>
spent some time to figure this out.. would attached change be more readable?
thanks,
jirka
---
diff --git a/tools/perf/tests/bp_signal.c b/tools/perf/tests/bp_signal.c
index 0bc4f76c22ca..e5349616ac3f 100644
--- a/tools/perf/tests/bp_signal.c
+++ b/tools/perf/tests/bp_signal.c
@@ -99,7 +99,7 @@ static void sig_handler(int signum __maybe_unused,
}
}
-static int __xp_event(bool is_bp, void *addr, int setup_signal, int signal)
+static int __event(bool is_x, void *addr, int signal)
{
struct perf_event_attr pe;
int fd;
@@ -109,7 +109,7 @@ static int __xp_event(bool is_bp, void *addr, int setup_signal, int signal)
pe.size = sizeof(struct perf_event_attr);
pe.config = 0;
- pe.bp_type = is_bp ? HW_BREAKPOINT_X : HW_BREAKPOINT_W;
+ pe.bp_type = is_x ? HW_BREAKPOINT_X : HW_BREAKPOINT_W;
pe.bp_addr = (unsigned long) addr;
pe.bp_len = sizeof(long);
@@ -128,25 +128,23 @@ static int __xp_event(bool is_bp, void *addr, int setup_signal, int signal)
return TEST_FAIL;
}
- if (setup_signal) {
- fcntl(fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC);
- fcntl(fd, F_SETSIG, signal);
- fcntl(fd, F_SETOWN, getpid());
- }
+ fcntl(fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC);
+ fcntl(fd, F_SETSIG, signal);
+ fcntl(fd, F_SETOWN, getpid());
ioctl(fd, PERF_EVENT_IOC_RESET, 0);
return fd;
}
-static int bp_event(void *addr, int setup_signal)
+static int bp_event(void *addr, int signal)
{
- return __xp_event(true, addr, setup_signal, SIGIO);
+ return __event(true, addr, signal);
}
-static int wp_event(void *addr, int setup_signal)
+static int wp_event(void *addr, int signal)
{
- return __xp_event(false, addr, setup_signal, SIGIO);
+ return __event(false, addr, signal);
}
static long long bp_count(int fd)
@@ -229,9 +227,9 @@ int test__bp_signal(int subtest __maybe_unused)
*
*/
- fd1 = bp_event(__test_function, 1);
- fd2 = __xp_event(true, sig_handler, 1, SIGUSR1);
- fd3 = wp_event((void *)&the_var, 1);
+ fd1 = bp_event(__test_function, SIGIO);
+ fd2 = bp_event(sig_handler, SIGUSR1);
+ fd3 = wp_event((void *)&the_var, SIGIO);
ioctl(fd1, PERF_EVENT_IOC_ENABLE, 0);
ioctl(fd2, PERF_EVENT_IOC_ENABLE, 0);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Jiri Olsa <jolsa@redhat.com> |
|---|---|
| Date | 2016-01-05 10:10 +0100 |
| Subject | Re: [RFC PATCH] arm64: perf test: Improbe bp_signal |
| Message-ID | <qNvMS-8om-11@gated-at.bofh.it> |
| In reply to | #1301274 |
On Tue, Jan 05, 2016 at 04:58:00AM +0000, Wang Nan wrote:
SNIP
> * Following processing should happen:
> @@ -141,6 +203,21 @@ int test__bp_signal(int subtest __maybe_unused)
> * - fd1 event breakpoint hit -> count1 == 1
> * - SIGIO is delivered -> overflows == 1
> * - fd2 event breakpoint hit -> count2 == 1
> + * - SIGUSR1 is delivered -> overflows_2 == 1 (nested signal)
> + * - sig_handler_2 return
> + * - sig_handler return
> + * - fd3 event watchpoint hit -> count3 == 1 (wp and bp in one insn)
> + * - SIGIO is delivered -> overflows == 2
> + * - fd2 event breakpoint hit -> count2 == 2
> + * - SIGUSR1 is delivered -> overflows_2 == 2
> + * - sig_handler_2 return
> + * - sig_handler return
> + * - fd3 event watchpoint hit -> count3 == 2 (standalone wp)
> + * - SIGIO is delivered -> overflows = 3
> + * - fd2 event breakpoint hit -> count2 == 3
> + * - SIGUSR1 is delivered -> overflows_2 == 3
> + * - sig_handler_2 return
> + * - sig_handler return
also each line in here could be prefixed with 'code action'
that led to the result on the line, like:
* exec: result:
*
* __test_function - fd1 event breakpoint hit -> count1 == 1
* - SIGIO is delivered -> overflows == 1
* sig_handler - fd2 event breakpoint hit -> count2 == 1
* - SIGUSR1 is delivered -> overflows_2 == 1 (nested signal)
* - sig_handler_2 return
* - sig_handler return
* incq (%rdi) - fd3 event watchpoint hit -> count3 == 1 (wp and bp in one insn)
* - SIGIO is delivered -> overflows == 2
hum.. but it might take all the fun out of it ;-)
jirka
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Jiri Olsa <jolsa@redhat.com> |
|---|---|
| Date | 2016-01-05 10:10 +0100 |
| Subject | Re: [RFC PATCH] arm64: perf test: Improbe bp_signal |
| Message-ID | <qNvMS-8om-13@gated-at.bofh.it> |
| In reply to | #1301274 |
On Tue, Jan 05, 2016 at 04:58:00AM +0000, Wang Nan wrote: > Will Deacon [1] has some question on patch [2]. This patch improves > test__bp_signal so we can test: there's typo (s/Improbe/Improve) in subject ;-) jirka -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | "Wangnan (F)" <wangnan0@huawei.com> |
|---|---|
| Date | 2016-01-05 06:10 +0100 |
| Message-ID | <qNs2C-5ze-5@gated-at.bofh.it> |
| In reply to | #1300884 |
Hi Will, On 2016/1/5 0:55, Will Deacon wrote: > Hello, > > On Thu, Dec 24, 2015 at 01:42:42AM +0000, Wang Nan wrote: [SNIP] > The problem seems to be that we take the debug exception before the > breakpointed instruction has been executed and call perf_bp_event at > that moment, so when we single-step the faulting instruction we actually > step into the SIGIO handler and end up getting stuck. > > Your fix doesn't really address this afaict, in that you don't (can't?) > handle: > > * A longjmp out of a signal handler > * A watchpoint and a breakpoint that fire on the same instruction > * User-controlled single-step from a signal handler that enables a > breakpoint explicitly > * Nested signals Please have a look at [1], which I improve test__bp_signal() to check bullet 2 and 4 you mentioned above. Seems my fix is correct. [1] http://lkml.kernel.org/g/1451969880-14877-1-git-send-email-wangnan0@huawei.com Thank you. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Will Deacon <will.deacon@arm.com> |
|---|---|
| Date | 2016-01-12 18:10 +0100 |
| Message-ID | <qQaCe-3TN-15@gated-at.bofh.it> |
| In reply to | #1301275 |
On Tue, Jan 05, 2016 at 01:06:15PM +0800, Wangnan (F) wrote: > On 2016/1/5 0:55, Will Deacon wrote: > >The problem seems to be that we take the debug exception before the > >breakpointed instruction has been executed and call perf_bp_event at > >that moment, so when we single-step the faulting instruction we actually > >step into the SIGIO handler and end up getting stuck. > > > >Your fix doesn't really address this afaict, in that you don't (can't?) > >handle: > > > > * A longjmp out of a signal handler > > * A watchpoint and a breakpoint that fire on the same instruction > > * User-controlled single-step from a signal handler that enables a > > breakpoint explicitly > > * Nested signals > > Please have a look at [1], which I improve test__bp_signal() to > check bullet 2 and 4 you mentioned above. Seems my fix is correct. > > [1] http://lkml.kernel.org/g/1451969880-14877-1-git-send-email-wangnan0@huawei.com I'm still really uneasy about this change. Pairing up the signal delivery with the sigreturn to keep track of the debug state is extremely fragile and I'm not keen on adding this logic there. I also think we need to track the address that the breakpoint is originally taken on so that we can only perform the extra sigreturn work if we're returning to the same instruction. Furthermore, I wouldn't want to do this for signals other than those generated directly by a breakpoint. An alternative would be to postpone the signal delivery until after the stepping has been taken care of, but that's a change in ABI and I worry we'll break somebody relying on the current behaviour. What exactly does x86 do? I couldn't figure it out from the code. Will
[toc] | [prev] | [next] | [standalone]
| From | xiakaixu <xiakaixu@huawei.com> |
|---|---|
| Date | 2016-01-15 09:30 +0100 |
| Message-ID | <qR7VE-3qX-25@gated-at.bofh.it> |
| In reply to | #1307638 |
δΊ 2016/1/13 1:06, Will Deacon ει:
> On Tue, Jan 05, 2016 at 01:06:15PM +0800, Wangnan (F) wrote:
>> On 2016/1/5 0:55, Will Deacon wrote:
>>> The problem seems to be that we take the debug exception before the
>>> breakpointed instruction has been executed and call perf_bp_event at
>>> that moment, so when we single-step the faulting instruction we actually
>>> step into the SIGIO handler and end up getting stuck.
>>>
>>> Your fix doesn't really address this afaict, in that you don't (can't?)
>>> handle:
>>>
>>> * A longjmp out of a signal handler
>>> * A watchpoint and a breakpoint that fire on the same instruction
>>> * User-controlled single-step from a signal handler that enables a
>>> breakpoint explicitly
>>> * Nested signals
>>
>> Please have a look at [1], which I improve test__bp_signal() to
>> check bullet 2 and 4 you mentioned above. Seems my fix is correct.
>>
>> [1] http://lkml.kernel.org/g/1451969880-14877-1-git-send-email-wangnan0@huawei.com
>
> I'm still really uneasy about this change. Pairing up the signal delivery
> with the sigreturn to keep track of the debug state is extremely fragile
> and I'm not keen on adding this logic there. I also think we need to
> track the address that the breakpoint is originally taken on so that we
> can only perform the extra sigreturn work if we're returning to the same
> instruction. Furthermore, I wouldn't want to do this for signals other
> than those generated directly by a breakpoint.
>
> An alternative would be to postpone the signal delivery until after the
> stepping has been taken care of, but that's a change in ABI and I worry
> we'll break somebody relying on the current behaviour.
>
> What exactly does x86 do? I couldn't figure it out from the code.
Hi Will,
I changed the signal SIGIO to SIGUSR2 according to the patch that Wang Nan
sent out about improving test__bp_signal() to check bullet 2 and 4 you mentioned.
I tested it with arm64 qemu and gdb. The single instruction execution on qemu
shows that the result is the same as the processing described in Wang Nan's patch[2].
I also tested the patch on x86 qemu and found that the result is the same as
arm64 qemu.
[1]
tools/perf/tests/bp_signal.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/perf/tests/bp_signal.c b/tools/perf/tests/bp_signal.c
index 1d1bb48..3046cba 100644
--- a/tools/perf/tests/bp_signal.c
+++ b/tools/perf/tests/bp_signal.c
@@ -175,7 +175,7 @@ int test__bp_signal(int subtest __maybe_unused)
sa.sa_sigaction = (void *) sig_handler;
sa.sa_flags = SA_SIGINFO;
- if (sigaction(SIGIO, &sa, NULL) < 0) {
+ if (sigaction(SIGUSR2, &sa, NULL) < 0) {
pr_debug("failed setting up signal handler\n");
return TEST_FAIL;
}
@@ -237,9 +237,9 @@ int test__bp_signal(int subtest __maybe_unused)
*
*/
- fd1 = bp_event(__test_function, SIGIO);
+ fd1 = bp_event(__test_function, SIGUSR2);
fd2 = bp_event(sig_handler, SIGUSR1);
- fd3 = wp_event((void *)&the_var, SIGIO);
+ fd3 = wp_event((void *)&the_var, SIGUSR2);
ioctl(fd1, PERF_EVENT_IOC_ENABLE, 0);
ioctl(fd2, PERF_EVENT_IOC_ENABLE, 0);
[2]
* Following processing should happen:
* Exec: Action: Result:
* incq (%rdi) - fd1 event breakpoint hit -> count1 == 1
* - SIGIO is delivered
* sig_handler - fd2 event breakpoint hit -> count2 == 1
* - SIGUSR1 is delivered
* sig_handler_2 -> overflows_2 == 1 (nested signal)
* sys_rt_sigreturn - return from sig_handler_2
* overflows++ -> overflows = 1
* sys_rt_sigreturn - return from sig_handler
* incq (%rdi) - fd3 event watchpoint hit -> count3 == 1 (wp and bp in one insn)
* - SIGIO is delivered
* sig_handler - fd2 event breakpoint hit -> count2 == 2
* - SIGUSR1 is delivered
* sig_handler_2 -> overflows_2 == 2 (nested signal)
* sys_rt_sigreturn - return from sig_handler_2
* overflows++ -> overflows = 2
* sys_rt_sigreturn - return from sig_handler
* the_var++ - fd3 event watchpoint hit -> count3 == 2 (standalone watchpoint)
* - SIGIO is delivered
* sig_handler - fd2 event breakpoint hit -> count2 == 3
* - SIGUSR1 is delivered
* sig_handler_2 -> overflows_2 == 3 (nested signal)
* sys_rt_sigreturn - return from sig_handler_2
* overflows++ -> overflows == 3
* sys_rt_sigreturn - return from sig_handler
>
> Will
>
> .
>
--
Regards
Kaixu Xia
[toc] | [prev] | [next] | [standalone]
| From | Wang Nan <wangnan0@huawei.com> |
|---|---|
| Date | 2016-01-05 11:00 +0100 |
| Subject | [RFC PATCH v2] perf test: Improve bp_signal |
| Message-ID | <qNwzg-j5-19@gated-at.bofh.it> |
| In reply to | #1300884 |
Will Deacon [1] has some question on patch [2]. This patch improves
test__bp_signal so we can test:
1. A watchpoint and a breakpoint that fire on the same instruction
2. Nested signals
Test result:
On x86_64 and ARM64 (result are similar with patch [2] on ARM64):
# ./perf test -v signal
17: Test breakpoint overflow signal handler :
--- start ---
test child forked, pid 10213
count1 1, count2 3, count3 2, overflow 3, overflows_2 3
test child finished with 0
---- end ----
Test breakpoint overflow signal handler: Ok
So at least 2 cases Will doubted are handled correctly.
[1] http://lkml.kernel.org/g/20160104165535.GI1616@arm.com
[2] http://lkml.kernel.org/g/1450921362-198371-1-git-send-email-wangnan0@huawei.com
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
---
v1 -> v2: Improve readability, fix typo. Thanks to Jiri Olsa.
To Jiri: I guess you will be okay to provide your SOB for your code at [3],
so I add it in this v2 patch.
[3] http://lkml.kernel.org/g/20160105090030.GC2192@krava.brq.redhat.com
---
tools/perf/tests/bp_signal.c | 140 ++++++++++++++++++++++++++++++++++++-------
1 file changed, 118 insertions(+), 22 deletions(-)
diff --git a/tools/perf/tests/bp_signal.c b/tools/perf/tests/bp_signal.c
index fb80c9e..1d1bb48 100644
--- a/tools/perf/tests/bp_signal.c
+++ b/tools/perf/tests/bp_signal.c
@@ -29,14 +29,59 @@
static int fd1;
static int fd2;
+static int fd3;
static int overflows;
+static int overflows_2;
+
+volatile long the_var;
+
+
+/*
+ * Use ASM to ensure watchpoint and breakpoint can be triggered
+ * at one instruction.
+ */
+#if defined (__x86_64__)
+extern void __test_function(volatile long *ptr);
+asm (
+ ".globl __test_function\n"
+ "__test_function:\n"
+ "incq (%rdi)\n"
+ "ret\n");
+#elif defined (__aarch64__)
+extern void __test_function(volatile long *ptr);
+asm (
+ ".globl __test_function\n"
+ "__test_function:\n"
+ "str x30, [x0]\n"
+ "ret\n");
+
+#else
+static void __test_function(volatile long *ptr)
+{
+ *ptr = 0x1234;
+}
+#endif
__attribute__ ((noinline))
static int test_function(void)
{
+ __test_function(&the_var);
+ the_var++;
return time(NULL);
}
+static void sig_handler_2(int signum __maybe_unused,
+ siginfo_t *oh __maybe_unused,
+ void *uc __maybe_unused)
+{
+ overflows_2++;
+ if (overflows_2 > 10) {
+ ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0);
+ ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0);
+ ioctl(fd3, PERF_EVENT_IOC_DISABLE, 0);
+ }
+}
+
static void sig_handler(int signum __maybe_unused,
siginfo_t *oh __maybe_unused,
void *uc __maybe_unused)
@@ -54,10 +99,11 @@ static void sig_handler(int signum __maybe_unused,
*/
ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0);
ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0);
+ ioctl(fd3, PERF_EVENT_IOC_DISABLE, 0);
}
}
-static int bp_event(void *fn, int setup_signal)
+static int __event(bool is_x, void *addr, int signal)
{
struct perf_event_attr pe;
int fd;
@@ -67,8 +113,8 @@ static int bp_event(void *fn, int setup_signal)
pe.size = sizeof(struct perf_event_attr);
pe.config = 0;
- pe.bp_type = HW_BREAKPOINT_X;
- pe.bp_addr = (unsigned long) fn;
+ pe.bp_type = is_x ? HW_BREAKPOINT_X : HW_BREAKPOINT_W;
+ pe.bp_addr = (unsigned long) addr;
pe.bp_len = sizeof(long);
pe.sample_period = 1;
@@ -86,17 +132,25 @@ static int bp_event(void *fn, int setup_signal)
return TEST_FAIL;
}
- if (setup_signal) {
- fcntl(fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC);
- fcntl(fd, F_SETSIG, SIGIO);
- fcntl(fd, F_SETOWN, getpid());
- }
+ fcntl(fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC);
+ fcntl(fd, F_SETSIG, signal);
+ fcntl(fd, F_SETOWN, getpid());
ioctl(fd, PERF_EVENT_IOC_RESET, 0);
return fd;
}
+static int bp_event(void *addr, int signal)
+{
+ return __event(true, addr, signal);
+}
+
+static int wp_event(void *addr, int signal)
+{
+ return __event(false, addr, signal);
+}
+
static long long bp_count(int fd)
{
long long count;
@@ -114,7 +168,7 @@ static long long bp_count(int fd)
int test__bp_signal(int subtest __maybe_unused)
{
struct sigaction sa;
- long long count1, count2;
+ long long count1, count2, count3;
/* setup SIGIO signal handler */
memset(&sa, 0, sizeof(struct sigaction));
@@ -126,21 +180,52 @@ int test__bp_signal(int subtest __maybe_unused)
return TEST_FAIL;
}
+ sa.sa_sigaction = (void *) sig_handler_2;
+ if (sigaction(SIGUSR1, &sa, NULL) < 0) {
+ pr_debug("failed setting up signal handler 2\n");
+ return TEST_FAIL;
+ }
+
/*
* We create following events:
*
- * fd1 - breakpoint event on test_function with SIGIO
+ * fd1 - breakpoint event on __test_function with SIGIO
* signal configured. We should get signal
* notification each time the breakpoint is hit
*
- * fd2 - breakpoint event on sig_handler without SIGIO
+ * fd2 - breakpoint event on sig_handler with SIGUSR1
+ * configured. We should get SIGUSR1 each time when
+ * breakpoint is hit
+ *
+ * fd3 - watchpoint event on __test_function with SIGIO
* configured.
*
* Following processing should happen:
- * - execute test_function
- * - fd1 event breakpoint hit -> count1 == 1
- * - SIGIO is delivered -> overflows == 1
- * - fd2 event breakpoint hit -> count2 == 1
+ * Exec: Action: Result:
+ * incq (%rdi) - fd1 event breakpoint hit -> count1 == 1
+ * - SIGIO is delivered
+ * sig_handler - fd2 event breakpoint hit -> count2 == 1
+ * - SIGUSR1 is delivered
+ * sig_handler_2 -> overflows_2 == 1 (nested signal)
+ * sys_rt_sigreturn - return from sig_handler_2
+ * overflows++ -> overflows = 1
+ * sys_rt_sigreturn - return from sig_handler
+ * incq (%rdi) - fd3 event watchpoint hit -> count3 == 1 (wp and bp in one insn)
+ * - SIGIO is delivered
+ * sig_handler - fd2 event breakpoint hit -> count2 == 2
+ * - SIGUSR1 is delivered
+ * sig_handler_2 -> overflows_2 == 2 (nested signal)
+ * sys_rt_sigreturn - return from sig_handler_2
+ * overflows++ -> overflows = 2
+ * sys_rt_sigreturn - return from sig_handler
+ * the_var++ - fd3 event watchpoint hit -> count3 == 2 (standalone watchpoint)
+ * - SIGIO is delivered
+ * sig_handler - fd2 event breakpoint hit -> count2 == 3
+ * - SIGUSR1 is delivered
+ * sig_handler_2 -> overflows_2 == 3 (nested signal)
+ * sys_rt_sigreturn - return from sig_handler_2
+ * overflows++ -> overflows == 3
+ * sys_rt_sigreturn - return from sig_handler
*
* The test case check following error conditions:
* - we get stuck in signal handler because of debug
@@ -152,11 +237,13 @@ int test__bp_signal(int subtest __maybe_unused)
*
*/
- fd1 = bp_event(test_function, 1);
- fd2 = bp_event(sig_handler, 0);
+ fd1 = bp_event(__test_function, SIGIO);
+ fd2 = bp_event(sig_handler, SIGUSR1);
+ fd3 = wp_event((void *)&the_var, SIGIO);
ioctl(fd1, PERF_EVENT_IOC_ENABLE, 0);
ioctl(fd2, PERF_EVENT_IOC_ENABLE, 0);
+ ioctl(fd3, PERF_EVENT_IOC_ENABLE, 0);
/*
* Kick off the test by trigering 'fd1'
@@ -166,15 +253,18 @@ int test__bp_signal(int subtest __maybe_unused)
ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0);
ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0);
+ ioctl(fd3, PERF_EVENT_IOC_DISABLE, 0);
count1 = bp_count(fd1);
count2 = bp_count(fd2);
+ count3 = bp_count(fd3);
close(fd1);
close(fd2);
+ close(fd3);
- pr_debug("count1 %lld, count2 %lld, overflow %d\n",
- count1, count2, overflows);
+ pr_debug("count1 %lld, count2 %lld, count3 %lld, overflow %d, overflows_2 %d\n",
+ count1, count2, count3, overflows, overflows_2);
if (count1 != 1) {
if (count1 == 11)
@@ -183,12 +273,18 @@ int test__bp_signal(int subtest __maybe_unused)
pr_debug("failed: wrong count for bp1%lld\n", count1);
}
- if (overflows != 1)
+ if (overflows != 3)
pr_debug("failed: wrong overflow hit\n");
- if (count2 != 1)
+ if (overflows_2 != 3)
+ pr_debug("failed: wrong overflow_2 hit\n");
+
+ if (count2 != 3)
pr_debug("failed: wrong count for bp2\n");
- return count1 == 1 && overflows == 1 && count2 == 1 ?
+ if (count3 != 2)
+ pr_debug("failed: wrong count for bp3\n");
+
+ return count1 == 1 && overflows == 3 && count2 == 3 && overflows_2 == 3 && count3 == 2 ?
TEST_OK : TEST_FAIL;
}
--
1.8.3.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Jiri Olsa <jolsa@redhat.com> |
|---|---|
| Date | 2016-01-05 11:10 +0100 |
| Subject | Re: [RFC PATCH v2] perf test: Improve bp_signal |
| Message-ID | <qNwIW-Cq-13@gated-at.bofh.it> |
| In reply to | #1301385 |
On Tue, Jan 05, 2016 at 09:57:55AM +0000, Wang Nan wrote: > Will Deacon [1] has some question on patch [2]. This patch improves > test__bp_signal so we can test: > > 1. A watchpoint and a breakpoint that fire on the same instruction > 2. Nested signals > > Test result: > > On x86_64 and ARM64 (result are similar with patch [2] on ARM64): > > # ./perf test -v signal > 17: Test breakpoint overflow signal handler : > --- start --- > test child forked, pid 10213 > count1 1, count2 3, count3 2, overflow 3, overflows_2 3 > test child finished with 0 > ---- end ---- > Test breakpoint overflow signal handler: Ok > > So at least 2 cases Will doubted are handled correctly. > > [1] http://lkml.kernel.org/g/20160104165535.GI1616@arm.com > [2] http://lkml.kernel.org/g/1450921362-198371-1-git-send-email-wangnan0@huawei.com > > Signed-off-by: Wang Nan <wangnan0@huawei.com> > Signed-off-by: Jiri Olsa <jolsa@kernel.org> > Cc: Will Deacon <will.deacon@arm.com> > Cc: Arnaldo Carvalho de Melo <acme@redhat.com> > --- > > v1 -> v2: Improve readability, fix typo. Thanks to Jiri Olsa. > > To Jiri: I guess you will be okay to provide your SOB for your code at [3], > so I add it in this v2 patch. sure, patch looks good to me thanks, jirka -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web