mirror of
https://github.com/torvalds/linux.git
synced 2024-12-27 13:22:23 +00:00
perf callchain: Move callchain specific routines from util.[ch]
Where they belong, no point in leaving those in the generic "util" files. Link: http://lkml.kernel.org/n/tip-ljx3iiip1hlfa7a7apjem7ph@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
611f0afee0
commit
56e2e05644
@ -24,6 +24,21 @@
|
|||||||
#include "machine.h"
|
#include "machine.h"
|
||||||
#include "callchain.h"
|
#include "callchain.h"
|
||||||
|
|
||||||
|
#define CALLCHAIN_PARAM_DEFAULT \
|
||||||
|
.mode = CHAIN_GRAPH_ABS, \
|
||||||
|
.min_percent = 0.5, \
|
||||||
|
.order = ORDER_CALLEE, \
|
||||||
|
.key = CCKEY_FUNCTION, \
|
||||||
|
.value = CCVAL_PERCENT, \
|
||||||
|
|
||||||
|
struct callchain_param callchain_param = {
|
||||||
|
CALLCHAIN_PARAM_DEFAULT
|
||||||
|
};
|
||||||
|
|
||||||
|
struct callchain_param callchain_param_default = {
|
||||||
|
CALLCHAIN_PARAM_DEFAULT
|
||||||
|
};
|
||||||
|
|
||||||
__thread struct callchain_cursor callchain_cursor;
|
__thread struct callchain_cursor callchain_cursor;
|
||||||
|
|
||||||
int parse_callchain_record_opt(const char *arg, struct callchain_param *param)
|
int parse_callchain_record_opt(const char *arg, struct callchain_param *param)
|
||||||
@ -113,6 +128,32 @@ static int parse_callchain_value(const char *value)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_stack_size(const char *str, unsigned long *_size)
|
||||||
|
{
|
||||||
|
char *endptr;
|
||||||
|
unsigned long size;
|
||||||
|
unsigned long max_size = round_down(USHRT_MAX, sizeof(u64));
|
||||||
|
|
||||||
|
size = strtoul(str, &endptr, 0);
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (*endptr)
|
||||||
|
break;
|
||||||
|
|
||||||
|
size = round_up(size, sizeof(u64));
|
||||||
|
if (!size || size > max_size)
|
||||||
|
break;
|
||||||
|
|
||||||
|
*_size = size;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
pr_err("callchain: Incorrect stack dump size (max %ld): %s\n",
|
||||||
|
max_size, str);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
__parse_callchain_report_opt(const char *arg, bool allow_record_opt)
|
__parse_callchain_report_opt(const char *arg, bool allow_record_opt)
|
||||||
{
|
{
|
||||||
@ -196,6 +237,68 @@ int parse_callchain_top_opt(const char *arg)
|
|||||||
return __parse_callchain_report_opt(arg, true);
|
return __parse_callchain_report_opt(arg, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int parse_callchain_record(const char *arg, struct callchain_param *param)
|
||||||
|
{
|
||||||
|
char *tok, *name, *saveptr = NULL;
|
||||||
|
char *buf;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
/* We need buffer that we know we can write to. */
|
||||||
|
buf = malloc(strlen(arg) + 1);
|
||||||
|
if (!buf)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
strcpy(buf, arg);
|
||||||
|
|
||||||
|
tok = strtok_r((char *)buf, ",", &saveptr);
|
||||||
|
name = tok ? : (char *)buf;
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* Framepointer style */
|
||||||
|
if (!strncmp(name, "fp", sizeof("fp"))) {
|
||||||
|
if (!strtok_r(NULL, ",", &saveptr)) {
|
||||||
|
param->record_mode = CALLCHAIN_FP;
|
||||||
|
ret = 0;
|
||||||
|
} else
|
||||||
|
pr_err("callchain: No more arguments "
|
||||||
|
"needed for --call-graph fp\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Dwarf style */
|
||||||
|
} else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
|
||||||
|
const unsigned long default_stack_dump_size = 8192;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
param->record_mode = CALLCHAIN_DWARF;
|
||||||
|
param->dump_size = default_stack_dump_size;
|
||||||
|
|
||||||
|
tok = strtok_r(NULL, ",", &saveptr);
|
||||||
|
if (tok) {
|
||||||
|
unsigned long size = 0;
|
||||||
|
|
||||||
|
ret = get_stack_size(tok, &size);
|
||||||
|
param->dump_size = size;
|
||||||
|
}
|
||||||
|
} else if (!strncmp(name, "lbr", sizeof("lbr"))) {
|
||||||
|
if (!strtok_r(NULL, ",", &saveptr)) {
|
||||||
|
param->record_mode = CALLCHAIN_LBR;
|
||||||
|
ret = 0;
|
||||||
|
} else
|
||||||
|
pr_err("callchain: No more arguments "
|
||||||
|
"needed for --call-graph lbr\n");
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
pr_err("callchain: Unknown --call-graph option "
|
||||||
|
"value: %s\n", arg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int perf_callchain_config(const char *var, const char *value)
|
int perf_callchain_config(const char *var, const char *value)
|
||||||
{
|
{
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
@ -4,12 +4,25 @@
|
|||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include "evlist.h"
|
#include "evlist.h"
|
||||||
|
#include "callchain.h"
|
||||||
#include "evsel.h"
|
#include "evsel.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "cpumap.h"
|
#include "cpumap.h"
|
||||||
#include "print_binary.h"
|
#include "print_binary.h"
|
||||||
#include "thread_map.h"
|
#include "thread_map.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Provide these two so that we don't have to link against callchain.c and
|
||||||
|
* start dragging hist.c, etc.
|
||||||
|
*/
|
||||||
|
struct callchain_param callchain_param;
|
||||||
|
|
||||||
|
int parse_callchain_record(const char *arg __maybe_unused,
|
||||||
|
struct callchain_param *param __maybe_unused)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Support debug printing even though util/debug.c is not linked. That means
|
* Support debug printing even though util/debug.c is not linked. That means
|
||||||
* implementing 'verbose' and 'eprintf'.
|
* implementing 'verbose' and 'eprintf'.
|
||||||
|
@ -17,24 +17,8 @@
|
|||||||
#include <linux/log2.h>
|
#include <linux/log2.h>
|
||||||
#include <linux/time64.h>
|
#include <linux/time64.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "callchain.h"
|
|
||||||
#include "strlist.h"
|
#include "strlist.h"
|
||||||
|
|
||||||
#define CALLCHAIN_PARAM_DEFAULT \
|
|
||||||
.mode = CHAIN_GRAPH_ABS, \
|
|
||||||
.min_percent = 0.5, \
|
|
||||||
.order = ORDER_CALLEE, \
|
|
||||||
.key = CCKEY_FUNCTION, \
|
|
||||||
.value = CCVAL_PERCENT, \
|
|
||||||
|
|
||||||
struct callchain_param callchain_param = {
|
|
||||||
CALLCHAIN_PARAM_DEFAULT
|
|
||||||
};
|
|
||||||
|
|
||||||
struct callchain_param callchain_param_default = {
|
|
||||||
CALLCHAIN_PARAM_DEFAULT
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX We need to find a better place for these things...
|
* XXX We need to find a better place for these things...
|
||||||
*/
|
*/
|
||||||
@ -377,94 +361,6 @@ unsigned long parse_tag_value(const char *str, struct parse_tag *tags)
|
|||||||
return (unsigned long) -1;
|
return (unsigned long) -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_stack_size(const char *str, unsigned long *_size)
|
|
||||||
{
|
|
||||||
char *endptr;
|
|
||||||
unsigned long size;
|
|
||||||
unsigned long max_size = round_down(USHRT_MAX, sizeof(u64));
|
|
||||||
|
|
||||||
size = strtoul(str, &endptr, 0);
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (*endptr)
|
|
||||||
break;
|
|
||||||
|
|
||||||
size = round_up(size, sizeof(u64));
|
|
||||||
if (!size || size > max_size)
|
|
||||||
break;
|
|
||||||
|
|
||||||
*_size = size;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
pr_err("callchain: Incorrect stack dump size (max %ld): %s\n",
|
|
||||||
max_size, str);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int parse_callchain_record(const char *arg, struct callchain_param *param)
|
|
||||||
{
|
|
||||||
char *tok, *name, *saveptr = NULL;
|
|
||||||
char *buf;
|
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
/* We need buffer that we know we can write to. */
|
|
||||||
buf = malloc(strlen(arg) + 1);
|
|
||||||
if (!buf)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
strcpy(buf, arg);
|
|
||||||
|
|
||||||
tok = strtok_r((char *)buf, ",", &saveptr);
|
|
||||||
name = tok ? : (char *)buf;
|
|
||||||
|
|
||||||
do {
|
|
||||||
/* Framepointer style */
|
|
||||||
if (!strncmp(name, "fp", sizeof("fp"))) {
|
|
||||||
if (!strtok_r(NULL, ",", &saveptr)) {
|
|
||||||
param->record_mode = CALLCHAIN_FP;
|
|
||||||
ret = 0;
|
|
||||||
} else
|
|
||||||
pr_err("callchain: No more arguments "
|
|
||||||
"needed for --call-graph fp\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Dwarf style */
|
|
||||||
} else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
|
|
||||||
const unsigned long default_stack_dump_size = 8192;
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
param->record_mode = CALLCHAIN_DWARF;
|
|
||||||
param->dump_size = default_stack_dump_size;
|
|
||||||
|
|
||||||
tok = strtok_r(NULL, ",", &saveptr);
|
|
||||||
if (tok) {
|
|
||||||
unsigned long size = 0;
|
|
||||||
|
|
||||||
ret = get_stack_size(tok, &size);
|
|
||||||
param->dump_size = size;
|
|
||||||
}
|
|
||||||
} else if (!strncmp(name, "lbr", sizeof("lbr"))) {
|
|
||||||
if (!strtok_r(NULL, ",", &saveptr)) {
|
|
||||||
param->record_mode = CALLCHAIN_LBR;
|
|
||||||
ret = 0;
|
|
||||||
} else
|
|
||||||
pr_err("callchain: No more arguments "
|
|
||||||
"needed for --call-graph lbr\n");
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
pr_err("callchain: Unknown --call-graph option "
|
|
||||||
"value: %s\n", arg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
free(buf);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int perf_event_paranoid(void)
|
int perf_event_paranoid(void)
|
||||||
{
|
{
|
||||||
int value;
|
int value;
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -25,7 +24,6 @@
|
|||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
extern char buildid_dir[];
|
extern char buildid_dir[];
|
||||||
@ -99,8 +97,6 @@ void mem_bswap_32(void *src, int byte_size);
|
|||||||
|
|
||||||
bool find_process(const char *name);
|
bool find_process(const char *name);
|
||||||
|
|
||||||
int get_stack_size(const char *str, unsigned long *_size);
|
|
||||||
|
|
||||||
int fetch_kernel_version(unsigned int *puint,
|
int fetch_kernel_version(unsigned int *puint,
|
||||||
char *str, size_t str_sz);
|
char *str, size_t str_sz);
|
||||||
#define KVER_VERSION(x) (((x) >> 16) & 0xff)
|
#define KVER_VERSION(x) (((x) >> 16) & 0xff)
|
||||||
|
Loading…
Reference in New Issue
Block a user