[Linux-Xtensa] Re: [patch 0/8] xtensa: s6000 & s6105 - Git Repo
Pulled; will try to merge early next week and get back to ya.
linux-xtensa at linux-xtensa.org
linux-xtensa at linux-xtensa.org
Fri Mar 20 03:19:00 PDT 2009
Johannes Weiner wrote:
> On Tue, Mar 17, 2009 at 03:23:17PM +0100, Johannes Weiner wrote:
>> On Tue, Mar 17, 2009 at 01:18:48AM -0700, Piet Delaney wrote:
>>
>>> Maxim and I sorted out the 2.6.27 header problem and I'm cleaning up my
>>> files to check in the stuff Marc and I did to stabilize the SMP (including
>>> cache alias issues) and new V3 MMU code. Once checked in I'll try
>>> merging with your git repository. I put a local cache on linux-xtensa.org
>>> so everyone here has ready access to it.
>>>
>>> http://git.linux-xtensa.org/cgi-bin/git.cgi?p=kernel/linux-2.6-xtensa-emlix;a=summary
>> That's great, thank you. Can I push to it as well? Then we could
>> have all 'linux on xtensa' related development in one place.
>>
>>> I've got a Stretch IP Camera board and a Stretch Debug board.
>> There are two versions of this board, the s6105 and the s6106. Which
>> one do you have? We have the s6105 but they differ only in the
>> peripherals AFAIK so the patches you have from us until now should
>> work on both.
>
> To get you kickstarted on testing, we tarballed a chroot directory
> that contains our cross-toolchain. All you need to do is to copy
> kernel sources into it and build them with our supplied config. There
> is a nice step-by-step README in the toplevel directory :-)
Thanks, I appreciate it.
>
> You can get the archive from here:
>
> http://filehub.emlix.com/filehub.php?md5=523b8d38bee5d588370d0f7f52ac086b
Got it.
>
> By the way, for when have you scheduled mainline integration of SMP
> support and the new MMU code?
I was wondering if we could push both of our changes together.
Our new code is much more stable and easy to debug with.
> We also have a bunch of device drivers that will soon show up on our
> public git repository. Our goal is to get as much of them into the
> .30 release but we'd need having our arch code adjustments in mainline
> first so that the order of merges make sense - otherwise there would
> be device drivers in the subtrees without any possible configurations
> to use them.
>
> Problem is, the merge window for .30 will probably open up in one to
> two weeks and when it closes, no new features are allowed anymore and
> we would have to wait for the next one in 6 to 8 weeks.
We had a kernel problem earlier this week where we hung after 5 days and
I needed to see what's going on inside the tasks. I got hung up getting
a gdb macro working that like the Kdump 'btt' macro dumps the stacks of all
of the kernel threads. See attachment. I think you will find it handy. I'm
shooting for one month without any failures by the time of the SMP release
but would like to check-in this Beta code now.
I'll be checking in tomorrow and merging with your code and the 2.6.27-stable
repository. I don't expect the merge with your changes to take long. Once
it's merged I'll post it and you guys and Christian can check it out. If there's
are no issues Christian could pull it to his linux-next repo, which is currently
linked to the linux-next repo for the Xtensa arch.
Perhaps it's more complicated than that. I think Christian, and the folks here
and over there are likely in the best position to judge the Xtensa arch code as
being worthy of an upgrade. If both of us are sure that the merged environment is
a significant improvement over the current code with no know downside, then it
seems reasonable to me to Christian should give it his blessing. I thought we'd
post notice of the change the Xtensa kernel mailing list to solicit feedback.
I'd also really like to get into the 2.6.30-next pipe. I have a one line fix
for the common kernel code and maybe I shouldn't include it. There a race condition
in the scheduler with a division by zero. Like:
if (p->n != 0)
a = b / p->n
changed to
divisor = p->n
if (divisor != 0)
a = b / divisor
Race is that p->n changes after the test but before the division. It likely only
occurs when the kernel isn't compiled with optimization.
A few more very small Xtensa changes to common code; should effect other arch.
I'm very likely am using more cache and TLB flushes than are needed for the SMP
cache alias problem but they were difficult to pull out until the system is rock solid;
seem to be ready for that removal but I'd like to get some testing on what we have now.
I thought we'd include Xtensa macros in a new Documentation/Xtensa, like the attached
ps.gdb macro and macros for dumping the TLB's and Caches.
Sound ok to you?
-piet
>
>>> -piet
>
> Hannes
>
-------------- next part --------------
#
# This file contains macros for walking through the list of task
# and performing various operations:
#
# 'ps' - Printing a 'ps' like brief stmmary of the task
# 'btt' - Printing a backtrace for all task (Similar to Kdump btt macro)
# 'btpid' - Print the backtrace for a partifular task
# 'btn' - Print the backtrace for the next task
# 'btp' - Print the backtrace for the previous task
# 'switch' - Switching to the stack environment for a particular task
# 'resume' - Switching back (resume) to the origianl task
# 'save_state' - Save current (Linux) State; done automatically when $ccount changes.
# 'check_state' - Compare current state to Saved (Linux) State; do before doing a 'continue'.
# 'print_state' - Print the current state
# 'print_saved_state' - Print the current saved (Linux) state
#
#
# It's designed to even run with xt-gdb being driven with ddd and being able to
# easily walk up and down the stack and displaying local and formal parameters.
# We reciently got to almost a week stability and a task seems to be holding a
# resource that the other task are waiting on. Needed to be able to see the stacks
# of all task prior to KGDB working.
#
# Credits:
# Piet Delaney <piet at tensilica.com>
# Marc Gauthier <marc at tensilica.com>
#
#
# Global gdb Variables:
# $_target_pid - looking only for this pid
# $_print_ps - print ps info while looking at tasks
# $_print_bt - print a backtrace while looking at task
# $_verbose - debug verbosity:
# 0: 0ff
# 1: Function Entrys and Exits
# 2: Details of Register Being changed
#
# $_saved_* 0 - Saved registers of current Linux task that gdb stopped in
# $bt_saved_* - Saved registers at entry to loop looking at task list
# $current - Current task we are giving backtrace for.
#
#
# While switching to another stack you have to be rather carefull
# with maintaining stack consistancy. gdb is rather unforgiving
# and doesn't allow 'set backtrace limit' to examine 0 frames.
# We get around this by switching to the non-windowed ABI while
# changing the state; see disable_bt(). For the task that are not
# running we use the windowed ABI to do the back-trace.
#
# The current running process is special, we can display the stack
# but it didn't go through switch, so we can't change the window
# parameters. For this context we restore the Saved Linux state.
#
# NOTE:
# $ptevadder is getting whacked by OCD but can't be preserved here.
#
set var $_saved_ccount = 0
set pagination off
define version
printf "Thu Mar 19 11:45pm\n"
end
define switch
set var $_target_pid = $arg0
set var $_print_ps = 0
set var $_print_bt = 1
set var $_verbose = 0
for_each_task
if ($current != 0)
save_state
switch_state $current
end
end
document switch
Switch backtrace context to 'pid'
end
define btt
save_state
set var $_target_pid = -1
set var $_print_ps = 1
set var $_print_bt = 1
set var $_verbose = 0
for_each_task
end
document btt
Backtrace all task
end
define btpid
save_state
set var $_target_pid = $arg0
set var $_print_ps = 0
set var $_print_bt = 1
set var $_verbose = 0
for_each_task
end
document btpid
Backtrace a particular 'pid'
end
define btn
set var $_target_pid = $next_tsk->pid
set var $_print_ps = 0
set var $_print_bt = 1
set var $_verbose = 0
for_each_task
if ($current != 0)
save_state
switch_state $current
end
end
document btn
Backtrace next task
end
define btp
set var $_target_pid = $prev_tsk->pid
set var $_print_ps = 0
set var $_print_bt = 1
set var $_verbose = 0
for_each_task
if ($current != 0)
state_state
switch_state $current
end
end
document btp
Backtrace previous task
end
define ps
save_state
set var $_target_pid = -1
set var $_print_ps = 1
set var $_print_bt = 0
set var $_verbose = 0
for_each_task
end
document ps
Show the process/task state
end
define resume
set var $_verbose = 0
restore_state
end
document resume
Restore current context back from Switch
end
define save_state
if ($_saved_ccount != $ccount)
printf "save_state: _saved_ccount:0x%x != $ccount:0x%x; Saving Current Linux State\n", $_saved_ccount, $ccount
set var $_saved_pc = $pc
set var $_saved_pc = $pc
set var $_saved_a0 = $a0
set var $_saved_a1 = $a1
set var $_saved_sp = $sp
set var $_saved_wb = $windowbase
set var $_saved_ws = $windowstart
set var $_saved_ps = $ps
set var $_saved_ccount = $ccount
set var $_saved_ptevaddr = $ptevaddr
set var $_saved_state_valid = 1
print_saved_state
end
end
document save_state
Internal Function to save the state prior to a switch to another task stack.
end
define print_state
printf " $pc: 0x%x\n", $pc
printf " $a0: 0x%x\n", $a0
printf " $a1: 0x%x\n", $a1
printf " $sp: 0x%x\n", $sp
printf " $windowbase: 0x%x\n", $windowbase
printf " $windowstart: 0x%x\n", $windowstart
printf " $ps: 0x%x\n", $ps
printf " $ccount: 0x%x\n", $ccount
printf " $ptevaddr: 0x%x\n", $ptevaddr
printf "\n"
end
document print_state
Print current state
end
define print_saved_state
if $_saved_state_valid
printf " $_saved_pc: 0x%x\n", $_saved_pc
printf " $_saved_a0: 0x%x\n", $_saved_a0
printf " $_saved_a1: 0x%x\n", $_saved_a1
printf " $_saved_sp: 0x%x\n", $_saved_sp
printf " $_saved_wb: 0x%x\n", $_saved_wb
printf " $_saved_ws: 0x%x\n", $_saved_ws
printf " $_saved_ps: 0x%x\n", $_saved_ps
printf " $_saved_ccount: 0x%x\n", $_saved_ccount
printf " $_saved_ptevaddr: 0x%x\n", $_saved_ptevaddr
printf "\n"
else
printf "State Not Saved Yet\n"
end
end
document print_saved_state
Usefull for debugging this script
end
define check_state
if $_saved_state_valid
if $_saved_pc != $pc
printf " $_saved_pc:0x%x != $pc:0x%x\n", $_saved_pc, $pc
end
if $_saved_a0 != $a0
printf " $_saved_a0:0x%x != $a0:0x%x\n", $_saved_a0, $a0
end
if $_saved_a1 != $a1
printf " $_saved_a1:0x%x != $a1:0x%x\n", $_saved_a1, $a1
end
if $_saved_sp != $sp
printf " $_saved_sp:0x%x != $sp:0x%x\n", $_saved_sp, $sp
end
if $_saved_wb != $windowbase
printf " $_saved_wb:0x%x != $windowbase:0x%x\n", $_saved_wb, $windowbase
end
if $_saved_ws != $windowstart
printf " $_saved_ws:0x%x != $windowstart:0x%x\n", $_saved_ws, $windowstart
end
if $_saved_ps != $ps
printf " $_saved_sp:0x%x != $sp:0x%x\n", $_saved_sp, $sp
end
if $_saved_ccount != $ccount
printf " $_saved_ccount:0x%x != $ccount:0x%x\n", $_saved_ccount, $ccount
end
if $_saved_ps != $ps
printf " $_saved_ptevaad:0x%x != $ptevaad:0x%x\n", $_saved_ptevaad, $ptevaad
end
printf "\n"
else
printf "State Not Saved Yet\n"
end
end
document check_state
Compares current state to saved state
end
define restore_state
if $_verbose
printf "restore_state {\n"
end
frame 0
disable_bt
set $restore_state_psexcm = $psexcm
set $psexcm = 1
set $pc = $_saved_pc
set $a0 = $_saved_a0
set $a1 = $_saved_a1
set $ptevaddr = $_saved_ptevaddr
set $windowbase = $_saved_wb
set $windowstart = $_saved_ws
set $psexcm = $restore_state_psexcm
enable_bt
set $ps = $_saved_ps
if ( $sp != $_saved_sp )
printf "restore_state: ERROR - $sp:0x%x != $_saved_sp:0x%x\n", $sp, $_saved_sp
end
if $_verbose
printf "restore_state }\n"
end
end
document restore_state
Internal Function to restore state after a switch to another task stack.
end
define disable_bt
if $_verbose
printf " disable_bt {\n"
printf " $ps:0x%x, $psexcm:0x%x, $pswoe:0x%x\n", $ps, $psexcm, $pswoe
end
set backtrace limit 1
set var $saved_psexcm = $psexcm
set var $saved_pswoe = $pswoe
if ($saved_psexcm == 0)
if $_verbose > 1
printf " set $psexcm = 1\n"
end
set $psexcm = 1
end
if ($saved_pswoe == 1)
if $_verbose > 1
printf " set $pswoe = 0\n"
end
set $pswoe = 0
end
if $_verbose
printf " disable_bt }\n"
end
end
document disable_bt
Internal Function to disable gdb from trying to do a backtrace while we are changing the stack
end
define enable_bt
if $_verbose
printf " enable_bt {\n"
end
if ( $saved_psexcm != $psexcm )
if $_verbose > 1
printf " set $psexcm = $saved_psexcm:%x\n", $saved_psexcm,
end
set $psexcm = $saved_psexcm
end
if ( $saved_pswoe != $pswoe )
if $_verbose > 1
printf " set $pswoe = $saved_pswoe:0x%x\n", $saved_pswoe
end
set $pswoe = $saved_pswoe
end
set backtrace limit 0
if $_verbose
printf " enable_bt }\n"
end
end
document enable_bt
Internal Function to disable gdb from trying to do a backtrace while we are changing the stack
end
#
# NOTE:
# From include/asm-xtensa/thread_info.h /* Used in switch_state() macro below ... */
# #define TIF_CURRENTLY_RUNNING 17 /* ... True if thread is currently running on ...*/
# /* ... it's CPU; Added for supporting this gdb macro */
#
# Returns via globals:
# $switchable
# $running
# $cpu
#
define switch_state
set var $new_tsk = $arg0
set var $ti = (struct thread_info *) $new_tsk->stack
set var $thread = (struct thread_struct *) &$new_tsk.thread
set var $cpu = $ti->cpu
set var $flags = $ti->flags
set var $status = $ti->status
set var $running = $flags & (1 << 17)
set var $switchable = (($running == 0) || ($cpu == $prid))
if $_verbose
printf "switch_state($new_tsk:%x) { switchable:%d", $new_tsk, $switchable
printf " $windowbase:%x, $windowstart:%x, $a0:%x, $sp:%x, $ps:%x\n", $windowbase, $windowstart, $a0, $sp, $ps
end
if ($switchable)
disable_bt
if $_verbose > 1
printf " set $windowstart = (1 << $windowbase:%d):0x%x\n", $windowbase, (1 << $windowbase)
end
set $windowstart = (1 << $windowbase)
if $_verbose > 1
printf " set $a0 = $thread->ra:0x%x\n", $thread->ra
end
set $a0 = $thread->ra
if $_verbose > 1
printf " set $sp = $thread->sp:0x%x\n", $thread->sp
end
set $sp = $thread->sp
if ($running == 0)
if ($_verbose > 1)
printf " set $pc = &switch_to:0x%x + 3\n", &_switch_to
end
set $pc = (&_switch_to + 3)
end
enable_bt
end
# flush
# flushregs
if $_verbose
printf "switch_state }\n"
end
end
document switch_state
Internal Function to switch stack to task for 'pid'.
end
define save_bt_state
if $_verbose
printf " save_bt_state: {\n"
printf " $a1:0x%x, $ps:0x%x, $ptevadder:0x%x, $sp:0x%x, $a0:0x%x, $windowbase:0x%x, $windowstart:0x%x\n", $a1, $ps, $ptevaddr, $sp, $a0, $windowbase, $windowstart
end
frame 0
set var $bt_saved_pc = $pc
set var $bt_saved_ps = $ps
set var $bt_saved_ptevaddr = $ptevaddr
set var $bt_saved_sp = $sp
set var $bt_saved_a0 = $a0
set var $bt_saved_wb = $windowbase
set var $bt_saved_ws = $windowstart
if $_verbose
printf " save_bt_state: }\n"
end
end
document save_bt_state
Internal Function to save stack context while walking thru task list.
end
define restore_bt_state
if $_verbose
printf " restore_bt_state {\n"
end
# flush
frame 0
disable_bt
set $ptevaddr = $bt_saved_ptevaddr
set $pc = $bt_saved_pc
set $a0 = $bt_saved_a0
set $sp = $bt_saved_sp
set $windowbase = $bt_saved_wb
set $windowstart = $bt_saved_ws
enable_bt
set $ps = $bt_saved_ps
if $_verbose
printf " restore_bt_state }\n"
end
end
document restore_bt_state
Internal Function to restore stack context while walking thru task list.
end
#
# This function starts with init_task (swapper), walks through task list,
# and does conditional things like printing 'ps' or 'bt' info.
#
define for_each_task
# printf "$argc: %d, $btiarg0: %d\n", $argc, $arg0
# set var $pid = $arg0
if $_verbose
printf "for_each_task {\n"
end
set $offset = (char *) &init_task->tasks - (char *) &init_task
set $initthread = &init_task
set $tsk = &init_task
set $prev_tsk = (struct task_struct *) 0
set $next_tsk = (struct task_struct *) 0
set $tsk_count = 0
set $done = 0
save_bt_state
while ($done == 0)
set var $ti = (struct thread_info *) $tsk->stack
set var $thread = (struct thread_struct *) &$tsk.thread
set var $cpu = $ti->cpu
set var $flags = $ti->flags
set var $status = $ti->status
set var $running = (($flags & (1 << 17)) != 0)
set $printed_bt = 0
set $tsk_count++
set $mm = $tsk->mm
set $active_mm = $tsk->active_mm
if $mm != 0
set $total_vm = $mm->total_vm
# set $cpu = $mm->context.cpu
set $asid = $mm->context.asid[$cpu]
else
set $total_vm = -1
set $asid = -1
# set $cpu = -1
end
if $_verbose
printf "$thread:%x, $ti:0x%x->{cpu:%d, flags:0x%x, status:0x%x}, $running:0x%x\n", $thread, $ti, $cpu, $flags, $status, $running
end
if (($_print_ps != 0) || ($_target_pid == $tsk->pid))
if $mm
printf "tsk:%p->{pid:%5d, cpus_allowed:%x, state:%2d, running:%d, mm:0x%08x->{asid[%2d]:0x%08x, total_vm:%5d}, \tcomm:'%s'}\n", $tsk, $tsk->pid, (int)$tsk->cpus_allowed, $tsk->state, $running, $mm, $cpu, $asid, $total_vm, (char*)$tsk->comm
else
printf "tsk:%p->{pid:%5d, cpus_allowed:%x, state:%2d, running:%d, mm:0x%08x, \tcomm:'%s'}\n", $tsk, $tsk->pid, (int)$tsk->cpus_allowed, $tsk->state, $running, $mm, (char*)$tsk->comm
end
end
if $_print_bt
if ($_target_pid < 0 || ($_target_pid == $tsk->pid))
# REMIND-FIXME: Need to Back-Trace Swapper also.
printf "-------------------------------------------------------------------------------------------------------------------------------------------------\n"
if (!$running)
switch_state($tsk)
#
# Switch to call4 ABI for kernel backtraces
#
set $saved_ps = $ps
set $psexcm = 0
set $pswoe = 1
bt
if ($_target_pid == $tsk->pid)
save_bt_state
end
set $ps = $saved_ps
else
if ($cpu == $prid)
#
# This is the current task actually running
# go back to it's original state but don't
# we continuie to mark it as valid.
#
restore_state
set var $_saved_state_valid = 1
bt
else
printf " CURRENTLY RUNNING ON ANOTHER CPU $cpu:%d != $prid:%d)\n", $cpu, $prid
end
end
set $printed_bt = 1
printf "-------------------------------------------------------------------------------------------------------------------------------------------------\n"
if ($_target_pid == $tsk->pid)
set var $current = $tsk
set var $done = 1
end
end
end
if ($tsk->state == 0)
set $current_running = $tsk
end
if ($done == 0)
set $prev_tsk = $tsk
set $next_tsk_ptr = $tsk->tasks.next
set $tsk = (struct task_struct *)((char*)$prev_tsk->tasks.next - $offset)
set $next_tsk = (struct task_struct *)((char*)$tsk->tasks.next - $offset)
if $_verbose
printf "$tsk:%x = prev_tsk:%x->tasks.next:%x - $offset:%x)\n\n\n", $tsk, $prev_tsk, $next_tsk_ptr, $offset
end
end
if ($next_tsk == $initthread)
set var $done = 1
end
if $printed_bt
printf "\n\n"
end
end
restore_bt_state
if $_verbose
printf "for_each_task }\n"
end
end
document for_each_task
Internal Function to walk through task list and perform conditional actions (Ex: back-trace).
end
More information about the linux-xtensa
mailing list