[PATCH 2/2] powerpc: Dynamically allocate most lppaca structs
This arranges for the lppaca structs for most cpus to be dynamically allocated in the same manner as the paca structs. If we don't include support for legacy iSeries, only the first lppaca is statically allocated; the rest are dynamically allocated. If we include legacy iSeries support, then we statically allocate the first 64 lppaca structs, since the iSeries hypervisor requires that the lppaca structs be present in the data section of the kernel image, but legacy iSeries supports at most 64 cpus. With CONFIG_NR_CPUS, the kernel image size for a typical pSeries config went from: textdata bss dec hex filename 9524478 4734564 8469944 2272898615ad11a ../test-1024/vmlinux to: textdata bss dec hex filename 9524482 3751508 8469944 2174593414bd10e ../test-1024/vmlinux a reduction of 983052 bytes overall. Signed-off-by: Paul Mackerras pau...@samba.org --- arch/powerpc/include/asm/lppaca.h |2 +- arch/powerpc/kernel/paca.c| 70 +++- 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h index 6b73554..6d02624 100644 --- a/arch/powerpc/include/asm/lppaca.h +++ b/arch/powerpc/include/asm/lppaca.h @@ -153,7 +153,7 @@ struct lppaca { extern struct lppaca lppaca[]; -#define lppaca_of(cpu) (lppaca[cpu]) +#define lppaca_of(cpu) (*paca[cpu].lppaca_ptr) /* * SLB shadow buffer structure as defined in the PAPR. The save_area diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index d0a26f1..1e068a4 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c @@ -27,6 +27,20 @@ extern unsigned long __toc_start; #ifdef CONFIG_PPC_BOOK3S /* + * We only have to have statically allocated lppaca structs on + * legacy iSeries, which supports at most 64 cpus. + */ +#ifdef CONFIG_PPC_ISERIES +#if NR_CPUS 64 +#define NR_LPPACAS NR_CPUS +#else +#define NR_LPPACAS 64 +#endif +#else /* not iSeries */ +#define NR_LPPACAS 1 +#endif + +/* * The structure which the hypervisor knows about - this structure * should not cross a page boundary. The vpa_init/register_vpa call * is now known to fail if the lppaca structure crosses a page @@ -36,7 +50,7 @@ extern unsigned long __toc_start; * will suffice to ensure that it doesn't cross a page boundary. */ struct lppaca lppaca[] = { - [0 ... (NR_CPUS-1)] = { + [0 ... (NR_LPPACAS-1)] = { .desc = 0xd397d781, /* LpPa */ .size = sizeof(struct lppaca), .dyn_proc_status = 2, @@ -49,6 +63,54 @@ struct lppaca lppaca[] = { }, }; +static struct lppaca *extra_lppacas; +static long __initdata lppaca_size; + +static void allocate_lppacas(int nr_cpus, unsigned long limit) +{ + if (nr_cpus = NR_LPPACAS) + return; + + lppaca_size = PAGE_ALIGN(sizeof(struct lppaca) * +(nr_cpus - NR_LPPACAS)); + extra_lppacas = __va(memblock_alloc_base(lppaca_size, +PAGE_SIZE, limit)); +} + +static struct lppaca *new_lppaca(int cpu) +{ + struct lppaca *lp; + + if (cpu NR_LPPACAS) + return lppaca[cpu]; + + lp = extra_lppacas + (cpu - NR_LPPACAS); + *lp = lppaca[0]; + + return lp; +} + +static void free_lppacas(void) +{ + long new_size = 0, nr; + + if (!lppaca_size) + return; + nr = num_possible_cpus() - NR_LPPACAS; + if (nr 0) + new_size = PAGE_ALIGN(nr * sizeof(struct lppaca)); + if (new_size = lppaca_size) + return; + + memblock_free(__pa(extra_lppacas) + new_size, lppaca_size - new_size); + lppaca_size = new_size; +} + +#else + +static inline void allocate_lppacas(int, unsigned long) { } +static inline void free_lppacas(void) { } + #endif /* CONFIG_PPC_BOOK3S */ #ifdef CONFIG_PPC_STD_MMU_64 @@ -88,7 +150,7 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu) unsigned long kernel_toc = (unsigned long)(__toc_start) + 0x8000UL; #ifdef CONFIG_PPC_BOOK3S - new_paca-lppaca_ptr = lppaca[cpu]; + new_paca-lppaca_ptr = new_lppaca(cpu); #else new_paca-kernel_pgd = swapper_pg_dir; #endif @@ -144,6 +206,8 @@ void __init allocate_pacas(void) printk(KERN_DEBUG Allocated %u bytes for %d pacas at %p\n, paca_size, nr_cpus, paca); + allocate_lppacas(nr_cpus, limit); + /* Can't use for_each_*_cpu, as they aren't functional yet */ for (cpu = 0; cpu nr_cpus; cpu++) initialise_paca(paca[cpu], cpu); @@ -164,4 +228,6 @@ void __init free_unused_pacas(void) paca_size - new_size); paca_size = new_size; + + free_lppacas(); } -- 1.7.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org
[PATCH 1/2] powerpc: Abstract indexing of lppaca structs
Currently we have the lppaca structs as a simple array of NR_CPUS entries, taking up space in the data section of the kernel image. In future we would like to allocate them dynamically, so this abstracts out the accesses to the array, making it easier to change how we locate the lppaca for a given cpu in future. Specifically, lppaca[cpu] changes to lppaca_of(cpu). Signed-off-by: Paul Mackerras pau...@samba.org --- arch/powerpc/include/asm/lppaca.h |2 ++ arch/powerpc/kernel/lparcfg.c | 14 +++--- arch/powerpc/lib/locks.c |4 ++-- arch/powerpc/platforms/iseries/dt.c |4 ++-- arch/powerpc/platforms/iseries/smp.c |2 +- arch/powerpc/platforms/pseries/dtl.c |8 arch/powerpc/platforms/pseries/lpar.c |4 ++-- 7 files changed, 20 insertions(+), 18 deletions(-) diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h index 14b592d..6b73554 100644 --- a/arch/powerpc/include/asm/lppaca.h +++ b/arch/powerpc/include/asm/lppaca.h @@ -153,6 +153,8 @@ struct lppaca { extern struct lppaca lppaca[]; +#define lppaca_of(cpu) (lppaca[cpu]) + /* * SLB shadow buffer structure as defined in the PAPR. The save_area * contains adjacent ESID and VSID pairs for each shadowed SLB. The diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index 50362b6..8d9e3b9 100644 --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c @@ -56,7 +56,7 @@ static unsigned long get_purr(void) for_each_possible_cpu(cpu) { if (firmware_has_feature(FW_FEATURE_ISERIES)) - sum_purr += lppaca[cpu].emulated_time_base; + sum_purr += lppaca_of(cpu).emulated_time_base; else { struct cpu_usage *cu; @@ -263,7 +263,7 @@ static void parse_ppp_data(struct seq_file *m) ppp_data.active_system_procs); /* pool related entries are apropriate for shared configs */ - if (lppaca[0].shared_proc) { + if (lppaca_of(0).shared_proc) { unsigned long pool_idle_time, pool_procs; seq_printf(m, pool=%d\n, ppp_data.pool_num); @@ -460,8 +460,8 @@ static void pseries_cmo_data(struct seq_file *m) return; for_each_possible_cpu(cpu) { - cmo_faults += lppaca[cpu].cmo_faults; - cmo_fault_time += lppaca[cpu].cmo_fault_time; + cmo_faults += lppaca_of(cpu).cmo_faults; + cmo_fault_time += lppaca_of(cpu).cmo_fault_time; } seq_printf(m, cmo_faults=%lu\n, cmo_faults); @@ -479,8 +479,8 @@ static void splpar_dispatch_data(struct seq_file *m) unsigned long dispatch_dispersions = 0; for_each_possible_cpu(cpu) { - dispatches += lppaca[cpu].yield_count; - dispatch_dispersions += lppaca[cpu].dispersion_count; + dispatches += lppaca_of(cpu).yield_count; + dispatch_dispersions += lppaca_of(cpu).dispersion_count; } seq_printf(m, dispatches=%lu\n, dispatches); @@ -545,7 +545,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v) seq_printf(m, partition_potential_processors=%d\n, partition_potential_processors); - seq_printf(m, shared_processor_mode=%d\n, lppaca[0].shared_proc); + seq_printf(m, shared_processor_mode=%d\n, lppaca_of(0).shared_proc); seq_printf(m, slb_size=%d\n, mmu_slb_size); diff --git a/arch/powerpc/lib/locks.c b/arch/powerpc/lib/locks.c index 58e14fb..9b8182e 100644 --- a/arch/powerpc/lib/locks.c +++ b/arch/powerpc/lib/locks.c @@ -34,7 +34,7 @@ void __spin_yield(arch_spinlock_t *lock) return; holder_cpu = lock_value 0x; BUG_ON(holder_cpu = NR_CPUS); - yield_count = lppaca[holder_cpu].yield_count; + yield_count = lppaca_of(holder_cpu).yield_count; if ((yield_count 1) == 0) return; /* virtual cpu is currently running */ rmb(); @@ -65,7 +65,7 @@ void __rw_yield(arch_rwlock_t *rw) return; /* no write lock at present */ holder_cpu = lock_value 0x; BUG_ON(holder_cpu = NR_CPUS); - yield_count = lppaca[holder_cpu].yield_count; + yield_count = lppaca_of(holder_cpu).yield_count; if ((yield_count 1) == 0) return; /* virtual cpu is currently running */ rmb(); diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c index 7f45a51..fdb7384 100644 --- a/arch/powerpc/platforms/iseries/dt.c +++ b/arch/powerpc/platforms/iseries/dt.c @@ -243,7 +243,7 @@ static void __init dt_cpus(struct iseries_flat_dt *dt) pft_size[1] = __ilog2(HvCallHpt_getHptPages() * HW_PAGE_SIZE); for (i = 0; i NR_CPUS; i++) { - if (lppaca[i].dyn_proc_status = 2) + if
Re: 2.6.35-stable/ppc64/p7: suspicious rcu_dereference_check() usage detected during 2.6.35-stable boot
Hi Paul, Is there any specific person(s) whom we whom we should direct this mail to ? We have not received any response from CGROUP developers on this. Kindly let me know whom to contact for this. I am adding few more people i know :-) Regards-- Subrata On Mon, 2010-08-09 at 09:12 -0700, Paul E. McKenney wrote: On Mon, Aug 02, 2010 at 02:22:12PM +0530, Subrata Modak wrote: Hi, The following suspicious rcu_dereference_check() usage is detected during 2.6.35-stable boot on my ppc64/p7 machine: == [ INFO: suspicious rcu_dereference_check() usage. ] --- kernel/sched.c:616 invoked rcu_dereference_check() without protection! other info that might help us debug this: rcu_scheduler_active = 1, debug_locks = 0 1 lock held by swapper/1: #0: (rq-lock){-.}, at: [c07ca2f8] .init_idle+0x78/0x4a8 stack backtrace: Call Trace: [c00f392bf990] [c0014f04] .show_stack+0xb0/0x1a0 (unreliable) [c00f392bfa50] [c07c87b4] .dump_stack+0x28/0x3c [c00f392bfad0] [c0103e1c] .lockdep_rcu_dereference+0xbc/0xe4 [c00f392bfb70] [c07ca434] .init_idle+0x1b4/0x4a8 [c00f392bfc30] [c07cad04] .fork_idle+0xa4/0xd0 [c00f392bfe30] [c0aefaac] .smp_prepare_cpus+0x23c/0x2f4 [c00f392bfed0] [c0ae1424] .kernel_init+0xec/0x32c [c00f392bff90] [c0033f40] .kernel_thread+0x54/0x70 == Please note that this was reported earlier on 2.6.34-rc6: http://marc.info/?l=linux-kernelm=127313031922395w=2, The issue was fixed with: commit 1ce7e4ff24fe338438bc7837e02780f202bf202b Author: Li Zefan l...@cn.fujitsu.com Date: Fri Apr 23 10:35:52 2010 +0800 cgroup: Check task_lock in task_subsys_state() According to: http://lkml.org/lkml/2010/7/1/883, commit dc61b1d65e353d638b2445f71fb8e5b5630f2415 Author: Peter Zijlstra a.p.zijls...@chello.nl Date: Tue Jun 8 11:40:42 2010 +0200 sched: Fix PROVE_RCU vs cpu_cgroup should have fixed this. But this is reproducible on 2.6.35-stable. Please also see the config file attached. Hello, Subrata, Thank you for locating this one! This looks like the same issue that Ilia Mirkin located. Please see below for my analysis -- no fix yet, as I need confirmation from cgroups experts. I can easily create a patch that suppresses the warning, but I don't yet know whether this is the right thing to do. Thanx, Paul On Thu, Aug 05, 2010 at 01:31:10PM -0400, Ilia Mirkin wrote: On Thu, Jul 1, 2010 at 6:18 PM, Paul E. McKenney paul...@linux.vnet.ibm.com wrote: On Thu, Jul 01, 2010 at 08:21:43AM -0400, Miles Lane wrote: [ INFO: suspicious rcu_dereference_check() usage. ] --- kernel/sched.c:616 invoked rcu_dereference_check() without protection! other info that might help us debug this: rcu_scheduler_active = 1, debug_locks = 1 3 locks held by swapper/1: #0: (cpu_add_remove_lock){+.+.+.}, at: [81042914] cpu_maps_update_begin+0x12/0x14 #1: (cpu_hotplug.lock){+.+.+.}, at: [8104294f] cpu_hotplug_begin+0x27/0x4e #2: (rq-lock){-.-...}, at: [812f8502] init_idle+0x2b/0x114 Hello, Miles! I believe that this one is fixed by commit dc61b1d6 in -tip. Hi Paul, Looks like that commit made it into 2.6.35: git tag -l --contains dc61b1d65e353d638b2445f71fb8e5b5630f2415 v2.6.35* v2.6.35 v2.6.35-rc4 v2.6.35-rc5 v2.6.35-rc6 However I still get: [0.051203] CPU0: AMD QEMU Virtual CPU version 0.12.4 stepping 03 [0.052999] lockdep: fixing up alternatives. [0.054105] [0.054106] === [0.054999] [ INFO: suspicious rcu_dereference_check() usage. ] [0.054999] --- [0.054999] kernel/sched.c:616 invoked rcu_dereference_check() without protection ! [0.054999] [0.054999] other info that might help us debug this: [0.054999] [0.054999] [0.054999] rcu_scheduler_active = 1, debug_locks = 1 [0.054999] 3 locks held by swapper/1: [0.054999] #0: (cpu_add_remove_lock){+.+.+.}, at: [814be933] cpu_up+ 0x42/0x6a [0.054999] #1: (cpu_hotplug.lock){+.+.+.}, at: [810400d8] cpu_hotplu g_begin+0x2a/0x51 [0.054999] #2: (rq-lock){-.-...}, at: [814be2f7] init_idle+0x2f/0x 113 [0.054999] [0.054999] stack backtrace: [0.054999] Pid: 1, comm: swapper Not tainted 2.6.35 #1 [0.054999] Call Trace: [0.054999] [81068054] lockdep_rcu_dereference+0x9b/0xa3
[PATCH] powerpc: Initialise paca-kstack before early_setup_secondary
As early setup calls down to slb_initialize(), we must have kstack initialised before checking should we add a bolted SLB entry for our kstack? Failing to do so means stack access requires an SLB miss exception to refill an entry dynamically, if the stack isn't accessible via SLB(0) (kernel text static data). It's not always allowable to take such a miss, and intermittent crashes will result. Primary CPUs don't have this issue; an SLB entry is not bolted for their stack anyway (as that lives within SLB(0)). This patch therefore only affects the init of secondaries. Signed-off-by: Matt Evans m...@ozlabs.org Cc: stable sta...@kernel.org --- arch/powerpc/kernel/head_64.S |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 844a44b..4d6681d 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -572,9 +572,6 @@ __secondary_start: /* Set thread priority to MEDIUM */ HMT_MEDIUM - /* Do early setup for that CPU (stab, slb, hash table pointer) */ - bl .early_setup_secondary - /* Initialize the kernel stack. Just a repeat for iSeries. */ LOAD_REG_ADDR(r3, current_set) sldir28,r24,3 /* get current_set[cpu#] */ @@ -582,6 +579,9 @@ __secondary_start: addir1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD std r1,PACAKSAVE(r13) + /* Do early setup for that CPU (stab, slb, hash table pointer) */ + bl .early_setup_secondary + /* Clear backchain so we get nice backtraces */ li r7,0 mtlrr7 -- 1.7.0.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: 2.6.35-stable/ppc64/p7: suspicious rcu_dereference_check() usage detected during 2.6.35-stable boot
On Fri, Aug 13, 2010 at 8:55 AM, Subrata Modak subr...@linux.vnet.ibm.com wrote: Hi Paul, Is there any specific person(s) whom we whom we should direct this mail to ? We have not received any response from CGROUP developers on this. Kindly let me know whom to contact for this. I am adding few more people i know :-) It would help if you would add in the cgroup maintainers and the containers mailing list to the cc as well. Regards-- Subrata On Mon, 2010-08-09 at 09:12 -0700, Paul E. McKenney wrote: On Mon, Aug 02, 2010 at 02:22:12PM +0530, Subrata Modak wrote: Hi, The following suspicious rcu_dereference_check() usage is detected during 2.6.35-stable boot on my ppc64/p7 machine: == [ INFO: suspicious rcu_dereference_check() usage. ] --- kernel/sched.c:616 invoked rcu_dereference_check() without protection! other info that might help us debug this: rcu_scheduler_active = 1, debug_locks = 0 1 lock held by swapper/1: #0: (rq-lock){-.}, at: [c07ca2f8] .init_idle+0x78/0x4a8 stack backtrace: Call Trace: [c00f392bf990] [c0014f04] .show_stack+0xb0/0x1a0 (unreliable) [c00f392bfa50] [c07c87b4] .dump_stack+0x28/0x3c [c00f392bfad0] [c0103e1c] .lockdep_rcu_dereference+0xbc/0xe4 [c00f392bfb70] [c07ca434] .init_idle+0x1b4/0x4a8 [c00f392bfc30] [c07cad04] .fork_idle+0xa4/0xd0 [c00f392bfe30] [c0aefaac] .smp_prepare_cpus+0x23c/0x2f4 [c00f392bfed0] [c0ae1424] .kernel_init+0xec/0x32c [c00f392bff90] [c0033f40] .kernel_thread+0x54/0x70 == Please note that this was reported earlier on 2.6.34-rc6: http://marc.info/?l=linux-kernelm=127313031922395w=2, The issue was fixed with: commit 1ce7e4ff24fe338438bc7837e02780f202bf202b Author: Li Zefan l...@cn.fujitsu.com Date: Fri Apr 23 10:35:52 2010 +0800 cgroup: Check task_lock in task_subsys_state() According to: http://lkml.org/lkml/2010/7/1/883, commit dc61b1d65e353d638b2445f71fb8e5b5630f2415 Author: Peter Zijlstra a.p.zijls...@chello.nl Date: Tue Jun 8 11:40:42 2010 +0200 sched: Fix PROVE_RCU vs cpu_cgroup should have fixed this. But this is reproducible on 2.6.35-stable. Please also see the config file attached. Hello, Subrata, Thank you for locating this one! This looks like the same issue that Ilia Mirkin located. Please see below for my analysis -- no fix yet, as I need confirmation from cgroups experts. I can easily create a patch that suppresses the warning, but I don't yet know whether this is the right thing to do. Thanx, Paul On Thu, Aug 05, 2010 at 01:31:10PM -0400, Ilia Mirkin wrote: On Thu, Jul 1, 2010 at 6:18 PM, Paul E. McKenney paul...@linux.vnet.ibm.com wrote: On Thu, Jul 01, 2010 at 08:21:43AM -0400, Miles Lane wrote: [ INFO: suspicious rcu_dereference_check() usage. ] --- kernel/sched.c:616 invoked rcu_dereference_check() without protection! other info that might help us debug this: rcu_scheduler_active = 1, debug_locks = 1 3 locks held by swapper/1: #0: (cpu_add_remove_lock){+.+.+.}, at: [81042914] cpu_maps_update_begin+0x12/0x14 #1: (cpu_hotplug.lock){+.+.+.}, at: [8104294f] cpu_hotplug_begin+0x27/0x4e #2: (rq-lock){-.-...}, at: [812f8502] init_idle+0x2b/0x114 Hello, Miles! I believe that this one is fixed by commit dc61b1d6 in -tip. Hi Paul, Looks like that commit made it into 2.6.35: git tag -l --contains dc61b1d65e353d638b2445f71fb8e5b5630f2415 v2.6.35* v2.6.35 v2.6.35-rc4 v2.6.35-rc5 v2.6.35-rc6 However I still get: [ 0.051203] CPU0: AMD QEMU Virtual CPU version 0.12.4 stepping 03 [ 0.052999] lockdep: fixing up alternatives. [ 0.054105] [ 0.054106] === [ 0.054999] [ INFO: suspicious rcu_dereference_check() usage. ] [ 0.054999] --- [ 0.054999] kernel/sched.c:616 invoked rcu_dereference_check() without protection ! [ 0.054999] [ 0.054999] other info that might help us debug this: [ 0.054999] [ 0.054999] [ 0.054999] rcu_scheduler_active = 1, debug_locks = 1 [ 0.054999] 3 locks held by swapper/1: [ 0.054999] #0: (cpu_add_remove_lock){+.+.+.}, at: [814be933] cpu_up+ 0x42/0x6a [ 0.054999] #1: (cpu_hotplug.lock){+.+.+.}, at: [810400d8] cpu_hotplu g_begin+0x2a/0x51 [ 0.054999] #2: (rq-lock){-.-...}, at: [814be2f7] init_idle+0x2f/0x 113 [ 0.054999] [
Re: 2.6.35-stable/ppc64/p7: suspicious rcu_dereference_check() usage detected during 2.6.35-stable boot
Adding CONTROL GROUP Maintainers/Mailing list.. Regards-- Subrata On Mon, 2010-08-09 at 09:12 -0700, Paul E. McKenney wrote: On Mon, Aug 02, 2010 at 02:22:12PM +0530, Subrata Modak wrote: Hi, The following suspicious rcu_dereference_check() usage is detected during 2.6.35-stable boot on my ppc64/p7 machine: == [ INFO: suspicious rcu_dereference_check() usage. ] --- kernel/sched.c:616 invoked rcu_dereference_check() without protection! other info that might help us debug this: rcu_scheduler_active = 1, debug_locks = 0 1 lock held by swapper/1: #0: (rq-lock){-.}, at: [c07ca2f8] .init_idle+0x78/0x4a8 stack backtrace: Call Trace: [c00f392bf990] [c0014f04] .show_stack+0xb0/0x1a0 (unreliable) [c00f392bfa50] [c07c87b4] .dump_stack+0x28/0x3c [c00f392bfad0] [c0103e1c] .lockdep_rcu_dereference+0xbc/0xe4 [c00f392bfb70] [c07ca434] .init_idle+0x1b4/0x4a8 [c00f392bfc30] [c07cad04] .fork_idle+0xa4/0xd0 [c00f392bfe30] [c0aefaac] .smp_prepare_cpus+0x23c/0x2f4 [c00f392bfed0] [c0ae1424] .kernel_init+0xec/0x32c [c00f392bff90] [c0033f40] .kernel_thread+0x54/0x70 == Please note that this was reported earlier on 2.6.34-rc6: http://marc.info/?l=linux-kernelm=127313031922395w=2, The issue was fixed with: commit 1ce7e4ff24fe338438bc7837e02780f202bf202b Author: Li Zefan l...@cn.fujitsu.com Date: Fri Apr 23 10:35:52 2010 +0800 cgroup: Check task_lock in task_subsys_state() According to: http://lkml.org/lkml/2010/7/1/883, commit dc61b1d65e353d638b2445f71fb8e5b5630f2415 Author: Peter Zijlstra a.p.zijls...@chello.nl Date: Tue Jun 8 11:40:42 2010 +0200 sched: Fix PROVE_RCU vs cpu_cgroup should have fixed this. But this is reproducible on 2.6.35-stable. Please also see the config file attached. Hello, Subrata, Thank you for locating this one! This looks like the same issue that Ilia Mirkin located. Please see below for my analysis -- no fix yet, as I need confirmation from cgroups experts. I can easily create a patch that suppresses the warning, but I don't yet know whether this is the right thing to do. Thanx, Paul On Thu, Aug 05, 2010 at 01:31:10PM -0400, Ilia Mirkin wrote: On Thu, Jul 1, 2010 at 6:18 PM, Paul E. McKenney paul...@linux.vnet.ibm.com wrote: On Thu, Jul 01, 2010 at 08:21:43AM -0400, Miles Lane wrote: [ INFO: suspicious rcu_dereference_check() usage. ] --- kernel/sched.c:616 invoked rcu_dereference_check() without protection! other info that might help us debug this: rcu_scheduler_active = 1, debug_locks = 1 3 locks held by swapper/1: #0: (cpu_add_remove_lock){+.+.+.}, at: [81042914] cpu_maps_update_begin+0x12/0x14 #1: (cpu_hotplug.lock){+.+.+.}, at: [8104294f] cpu_hotplug_begin+0x27/0x4e #2: (rq-lock){-.-...}, at: [812f8502] init_idle+0x2b/0x114 Hello, Miles! I believe that this one is fixed by commit dc61b1d6 in -tip. Hi Paul, Looks like that commit made it into 2.6.35: git tag -l --contains dc61b1d65e353d638b2445f71fb8e5b5630f2415 v2.6.35* v2.6.35 v2.6.35-rc4 v2.6.35-rc5 v2.6.35-rc6 However I still get: [0.051203] CPU0: AMD QEMU Virtual CPU version 0.12.4 stepping 03 [0.052999] lockdep: fixing up alternatives. [0.054105] [0.054106] === [0.054999] [ INFO: suspicious rcu_dereference_check() usage. ] [0.054999] --- [0.054999] kernel/sched.c:616 invoked rcu_dereference_check() without protection ! [0.054999] [0.054999] other info that might help us debug this: [0.054999] [0.054999] [0.054999] rcu_scheduler_active = 1, debug_locks = 1 [0.054999] 3 locks held by swapper/1: [0.054999] #0: (cpu_add_remove_lock){+.+.+.}, at: [814be933] cpu_up+ 0x42/0x6a [0.054999] #1: (cpu_hotplug.lock){+.+.+.}, at: [810400d8] cpu_hotplu g_begin+0x2a/0x51 [0.054999] #2: (rq-lock){-.-...}, at: [814be2f7] init_idle+0x2f/0x 113 [0.054999] [0.054999] stack backtrace: [0.054999] Pid: 1, comm: swapper Not tainted 2.6.35 #1 [0.054999] Call Trace: [0.054999] [81068054] lockdep_rcu_dereference+0x9b/0xa3 [0.054999] [810325c3] task_group+0x7b/0x8a [0.054999] [810325e5] set_task_rq+0x13/0x40 [0.054999] [814be39a] init_idle+0xd2/0x113 [
Re: [PATCH 08/12] ptp: Added a brand new class driver for ptp clocks.
On Tue, Jun 15, 2010 at 01:11:30PM -0600, Grant Likely wrote: On Tue, Jun 15, 2010 at 10:09 AM, Richard Cochran +static DEFINE_SPINLOCK(clocks_lock); /* protects 'clocks' */ Doesn't appear that clocks is manipulated at atomic context. Mutex instead? ... If the spinlock is changed to a mutex that is held for the entire function call, then the logic here can be simpler. Grant, I am working on another go at this patch series. Stupid question: The caller of ptp_clock_register(), which takes the clocks_lock, is always a module_init() function. Is this always a safe context in which to call mutex_lock? Thanks, Richard ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: How to use mpc8xxx_gpio.c device driver
On Wed, Aug 11, 2010 at 10:15 PM, Anton Vorontsov cbouatmai...@gmail.comwrote: Hi, On Wed, Aug 11, 2010 at 06:57:16PM +0530, Ravi Gupta wrote: I am new to device driver development. I am trying to access the GPIO of MPC837xERDB eval board. I have upgraded its kernel to linux-2.6.28.9 and enable support for mpc8xxx_gpio.c. On boot up, it successfully detect two gpio controllers. Now my question is how I am going to use it to communicate with the gpio pins? Do I have to modify the code in mpc8xxx_gpio.c file to do whatever I want to do with gpios or I can use the standard gpio API provided in kernel ( gpio_request()/gpio_free() ). I also tries the standard kernel API, but it fails. Here is my code : No, you don't have to modify anything, and yes, you can use standard kernel GPIO API. #include linux/module.h #include linux/errno.h /* error codes */ #include linux/gpio.h static __init int sample_module_init(void) { int ret; int i; for (i=1; i32; i++) { ret = gpio_request(i, Sample Driver); Before issing gpio_request() you must get GPIO number from the of_get_gpio() or of_get_gpio_flags() calls (the _flags variant will also retreive flags such as 'active-low'). The calls assume that you have gpio = specifier in the device tree, see arch/powerpc/boot/dts/mpc8377_rdb.dts's leds node as an example. As you want GPIO LEDs, you can use drivers/leds/leds-gpio.c (see of_gpio_leds_probe() call, it gets gpio numbers via of_get_gpio_flags() and then requests them via gpio_request()). Also see Documentation/powerpc/dts-bindings/gpio/gpio.txt Documentation/powerpc/dts-bindings/gpio/led.txt if (ret) { printk(KERN_WARNING sample_driver: unable to request GPIO_PG%d\n, i); //return ret; } } return 0; } On Wed, Aug 11, 2010 at 07:49:40PM +0530, Ravi Gupta wrote: Also, when I try to export a gpio in sysfs echo 9 /sys/class/gpio/export The gpio numbers are global, i.e. GPIO controller base + GPIO number within the controller. [...] drwxr-xr-x3 root root0 Jan 1 00:00 gpiochip192 So, if you want GPIO9 within gpiochip192, you should issue echo 201 export. Thanks, -- Anton Vorontsov email: cbouatmai...@gmail.com irc://irc.freenode.net/bd2 Hi Anton, Thanks for the reply. I had added the entries for gpio pin 9 for both controllers(I was not sure with controller's pin is connected to LED, but now I know it is pin no. 233 i.e 224+9) in the mpc8377_rdb.dts file. Below is a portion of my dts file, I have attached the complete dts file as attachment. i...@e000 { #address-cells = 1; #size-cells = 1; device_type = soc; compatible = simple-bus; ranges = 0x0 0xe000 0x0010; reg = 0xe000 0x0200; bus-frequency = 0; w...@200 { device_type = watchdog; compatible = mpc83xx_wdt; reg = 0x200 0x100; }; gpio1: gpio-control...@c00 { #gpio-cells = 2; compatible = fsl,mpc8377-gpio, fsl,mpc8349-gpio; reg = 0xc00 0x100; interrupts = 74 0x8; interrupt-parent = ipic; gpio-controller; }; gpio2: gpio-control...@d00 { #gpio-cells = 2; compatible = fsl,mpc8377-gpio, fsl,mpc8349-gpio; reg = 0xd00 0x100; interrupts = 75 0x8; interrupt-parent = ipic; gpio-controller; }; * l...@0 { compatible = gpio-leds; label = hdd; gpios = gpio1 9 0; }; l...@1 { compatible = gpio-leds; label = rom; gpios = gpio2 9 0; };* . . . . }; Also I have enabled drivers/leds/leds-gpio.c in my kernel. To test whether the leds entires in dts file get attached to leds-gpio driver, I added printks in the probe function of the driver. static int gpio_led_probe(struct platform_device *pdev) { struct gpio_led_platform_data *pdata = pdev-dev.platform_data; struct gpio_led *cur_led; struct gpio_led_data *leds_data, *led_dat; int i, ret = 0; *printk(KERN_INFO led: inside gpio_led_probe.\n);* } But I couldn't see led: inside gpio_led_probe. message in dmesg. I checked sysfs and I can see entries of leds. Here is contents of sysfs on my machine. # ls /sys/devices/ -la drwxr-xr-x7 root root0 Jan 1 01:58 . drwxr-xr-x 12 root root0 Jan 1 00:00 .. drwxr-xr-x 22 root root0 Jan 1 01:58 *e000.immr* drwxr-xr-x5 root root0 Jan 1 01:58 e0005000.localbus drwxr-xr-x4 root root0 Jan 1 01:58 pci:00 drwxr-xr-x9 root root0 Jan 1 01:58 platform drwxr-xr-x8 root root0 Jan 1 01:58 system # ls /sys/devices/e000.immr/ bus e0004600.serial *led1.0* devspece0007000.spi *led2.1* e200.wdte00082a8.dma modalias
Re: How to use mpc8xxx_gpio.c device driver
Looking at the device tree for this board, it appears U-Boot remaps the IMMR registers to 0xe000. They are no longer accessible at 0xff40. I would recommend studying arch/powerpc/boot/dts/mpc8377_rdb.dts in the Linux source code. That describes the device layout on your board after U-Boot has run. A wonderful tool for testing devices from userspace is busybox devmem. It allows you to poke any physical address with any value. The output of busybox devmem --help should get you started. As a quick example, busybox devmem 0xec00 w 0x1 will write the 32-bit value 0x1 to address 0xec00. I would also recommend using the built-in Linux GPIO API. It works, you just need to figure out how to use it. It will be much easier to get your code upstream if you use the provided APIs. The Documentation/gpio.txt file should help you in understanding the in-kernel Linux GPIO API. I'm afraid I don't have much experience other than accessing it via sysfs from userspace. Ira Hi Ira, Thanks for another great reply. Now I can also access gpio memory map registers. Thanks and Regards, Ravi Gupta ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: How to use mpc8xxx_gpio.c device driver
Hi, On Fri, Aug 13, 2010 at 03:29:11PM +0530, Ravi Gupta wrote: [...] Thanks for the reply. I had added the entries for gpio pin 9 for both controllers(I was not sure with controller's pin is connected to LED, but now I know it is pin no. 233 i.e 224+9) in the mpc8377_rdb.dts file. Below is a portion of my dts file, I have attached the complete dts file as attachment. i...@e000 { [...] * l...@0 { compatible = gpio-leds; label = hdd; gpios = gpio1 9 0; }; What kernel version you look at? Please see the latest kernel, it has MCU GPIO LED nodes already, and you can just add some additional nodes. http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=arch/powerpc/boot/dts/mpc8377_rdb.dts#l490 [...] Also I have enabled drivers/leds/leds-gpio.c in my kernel. To test whether the leds entires in dts file get attached to leds-gpio driver, I added printks in the probe function of the driver. static int gpio_led_probe(struct platform_device *pdev) { struct gpio_led_platform_data *pdata = pdev-dev.platform_data; struct gpio_led *cur_led; struct gpio_led_data *leds_data, *led_dat; int i, ret = 0; *printk(KERN_INFO led: inside gpio_led_probe.\n);* You have put the printk into the wrong function. It should have been of_gpio_leds_probe(): http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=drivers/leds/leds-gpio.c#l227 If you don't have that function then you use too old kernel. Thanks, -- Anton Vorontsov email: cbouatmai...@gmail.com irc://irc.freenode.net/bd2 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/9] RapidIO: fix RapidIO sysfs hierarchy
Makes RapidIO devices appear in /sys/devices/rapidio directory instead of top of /sys/devices directory. Signed-off-by: Alexandre Bounine alexandre.boun...@idt.com Reviewed-by: Thomas Moll thomas.m...@sysgo.com Cc: Matt Porter mpor...@kernel.crashing.org Cc: Li Yang le...@freescale.com Cc: Kumar Gala ga...@kernel.crashing.org --- drivers/rapidio/rio-driver.c |2 +- drivers/rapidio/rio-scan.c |1 + include/linux/rio.h |1 + 3 files changed, 3 insertions(+), 1 deletions(-) diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c index 3222fa3..0f4a53b 100644 --- a/drivers/rapidio/rio-driver.c +++ b/drivers/rapidio/rio-driver.c @@ -192,7 +192,7 @@ static int rio_match_bus(struct device *dev, struct device_driver *drv) out:return 0; } -static struct device rio_bus = { +struct device rio_bus = { .init_name = rapidio, }; diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index 8070e07..1123be8 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c @@ -478,6 +478,7 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, } rdev-dev.bus = rio_bus_type; + rdev-dev.parent = rio_bus; device_initialize(rdev-dev); rdev-dev.release = rio_release_dev; diff --git a/include/linux/rio.h b/include/linux/rio.h index bd6eb0e..84c9f8c 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h @@ -67,6 +67,7 @@ #define RIO_PW_MSG_SIZE64 extern struct bus_type rio_bus_type; +extern struct device rio_bus; extern struct list_head rio_devices; /* list of all devices */ struct rio_mport; -- 1.7.0.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 0/9] RapidIO: Set of patches to add Gen2 switches
This set of RapidIO patches adds support for new IDT Gen2 sRIO switch devices - CPS-1848 and CPS-1616. Adding these sRIO switches required to implement standard error recovery mechanism defined by the RapidIO specification. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 2/9] RapidIO, powerpc/85xx: modify RIO port-write interrupt handler
- Rearranged RIO port-write interrupt handling to perform message buffering as soon as possible. - Modified to disable port-write controller when clearing Transaction Error (TE) bit. Signed-off-by: Alexandre Bounine alexandre.boun...@idt.com Reviewed-by: Thomas Moll thomas.m...@sysgo.com Cc: Matt Porter mpor...@kernel.crashing.org Cc: Li Yang le...@freescale.com Cc: Kumar Gala ga...@kernel.crashing.org --- arch/powerpc/sysdev/fsl_rio.c | 67 ++-- 1 files changed, 37 insertions(+), 30 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index cd71dc1..708d94e 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -1065,18 +1065,12 @@ fsl_rio_port_write_handler(int irq, void *dev_instance) struct rio_priv *priv = port-priv; u32 epwisr, tmp; - ipwmr = in_be32(priv-msg_regs-pwmr); - ipwsr = in_be32(priv-msg_regs-pwsr); - epwisr = in_be32(priv-regs_win + RIO_EPWISR); - if (epwisr 0x8000) { - tmp = in_be32(priv-regs_win + RIO_LTLEDCSR); - pr_info(RIO_LTLEDCSR = 0x%x\n, tmp); - out_be32(priv-regs_win + RIO_LTLEDCSR, 0); - } - if (!(epwisr 0x0001)) - return IRQ_HANDLED; + goto pw_done; + + ipwmr = in_be32(priv-msg_regs-pwmr); + ipwsr = in_be32(priv-msg_regs-pwsr); #ifdef DEBUG_PW pr_debug(PW Int-IPWMR: 0x%08x IPWSR: 0x%08x (, ipwmr, ipwsr); @@ -1092,22 +1086,8 @@ fsl_rio_port_write_handler(int irq, void *dev_instance) pr_debug( PWB); pr_debug( )\n); #endif - out_be32(priv-msg_regs-pwsr, -ipwsr (RIO_IPWSR_TE | RIO_IPWSR_QFI | RIO_IPWSR_PWD)); - - if ((ipwmr RIO_IPWMR_EIE) (ipwsr RIO_IPWSR_TE)) { - priv-port_write_msg.err_count++; - pr_info(RIO: Port-Write Transaction Err (%d)\n, -priv-port_write_msg.err_count); - } - if (ipwsr RIO_IPWSR_PWD) { - priv-port_write_msg.discard_count++; - pr_info(RIO: Port Discarded Port-Write Msg(s) (%d)\n, -priv-port_write_msg.discard_count); - } - /* Schedule deferred processing if PW was received */ - if (ipwsr RIO_IPWSR_QFI) { + if ((ipwmr RIO_IPWMR_QFIE) (ipwsr RIO_IPWSR_QFI)) { /* Save PW message (if there is room in FIFO), * otherwise discard it. */ @@ -1117,16 +1097,43 @@ fsl_rio_port_write_handler(int irq, void *dev_instance) RIO_PW_MSG_SIZE); } else { priv-port_write_msg.discard_count++; - pr_info(RIO: ISR Discarded Port-Write Msg(s) (%d)\n, + pr_debug(RIO: ISR Discarded Port-Write Msg(s) (%d)\n, priv-port_write_msg.discard_count); } + /* Clear interrupt and issue Clear Queue command. This allows +* another port-write to be received. +*/ + out_be32(priv-msg_regs-pwsr, RIO_IPWSR_QFI); + out_be32(priv-msg_regs-pwmr, ipwmr | RIO_IPWMR_CQ); + schedule_work(priv-pw_work); } - /* Issue Clear Queue command. This allows another -* port-write to be received. -*/ - out_be32(priv-msg_regs-pwmr, ipwmr | RIO_IPWMR_CQ); + if ((ipwmr RIO_IPWMR_EIE) (ipwsr RIO_IPWSR_TE)) { + priv-port_write_msg.err_count++; + pr_debug(RIO: Port-Write Transaction Err (%d)\n, +priv-port_write_msg.err_count); + /* Clear Transaction Error: port-write controller should be +* disabled when clearing this error +*/ + out_be32(priv-msg_regs-pwmr, ipwmr ~RIO_IPWMR_PWE); + out_be32(priv-msg_regs-pwsr, RIO_IPWSR_TE); + out_be32(priv-msg_regs-pwmr, ipwmr); + } + + if (ipwsr RIO_IPWSR_PWD) { + priv-port_write_msg.discard_count++; + pr_debug(RIO: Port Discarded Port-Write Msg(s) (%d)\n, +priv-port_write_msg.discard_count); + out_be32(priv-msg_regs-pwsr, RIO_IPWSR_PWD); + } + +pw_done: + if (epwisr 0x8000) { + tmp = in_be32(priv-regs_win + RIO_LTLEDCSR); + pr_debug(RIO_LTLEDCSR = 0x%x\n, tmp); + out_be32(priv-regs_win + RIO_LTLEDCSR, 0); + } return IRQ_HANDLED; } -- 1.7.0.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 3/9] RapidIO: Add the ingress port number into the RIO switch data structure
A switch ingress port number has to be saved for software assisted error recovery from the error-stopped state. Saving this information also allows to remove several register reads from the RIO enumeration process. Signed-off-by: Alexandre Bounine alexandre.boun...@idt.com Reviewed-by: Thomas Moll thomas.m...@sysgo.com Cc: Matt Porter mpor...@kernel.crashing.org Cc: Li Yang le...@freescale.com Cc: Kumar Gala ga...@kernel.crashing.org --- drivers/rapidio/rio-scan.c | 38 -- include/linux/rio.h|4 ++-- 2 files changed, 10 insertions(+), 32 deletions(-) diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index 1123be8..efe3519 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c @@ -389,6 +389,7 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, int ret = 0; struct rio_dev *rdev; struct rio_switch *rswitch = NULL; + u32 swpinfo; int result, rdid; rdev = kzalloc(sizeof(struct rio_dev), GFP_KERNEL); @@ -440,7 +441,7 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, /* If a PE has both switch and other functions, show it as a switch */ if (rio_is_switch(rdev)) { rio_mport_read_config_32(port, destid, hopcount, -RIO_SWP_INFO_CAR, rdev-swpinfo); +RIO_SWP_INFO_CAR, swpinfo); rswitch = kzalloc(sizeof(struct rio_switch), GFP_KERNEL); if (!rswitch) goto cleanup; @@ -448,6 +449,7 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, rswitch-hopcount = hopcount; rswitch-destid = destid; rswitch-port_ok = 0; + rswitch-inport = (u8)(swpinfo RIO_SWP_INFO_PORT_NUM_MASK); rswitch-route_table = kzalloc(sizeof(u8)* RIO_MAX_ROUTE_ENTRIES(port-sys_size), GFP_KERNEL); @@ -719,25 +721,6 @@ static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount) } /** - * rio_get_swpinfo_inport- Gets the ingress port number - * @mport: Master port to send transaction - * @destid: Destination ID associated with the switch - * @hopcount: Number of hops to the device - * - * Returns port number being used to access the switch device. - */ -static u8 -rio_get_swpinfo_inport(struct rio_mport *mport, u16 destid, u8 hopcount) -{ - u32 result; - - rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR, -result); - - return (u8) (result 0xff); -} - -/** * rio_get_swpinfo_tports- Gets total number of ports on the switch * @mport: Master port to send transaction * @destid: Destination ID associated with the switch @@ -834,8 +817,7 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, if (rio_is_switch(rdev)) { next_switchid++; - sw_inport = rio_get_swpinfo_inport(port, - RIO_ANY_DESTID(port-sys_size), hopcount); + sw_inport = rdev-rswitch-inport; rio_route_add_entry(port, rdev-rswitch, RIO_GLOBAL_TABLE, port-host_deviceid, sw_inport, 0); rdev-rswitch-route_table[port-host_deviceid] = sw_inport; @@ -989,8 +971,7 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid, RIO: found %s (vid %4.4x did %4.4x) with %d ports\n, rio_name(rdev), rdev-vid, rdev-did, num_ports); for (port_num = 0; port_num num_ports; port_num++) { - if (rio_get_swpinfo_inport(port, destid, hopcount) == - port_num) + if (rdev-rswitch-inport == port_num) continue; if (rio_sport_is_active @@ -1092,7 +1073,6 @@ static void rio_update_route_tables(struct rio_mport *port) { struct rio_dev *rdev; struct rio_switch *rswitch; - u8 sport; u16 destid; list_for_each_entry(rdev, rio_devices, global_list) { @@ -1109,14 +1089,12 @@ static void rio_update_route_tables(struct rio_mport *port) if (rswitch-destid == destid) continue; - sport = rio_get_swpinfo_inport(port, - rswitch-destid, rswitch-hopcount); - if (rswitch-add_entry) { rio_route_add_entry(port, rswitch, RIO_GLOBAL_TABLE, destid, - sport, 0); -
[PATCH 4/9] RapidIO: Add relation links between RIO device structures
Create back and forward links between RIO devices. These links are intended for use by error management and hot-plug extensions. Signed-off-by: Alexandre Bounine alexandre.boun...@idt.com Reviewed-by: Thomas Moll thomas.m...@sysgo.com Cc: Matt Porter mpor...@kernel.crashing.org Cc: Li Yang le...@freescale.com Cc: Kumar Gala ga...@kernel.crashing.org --- drivers/rapidio/rio-scan.c | 55 +-- include/linux/rio.h|6 2 files changed, 28 insertions(+), 33 deletions(-) diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index efe3519..5dc33d1 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c @@ -442,7 +442,10 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, if (rio_is_switch(rdev)) { rio_mport_read_config_32(port, destid, hopcount, RIO_SWP_INFO_CAR, swpinfo); - rswitch = kzalloc(sizeof(struct rio_switch), GFP_KERNEL); + rswitch = kzalloc(sizeof(*rswitch) + + RIO_GET_TOTAL_PORTS(swpinfo) * + sizeof(rswitch-nextdev[0]), + GFP_KERNEL); if (!rswitch) goto cleanup; rswitch-switchid = next_switchid; @@ -450,6 +453,7 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, rswitch-destid = destid; rswitch-port_ok = 0; rswitch-inport = (u8)(swpinfo RIO_SWP_INFO_PORT_NUM_MASK); + rswitch-nports = (u8)RIO_GET_TOTAL_PORTS(swpinfo); rswitch-route_table = kzalloc(sizeof(u8)* RIO_MAX_ROUTE_ENTRIES(port-sys_size), GFP_KERNEL); @@ -721,25 +725,6 @@ static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount) } /** - * rio_get_swpinfo_tports- Gets total number of ports on the switch - * @mport: Master port to send transaction - * @destid: Destination ID associated with the switch - * @hopcount: Number of hops to the device - * - * Returns total numbers of ports implemented by the switch device. - */ -static u8 rio_get_swpinfo_tports(struct rio_mport *mport, u16 destid, -u8 hopcount) -{ - u32 result; - - rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR, -result); - - return RIO_GET_TOTAL_PORTS(result); -} - -/** * rio_net_add_mport- Add a master port to a RIO network * @net: RIO network * @port: Master port to add @@ -759,15 +744,16 @@ static void rio_net_add_mport(struct rio_net *net, struct rio_mport *port) * @net: RIO network being enumerated * @port: Master port to send transactions * @hopcount: Number of hops into the network + * @prev: Previous RIO device connected to the enumerated one + * @prev_port: Port on previous RIO device * * Recursively enumerates a RIO network. Transactions are sent via the * master port passed in @port. */ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, -u8 hopcount) +u8 hopcount, struct rio_dev *prev, int prev_port) { int port_num; - int num_ports; int cur_destid; int sw_destid; int sw_inport; @@ -812,6 +798,9 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, if (rdev) { /* Add device to the global and bus/net specific list. */ list_add_tail(rdev-net_list, net-devices); + rdev-prev = prev; + if (prev rio_is_switch(prev)) + prev-rswitch-nextdev[prev_port] = rdev; } else return -1; @@ -830,14 +819,13 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, rdev-rswitch-route_table[destid] = sw_inport; } - num_ports = - rio_get_swpinfo_tports(port, RIO_ANY_DESTID(port-sys_size), - hopcount); pr_debug( RIO: found %s (vid %4.4x did %4.4x) with %d ports\n, - rio_name(rdev), rdev-vid, rdev-did, num_ports); + rio_name(rdev), rdev-vid, rdev-did, + rdev-rswitch-nports); sw_destid = next_destid; - for (port_num = 0; port_num num_ports; port_num++) { + for (port_num = 0; +port_num rdev-rswitch-nports; port_num++) { /*Enable Input Output Port (transmitter reviever)*/ rio_enable_rx_tx_port(port, 0, RIO_ANY_DESTID(port-sys_size), @@ -862,7 +850,8 @@ static int __devinit
[PATCH 5/9] RapidIO: Add default handler for error_stopped state
The default error-stopped state handler provides recovery mechanism as defined by RIO specification. Signed-off-by: Alexandre Bounine alexandre.boun...@idt.com Reviewed-by: Thomas Moll thomas.m...@sysgo.com Cc: Matt Porter mpor...@kernel.crashing.org Cc: Li Yang le...@freescale.com Cc: Kumar Gala ga...@kernel.crashing.org --- drivers/rapidio/rio.c | 191 +++-- drivers/rapidio/switches/idtcps.c | 10 ++ drivers/rapidio/switches/tsi57x.c |4 + include/linux/rio_regs.h |8 +- 4 files changed, 179 insertions(+), 34 deletions(-) diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index 74e9d22..f58df11 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c @@ -495,6 +495,121 @@ int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock) } /** + * rio_clr_err_stopped - Clears port Error-stopped states. + * @rdev: Pointer to RIO device control structure + * @pnum: Switch port number to clear errors + * @err_status: port error status (if 0 reads register from device) + */ +static int rio_clr_err_stopped(struct rio_dev *rdev, u32 pnum, u32 err_status) +{ + struct rio_mport *mport = rdev-net-hport; + u16 destid = rdev-rswitch-destid; + u8 hopcount = rdev-rswitch-hopcount; + struct rio_dev *nextdev = rdev-rswitch-nextdev[pnum]; + u32 regval; + u32 far_ackid, far_linkstat, near_ackid; + int checkcount; + + if (err_status == 0) + rio_mport_read_config_32(mport, destid, hopcount, + rdev-phys_efptr + RIO_PORT_N_ERR_STS_CSR(pnum), + err_status); + + if (err_status RIO_PORT_N_ERR_STS_PW_OUT_ES) { + pr_debug(RIO_EM: servicing Output Error-Stopped state\n); + /* +* Send a Link-Request/Input-Status control symbol +*/ + + /* Read from link maintenance response register +* to clear valid bit */ + rio_mport_read_config_32(mport, destid, hopcount, + rdev-phys_efptr + RIO_PORT_N_MNT_RSP_CSR(pnum), + regval); + udelay(50); + + /* Issue Input-status command */ + rio_mport_write_config_32(mport, destid, hopcount, + rdev-phys_efptr + RIO_PORT_N_MNT_REQ_CSR(pnum), + RIO_MNT_REQ_CMD_IS); + + checkcount = 3; + while (checkcount--) { + udelay(50); + rio_mport_read_config_32(mport, destid, hopcount, + rdev-phys_efptr + RIO_PORT_N_MNT_RSP_CSR(pnum), + regval); + if (regval RIO_PORT_N_MNT_RSP_RVAL) + break; + } + + pr_debug(RIO_EM: SP%d_MNT_RSP_CSR=0x%08x\n, pnum, regval); + if (regval RIO_PORT_N_MNT_RSP_RVAL) { + far_ackid = (regval RIO_PORT_N_MNT_RSP_ASTAT) 5; + far_linkstat = regval RIO_PORT_N_MNT_RSP_LSTAT; + rio_mport_read_config_32(mport, destid, hopcount, + rdev-phys_efptr + RIO_PORT_N_ACK_STS_CSR(pnum), + regval); + pr_debug(RIO_EM: SP%d_ACK_STS_CSR=0x%08x\n, + pnum, regval); + near_ackid = (regval RIO_PORT_N_ACK_INBOUND) 24; + pr_debug(RIO_EM: SP%d far_ackID=0x%02x far_linkstat=0x%02x near_ackID=0x%02x\n, + pnum, far_ackid, far_linkstat, near_ackid); + + /* +* If required, synchronize ackIDs of near and +* far sides. +*/ + if ((far_ackid != ((regval RIO_PORT_N_ACK_OUTSTAND) 8)) || + (far_ackid != (regval RIO_PORT_N_ACK_OUTBOUND))) { + /* Align near outstanding/outbound ackIDs with +* far inbound. +*/ + rio_mport_write_config_32(mport, destid, + hopcount, rdev-phys_efptr + + RIO_PORT_N_ACK_STS_CSR(pnum), + (near_ackid 24) | + (far_ackid 8) | far_ackid); + /* Align far outstanding/outbound ackIDs with +* near inbound. +*/ + far_ackid++; + if (nextdev) + rio_write_config_32(nextdev, + nextdev-phys_efptr + +
[PATCH 6/9] RapidIO: Add switch-specific sysfs initialization callback
Add callback that allows to create/remove switch-specific sysfs attributes. Signed-off-by: Alexandre Bounine alexandre.boun...@idt.com Reviewed-by: Thomas Moll thomas.m...@sysgo.com Cc: Matt Porter mpor...@kernel.crashing.org Cc: Li Yang le...@freescale.com Cc: Kumar Gala ga...@kernel.crashing.org --- drivers/rapidio/rio-sysfs.c | 26 +++--- include/linux/rio.h |2 ++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c index 00b4756..bfc483b 100644 --- a/drivers/rapidio/rio-sysfs.c +++ b/drivers/rapidio/rio-sysfs.c @@ -40,9 +40,6 @@ static ssize_t routes_show(struct device *dev, struct device_attribute *attr, ch char *str = buf; int i; - if (!rdev-rswitch) - goto out; - for (i = 0; i RIO_MAX_ROUTE_ENTRIES(rdev-net-hport-sys_size); i++) { if (rdev-rswitch-route_table[i] == RIO_INVALID_ROUTE) @@ -52,7 +49,6 @@ static ssize_t routes_show(struct device *dev, struct device_attribute *attr, ch rdev-rswitch-route_table[i]); } - out: return (str - buf); } @@ -63,10 +59,11 @@ struct device_attribute rio_dev_attrs[] = { __ATTR_RO(asm_did), __ATTR_RO(asm_vid), __ATTR_RO(asm_rev), - __ATTR_RO(routes), __ATTR_NULL, }; +static DEVICE_ATTR(routes, S_IRUGO, routes_show, NULL); + static ssize_t rio_read_config(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, @@ -218,7 +215,17 @@ int rio_create_sysfs_dev_files(struct rio_dev *rdev) { int err = 0; - err = sysfs_create_bin_file(rdev-dev.kobj, rio_config_attr); + err = device_create_bin_file(rdev-dev, rio_config_attr); + + if (!err rdev-rswitch) { + err = device_create_file(rdev-dev, dev_attr_routes); + if (!err rdev-rswitch-sw_sysfs) + err = rdev-rswitch-sw_sysfs(rdev, 1); + } + + if (err) + pr_warning(RIO: Failed to create attribute file(s) for %s\n, + rio_name(rdev)); return err; } @@ -231,5 +238,10 @@ int rio_create_sysfs_dev_files(struct rio_dev *rdev) */ void rio_remove_sysfs_dev_files(struct rio_dev *rdev) { - sysfs_remove_bin_file(rdev-dev.kobj, rio_config_attr); + device_remove_bin_file(rdev-dev, rio_config_attr); + if (rdev-rswitch) { + device_remove_file(rdev-dev, dev_attr_routes); + if (rdev-rswitch-sw_sysfs) + rdev-rswitch-sw_sysfs(rdev, 0); + } } diff --git a/include/linux/rio.h b/include/linux/rio.h index 754895c..8f19fb2 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h @@ -233,6 +233,7 @@ struct rio_net { * @get_domain: Callback for switch-specific domain get function * @em_init: Callback for switch-specific error management initialization function * @em_handle: Callback for switch-specific error management handler function + * @sw_sysfs: Callback that initializes switch-specific sysfs attributes * @nextdev: Array of per-port pointers to the next attached device */ struct rio_switch { @@ -256,6 +257,7 @@ struct rio_switch { u8 *sw_domain); int (*em_init) (struct rio_dev *dev); int (*em_handle) (struct rio_dev *dev, u8 swport); + int (*sw_sysfs) (struct rio_dev *dev, int create); struct rio_dev *nextdev[0]; }; -- 1.7.0.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 7/9] RapidIO: Add handling for PW message from a lost device
Add check if PW message source device is accessible and change PW message handler to recover if PW message source device is not available anymore (power down or link disconnect). To avoid possible loss of notification, the PW message handler scans the route back from the source device to identify end of the broken link. Signed-off-by: Alexandre Bounine alexandre.boun...@idt.com Reviewed-by: Thomas Moll thomas.m...@sysgo.com Cc: Matt Porter mpor...@kernel.crashing.org Cc: Li Yang le...@freescale.com Cc: Kumar Gala ga...@kernel.crashing.org --- drivers/rapidio/rio.c | 111 ++-- drivers/rapidio/rio.h |2 + 2 files changed, 108 insertions(+), 5 deletions(-) diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index f58df11..22f7847 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c @@ -495,6 +495,90 @@ int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock) } /** + * rio_chk_dev_route - Validate route to the specified device. + * @rdev: Pointer to RIO device control structure + * @nrdev: Pointer to last active device on the route to rdev + * @npnum: nrdev port number on the route to rdev + * + * Follows a route to the specified RIO device to determine the last available + * device (and corresponding RIO port) on the route. + */ +static int +rio_chk_dev_route(struct rio_dev *rdev, struct rio_dev **nrdev, int *npnum) +{ + u32 result; + int p_port, rc = -EIO; + struct rio_dev *prev = NULL; + + while (rdev-prev (rdev-prev-pef RIO_PEF_SWITCH)) { + if (rio_read_config_32(rdev-prev, RIO_DEV_ID_CAR, result)) { + rdev = rdev-prev; + continue; + } + + prev = rdev-prev; + for (p_port = 0; p_port prev-rswitch-nports; p_port++) + if (prev-rswitch-nextdev[p_port] == rdev) + break; + + if (p_port prev-rswitch-nports) { + pr_debug(RIO: link failed on [%s]-P%d\n, +rio_name(prev), p_port); + *nrdev = prev; + *npnum = p_port; + rc = 0; + } else { + pr_debug(RIO: failed to trace route to %s\n, +rio_name(prev)); + } + + break; + } + + return rc; +} + +/** + * rio_mport_chk_dev_access - Validate access to the specified device. + * @mport: Master port to send transactions + * @destid: Device destination ID in network + * @hopcount: Number of hops into the network + */ +static int +rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, u8 hopcount) +{ + int i = 0; + u32 tmp; + + while (rio_mport_read_config_32(mport, destid, hopcount, + RIO_DEV_ID_CAR, tmp)) { + i++; + if (i == RIO_MAX_CHK_RETRY) + return -EIO; + mdelay(1); + } + + return 0; +} + +/** + * rio_chk_dev_access - Validate access to the specified device. + * @rdev: Pointer to RIO device control structure + */ +static int rio_chk_dev_access(struct rio_dev *rdev) +{ + u8 hopcount = 0xff; + u16 destid = rdev-destid; + + if (rdev-rswitch) { + destid = rdev-rswitch-destid; + hopcount = rdev-rswitch-hopcount; + } + + return rio_mport_chk_dev_access(rdev-net-hport, destid, hopcount); +} + +/** * rio_clr_err_stopped - Clears port Error-stopped states. * @rdev: Pointer to RIO device control structure * @pnum: Switch port number to clear errors @@ -627,8 +711,8 @@ int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg) rdev = rio_get_comptag(pw_msg-em.comptag, NULL); if (rdev == NULL) { - /* Someting bad here (probably enumeration error) */ - pr_err(RIO: %s No matching device for CTag 0x%08x\n, + /* Device removed or enumeration error */ + pr_debug(RIO: %s No matching device for CTag 0x%08x\n, __func__, pw_msg-em.comptag); return -EIO; } @@ -659,6 +743,26 @@ int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg) return 0; } + portnum = pw_msg-em.is_port 0xFF; + + /* Check if device and route to it are functional: +* Sometimes devices may send PW message(s) just before being +* powered down (or link being lost). +*/ + if (rio_chk_dev_access(rdev)) { + pr_debug(RIO: device access failed - get link partner\n); + /* Scan route to the device and identify failed link. +* This will replace device and port reported in PW message. +* PW message should not be used after this point. +*/ + if (rio_chk_dev_route(rdev,
[PATCH 8/9] RapidIO: Add device access check into the enumeration
Add explicit device access check before performing device enumeration. This gives a chance to clear possible link error conditions by issuing safe maintenance read request(s). Signed-off-by: Alexandre Bounine alexandre.boun...@idt.com Reviewed-by: Thomas Moll thomas.m...@sysgo.com Cc: Matt Porter mpor...@kernel.crashing.org Cc: Li Yang le...@freescale.com Cc: Kumar Gala ga...@kernel.crashing.org --- drivers/rapidio/rio-scan.c |6 ++ drivers/rapidio/rio.c |2 +- drivers/rapidio/rio.h |2 ++ 3 files changed, 9 insertions(+), 1 deletions(-) diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index 5dc33d1..fb5324b 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c @@ -761,6 +761,12 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, u16 destid; int tmp; + if (rio_mport_chk_dev_access(port, + RIO_ANY_DESTID(port-sys_size), hopcount)) { + pr_debug(RIO: device access check failed\n); + return -1; + } + if (rio_get_host_deviceid_lock(port, hopcount) == port-host_deviceid) { pr_debug(RIO: PE already discovered by this host\n); /* diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index 22f7847..9621a7b 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c @@ -544,7 +544,7 @@ rio_chk_dev_route(struct rio_dev *rdev, struct rio_dev **nrdev, int *npnum) * @destid: Device destination ID in network * @hopcount: Number of hops into the network */ -static int +int rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, u8 hopcount) { int i = 0; diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h index bc71ba1..d249a12 100644 --- a/drivers/rapidio/rio.h +++ b/drivers/rapidio/rio.h @@ -24,6 +24,8 @@ extern u32 rio_mport_get_physefb(struct rio_mport *port, int local, u16 destid, u8 hopcount); extern u32 rio_mport_get_efb(struct rio_mport *port, int local, u16 destid, u8 hopcount, u32 from); +extern int rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, + u8 hopcount); extern int rio_create_sysfs_dev_files(struct rio_dev *rdev); extern int rio_enum_mport(struct rio_mport *mport); extern int rio_disc_mport(struct rio_mport *mport); -- 1.7.0.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 9/9] RapidIO: Add support for IDT CPS Gen2 switches
Add the RIO switch driver and definitions for IDT CPS-1848 and CPS-1616 Gen2 devices. Signed-off-by: Alexandre Bounine alexandre.boun...@idt.com Reviewed-by: Thomas Moll thomas.m...@sysgo.com Cc: Matt Porter mpor...@kernel.crashing.org Cc: Li Yang le...@freescale.com Cc: Kumar Gala ga...@kernel.crashing.org --- drivers/rapidio/switches/Kconfig|7 + drivers/rapidio/switches/Makefile |1 + drivers/rapidio/switches/idt_gen2.c | 439 +++ include/linux/rio_ids.h |2 + include/linux/rio_regs.h|4 + 5 files changed, 453 insertions(+), 0 deletions(-) create mode 100644 drivers/rapidio/switches/idt_gen2.c diff --git a/drivers/rapidio/switches/Kconfig b/drivers/rapidio/switches/Kconfig index 2b4e9b2..f47fee5 100644 --- a/drivers/rapidio/switches/Kconfig +++ b/drivers/rapidio/switches/Kconfig @@ -20,6 +20,13 @@ config RAPIDIO_TSI568 ---help--- Includes support for IDT Tsi568 serial RapidIO switch. +config RAPIDIO_CPS_GEN2 + bool IDT CPS Gen.2 SRIO switch support + depends on RAPIDIO + default n + ---help--- + Includes support for ITD CPS Gen.2 serial RapidIO switches. + config RAPIDIO_TSI500 bool Tsi500 Parallel RapidIO switch support depends on RAPIDIO diff --git a/drivers/rapidio/switches/Makefile b/drivers/rapidio/switches/Makefile index fe4adc3..48d67a6 100644 --- a/drivers/rapidio/switches/Makefile +++ b/drivers/rapidio/switches/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_RAPIDIO_TSI57X)+= tsi57x.o obj-$(CONFIG_RAPIDIO_CPS_XX) += idtcps.o obj-$(CONFIG_RAPIDIO_TSI568) += tsi568.o obj-$(CONFIG_RAPIDIO_TSI500) += tsi500.o +obj-$(CONFIG_RAPIDIO_CPS_GEN2) += idt_gen2.o ifeq ($(CONFIG_RAPIDIO_DEBUG),y) EXTRA_CFLAGS += -DDEBUG diff --git a/drivers/rapidio/switches/idt_gen2.c b/drivers/rapidio/switches/idt_gen2.c new file mode 100644 index 000..0de4a9c --- /dev/null +++ b/drivers/rapidio/switches/idt_gen2.c @@ -0,0 +1,439 @@ +/* + * IDT CPS Gen.2 Serial RapidIO switch family support + * + * Copyright 2010 Integrated Device Technology, Inc. + * Alexandre Bounine alexandre.boun...@idt.com + * + * 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 the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include linux/rio.h +#include linux/rio_drv.h +#include linux/rio_ids.h +#include linux/delay.h +#include ../rio.h + +#define LOCAL_RTE_CONF_DESTID_SEL 0x010070 +#define LOCAL_RTE_CONF_DESTID_SEL_PSEL 0x001f + +#define IDT_LT_ERR_REPORT_EN 0x03100c + +#define IDT_PORT_ERR_REPORT_EN(n) (0x031044 + (n)*0x40) +#define IDT_PORT_ERR_REPORT_EN_BC 0x03ff04 + +#define IDT_PORT_ISERR_REPORT_EN(n)(0x03104C + (n)*0x40) +#define IDT_PORT_ISERR_REPORT_EN_BC0x03ff0c +#define IDT_PORT_INIT_TX_ACQUIRED 0x0020 + +#define IDT_LANE_ERR_REPORT_EN(n) (0x038010 + (n)*0x100) +#define IDT_LANE_ERR_REPORT_EN_BC 0x03ff10 + +#define IDT_DEV_CTRL_1 0xf2000c +#define IDT_DEV_CTRL_1_GENPW 0x0200 +#define IDT_DEV_CTRL_1_PRSTBEH 0x0001 + +#define IDT_CFGBLK_ERR_CAPTURE_EN 0x020008 +#define IDT_CFGBLK_ERR_REPORT 0xf20014 +#define IDT_CFGBLK_ERR_REPORT_GENPW0x0002 + +#define IDT_AUX_PORT_ERR_CAP_EN0x02 +#define IDT_AUX_ERR_REPORT_EN 0xf20018 +#define IDT_AUX_PORT_ERR_LOG_I2C 0x0002 +#define IDT_AUX_PORT_ERR_LOG_JTAG 0x0001 + +#defineIDT_ISLTL_ADDRESS_CAP 0x021014 + +#define IDT_RIO_DOMAIN 0xf20020 +#define IDT_RIO_DOMAIN_MASK0x00ff + +#define IDT_PW_INFO_CSR0xf20024 + +#define IDT_SOFT_RESET 0xf20040 +#define IDT_SOFT_RESET_REQ 0x00030097 + +#define IDT_I2C_MCTRL 0xf20050 +#define IDT_I2C_MCTRL_GENPW0x0400 + +#define IDT_JTAG_CTRL 0xf2005c +#define IDT_JTAG_CTRL_GENPW0x0002 + +#define IDT_LANE_CTRL(n) (0xff8000 + (n)*0x100) +#define IDT_LANE_CTRL_BC 0x00 +#define IDT_LANE_CTRL_GENPW0x0020 +#define IDT_LANE_DFE_1_BC 0x18 +#define IDT_LANE_DFE_2_BC 0x1c + +#define IDT_PORT_OPS(n)(0xf40004 + (n)*0x100) +#define IDT_PORT_OPS_GENPW 0x0800 +#define IDT_PORT_OPS_PL_ELOG 0x0040 +#define IDT_PORT_OPS_LL_ELOG 0x0020 +#define IDT_PORT_OPS_LT_ELOG 0x0010 +#define IDT_PORT_OPS_BC0xf4ff04 + +#define IDT_PORT_ISERR_DET(n) (0xf40008 + (n)*0x100) + +#define IDT_ERR_CAP0xfd +#define IDT_ERR_CAP_LOG_OVERWR 0x0004 + +#define IDT_ERR_RD 0xfd0004 + +#define IDT_DEFAULT_ROUTE 0xde +#define IDT_NO_ROUTE 0xdf + +static int +idtg2_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, +
help with kernel panics in task swapper on 460ex
I have an odd problem when using the 460ex rev b processors. Previously, I'd used the rev A without any issues on the same pcbs. This happens on multiple units now. Basically, while running the system will just randomly kernel panic. We have seen this probably 4 or 5 times on a over the course of several days per board. On many occasions, the CPU will not kernel dump at all and will just be dead after having run for some amount of time. The kernel is 2.6.31.5 The exact details (though I don't think they are too useful are as follows. The one interesting item if I read it correctly, is that the CPU was trying to get instructions from c002 address. However, this board only has 512MB of memory so it seems that the address (if it is physical) isn't valid. Are there any tricks we can use to analyze this problem? Or is there any information we can collect to help pinpoint where this issue might lie? Thanks ame Unable to handle kernel paging request for data at address 0x8072f938 Faulting instruction address: 0xc002eac4 Oops: Kernel access of bad area, sig: 11 [#1] PowerPC 44x Platform Modules linked in: mapper NIP: c002eac4 LR: c004811c CTR: c000add0 REGS: c038be60 TRAP: 0300 Not tainted (2.6.31.5) MSR: 00021000 ME,CE CR: 24644324 XER: DEAR: 8072f938, ESR: TASK = c036a318[0] 'swapper' THREAD: c038a000 GPR00: 00f6 c038bf10 c036a318 fffef700 fffef6f9 00f9 00f6 00061583 GPR08: c0398070 8072f930 c0398070 c03978c0 004e 415ec006 1ffb3300 GPR16: 1ffa6e70 1ffad780 c036b1a0 ff1ad8aa c038bf48 GPR24: 00029000 001c 262a1965 c036de50 c039269c fffef700 fffef700 2625a000 NIP [c002eac4] get_next_timer_interrupt+0x30/0x260 LR [c004811c] tick_nohz_stop_sched_tick+0x110/0x404 Call Trace: [c038bf10] [c003df74] ktime_get+0x1c/0x44 (unreliable) [c038bf40] [c004811c] tick_nohz_stop_sched_tick+0x110/0x404 [c038bf90] [c0006f00] cpu_idle+0x50/0xd8 [c038bfb0] [c000197c] rest_init+0x5c/0x70 [c038bfc0] [c033f844] start_kernel+0x224/0x2a0 [c038bff0] [c200] skpinv+0x190/0x1cc Instruction dump: 9421ffd0 7c0802a6 bfa10024 90010034 3d20c037 8169d1b8 7c7e1b78 808b0004 5485063e 7ca62b78 54c91838 7d295a14 81090008 39290008 4814 80080014 ---[ end trace 13e96cd635551e49 ]--- Kernel panic - not syncing: Attempted to kill the idle task! Rebooting in 1 seconds..aym...@vbox:~$ ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: help with kernel panics in task swapper on 460ex
On Fri, 2010-08-13 at 15:36 -0500, Ayman El-Khashab wrote: The exact details (though I don't think they are too useful are as follows. The one interesting item if I read it correctly, is that the CPU was trying to get instructions from c002 address. However, this board only has 512MB of memory so it seems that the address (if it is physical) isn't valid. Actually this is a perfectly valid virtual address. The kernel maps memory at 0xc000 (at least the first 768M of it, the rest is dynamically mapped in/out). Are there any tricks we can use to analyze this problem? Or is there any information we can collect to help pinpoint where this issue might lie? Well, xmon is your friend ... Ben. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 08/12] ptp: Added a brand new class driver for ptp clocks.
On Fri, Aug 13, 2010 at 3:34 AM, Richard Cochran richardcoch...@gmail.com wrote: On Tue, Jun 15, 2010 at 01:11:30PM -0600, Grant Likely wrote: On Tue, Jun 15, 2010 at 10:09 AM, Richard Cochran +static DEFINE_SPINLOCK(clocks_lock); /* protects 'clocks' */ Doesn't appear that clocks is manipulated at atomic context. Mutex instead? ... If the spinlock is changed to a mutex that is held for the entire function call, then the logic here can be simpler. Grant, I am working on another go at this patch series. Stupid question: The caller of ptp_clock_register(), which takes the clocks_lock, is always a module_init() function. Is this always a safe context in which to call mutex_lock? Yes, you can take mutexes in the module_init context. g. -- Grant Likely, B.Sc., P.Eng. Secret Lab Technologies Ltd. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[Resend][PATCHv3] Xilinx Virtex 4 FX Soft FPU support
This patch enables support for Xilinx Virtex 4 FX singe-float FPU. Changelog v2-v3: -Fixed whitespaces for SAVE_FPR/REST_FPR. -Changed description of MSR_AP bit. -Removed the stub for APU unavailable exception. Changelog v1-v2: -Added MSR_AP bit definition -Renamed CONFIG_XILINX_FPU to CONFIG_XILINX_SOFTFPU, moved it to 'Platform support' and made it Virtex4-FX-only. -Changed SAVE_FPR/REST_FPR definition style. Caveats: - Hard-float binaries which rely on in-kernel math emulation will give wrong results since they expect 64-bit double-precision instead of 32-bit single-precision numbers which Xilinx V4-FX Soft FPU produces. Signed-off-by: Sergey Temerkhanovtemerkha...@cifronik.ru diff -r 626de0d94469 arch/powerpc/include/asm/ppc_asm.h --- a/arch/powerpc/include/asm/ppc_asm.hWed May 26 15:33:32 2010 +0400 +++ b/arch/powerpc/include/asm/ppc_asm.hWed May 26 20:30:43 2010 +0400 @@ -85,13 +85,21 @@ #define REST_8GPRS(n, base)REST_4GPRS(n, base); REST_4GPRS(n+4, base) #define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base) + +#ifdef CONFIG_XILINX_SOFTFPU +#define SAVE_FPR(n, base) stfsn,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base) +#define REST_FPR(n, base) lfs n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base) +#else #define SAVE_FPR(n, base) stfdn,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base) +#define REST_FPR(n, base) lfd n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base) +#endif + #define SAVE_2FPRS(n, base)SAVE_FPR(n, base); SAVE_FPR(n+1, base) #define SAVE_4FPRS(n, base)SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base) #define SAVE_8FPRS(n, base)SAVE_4FPRS(n, base); SAVE_4FPRS(n+4, base) #define SAVE_16FPRS(n, base) SAVE_8FPRS(n, base); SAVE_8FPRS(n+8, base) #define SAVE_32FPRS(n, base) SAVE_16FPRS(n, base); SAVE_16FPRS(n+16, base) -#define REST_FPR(n, base) lfd n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base) + #define REST_2FPRS(n, base)REST_FPR(n, base); REST_FPR(n+1, base) #define REST_4FPRS(n, base)REST_2FPRS(n, base); REST_2FPRS(n+2, base) #define REST_8FPRS(n, base)REST_4FPRS(n, base); REST_4FPRS(n+4, base) diff -r 626de0d94469 arch/powerpc/include/asm/reg.h --- a/arch/powerpc/include/asm/reg.hWed May 26 15:33:32 2010 +0400 +++ b/arch/powerpc/include/asm/reg.hWed May 26 20:30:43 2010 +0400 @@ -30,6 +30,7 @@ #define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */ #define MSR_HV_LG 60 /* Hypervisor state */ #define MSR_VEC_LG 25 /* Enable AltiVec */ +#define MSR_AP_LG 25 /* Enable PPC405 APU */ #define MSR_VSX_LG 23 /* Enable VSX */ #define MSR_POW_LG 18 /* Enable Power Management */ #define MSR_WE_LG 18 /* Wait State Enable */ @@ -71,6 +72,7 @@ #define MSR_HV 0 #endif +#define MSR_AP __MASK(MSR_AP_LG) /* Enable PPC405 APU */ #define MSR_VEC__MASK(MSR_VEC_LG) /* Enable AltiVec */ #define MSR_VSX__MASK(MSR_VSX_LG) /* Enable VSX */ #define MSR_POW__MASK(MSR_POW_LG) /* Enable Power Management */ diff -r 626de0d94469 arch/powerpc/kernel/fpu.S --- a/arch/powerpc/kernel/fpu.S Wed May 26 15:33:32 2010 +0400 +++ b/arch/powerpc/kernel/fpu.S Wed May 26 20:30:43 2010 +0400 @@ -57,6 +57,9 @@ _GLOBAL(load_up_fpu) mfmsr r5 ori r5,r5,MSR_FP +#ifdef CONFIG_XILINX_SOFTFPU + orisr5,r5,msr...@h +#endif #ifdef CONFIG_VSX BEGIN_FTR_SECTION orisr5,r5,msr_...@h @@ -85,6 +88,9 @@ toreal(r5) PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5) li r10,MSR_FP|MSR_FE0|MSR_FE1 +#ifdef CONFIG_XILINX_SOFTFPU + orisr10,r10,msr...@h +#endif andcr4,r4,r10 /* disable FP for previous task */ PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5) 1: @@ -94,6 +100,9 @@ mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */ lwz r4,THREAD_FPEXC_MODE(r5) ori r9,r9,MSR_FP/* enable FP for current */ +#ifdef CONFIG_XILINX_SOFTFPU + orisr9,r9,msr...@h +#endif or r9,r9,r4 #else ld r4,PACACURRENT(r13) @@ -124,6 +133,9 @@ _GLOBAL(giveup_fpu) mfmsr r5 ori r5,r5,MSR_FP +#ifdef CONFIG_XILINX_SOFTFPU + orisr5,r5,msr...@h +#endif #ifdef CONFIG_VSX BEGIN_FTR_SECTION orisr5,r5,msr_...@h @@ -145,6 +157,9 @@ beq 1f PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5) li r3,MSR_FP|MSR_FE0|MSR_FE1 +#ifdef CONFIG_XILINX_SOFTFPU + orisr3,r3,msr...@h +#endif #ifdef CONFIG_VSX BEGIN_FTR_SECTION orisr3,r3,msr_...@h diff -r 626de0d94469 arch/powerpc/kernel/head_40x.S --- a/arch/powerpc/kernel/head_40x.SWed May 26 15:33:32 2010 +0400 +++ b/arch/powerpc/kernel/head_40x.SWed May 26 20:30:43 2010 +0400 @@ -420,7