[PATCH v5 0/7] Adding general performance benchmarking subcommand to perf.

View: New views
20 Messages — Rating Filter:   Alert me  
< Prev | 1 - 2 | Next >

[PATCH v5 0/7] Adding general performance benchmarking subcommand to perf.

by Hitoshi Mitake-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

This patch series add general benchmark subcommand to perf.

The subcommand will unify the benchmarking programs
and provide these in standardized way.

I fixed this series for latest tip tree.
My previous patch series conflicts with cmd_probe().
So please discard v4 and use this v5.

Hitoshi Mitake (7):
  Adding new directory and header for new subcommand 'bench'
  sched-messaging.c: benchmark for scheduler and IPC mechanisms based
    on hackbench
  sched-pipe.c: benchmark for pipe() system call
  builtin-bench.c: General framework for benchmark suites
  Modifying builtin.h for new prototype
  Modyfing perf.c for subcommand 'bench'
  Modyfing Makefile to build subcommand 'bench'

 tools/perf/Makefile                |    6 +
 tools/perf/bench/bench.h           |    9 +
 tools/perf/bench/sched-messaging.c |  332 ++++++++++++++++++++++++++++++++++++
 tools/perf/bench/sched-pipe.c      |  113 ++++++++++++
 tools/perf/builtin-bench.c         |  128 ++++++++++++++
 tools/perf/builtin.h               |    1 +
 tools/perf/perf.c                  |    1 +
 7 files changed, 590 insertions(+), 0 deletions(-)
 create mode 100644 tools/perf/bench/bench.h
 create mode 100644 tools/perf/bench/sched-messaging.c
 create mode 100644 tools/perf/bench/sched-pipe.c
 create mode 100644 tools/perf/builtin-bench.c

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[PATCH v5 1/7] Adding new directory and header for new subcommand 'bench'

by Hitoshi Mitake-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

This patch adds bench/ directory and bench/bench.h.
bench/ directory will contain modules for bench subcommand.
bench/bench.h is for listing prototypes of module functions.

Signed-off-by: Hitoshi Mitake <mitake@...>
Cc: Rusty Russell <rusty@...>
Cc: Thomas Gleixner <tglx@...>
Cc: Peter Zijlstra <a.p.zijlstra@...>
Cc: Mike Galbraith <efault@...>
---
 tools/perf/bench/bench.h |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)
 create mode 100644 tools/perf/bench/bench.h

diff --git a/tools/perf/bench/bench.h b/tools/perf/bench/bench.h
new file mode 100644
index 0000000..59adb27
--- /dev/null
+++ b/tools/perf/bench/bench.h
@@ -0,0 +1,9 @@
+#ifndef BENCH_H
+#define BENCH_H
+
+extern int bench_sched_messaging(int argc, const char **argv,
+ const char *prefix);
+extern int bench_sched_pipe(int argc, const char **argv,
+    const char *prefix);
+
+#endif
--
1.6.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[PATCH v5 2/7] sched-messaging.c: benchmark for scheduler and IPC mechanisms based on hackbench

by Hitoshi Mitake-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

This patch adds bench/sched-messaging.c.
This benchmark measures performance of scheduler and IPC mechanisms,
and is based on hackbench by Rusty Russell.

Example of usage:
% perf bench sched messaging -g 20 -l 1000 -s
5.432                       # in sec
% perf bench sched messaging                 # run with default options
(20 sender and receiver processes per group)
(10 groups == 400 processes run)

        Total time:0.308 sec
% perf bench sched messaging -t -g 20     # # be multi-thread, with 20 groups
(20 sender and receiver threads per group)
(20 groups == 800 threads run)

        Total time:0.582 sec

Signed-off-by: Hitoshi Mitake <mitake@...>
Cc: Rusty Russell <rusty@...>
Cc: Thomas Gleixner <tglx@...>
Cc: Peter Zijlstra <a.p.zijlstra@...>
Cc: Mike Galbraith <efault@...>
---
 tools/perf/bench/sched-messaging.c |  332 ++++++++++++++++++++++++++++++++++++
 1 files changed, 332 insertions(+), 0 deletions(-)
 create mode 100644 tools/perf/bench/sched-messaging.c

diff --git a/tools/perf/bench/sched-messaging.c b/tools/perf/bench/sched-messaging.c
new file mode 100644
index 0000000..36b62c5
--- /dev/null
+++ b/tools/perf/bench/sched-messaging.c
@@ -0,0 +1,332 @@
+/*
+ *
+ * builtin-bench-messaging.c
+ *
+ * messaging: Benchmark for scheduler and IPC mechanisms
+ *
+ * Based on hackbench by Rusty Russell <rusty@...>
+ * Ported to perf by Hitoshi Mitake <mitake@...>
+ *
+ */
+
+#include "../perf.h"
+#include "../util/util.h"
+#include "../util/parse-options.h"
+#include "../builtin.h"
+#include "bench.h"
+
+/* Test groups of 20 processes spraying to 20 receivers */
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/poll.h>
+#include <limits.h>
+
+#define DATASIZE 100
+
+static int use_pipes = 0;
+static unsigned int loops = 100;
+static unsigned int thread_mode = 0;
+static unsigned int num_groups = 10;
+static int simple = 0;
+
+struct sender_context {
+ unsigned int num_fds;
+ int ready_out;
+ int wakefd;
+ int out_fds[0];
+};
+
+struct receiver_context {
+ unsigned int num_packets;
+ int in_fds[2];
+ int ready_out;
+ int wakefd;
+};
+
+static void barf(const char *msg)
+{
+ fprintf(stderr, "%s (error: %s)\n", msg, strerror(errno));
+ exit(1);
+}
+
+static void fdpair(int fds[2])
+{
+ if (use_pipes) {
+ if (pipe(fds) == 0)
+ return;
+ } else {
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0)
+ return;
+ }
+
+ barf(use_pipes ? "pipe()" : "socketpair()");
+}
+
+/* Block until we're ready to go */
+static void ready(int ready_out, int wakefd)
+{
+ char dummy;
+ struct pollfd pollfd = { .fd = wakefd, .events = POLLIN };
+
+ /* Tell them we're ready. */
+ if (write(ready_out, &dummy, 1) != 1)
+ barf("CLIENT: ready write");
+
+ /* Wait for "GO" signal */
+ if (poll(&pollfd, 1, -1) != 1)
+ barf("poll");
+}
+
+/* Sender sprays loops messages down each file descriptor */
+static void *sender(struct sender_context *ctx)
+{
+ char data[DATASIZE];
+ unsigned int i, j;
+
+ ready(ctx->ready_out, ctx->wakefd);
+
+ /* Now pump to every receiver. */
+ for (i = 0; i < loops; i++) {
+ for (j = 0; j < ctx->num_fds; j++) {
+ int ret, done = 0;
+
+again:
+ ret = write(ctx->out_fds[j], data + done,
+    sizeof(data)-done);
+ if (ret < 0)
+ barf("SENDER: write");
+ done += ret;
+ if (done < DATASIZE)
+ goto again;
+ }
+ }
+
+ return NULL;
+}
+
+
+/* One receiver per fd */
+static void *receiver(struct receiver_context* ctx)
+{
+ unsigned int i;
+
+ if (!thread_mode)
+ close(ctx->in_fds[1]);
+
+ /* Wait for start... */
+ ready(ctx->ready_out, ctx->wakefd);
+
+ /* Receive them all */
+ for (i = 0; i < ctx->num_packets; i++) {
+ char data[DATASIZE];
+ int ret, done = 0;
+
+again:
+ ret = read(ctx->in_fds[0], data + done, DATASIZE - done);
+ if (ret < 0)
+ barf("SERVER: read");
+ done += ret;
+ if (done < DATASIZE)
+ goto again;
+ }
+
+ return NULL;
+}
+
+static pthread_t create_worker(void *ctx, void *(*func)(void *))
+{
+ pthread_attr_t attr;
+ pthread_t childid;
+ int err;
+
+ if (!thread_mode) {
+ /* process mode */
+ /* Fork the receiver. */
+ switch (fork()) {
+ case -1:
+ barf("fork()");
+ break;
+ case 0:
+ (*func) (ctx);
+ exit(0);
+ break;
+ default:
+ break;
+ }
+
+ return (pthread_t)0;
+ }
+
+ if (pthread_attr_init(&attr) != 0)
+ barf("pthread_attr_init:");
+
+#ifndef __ia64__
+ if (pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN) != 0)
+ barf("pthread_attr_setstacksize");
+#endif
+
+ err = pthread_create(&childid, &attr, func, ctx);
+ if (err != 0) {
+ fprintf(stderr, "pthread_create failed: %s (%d)\n",
+ strerror(err), err);
+ exit(-1);
+ }
+ return childid;
+}
+
+static void reap_worker(pthread_t id)
+{
+ int proc_status;
+ void *thread_status;
+
+ if (!thread_mode) {
+ /* process mode */
+ wait(&proc_status);
+ if (!WIFEXITED(proc_status))
+ exit(1);
+ } else {
+ pthread_join(id, &thread_status);
+ }
+}
+
+/* One group of senders and receivers */
+static unsigned int group(pthread_t *pth,
+ unsigned int num_fds,
+ int ready_out,
+ int wakefd)
+{
+ unsigned int i;
+ struct sender_context *snd_ctx = malloc(sizeof(struct sender_context)
+ + num_fds * sizeof(int));
+
+ if (!snd_ctx)
+ barf("malloc()");
+
+ for (i = 0; i < num_fds; i++) {
+ int fds[2];
+ struct receiver_context *ctx = malloc(sizeof(*ctx));
+
+ if (!ctx)
+ barf("malloc()");
+
+
+ /* Create the pipe between client and server */
+ fdpair(fds);
+
+ ctx->num_packets = num_fds * loops;
+ ctx->in_fds[0] = fds[0];
+ ctx->in_fds[1] = fds[1];
+ ctx->ready_out = ready_out;
+ ctx->wakefd = wakefd;
+
+ pth[i] = create_worker(ctx, (void *)receiver);
+
+ snd_ctx->out_fds[i] = fds[1];
+ if (!thread_mode)
+ close(fds[0]);
+ }
+
+ /* Now we have all the fds, fork the senders */
+ for (i = 0; i < num_fds; i++) {
+ snd_ctx->ready_out = ready_out;
+ snd_ctx->wakefd = wakefd;
+ snd_ctx->num_fds = num_fds;
+
+ pth[num_fds+i] = create_worker(snd_ctx, (void *)sender);
+ }
+
+ /* Close the fds we have left */
+ if (!thread_mode)
+ for (i = 0; i < num_fds; i++)
+ close(snd_ctx->out_fds[i]);
+
+ /* Return number of children to reap */
+ return num_fds * 2;
+}
+
+static const struct option options[] = {
+ OPT_BOOLEAN('p', "pipe", &use_pipes,
+    "Use pipe() instead of socketpair()"),
+ OPT_BOOLEAN('t', "thread", &thread_mode,
+    "Be multi thread instead of multi process"),
+ OPT_INTEGER('g', "group", &num_groups,
+    "Specify number of groups"),
+ OPT_INTEGER('l', "loop", &loops,
+    "Specify number of loops"),
+ OPT_BOOLEAN('s', "simple-output", &simple,
+    "Do simple output (this maybe useful for"
+    "processing by scripts or graph tools like gnuplot)"),
+ OPT_END()
+};
+
+static const char * const bench_sched_message_usage[] = {
+ "perf bench sched messaging <options>",
+ NULL
+};
+
+int bench_sched_messaging(int argc, const char **argv,
+    const char *prefix __used)
+{
+ unsigned int i, total_children;
+ struct timeval start, stop, diff;
+ unsigned int num_fds = 20;
+ int readyfds[2], wakefds[2];
+ char dummy;
+ pthread_t *pth_tab;
+
+ argc = parse_options(argc, argv, options,
+     bench_sched_message_usage, 0);
+
+ pth_tab = malloc(num_fds * 2 * num_groups * sizeof(pthread_t));
+ if (!pth_tab)
+ barf("main:malloc()");
+
+ fdpair(readyfds);
+ fdpair(wakefds);
+
+ total_children = 0;
+ for (i = 0; i < num_groups; i++)
+ total_children += group(pth_tab+total_children, num_fds,
+ readyfds[1], wakefds[0]);
+
+ /* Wait for everyone to be ready */
+ for (i = 0; i < total_children; i++)
+ if (read(readyfds[0], &dummy, 1) != 1)
+ barf("Reading for readyfds");
+
+ gettimeofday(&start, NULL);
+
+ /* Kick them off */
+ if (write(wakefds[1], &dummy, 1) != 1)
+ barf("Writing to start them");
+
+ /* Reap them all */
+ for (i = 0; i < total_children; i++)
+ reap_worker(pth_tab[i]);
+
+ gettimeofday(&stop, NULL);
+
+ timersub(&stop, &start, &diff);
+
+ if (simple)
+ printf("%lu.%03lu\n", diff.tv_sec, diff.tv_usec/1000);
+ else {
+ printf("(%d sender and receiver %s per group)\n",
+       num_fds, thread_mode ? "threads" : "processes");
+ printf("(%d groups == %d %s run)\n\n",
+       num_groups, num_groups * 2 * num_fds,
+       thread_mode ? "threads" : "processes");
+ printf("\tTotal time:%lu.%03lu sec\n",
+       diff.tv_sec, diff.tv_usec/1000);
+ }
+
+ return 0;
+}
--
1.6.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[PATCH v5 3/7] sched-pipe.c: benchmark for pipe() system call

by Hitoshi Mitake-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

This patch adds bench/sched-pipe.c.

bench/sched-pipe.c is a benchmark program
to measure performance of pipe() system call.
This benchmark is based on pipe-test-1m.c by Ingo Molnar.
http://people.redhat.com/mingo/cfs-scheduler/tools/pipe-test-1m.c

Example of use:
% perf bench sched pipe
(executing 1000000 pipe operations between two tasks)

        Total time:4.499 sec
                4.499179 usecs/op
                222262 ops/sec
% perf bench sched pipe -s -l 1000
0.015

Signed-off-by: Hitoshi Mitake <mitake@...>
Cc: Rusty Russell <rusty@...>
Cc: Thomas Gleixner <tglx@...>
Cc: Peter Zijlstra <a.p.zijlstra@...>
Cc: Mike Galbraith <efault@...>
---
 tools/perf/bench/sched-pipe.c |  113 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 113 insertions(+), 0 deletions(-)
 create mode 100644 tools/perf/bench/sched-pipe.c

diff --git a/tools/perf/bench/sched-pipe.c b/tools/perf/bench/sched-pipe.c
new file mode 100644
index 0000000..3214ed2
--- /dev/null
+++ b/tools/perf/bench/sched-pipe.c
@@ -0,0 +1,113 @@
+/*
+ *
+ * builtin-bench-pipe.c
+ *
+ * pipe: Benchmark for pipe()
+ *
+ * Based on pipe-test-1m.c by Ingo Molnar <mingo@...>
+ *  http://people.redhat.com/mingo/cfs-scheduler/tools/pipe-test-1m.c
+ * Ported to perf by Hitoshi Mitake <mitake@...>
+ *
+ */
+
+#include "../perf.h"
+#include "../util/util.h"
+#include "../util/parse-options.h"
+#include "../builtin.h"
+#include "bench.h"
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <linux/unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <sys/time.h>
+
+#define LOOPS_DEFAULT 1000000
+static int loops = LOOPS_DEFAULT;
+static int simple = 0;
+
+static const struct option options[] = {
+ OPT_INTEGER('l', "loop", &loops,
+    "Specify number of loops"),
+ OPT_BOOLEAN('s', "simple-output", &simple,
+    "Do simple output (this maybe useful for"
+    "processing by scripts or graph tools like gnuplot)"),
+ OPT_END()
+};
+
+static const char * const bench_sched_pipe_usage[] = {
+ "perf bench sched pipe <options>",
+ NULL
+};
+
+int bench_sched_pipe(int argc, const char **argv,
+     const char *prefix __used)
+{
+ int pipe_1[2], pipe_2[2];
+ int m = 0, i;
+ struct timeval start, stop, diff;
+ unsigned long long result_usec = 0;
+
+ /*
+ * why does "ret" exist?
+ * discarding returned value of read(), write()
+ * causes error in building environment for perf
+ */
+ int ret;
+ pid_t pid;
+
+ argc = parse_options(argc, argv, options,
+     bench_sched_pipe_usage, 0);
+
+ assert(!pipe(pipe_1));
+ assert(!pipe(pipe_2));
+
+ pid = fork();
+ assert(pid >= 0);
+
+ gettimeofday(&start, NULL);
+
+ if (!pid) {
+ for (i = 0; i < loops; i++) {
+ ret = read(pipe_1[0], &m, sizeof(int));
+ ret = write(pipe_2[1], &m, sizeof(int));
+ }
+ } else {
+ for (i = 0; i < loops; i++) {
+ ret = write(pipe_1[1], &m, sizeof(int));
+ ret = read(pipe_2[0], &m, sizeof(int));
+ }
+ }
+
+ gettimeofday(&stop, NULL);
+ timersub(&stop, &start, &diff);
+
+ if (pid)
+ return 0;
+
+ if (simple)
+ printf("%lu.%03lu\n",
+       diff.tv_sec, diff.tv_usec / 1000);
+ else {
+ printf("(executing %d pipe operations between two tasks)\n\n",
+ loops);
+
+ result_usec = diff.tv_sec * 1000000;
+ result_usec += diff.tv_usec;
+
+ printf("\tTotal time:%lu.%03lu sec\n",
+       diff.tv_sec, diff.tv_usec / 1000);
+ printf("\t\t%lf usecs/op\n",
+       (double)result_usec / (double)loops);
+ printf("\t\t%d ops/sec\n",
+       (int)((double)loops /
+     ((double)result_usec / (double)1000000)));
+ }
+
+ return 0;
+}
--
1.6.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[PATCH v5 4/7] builtin-bench.c: General framework for benchmark suites

by Hitoshi Mitake-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

This patch adds builtin-bench.c
builtin-bench.c is a general framework for benchmark suites.

Signed-off-by: Hitoshi Mitake <mitake@...>
Cc: Rusty Russell <rusty@...>
Cc: Thomas Gleixner <tglx@...>
Cc: Peter Zijlstra <a.p.zijlstra@...>
Cc: Mike Galbraith <efault@...>
---
 tools/perf/builtin-bench.c |  128 ++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 128 insertions(+), 0 deletions(-)
 create mode 100644 tools/perf/builtin-bench.c

diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c
new file mode 100644
index 0000000..31f4164
--- /dev/null
+++ b/tools/perf/builtin-bench.c
@@ -0,0 +1,128 @@
+/*
+ *
+ * builtin-bench.c
+ *
+ * General benchmarking subsystem provided by perf
+ *
+ * Copyright (C) 2009, Hitoshi Mitake <mitake@...>
+ *
+ */
+
+/*
+ *
+ * Available subsystem list:
+ *  sched ... scheduler and IPC mechanism
+ *
+ */
+
+#include "perf.h"
+#include "util/util.h"
+#include "util/parse-options.h"
+#include "builtin.h"
+#include "bench/bench.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct bench_suite {
+ const char *name;
+ const char *summary;
+ int (*fn)(int, const char **, const char *);
+};
+
+static struct bench_suite sched_suites[] = {
+ { "messaging",
+  "Benchmark for scheduler and IPC mechanisms",
+  bench_sched_messaging },
+ { "pipe",
+  "Flood of communication over pipe() between two processes",
+  bench_sched_pipe      },
+ { NULL,
+  NULL,
+  NULL                  }
+};
+
+struct bench_subsys {
+ const char *name;
+ const char *summary;
+ struct bench_suite *suites;
+};
+
+static struct bench_subsys subsystems[] = {
+ { "sched",
+  "scheduler and IPC mechanism",
+  sched_suites },
+ { NULL,
+  NULL,
+  NULL         }
+};
+
+static void dump_suites(int subsys_index)
+{
+ int i;
+
+ printf("List of available suites for %s...\n\n",
+       subsystems[subsys_index].name);
+
+ for (i = 0; subsystems[subsys_index].suites[i].name; i++)
+ printf("\t%s: %s\n",
+       subsystems[subsys_index].suites[i].name,
+       subsystems[subsys_index].suites[i].summary);
+
+ printf("\n");
+ return;
+}
+
+int cmd_bench(int argc, const char **argv, const char *prefix __used)
+{
+ int i, j, status = 0;
+
+ if (argc < 2) {
+ /* No subsystem specified. */
+ printf("Usage: perf bench <subsystem> <suite> [<options>]\n\n");
+ printf("List of available subsystems...\n\n");
+
+ for (i = 0; subsystems[i].name; i++)
+ printf("\t%s: %s\n",
+       subsystems[i].name, subsystems[i].summary);
+ printf("\n");
+
+ goto end;
+ }
+
+ for (i = 0; subsystems[i].name; i++) {
+ if (strcmp(subsystems[i].name, argv[1]))
+ continue;
+
+ if (argc < 3) {
+ /* No suite specified. */
+ dump_suites(i);
+ goto end;
+ }
+
+ for (j = 0; subsystems[i].suites[j].name; j++) {
+ if (strcmp(subsystems[i].suites[j].name, argv[2]))
+ continue;
+
+ status = subsystems[i].suites[j].fn(argc - 2,
+    argv + 2, prefix);
+ goto end;
+ }
+
+ if (!strcmp(argv[2], "-h") || !strcmp(argv[2], "--help")) {
+ dump_suites(i);
+ goto end;
+ }
+
+ printf("Unknown suite:%s for %s\n", argv[2], argv[1]);
+ status = 1;
+ goto end;
+ }
+
+ printf("Unknown subsystem:%s\n", argv[1]);
+ status = 1;
+
+end:
+ return status;
+}
--
1.6.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[PATCH v5 5/7] Modifying builtin.h for new prototype

by Hitoshi Mitake-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

This patch modifies builtin.h to add prototype of cmd_bench().

Signed-off-by: Hitoshi Mitake <mitake@...>
Cc: Rusty Russell <rusty@...>
Cc: Thomas Gleixner <tglx@...>
Cc: Peter Zijlstra <a.p.zijlstra@...>
Cc: Mike Galbraith <efault@...>
---
 tools/perf/builtin.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h
index ad5f0f4..e84f63e 100644
--- a/tools/perf/builtin.h
+++ b/tools/perf/builtin.h
@@ -26,5 +26,6 @@ extern int cmd_top(int argc, const char **argv, const char *prefix);
 extern int cmd_trace(int argc, const char **argv, const char *prefix);
 extern int cmd_version(int argc, const char **argv, const char *prefix);
 extern int cmd_probe(int argc, const char **argv, const char *prefix);
+extern int cmd_bench(int argc, const char **argv, const char *prefix);
 
 #endif
--
1.6.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[PATCH v5 6/7] Modyfing perf.c for subcommand 'bench'

by Hitoshi Mitake-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

This patch modifies perf.c for invoking 'bench' subcommand.

Signed-off-by: Hitoshi Mitake <mitake@...>
Cc: Rusty Russell <rusty@...>
Cc: Thomas Gleixner <tglx@...>
Cc: Peter Zijlstra <a.p.zijlstra@...>
Cc: Mike Galbraith <efault@...>
---
 tools/perf/perf.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 9cafe54..5877b01 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -296,6 +296,7 @@ static void handle_internal_command(int argc, const char **argv)
  { "trace", cmd_trace, 0 },
  { "sched", cmd_sched, 0 },
  { "probe", cmd_probe, 0 },
+ { "bench", cmd_bench, 0 },
  };
  unsigned int i;
  static const char ext[] = STRIP_EXTENSION;
--
1.6.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[PATCH v5 7/7] Modyfing Makefile to build subcommand 'bench'

by Hitoshi Mitake-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

This patch modifies Makefile for new files related to 'bench' subcommand.

Signed-off-by: Hitoshi Mitake <mitake@...>
Cc: Rusty Russell <rusty@...>
Cc: Thomas Gleixner <tglx@...>
Cc: Peter Zijlstra <a.p.zijlstra@...>
Cc: Mike Galbraith <efault@...>
---
 tools/perf/Makefile |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index a130134..17f8e9d 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -427,6 +427,12 @@ BUILTIN_OBJS += builtin-timechart.o
 BUILTIN_OBJS += builtin-top.o
 BUILTIN_OBJS += builtin-trace.o
 BUILTIN_OBJS += builtin-probe.o
+BUILTIN_OBJS += builtin-bench.o
+
+# Benchmark modules
+BUILTIN_OBJS += bench/sched-messaging.o
+BUILTIN_OBJS += bench/sched-pipe.o
+
 
 PERFLIBS = $(LIB_FILE)
 
--
1.6.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Re: [PATCH v5 0/7] Adding general performance benchmarking subcommand to perf.

by Ingo Molnar :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


* Hitoshi Mitake <mitake@...> wrote:

> This patch series add general benchmark subcommand to perf.
>
> The subcommand will unify the benchmarking programs
> and provide these in standardized way.
>
> I fixed this series for latest tip tree.
> My previous patch series conflicts with cmd_probe().
> So please discard v4 and use this v5.
>
> Hitoshi Mitake (7):
>   Adding new directory and header for new subcommand 'bench'
>   sched-messaging.c: benchmark for scheduler and IPC mechanisms based
>     on hackbench
>   sched-pipe.c: benchmark for pipe() system call
>   builtin-bench.c: General framework for benchmark suites
>   Modifying builtin.h for new prototype
>   Modyfing perf.c for subcommand 'bench'
>   Modyfing Makefile to build subcommand 'bench'
>
>  tools/perf/Makefile                |    6 +
>  tools/perf/bench/bench.h           |    9 +
>  tools/perf/bench/sched-messaging.c |  332 ++++++++++++++++++++++++++++++++++++
>  tools/perf/bench/sched-pipe.c      |  113 ++++++++++++
>  tools/perf/builtin-bench.c         |  128 ++++++++++++++
>  tools/perf/builtin.h               |    1 +
>  tools/perf/perf.c                  |    1 +
>  7 files changed, 590 insertions(+), 0 deletions(-)
>  create mode 100644 tools/perf/bench/bench.h
>  create mode 100644 tools/perf/bench/sched-messaging.c
>  create mode 100644 tools/perf/bench/sched-pipe.c
>  create mode 100644 tools/perf/builtin-bench.c

Looks good - i've applied the patches to tip:perf/bench, thanks!

There's one small bug i noticed:

$ ./perf bench sched pipe
(executing 1000000 pipe operations between two tasks)

        Total time:4.898 sec
$ 4.898586 usecs/op
                204140 ops/sec


the shell prompt came back before the usecs/op and ops/sec line was
printed. Process teardown race, lack of wait() or so?

        Ingo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[tip:perf/bench] perf bench: Add new directory and header for new subcommand 'bench'

by Hitoshi Mitake-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Commit-ID:  c426bba069e65ea438880a04aa4e7c5b880e1728
Gitweb:     http://git.kernel.org/tip/c426bba069e65ea438880a04aa4e7c5b880e1728
Author:     Hitoshi Mitake <mitake@...>
AuthorDate: Thu, 5 Nov 2009 09:31:31 +0900
Committer:  Ingo Molnar <mingo@...>
CommitDate: Sun, 8 Nov 2009 10:19:15 +0100

perf bench: Add new directory and header for new subcommand 'bench'

This patch adds bench/ directory and bench/bench.h.

bench/ directory will contain modules for bench subcommand.
bench/bench.h is for listing prototypes of module functions.

Signed-off-by: Hitoshi Mitake <mitake@...>
Cc: Rusty Russell <rusty@...>
Cc: Peter Zijlstra <a.p.zijlstra@...>
Cc: Mike Galbraith <efault@...>
Cc: Arnaldo Carvalho de Melo <acme@...>
Cc: fweisbec@...
Cc: Jiri Kosina <jkosina@...>
LKML-Reference: <1257381097-4743-2-git-send-email-mitake@...>
Signed-off-by: Ingo Molnar <mingo@...>
---
 tools/perf/bench/bench.h |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/tools/perf/bench/bench.h b/tools/perf/bench/bench.h
new file mode 100644
index 0000000..59adb27
--- /dev/null
+++ b/tools/perf/bench/bench.h
@@ -0,0 +1,9 @@
+#ifndef BENCH_H
+#define BENCH_H
+
+extern int bench_sched_messaging(int argc, const char **argv,
+ const char *prefix);
+extern int bench_sched_pipe(int argc, const char **argv,
+    const char *prefix);
+
+#endif
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[tip:perf/bench] perf bench: Add sched-messaging.c: Benchmark for scheduler and IPC mechanisms based on hackbench

by Hitoshi Mitake-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Commit-ID:  e27454cc6352c4226ddc76f5e3a5dedd7dff456a
Gitweb:     http://git.kernel.org/tip/e27454cc6352c4226ddc76f5e3a5dedd7dff456a
Author:     Hitoshi Mitake <mitake@...>
AuthorDate: Thu, 5 Nov 2009 09:31:32 +0900
Committer:  Ingo Molnar <mingo@...>
CommitDate: Sun, 8 Nov 2009 10:19:17 +0100

perf bench: Add sched-messaging.c: Benchmark for scheduler and IPC mechanisms based on hackbench

This patch adds bench/sched-messaging.c.

This benchmark measures performance of scheduler and IPC
mechanisms, and is based on hackbench by Rusty Russell.

Example of usage:

  % perf bench sched messaging -g 20 -l 1000 -s
  5.432                       # in sec

  % perf bench sched messaging                 # run with default
  options (20 sender and receiver processes per group)
  (10 groups == 400 processes run)

        Total time:0.308 sec

  % perf bench sched messaging -t -g 20     # # be multi-thread,
  with 20 groups (20 sender and receiver threads per group)
  (20 groups == 800 threads run)

        Total time:0.582 sec

( Rusty is the original author of hackbench.c and he said the code is
  and was under the GPLv2 so fine to be merged. )

Signed-off-by: Hitoshi Mitake <mitake@...>
Acked-by: Rusty Russell <rusty@...>
Cc: Peter Zijlstra <a.p.zijlstra@...>
Cc: Mike Galbraith <efault@...>
Cc: Arnaldo Carvalho de Melo <acme@...>
Cc: fweisbec@...
Cc: Jiri Kosina <jkosina@...>
LKML-Reference: <1257381097-4743-3-git-send-email-mitake@...>
Signed-off-by: Ingo Molnar <mingo@...>
---
 tools/perf/bench/sched-messaging.c |  332 ++++++++++++++++++++++++++++++++++++
 1 files changed, 332 insertions(+), 0 deletions(-)

diff --git a/tools/perf/bench/sched-messaging.c b/tools/perf/bench/sched-messaging.c
new file mode 100644
index 0000000..36b62c5
--- /dev/null
+++ b/tools/perf/bench/sched-messaging.c
@@ -0,0 +1,332 @@
+/*
+ *
+ * builtin-bench-messaging.c
+ *
+ * messaging: Benchmark for scheduler and IPC mechanisms
+ *
+ * Based on hackbench by Rusty Russell <rusty@...>
+ * Ported to perf by Hitoshi Mitake <mitake@...>
+ *
+ */
+
+#include "../perf.h"
+#include "../util/util.h"
+#include "../util/parse-options.h"
+#include "../builtin.h"
+#include "bench.h"
+
+/* Test groups of 20 processes spraying to 20 receivers */
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/poll.h>
+#include <limits.h>
+
+#define DATASIZE 100
+
+static int use_pipes = 0;
+static unsigned int loops = 100;
+static unsigned int thread_mode = 0;
+static unsigned int num_groups = 10;
+static int simple = 0;
+
+struct sender_context {
+ unsigned int num_fds;
+ int ready_out;
+ int wakefd;
+ int out_fds[0];
+};
+
+struct receiver_context {
+ unsigned int num_packets;
+ int in_fds[2];
+ int ready_out;
+ int wakefd;
+};
+
+static void barf(const char *msg)
+{
+ fprintf(stderr, "%s (error: %s)\n", msg, strerror(errno));
+ exit(1);
+}
+
+static void fdpair(int fds[2])
+{
+ if (use_pipes) {
+ if (pipe(fds) == 0)
+ return;
+ } else {
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0)
+ return;
+ }
+
+ barf(use_pipes ? "pipe()" : "socketpair()");
+}
+
+/* Block until we're ready to go */
+static void ready(int ready_out, int wakefd)
+{
+ char dummy;
+ struct pollfd pollfd = { .fd = wakefd, .events = POLLIN };
+
+ /* Tell them we're ready. */
+ if (write(ready_out, &dummy, 1) != 1)
+ barf("CLIENT: ready write");
+
+ /* Wait for "GO" signal */
+ if (poll(&pollfd, 1, -1) != 1)
+ barf("poll");
+}
+
+/* Sender sprays loops messages down each file descriptor */
+static void *sender(struct sender_context *ctx)
+{
+ char data[DATASIZE];
+ unsigned int i, j;
+
+ ready(ctx->ready_out, ctx->wakefd);
+
+ /* Now pump to every receiver. */
+ for (i = 0; i < loops; i++) {
+ for (j = 0; j < ctx->num_fds; j++) {
+ int ret, done = 0;
+
+again:
+ ret = write(ctx->out_fds[j], data + done,
+    sizeof(data)-done);
+ if (ret < 0)
+ barf("SENDER: write");
+ done += ret;
+ if (done < DATASIZE)
+ goto again;
+ }
+ }
+
+ return NULL;
+}
+
+
+/* One receiver per fd */
+static void *receiver(struct receiver_context* ctx)
+{
+ unsigned int i;
+
+ if (!thread_mode)
+ close(ctx->in_fds[1]);
+
+ /* Wait for start... */
+ ready(ctx->ready_out, ctx->wakefd);
+
+ /* Receive them all */
+ for (i = 0; i < ctx->num_packets; i++) {
+ char data[DATASIZE];
+ int ret, done = 0;
+
+again:
+ ret = read(ctx->in_fds[0], data + done, DATASIZE - done);
+ if (ret < 0)
+ barf("SERVER: read");
+ done += ret;
+ if (done < DATASIZE)
+ goto again;
+ }
+
+ return NULL;
+}
+
+static pthread_t create_worker(void *ctx, void *(*func)(void *))
+{
+ pthread_attr_t attr;
+ pthread_t childid;
+ int err;
+
+ if (!thread_mode) {
+ /* process mode */
+ /* Fork the receiver. */
+ switch (fork()) {
+ case -1:
+ barf("fork()");
+ break;
+ case 0:
+ (*func) (ctx);
+ exit(0);
+ break;
+ default:
+ break;
+ }
+
+ return (pthread_t)0;
+ }
+
+ if (pthread_attr_init(&attr) != 0)
+ barf("pthread_attr_init:");
+
+#ifndef __ia64__
+ if (pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN) != 0)
+ barf("pthread_attr_setstacksize");
+#endif
+
+ err = pthread_create(&childid, &attr, func, ctx);
+ if (err != 0) {
+ fprintf(stderr, "pthread_create failed: %s (%d)\n",
+ strerror(err), err);
+ exit(-1);
+ }
+ return childid;
+}
+
+static void reap_worker(pthread_t id)
+{
+ int proc_status;
+ void *thread_status;
+
+ if (!thread_mode) {
+ /* process mode */
+ wait(&proc_status);
+ if (!WIFEXITED(proc_status))
+ exit(1);
+ } else {
+ pthread_join(id, &thread_status);
+ }
+}
+
+/* One group of senders and receivers */
+static unsigned int group(pthread_t *pth,
+ unsigned int num_fds,
+ int ready_out,
+ int wakefd)
+{
+ unsigned int i;
+ struct sender_context *snd_ctx = malloc(sizeof(struct sender_context)
+ + num_fds * sizeof(int));
+
+ if (!snd_ctx)
+ barf("malloc()");
+
+ for (i = 0; i < num_fds; i++) {
+ int fds[2];
+ struct receiver_context *ctx = malloc(sizeof(*ctx));
+
+ if (!ctx)
+ barf("malloc()");
+
+
+ /* Create the pipe between client and server */
+ fdpair(fds);
+
+ ctx->num_packets = num_fds * loops;
+ ctx->in_fds[0] = fds[0];
+ ctx->in_fds[1] = fds[1];
+ ctx->ready_out = ready_out;
+ ctx->wakefd = wakefd;
+
+ pth[i] = create_worker(ctx, (void *)receiver);
+
+ snd_ctx->out_fds[i] = fds[1];
+ if (!thread_mode)
+ close(fds[0]);
+ }
+
+ /* Now we have all the fds, fork the senders */
+ for (i = 0; i < num_fds; i++) {
+ snd_ctx->ready_out = ready_out;
+ snd_ctx->wakefd = wakefd;
+ snd_ctx->num_fds = num_fds;
+
+ pth[num_fds+i] = create_worker(snd_ctx, (void *)sender);
+ }
+
+ /* Close the fds we have left */
+ if (!thread_mode)
+ for (i = 0; i < num_fds; i++)
+ close(snd_ctx->out_fds[i]);
+
+ /* Return number of children to reap */
+ return num_fds * 2;
+}
+
+static const struct option options[] = {
+ OPT_BOOLEAN('p', "pipe", &use_pipes,
+    "Use pipe() instead of socketpair()"),
+ OPT_BOOLEAN('t', "thread", &thread_mode,
+    "Be multi thread instead of multi process"),
+ OPT_INTEGER('g', "group", &num_groups,
+    "Specify number of groups"),
+ OPT_INTEGER('l', "loop", &loops,
+    "Specify number of loops"),
+ OPT_BOOLEAN('s', "simple-output", &simple,
+    "Do simple output (this maybe useful for"
+    "processing by scripts or graph tools like gnuplot)"),
+ OPT_END()
+};
+
+static const char * const bench_sched_message_usage[] = {
+ "perf bench sched messaging <options>",
+ NULL
+};
+
+int bench_sched_messaging(int argc, const char **argv,
+    const char *prefix __used)
+{
+ unsigned int i, total_children;
+ struct timeval start, stop, diff;
+ unsigned int num_fds = 20;
+ int readyfds[2], wakefds[2];
+ char dummy;
+ pthread_t *pth_tab;
+
+ argc = parse_options(argc, argv, options,
+     bench_sched_message_usage, 0);
+
+ pth_tab = malloc(num_fds * 2 * num_groups * sizeof(pthread_t));
+ if (!pth_tab)
+ barf("main:malloc()");
+
+ fdpair(readyfds);
+ fdpair(wakefds);
+
+ total_children = 0;
+ for (i = 0; i < num_groups; i++)
+ total_children += group(pth_tab+total_children, num_fds,
+ readyfds[1], wakefds[0]);
+
+ /* Wait for everyone to be ready */
+ for (i = 0; i < total_children; i++)
+ if (read(readyfds[0], &dummy, 1) != 1)
+ barf("Reading for readyfds");
+
+ gettimeofday(&start, NULL);
+
+ /* Kick them off */
+ if (write(wakefds[1], &dummy, 1) != 1)
+ barf("Writing to start them");
+
+ /* Reap them all */
+ for (i = 0; i < total_children; i++)
+ reap_worker(pth_tab[i]);
+
+ gettimeofday(&stop, NULL);
+
+ timersub(&stop, &start, &diff);
+
+ if (simple)
+ printf("%lu.%03lu\n", diff.tv_sec, diff.tv_usec/1000);
+ else {
+ printf("(%d sender and receiver %s per group)\n",
+       num_fds, thread_mode ? "threads" : "processes");
+ printf("(%d groups == %d %s run)\n\n",
+       num_groups, num_groups * 2 * num_fds,
+       thread_mode ? "threads" : "processes");
+ printf("\tTotal time:%lu.%03lu sec\n",
+       diff.tv_sec, diff.tv_usec/1000);
+ }
+
+ return 0;
+}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[tip:perf/bench] perf bench: Add sched-pipe.c: Benchmark for pipe() system call

by Hitoshi Mitake-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Commit-ID:  c7d9300f367f480aee4663a0e3695c5b48859a1a
Gitweb:     http://git.kernel.org/tip/c7d9300f367f480aee4663a0e3695c5b48859a1a
Author:     Hitoshi Mitake <mitake@...>
AuthorDate: Thu, 5 Nov 2009 09:31:33 +0900
Committer:  Ingo Molnar <mingo@...>
CommitDate: Sun, 8 Nov 2009 10:19:18 +0100

perf bench: Add sched-pipe.c: Benchmark for pipe() system call

This patch adds bench/sched-pipe.c.

bench/sched-pipe.c is a benchmark program
to measure performance of pipe() system call.
This benchmark is based on pipe-test-1m.c by Ingo Molnar:

   http://people.redhat.com/mingo/cfs-scheduler/tools/pipe-test-1m.c

Example of use:

% perf bench sched pipe
  (executing 1000000 pipe operations between two tasks)

          Total time:4.499 sec
                  4.499179 usecs/op
                  222262 ops/sec

% perf bench sched pipe -s -l 1000
0.015

Signed-off-by: Hitoshi Mitake <mitake@...>
Cc: Rusty Russell <rusty@...>
Cc: Peter Zijlstra <a.p.zijlstra@...>
Cc: Mike Galbraith <efault@...>
Cc: Arnaldo Carvalho de Melo <acme@...>
Cc: fweisbec@...
Cc: Jiri Kosina <jkosina@...>
LKML-Reference: <1257381097-4743-4-git-send-email-mitake@...>
Signed-off-by: Ingo Molnar <mingo@...>
---
 tools/perf/bench/sched-pipe.c |  113 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 113 insertions(+), 0 deletions(-)

diff --git a/tools/perf/bench/sched-pipe.c b/tools/perf/bench/sched-pipe.c
new file mode 100644
index 0000000..3214ed2
--- /dev/null
+++ b/tools/perf/bench/sched-pipe.c
@@ -0,0 +1,113 @@
+/*
+ *
+ * builtin-bench-pipe.c
+ *
+ * pipe: Benchmark for pipe()
+ *
+ * Based on pipe-test-1m.c by Ingo Molnar <mingo@...>
+ *  http://people.redhat.com/mingo/cfs-scheduler/tools/pipe-test-1m.c
+ * Ported to perf by Hitoshi Mitake <mitake@...>
+ *
+ */
+
+#include "../perf.h"
+#include "../util/util.h"
+#include "../util/parse-options.h"
+#include "../builtin.h"
+#include "bench.h"
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <linux/unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <sys/time.h>
+
+#define LOOPS_DEFAULT 1000000
+static int loops = LOOPS_DEFAULT;
+static int simple = 0;
+
+static const struct option options[] = {
+ OPT_INTEGER('l', "loop", &loops,
+    "Specify number of loops"),
+ OPT_BOOLEAN('s', "simple-output", &simple,
+    "Do simple output (this maybe useful for"
+    "processing by scripts or graph tools like gnuplot)"),
+ OPT_END()
+};
+
+static const char * const bench_sched_pipe_usage[] = {
+ "perf bench sched pipe <options>",
+ NULL
+};
+
+int bench_sched_pipe(int argc, const char **argv,
+     const char *prefix __used)
+{
+ int pipe_1[2], pipe_2[2];
+ int m = 0, i;
+ struct timeval start, stop, diff;
+ unsigned long long result_usec = 0;
+
+ /*
+ * why does "ret" exist?
+ * discarding returned value of read(), write()
+ * causes error in building environment for perf
+ */
+ int ret;
+ pid_t pid;
+
+ argc = parse_options(argc, argv, options,
+     bench_sched_pipe_usage, 0);
+
+ assert(!pipe(pipe_1));
+ assert(!pipe(pipe_2));
+
+ pid = fork();
+ assert(pid >= 0);
+
+ gettimeofday(&start, NULL);
+
+ if (!pid) {
+ for (i = 0; i < loops; i++) {
+ ret = read(pipe_1[0], &m, sizeof(int));
+ ret = write(pipe_2[1], &m, sizeof(int));
+ }
+ } else {
+ for (i = 0; i < loops; i++) {
+ ret = write(pipe_1[1], &m, sizeof(int));
+ ret = read(pipe_2[0], &m, sizeof(int));
+ }
+ }
+
+ gettimeofday(&stop, NULL);
+ timersub(&stop, &start, &diff);
+
+ if (pid)
+ return 0;
+
+ if (simple)
+ printf("%lu.%03lu\n",
+       diff.tv_sec, diff.tv_usec / 1000);
+ else {
+ printf("(executing %d pipe operations between two tasks)\n\n",
+ loops);
+
+ result_usec = diff.tv_sec * 1000000;
+ result_usec += diff.tv_usec;
+
+ printf("\tTotal time:%lu.%03lu sec\n",
+       diff.tv_sec, diff.tv_usec / 1000);
+ printf("\t\t%lf usecs/op\n",
+       (double)result_usec / (double)loops);
+ printf("\t\t%d ops/sec\n",
+       (int)((double)loops /
+     ((double)result_usec / (double)1000000)));
+ }
+
+ return 0;
+}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[tip:perf/bench] perf bench: Add builtin-bench.c: General framework for benchmark suites

by Hitoshi Mitake-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Commit-ID:  629cc356653719c206a05f4dee5c5e242edb6546
Gitweb:     http://git.kernel.org/tip/629cc356653719c206a05f4dee5c5e242edb6546
Author:     Hitoshi Mitake <mitake@...>
AuthorDate: Thu, 5 Nov 2009 09:31:34 +0900
Committer:  Ingo Molnar <mingo@...>
CommitDate: Sun, 8 Nov 2009 10:19:18 +0100

perf bench: Add builtin-bench.c: General framework for benchmark suites

This patch adds builtin-bench.c
builtin-bench.c is a general framework for benchmark suites.

Signed-off-by: Hitoshi Mitake <mitake@...>
Cc: Rusty Russell <rusty@...>
Cc: Peter Zijlstra <a.p.zijlstra@...>
Cc: Mike Galbraith <efault@...>
Cc: Arnaldo Carvalho de Melo <acme@...>
Cc: fweisbec@...
Cc: Jiri Kosina <jkosina@...>
LKML-Reference: <1257381097-4743-5-git-send-email-mitake@...>
Signed-off-by: Ingo Molnar <mingo@...>
---
 tools/perf/builtin-bench.c |  128 ++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 128 insertions(+), 0 deletions(-)

diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c
new file mode 100644
index 0000000..31f4164
--- /dev/null
+++ b/tools/perf/builtin-bench.c
@@ -0,0 +1,128 @@
+/*
+ *
+ * builtin-bench.c
+ *
+ * General benchmarking subsystem provided by perf
+ *
+ * Copyright (C) 2009, Hitoshi Mitake <mitake@...>
+ *
+ */
+
+/*
+ *
+ * Available subsystem list:
+ *  sched ... scheduler and IPC mechanism
+ *
+ */
+
+#include "perf.h"
+#include "util/util.h"
+#include "util/parse-options.h"
+#include "builtin.h"
+#include "bench/bench.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct bench_suite {
+ const char *name;
+ const char *summary;
+ int (*fn)(int, const char **, const char *);
+};
+
+static struct bench_suite sched_suites[] = {
+ { "messaging",
+  "Benchmark for scheduler and IPC mechanisms",
+  bench_sched_messaging },
+ { "pipe",
+  "Flood of communication over pipe() between two processes",
+  bench_sched_pipe      },
+ { NULL,
+  NULL,
+  NULL                  }
+};
+
+struct bench_subsys {
+ const char *name;
+ const char *summary;
+ struct bench_suite *suites;
+};
+
+static struct bench_subsys subsystems[] = {
+ { "sched",
+  "scheduler and IPC mechanism",
+  sched_suites },
+ { NULL,
+  NULL,
+  NULL         }
+};
+
+static void dump_suites(int subsys_index)
+{
+ int i;
+
+ printf("List of available suites for %s...\n\n",
+       subsystems[subsys_index].name);
+
+ for (i = 0; subsystems[subsys_index].suites[i].name; i++)
+ printf("\t%s: %s\n",
+       subsystems[subsys_index].suites[i].name,
+       subsystems[subsys_index].suites[i].summary);
+
+ printf("\n");
+ return;
+}
+
+int cmd_bench(int argc, const char **argv, const char *prefix __used)
+{
+ int i, j, status = 0;
+
+ if (argc < 2) {
+ /* No subsystem specified. */
+ printf("Usage: perf bench <subsystem> <suite> [<options>]\n\n");
+ printf("List of available subsystems...\n\n");
+
+ for (i = 0; subsystems[i].name; i++)
+ printf("\t%s: %s\n",
+       subsystems[i].name, subsystems[i].summary);
+ printf("\n");
+
+ goto end;
+ }
+
+ for (i = 0; subsystems[i].name; i++) {
+ if (strcmp(subsystems[i].name, argv[1]))
+ continue;
+
+ if (argc < 3) {
+ /* No suite specified. */
+ dump_suites(i);
+ goto end;
+ }
+
+ for (j = 0; subsystems[i].suites[j].name; j++) {
+ if (strcmp(subsystems[i].suites[j].name, argv[2]))
+ continue;
+
+ status = subsystems[i].suites[j].fn(argc - 2,
+    argv + 2, prefix);
+ goto end;
+ }
+
+ if (!strcmp(argv[2], "-h") || !strcmp(argv[2], "--help")) {
+ dump_suites(i);
+ goto end;
+ }
+
+ printf("Unknown suite:%s for %s\n", argv[2], argv[1]);
+ status = 1;
+ goto end;
+ }
+
+ printf("Unknown subsystem:%s\n", argv[1]);
+ status = 1;
+
+end:
+ return status;
+}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[tip:perf/bench] perf bench: Modify builtin.h for new prototype

by Hitoshi Mitake-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Commit-ID:  11bd341c043348ecb7462d3bd8e1ad6d00f6892a
Gitweb:     http://git.kernel.org/tip/11bd341c043348ecb7462d3bd8e1ad6d00f6892a
Author:     Hitoshi Mitake <mitake@...>
AuthorDate: Thu, 5 Nov 2009 09:31:35 +0900
Committer:  Ingo Molnar <mingo@...>
CommitDate: Sun, 8 Nov 2009 10:19:19 +0100

perf bench: Modify builtin.h for new prototype

This patch modifies builtin.h to add prototype of cmd_bench().

Signed-off-by: Hitoshi Mitake <mitake@...>
Cc: Rusty Russell <rusty@...>
Cc: Peter Zijlstra <a.p.zijlstra@...>
Cc: Mike Galbraith <efault@...>
Cc: Arnaldo Carvalho de Melo <acme@...>
Cc: fweisbec@...
Cc: Jiri Kosina <jkosina@...>
LKML-Reference: <1257381097-4743-6-git-send-email-mitake@...>
Signed-off-by: Ingo Molnar <mingo@...>
---
 tools/perf/builtin.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h
index e11d8d2..f0cd5b1 100644
--- a/tools/perf/builtin.h
+++ b/tools/perf/builtin.h
@@ -15,6 +15,7 @@ extern int read_line_with_nul(char *buf, int size, FILE *file);
 extern int check_pager_config(const char *cmd);
 
 extern int cmd_annotate(int argc, const char **argv, const char *prefix);
+extern int cmd_bench(int argc, const char **argv, const char *prefix);
 extern int cmd_help(int argc, const char **argv, const char *prefix);
 extern int cmd_sched(int argc, const char **argv, const char *prefix);
 extern int cmd_list(int argc, const char **argv, const char *prefix);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[tip:perf/bench] perf bench: Add new subcommand 'bench' to perf.c

by Hitoshi Mitake-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Commit-ID:  dcba8848d3bc83ec9ee0858b9ae6e4f1c1fa7fa3
Gitweb:     http://git.kernel.org/tip/dcba8848d3bc83ec9ee0858b9ae6e4f1c1fa7fa3
Author:     Hitoshi Mitake <mitake@...>
AuthorDate: Thu, 5 Nov 2009 09:31:36 +0900
Committer:  Ingo Molnar <mingo@...>
CommitDate: Sun, 8 Nov 2009 10:19:19 +0100

perf bench: Add new subcommand 'bench' to perf.c

This patch modifies perf.c for invoking 'bench' subcommand.

Signed-off-by: Hitoshi Mitake <mitake@...>
Cc: Rusty Russell <rusty@...>
Cc: Peter Zijlstra <a.p.zijlstra@...>
Cc: Mike Galbraith <efault@...>
Cc: Arnaldo Carvalho de Melo <acme@...>
Cc: fweisbec@...
Cc: Jiri Kosina <jkosina@...>
LKML-Reference: <1257381097-4743-7-git-send-email-mitake@...>
Signed-off-by: Ingo Molnar <mingo@...>
---
 tools/perf/perf.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 624e62d..f90ca5e 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -288,6 +288,7 @@ static void handle_internal_command(int argc, const char **argv)
  { "list", cmd_list, 0 },
  { "record", cmd_record, 0 },
  { "report", cmd_report, 0 },
+ { "bench", cmd_bench, 0 },
  { "stat", cmd_stat, 0 },
  { "timechart", cmd_timechart, 0 },
  { "top", cmd_top, 0 },
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[tip:perf/bench] perf bench: Add subcommand 'bench' to the Makefile

by Hitoshi Mitake-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Commit-ID:  bfde82ef51e3ea6ab8634d0fdbf5adcdd1b429cb
Gitweb:     http://git.kernel.org/tip/bfde82ef51e3ea6ab8634d0fdbf5adcdd1b429cb
Author:     Hitoshi Mitake <mitake@...>
AuthorDate: Thu, 5 Nov 2009 09:31:37 +0900
Committer:  Ingo Molnar <mingo@...>
CommitDate: Sun, 8 Nov 2009 10:19:20 +0100

perf bench: Add subcommand 'bench' to the Makefile

This patch modifies Makefile for new files related to 'bench'
subcommand. The new code is active from this point on.

Signed-off-by: Hitoshi Mitake <mitake@...>
Cc: Rusty Russell <rusty@...>
Cc: Peter Zijlstra <a.p.zijlstra@...>
Cc: Mike Galbraith <efault@...>
Cc: Arnaldo Carvalho de Melo <acme@...>
Cc: fweisbec@...
Cc: Jiri Kosina <jkosina@...>
LKML-Reference: <1257381097-4743-8-git-send-email-mitake@...>
Signed-off-by: Ingo Molnar <mingo@...>
---
 tools/perf/Makefile |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 542b29e..0a25428 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -416,6 +416,13 @@ LIB_OBJS += util/hist.o
 LIB_OBJS += util/data_map.o
 
 BUILTIN_OBJS += builtin-annotate.o
+
+BUILTIN_OBJS += builtin-bench.o
+
+# Benchmark modules
+BUILTIN_OBJS += bench/sched-messaging.o
+BUILTIN_OBJS += bench/sched-pipe.o
+
 BUILTIN_OBJS += builtin-help.o
 BUILTIN_OBJS += builtin-sched.o
 BUILTIN_OBJS += builtin-list.o
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Re: [PATCH v5 0/7] Adding general performance benchmarking subcommand to perf.

by Hitoshi Mitake-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

From: Ingo Molnar <mingo@...>
Subject: Re: [PATCH v5 0/7] Adding general performance benchmarking subcommand to perf.
Date: Sun, 8 Nov 2009 10:21:21 +0100

>
> * Hitoshi Mitake <mitake@...> wrote:
>
> > This patch series add general benchmark subcommand to perf.
> >
> > The subcommand will unify the benchmarking programs
> > and provide these in standardized way.
> >
> > I fixed this series for latest tip tree.
> > My previous patch series conflicts with cmd_probe().
> > So please discard v4 and use this v5.
> >
> > Hitoshi Mitake (7):
> >   Adding new directory and header for new subcommand 'bench'
> >   sched-messaging.c: benchmark for scheduler and IPC mechanisms based
> >     on hackbench
> >   sched-pipe.c: benchmark for pipe() system call
> >   builtin-bench.c: General framework for benchmark suites
> >   Modifying builtin.h for new prototype
> >   Modyfing perf.c for subcommand 'bench'
> >   Modyfing Makefile to build subcommand 'bench'
> >
> >  tools/perf/Makefile                |    6 +
> >  tools/perf/bench/bench.h           |    9 +
> >  tools/perf/bench/sched-messaging.c |  332 ++++++++++++++++++++++++++++++++++++
> >  tools/perf/bench/sched-pipe.c      |  113 ++++++++++++
> >  tools/perf/builtin-bench.c         |  128 ++++++++++++++
> >  tools/perf/builtin.h               |    1 +
> >  tools/perf/perf.c                  |    1 +
> >  7 files changed, 590 insertions(+), 0 deletions(-)
> >  create mode 100644 tools/perf/bench/bench.h
> >  create mode 100644 tools/perf/bench/sched-messaging.c
> >  create mode 100644 tools/perf/bench/sched-pipe.c
> >  create mode 100644 tools/perf/builtin-bench.c
>
> Looks good - i've applied the patches to tip:perf/bench, thanks!

Thanks! Then I'll work on documentation and merging other
benchmarks such like lmbench or copybench.

>
> There's one small bug i noticed:
>
> $ ./perf bench sched pipe
> (executing 1000000 pipe operations between two tasks)
>
> Total time:4.898 sec
> $ 4.898586 usecs/op
> 204140 ops/sec
>
>
> the shell prompt came back before the usecs/op and ops/sec line was
> printed. Process teardown race, lack of wait() or so?

Thanks for your notify. I prepared a patch to fix this problem.
I'll send it later.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[PATCH] perf bench:Fix bench/sched-pipe.c to wait child process

by Hitoshi Mitake-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Fixed bench/sched-pipe.c to avoid the below case
notified by Ingo Molnar,

---

$ ./perf bench sched pipe
(executing 1000000 pipe operations between two tasks)

        Total time:4.898 sec
$ 4.898586 usecs/op
                204140 ops/sec

the shell prompt came back before the usecs/op and ops/sec line was
printed. Process teardown race, lack of wait() or so?

---

This caused by lack of calling waitpid() by parent process,
so I added it.

Signed-off-by: Hitoshi Mitake <mitake@...>
Cc: Rusty Russell <rusty@...>
Cc: Peter Zijlstra <a.p.zijlstra@...>
Cc: Paul Mackerras <paulus@...>
Cc: Mike Galbraith <efault@...>
Cc: Arnaldo Carvalho de Melo <acme@...>
Cc: Frederic Weisbecker <fweisbec@...>
Cc: Jiri Kosina <jkosina@...>
---
 tools/perf/bench/sched-pipe.c |   10 +++++++---
 1 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/tools/perf/bench/sched-pipe.c b/tools/perf/bench/sched-pipe.c
index 3214ed2..6a29100 100644
--- a/tools/perf/bench/sched-pipe.c
+++ b/tools/perf/bench/sched-pipe.c
@@ -26,6 +26,7 @@
 #include <errno.h>
 #include <assert.h>
 #include <sys/time.h>
+#include <sys/types.h>
 
 #define LOOPS_DEFAULT 1000000
 static int loops = LOOPS_DEFAULT;
@@ -58,8 +59,8 @@ int bench_sched_pipe(int argc, const char **argv,
  * discarding returned value of read(), write()
  * causes error in building environment for perf
  */
- int ret;
- pid_t pid;
+ int ret, wait_stat;
+ pid_t pid, retpid;
 
  argc = parse_options(argc, argv, options,
      bench_sched_pipe_usage, 0);
@@ -87,8 +88,11 @@ int bench_sched_pipe(int argc, const char **argv,
  gettimeofday(&stop, NULL);
  timersub(&stop, &start, &diff);
 
- if (pid)
+ if (pid) {
+ retpid = waitpid(pid, &wait_stat, 0);
+ assert((retpid == pid) && WIFEXITED(wait_stat));
  return 0;
+ }
 
  if (simple)
  printf("%lu.%03lu\n",
--
1.6.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Re: [PATCH] perf bench:Fix bench/sched-pipe.c to wait child process

by Hitoshi Mitake-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

From: Hitoshi Mitake <mitake@...>
Subject: [PATCH] perf bench:Fix bench/sched-pipe.c to wait child process
Date: Mon,  9 Nov 2009 12:13:08 +0900

Sorry, the title lacks space after "perf bench:".
I'll send new fixed one, please discard this.

> Fixed bench/sched-pipe.c to avoid the below case
> notified by Ingo Molnar,
>
> ---
>
> $ ./perf bench sched pipe
> (executing 1000000 pipe operations between two tasks)
>
> Total time:4.898 sec
> $ 4.898586 usecs/op
> 204140 ops/sec
>
> the shell prompt came back before the usecs/op and ops/sec line was
> printed. Process teardown race, lack of wait() or so?
>
> ---
>
> This caused by lack of calling waitpid() by parent process,
> so I added it.
>
> Signed-off-by: Hitoshi Mitake <mitake@...>
> Cc: Rusty Russell <rusty@...>
> Cc: Peter Zijlstra <a.p.zijlstra@...>
> Cc: Paul Mackerras <paulus@...>
> Cc: Mike Galbraith <efault@...>
> Cc: Arnaldo Carvalho de Melo <acme@...>
> Cc: Frederic Weisbecker <fweisbec@...>
> Cc: Jiri Kosina <jkosina@...>
> ---
>  tools/perf/bench/sched-pipe.c |   10 +++++++---
>  1 files changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/tools/perf/bench/sched-pipe.c b/tools/perf/bench/sched-pipe.c
> index 3214ed2..6a29100 100644
> --- a/tools/perf/bench/sched-pipe.c
> +++ b/tools/perf/bench/sched-pipe.c
> @@ -26,6 +26,7 @@
>  #include <errno.h>
>  #include <assert.h>
>  #include <sys/time.h>
> +#include <sys/types.h>
>  
>  #define LOOPS_DEFAULT 1000000
>  static int loops = LOOPS_DEFAULT;
> @@ -58,8 +59,8 @@ int bench_sched_pipe(int argc, const char **argv,
>   * discarding returned value of read(), write()
>   * causes error in building environment for perf
>   */
> - int ret;
> - pid_t pid;
> + int ret, wait_stat;
> + pid_t pid, retpid;
>  
>   argc = parse_options(argc, argv, options,
>       bench_sched_pipe_usage, 0);
> @@ -87,8 +88,11 @@ int bench_sched_pipe(int argc, const char **argv,
>   gettimeofday(&stop, NULL);
>   timersub(&stop, &start, &diff);
>  
> - if (pid)
> + if (pid) {
> + retpid = waitpid(pid, &wait_stat, 0);
> + assert((retpid == pid) && WIFEXITED(wait_stat));
>   return 0;
> + }
>  
>   if (simple)
>   printf("%lu.%03lu\n",
> --
> 1.6.5.2
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[PATCH] perf bench: Fix bench/sched-pipe.c to wait child process

by Hitoshi Mitake-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Fixed bench/sched-pipe.c to avoid the below case
notified by Ingo Molnar,

---

$ ./perf bench sched pipe
(executing 1000000 pipe operations between two tasks)

        Total time:4.898 sec
$ 4.898586 usecs/op
                204140 ops/sec

the shell prompt came back before the usecs/op and ops/sec line was
printed. Process teardown race, lack of wait() or so?

---

This caused by lack of calling waitpid() by parent process,
so I added it.

Signed-off-by: Hitoshi Mitake <mitake@...>
Cc: Rusty Russell <rusty@...>
Cc: Peter Zijlstra <a.p.zijlstra@...>
Cc: Paul Mackerras <paulus@...>
Cc: Mike Galbraith <efault@...>
Cc: Arnaldo Carvalho de Melo <acme@...>
Cc: Frederic Weisbecker <fweisbec@...>
Cc: Jiri Kosina <jkosina@...>
---
 tools/perf/bench/sched-pipe.c |   10 +++++++---
 1 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/tools/perf/bench/sched-pipe.c b/tools/perf/bench/sched-pipe.c
index 3214ed2..6a29100 100644
--- a/tools/perf/bench/sched-pipe.c
+++ b/tools/perf/bench/sched-pipe.c
@@ -26,6 +26,7 @@
 #include <errno.h>
 #include <assert.h>
 #include <sys/time.h>
+#include <sys/types.h>
 
 #define LOOPS_DEFAULT 1000000
 static int loops = LOOPS_DEFAULT;
@@ -58,8 +59,8 @@ int bench_sched_pipe(int argc, const char **argv,
  * discarding returned value of read(), write()
  * causes error in building environment for perf
  */
- int ret;
- pid_t pid;
+ int ret, wait_stat;
+ pid_t pid, retpid;
 
  argc = parse_options(argc, argv, options,
      bench_sched_pipe_usage, 0);
@@ -87,8 +88,11 @@ int bench_sched_pipe(int argc, const char **argv,
  gettimeofday(&stop, NULL);
  timersub(&stop, &start, &diff);
 
- if (pid)
+ if (pid) {
+ retpid = waitpid(pid, &wait_stat, 0);
+ assert((retpid == pid) && WIFEXITED(wait_stat));
  return 0;
+ }
 
  if (simple)
  printf("%lu.%03lu\n",
--
1.6.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
< Prev | 1 - 2 | Next >