Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 169784
b: refs/heads/master
c: 9533ac6
h: refs/heads/master
v: v3
  • Loading branch information
Ingo Molnar committed Nov 25, 2009
1 parent b7cdc55 commit 0c1404f
Show file tree
Hide file tree
Showing 36 changed files with 917 additions and 421 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 75ec29ab848a7e92a41aaafaeb33d1afbc839be4
refs/heads/master: 9533ac6291d78cd16c4b11a15bfbb055affd76c3
4 changes: 2 additions & 2 deletions trunk/arch/x86/kernel/cpu/perf_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -2229,10 +2229,10 @@ validate_event(struct cpu_hw_events *cpuc, struct perf_event *event)
{
struct hw_perf_event fake_event = event->hw;

if (event->pmu != &pmu)
if (event->pmu && event->pmu != &pmu)
return 0;

return x86_schedule_event(cpuc, &fake_event);
return x86_schedule_event(cpuc, &fake_event) >= 0;
}

static int validate_group(struct perf_event *event)
Expand Down
4 changes: 2 additions & 2 deletions trunk/kernel/perf_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -1831,7 +1831,7 @@ static int perf_event_read_group(struct perf_event *event,

size = n * sizeof(u64);

if (copy_to_user(buf + size, values, size)) {
if (copy_to_user(buf + ret, values, size)) {
ret = -EFAULT;
goto unlock;
}
Expand Down Expand Up @@ -3914,7 +3914,7 @@ void perf_swevent_put_recursion_context(int rctx)
{
struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);
barrier();
cpuctx->recursion[rctx]++;
cpuctx->recursion[rctx]--;
put_cpu_var(perf_cpu_context);
}
EXPORT_SYMBOL_GPL(perf_swevent_put_recursion_context);
Expand Down
1 change: 1 addition & 0 deletions trunk/tools/perf/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ perf*.1
perf*.xml
perf*.html
common-cmds.h
perf.data
tags
TAGS
cscope*
44 changes: 44 additions & 0 deletions trunk/tools/perf/Documentation/perf-kmem.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
perf-kmem(1)
==============

NAME
----
perf-kmem - Tool to trace/measure kernel memory(slab) properties

SYNOPSIS
--------
[verse]
'perf kmem' {record} [<options>]

DESCRIPTION
-----------
There's two variants of perf kmem:

'perf kmem record <command>' to record the kmem events
of an arbitrary workload.

'perf kmem' to report kernel memory statistics.

OPTIONS
-------
-i <file>::
--input=<file>::
Select the input file (default: perf.data)

--stat=<caller|alloc>::
Select per callsite or per allocation statistics

-s <key[,key2...]>::
--sort=<key[,key2...]>::
Sort the output (default: frag,hit,bytes)

-l <num>::
--line=<num>::
Print n lines only

--raw-ip::
Print raw ip instead of symbol

SEE ALSO
--------
linkperf:perf-record[1]
3 changes: 3 additions & 0 deletions trunk/tools/perf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ LIB_H += util/sort.h
LIB_H += util/hist.h
LIB_H += util/thread.h
LIB_H += util/data_map.h
LIB_H += util/process_events.h

LIB_OBJS += util/abspath.o
LIB_OBJS += util/alias.o
Expand Down Expand Up @@ -411,6 +412,7 @@ LIB_OBJS += util/svghelper.o
LIB_OBJS += util/sort.o
LIB_OBJS += util/hist.o
LIB_OBJS += util/data_map.o
LIB_OBJS += util/process_events.o

BUILTIN_OBJS += builtin-annotate.o

Expand All @@ -419,6 +421,7 @@ BUILTIN_OBJS += builtin-bench.o
# Benchmark modules
BUILTIN_OBJS += bench/sched-messaging.o
BUILTIN_OBJS += bench/sched-pipe.o
BUILTIN_OBJS += bench/mem-memcpy.o

BUILTIN_OBJS += builtin-help.o
BUILTIN_OBJS += builtin-sched.o
Expand Down
1 change: 1 addition & 0 deletions trunk/tools/perf/bench/bench.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

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);
extern int bench_mem_memcpy(int argc, const char **argv, const char *prefix __used);

#define BENCH_FORMAT_DEFAULT_STR "default"
#define BENCH_FORMAT_DEFAULT 0
Expand Down
193 changes: 193 additions & 0 deletions trunk/tools/perf/bench/mem-memcpy.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
/*
* mem-memcpy.c
*
* memcpy: Simple memory copy in various ways
*
* Written by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
*/
#include <ctype.h>

#include "../perf.h"
#include "../util/util.h"
#include "../util/parse-options.h"
#include "../util/string.h"
#include "../util/header.h"
#include "bench.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <errno.h>

#define K 1024

static const char *length_str = "1MB";
static const char *routine = "default";
static int use_clock = 0;
static int clock_fd;

static const struct option options[] = {
OPT_STRING('l', "length", &length_str, "1MB",
"Specify length of memory to copy. "
"available unit: B, MB, GB (upper and lower)"),
OPT_STRING('r', "routine", &routine, "default",
"Specify routine to copy"),
OPT_BOOLEAN('c', "clock", &use_clock,
"Use CPU clock for measuring"),
OPT_END()
};

struct routine {
const char *name;
const char *desc;
void * (*fn)(void *dst, const void *src, size_t len);
};

struct routine routines[] = {
{ "default",
"Default memcpy() provided by glibc",
memcpy },
{ NULL,
NULL,
NULL }
};

static const char * const bench_mem_memcpy_usage[] = {
"perf bench mem memcpy <options>",
NULL
};

static struct perf_event_attr clock_attr = {
.type = PERF_TYPE_HARDWARE,
.config = PERF_COUNT_HW_CPU_CYCLES
};

static void init_clock(void)
{
clock_fd = sys_perf_event_open(&clock_attr, getpid(), -1, -1, 0);

if (clock_fd < 0 && errno == ENOSYS)
die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
else
BUG_ON(clock_fd < 0);
}

static u64 get_clock(void)
{
int ret;
u64 clk;

ret = read(clock_fd, &clk, sizeof(u64));
BUG_ON(ret != sizeof(u64));

return clk;
}

static double timeval2double(struct timeval *ts)
{
return (double)ts->tv_sec +
(double)ts->tv_usec / (double)1000000;
}

int bench_mem_memcpy(int argc, const char **argv,
const char *prefix __used)
{
int i;
void *dst, *src;
size_t length;
double bps = 0.0;
struct timeval tv_start, tv_end, tv_diff;
u64 clock_start, clock_end, clock_diff;

clock_start = clock_end = clock_diff = 0ULL;
argc = parse_options(argc, argv, options,
bench_mem_memcpy_usage, 0);

tv_diff.tv_sec = 0;
tv_diff.tv_usec = 0;
length = (size_t)perf_atoll((char *)length_str);

if ((s64)length <= 0) {
fprintf(stderr, "Invalid length:%s\n", length_str);
return 1;
}

for (i = 0; routines[i].name; i++) {
if (!strcmp(routines[i].name, routine))
break;
}
if (!routines[i].name) {
printf("Unknown routine:%s\n", routine);
printf("Available routines...\n");
for (i = 0; routines[i].name; i++) {
printf("\t%s ... %s\n",
routines[i].name, routines[i].desc);
}
return 1;
}

dst = zalloc(length);
if (!dst)
die("memory allocation failed - maybe length is too large?\n");

src = zalloc(length);
if (!src)
die("memory allocation failed - maybe length is too large?\n");

if (bench_format == BENCH_FORMAT_DEFAULT) {
printf("# Copying %s Bytes from %p to %p ...\n\n",
length_str, src, dst);
}

if (use_clock) {
init_clock();
clock_start = get_clock();
} else {
BUG_ON(gettimeofday(&tv_start, NULL));
}

routines[i].fn(dst, src, length);

if (use_clock) {
clock_end = get_clock();
clock_diff = clock_end - clock_start;
} else {
BUG_ON(gettimeofday(&tv_end, NULL));
timersub(&tv_end, &tv_start, &tv_diff);
bps = (double)((double)length / timeval2double(&tv_diff));
}

switch (bench_format) {
case BENCH_FORMAT_DEFAULT:
if (use_clock) {
printf(" %14lf Clock/Byte\n",
(double)clock_diff / (double)length);
} else {
if (bps < K)
printf(" %14lf B/Sec\n", bps);
else if (bps < K * K)
printf(" %14lfd KB/Sec\n", bps / 1024);
else if (bps < K * K * K)
printf(" %14lf MB/Sec\n", bps / 1024 / 1024);
else {
printf(" %14lf GB/Sec\n",
bps / 1024 / 1024 / 1024);
}
}
break;
case BENCH_FORMAT_SIMPLE:
if (use_clock) {
printf("%14lf\n",
(double)clock_diff / (double)length);
} else
printf("%lf\n", bps);
break;
default:
/* reaching this means there's some disaster: */
die("unknown format: %d\n", bench_format);
break;
}

return 0;
}
Loading

0 comments on commit 0c1404f

Please sign in to comment.