On Wed, 2010-02-10 at 10:08 -0500, Dave Anderson wrote: > ----- "Michael Holzheu" <holzheu@xxxxxxxxxxxxxxxxxx> wrote: > > > Hi again, > > > > When I change get_smp_cpus() to return "get_highest_cpu_online() + 1" I > > > see five swapper idle tasks when using "ps". The problem I now have is > > > that I have to provide a backtrace for the offline cpus. But the offline > > > CPUs do not have any stack on s390. Is there a way to tell crash that > > > there is no backtrace available? Probably I overlooked something... > > > > Ok, I think I got it now. In case of an offline CPU, I will use > > "task_struct_thread_ksp" like I do it for non active tasks. > > > > When I do that I get for the swapper tasks with the offline CPUs: > > > > PID: 0 TASK: 18d38340 CPU: 2 COMMAND: "swapper" > > #0 [18d3feb8] ret_from_fork at 117e12 > > > > PID: 0 TASK: 18d40440 CPU: 3 COMMAND: "swapper" > > #0 [18d47eb8] ret_from_fork at 117e12 > > I'm not why you should do anything. The cpu is offline and for all > practical purposes it doesn't exist, so why bother? Because you can do a "bt" on the swapper task with the offline CPU. Then s390x_get_stack_frame() is called where I figure out the stack pointer and instruction address. In that function I check if the task is currently running on a CPU and in that case I get the information from the associated s390 lowcore, where the registers are stored in case of a dump. If the task is not running I get the information from the thread struct. > The patch I have queued just uses get_highest_cpu_online()+1 and > does nothing else. But I only tested it on a live system, and > any backtrace attempt on the offlined swapper task just shows > (active). What happens when you do a "bt -a" with a dumpfile? It shows all swapper tasks (online and offline), but I get errors for the backtrace for the offline CPUs. The attached patch would solve the problem (and eliminate most of the probably redundant s390(x)_has_cpu() function. With this patch "ps" shows: PID PPID CPU TASK ST %MEM VSZ RSS COMM > 0 0 0 800ef0 RU 0.0 0 0 [swapper] > 0 0 1 18d30240 RU 0.0 0 0 [swapper] > 0 0 2 18d38340 RU 0.0 0 0 [swapper] > 0 0 3 18d40440 RU 0.0 0 0 [swapper] > 0 0 4 18d48540 RU 0.0 0 0 [swapper] 1 0 1 18d18040 IN 0.2 2244 1020 init ... And "bt -a" shows: PID: 0 TASK: 800ef0 CPU: 0 COMMAND: "swapper" LOWCORE INFO: -psw : 0x0706000180000000 0x0000000000115564 -function : vtime_stop_cpu at 115564 -prefix : 0x18d28000 -cpu timer: 0x7fff00c1 0x00c584ef ... PID: 0 TASK: 18d30240 CPU: 1 COMMAND: "swapper" LOWCORE INFO: -psw : 0x0706000180000000 0x0000000000115564 -function : vtime_stop_cpu at 115564 ... PID: 0 TASK: 18d38340 CPU: 2 COMMAND: "swapper" #0 [18d3feb8] ret_from_fork at 117e12 ... PID: 0 TASK: 18d40440 CPU: 3 COMMAND: "swapper" #0 [18d47eb8] ret_from_fork at 117e12 ... PID: 0 TASK: 18d48540 CPU: 4 COMMAND: "swapper" LOWCORE INFO: -psw : 0x0706000180000000 0x0000000000115564 -function : vtime_stop_cpu at 115564 -prefix : 0x1416a000 Michael
--- s390.c | 57 ++++++++++++++------------------------------------------- s390x.c | 57 ++++++++++++++------------------------------------------- 2 files changed, 28 insertions(+), 86 deletions(-) --- a/s390.c +++ b/s390.c @@ -542,46 +542,17 @@ s390_cpu_of_task(unsigned long task) } /* - * returns true, if task currently is executed by a cpu + * returns true, if task of bt currently is executed by a cpu */ static int -s390_has_cpu(unsigned long task) +s390_has_cpu(struct bt_info *bt) { - if(VALID_MEMBER(task_struct_cpus_runnable)){ - /* Linux 2.4 */ - unsigned long cpus_runnable; - readmem(task+OFFSET(task_struct_cpus_runnable),KVADDR, - &cpus_runnable,sizeof(cpus_runnable), - "cpus_runnable", FAULT_ON_ERROR); - if(cpus_runnable != ~0U) - return TRUE; - else - return FALSE; - } else { - /* Linux 2.6 */ - unsigned long runqueue_addr, runqueue_offset; - unsigned long cpu_offset, per_cpu_offset_addr, running_task; - char *runqueue; - int cpu; - - cpu = s390_cpu_of_task(task); - runqueue = GETBUF(SIZE(runqueue)); - - runqueue_offset=symbol_value("per_cpu__runqueues"); - per_cpu_offset_addr=symbol_value("__per_cpu_offset"); - readmem(per_cpu_offset_addr + cpu * sizeof(long),KVADDR, - &cpu_offset, sizeof(long),"per_cpu_offset", - FAULT_ON_ERROR); - runqueue_addr=runqueue_offset + cpu_offset; - readmem(runqueue_addr,KVADDR,runqueue,SIZE(runqueue), - "runqueue", FAULT_ON_ERROR); - running_task = ULONG(runqueue + OFFSET(runqueue_curr)); - FREEBUF(runqueue); - if(running_task == task) - return TRUE; - else - return FALSE; - } + int cpu = bt->tc->processor; + + if (is_task_active(bt->task) && (kt->cpu_flags[cpu] & ONLINE)) + return TRUE; + else + return FALSE; } /* @@ -635,7 +606,7 @@ s390_back_trace_cmd(struct bt_info *bt) ksp = bt->stkptr; /* print lowcore and get async stack when task has cpu */ - if(s390_has_cpu(bt->task)){ + if(s390_has_cpu(bt)){ char lowcore[LOWCORE_SIZE]; unsigned long psw_flags; int cpu = s390_cpu_of_task(bt->task); @@ -687,7 +658,7 @@ s390_back_trace_cmd(struct bt_info *bt) stack = bt->stackbuf; stack_base = stack_start; } else if((backchain > async_start) && (backchain < async_end) - && s390_has_cpu(bt->task)){ + && s390_has_cpu(bt)){ stack = async_stack; stack_base = async_start; } else { @@ -903,12 +874,12 @@ s390_get_stack_frame(struct bt_info *bt, int r14_offset; char lowcore[LOWCORE_SIZE]; - if(s390_has_cpu(bt->task)) + if(s390_has_cpu(bt)) s390_get_lowcore(s390_cpu_of_task(bt->task),lowcore); /* get the stack pointer */ if(esp){ - if(s390_has_cpu(bt->task)){ + if(s390_has_cpu(bt)){ ksp = ULONG(lowcore + MEMBER_OFFSET("_lowcore", "gpregs_save_area") + (15 * S390_WORD_SIZE)); } else { @@ -926,7 +897,7 @@ s390_get_stack_frame(struct bt_info *bt, if(!eip) return; - if(s390_has_cpu(bt->task) && esp){ + if(s390_has_cpu(bt) && esp){ *eip = ULONG(lowcore + OFFSET(s390_lowcore_psw_save_area) + S390_WORD_SIZE) & S390_ADDR_MASK; } else { @@ -1015,7 +986,7 @@ s390_dis_filter(ulong vaddr, char *inbuf int s390_get_smp_cpus(void) { - return get_cpus_online(); + return (get_highest_cpu_online() + 1); } /* --- a/s390x.c +++ b/s390x.c @@ -554,46 +554,17 @@ s390x_cpu_of_task(unsigned long task) } /* - * returns true, if task currently is executed by a cpu + * returns true, if task of bt currently is executed by a cpu */ static int -s390x_has_cpu(unsigned long task) +s390x_has_cpu(struct bt_info *bt) { - if(VALID_MEMBER(task_struct_cpus_runnable)){ - /* Linux 2.4 */ - unsigned long cpus_runnable; - readmem(task+OFFSET(task_struct_cpus_runnable),KVADDR, - &cpus_runnable,sizeof(cpus_runnable), - "cpus_runnable", FAULT_ON_ERROR); - if(cpus_runnable != ~0ULL) - return TRUE; - else - return FALSE; - } else { - /* Linux 2.6 */ - unsigned long runqueue_addr, runqueue_offset; - unsigned long cpu_offset, per_cpu_offset_addr, running_task; - char *runqueue; - int cpu; - - cpu = s390x_cpu_of_task(task); - runqueue = GETBUF(SIZE(runqueue)); - - runqueue_offset=symbol_value("per_cpu__runqueues"); - per_cpu_offset_addr=symbol_value("__per_cpu_offset"); - readmem(per_cpu_offset_addr + cpu * sizeof(long),KVADDR, - &cpu_offset, sizeof(long),"per_cpu_offset", - FAULT_ON_ERROR); - runqueue_addr=runqueue_offset + cpu_offset; - readmem(runqueue_addr,KVADDR,runqueue,SIZE(runqueue), - "runqueue", FAULT_ON_ERROR); - running_task = ULONG(runqueue + OFFSET(runqueue_curr)); - FREEBUF(runqueue); - if(running_task == task) - return TRUE; - else - return FALSE; - } + int cpu = bt->tc->processor; + + if (is_task_active(bt->task) && (kt->cpu_flags[cpu] & ONLINE)) + return TRUE; + else + return FALSE; } /* @@ -647,7 +618,7 @@ s390x_back_trace_cmd(struct bt_info *bt) ksp = bt->stkptr; /* print lowcore and get async stack when task has cpu */ - if(s390x_has_cpu(bt->task)){ + if(s390x_has_cpu(bt)){ char lowcore[LOWCORE_SIZE]; unsigned long psw_flags; int cpu = s390x_cpu_of_task(bt->task); @@ -700,7 +671,7 @@ s390x_back_trace_cmd(struct bt_info *bt) stack = bt->stackbuf; stack_base = stack_start; } else if((backchain > async_start) && (backchain < async_end) - && s390x_has_cpu(bt->task)){ + && s390x_has_cpu(bt)){ stack = async_stack; stack_base = async_start; } else { @@ -936,12 +907,12 @@ s390x_get_stack_frame(struct bt_info *bt int r14_offset; char lowcore[LOWCORE_SIZE]; - if(s390x_has_cpu(bt->task)) + if(s390x_has_cpu(bt)) s390x_get_lowcore(s390x_cpu_of_task(bt->task),lowcore); /* get the stack pointer */ if(esp){ - if(s390x_has_cpu(bt->task)){ + if(s390x_has_cpu(bt)){ ksp = ULONG(lowcore + MEMBER_OFFSET("_lowcore", "gpregs_save_area") + (15 * S390X_WORD_SIZE)); } else { @@ -959,7 +930,7 @@ s390x_get_stack_frame(struct bt_info *bt if(!eip) return; - if(s390x_has_cpu(bt->task) && esp){ + if(s390x_has_cpu(bt) && esp){ *eip = ULONG(lowcore + OFFSET(s390_lowcore_psw_save_area) + S390X_WORD_SIZE); } else { @@ -1048,7 +1019,7 @@ s390x_dis_filter(ulong vaddr, char *inbu int s390x_get_smp_cpus(void) { - return get_cpus_online(); + return (get_highest_cpu_online() + 1); } /*
-- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility