Merge branches 'perf-fixes-for-linus' and 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: perf probe: Fix to support libdwfl older than 0.148 perf tools: Fix lazy wildcard matching perf buildid-list: Fix error return for success perf buildid-cache: Fix symbolic link handling perf symbols: Stop using vmlinux files with no symbols perf probe: Fix use of kernel image path given by 'k' option * 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86, kexec: Limit the crashkernel address appropriately
This commit is contained in:
commit
79534f237f
|
@ -501,7 +501,18 @@ static inline unsigned long long get_total_mem(void)
|
||||||
return total << PAGE_SHIFT;
|
return total << PAGE_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEFAULT_BZIMAGE_ADDR_MAX 0x37FFFFFF
|
/*
|
||||||
|
* Keep the crash kernel below this limit. On 32 bits earlier kernels
|
||||||
|
* would limit the kernel to the low 512 MiB due to mapping restrictions.
|
||||||
|
* On 64 bits, kexec-tools currently limits us to 896 MiB; increase this
|
||||||
|
* limit once kexec-tools are fixed.
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_X86_32
|
||||||
|
# define CRASH_KERNEL_ADDR_MAX (512 << 20)
|
||||||
|
#else
|
||||||
|
# define CRASH_KERNEL_ADDR_MAX (896 << 20)
|
||||||
|
#endif
|
||||||
|
|
||||||
static void __init reserve_crashkernel(void)
|
static void __init reserve_crashkernel(void)
|
||||||
{
|
{
|
||||||
unsigned long long total_mem;
|
unsigned long long total_mem;
|
||||||
|
@ -520,10 +531,10 @@ static void __init reserve_crashkernel(void)
|
||||||
const unsigned long long alignment = 16<<20; /* 16M */
|
const unsigned long long alignment = 16<<20; /* 16M */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* kexec want bzImage is below DEFAULT_BZIMAGE_ADDR_MAX
|
* kexec want bzImage is below CRASH_KERNEL_ADDR_MAX
|
||||||
*/
|
*/
|
||||||
crash_base = memblock_find_in_range(alignment,
|
crash_base = memblock_find_in_range(alignment,
|
||||||
DEFAULT_BZIMAGE_ADDR_MAX, crash_size, alignment);
|
CRASH_KERNEL_ADDR_MAX, crash_size, alignment);
|
||||||
|
|
||||||
if (crash_base == MEMBLOCK_ERROR) {
|
if (crash_base == MEMBLOCK_ERROR) {
|
||||||
pr_info("crashkernel reservation failed - No suitable area found.\n");
|
pr_info("crashkernel reservation failed - No suitable area found.\n");
|
||||||
|
|
|
@ -36,7 +36,6 @@ static const struct option options[] = {
|
||||||
|
|
||||||
static int __cmd_buildid_list(void)
|
static int __cmd_buildid_list(void)
|
||||||
{
|
{
|
||||||
int err = -1;
|
|
||||||
struct perf_session *session;
|
struct perf_session *session;
|
||||||
|
|
||||||
session = perf_session__new(input_name, O_RDONLY, force, false);
|
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__fprintf_dsos_buildid(session, stdout, with_hits);
|
||||||
|
|
||||||
perf_session__delete(session);
|
perf_session__delete(session);
|
||||||
return err;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_buildid_list(int argc, const char **argv, const char *prefix __used)
|
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))
|
!params.show_lines))
|
||||||
usage_with_options(probe_usage, options);
|
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.list_events) {
|
||||||
if (params.mod_events) {
|
if (params.mod_events) {
|
||||||
pr_err(" Error: Don't use --list with --add/--del.\n");
|
pr_err(" Error: Don't use --list with --add/--del.\n");
|
||||||
|
|
|
@ -265,15 +265,16 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
|
||||||
const char *name, bool is_kallsyms)
|
const char *name, bool is_kallsyms)
|
||||||
{
|
{
|
||||||
const size_t size = PATH_MAX;
|
const size_t size = PATH_MAX;
|
||||||
char *filename = malloc(size),
|
char *realname = realpath(name, NULL),
|
||||||
|
*filename = malloc(size),
|
||||||
*linkname = malloc(size), *targetname;
|
*linkname = malloc(size), *targetname;
|
||||||
int len, err = -1;
|
int len, err = -1;
|
||||||
|
|
||||||
if (filename == NULL || linkname == NULL)
|
if (realname == NULL || filename == NULL || linkname == NULL)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
||||||
len = snprintf(filename, size, "%s%s%s",
|
len = snprintf(filename, size, "%s%s%s",
|
||||||
debugdir, is_kallsyms ? "/" : "", name);
|
debugdir, is_kallsyms ? "/" : "", realname);
|
||||||
if (mkdir_p(filename, 0755))
|
if (mkdir_p(filename, 0755))
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
||||||
|
@ -283,7 +284,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
|
||||||
if (is_kallsyms) {
|
if (is_kallsyms) {
|
||||||
if (copyfile("/proc/kallsyms", filename))
|
if (copyfile("/proc/kallsyms", filename))
|
||||||
goto out_free;
|
goto out_free;
|
||||||
} else if (link(name, filename) && copyfile(name, filename))
|
} else if (link(realname, filename) && copyfile(name, filename))
|
||||||
goto out_free;
|
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)
|
if (symlink(targetname, linkname) == 0)
|
||||||
err = 0;
|
err = 0;
|
||||||
out_free:
|
out_free:
|
||||||
|
free(realname);
|
||||||
free(filename);
|
free(filename);
|
||||||
free(linkname);
|
free(linkname);
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -114,6 +114,8 @@ static struct symbol *__find_kernel_function_by_name(const char *name,
|
||||||
const char *kernel_get_module_path(const char *module)
|
const char *kernel_get_module_path(const char *module)
|
||||||
{
|
{
|
||||||
struct dso *dso;
|
struct dso *dso;
|
||||||
|
struct map *map;
|
||||||
|
const char *vmlinux_name;
|
||||||
|
|
||||||
if (module) {
|
if (module) {
|
||||||
list_for_each_entry(dso, &machine.kernel_dsos, node) {
|
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);
|
pr_debug("Failed to find module %s.\n", module);
|
||||||
return NULL;
|
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 {
|
} else {
|
||||||
dso = machine.vmlinux_maps[MAP__FUNCTION]->dso;
|
if (dso__load_vmlinux_path(dso, map, NULL) <= 0) {
|
||||||
if (dso__load_vmlinux_path(dso,
|
|
||||||
machine.vmlinux_maps[MAP__FUNCTION], NULL) < 0) {
|
|
||||||
pr_debug("Failed to load kernel map.\n");
|
pr_debug("Failed to load kernel map.\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,28 +117,6 @@ static void line_list__free(struct list_head *head)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dwarf FL wrappers */
|
/* 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 char *debuginfo_path; /* Currently dummy */
|
||||||
|
|
||||||
static const Dwfl_Callbacks offline_callbacks = {
|
static const Dwfl_Callbacks offline_callbacks = {
|
||||||
|
@ -151,14 +129,6 @@ static const Dwfl_Callbacks offline_callbacks = {
|
||||||
.find_elf = dwfl_build_id_find_elf,
|
.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 */
|
/* Get a Dwarf from offline image */
|
||||||
static Dwarf *dwfl_init_offline_dwarf(int fd, Dwfl **dwflp, Dwarf_Addr *bias)
|
static Dwarf *dwfl_init_offline_dwarf(int fd, Dwfl **dwflp, Dwarf_Addr *bias)
|
||||||
{
|
{
|
||||||
|
@ -185,6 +155,38 @@ error:
|
||||||
return dbg;
|
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 */
|
/* Get a Dwarf from live kernel image */
|
||||||
static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr, Dwfl **dwflp,
|
static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr, Dwfl **dwflp,
|
||||||
Dwarf_Addr *bias)
|
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);
|
dbg = dwfl_addrdwarf(*dwflp, addr, bias);
|
||||||
/* Here, check whether we could get a real dwarf */
|
/* Here, check whether we could get a real dwarf */
|
||||||
if (!dbg) {
|
if (!dbg) {
|
||||||
|
pr_debug("Failed to find kernel dwarf at %lx\n",
|
||||||
|
(unsigned long)addr);
|
||||||
dwfl_end(*dwflp);
|
dwfl_end(*dwflp);
|
||||||
*dwflp = NULL;
|
*dwflp = NULL;
|
||||||
}
|
}
|
||||||
return dbg;
|
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 */
|
/* 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 */
|
if (!*pat) /* Tail wild card matches all */
|
||||||
return true;
|
return true;
|
||||||
while (*str)
|
while (*str)
|
||||||
if (strglobmatch(str++, pat))
|
if (__match_glob(str++, pat, ignore_space))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return !*str && !*pat;
|
return !*str && !*pat;
|
||||||
|
|
|
@ -1780,8 +1780,8 @@ out_failure:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dso__load_vmlinux(struct dso *self, struct map *map,
|
int dso__load_vmlinux(struct dso *self, struct map *map,
|
||||||
const char *vmlinux, symbol_filter_t filter)
|
const char *vmlinux, symbol_filter_t filter)
|
||||||
{
|
{
|
||||||
int err = -1, fd;
|
int err = -1, fd;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
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(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,
|
int dso__load_vmlinux_path(struct dso *self, struct map *map,
|
||||||
symbol_filter_t filter);
|
symbol_filter_t filter);
|
||||||
int dso__load_kallsyms(struct dso *self, const char *filename, struct map *map,
|
int dso__load_kallsyms(struct dso *self, const char *filename, struct map *map,
|
||||||
|
|
Loading…
Reference in New Issue