Skip to content

Commit

Permalink
Merge branches 'x86-fixes-for-linus', 'perf-fixes-for-linus' and 'sch…
Browse files Browse the repository at this point in the history
…ed-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86/pvclock: Zero last_value on resume

* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  perf record: Fix eternal wait for stillborn child
  perf header: Don't assume there's no attr info if no sample ids is provided
  perf symbols: Figure out start address of kernel map from kallsyms
  perf symbols: Fix kallsyms kernel/module map splitting

* 'sched-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  nohz: Fix printk_needs_cpu() return value on offline cpus
  printk: Fix wake_up_klogd() vs cpu hotplug
  • Loading branch information
torvalds committed Dec 8, 2010
4 parents 6dde39b + e7a3481 + 18483b8 + 61ab254 commit 6313e3c
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 12 deletions.
1 change: 1 addition & 0 deletions arch/x86/include/asm/pvclock.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src);
void pvclock_read_wallclock(struct pvclock_wall_clock *wall,
struct pvclock_vcpu_time_info *vcpu,
struct timespec *ts);
void pvclock_resume(void);

/*
* Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction,
Expand Down
5 changes: 5 additions & 0 deletions arch/x86/kernel/pvclock.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src)

static atomic64_t last_value = ATOMIC64_INIT(0);

void pvclock_resume(void)
{
atomic64_set(&last_value, 0);
}

cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src)
{
struct pvclock_shadow_time shadow;
Expand Down
2 changes: 2 additions & 0 deletions arch/x86/xen/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,8 @@ void xen_timer_resume(void)
{
int cpu;

pvclock_resume();

if (xen_clockevent != &xen_vcpuop_clockevent)
return;

Expand Down
4 changes: 3 additions & 1 deletion kernel/printk.c
Original file line number Diff line number Diff line change
Expand Up @@ -1082,13 +1082,15 @@ void printk_tick(void)

int printk_needs_cpu(int cpu)
{
if (unlikely(cpu_is_offline(cpu)))
printk_tick();
return per_cpu(printk_pending, cpu);
}

void wake_up_klogd(void)
{
if (waitqueue_active(&log_wait))
__raw_get_cpu_var(printk_pending) = 1;
this_cpu_write(printk_pending, 1);
}

/**
Expand Down
6 changes: 4 additions & 2 deletions tools/perf/builtin-record.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -762,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);
Expand Down
11 changes: 8 additions & 3 deletions tools/perf/util/header.c
Original file line number Diff line number Diff line change
Expand Up @@ -946,11 +946,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];
Expand Down
59 changes: 53 additions & 6 deletions tools/perf/util/symbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -532,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;
Expand Down Expand Up @@ -590,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",
Expand All @@ -615,16 +620,17 @@ 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);
} else {
if (curr_map != map) {
rb_erase(&pos->rb_node, root);
symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
}
count++;
++moved;
} else
++count;
}
}

Expand All @@ -634,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,
Expand Down Expand Up @@ -2125,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;

Expand Down

0 comments on commit 6313e3c

Please sign in to comment.