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:
Linus Torvalds 2010-12-23 15:39:40 -08:00
commit 79534f237f
9 changed files with 98 additions and 45 deletions

View File

@ -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");

View File

@ -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)

View File

@ -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");

View File

@ -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;

View File

@ -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;
} }

View File

@ -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 */

View File

@ -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;

View File

@ -1780,7 +1780,7 @@ 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;

View File

@ -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,