* Re: AW: PowerPC PCI DMA issues (prefetch/coherency?)
From: Tom Burns @ 2009-09-11 13:51 UTC (permalink / raw)
To: benh; +Cc: Prodyut Hazarika, Andrea Zypchen, linuxppc-dev, azilkie, lebon
In-Reply-To: <1252634148.8566.11.camel@pasglop>
Hi Ben,
Benjamin Herrenschmidt wrote:
> On Wed, 2009-09-09 at 09:43 -0400, Tom Burns wrote:
>
>> Hi,
>>
>> With the default config for the Sequoia board on 2.6.24, calling
>> pci_dma_sync_sg_for_cpu() results in executing
>> invalidate_dcache_range() in arch/ppc/kernel/misc.S from __dma_sync().
>> This OOPses on PPC440 since it tries to call directly the assembly
>> instruction dcbi, which can only be executed in supervisor mode. We
>> tried that before resorting to manual cache line management with
>> usermode-safe assembly calls.
>>
>
> Wait a minute.... usermode ? You are doing all of that from userspace ?
> I don't understand the story here. You can't call all those kernel APIs
> form userspace in the first place, indeed... But then an IDE driver has
> nothing to do in userspace neither.
>
Sorry, I was referring to whether or not the CPU is in supervisor mode.
Our code is all in the kernel, not userspace :). I can see now from the
value of MSR at the time of the OOPS that the processor was in
supervisor mode, I missed that earlier. Looks like you're right about
the bad address, I will investigate.
Thanks,
Tom
> Cheers,
> Ben.
>
>
>> Regards,
>> Tom Burns
>> International Datacasting Corporation
>>
>> Mikhail Zolotaryov wrote:
>>
>>> Hi,
>>>
>>> Why manage cache lines manually, if appropriate code is a part of
>>> __dma_sync / dma_sync_single_for_device of DMA API ? (implies
>>> CONFIG_NOT_COHERENT_CACHE enabled, as default for Sequoia Board)
>>>
>>> Prodyut Hazarika wrote:
>>>
>>>> Hi Adam,
>>>>
>>>>
>>>>
>>>>> Yes, I am using the 440EPx (same as the sequoia board). Our
>>>>> ideDriver is DMA'ing blocks of 192-byte data over the PCI bus
>>>>>
>>>>>
>>>> (using
>>>>
>>>>
>>>>> the Sil0680A PCI-IDE bridge). Most of the DMA's (depending on timing)
>>>>> end up being partially corrupted when we try to parse the data in the
>>>>> virtual page. We have confirmed the data is good before the PCI-IDE
>>>>> bridge. We are creating two 8K pages and map them to physical DMA
>>>>>
>>>>>
>>>> memory
>>>>
>>>>
>>>>> using single-entry scatter/gather structs. When a DMA block is
>>>>> corrupted, we see a random portion of it (always a multiple of 16byte
>>>>> cache lines) is overwritten with old data from the last time the
>>>>>
>>>>>
>>>> buffer
>>>>
>>>>
>>>>> was used.
>>>>>
>>>> This looks like a cache coherency problem.
>>>> Can you ensure that the TLB entries corresponding to the DMA region has
>>>> the CacheInhibit bit set.
>>>> You will need a BDI connected to your system.
>>>>
>>>> Also, you will need to invalidate and flush the lines appropriately,
>>>> since in 440 cores,
>>>> L1Cache coherency is managed entirely by software.
>>>> Please look at drivers/net/ibm_newemac/mal.c and core.c for example on
>>>> how to do it.
>>>>
>>>> Thanks
>>>> Prodyut
>>>>
>>>> On Thu, 2009-09-03 at 13:27 -0700, Prodyut Hazarika wrote:
>>>>
>>>>
>>>>> Hi Adam,
>>>>>
>>>>>
>>>>>
>>>>>> Are you sure there is L2 cache on the 440?
>>>>>>
>>>>>>
>>>>> It depends on the SoC you are using. SoC like 460EX (Canyonlands
>>>>>
>>>>>
>>>> board)
>>>>
>>>>
>>>>> have L2Cache.
>>>>> It seems you are using a Sequoia board, which has a 440EPx SoC. 440EPx
>>>>> has a 440 cpu core, but no L2Cache.
>>>>> Could you please tell me which SoC you are using?
>>>>> You can also refer to the appropriate dts file to see if there is L2C.
>>>>> For example, in canyonlands.dts (460EX based board), we have the L2C
>>>>> entry.
>>>>> L2C0: l2c {
>>>>> ...
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>>> I am seeing this problem with our custom IDE driver which is based on
>>>>>>
>>>>>>
>>>>
>>>>
>>>>>> pretty old code. Our driver uses pci_alloc_consistent() to allocate
>>>>>>
>>>>>>
>>>> the
>>>>
>>>>
>>>>>> physical DMA memory and alloc_pages() to allocate a virtual page.
>>>>>> It then uses pci_map_sg() to map to a scatter/gather buffer.
>>>>>> Perhaps I should convert these to the DMA API calls as you suggest.
>>>>>>
>>>>>>
>>>>> Could you give more details on the consistency problem? It is a good
>>>>> idea to change to the new DMA APIs, but pci_alloc_consistent() should
>>>>> work too
>>>>>
>>>>> Thanks
>>>>> Prodyut
>>>>>
>>>>> On Thu, 2009-09-03 at 19:57 +1000, Benjamin Herrenschmidt wrote:
>>>>>
>>>>>
>>>>>> On Thu, 2009-09-03 at 09:05 +0100, Chris Pringle wrote:
>>>>>>
>>>>>>
>>>>>>> Hi Adam,
>>>>>>>
>>>>>>> If you have a look in include/asm-ppc/pgtable.h for the following
>>>>>>>
>>>>>>>
>>>>> section:
>>>>>
>>>>>
>>>>>>> #ifdef CONFIG_44x
>>>>>>> #define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED |
>>>>>>>
>>>>>>>
>>>>> _PAGE_GUARDED)
>>>>>
>>>>>
>>>>>>> #else
>>>>>>> #define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED)
>>>>>>> #endif
>>>>>>>
>>>>>>> Try adding _PAGE_COHERENT to the appropriate line above and see if
>>>>>>>
>>>>>>>
>>>>> that
>>>>>
>>>>>>> fixes your issue - this causes the 'M' bit to be set on the page
>>>>>>>
>>>>>>>
>>>>> which
>>>>>
>>>>>>> sure enforce cache coherency. If it doesn't, you'll need to check
>>>>>>>
>>>>>>>
>>>>> the
>>>>>
>>>>>>> 'M' bit isn't being masked out in head_44x.S (it was originally
>>>>>>>
>>>>>>>
>>>>> masked
>>>>>
>>>>>>> out on arch/powerpc, but was fixed in later kernels when the cache
>>>>>>>
>>>>>>>
>>>>
>>>>
>>>>>>> coherency issues with non-SMP systems were resolved).
>>>>>>>
>>>>>>>
>>>>>> I have some doubts about the usefulness of doing that for 4xx.
>>>>>>
>>>>>>
>>>> AFAIK,
>>>>
>>>>
>>>>>> the 440 core just ignores M.
>>>>>>
>>>>>> The problem lies probably elsewhere. Maybe the L2 cache coherency
>>>>>>
>>>>>>
>>>>> isn't
>>>>>
>>>>>
>>>>>> enabled or not working ?
>>>>>>
>>>>>> The L1 cache on 440 is simply not coherent, so drivers have to make
>>>>>>
>>>>>>
>>>>> sure
>>>>>
>>>>>
>>>>>> they use the appropriate DMA APIs which will do cache flushing when
>>>>>> needed.
>>>>>>
>>>>>> Adam, what driver is causing you that sort of problems ?
>>>>>>
>>>>>> Cheers,
>>>>>> Ben.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>
>> _______________________________________________
>> Linuxppc-dev mailing list
>> Linuxppc-dev@lists.ozlabs.org
>> https://lists.ozlabs.org/listinfo/linuxppc-dev
>>
>
>
>
>
^ permalink raw reply
* Re: [PATCH 01/10] Add support for GCC-4.5's __builtin_unreachable() to compiler.h
From: Michael Buesch @ 2009-09-11 14:32 UTC (permalink / raw)
To: linuxppc-dev
Cc: linux-mips, Heiko Carstens, linuxppc-dev, Paul Mackerras,
H. Peter Anvin, linux-s390, linux-am33-list, Helge Deller, x86,
David Daney, Ingo Molnar, Mike Frysinger, Ivan Kokshaysky,
linux390, Thomas Gleixner, Richard Henderson, Haavard Skinnemoen,
linux-parisc, linux-kernel, ralf, Kyle McMartin, linux-alpha,
Martin Schwidefsky, uclinux-dist-devel, akpm, Koichi Yasutake,
torvalds
In-Reply-To: <1252627011-2933-1-git-send-email-ddaney@caviumnetworks.com>
On Friday 11 September 2009 01:56:42 David Daney wrote:
> +/* Unreachable code */
> +#ifndef unreachable
> +# define unreachable() do { for (;;) ; } while (0)
> +#endif
# define unreachable() do { } while (1)
? :)
--
Greetings, Michael.
^ permalink raw reply
* Re: [PATCH 01/10] Add support for GCC-4.5's __builtin_unreachable() to compiler.h
From: David Daney @ 2009-09-11 15:58 UTC (permalink / raw)
To: Michael Buesch
Cc: linux-mips, Heiko Carstens, linuxppc-dev, Paul Mackerras,
H. Peter Anvin, linux-s390, linux-am33-list, Helge Deller, x86,
Ingo Molnar, Mike Frysinger, Ivan Kokshaysky, linux390,
Thomas Gleixner, Richard Henderson, Haavard Skinnemoen,
linux-parisc, torvalds, linux-kernel, ralf, Kyle McMartin,
linux-alpha, Martin Schwidefsky, uclinux-dist-devel, akpm,
Koichi Yasutake, linuxppc-dev
In-Reply-To: <200909111633.00665.mb@bu3sch.de>
Michael Buesch wrote:
> On Friday 11 September 2009 01:56:42 David Daney wrote:
>> +/* Unreachable code */
>> +#ifndef unreachable
>> +# define unreachable() do { for (;;) ; } while (0)
>> +#endif
>
> # define unreachable() do { } while (1)
>
> ? :)
Clearly I was not thinking clearly when I wrote that part. RTH noted
the same thing. I will fix it.
Thanks,
David Daney
^ permalink raw reply
* RE: AW: PowerPC PCI DMA issues (prefetch/coherency?)
From: Prodyut Hazarika @ 2009-09-11 16:05 UTC (permalink / raw)
To: tburns, lebon; +Cc: Andrea Zypchen, linuxppc-dev, azilkie
In-Reply-To: <4AA95941.20506@datacast.com>
> I tried, using our JTAG debugger (BDI3000), to pause operation after=20
> calling dma_alloc_coherent to examine the TLB entry for the memory=20
> returned by the call (which was just past=20
> CONFIG_CONSISTENT_START=3D0xff100000). The TLB list loaded at the =
time=20
> that I paused operation did not show a mapping for this area. I guess
> the kernel swaps TLB entries on the fly so it isn't limited to only 64
> entries? I will try to sleep in the same context as the=20
> dma_alloc_coherent call to try to catch the TLB entry while loaded to=20
> see if it has the I bit set.
> If that fails, any ideas?
Sleeping won't cause the entry to appear at the TLB.
After the dma_alloc call, try to deference the pointer returned.
As a result of the dereference, a DataTLB Miss will happen which will
result in
the appropriate entry put in TLB.
Then do a JTAG break right after the dereference, and you should be able
to see the TLB entry.
Thanks
Prodyut
Mikhail Zolotaryov wrote:
> Hi Tom,
>
> possible solution could be to use tasklet to perform DMA-related job=20
> (as in most cases DMA transfer is interrupt driven - makes sense).
>
>
> Tom Burns wrote:
>> Hi,
>>
>> With the default config for the Sequoia board on 2.6.24, calling=20
>> pci_dma_sync_sg_for_cpu() results in executing
>> invalidate_dcache_range() in arch/ppc/kernel/misc.S from=20
>> __dma_sync(). This OOPses on PPC440 since it tries to call directly=20
>> the assembly instruction dcbi, which can only be executed in=20
>> supervisor mode. We tried that before resorting to manual cache line
>> management with usermode-safe assembly calls.
>>
>> Regards,
>> Tom Burns
>> International Datacasting Corporation
>>
>> Mikhail Zolotaryov wrote:
>>> Hi,
>>>
>>> Why manage cache lines manually, if appropriate code is a part of=20
>>> __dma_sync / dma_sync_single_for_device of DMA API ? (implies=20
>>> CONFIG_NOT_COHERENT_CACHE enabled, as default for Sequoia Board)
>>>
>>> Prodyut Hazarika wrote:
>>>> Hi Adam,
>>>>
>>>> =20
>>>>> Yes, I am using the 440EPx (same as the sequoia board). Our=20
>>>>> ideDriver is DMA'ing blocks of 192-byte data over the PCI bus
>>>>> =20
>>>> (using
>>>> =20
>>>>> the Sil0680A PCI-IDE bridge). Most of the DMA's (depending on
timing)
>>>>> end up being partially corrupted when we try to parse the data in
the
>>>>> virtual page. We have confirmed the data is good before the
PCI-IDE
>>>>> bridge. We are creating two 8K pages and map them to physical DMA
>>>>> =20
>>>> memory
>>>> =20
>>>>> using single-entry scatter/gather structs. When a DMA block is
>>>>> corrupted, we see a random portion of it (always a multiple of
16byte
>>>>> cache lines) is overwritten with old data from the last time the
>>>>> =20
>>>> buffer
>>>> =20
>>>>> was used. =20
>>>>
>>>> This looks like a cache coherency problem.
>>>> Can you ensure that the TLB entries corresponding to the DMA region
>>>> has
>>>> the CacheInhibit bit set.
>>>> You will need a BDI connected to your system.
>>>>
>>>> Also, you will need to invalidate and flush the lines
appropriately,
>>>> since in 440 cores,
>>>> L1Cache coherency is managed entirely by software.
>>>> Please look at drivers/net/ibm_newemac/mal.c and core.c for example
on
>>>> how to do it.
>>>>
>>>> Thanks
>>>> Prodyut
>>>>
>>>> On Thu, 2009-09-03 at 13:27 -0700, Prodyut Hazarika wrote:
>>>> =20
>>>>> Hi Adam,
>>>>>
>>>>> =20
>>>>>> Are you sure there is L2 cache on the 440?
>>>>>> =20
>>>>> It depends on the SoC you are using. SoC like 460EX (Canyonlands
>>>>> =20
>>>> board)
>>>> =20
>>>>> have L2Cache.
>>>>> It seems you are using a Sequoia board, which has a 440EPx SoC.=20
>>>>> 440EPx
>>>>> has a 440 cpu core, but no L2Cache.
>>>>> Could you please tell me which SoC you are using?
>>>>> You can also refer to the appropriate dts file to see if there is=20
>>>>> L2C.
>>>>> For example, in canyonlands.dts (460EX based board), we have the
L2C
>>>>> entry.
>>>>> L2C0: l2c {
>>>>> ...
>>>>> }
>>>>>
>>>>> =20
>>>>>> I am seeing this problem with our custom IDE driver which is=20
>>>>>> based on
>>>>>> =20
>>>>
>>>> =20
>>>>>> pretty old code. Our driver uses pci_alloc_consistent() to
allocate
>>>>>> =20
>>>> the
>>>> =20
>>>>>> physical DMA memory and alloc_pages() to allocate a virtual page.
>>>>>> It then uses pci_map_sg() to map to a scatter/gather buffer.=20
>>>>>> Perhaps I should convert these to the DMA API calls as you
suggest.
>>>>>> =20
>>>>> Could you give more details on the consistency problem? It is a
good
>>>>> idea to change to the new DMA APIs, but pci_alloc_consistent()
should
>>>>> work too
>>>>>
>>>>> Thanks
>>>>> Prodyut On Thu, 2009-09-03 at 19:57 +1000, Benjamin Herrenschmidt
>>>>> wrote:
>>>>> =20
>>>>>> On Thu, 2009-09-03 at 09:05 +0100, Chris Pringle wrote:
>>>>>> =20
>>>>>>> Hi Adam,
>>>>>>>
>>>>>>> If you have a look in include/asm-ppc/pgtable.h for the
following
>>>>>>> =20
>>>>> section:
>>>>> =20
>>>>>>> #ifdef CONFIG_44x
>>>>>>> #define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED |
>>>>>>> =20
>>>>> _PAGE_GUARDED)
>>>>> =20
>>>>>>> #else
>>>>>>> #define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED)
>>>>>>> #endif
>>>>>>>
>>>>>>> Try adding _PAGE_COHERENT to the appropriate line above and see
if
>>>>>>> =20
>>>>> that =20
>>>>>>> fixes your issue - this causes the 'M' bit to be set on the page
>>>>>>> =20
>>>>> which =20
>>>>>>> sure enforce cache coherency. If it doesn't, you'll need to
check
>>>>>>> =20
>>>>> the =20
>>>>>>> 'M' bit isn't being masked out in head_44x.S (it was originally
>>>>>>> =20
>>>>> masked =20
>>>>>>> out on arch/powerpc, but was fixed in later kernels when the
cache
>>>>>>> =20
>>>>
>>>> =20
>>>>>>> coherency issues with non-SMP systems were resolved).
>>>>>>> =20
>>>>>> I have some doubts about the usefulness of doing that for 4xx.
>>>>>> =20
>>>> AFAIK,
>>>> =20
>>>>>> the 440 core just ignores M.
>>>>>>
>>>>>> The problem lies probably elsewhere. Maybe the L2 cache coherency
>>>>>> =20
>>>>> isn't
>>>>> =20
>>>>>> enabled or not working ?
>>>>>>
>>>>>> The L1 cache on 440 is simply not coherent, so drivers have to
make
>>>>>> =20
>>>>> sure
>>>>> =20
>>>>>> they use the appropriate DMA APIs which will do cache flushing
when
>>>>>> needed.
>>>>>>
>>>>>> Adam, what driver is causing you that sort of problems ?
>>>>>>
>>>>>> Cheers,
>>>>>> Ben.
>>>>>>
>>>>>>
>>>>>> =20
>>>
>>>
>>
>>
>
>
--------------------------------------------------------
CONFIDENTIALITY NOTICE: This e-mail message, including any attachments, =
is for the sole use of the intended recipient(s) and contains =
information that is confidential and proprietary to AppliedMicro =
Corporation or its subsidiaries. It is to be used solely for the purpose =
of furthering the parties' business relationship. All unauthorized =
review, use, disclosure or distribution is prohibited. If you are not =
the intended recipient, please contact the sender by reply e-mail and =
destroy all copies of the original message.
^ permalink raw reply
* Re: [FTRACE] Enabling function_graph causes OOPS
From: Steven Rostedt @ 2009-09-11 18:05 UTC (permalink / raw)
To: Sachin Sant; +Cc: linuxppc-dev
In-Reply-To: <4AA88F7D.5030302@in.ibm.com>
On Thu, 2009-09-10 at 11:02 +0530, Sachin Sant wrote:
> Steven Rostedt wrote:
> > Ah, seems the bug happens to be in the module handling. Does the call
> > back always have .mod_return_to_handler?
> >
> Yes. Every time it ends up in .mod_return_to_handler
Hmm, I still can not reproduce it, and I've confirmed that I
hit .mod_return_to_handler too.
Could you apply the below patch. This wont fix anything, but it will at
least make the trace back show the real functions that were called.
Thanks,
-- Steve
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 892a9f2..a2e1b15 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1014,9 +1014,13 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
int curr_frame = current->curr_ret_stack;
extern void return_to_handler(void);
- unsigned long addr = (unsigned long)return_to_handler;
+ unsigned long rth = (unsigned long)return_to_handler;
+ unsigned long mrth = -1;
#ifdef CONFIG_PPC64
- addr = *(unsigned long*)addr;
+ extern void mod_return_to_handler(void);
+ rth = *(unsigned long *)rth;
+ mrth = (unsigned long)mod_return_to_handler;
+ mrth = *(unsigned long *)mrth;
#endif
#endif
@@ -1042,7 +1046,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
if (!firstframe || ip != lr) {
printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip);
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
- if (ip == addr && curr_frame >= 0) {
+ if ((ip == rth || ip == mrth) && curr_frame >= 0) {
printk(" (%pS)",
(void *)current->ret_stack[curr_frame].ret);
curr_frame--;
^ permalink raw reply related
* Re: [PATCH 1/3] phy/marvell: Make non-aneg speed/duplex forcing work for 88E1111 PHYs
From: David Miller @ 2009-09-11 19:19 UTC (permalink / raw)
To: avorontsov; +Cc: netdev, linuxppc-dev, afleming, timur
In-Reply-To: <20090910020130.GA31083@oksana.dev.rtsoft.ru>
From: Anton Vorontsov <avorontsov@ru.mvista.com>
Date: Thu, 10 Sep 2009 06:01:30 +0400
> According to specs, when auto-negotiation is disabled, Marvell PHYs need
> a software reset after changing speed/duplex forcing bits. Otherwise,
> the modified bits have no effect.
>
> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Applied.
^ permalink raw reply
* Re: [PATCH 2/3] ucc_geth: Rearrange some code to avoid forward declarations
From: David Miller @ 2009-09-11 19:19 UTC (permalink / raw)
To: timur; +Cc: netdev, linuxppc-dev, afleming
In-Reply-To: <4AA8F880.1000300@freescale.com>
From: Timur Tabi <timur@freescale.com>
Date: Thu, 10 Sep 2009 08:00:48 -0500
> Anton Vorontsov wrote:
>> We'll need ugeth_disable() and ugeth_enable() calls earlier in the
>> file, so rearrange some code to avoid forward declarations.
>>
>> The patch doesn't contain any functional changes.
>>
>> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
>
> Acked-by: Timur Tabi <timur@freescale.com>
Applied.
^ permalink raw reply
* Re: [PATCH v3 3/3] ucc_geth: Fix hangs after switching from full to half duplex
From: David Miller @ 2009-09-11 19:19 UTC (permalink / raw)
To: avorontsov; +Cc: scottwood, netdev, afleming, timur, linuxppc-dev
In-Reply-To: <20090910214812.GA30564@oksana.dev.rtsoft.ru>
From: Anton Vorontsov <avorontsov@ru.mvista.com>
Date: Fri, 11 Sep 2009 01:48:12 +0400
> MPC8360 QE UCC ethernet controllers hang when changing link duplex
> under a load (a bit of NFS activity is enough).
>
> PHY: mdio@e0102120:00 - Link is Up - 1000/Full
> sh-3.00# ethtool -s eth0 speed 100 duplex half autoneg off
> PHY: mdio@e0102120:00 - Link is Down
> PHY: mdio@e0102120:00 - Link is Up - 100/Half
> NETDEV WATCHDOG: eth0 (ucc_geth): transmit queue 0 timed out
> ------------[ cut here ]------------
> Badness at c01fcbd0 [verbose debug info unavailable]
> NIP: c01fcbd0 LR: c01fcbd0 CTR: c0194e44
> ...
>
> The cure is to disable the controller before changing speed/duplex
> and enable it afterwards.
>
> Though, disabling the controller might take quite a while, so we
> better not grab any spinlocks in adjust_link(). Instead, we quiesce
> the driver's activity, and only then disable the controller.
>
> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Applied.
^ permalink raw reply
* Re: [Bugme-new] [Bug 14148] New: kernel panic: do_wp_page assert_pte_locked failed when DEBUG_VM
From: Andrew Morton @ 2009-09-11 20:09 UTC (permalink / raw)
To: linux-mm, linuxppc-dev; +Cc: wangbj, bugzilla-daemon, bugme-daemon
In-Reply-To: <bug-14148-10286@http.bugzilla.kernel.org/>
(switched to email. Please respond via emailed reply-to-all, not via the
bugzilla web interface).
On Wed, 9 Sep 2009 15:09:15 GMT
bugzilla-daemon@bugzilla.kernel.org wrote:
> http://bugzilla.kernel.org/show_bug.cgi?id=14148
>
> Summary: kernel panic: do_wp_page assert_pte_locked failed when
> DEBUG_VM
> Product: Platform Specific/Hardware
> Version: 2.5
> Kernel Version: 2.6.31-rc3, 2.6.31-rc9-git2
> Platform: All
> OS/Version: Linux
> Tree: Mainline
> Status: NEW
> Severity: normal
> Priority: P1
> Component: PPC-32
> AssignedTo: platform_ppc-32@kernel-bugs.osdl.org
> ReportedBy: wangbj@lzu.edu.cn
> Regression: Yes
>
>
> Created an attachment (id=23049)
> --> (http://bugzilla.kernel.org/attachment.cgi?id=23049)
> problematic config file for mpc8548cds
>
> powerpc mpc8548cds (I only have this board on hand) will kernel panic if
> DEBUG_VM (kernel hacking) is enabled due to assertion failed in function
> do_wp_page(). I think it highly possible for other ppc boards like 44x have the
> same problem too, but I don't have the board.
>
> here is the full log from power up (after u-boot). and the attachment is
> related .config, NOTE the kernel boot successfully if CONFIG_DEBUG_VM is not
> enabled.
>
> host system is gentoo, the gcc (powerpc-unknown-linux-gnu-gcc) is build by
> gentoo crossdev, version 4.4.1, (cross) glibc is 2.9, (cross) binutils is
> 2.19.1, (cross) kernel headers is 2.6.30. target (mpc8548cds) root filesystem
> is also gentoo (200907xx, extracted from stage3 tarball).
>
> I have running similar test on x86 using qemu (0.10.6, +kvm), the result seems
> OK, especially x86 pass all lock api test suite.
First question:
> [10611.192802] ------------[ cut here ]------------
> [10611.197409] Kernel BUG at c0014d70 [verbose debug info unavailable]
Why did we not get the file-n-line? That's iritating.
Oh, CONFIG_DEBUG_BUGVERBOSE=n. Don't do that. We should make that thing
harder to get at, to stop people shooting our feet off.
> [10611.203660] Oops: Exception in kernel mode, sig: 5 [#1]
> [10611.208866] PREEMPT MPC85xx CDS
> [10611.211997] Modules linked in:
> [10611.215040] NIP: c0014d70 LR: c0014eb4 CTR: 00000002
> [10611.219988] REGS: cf82db40 TRAP: 0700 Not tainted (2.6.31-rc3)
> [10611.226061] MSR: 00029000 <EE,ME,CE> CR: 88448044 XER: 20000000
> [10611.232162] TASK = cf828000[1] 'init' THREAD: cf82c000
> [10611.237108] GPR00: 00000001 cf82dbf0 cf828000 cf9781c0 bf8031d8 cf9f400c
> 0057902f 00000001
> [10611.245471] GPR08: cf978200 cf9f4000 00000002 00000000 28448042 1001b0b0
> 00000001 cf88ee00
> [10611.253833] GPR16: c05c0000 bf8031d8 00000002 10000000 48000000 00000001
> 00000008 c05ecf20
> [10611.262196] GPR24: 0057902b 0057902f cf82c000 00000000 cf9f400c 00000001
> bf8031d8 cf98b000
> [10611.270749] NIP [c0014d70] assert_pte_locked+0x3c/0x44
> [10611.275872] LR [c0014eb4] ptep_set_access_flags+0xa8/0xf4
> [10611.281252] Call Trace:
> [10611.283687] [cf82dbf0] [bf8031d8] 0xbf8031d8 (unreliable)
> [10611.289079] [cf82dc10] [c008e87c] do_wp_page+0xf8/0x82c
> [10611.294292] [cf82dc60] [c0014770] do_page_fault+0x2c0/0x480
> [10611.299851] [cf82dd10] [c0011078] handle_page_fault+0xc/0x80
> [10611.305504] [cf82ddd0] [c00f2b4c] load_elf_binary+0x8a8/0x121c
> [10611.311325] [cf82de50] [c00af418] search_binary_handler+0x144/0x37c
> [10611.317578] [cf82dea0] [c00b0bc8] do_execve+0x270/0x2c8
> [10611.322794] [cf82dee0] [c0008754] sys_execve+0x68/0xa4
> [10611.327919] [cf82df00] [c0010c38] ret_from_syscall+0x0/0x3c
> [10611.333482] [cf82dfc0] [c00b9350] sys_dup+0x38/0x78
> [10611.338349] [cf82dfd0] [c0002030] init_post+0x94/0x108
> [10611.343478] [cf82dfe0] [c054c234] kernel_init+0x114/0x130
> [10611.348865] [cf82dff0] [c00109b8] kernel_thread+0x4c/0x68
> [10611.354249] Instruction dump:
> [10611.357206] 4d9e0020 38000000 0f000000 0f000000 81230024 5480653a 7c09002e
> 54090027
> [10611.364959] 7c000026 54001ffe 0f000000 38000001 <0f000000> 4e800020 7c0802a6
> 9421fff0
> [10611.372887] ---[ end trace 0cda2392272f221a ]---
So do_wp_page() called ptep_set_access_flags(). If CONFIG_DEBUG_VM=y,
powerpc's ptep_set_access_flags() will call
arch/powerpc/mm/pgtable.c:assert_pte_locked(). Because of the lack of
file-n-line info it is unclear which of those many assertions
triggered. It looks like BUG_ON(!pmd_present(*pmd)). Perhaps.
Please set CONFIG_DEBUG_BUGVERBOSE=y in your .config and then tell us
(via emailed reply-to-all) which line in arch/powerpc/mm/pgtable.c
triggered the BUG. Please actually quote that line, or tell us exactly
which kernel version you're using so we can see which line it was in
the source code.
Thanks.
^ permalink raw reply
* [PATCH 0/5] kernel handling of dynamic logical partitioning
From: Nathan Fontenot @ 2009-09-11 20:56 UTC (permalink / raw)
To: linuxppc-dev; +Cc: lkml
The Dynamic Logical Partitioning (DLPAR) capabilities of the powerpc pseries
platform allows for the addition and removal of resources (i.e. cpus,
memory, pci devices) from a partition. The removal of a resource involves
removing the resource's node from the device tree and then returning the
resource to firmware via the rtas set-indicator call. To add a resource, it
is first obtained from firmware via the rtas set-indicator call and then a
new device tree node is created using the ibm,configure-coinnector rtas call
and added to the device tree.
The following set of patches implements the needed infrastructure to have the
kernel handle the DLPAR addition and removal of memory and cpus (other
DLPAR'able items to follow in future patches). The framework for this is
to create a set of probe/release sysfs files in pseries that will add or
remove the cpu or memory to the system.
The majority of the code is powerpc/pseries specific except for PATCH 3/5, so
I am cc'ing lkml.
Patches include in this set:
1/5 - DLPAR infracstructure for powerpc/pseries platform.
2/5 - Move the of_drconf_cell struct to prom.h
3/5 - Export the memory sysdev class
4/5 - Memory DLPAR handling
5/5 - CPU DLPAR handling
-Nathan Fontenot
^ permalink raw reply
* [PATCH 0/5] kernel handling of dynamic logical partitioning
From: Nathan Fontenot @ 2009-09-11 21:08 UTC (permalink / raw)
To: linuxppc-dev; +Cc: linux-kernel
The Dynamic Logical Partitioning (DLPAR) capabilities of the powerpc pseries
platform allows for the addition and removal of resources (i.e. cpus,
memory, pci devices) from a partition. The removal of a resource involves
removing the resource's node from the device tree and then returning the
resource to firmware via the rtas set-indicator call. To add a resource, it
is first obtained from firmware via the rtas set-indicator call and then a
new device tree node is created using the ibm,configure-connector rtas call
and added to the device tree.
The following set of patches implements the needed infrastructure to have the
kernel handle the DLPAR addition and removal of memory and cpus (other
DLPAR'able items to follow in future patches). The framework for this is
to create a set of probe/release sysfs files in pseries that will add or
remove the cpu or memory to the system.
The majority of the code is powerpc/pseries specific except for PATCH 3/5, so
I am cc'ing lkml.
Patches include in this set:
1/5 - DLPAR infrastructure for powerpc/pseries platform.
2/5 - Move the of_drconf_cell struct to prom.h
3/5 - Export the memory sysdev class
4/5 - Memory DLPAR handling
5/5 - CPU DLPAR handling
Please pardon the re-send, I borked the lkml address on cc the first time.
-Nathan Fontenot
^ permalink raw reply
* Re: [PATCH 0/5] kernel handling of dynamic logical partitioning
From: Nathan Fontenot @ 2009-09-11 21:09 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <4AAAB99B.2080503@austin.ibm.com>
Disregard. Re-sending with corrections.
-Nathan
Nathan Fontenot wrote:
> The Dynamic Logical Partitioning (DLPAR) capabilities of the powerpc
> pseries
> platform allows for the addition and removal of resources (i.e. cpus,
> memory, pci devices) from a partition. The removal of a resource involves
> removing the resource's node from the device tree and then returning the
> resource to firmware via the rtas set-indicator call. To add a
> resource, it
> is first obtained from firmware via the rtas set-indicator call and then a
> new device tree node is created using the ibm,configure-coinnector rtas
> call
> and added to the device tree.
>
> The following set of patches implements the needed infrastructure to
> have the
> kernel handle the DLPAR addition and removal of memory and cpus (other
> DLPAR'able items to follow in future patches). The framework for this is
> to create a set of probe/release sysfs files in pseries that will add or
> remove the cpu or memory to the system.
>
> The majority of the code is powerpc/pseries specific except for PATCH
> 3/5, so
> I am cc'ing lkml.
>
> Patches include in this set:
> 1/5 - DLPAR infracstructure for powerpc/pseries platform.
> 2/5 - Move the of_drconf_cell struct to prom.h
> 3/5 - Export the memory sysdev class
> 4/5 - Memory DLPAR handling
> 5/5 - CPU DLPAR handling
>
> -Nathan Fontenot
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
^ permalink raw reply
* [PATCH 1/5] dynamic logical partitioning infrastructure
From: Nathan Fontenot @ 2009-09-11 21:10 UTC (permalink / raw)
To: linuxppc-dev; +Cc: linux-kernel
In-Reply-To: <4AAABC55.4070207@austin.ibm.com>
This patch provides the kernel DLPAR infrastructure in a new filed named
dlpar.c. The functionality provided is for acquiring and releasing a
resource from firmware and the parsing of information returned from the
ibm,configure-connector rtas call. Additionally this exports the
pSeries reconfiguration notifier chain so that it can be invoked when
device tree updates are made.
Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com>
---
Index: powerpc/arch/powerpc/platforms/pseries/dlpar.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ powerpc/arch/powerpc/platforms/pseries/dlpar.c 2009-09-11 12:51:52.000000000 -0500
@@ -0,0 +1,416 @@
+/*
+ * dlpar.c - support for dynamic reconfiguration (including PCI
+ * Hotplug and Dynamic Logical Partitioning on RPA platforms).
+ *
+ * Copyright (C) 2009 Nathan Fontenot
+ * Copyright (C) 2009 IBM Corporation
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/kref.h>
+#include <linux/notifier.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/uaccess.h>
+#include <asm/rtas.h>
+#include <asm/pSeries_reconfig.h>
+
+#define CFG_CONN_WORK_SIZE 4096
+static char workarea[CFG_CONN_WORK_SIZE];
+spinlock_t workarea_lock;
+
+static struct property *parse_cc_property(char *workarea)
+{
+ struct property *prop;
+ u32 *work_ints;
+ char *name;
+ char *value;
+
+ prop = kzalloc(sizeof(*prop), GFP_KERNEL);
+ if (!prop)
+ return NULL;
+
+ work_ints = (u32 *)workarea;
+ name = workarea + work_ints[2];
+ prop->name = kzalloc(strlen(name) + 1, GFP_KERNEL);
+ if (!prop->name) {
+ kfree(prop);
+ return NULL;
+ }
+
+ strcpy(prop->name, name);
+
+ prop->length = work_ints[3];
+ value = workarea + work_ints[4];
+ prop->value = kzalloc(prop->length, GFP_KERNEL);
+ if (!prop->value) {
+ kfree(prop->name);
+ kfree(prop);
+ return NULL;
+ }
+
+ memcpy(prop->value, value, prop->length);
+ return prop;
+}
+
+static void free_cc_property(struct property *prop)
+{
+ if (prop->name)
+ kfree(prop->name);
+ if (prop->value)
+ kfree(prop->value);
+
+ kfree(prop);
+}
+
+static struct device_node *parse_cc_node(char *work_area)
+{
+ struct device_node *dn;
+ u32 *work_ints;
+ char *name;
+
+ dn = kzalloc(sizeof(*dn), GFP_KERNEL);
+ if (!dn)
+ return NULL;
+
+ work_ints = (u32 *)work_area;
+ name = work_area + work_ints[2];
+ dn->full_name = kzalloc(strlen(name) + 1, GFP_KERNEL);
+ if (!dn->full_name) {
+ kfree(dn);
+ return NULL;
+ }
+
+ strcpy(dn->full_name, name);
+ return dn;
+}
+
+static void free_one_cc_node(struct device_node *dn)
+{
+ struct property *prop;
+
+ while (dn->properties) {
+ prop = dn->properties;
+ dn->properties = prop->next;
+ free_cc_property(prop);
+ }
+
+ if (dn->full_name)
+ kfree(dn->full_name);
+
+ kfree(dn);
+}
+
+static void free_cc_nodes(struct device_node *dn)
+{
+ if (dn->child)
+ free_cc_nodes(dn->child);
+
+ if (dn->sibling)
+ free_cc_nodes(dn->sibling);
+
+ free_one_cc_node(dn);
+}
+
+#define NEXT_SIBLING 1
+#define NEXT_CHILD 2
+#define NEXT_PROPERTY 3
+#define PREV_PARENT 4
+#define MORE_MEMORY 5
+#define CALL_AGAIN -2
+#define ERR_CFG_USE -9003
+
+struct device_node *configure_connector(u32 drc_index)
+{
+ struct device_node *dn;
+ struct device_node *first_dn = NULL;
+ struct device_node *last_dn = NULL;
+ struct property *property;
+ struct property *last_property = NULL;
+ u32 *work_int;
+ int cc_token;
+ int rc;
+
+ cc_token = rtas_token("ibm,configure-connector");
+ if (cc_token == RTAS_UNKNOWN_SERVICE)
+ return NULL;
+
+ spin_lock(&workarea_lock);
+
+ work_int = (u32 *)&workarea[0];
+ work_int[0] = drc_index;
+ work_int[1] = 0;
+
+ rc = rtas_call(cc_token, 2, 1, NULL, workarea, NULL);
+ while (rc) {
+ switch (rc) {
+ case NEXT_SIBLING:
+ dn = parse_cc_node(workarea);
+ if (!dn)
+ goto cc_error;
+
+ dn->parent = last_dn->parent;
+ last_dn->sibling = dn;
+ last_dn = dn;
+ break;
+
+ case NEXT_CHILD:
+ dn = parse_cc_node(workarea);
+ if (!dn)
+ goto cc_error;
+
+ if (!first_dn)
+ first_dn = dn;
+ else {
+ dn->parent = last_dn;
+ if (last_dn)
+ last_dn->child = dn;
+ }
+
+ last_dn = dn;
+ break;
+
+ case NEXT_PROPERTY:
+ property = parse_cc_property(workarea);
+ if (!property)
+ goto cc_error;
+
+ if (!last_dn->properties)
+ last_dn->properties = property;
+ else
+ last_property->next = property;
+
+ last_property = property;
+ break;
+
+ case PREV_PARENT:
+ last_dn = last_dn->parent;
+ break;
+
+ case CALL_AGAIN:
+ break;
+
+ case MORE_MEMORY:
+ case ERR_CFG_USE:
+ default:
+ printk(KERN_ERR "Unexpected Error (%d) "
+ "returned from configure-connector\n",
+ rc);
+ goto cc_error;
+ }
+
+ rc = rtas_call(cc_token, 2, 1, NULL, workarea, NULL);
+ }
+
+ spin_unlock(&workarea_lock);
+ return first_dn;
+
+cc_error:
+ spin_unlock(&workarea_lock);
+
+ if (first_dn)
+ free_cc_nodes(first_dn);
+
+ return NULL;
+}
+
+static struct device_node *derive_parent(const char *path)
+{
+ struct device_node *parent;
+ char parent_path[128];
+ int parent_path_len;
+
+ parent_path_len = strrchr(path, '/') - path + 1;
+ strlcpy(parent_path, path, parent_path_len);
+
+ parent = of_find_node_by_path(parent_path);
+
+ return parent;
+}
+
+static int add_one_node(struct device_node *dn)
+{
+ struct proc_dir_entry *ent;
+ int rc;
+
+ of_node_set_flag(dn, OF_DYNAMIC);
+ kref_init(&dn->kref);
+ dn->parent = derive_parent(dn->full_name);
+
+ rc = blocking_notifier_call_chain(&pSeries_reconfig_chain,
+ PSERIES_RECONFIG_ADD, dn);
+ if (rc == NOTIFY_BAD) {
+ printk(KERN_ERR "Failed to add device node %s\n",
+ dn->full_name);
+ return -ENOMEM; /* For now, safe to assume kmalloc failure */
+ }
+
+ of_attach_node(dn);
+
+#ifdef CONFIG_PROC_DEVICETREE
+ ent = proc_mkdir(strrchr(dn->full_name, '/') + 1, dn->parent->pde);
+ if (ent)
+ proc_device_tree_add_node(dn, ent);
+#endif
+
+ of_node_put(dn->parent);
+ return 0;
+}
+
+int add_device_tree_nodes(struct device_node *dn)
+{
+ struct device_node *child = dn->child;
+ struct device_node *sibling = dn->sibling;
+ int rc;
+
+ dn->child = NULL;
+ dn->sibling = NULL;
+ dn->parent = NULL;
+
+ rc = add_one_node(dn);
+ if (rc)
+ return rc;
+
+ if (child) {
+ rc = add_device_tree_nodes(child);
+ if (rc)
+ return rc;
+ }
+
+ if (sibling)
+ rc = add_device_tree_nodes(sibling);
+
+ return rc;
+}
+
+static int remove_one_node(struct device_node *dn)
+{
+ struct device_node *parent = dn->parent;
+ struct property *prop = dn->properties;
+
+#ifdef CONFIG_PROC_DEVICETREE
+ while (prop) {
+ remove_proc_entry(prop->name, dn->pde);
+ prop = prop->next;
+ }
+
+ if (dn->pde)
+ remove_proc_entry(dn->pde->name, parent->pde);
+#endif
+
+ blocking_notifier_call_chain(&pSeries_reconfig_chain,
+ PSERIES_RECONFIG_REMOVE, dn);
+ of_detach_node(dn);
+
+ of_node_put(parent);
+ of_node_put(dn); /* Must decrement the refcount */
+
+ return 0;
+}
+
+static int _remove_device_tree_nodes(struct device_node *dn)
+{
+ int rc;
+
+ if (dn->child) {
+ rc = _remove_device_tree_nodes(dn->child);
+ if (rc)
+ return rc;
+ }
+
+ if (dn->sibling) {
+ rc = _remove_device_tree_nodes(dn->sibling);
+ if (rc)
+ return rc;
+ }
+
+ rc = remove_one_node(dn);
+ return rc;
+}
+
+int remove_device_tree_nodes(struct device_node *dn)
+{
+ int rc;
+
+ if (dn->child) {
+ rc = _remove_device_tree_nodes(dn->child);
+ if (rc)
+ return rc;
+ }
+
+ rc = remove_one_node(dn);
+ return rc;
+}
+
+#define DR_ENTITY_SENSE 9003
+#define DR_ENTITY_PRESENT 1
+#define DR_ENTITY_UNUSABLE 2
+#define ALLOCATION_STATE 9003
+#define ALLOC_UNUSABLE 0
+#define ALLOC_USABLE 1
+#define ISOLATION_STATE 9001
+#define ISOLATE 0
+#define UNISOLATE 1
+
+int acquire_drc(u32 drc_index)
+{
+ int dr_status, rc;
+
+ rc = rtas_call(rtas_token("get-sensor-state"), 2, 2, &dr_status,
+ DR_ENTITY_SENSE, drc_index);
+ if (rc || dr_status != DR_ENTITY_UNUSABLE)
+ return -1;
+
+ rc = rtas_set_indicator(ALLOCATION_STATE, drc_index, ALLOC_USABLE);
+ if (rc)
+ return -1;
+
+ rc = rtas_set_indicator(ISOLATION_STATE, drc_index, UNISOLATE);
+ if (rc) {
+ rtas_set_indicator(ALLOCATION_STATE, drc_index, ALLOC_UNUSABLE);
+ return -1;
+ }
+
+ return 0;
+}
+
+int release_drc(u32 drc_index)
+{
+ int dr_status, rc;
+
+ rc = rtas_call(rtas_token("get-sensor-state"), 2, 2, &dr_status,
+ DR_ENTITY_SENSE, drc_index);
+ if (rc || dr_status != DR_ENTITY_PRESENT)
+ return -1;
+
+ rc = rtas_set_indicator(ISOLATION_STATE, drc_index, ISOLATE);
+ if (rc)
+ return -1;
+
+ rc = rtas_set_indicator(ALLOCATION_STATE, drc_index, ALLOC_UNUSABLE);
+ if (rc) {
+ rtas_set_indicator(ISOLATION_STATE, drc_index, UNISOLATE);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int pseries_dlpar_init(void)
+{
+ spin_lock_init(&workarea_lock);
+
+ if (!machine_is(pseries))
+ return 0;
+
+ return 0;
+}
+__initcall(pseries_dlpar_init);
Index: powerpc/arch/powerpc/platforms/pseries/Makefile
===================================================================
--- powerpc.orig/arch/powerpc/platforms/pseries/Makefile 2009-09-11 12:43:39.000000000 -0500
+++ powerpc/arch/powerpc/platforms/pseries/Makefile 2009-09-11 12:51:52.000000000 -0500
@@ -8,7 +8,7 @@
obj-y := lpar.o hvCall.o nvram.o reconfig.o \
setup.o iommu.o ras.o rtasd.o \
- firmware.o power.o
+ firmware.o power.o dlpar.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_XICS) += xics.o
obj-$(CONFIG_SCANLOG) += scanlog.o
Index: powerpc/arch/powerpc/include/asm/pSeries_reconfig.h
===================================================================
--- powerpc.orig/arch/powerpc/include/asm/pSeries_reconfig.h 2009-09-11 12:43:39.000000000 -0500
+++ powerpc/arch/powerpc/include/asm/pSeries_reconfig.h 2009-09-11 12:51:52.000000000 -0500
@@ -17,6 +17,7 @@
#ifdef CONFIG_PPC_PSERIES
extern int pSeries_reconfig_notifier_register(struct notifier_block *);
extern void pSeries_reconfig_notifier_unregister(struct notifier_block *);
+extern struct blocking_notifier_head pSeries_reconfig_chain;
#else /* !CONFIG_PPC_PSERIES */
static inline int pSeries_reconfig_notifier_register(struct notifier_block *nb)
{
Index: powerpc/arch/powerpc/platforms/pseries/reconfig.c
===================================================================
--- powerpc.orig/arch/powerpc/platforms/pseries/reconfig.c 2009-09-11 12:43:39.000000000 -0500
+++ powerpc/arch/powerpc/platforms/pseries/reconfig.c 2009-09-11 12:51:52.000000000 -0500
@@ -95,7 +95,7 @@
return parent;
}
-static BLOCKING_NOTIFIER_HEAD(pSeries_reconfig_chain);
+struct blocking_notifier_head pSeries_reconfig_chain = BLOCKING_NOTIFIER_INIT(pSeries_reconfig_chain);
int pSeries_reconfig_notifier_register(struct notifier_block *nb)
{
^ permalink raw reply
* [PATCH 2/5] move of_drconf_cell definition to prom.h
From: Nathan Fontenot @ 2009-09-11 21:12 UTC (permalink / raw)
To: linuxppc-dev; +Cc: linux-kernel
In-Reply-To: <4AAABC55.4070207@austin.ibm.com>
Move the definition of the of_drconf_cell struct from numa.c to prom.h. This
is needed so that we can parse the ibm,dynamic-memory device-tree property
when DLPAR adding and removing memory.
Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com>
---
Index: powerpc/arch/powerpc/include/asm/prom.h
===================================================================
--- powerpc.orig/arch/powerpc/include/asm/prom.h 2009-09-11 12:43:39.000000000 -0500
+++ powerpc/arch/powerpc/include/asm/prom.h 2009-09-11 12:52:11.000000000 -0500
@@ -349,6 +349,18 @@
*/
extern void __iomem *of_iomap(struct device_node *device, int index);
+struct of_drconf_cell {
+ u64 base_addr;
+ u32 drc_index;
+ u32 reserved;
+ u32 aa_index;
+ u32 flags;
+};
+
+#define DRCONF_MEM_ASSIGNED 0x00000008
+#define DRCONF_MEM_AI_INVALID 0x00000040
+#define DRCONF_MEM_RESERVED 0x00000080
+
/*
* NB: This is here while we transition from using asm/prom.h
* to linux/of.h
Index: powerpc/arch/powerpc/mm/numa.c
===================================================================
--- powerpc.orig/arch/powerpc/mm/numa.c 2009-09-11 12:43:39.000000000 -0500
+++ powerpc/arch/powerpc/mm/numa.c 2009-09-11 12:52:11.000000000 -0500
@@ -296,18 +296,6 @@
return result;
}
-struct of_drconf_cell {
- u64 base_addr;
- u32 drc_index;
- u32 reserved;
- u32 aa_index;
- u32 flags;
-};
-
-#define DRCONF_MEM_ASSIGNED 0x00000008
-#define DRCONF_MEM_AI_INVALID 0x00000040
-#define DRCONF_MEM_RESERVED 0x00000080
-
/*
* Read the next lmb list entry from the ibm,dynamic-memory property
* and return the information in the provided of_drconf_cell structure.
^ permalink raw reply
* [PATCH 3/5] Export memory_sysdev_class
From: Nathan Fontenot @ 2009-09-11 21:13 UTC (permalink / raw)
To: linuxppc-dev; +Cc: linux-kernel
In-Reply-To: <4AAABC55.4070207@austin.ibm.com>
Export the memory_sysdev_class structure. This is needed so we can create
a 'release' file in sysfs in addition to the existing 'probe' file in
order to support DLPAR removal of memory on the powerpc/pseries platform.
The new 'release' file will be powerpc/pseries only.
Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com>
---
Index: powerpc/drivers/base/memory.c
===================================================================
--- powerpc.orig/drivers/base/memory.c 2009-09-11 12:43:40.000000000 -0500
+++ powerpc/drivers/base/memory.c 2009-09-11 12:52:26.000000000 -0500
@@ -28,9 +28,10 @@
#define MEMORY_CLASS_NAME "memory"
-static struct sysdev_class memory_sysdev_class = {
+struct sysdev_class memory_sysdev_class = {
.name = MEMORY_CLASS_NAME,
};
+EXPORT_SYMBOL(memory_sysdev_class);
static const char *memory_uevent_name(struct kset *kset, struct kobject *kobj)
{
Index: powerpc/include/linux/memory_hotplug.h
===================================================================
--- powerpc.orig/include/linux/memory_hotplug.h 2009-09-11 12:43:44.000000000 -0500
+++ powerpc/include/linux/memory_hotplug.h 2009-09-11 12:52:26.000000000 -0500
@@ -12,6 +12,8 @@
#ifdef CONFIG_MEMORY_HOTPLUG
+extern struct sysdev_class memory_sysdev_class;
+
/*
* Types for free bootmem.
* The normal smallest mapcount is -1. Here is smaller value than it.
^ permalink raw reply
* [PATCH 4/5] kernel handling of memory DLPAR
From: Nathan Fontenot @ 2009-09-11 21:14 UTC (permalink / raw)
To: linuxppc-dev; +Cc: linux-kernel
In-Reply-To: <4AAABC55.4070207@austin.ibm.com>
This adds the capability to DLPAR add and remove memory from the kernel. The
patch extends the powerpc handling of memory_add_physaddr_to_nid(), which is
called from the sysfs memory 'probe' file to first ensure that the memory
has been added to the system. This is done by creating a platform specific
callout from the routine. The pseries implementation of this handles the
DLPAR work to add the memory to the system and update the device tree.
The patch also creates a pseries only 'release' sys file,
/sys/devices/system/memory/release. This file handles the DLPAR release of
memory back to firmware and updating of the device-tree.
Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com>
---
Index: powerpc/arch/powerpc/platforms/pseries/dlpar.c
===================================================================
--- powerpc.orig/arch/powerpc/platforms/pseries/dlpar.c 2009-09-11 12:51:52.000000000 -0500
+++ powerpc/arch/powerpc/platforms/pseries/dlpar.c 2009-09-11 13:05:23.000000000 -0500
@@ -16,6 +16,10 @@
#include <linux/notifier.h>
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
+#include <linux/memory_hotplug.h>
+#include <linux/sysdev.h>
+#include <linux/sysfs.h>
+
#include <asm/prom.h>
#include <asm/machdep.h>
@@ -404,13 +408,174 @@
return 0;
}
+static void free_property(struct property *prop)
+{
+ if (prop->name)
+ kfree(prop->name);
+ if (prop->value)
+ kfree(prop->value);
+ kfree(prop);
+}
+
+static struct property *clone_property(struct property *old_prop)
+{
+ struct property *new_prop;
+
+ new_prop = kzalloc((sizeof *new_prop), GFP_KERNEL);
+ if (!new_prop)
+ return NULL;
+
+ new_prop->name = kzalloc(strlen(old_prop->name) + 1, GFP_KERNEL);
+ new_prop->value = kzalloc(old_prop->length + 1, GFP_KERNEL);
+ if (!new_prop->name || !new_prop->value) {
+ free_property(new_prop);
+ return NULL;
+ }
+
+ strcpy(new_prop->name, old_prop->name);
+ memcpy(new_prop->value, old_prop->value, old_prop->length);
+ new_prop->length = old_prop->length;
+
+ return new_prop;
+}
+
+int platform_probe_memory(u64 phys_addr)
+{
+ struct device_node *dn;
+ struct property *new_prop, *old_prop;
+ struct property *lmb_sz_prop;
+ struct of_drconf_cell *drmem;
+ u64 lmb_size;
+ int num_entries, i, rc;
+
+ if (!phys_addr)
+ return -EINVAL;
+
+ dn = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
+ if (!dn)
+ return -EINVAL;
+
+ lmb_sz_prop = of_find_property(dn, "ibm,lmb-size", NULL);
+ lmb_size = *(u64 *)lmb_sz_prop->value;
+
+ old_prop = of_find_property(dn, "ibm,dynamic-memory", NULL);
+
+ num_entries = *(u32 *)old_prop->value;
+ drmem = (struct of_drconf_cell *)
+ ((char *)old_prop->value + sizeof(u32));
+
+ for (i = 0; i < num_entries; i++) {
+ u64 lmb_end_addr = drmem[i].base_addr + lmb_size;
+ if (phys_addr >= drmem[i].base_addr
+ && phys_addr < lmb_end_addr)
+ break;
+ }
+
+ if (i >= num_entries) {
+ of_node_put(dn);
+ return -EINVAL;
+ }
+
+ if (drmem[i].flags & DRCONF_MEM_ASSIGNED) {
+ of_node_put(dn);
+ return 0;
+ }
+
+ rc = acquire_drc(drmem[i].drc_index);
+ if (rc) {
+ of_node_put(dn);
+ return -1;
+ }
+
+ new_prop = clone_property(old_prop);
+ drmem = (struct of_drconf_cell *)
+ ((char *)new_prop->value + sizeof(u32));
+
+ drmem[i].flags |= DRCONF_MEM_ASSIGNED;
+ prom_update_property(dn, new_prop, old_prop);
+
+ rc = blocking_notifier_call_chain(&pSeries_reconfig_chain,
+ PSERIES_DRCONF_MEM_ADD,
+ &drmem[i].base_addr);
+ if (rc == NOTIFY_BAD) {
+ prom_update_property(dn, old_prop, new_prop);
+ release_drc(drmem[i].drc_index);
+ }
+
+ of_node_put(dn);
+ return rc == NOTIFY_BAD ? -1 : 0;
+}
+
+static ssize_t memory_release_store(struct class *class, const char *buf,
+ size_t count)
+{
+ u32 drc_index;
+ struct device_node *dn;
+ struct property *new_prop, *old_prop;
+ struct of_drconf_cell *drmem;
+ int num_entries;
+ int i, rc;
+
+ drc_index = simple_strtoull(buf, NULL, 0);
+ if (!drc_index)
+ return -EINVAL;
+
+ dn = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
+ if (!dn)
+ return 0;
+
+ old_prop = of_find_property(dn, "ibm,dynamic-memory", NULL);
+ new_prop = clone_property(old_prop);
+
+ num_entries = *(u32 *)new_prop->value;
+ drmem = (struct of_drconf_cell *)
+ ((char *)new_prop->value + sizeof(u32));
+
+ for (i = 0; i < num_entries; i++) {
+ if (drmem[i].drc_index == drc_index)
+ break;
+ }
+
+ if (i >= num_entries) {
+ free_property(new_prop);
+ of_node_put(dn);
+ return -EINVAL;
+ }
+
+ drmem[i].flags &= ~DRCONF_MEM_ASSIGNED;
+ prom_update_property(dn, new_prop, old_prop);
+
+ rc = blocking_notifier_call_chain(&pSeries_reconfig_chain,
+ PSERIES_DRCONF_MEM_REMOVE,
+ &drmem[i].base_addr);
+ if (rc != NOTIFY_BAD)
+ rc = release_drc(drc_index);
+
+ if (rc)
+ prom_update_property(dn, old_prop, new_prop);
+
+ of_node_put(dn);
+ return rc ? -1 : count;
+}
+
+static struct class_attribute class_attr_mem_release =
+ __ATTR(release, S_IWUSR, NULL, memory_release_store);
+
static int pseries_dlpar_init(void)
{
+ int rc;
+
spin_lock_init(&workarea_lock);
if (!machine_is(pseries))
return 0;
+ rc = sysfs_create_file(&memory_sysdev_class.kset.kobj,
+ &class_attr_mem_release.attr);
+ if (rc)
+ printk(KERN_INFO "DLPAR: Could not create sysfs memory "
+ "release file\n");
+
return 0;
}
__initcall(pseries_dlpar_init);
Index: powerpc/arch/powerpc/mm/mem.c
===================================================================
--- powerpc.orig/arch/powerpc/mm/mem.c 2009-09-11 12:43:39.000000000 -0500
+++ powerpc/arch/powerpc/mm/mem.c 2009-09-11 12:52:42.000000000 -0500
@@ -111,8 +111,19 @@
#ifdef CONFIG_MEMORY_HOTPLUG
#ifdef CONFIG_NUMA
+int __attribute ((weak)) platform_probe_memory(u64 start)
+{
+ return 0;
+}
+
int memory_add_physaddr_to_nid(u64 start)
{
+ int rc;
+
+ rc = platform_probe_memory(start);
+ if (rc)
+ return rc;
+
return hot_add_scn_to_nid(start);
}
#endif
^ permalink raw reply
* [PATCH 5/5] kernel handling of CPU DLPAR
From: Nathan Fontenot @ 2009-09-11 21:15 UTC (permalink / raw)
To: linuxppc-dev; +Cc: linux-kernel
In-Reply-To: <4AAABC55.4070207@austin.ibm.com>
This adds the capability to DLPAR add and remove CPUs from the kernel. The
creates two new files /sys/devices/system/cpu/probe and
/sys/devices/system/cpu/release to handle the DLPAR addition and removal of
CPUs respectively.
CPU DLPAR add is accomplished by writing the drc-index of the CPU to the
probe file, and removal is done by writing the device-tree path of the cpu
to the release file.
Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com>
Index: powerpc/arch/powerpc/platforms/pseries/dlpar.c
===================================================================
--- powerpc.orig/arch/powerpc/platforms/pseries/dlpar.c 2009-09-11 13:05:23.000000000 -0500
+++ powerpc/arch/powerpc/platforms/pseries/dlpar.c 2009-09-11 14:10:28.000000000 -0500
@@ -1,11 +1,11 @@
/*
- * dlpar.c - support for dynamic reconfiguration (including PCI
- * Hotplug and Dynamic Logical Partitioning on RPA platforms).
+ * dlpar.c - support for dynamic reconfiguration (including PCI,
+ * Memory, and CPU Hotplug and Dynamic Logical Partitioning on
+ * PAPR platforms).
*
* Copyright (C) 2009 Nathan Fontenot
* Copyright (C) 2009 IBM Corporation
*
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 as published by the Free Software Foundation.
@@ -19,6 +19,7 @@
#include <linux/memory_hotplug.h>
#include <linux/sysdev.h>
#include <linux/sysfs.h>
+#include <linux/cpu.h>
#include <asm/prom.h>
@@ -558,8 +559,79 @@
return rc ? -1 : count;
}
+static ssize_t cpu_probe_store(struct class *class, const char *buf,
+ size_t count)
+{
+ struct device_node *dn;
+ u32 drc_index;
+ char *cpu_name;
+ int rc;
+
+ drc_index = simple_strtoull(buf, NULL, 0);
+ if (!drc_index)
+ return -EINVAL;
+
+ rc = acquire_drc(drc_index);
+ if (rc)
+ return rc;
+
+ dn = configure_connector(drc_index);
+ if (!dn) {
+ release_drc(drc_index);
+ return rc;
+ }
+
+ /* fixup dn name */
+ cpu_name = kzalloc(strlen(dn->full_name) + strlen("/cpus/") + 1,
+ GFP_KERNEL);
+ sprintf(cpu_name, "/cpus/%s", dn->full_name);
+ kfree(dn->full_name);
+ dn->full_name = cpu_name;
+
+ rc = add_device_tree_nodes(dn);
+ if (rc)
+ release_drc(drc_index);
+
+ return rc ? rc : count;
+}
+
+static ssize_t cpu_release_store(struct class *class, const char *buf,
+ size_t count)
+{
+ struct device_node *dn;
+ u32 *drc_index;
+ int rc;
+
+ dn = of_find_node_by_path(buf);
+ if (!dn)
+ return -EINVAL;
+
+ drc_index = (u32 *)of_get_property(dn, "ibm,my-drc-index", NULL);
+ if (!drc_index) {
+ of_node_put(dn);
+ return -EINVAL;
+ }
+
+ rc = release_drc(*drc_index);
+ if (rc) {
+ of_node_put(dn);
+ return rc;
+ }
+
+ rc = remove_device_tree_nodes(dn);
+ if (rc)
+ acquire_drc(*drc_index);
+
+ of_node_put(dn);
+ return rc? rc : count;
+}
+
static struct class_attribute class_attr_mem_release =
__ATTR(release, S_IWUSR, NULL, memory_release_store);
+static struct class_attribute class_attr_cpu_probe =
+ __ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
+static struct class_attribute class_attr_cpu_release =
+ __ATTR(release, S_IWUSR, NULL, cpu_release_store);
static int pseries_dlpar_init(void)
{
@@ -576,6 +648,18 @@
printk(KERN_INFO "DLPAR: Could not create sysfs memory "
"release file\n");
+ rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
+ &class_attr_cpu_probe.attr);
+ if (rc)
+ printk(KERN_INFO "DLPAR: Could not create sysfs cpu "
+ "probe file\n");
+
+ rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
+ &class_attr_cpu_release.attr);
+ if (rc)
+ printk(KERN_INFO "DLPAR: Could not create sysfs cpu "
+ "release file\n");
+
return 0;
}
__initcall(pseries_dlpar_init);
^ permalink raw reply
* Re: [PATCH 0/5] kernel handling of dynamic logical partitioning
From: Daniel Walker @ 2009-09-11 21:23 UTC (permalink / raw)
To: Nathan Fontenot; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <4AAABC55.4070207@austin.ibm.com>
On Fri, 2009-09-11 at 16:08 -0500, Nathan Fontenot wrote:
> am cc'ing lkml.
>
> Patches include in this set:
> 1/5 - DLPAR infrastructure for powerpc/pseries platform.
> 2/5 - Move the of_drconf_cell struct to prom.h
> 3/5 - Export the memory sysdev class
> 4/5 - Memory DLPAR handling
> 5/5 - CPU DLPAR handling
>
It looks like a couple of your patches have some checkpatch issues..
Could you run these through scripts/checkpatch.pl and clean up any
problems it raises ? Specifically patches 1, 4, and 5 ..
Daniel
^ permalink raw reply
* Re: [Bugme-new] [Bug 14148] New: kernel panic: do_wp_page assert_pte_locked failed when DEBUG_VM
From: Kumar Gala @ 2009-09-11 21:37 UTC (permalink / raw)
To: Andrew Morton
Cc: wangbj, linux-mm, bugzilla-daemon, bugme-daemon, linuxppc-dev
In-Reply-To: <20090911130940.a99708dc.akpm@linux-foundation.org>
On Sep 11, 2009, at 3:09 PM, Andrew Morton wrote:
>
> (switched to email. Please respond via emailed reply-to-all, not
> via the
> bugzilla web interface).
>
> On Wed, 9 Sep 2009 15:09:15 GMT
> bugzilla-daemon@bugzilla.kernel.org wrote:
>
>> http://bugzilla.kernel.org/show_bug.cgi?id=14148
>>
>> Summary: kernel panic: do_wp_page assert_pte_locked
>> failed when
>> DEBUG_VM
>> Product: Platform Specific/Hardware
>> Version: 2.5
>> Kernel Version: 2.6.31-rc3, 2.6.31-rc9-git2
>> Platform: All
>> OS/Version: Linux
>> Tree: Mainline
>> Status: NEW
>> Severity: normal
>> Priority: P1
>> Component: PPC-32
>> AssignedTo: platform_ppc-32@kernel-bugs.osdl.org
>> ReportedBy: wangbj@lzu.edu.cn
>> Regression: Yes
>>
>>
>> Created an attachment (id=23049)
>> --> (http://bugzilla.kernel.org/attachment.cgi?id=23049)
>> problematic config file for mpc8548cds
>>
>> powerpc mpc8548cds (I only have this board on hand) will kernel
>> panic if
>> DEBUG_VM (kernel hacking) is enabled due to assertion failed in
>> function
>> do_wp_page(). I think it highly possible for other ppc boards like
>> 44x have the
>> same problem too, but I don't have the board.
>>
>> here is the full log from power up (after u-boot). and the
>> attachment is
>> related .config, NOTE the kernel boot successfully if
>> CONFIG_DEBUG_VM is not
>> enabled.
>>
>> host system is gentoo, the gcc (powerpc-unknown-linux-gnu-gcc) is
>> build by
>> gentoo crossdev, version 4.4.1, (cross) glibc is 2.9, (cross)
>> binutils is
>> 2.19.1, (cross) kernel headers is 2.6.30. target (mpc8548cds) root
>> filesystem
>> is also gentoo (200907xx, extracted from stage3 tarball).
>>
>> I have running similar test on x86 using qemu (0.10.6, +kvm), the
>> result seems
>> OK, especially x86 pass all lock api test suite.
>
> First question:
>
>> [10611.192802] ------------[ cut here ]------------
>> [10611.197409] Kernel BUG at c0014d70 [verbose debug info
>> unavailable]
>
> Why did we not get the file-n-line? That's iritating.
>
> Oh, CONFIG_DEBUG_BUGVERBOSE=n. Don't do that. We should make that
> thing
> harder to get at, to stop people shooting our feet off.
>
>> [10611.203660] Oops: Exception in kernel mode, sig: 5 [#1]
>> [10611.208866] PREEMPT MPC85xx CDS
>> [10611.211997] Modules linked in:
>> [10611.215040] NIP: c0014d70 LR: c0014eb4 CTR: 00000002
>> [10611.219988] REGS: cf82db40 TRAP: 0700 Not tainted (2.6.31-rc3)
>> [10611.226061] MSR: 00029000 <EE,ME,CE> CR: 88448044 XER: 20000000
>> [10611.232162] TASK = cf828000[1] 'init' THREAD: cf82c000
>> [10611.237108] GPR00: 00000001 cf82dbf0 cf828000 cf9781c0 bf8031d8
>> cf9f400c
>> 0057902f 00000001
>> [10611.245471] GPR08: cf978200 cf9f4000 00000002 00000000 28448042
>> 1001b0b0
>> 00000001 cf88ee00
>> [10611.253833] GPR16: c05c0000 bf8031d8 00000002 10000000 48000000
>> 00000001
>> 00000008 c05ecf20
>> [10611.262196] GPR24: 0057902b 0057902f cf82c000 00000000 cf9f400c
>> 00000001
>> bf8031d8 cf98b000
>> [10611.270749] NIP [c0014d70] assert_pte_locked+0x3c/0x44
>> [10611.275872] LR [c0014eb4] ptep_set_access_flags+0xa8/0xf4
>> [10611.281252] Call Trace:
>> [10611.283687] [cf82dbf0] [bf8031d8] 0xbf8031d8 (unreliable)
>> [10611.289079] [cf82dc10] [c008e87c] do_wp_page+0xf8/0x82c
>> [10611.294292] [cf82dc60] [c0014770] do_page_fault+0x2c0/0x480
>> [10611.299851] [cf82dd10] [c0011078] handle_page_fault+0xc/0x80
>> [10611.305504] [cf82ddd0] [c00f2b4c] load_elf_binary+0x8a8/0x121c
>> [10611.311325] [cf82de50] [c00af418] search_binary_handler
>> +0x144/0x37c
>> [10611.317578] [cf82dea0] [c00b0bc8] do_execve+0x270/0x2c8
>> [10611.322794] [cf82dee0] [c0008754] sys_execve+0x68/0xa4
>> [10611.327919] [cf82df00] [c0010c38] ret_from_syscall+0x0/0x3c
>> [10611.333482] [cf82dfc0] [c00b9350] sys_dup+0x38/0x78
>> [10611.338349] [cf82dfd0] [c0002030] init_post+0x94/0x108
>> [10611.343478] [cf82dfe0] [c054c234] kernel_init+0x114/0x130
>> [10611.348865] [cf82dff0] [c00109b8] kernel_thread+0x4c/0x68
>> [10611.354249] Instruction dump:
>> [10611.357206] 4d9e0020 38000000 0f000000 0f000000 81230024
>> 5480653a 7c09002e
>> 54090027
>> [10611.364959] 7c000026 54001ffe 0f000000 38000001 <0f000000>
>> 4e800020 7c0802a6
>> 9421fff0
>> [10611.372887] ---[ end trace 0cda2392272f221a ]---
>
> So do_wp_page() called ptep_set_access_flags(). If CONFIG_DEBUG_VM=y,
> powerpc's ptep_set_access_flags() will call
> arch/powerpc/mm/pgtable.c:assert_pte_locked(). Because of the lack of
> file-n-line info it is unclear which of those many assertions
> triggered. It looks like BUG_ON(!pmd_present(*pmd)). Perhaps.
>
>
> Please set CONFIG_DEBUG_BUGVERBOSE=y in your .config and then tell us
> (via emailed reply-to-all) which line in arch/powerpc/mm/pgtable.c
> triggered the BUG. Please actually quote that line, or tell us
> exactly
> which kernel version you're using so we can see which line it was in
> the source code.
>
> Thanks.
I think I fixed this:
commit 797a747a82e23530ee45d2927bf84f3571c1acb2
Author: Kumar Gala <galak@kernel.crashing.org>
Date: Tue Aug 18 15:21:40 2009 +0000
powerpc/mm: Fix assert_pte_locked to work properly on uniprocessor
Since the pte_lockptr is a spinlock it gets optimized away on
uniprocessor builds so using spin_is_locked is not correct. We
can use
assert_spin_locked instead and get the proper behavior between UP
and
SMP builds.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
But the patch was queued up for .32 not .31
- k
^ permalink raw reply
* Re: linux booting fine but running slow
From: Gao Ya'nan @ 2009-09-11 22:33 UTC (permalink / raw)
To: Frank Svendsbøe; +Cc: linuxppc-dev, stevan
In-Reply-To: <1ba63b520909110606x4599dd5bt428e03775805dff2@mail.gmail.com>
2009/9/11 Frank Svendsb=F8e <frank.svendsboe@gmail.com>:
> Hi Gao and Stevan
>
> I've observed the same slow-down issue on an MPC875 a while now, but
> haven't had the time to do a git-bisect
> and find the patch that causes the problem. So far, I'm running
> torvalds 2.6.29-rc6, and the slow-down problem
> was introduced somewhere between 2.6.26-rc6 and 2.6.30-rc2.
>
> What options did you specify to improve the performance?
>
Actually, I think It didn't improve the performance but perhaps solved
some conflicts.
I'll check the configuration and put up here later.
> Regards,
> Frank
>
I was in doubt where I went wrong before your mail. So, thanks, Frank.
> On Fri, Sep 11, 2009 at 1:59 PM, Gao Ya'nan <abutter.gao@gmail.com> wrote=
:
>> Hi, stevan, I had met a similarly problem with U-Boot-v2009.08 and
>> DENX-v2.6.30.3 Linux.
>>
>> Today, I add some options to Linux, everythings worked well, but I got
>> a fat kernel. Do you solve it now ?
>>
>> Gao Ya'nan
>> _______________________________________________
>> Linuxppc-dev mailing list
>> Linuxppc-dev@lists.ozlabs.org
>> https://lists.ozlabs.org/listinfo/linuxppc-dev
>>
>
^ permalink raw reply
* [RFC] powerpc/irq: Add generic API for setting up cascaded IRQs
From: Grant Likely @ 2009-09-12 5:46 UTC (permalink / raw)
To: benh, linuxppc-dev
From: Grant Likely <grant.likely@secretlab.ca>
prototype implementation. This probably doesn't work at all right now.
Ben, I'm posting this now to get your thoughts before I go too far down
this path.
Cheers,
g.
---
arch/powerpc/include/asm/irq.h | 3 ++
arch/powerpc/kernel/irq.c | 20 +++++++++++++++
arch/powerpc/platforms/52xx/mpc52xx_pic.c | 39 +++++++++++++++++++++++++++++
3 files changed, 62 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h
index 0a51376..014e1e8 100644
--- a/arch/powerpc/include/asm/irq.h
+++ b/arch/powerpc/include/asm/irq.h
@@ -90,6 +90,9 @@ struct irq_host_ops {
/* Update of such a mapping */
void (*remap)(struct irq_host *h, unsigned int virq, irq_hw_number_t hw);
+ /* Setup hook for cascade irqs */
+ int (*cascade_setup)(int virq, int (*get_irq)(void *data), void *data);
+
/* Translate device-tree interrupt specifier from raw format coming
* from the firmware to a irq_hw_number_t (interrupt line number) and
* type (sense) that can be passed to set_irq_type(). In the absence
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index f7f376e..5a9cb46 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -750,6 +750,26 @@ unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
}
EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
+unsigned int irq_of_cascade_setup(int virq, int (*get_irq)(void *data),
+ void *data)
+{
+ struct irq_host *host = irq_map[virq].host;
+
+ if (!host) {
+ pr_err("error: no irq host found virq %i !\n", virq);
+ return -ENODEV;
+ }
+
+ /* If host has no cascade setup function, then this method for
+ * setting up a cascade is not available */
+ if (!host->ops->cascade_setup) {
+ pr_err("error: no cascade_setup support on virq %i\n", virq);
+ return -EINVAL;
+ }
+
+ return host->ops->cascade_setup(virq, get_irq, data);
+}
+
void irq_dispose_mapping(unsigned int virq)
{
struct irq_host *host;
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 480f806..a91c69b 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -437,9 +437,48 @@ static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
return 0;
}
+struct mpc52xx_cascade_data {
+ int (*get_irq)(void *data);
+ void *data;
+};
+
+void mpc52xx_handle_level_cascade(unsigned int irq, struct irq_desc *desc)
+{
+ struct mpc52xx_cascade_data *cascade_data = get_irq_desc_data(desc);
+ int cascade_virq;
+
+ cascade_virq = cascade_data->get_irq(cascade_data->data);
+ if (cascade_virq)
+ generic_handle_irq(cascade_virq);
+}
+
+void mpc52xx_handle_edge_cascade(unsigned int virq, struct irq_desc *desc)
+{
+ mpc52xx_handle_level_cascade(virq, desc);
+ /** TODO: clear edge IRQ here **/
+}
+
+int mpc52xx_cascade_setup(int virq, int (*get_irq)(void *data), void *data)
+{
+ struct mpc52xx_cascade_data *cascade_data;
+
+ cascade_data = kzalloc(sizeof(struct mpc52xx_cascade_data), GFP_KERNEL);
+ if (!cascade_data)
+ return -ENOMEM;
+
+ /* TODO: make this handle edge cascades too */
+ cascade_data->get_irq = get_irq;
+ cascade_data->data = data;
+ set_irq_data(virq, cascade_data);
+ set_irq_chained_handler(virq, mpc52xx_handle_level_cascade);
+
+ return 0;
+}
+
static struct irq_host_ops mpc52xx_irqhost_ops = {
.xlate = mpc52xx_irqhost_xlate,
.map = mpc52xx_irqhost_map,
+ .cascade_setup = mpc52xx_cascade_setup,
};
/**
^ permalink raw reply related
* Re: [RFC] powerpc/irq: Add generic API for setting up cascaded IRQs
From: Benjamin Herrenschmidt @ 2009-09-12 6:28 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <20090912054410.21847.63718.stgit@localhost.localdomain>
On Fri, 2009-09-11 at 23:46 -0600, Grant Likely wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> prototype implementation. This probably doesn't work at all right now.
>
> Ben, I'm posting this now to get your thoughts before I go too far down
> this path.
Looks ok. I was initially thinking about putting get_irq() in irq_host,
but as we discussed on IRC, a host is not necessarily a PIC, and it's
nice for the parent to have a way to setup/init the cascade in case
it needs to do some HW tweaking there as well.
However, why cascade_setup() and not setup_cascade() which sounds
somewhat more natural ? :-)
Cheers,
Ben.
> Cheers,
> g.
>
> ---
>
> arch/powerpc/include/asm/irq.h | 3 ++
> arch/powerpc/kernel/irq.c | 20 +++++++++++++++
> arch/powerpc/platforms/52xx/mpc52xx_pic.c | 39 +++++++++++++++++++++++++++++
> 3 files changed, 62 insertions(+), 0 deletions(-)
>
>
> diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h
> index 0a51376..014e1e8 100644
> --- a/arch/powerpc/include/asm/irq.h
> +++ b/arch/powerpc/include/asm/irq.h
> @@ -90,6 +90,9 @@ struct irq_host_ops {
> /* Update of such a mapping */
> void (*remap)(struct irq_host *h, unsigned int virq, irq_hw_number_t hw);
>
> + /* Setup hook for cascade irqs */
> + int (*cascade_setup)(int virq, int (*get_irq)(void *data), void *data);
> +
> /* Translate device-tree interrupt specifier from raw format coming
> * from the firmware to a irq_hw_number_t (interrupt line number) and
> * type (sense) that can be passed to set_irq_type(). In the absence
> diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
> index f7f376e..5a9cb46 100644
> --- a/arch/powerpc/kernel/irq.c
> +++ b/arch/powerpc/kernel/irq.c
> @@ -750,6 +750,26 @@ unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
> }
> EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
>
> +unsigned int irq_of_cascade_setup(int virq, int (*get_irq)(void *data),
> + void *data)
> +{
> + struct irq_host *host = irq_map[virq].host;
> +
> + if (!host) {
> + pr_err("error: no irq host found virq %i !\n", virq);
> + return -ENODEV;
> + }
> +
> + /* If host has no cascade setup function, then this method for
> + * setting up a cascade is not available */
> + if (!host->ops->cascade_setup) {
> + pr_err("error: no cascade_setup support on virq %i\n", virq);
> + return -EINVAL;
> + }
> +
> + return host->ops->cascade_setup(virq, get_irq, data);
> +}
> +
> void irq_dispose_mapping(unsigned int virq)
> {
> struct irq_host *host;
> diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
> index 480f806..a91c69b 100644
> --- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
> +++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
> @@ -437,9 +437,48 @@ static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
> return 0;
> }
>
> +struct mpc52xx_cascade_data {
> + int (*get_irq)(void *data);
> + void *data;
> +};
> +
> +void mpc52xx_handle_level_cascade(unsigned int irq, struct irq_desc *desc)
> +{
> + struct mpc52xx_cascade_data *cascade_data = get_irq_desc_data(desc);
> + int cascade_virq;
> +
> + cascade_virq = cascade_data->get_irq(cascade_data->data);
> + if (cascade_virq)
> + generic_handle_irq(cascade_virq);
> +}
> +
> +void mpc52xx_handle_edge_cascade(unsigned int virq, struct irq_desc *desc)
> +{
> + mpc52xx_handle_level_cascade(virq, desc);
> + /** TODO: clear edge IRQ here **/
> +}
> +
> +int mpc52xx_cascade_setup(int virq, int (*get_irq)(void *data), void *data)
> +{
> + struct mpc52xx_cascade_data *cascade_data;
> +
> + cascade_data = kzalloc(sizeof(struct mpc52xx_cascade_data), GFP_KERNEL);
> + if (!cascade_data)
> + return -ENOMEM;
> +
> + /* TODO: make this handle edge cascades too */
> + cascade_data->get_irq = get_irq;
> + cascade_data->data = data;
> + set_irq_data(virq, cascade_data);
> + set_irq_chained_handler(virq, mpc52xx_handle_level_cascade);
> +
> + return 0;
> +}
> +
> static struct irq_host_ops mpc52xx_irqhost_ops = {
> .xlate = mpc52xx_irqhost_xlate,
> .map = mpc52xx_irqhost_map,
> + .cascade_setup = mpc52xx_cascade_setup,
> };
>
> /**
^ permalink raw reply
* Re: [PATCH 01/10] Add support for GCC-4.5's __builtin_unreachable() to compiler.h
From: Geert Uytterhoeven @ 2009-09-12 7:22 UTC (permalink / raw)
To: David Daney
Cc: linux-mips, Heiko Carstens, linuxppc-dev, Paul Mackerras,
H. Peter Anvin, linux-s390, linux-am33-list, Helge Deller, x86,
Ingo Molnar, Mike Frysinger, Ivan Kokshaysky, linux390,
Thomas Gleixner, Richard Henderson, Haavard Skinnemoen,
linux-parisc, torvalds, linux-kernel, ralf, Kyle McMartin,
linux-alpha, Martin Schwidefsky, uclinux-dist-devel, akpm,
Koichi Yasutake, linuxppc-dev
In-Reply-To: <4AAA73A4.9010601@caviumnetworks.com>
On Fri, Sep 11, 2009 at 17:58, David Daney<ddaney@caviumnetworks.com> wrote=
:
> Michael Buesch wrote:
>>
>> On Friday 11 September 2009 01:56:42 David Daney wrote:
>>>
>>> +/* Unreachable code */
>>> +#ifndef unreachable
>>> +# define unreachable() do { for (;;) ; } while (0)
>>> +#endif
>>
>> # define unreachable() do { } while (1)
>>
>> ? :)
>
> Clearly I was not thinking clearly when I wrote that part. =C2=A0RTH note=
d the
> same thing. =C2=A0I will fix it.
However, people are so used to seeing the `do { } while (0)' idiom,
that they might miss
there's a `1' here, not a `0'.
So perhaps it's better to use plain `for (;;)' for infinite loops?
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k=
.org
In personal conversations with technical people, I call myself a hacker. Bu=
t
when I'm talking to journalists I just say "programmer" or something like t=
hat.
-- Linus Torvalds
^ permalink raw reply
* MPC5200/BestComm functions question
From: Albrecht Dreß @ 2009-09-12 12:36 UTC (permalink / raw)
To: Linux PPC Development
[-- Attachment #1: Type: text/plain, Size: 944 bytes --]
Hi all,
I have a MPC5200B based system with a 16-bit peripheral attached to the
Local Bus, and I am looking into possibilities to use BestComm for the
data transfer.
I found Grant Likely's cool 'mpc5200-localplus-test.c' driver which
demonstrates this using the 'gen_bd' driver, and which is apparently a
great starting point.
However, I also have to (a) 32-bit endianess-swap the data and (b)
calculate a 32-bit crc on it. Of course, this is possible with the
buffers using the cpu, but I saw some remarks that the Bestcomm engine
also includes functions which can perform swapping and crc
calculation. I believe it would unload the cpu if the BestComm engine
could perform these tasks, but I cannot find a good
documentation/example for that. Does anyone know any pointers for
that? Or maybe even a tool to create the bestcomm tasks from a
'readable' source?
Thanks in advance,
Albrecht.
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: MPC5200/BestComm functions question
From: Grant Likely @ 2009-09-12 14:01 UTC (permalink / raw)
To: Albrecht Dreß; +Cc: Linux PPC Development
In-Reply-To: <1252758988.3310.0@antares>
On Sat, Sep 12, 2009 at 6:36 AM, Albrecht Dre=DF <albrecht.dress@arcor.de> =
wrote:
> Hi all,
>
> I have a MPC5200B based system with a 16-bit peripheral attached to the
> Local Bus, and I am looking into possibilities to use BestComm for the da=
ta
> transfer.
>
> I found Grant Likely's cool 'mpc5200-localplus-test.c' driver which
> demonstrates this using the 'gen_bd' driver, and which is apparently a gr=
eat
> starting point.
I've actually got a better driver which exports an API for doing local
plus bus FIFO transfers. It's been posted to the mailing list a
couple of times. I'll cc: you the next time I post it (real soon
now).
> However, I also have to (a) 32-bit endianess-swap the data and (b) calcul=
ate
> a 32-bit crc on it. =A0Of course, this is possible with the buffers using=
the
> cpu, but I saw some remarks that the Bestcomm engine also includes functi=
ons
> which can perform swapping and crc calculation. =A0I believe it would unl=
oad
> the cpu if the BestComm engine could perform these tasks, but I cannot fi=
nd
> a good documentation/example for that. =A0Does anyone know any pointers f=
or
> that? =A0Or maybe even a tool to create the bestcomm tasks from a 'readab=
le'
> source?
Bestcomm can do that, but Freescale has not publically released the
bestcomm documentation, and they do not support writing custom
bestcomm tasks. From what I understand there are a number of hidden
bugs in the bestcomm engine which you could run into if you deviate
from the provided tasks. You're very much on your own if you go down
that route. :-(
g.
--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox