Make the "bt -E" option conform to a "-c cpu(s)" specification when

the the two options are used together.  Without the patch, "bt -E"
ignores a cpu specifier.
(anderson@redhat.com)
This commit is contained in:
Dave Anderson 2014-10-15 13:30:29 -04:00
parent 00cfb79c04
commit 0c0f2e7440
5 changed files with 32 additions and 7 deletions

2
defs.h
View File

@ -890,6 +890,7 @@ struct bt_info {
ulong debug;
ulong eframe_ip;
ulong radix;
ulong *cpumask;
};
#define STACK_OFFSET_TYPE(OFF) \
@ -4959,6 +4960,7 @@ ulong cpu_map_addr(const char *type);
#define BT_KERNEL_SPACE (0x200000000000ULL)
#define BT_FULL_SYM_SLAB2 (0x400000000000ULL)
#define BT_EFRAME_TARGET (0x800000000000ULL)
#define BT_CPUMASK (0x1000000000000ULL)
#define BT_SYMBOL_OFFSET (BT_SYMBOLIC_ARGS)
#define BT_REF_HEXVAL (0x1)

View File

@ -1983,7 +1983,7 @@ cmd_bt(void)
int i, c;
ulong value, *cpus;
struct task_context *tc;
int subsequent, active, choose_cpu;
int subsequent, active;
struct stack_hook hook;
struct bt_info bt_info, bt_setup, *bt;
struct reference reference;
@ -1993,7 +1993,7 @@ cmd_bt(void)
tc = NULL;
cpus = NULL;
subsequent = active = choose_cpu = 0;
subsequent = active = 0;
hook.eip = hook.esp = 0;
refptr = 0;
bt = &bt_info;
@ -2146,11 +2146,11 @@ cmd_bt(void)
break;
case 'c':
if (choose_cpu) {
if (bt->flags & BT_CPUMASK) {
error(INFO, "only one -c option allowed\n");
argerrs++;
} else {
choose_cpu = 1;
bt->flags |= BT_CPUMASK;
BZERO(arg_buf, BUFSIZE);
strncpy(arg_buf, optarg, strlen(optarg));
cpus = get_cpumask_buf();
@ -2212,6 +2212,10 @@ cmd_bt(void)
if (bt->flags & BT_EFRAME_SEARCH2) {
tc = CURRENT_CONTEXT(); /* borrow stack */
BT_SETUP(tc);
if (bt->flags & BT_CPUMASK) {
make_cpumask(arg_buf, cpus, FAULT_ON_ERROR, NULL);
bt->cpumask = cpus;
}
back_trace(bt);
return;
}
@ -2248,7 +2252,7 @@ cmd_bt(void)
#endif
}
if (choose_cpu) {
if (bt->flags & BT_CPUMASK) {
if (LIVE())
error(FATAL,
"-c option not supported on a live system or live dump\n");
@ -2831,6 +2835,7 @@ dump_bt_info(struct bt_info *bt, char *where)
fprintf(fp, " eframe_ip: %lx\n", bt->eframe_ip);
fprintf(fp, " debug: %lx\n", bt->debug);
fprintf(fp, " radix: %ld\n", bt->radix);
fprintf(fp, " cpumask: %lx\n", (ulong)bt->cpumask);
}
/*

View File

@ -1385,6 +1385,9 @@ ppc64_eframe_search(struct bt_info *bt_in)
for (c = 0; c < NR_CPUS; c++) {
if (tt->hardirq_ctx[c]) {
if ((bt->flags & BT_CPUMASK) &&
!(NUM_IN_BITMAP(bt->cpumask, c)))
continue;
bt->hp->esp = tt->hardirq_ctx[c];
fprintf(fp, "CPU %d HARD IRQ STACK:\n", c);
if ((cnt = ppc64_eframe_search(bt)))
@ -1395,6 +1398,9 @@ ppc64_eframe_search(struct bt_info *bt_in)
}
for (c = 0; c < NR_CPUS; c++) {
if (tt->softirq_ctx[c]) {
if ((bt->flags & BT_CPUMASK) &&
!(NUM_IN_BITMAP(bt->cpumask, c)))
continue;
bt->hp->esp = tt->softirq_ctx[c];
fprintf(fp, "CPU %d SOFT IRQ STACK:\n", c);
if ((cnt = ppc64_eframe_search(bt)))

10
x86.c
View File

@ -1,8 +1,8 @@
/* x86.c - core analysis suite
*
* Portions Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
* Copyright (C) 2002-2013 David Anderson
* Copyright (C) 2002-2013 Red Hat, Inc. All rights reserved.
* Copyright (C) 2002-2014 David Anderson
* Copyright (C) 2002-2014 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -1581,6 +1581,9 @@ x86_eframe_search(struct bt_info *bt_in)
for (c = 0; c < NR_CPUS; c++) {
if (tt->hardirq_ctx[c]) {
if ((bt->flags & BT_CPUMASK) &&
!(NUM_IN_BITMAP(bt->cpumask, c)))
continue;
bt->hp->esp = tt->hardirq_ctx[c];
fprintf(fp, "CPU %d HARD IRQ STACK:\n", c);
if ((cnt = x86_eframe_search(bt)))
@ -1591,6 +1594,9 @@ x86_eframe_search(struct bt_info *bt_in)
}
for (c = 0; c < NR_CPUS; c++) {
if (tt->softirq_ctx[c]) {
if ((bt->flags & BT_CPUMASK) &&
!(NUM_IN_BITMAP(bt->cpumask, c)))
continue;
bt->hp->esp = tt->softirq_ctx[c];
fprintf(fp, "CPU %d SOFT IRQ STACK:\n", c);
if ((cnt = x86_eframe_search(bt)))

View File

@ -2322,6 +2322,9 @@ x86_64_eframe_search(struct bt_info *bt)
ms = machdep->machspec;
for (c = 0; c < kt->cpus; c++) {
if ((bt->flags & BT_CPUMASK) &&
!(NUM_IN_BITMAP(bt->cpumask, c)))
continue;
if (ms->stkinfo.ibase[c] == 0)
break;
bt->hp->esp = ms->stkinfo.ibase[c];
@ -2340,6 +2343,9 @@ x86_64_eframe_search(struct bt_info *bt)
}
for (c = 0; c < kt->cpus; c++) {
if ((bt->flags & BT_CPUMASK) &&
!(NUM_IN_BITMAP(bt->cpumask, c)))
continue;
for (i = 0; i < MAX_EXCEPTION_STACKS; i++) {
if (ms->stkinfo.ebase[c][i] == 0)
break;