You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts: net/ipv4/fib_frontend.c
This commit is contained in:
@@ -36,7 +36,6 @@ static const struct option options[] = {
|
||||
|
||||
static int __cmd_buildid_list(void)
|
||||
{
|
||||
int err = -1;
|
||||
struct perf_session *session;
|
||||
|
||||
session = perf_session__new(input_name, O_RDONLY, force, false);
|
||||
@@ -49,7 +48,7 @@ static int __cmd_buildid_list(void)
|
||||
perf_session__fprintf_dsos_buildid(session, stdout, with_hits);
|
||||
|
||||
perf_session__delete(session);
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cmd_buildid_list(int argc, const char **argv, const char *prefix __used)
|
||||
|
||||
@@ -249,6 +249,11 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
|
||||
!params.show_lines))
|
||||
usage_with_options(probe_usage, options);
|
||||
|
||||
/*
|
||||
* Only consider the user's kernel image path if given.
|
||||
*/
|
||||
symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
|
||||
|
||||
if (params.list_events) {
|
||||
if (params.mod_events) {
|
||||
pr_err(" Error: Don't use --list with --add/--del.\n");
|
||||
|
||||
+13
-10
@@ -197,7 +197,7 @@ static void sig_atexit(void)
|
||||
if (child_pid > 0)
|
||||
kill(child_pid, SIGTERM);
|
||||
|
||||
if (signr == -1)
|
||||
if (signr == -1 || signr == SIGUSR1)
|
||||
return;
|
||||
|
||||
signal(signr, SIG_DFL);
|
||||
@@ -515,6 +515,7 @@ static int __cmd_record(int argc, const char **argv)
|
||||
atexit(sig_atexit);
|
||||
signal(SIGCHLD, sig_handler);
|
||||
signal(SIGINT, sig_handler);
|
||||
signal(SIGUSR1, sig_handler);
|
||||
|
||||
if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) {
|
||||
perror("failed to create pipes");
|
||||
@@ -606,6 +607,7 @@ static int __cmd_record(int argc, const char **argv)
|
||||
execvp(argv[0], (char **)argv);
|
||||
|
||||
perror(argv[0]);
|
||||
kill(getppid(), SIGUSR1);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
@@ -697,17 +699,18 @@ static int __cmd_record(int argc, const char **argv)
|
||||
if (err < 0)
|
||||
err = event__synthesize_kernel_mmap(process_synthesized_event,
|
||||
session, machine, "_stext");
|
||||
if (err < 0) {
|
||||
pr_err("Couldn't record kernel reference relocation symbol.\n");
|
||||
return err;
|
||||
}
|
||||
if (err < 0)
|
||||
pr_err("Couldn't record kernel reference relocation symbol\n"
|
||||
"Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
|
||||
"Check /proc/kallsyms permission or run as root.\n");
|
||||
|
||||
err = event__synthesize_modules(process_synthesized_event,
|
||||
session, machine);
|
||||
if (err < 0) {
|
||||
pr_err("Couldn't record kernel reference relocation symbol.\n");
|
||||
return err;
|
||||
}
|
||||
if (err < 0)
|
||||
pr_err("Couldn't record kernel module information.\n"
|
||||
"Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
|
||||
"Check /proc/modules permission or run as root.\n");
|
||||
|
||||
if (perf_guest)
|
||||
perf_session__process_machines(session, event__synthesize_guest_os);
|
||||
|
||||
@@ -761,7 +764,7 @@ static int __cmd_record(int argc, const char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (quiet)
|
||||
if (quiet || signr == SIGUSR1)
|
||||
return 0;
|
||||
|
||||
fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
|
||||
|
||||
@@ -265,15 +265,16 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
|
||||
const char *name, bool is_kallsyms)
|
||||
{
|
||||
const size_t size = PATH_MAX;
|
||||
char *filename = malloc(size),
|
||||
char *realname = realpath(name, NULL),
|
||||
*filename = malloc(size),
|
||||
*linkname = malloc(size), *targetname;
|
||||
int len, err = -1;
|
||||
|
||||
if (filename == NULL || linkname == NULL)
|
||||
if (realname == NULL || filename == NULL || linkname == NULL)
|
||||
goto out_free;
|
||||
|
||||
len = snprintf(filename, size, "%s%s%s",
|
||||
debugdir, is_kallsyms ? "/" : "", name);
|
||||
debugdir, is_kallsyms ? "/" : "", realname);
|
||||
if (mkdir_p(filename, 0755))
|
||||
goto out_free;
|
||||
|
||||
@@ -283,7 +284,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
|
||||
if (is_kallsyms) {
|
||||
if (copyfile("/proc/kallsyms", filename))
|
||||
goto out_free;
|
||||
} else if (link(name, filename) && copyfile(name, filename))
|
||||
} else if (link(realname, filename) && copyfile(name, filename))
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
@@ -300,6 +301,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
|
||||
if (symlink(targetname, linkname) == 0)
|
||||
err = 0;
|
||||
out_free:
|
||||
free(realname);
|
||||
free(filename);
|
||||
free(linkname);
|
||||
return err;
|
||||
@@ -946,11 +948,16 @@ perf_header__find_attr(u64 id, struct perf_header *header)
|
||||
|
||||
/*
|
||||
* We set id to -1 if the data file doesn't contain sample
|
||||
* ids. Check for this and avoid walking through the entire
|
||||
* list of ids which may be large.
|
||||
* ids. This can happen when the data file contains one type
|
||||
* of event and in that case, the header can still store the
|
||||
* event attribute information. Check for this and avoid
|
||||
* walking through the entire list of ids which may be large.
|
||||
*/
|
||||
if (id == -1ULL)
|
||||
if (id == -1ULL) {
|
||||
if (header->attrs > 0)
|
||||
return &header->attr[0]->attr;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < header->attrs; i++) {
|
||||
struct perf_header_attr *attr = header->attr[i];
|
||||
|
||||
@@ -114,6 +114,8 @@ static struct symbol *__find_kernel_function_by_name(const char *name,
|
||||
const char *kernel_get_module_path(const char *module)
|
||||
{
|
||||
struct dso *dso;
|
||||
struct map *map;
|
||||
const char *vmlinux_name;
|
||||
|
||||
if (module) {
|
||||
list_for_each_entry(dso, &machine.kernel_dsos, node) {
|
||||
@@ -123,10 +125,17 @@ const char *kernel_get_module_path(const char *module)
|
||||
}
|
||||
pr_debug("Failed to find module %s.\n", module);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
map = machine.vmlinux_maps[MAP__FUNCTION];
|
||||
dso = map->dso;
|
||||
|
||||
vmlinux_name = symbol_conf.vmlinux_name;
|
||||
if (vmlinux_name) {
|
||||
if (dso__load_vmlinux(dso, map, vmlinux_name, NULL) <= 0)
|
||||
return NULL;
|
||||
} else {
|
||||
dso = machine.vmlinux_maps[MAP__FUNCTION]->dso;
|
||||
if (dso__load_vmlinux_path(dso,
|
||||
machine.vmlinux_maps[MAP__FUNCTION], NULL) < 0) {
|
||||
if (dso__load_vmlinux_path(dso, map, NULL) <= 0) {
|
||||
pr_debug("Failed to load kernel map.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -117,28 +117,6 @@ static void line_list__free(struct list_head *head)
|
||||
}
|
||||
|
||||
/* Dwarf FL wrappers */
|
||||
|
||||
static int __linux_kernel_find_elf(Dwfl_Module *mod,
|
||||
void **userdata,
|
||||
const char *module_name,
|
||||
Dwarf_Addr base,
|
||||
char **file_name, Elf **elfp)
|
||||
{
|
||||
int fd;
|
||||
const char *path = kernel_get_module_path(module_name);
|
||||
|
||||
if (path) {
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd >= 0) {
|
||||
*file_name = strdup(path);
|
||||
return fd;
|
||||
}
|
||||
}
|
||||
/* If failed, try to call standard method */
|
||||
return dwfl_linux_kernel_find_elf(mod, userdata, module_name, base,
|
||||
file_name, elfp);
|
||||
}
|
||||
|
||||
static char *debuginfo_path; /* Currently dummy */
|
||||
|
||||
static const Dwfl_Callbacks offline_callbacks = {
|
||||
@@ -151,14 +129,6 @@ static const Dwfl_Callbacks offline_callbacks = {
|
||||
.find_elf = dwfl_build_id_find_elf,
|
||||
};
|
||||
|
||||
static const Dwfl_Callbacks kernel_callbacks = {
|
||||
.find_debuginfo = dwfl_standard_find_debuginfo,
|
||||
.debuginfo_path = &debuginfo_path,
|
||||
|
||||
.find_elf = __linux_kernel_find_elf,
|
||||
.section_address = dwfl_linux_kernel_module_section_address,
|
||||
};
|
||||
|
||||
/* Get a Dwarf from offline image */
|
||||
static Dwarf *dwfl_init_offline_dwarf(int fd, Dwfl **dwflp, Dwarf_Addr *bias)
|
||||
{
|
||||
@@ -185,6 +155,38 @@ error:
|
||||
return dbg;
|
||||
}
|
||||
|
||||
#if _ELFUTILS_PREREQ(0, 148)
|
||||
/* This method is buggy if elfutils is older than 0.148 */
|
||||
static int __linux_kernel_find_elf(Dwfl_Module *mod,
|
||||
void **userdata,
|
||||
const char *module_name,
|
||||
Dwarf_Addr base,
|
||||
char **file_name, Elf **elfp)
|
||||
{
|
||||
int fd;
|
||||
const char *path = kernel_get_module_path(module_name);
|
||||
|
||||
pr_debug2("Use file %s for %s\n", path, module_name);
|
||||
if (path) {
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd >= 0) {
|
||||
*file_name = strdup(path);
|
||||
return fd;
|
||||
}
|
||||
}
|
||||
/* If failed, try to call standard method */
|
||||
return dwfl_linux_kernel_find_elf(mod, userdata, module_name, base,
|
||||
file_name, elfp);
|
||||
}
|
||||
|
||||
static const Dwfl_Callbacks kernel_callbacks = {
|
||||
.find_debuginfo = dwfl_standard_find_debuginfo,
|
||||
.debuginfo_path = &debuginfo_path,
|
||||
|
||||
.find_elf = __linux_kernel_find_elf,
|
||||
.section_address = dwfl_linux_kernel_module_section_address,
|
||||
};
|
||||
|
||||
/* Get a Dwarf from live kernel image */
|
||||
static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr, Dwfl **dwflp,
|
||||
Dwarf_Addr *bias)
|
||||
@@ -205,11 +207,34 @@ static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr, Dwfl **dwflp,
|
||||
dbg = dwfl_addrdwarf(*dwflp, addr, bias);
|
||||
/* Here, check whether we could get a real dwarf */
|
||||
if (!dbg) {
|
||||
pr_debug("Failed to find kernel dwarf at %lx\n",
|
||||
(unsigned long)addr);
|
||||
dwfl_end(*dwflp);
|
||||
*dwflp = NULL;
|
||||
}
|
||||
return dbg;
|
||||
}
|
||||
#else
|
||||
/* With older elfutils, this just support kernel module... */
|
||||
static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr __used, Dwfl **dwflp,
|
||||
Dwarf_Addr *bias)
|
||||
{
|
||||
int fd;
|
||||
const char *path = kernel_get_module_path("kernel");
|
||||
|
||||
if (!path) {
|
||||
pr_err("Failed to find vmlinux path\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pr_debug2("Use file %s for debuginfo\n", path);
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
return dwfl_init_offline_dwarf(fd, dwflp, bias);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Dwarf wrappers */
|
||||
|
||||
|
||||
@@ -259,7 +259,7 @@ static bool __match_glob(const char *str, const char *pat, bool ignore_space)
|
||||
if (!*pat) /* Tail wild card matches all */
|
||||
return true;
|
||||
while (*str)
|
||||
if (strglobmatch(str++, pat))
|
||||
if (__match_glob(str++, pat, ignore_space))
|
||||
return true;
|
||||
}
|
||||
return !*str && !*pat;
|
||||
|
||||
@@ -295,7 +295,9 @@ static void symbols__insert_by_name(struct rb_root *self, struct symbol *sym)
|
||||
{
|
||||
struct rb_node **p = &self->rb_node;
|
||||
struct rb_node *parent = NULL;
|
||||
struct symbol_name_rb_node *symn = ((void *)sym) - sizeof(*parent), *s;
|
||||
struct symbol_name_rb_node *symn, *s;
|
||||
|
||||
symn = container_of(sym, struct symbol_name_rb_node, sym);
|
||||
|
||||
while (*p != NULL) {
|
||||
parent = *p;
|
||||
@@ -530,7 +532,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
|
||||
struct machine *machine = kmaps->machine;
|
||||
struct map *curr_map = map;
|
||||
struct symbol *pos;
|
||||
int count = 0;
|
||||
int count = 0, moved = 0;
|
||||
struct rb_root *root = &self->symbols[map->type];
|
||||
struct rb_node *next = rb_first(root);
|
||||
int kernel_range = 0;
|
||||
@@ -588,6 +590,11 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
|
||||
char dso_name[PATH_MAX];
|
||||
struct dso *dso;
|
||||
|
||||
if (count == 0) {
|
||||
curr_map = map;
|
||||
goto filter_symbol;
|
||||
}
|
||||
|
||||
if (self->kernel == DSO_TYPE_GUEST_KERNEL)
|
||||
snprintf(dso_name, sizeof(dso_name),
|
||||
"[guest.kernel].%d",
|
||||
@@ -613,7 +620,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
|
||||
map_groups__insert(kmaps, curr_map);
|
||||
++kernel_range;
|
||||
}
|
||||
|
||||
filter_symbol:
|
||||
if (filter && filter(curr_map, pos)) {
|
||||
discard_symbol: rb_erase(&pos->rb_node, root);
|
||||
symbol__delete(pos);
|
||||
@@ -621,8 +628,9 @@ discard_symbol: rb_erase(&pos->rb_node, root);
|
||||
if (curr_map != map) {
|
||||
rb_erase(&pos->rb_node, root);
|
||||
symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
|
||||
}
|
||||
count++;
|
||||
++moved;
|
||||
} else
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -632,7 +640,7 @@ discard_symbol: rb_erase(&pos->rb_node, root);
|
||||
dso__set_loaded(curr_map->dso, curr_map->type);
|
||||
}
|
||||
|
||||
return count;
|
||||
return count + moved;
|
||||
}
|
||||
|
||||
int dso__load_kallsyms(struct dso *self, const char *filename,
|
||||
@@ -1772,8 +1780,8 @@ out_failure:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int dso__load_vmlinux(struct dso *self, struct map *map,
|
||||
const char *vmlinux, symbol_filter_t filter)
|
||||
int dso__load_vmlinux(struct dso *self, struct map *map,
|
||||
const char *vmlinux, symbol_filter_t filter)
|
||||
{
|
||||
int err = -1, fd;
|
||||
|
||||
@@ -2123,14 +2131,55 @@ static struct dso *machine__create_kernel(struct machine *self)
|
||||
return kernel;
|
||||
}
|
||||
|
||||
struct process_args {
|
||||
u64 start;
|
||||
};
|
||||
|
||||
static int symbol__in_kernel(void *arg, const char *name,
|
||||
char type __used, u64 start)
|
||||
{
|
||||
struct process_args *args = arg;
|
||||
|
||||
if (strchr(name, '['))
|
||||
return 0;
|
||||
|
||||
args->start = start;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Figure out the start address of kernel map from /proc/kallsyms */
|
||||
static u64 machine__get_kernel_start_addr(struct machine *machine)
|
||||
{
|
||||
const char *filename;
|
||||
char path[PATH_MAX];
|
||||
struct process_args args;
|
||||
|
||||
if (machine__is_host(machine)) {
|
||||
filename = "/proc/kallsyms";
|
||||
} else {
|
||||
if (machine__is_default_guest(machine))
|
||||
filename = (char *)symbol_conf.default_guest_kallsyms;
|
||||
else {
|
||||
sprintf(path, "%s/proc/kallsyms", machine->root_dir);
|
||||
filename = path;
|
||||
}
|
||||
}
|
||||
|
||||
if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0)
|
||||
return 0;
|
||||
|
||||
return args.start;
|
||||
}
|
||||
|
||||
int __machine__create_kernel_maps(struct machine *self, struct dso *kernel)
|
||||
{
|
||||
enum map_type type;
|
||||
u64 start = machine__get_kernel_start_addr(self);
|
||||
|
||||
for (type = 0; type < MAP__NR_TYPES; ++type) {
|
||||
struct kmap *kmap;
|
||||
|
||||
self->vmlinux_maps[type] = map__new2(0, kernel, type);
|
||||
self->vmlinux_maps[type] = map__new2(start, kernel, type);
|
||||
if (self->vmlinux_maps[type] == NULL)
|
||||
return -1;
|
||||
|
||||
|
||||
@@ -166,6 +166,8 @@ void dso__sort_by_name(struct dso *self, enum map_type type);
|
||||
struct dso *__dsos__findnew(struct list_head *head, const char *name);
|
||||
|
||||
int dso__load(struct dso *self, struct map *map, symbol_filter_t filter);
|
||||
int dso__load_vmlinux(struct dso *self, struct map *map,
|
||||
const char *vmlinux, symbol_filter_t filter);
|
||||
int dso__load_vmlinux_path(struct dso *self, struct map *map,
|
||||
symbol_filter_t filter);
|
||||
int dso__load_kallsyms(struct dso *self, const char *filename, struct map *map,
|
||||
|
||||
Reference in New Issue
Block a user