* Re: [PATCH 1/3] Fix Unlikely(x) == y
From: Adrian Bunk @ 2008-02-18 14:13 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Roel Kluin, lkml, cbe-oss-dev, linuxppc-dev, Willy Tarreau,
Arjan van de Ven
In-Reply-To: <Pine.LNX.4.64.0802181500410.13406@vixen.sonytel.be>
On Mon, Feb 18, 2008 at 03:01:35PM +0100, Geert Uytterhoeven wrote:
> On Mon, 18 Feb 2008, Adrian Bunk wrote:
> >
> > This means it generates faster code with a current gcc for your platform.
> >
> > But a future gcc might e.g. replace the whole loop with a division
> > (gcc SVN head (that will soon become gcc 4.3) already does
> > transformations like replacing loops with divisions [1]).
>
> Hence shouldn't we ask the gcc people what's the purpose of __builtin_expect(),
> if it doesn't live up to its promise?
That's a different issue.
My point here is that we do not know how the latest gcc available in the
year 2010 might transform this code, and how a likely/unlikely placed
there might influence gcc's optimizations then.
If this is in hotpath code with a measurable speedup when using
likely/unlikely with a current gcc then it's worth it.
But otherwise it brings no real advantage today and the longterm effects
are not predictable.
> With kind regards,
>
> Geert Uytterhoeven
cu
Adrian
--
"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed
^ permalink raw reply
* Re: Does anyone have a simple UIO driver that uses an interrupt handler?
From: Hans-Jürgen Koch @ 2008-02-18 13:09 UTC (permalink / raw)
To: ndroogh; +Cc: linuxppc-embedded
In-Reply-To: <47B8BF83.2070907@cadlink.com>
Am Sun, 17 Feb 2008 18:13:07 -0500
schrieb Nick Droogh <ndroogh@cadlink.com>:
> Hi everyone,
Hi Nick,
>
> I am looking for a driver example for a user space driver utilizing
> an interrupt handler. I am having trouble registering a handler in
> my driver attempt and would like to see an example of a working UIO
> driver.
Did you have a look at uio-howto in Documentation/DocBook/ in the
kernel sources? Just do a "make htmldocs", and you get the UIO howto in
html format in its own subdirectory.
You don't have to "register" the userspace part of an UIO driver. You
simply open /dev/uio0, mmap() your device's memory, and wait for
interrupts using a blocking read() or select() on /dev/uio0.
If you want to do it properly, you should use sysfs to find the right
UIO device (there could be others...) and the size of the memory to
map. Have a look at the sources of lsuio to see how this is done:
http://www.osadl.org/projects/downloads/UIO/user/
You find the userspace part of the uio_cif driver there, too.
If you still got problems after reading this, feel free to ask me. Note
that I'm not subscribed to linuxppc-embedded. The preferred list for
UIO questions is LKML. If you don't want to subscribe to LKML, you can
also ask me by private mail. You should ask detailed questions, ideally
accompanied by a piece of your code that shows the problem.
Thanks,
Hans
^ permalink raw reply
* [PATCH] next-20080218 build failure at pmac_ide_macio_attach ()
From: Kamalesh Babulal @ 2008-02-18 14:01 UTC (permalink / raw)
To: linux-kernel; +Cc: linux-ide, sfr, linuxppc-dev
Hi,
The next-20080218 kernel build fails on the powerpc(s)
drivers/ide/ppc/pmac.c: In function ‘pmac_ide_macio_attach’:
drivers/ide/ppc/pmac.c:1094: error: conversion to non-scalar type requested
drivers/ide/ppc/pmac.c: In function ‘pmac_ide_pci_attach’:
drivers/ide/ppc/pmac.c:1232: error: conversion to non-scalar type requested
make[3]: *** [drivers/ide/ppc/pmac.o] Error 1
make[2]: *** [drivers/ide/ppc] Error 2
make[1]: *** [drivers/ide] Error 2
make: *** [drivers] Error 2
I Have tested this patch for build failure only.
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
---
--- linux-2.6.25-rc1/drivers/ide/ppc/pmac.c 2008-02-18 18:41:48.000000000 +0530
+++ linux-2.6.25-rc1/drivers/ide/ppc/~pmac.c 2008-02-18 19:20:37.000000000 +0530
@@ -1091,7 +1091,7 @@ pmac_ide_macio_attach(struct macio_dev *
int irq, rc;
hw_regs_t hw;
- pmif = (struct pmac_ide_hwif)kzalloc(sizeof(*pmif), GFP_KERNEL);
+ pmif = (struct pmac_ide_hwif*)kzalloc(sizeof(*pmif), GFP_KERNEL);
if (pmif == NULL)
return -ENOMEM;
@@ -1229,7 +1229,7 @@ pmac_ide_pci_attach(struct pci_dev *pdev
return -ENODEV;
}
- pmif = (struct pmac_ide_hwif)kzalloc(sizeof(*pmif), GFP_KERNEL);
+ pmif = (struct pmac_ide_hwif*)kzalloc(sizeof(*pmif), GFP_KERNEL);
if (pmif == NULL)
return -ENOMEM;
--
Thanks & Regards,
Kamalesh Babulal,
Linux Technology Center,
IBM, ISTL.
^ permalink raw reply
* Re: [PATCH 1/3] Fix Unlikely(x) == y
From: Geert Uytterhoeven @ 2008-02-18 14:01 UTC (permalink / raw)
To: Adrian Bunk
Cc: Roel Kluin, lkml, cbe-oss-dev, linuxppc-dev, Willy Tarreau,
Arjan van de Ven
In-Reply-To: <20080218135609.GD21080@cs181133002.pp.htv.fi>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 2637 bytes --]
On Mon, 18 Feb 2008, Adrian Bunk wrote:
> On Sun, Feb 17, 2008 at 10:50:03PM +1100, Michael Ellerman wrote:
> > On Sat, 2008-02-16 at 10:39 -0800, Arjan van de Ven wrote:
> >...
> > > for mordern (last 10 years) x86 cpus... the cpu branchpredictor is better
> > > than the coder in general. Same for most other architectures.
> > >
> > > unlikely() creates bigger code as well.
> > >
> > > Now... we're talking about your super duper hotpath function here right?
> > > One where you care about 0.5 cycle speed improvement? (less on modern
> > > systems ;)
> >
> > The first patch was to platforms/ps3 code, which runs on the Cell, in
> > particular the PPE ... which is not an x86 :)
> >
> > eg:
> >
> > [michael@schoenaich ~]$ cat branch.c
> > #include <stdio.h>
> > int main(void)
> > {
> > int i, j;
> >
> > for (i = 0, j = 0; i < 1000000000; i++)
> > if (i % 4 == 0)
> > j++;
> >
> > printf("j = %d\n", j);
> > return 0;
> > }
> > [michael@schoenaich ~]$ ppu-gcc -Wall -O3 -o branch branch.c
> > [michael@schoenaich ~]$ time ./branch
> > real 0m5.172s
> >
> > [michael@schoenaich ~]$ cat branch.c
> > ..
> > for (i = 0, j = 0; i < 1000000000; i++)
> > if (__builtin_expect(i % 4 == 0, 0))
> > j++;
> > ..
> > [michael@schoenaich ~]$ ppu-gcc -Wall -O3 -o branch branch.c
> > [michael@schoenaich ~]$ time ./branch
> > real 0m3.762s
> >
> >
> > Which looks as though unlikely() is helping. Admittedly we don't have a
> > lot of kernel code that looks like that, but at least unlikely is doing
> > what we want it to.
>
> This means it generates faster code with a current gcc for your platform.
>
> But a future gcc might e.g. replace the whole loop with a division
> (gcc SVN head (that will soon become gcc 4.3) already does
> transformations like replacing loops with divisions [1]).
Hence shouldn't we ask the gcc people what's the purpose of __builtin_expect(),
if it doesn't live up to its promise?
With kind regards,
Geert Uytterhoeven
Software Architect
Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
Phone: +32 (0)2 700 8453
Fax: +32 (0)2 700 8622
E-mail: Geert.Uytterhoeven@sonycom.com
Internet: http://www.sony-europe.com/
Sony Network and Software Technology Center Europe
A division of Sony Service Centre (Europe) N.V.
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium
VAT BE 0413.825.160 · RPR Brussels
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619
^ permalink raw reply
* Re: [PATCH 1/3] Fix Unlikely(x) == y
From: Adrian Bunk @ 2008-02-18 13:56 UTC (permalink / raw)
To: Michael Ellerman
Cc: Roel Kluin, lkml, cbe-oss-dev, linuxppc-dev, Willy Tarreau,
Arjan van de Ven
In-Reply-To: <1203249003.6718.24.camel@concordia>
On Sun, Feb 17, 2008 at 10:50:03PM +1100, Michael Ellerman wrote:
> On Sat, 2008-02-16 at 10:39 -0800, Arjan van de Ven wrote:
>...
> > for mordern (last 10 years) x86 cpus... the cpu branchpredictor is better
> > than the coder in general. Same for most other architectures.
> >
> > unlikely() creates bigger code as well.
> >
> > Now... we're talking about your super duper hotpath function here right?
> > One where you care about 0.5 cycle speed improvement? (less on modern
> > systems ;)
>
> The first patch was to platforms/ps3 code, which runs on the Cell, in
> particular the PPE ... which is not an x86 :)
>
> eg:
>
> [michael@schoenaich ~]$ cat branch.c
> #include <stdio.h>
> int main(void)
> {
> int i, j;
>
> for (i = 0, j = 0; i < 1000000000; i++)
> if (i % 4 == 0)
> j++;
>
> printf("j = %d\n", j);
> return 0;
> }
> [michael@schoenaich ~]$ ppu-gcc -Wall -O3 -o branch branch.c
> [michael@schoenaich ~]$ time ./branch
> real 0m5.172s
>
> [michael@schoenaich ~]$ cat branch.c
> ..
> for (i = 0, j = 0; i < 1000000000; i++)
> if (__builtin_expect(i % 4 == 0, 0))
> j++;
> ..
> [michael@schoenaich ~]$ ppu-gcc -Wall -O3 -o branch branch.c
> [michael@schoenaich ~]$ time ./branch
> real 0m3.762s
>
>
> Which looks as though unlikely() is helping. Admittedly we don't have a
> lot of kernel code that looks like that, but at least unlikely is doing
> what we want it to.
This means it generates faster code with a current gcc for your platform.
But a future gcc might e.g. replace the whole loop with a division
(gcc SVN head (that will soon become gcc 4.3) already does
transformations like replacing loops with divisions [1]).
And your __builtin_expect() then might have unwanted effects on gcc.
Or the kernel code changes much but the likely/unlikely stays unchanged
although it becomes wrong.
If it is a real hotpath in the kernel where you have _measurable_
performance advantages from using likely/unlikely it's usage might be
justified, but otherwise it shouldn't be used.
> cheers
cu
Adrian
[1] e.g. the while() loop in timespec_add_ns() in include/linux/time.h
gets replaced by a division and a modulo (whether this
transformation is correct in this specific case is a different
question, but that's the level of code transformation gcc already
does today)
--
"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed
^ permalink raw reply
* linux-next: ide pmac.c fix
From: Stephen Rothwell @ 2008-02-18 13:53 UTC (permalink / raw)
To: Bartlomiej Zolnierkiewicz; +Cc: ppc-dev, linux-next
[-- Attachment #1: Type: text/plain, Size: 314 bytes --]
Hi Bart,
the current linux-next produces this error for a pmac32 powerpc build:
drivers/ide/ppc/pmac.c:1094: error: conversion to non-scalar type requested
drivers/ide/ppc/pmac.c:1232: error: conversion to non-scalar type requested
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [Patch 2/2] powerpc: i2c-isa: add access check to legacy ioports
From: Jean Delvare @ 2008-02-18 13:31 UTC (permalink / raw)
To: Christian Krafft; +Cc: parabelboi, linuxppc-dev, linux-kernel
In-Reply-To: <20080213183701.254391cc@de.ibm.com>
Hi Christian,
On Wed, 13 Feb 2008 18:37:01 +0100, Christian Krafft wrote:
> when probing i2c-pca-isa writes to legacy ioports, which crashes the kernel
> if there is no device at that port.
> This patch adds a check_legacy_ioport call, so probe failes gracefully
> and thus prevents the oops.
>
> Signed-off-by: Christian Krafft <krafft@de.ibm.com>
>
> Index: linux.git/drivers/i2c/busses/i2c-pca-isa.c
> ===================================================================
> --- linux.git.orig/drivers/i2c/busses/i2c-pca-isa.c
> +++ linux.git/drivers/i2c/busses/i2c-pca-isa.c
> @@ -125,6 +125,13 @@ static int __devinit pca_isa_probe(struc
>
> dev_info(dev, "i/o base %#08lx. irq %d\n", base, irq);
>
> +#ifdef CONFIG_PPC_MERGE
> + if (check_legacy_ioport(base)) {
> + dev_err(dev, "I/O address %#08lx is not available\n", base);
> + goto out;
> + }
> +#endif
> +
> if (!request_region(base, IO_SIZE, "i2c-pca-isa")) {
> dev_err(dev, "I/O address %#08lx is in use\n", base);
> goto out;
>
I can apply this, no problem. That being said, you might alternatively
just exclude this driver from PPC. It's for a rare device with no known
user, the driver is unmaintained and will hopefully be replaced soon by
a platform driver which will not probe random ports at load time.
--
Jean Delvare
^ permalink raw reply
* Re: "make ARCH=ppc defconfig" fails looking for common_defconfig
From: Josh Boyer @ 2008-02-18 12:43 UTC (permalink / raw)
To: Robert P. J. Day; +Cc: Linux PPC Mailing List
In-Reply-To: <alpine.LFD.1.00.0802180430100.10518@localhost.localdomain>
On Mon, 18 Feb 2008 04:32:24 -0500 (EST)
"Robert P. J. Day" <rpjday@crashcourse.ca> wrote:
>
> (AIUI, the entire ppc/ architecture is going away, yes? which means
> i probably shouldn't care about any errors within. is that correct?
> even so, build errors should probably still be avoided for now.)
Yes, it's going away. There's really no longer support for anything
"common" in it now anyway. CHRP, POWER3 and POWER4 have been removed.
So have 83xx and 85xx.
Just let it go.
josh
^ permalink raw reply
* How to describe FPGA-based devices in the device tree ?
From: Laurent Pinchart @ 2008-02-18 12:43 UTC (permalink / raw)
To: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 2664 bytes --]
Hi everybody,
I'm (at last) trying to move from ARCH=ppc to ARCH=powerpc. After reading
Documentation/powerpc/booting-without-of.txt and various device trees in
arch/powerpc/boot/dts, I still don't know how to express some devices in the
device tree.
The target board has several devices on the processor local bus, as described
in the following device tree fragment.
localbus@f0010100 {
compatible = "fsl,mpc8260-localbus",
"fsl,pq2-localbus";
#address-cells = <2>;
#size-cells = <1>;
reg = <f0010100 60>;
ranges = <0 0 40000000 01000000
2 0 f2000000 00100000
3 0 f3000000 00100000
4 0 f4000000 00100000>;
flash@0,0 {
compatible = "cfi-flash";
reg = <0 0 01000000>;
bank-width = <2>;
};
nvram@2,0 {
compatible = "mtd-ram";
reg = <2 0 00100000>;
bank-width = <2>;
};
bcsr@3,0 {
device_type = "board-control";
reg = <3 0 00000020>;
};
fpga@4,0 {
reg = <4 0 00010000>;
};
};
The fourth device is a FPGA that contains several IP cores such as an
interrupt controller and a SD/MMC host controller. If I understand things
correctly, each IP core should have its own node in the device tree to allow
proper binding with device drivers. As booting-without-of.txt describes the
localbus node ranges as corresponding to a single chipselect and covering the
entire chipselect access window, I can't have nodes for each IP core as
children of the localbus node.
Should I put IP core nodes as children of the FPGA node ? If so, how do I map
addresses at the FPGA level ? A ranges property in the FPGA node would let me
map addresses in the FPGA scope to the localbus scope. However, as the
localbus scope use the chipselect number as its first address cell and 0 as
its second address cell, I don't see how I could translate offsets in the
FPGA into an address at the localbus scope.
Could anyone advice me regarding how to properly describe my hardware in the
device tree ?
Best regards,
--
Laurent Pinchart
CSE Semaphore Belgium
Chaussée de Bruxelles, 732A
B-1410 Waterloo
Belgium
T +32 (2) 387 42 59
F +32 (2) 387 42 75
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* mm section mismatch warnings for ps3
From: Geert Uytterhoeven @ 2008-02-18 12:14 UTC (permalink / raw)
To: Linux/PPC Development, Linux Kernel Development
[-- Attachment #1: Type: TEXT/PLAIN, Size: 5015 bytes --]
When building current mainline for ps3_defconfig, I get the following
mm-related section mismatches:
| WARNING: mm/built-in.o(.text+0x25094): Section mismatch in reference from the function .sparse_add_one_section() to the function .meminit.text:.sparse_index_init()
| The function .sparse_add_one_section() references
| the function __meminit .sparse_index_init().
| This is often because .sparse_add_one_section lacks a __meminit
| annotation or the annotation of .sparse_index_init is wrong.
|
| WARNING: mm/built-in.o(.text+0x25128): Section mismatch in reference from the function .sparse_add_one_section() to the function .meminit.text:.sparse_init_one_section()
| The function .sparse_add_one_section() references
| the function __meminit .sparse_init_one_section().
| This is often because .sparse_add_one_section lacks a __meminit
| annotation or the annotation of .sparse_init_one_section is wrong.
|
| WARNING: mm/built-in.o(.text+0x2c5fc): Section mismatch in reference from the function .__add_zone() to the function .meminit.text:.init_currently_empty_zone()
| The function .__add_zone() references
| the function __meminit .init_currently_empty_zone().
| This is often because .__add_zone lacks a __meminit
| annotation or the annotation of .init_currently_empty_zone is wrong.
|
| WARNING: mm/built-in.o(.text+0x2c628): Section mismatch in reference from the function .__add_zone() to the function .meminit.text:.memmap_init_zone()
| The function .__add_zone() references
| the function __meminit .memmap_init_zone().
| This is often because .__add_zone lacks a __meminit
| annotation or the annotation of .memmap_init_zone is wrong.
|
| WARNING: vmlinux.o(.text+0x7360): Section mismatch in reference from the function .start_secondary_prolog() to the function .devinit.text:.start_secondary()
| The function .start_secondary_prolog() references
| the function __devinit .start_secondary().
| This is often because .start_secondary_prolog lacks a __devinit
| annotation or the annotation of .start_secondary is wrong.
|
| WARNING: vmlinux.o(.text+0x1dea0): Section mismatch in reference from the function .move_device_tree() to the function .init.text:.lmb_alloc_base()
| The function .move_device_tree() references
| the function __init .lmb_alloc_base().
| This is often because .move_device_tree lacks a __init
| annotation or the annotation of .lmb_alloc_base is wrong.
|
| WARNING: vmlinux.o(.text+0xabd7c): Section mismatch in reference from the function .sparse_add_one_section() to the function .meminit.text:.sparse_index_init()
| The function .sparse_add_one_section() references
| the function __meminit .sparse_index_init().
| This is often because .sparse_add_one_section lacks a __meminit
| annotation or the annotation of .sparse_index_init is wrong.
|
| WARNING: vmlinux.o(.text+0xabe10): Section mismatch in reference from the function .sparse_add_one_section() to the function .meminit.text:.sparse_init_one_section()
| The function .sparse_add_one_section() references
| the function __meminit .sparse_init_one_section().
| This is often because .sparse_add_one_section lacks a __meminit
| annotation or the annotation of .sparse_init_one_section is wrong.
|
| WARNING: vmlinux.o(.text+0xb3198): Section mismatch in reference from the function .add_memory() to the function .devinit.text:.arch_add_memory()
| The function .add_memory() references
| the function __devinit .arch_add_memory().
| This is often because .add_memory lacks a __devinit
| annotation or the annotation of .arch_add_memory is wrong.
|
| WARNING: vmlinux.o(.text+0xb32e4): Section mismatch in reference from the function .__add_zone() to the function .meminit.text:.init_currently_empty_zone()
| The function .__add_zone() references
| the function __meminit .init_currently_empty_zone().
| This is often because .__add_zone lacks a __meminit
| annotation or the annotation of .init_currently_empty_zone is wrong.
|
| WARNING: vmlinux.o(.text+0xb3310): Section mismatch in reference from the function .__add_zone() to the function .meminit.text:.memmap_init_zone()
| The function .__add_zone() references
| the function __meminit .memmap_init_zone().
| This is often because .__add_zone lacks a __meminit
| annotation or the annotation of .memmap_init_zone is wrong.
(there are a few more regarding ps3_register_repository_device(), but these
cannot happen as only storage devices can be added later)
With kind regards,
Geert Uytterhoeven
Software Architect
Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
Phone: +32 (0)2 700 8453
Fax: +32 (0)2 700 8622
E-mail: Geert.Uytterhoeven@sonycom.com
Internet: http://www.sony-europe.com/
Sony Network and Software Technology Center Europe
A division of Sony Service Centre (Europe) N.V.
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium
VAT BE 0413.825.160 · RPR Brussels
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619
^ permalink raw reply
* EBC configuration for mmio
From: sunil dutt @ 2008-02-18 10:42 UTC (permalink / raw)
To: linuxppc-embedded
Hi,
We are working on the MMIO interface and are struck up at sending the data
over the interface on PPC405EXr.The following are the configurations done by
us to use EBC Bank3.
EBC0_B3CR = 0x80018000 /*Base address 0x800 size 1MB Read/Write set */
EBC0_B3AP = 0x07840f80
We have configured GPIO pin 10 (PER_CS3) for the chip select.The following
is the configuration for the CS .
OSRL : 00aa54aa
TSRL : 00aa54aa
ISR1L: XX(Dont care)
Here are our observations while doing the data transfer.
1.When the data of one byte is sent continuously we have observed that the
second write blocks and the chip select is not triggered for the second
transfer.
2.When one byte is sent and immediately we read the data over the interface
the read blocks and we also see that chip select is not triggered for the
read.
3.The point 2 mentioned above is not consistent.We some times read the value
from the interface though the chip select is not triggered.
Please could you verify our configurations.Please let us know if there is
any thing additional to be done.
Thanks and Regards,
Sunil
--
View this message in context: http://www.nabble.com/EBC-configuration-for-mmio-tp15542516p15542516.html
Sent from the linuxppc-embedded mailing list archive at Nabble.com.
^ permalink raw reply
* Re: [PATCH] drivers/base: export gpl (un)register_memory_notifier
From: Jan-Bernd Themann @ 2008-02-18 10:00 UTC (permalink / raw)
To: linuxppc-dev
Cc: Thomas Q Klein, ossthema, Jan-Bernd Themann, Greg KH, Dave Hansen,
apw, linux-kernel, Christoph Raisch, Badari Pulavarty, netdev,
tklein
In-Reply-To: <1203094538.8142.23.camel@nimitz.home.sr71.net>
switching to proper mail client...
Dave Hansen <haveblue@us.ibm.com> wrote on 15.02.2008 17:55:38:
> I've been thinking about that, and I don't think you really *need* to
> keep a comprehensive map like that.=20
>=20
> When the memory is in a particular configuration (range of memory
> present along with unique set of holes) you get a unique ehea_bmap
> configuration. =A0That layout is completely predictable.
>=20
> So, if at any time you want to figure out what the ehea_bmap address for
> a particular *Linux* virtual address is, you just need to pretend that
> you're creating the entire ehea_bmap, use the same algorithm and figure
> out host you would have placed things, and use that result.
>=20
> Now, that's going to be a slow, crappy linear search (but maybe not as
> slow as recreating the silly thing). =A0So, you might eventually run into
> some scalability problems with a lot of packets going around. =A0But, I'd
> be curious if you do in practice.
Up to 14 addresses translation per packet (sg_list) might be required on=20
the transmit side. On receive side it is only 1. Most packets require only=
=20
very few translations (1 or sometimes more) =A0translations. However,=20
with more then 700.000 packets per second this approach does not seem=20
reasonable from performance perspective when memory is fragmented as you
described.
>=20
> The other idea is that you create a mapping that is precisely 1:1 with
> kernel memory. =A0Let's say you have two sections present, 0 and 100. =A0=
You
> have a high_section_index of 100, and you vmalloc() a 100 entry array.
>=20
> You need to create a *CONTIGUOUS* ehea map? =A0Create one like this:
>=20
> EHEA_VADDR->Linux Section
> 0->0
> 1->0
> 2->0
> 3->0
> ...
> 100->100
>=20
> It's contiguous. =A0Each area points to a valid Linux memory address.
> It's also discernable in O(1) to what EHEA address a given Linux address
> is mapped. =A0You just have a couple of duplicate entries.=20
This has a serious issues with constraint I mentions in the previous mail:=
=20
"- MRs can have a maximum size of the memory available under linux"
The requirement is not met that the memory region must not be=20
larger then the available memory for that partition. The "create MR"=20
H_CALL will fails (we tried this and discussed with FW development)
Regards,
Jan-Bernd & Christoph
^ permalink raw reply
* Re: [PATCH] drivers/base: export gpl (un)register_memory_notifier
From: Jan-Bernd Themann @ 2008-02-18 9:56 UTC (permalink / raw)
To: Dave Hansen
Cc: Thomas Q Klein, ossthema, Greg KH, apw, linux-kernel,
linuxppc-dev, Christoph Raisch, Badari Pulavarty, netdev, tklein
In-Reply-To: <1203094538.8142.23.camel@nimitz.home.sr71.net>
[-- Attachment #1: Type: text/plain, Size: 2256 bytes --]
Dave Hansen <haveblue@us.ibm.com> wrote on 15.02.2008 17:55:38:
> I've been thinking about that, and I don't think you really *need* to
> keep a comprehensive map like that.
>
> When the memory is in a particular configuration (range of memory
> present along with unique set of holes) you get a unique ehea_bmap
> configuration. That layout is completely predictable.
>
> So, if at any time you want to figure out what the ehea_bmap address for
> a particular *Linux* virtual address is, you just need to pretend that
> you're creating the entire ehea_bmap, use the same algorithm and figure
> out host you would have placed things, and use that result.
>
> Now, that's going to be a slow, crappy linear search (but maybe not as
> slow as recreating the silly thing). So, you might eventually run into
> some scalability problems with a lot of packets going around. But, I'd
> be curious if you do in practice.
Up to 14 addresses translation per packet (sg_list) might be required on
the
transmit side. On receive side it is only 1. Most packets require only
very few
translations (1 or sometimes more) translations. However, with more then
700.000
packets per second this approach does not seem reasonable from performance
perspective when memory is fragmented as you described.
>
> The other idea is that you create a mapping that is precisely 1:1 with
> kernel memory. Let's say you have two sections present, 0 and 100. You
> have a high_section_index of 100, and you vmalloc() a 100 entry array.
>
> You need to create a *CONTIGUOUS* ehea map? Create one like this:
>
> EHEA_VADDR->Linux Section
> 0->0
> 1->0
> 2->0
> 3->0
> ...
> 100->100
>
> It's contiguous. Each area points to a valid Linux memory address.
> It's also discernable in O(1) to what EHEA address a given Linux address
> is mapped. You just have a couple of duplicate entries.
This has a serious issues with constraint I mentions in the previous mail:
"- MRs can have a maximum size of the memory available under linux"
The requirement is not met that the memory region must not be
larger then the available memory for that partition. The "create MR"
H_CALL
will fails (we tried this and discussed with FW development)
Regards,
Jan-Bernd & Christoph
[-- Attachment #2: Type: text/html, Size: 4038 bytes --]
^ permalink raw reply
* "make ARCH=ppc defconfig" fails looking for common_defconfig
From: Robert P. J. Day @ 2008-02-18 9:32 UTC (permalink / raw)
To: Linux PPC Mailing List
(AIUI, the entire ppc/ architecture is going away, yes? which means
i probably shouldn't care about any errors within. is that correct?
even so, build errors should probably still be avoided for now.)
$ make ARCH=ppc defconfig
HOSTCC scripts/basic/fixdep
HOSTCC scripts/basic/docproc
HOSTCC scripts/kconfig/conf.o
HOSTCC scripts/kconfig/kxgettext.o
SHIPPED scripts/kconfig/zconf.tab.c
SHIPPED scripts/kconfig/lex.zconf.c
SHIPPED scripts/kconfig/zconf.hash.c
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/conf
*** Default configuration is based on 'common_defconfig'
***
*** Can't find default configuration "arch/ppc/configs/common_defconfig"!
***
make[1]: *** [defconfig] Error 1
make: *** [defconfig] Error 2
rday
--
========================================================================
Robert P. J. Day
Linux Consulting, Training and Annoying Kernel Pedantry:
Have classroom, will lecture.
http://crashcourse.ca Waterloo, Ontario, CANADA
========================================================================
^ permalink raw reply
* Re: [Linux-fbdev-devel] [PATCH 1/2] fb: add support for foreign endianness
From: Krzysztof Helt @ 2008-02-18 7:18 UTC (permalink / raw)
To: linux-fbdev-devel
Cc: adaplas, linux-kernel, linuxppc-dev, Geert Uytterhoeven,
Andrew Morton
In-Reply-To: <Pine.LNX.4.64.0802171030330.6848@anakin>
On Sun, 17 Feb 2008 10:44:32 +0100 (CET)
Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> On Fri, 15 Feb 2008, Anton Vorontsov wrote:
> > On Thu, Feb 14, 2008 at 10:49:42PM -0800, Andrew Morton wrote:
> > > On Tue, 5 Feb 2008 18:44:32 +0300 Anton Vorontsov <avorontsov@ru.mvista.com> wrote:
> > > Actually... should CONFIG_FB_FOREIGN_ENDIAN exist, or should this feature
> > > be permanently enabled?
> >
(...)
>
> The notion of `FOREIGN_ENDIAN' is relative, as it depends on the
> architecture you're compiling for.
>
> Suppose you have a PCI graphics card with a frame buffer that's always
> big endian. When compiling for a big endian platform, the driver won't
> depend on FB_FOREIGN_ENDIAN. When compiling for a little endian
> platform, it will.
>
> Shouldn't we add LITTLE_ENDIAN and BIG_ENDIAN Kconfig vars first, just
> like we have 64BIT?
>
I disagree here. The FOREIGN_ENDIAN is enough. It is determined only by
graphics chip endianess and CPU (arch) endianess.
I know two fb drivers which use endianess information (pm2fb and s3c2410fb).
Both resolve endianess at driver level. Actually, both handle it by setting special
bits so the graphics chip itself reorder bytes to transform foreign endianess.
I understand that this patch is for chips which cannot reorder bytes by themselves.
So the FOREIGN_ENDIANESS flag should be set by the driver if it is needed
(if the graphics chip is BE and CPU is LE a simple #ifdef will add the flag).
>
> I'd like to handle this in Kconfig (cfr. above).
>
Again, it is possible. It is enough to put one rule which enables
the FOREIGN_ENDIAN if the architecture endianess is "foreign"
for the driver. The advantage here is that it can be set only
for drivers which need it (as some driver can handle it without
this code). It should be hidden option set only internally if needed
(no user selectable).
I tested this patch on the s3c2410fb with disabled byte order
corrections by the graphics chip itself. It worked for 8-bit depth
but not for 16-bit depth (pixel position seemed ok but wrong tux'
colors). I will investigate. The s3c2410fb is BE and the kernel
was arm LE.
I would like to extend this patch to fb depths below 8-bit. The
s3c2410fb cannot handle this correctly with LE kernel.
Kind regards,
Krzysztof
----------------------------------------------------------------------
Masz ostatnia szanse !
Sprawdz >>> http://link.interia.pl/f1d02
^ permalink raw reply
* RE: [PATCH 4/6] Add multi mport support.
From: Zhang Wei @ 2008-02-18 7:33 UTC (permalink / raw)
To: Matt Porter; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20080205162942.GB20177@gate.crashing.org>
Hi, Matt,
So glad to see you again!
> -----Original Message-----
> From: Matt Porter [mailto:mporter@kernel.crashing.org]=20
> On Thu, Jan 31, 2008 at 02:30:13PM +0800, Zhang Wei wrote:
> > > -----Original Message-----
> > > From: Kumar Gala [mailto:galak@kernel.crashing.org]=20
> > > when we have multiple ports are the device IDs on the=20
> ports intended =20
> > > to be unique only to a port or unique across all ports?
> > >=20
> > I consider each RIO controller will has its own network,=20
> the device IDs
> > should be
> > unique only in its port network.
>=20
> This is a bad assumption IMHO. It pushes policy on to the system
> designer of a RapidIO network.
I know it is a real bad assumption. However, the RIO initial ID is only
transported to
driver by kernel parameter "riohdid", which can not distinguish the
multi
rio controllers. It may be more better add a "rio-id" property in RIO
dts node, but
the u-boot need some changes to support the rio-id assignment.
Cheers!
Wei.
^ permalink raw reply
* RE: [PATCH 5/6] Add OF-tree support to RapidIO controller driver.
From: Zhang Wei @ 2008-02-18 7:24 UTC (permalink / raw)
To: Kumar Gala, Stephen Rothwell; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <4A9328DB-F68C-4C09-B762-44FEA85DD12E@kernel.crashing.org>
=20
> -----Original Message-----
> From: Kumar Gala [mailto:galak@kernel.crashing.org]=20
>=20
>=20
> On Feb 4, 2008, at 11:44 PM, Stephen Rothwell wrote:
>=20
> >>
> >> + aw =3D *(u32 *)of_get_property(dev->node, "#address-cells", =
NULL);
> >> + sw =3D *(u32 *)of_get_property(dev->node, "#size-cells", NULL);
> >
> > What happens if either of these properties is missing?
>=20
> Should we add __must_check to of_get_property?
>=20
You are right, I'll add the checking here.
Thanks!
Wei.
^ permalink raw reply
* libfdt: Remove no longer used code from fdt_node_offset_by_compatible()
From: David Gibson @ 2008-02-18 7:09 UTC (permalink / raw)
To: Jon Loeliger; +Cc: linuxppc-dev
Since fdt_node_offset_by_compatible() was converted to the new
fdt_next_node() iterator, a chunk of initialization code became
redundant, but was not removed by oversight. This patch cleans it up.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Index: dtc/libfdt/fdt_ro.c
===================================================================
--- dtc.orig/libfdt/fdt_ro.c 2008-02-18 18:02:01.000000000 +1100
+++ dtc/libfdt/fdt_ro.c 2008-02-18 18:06:33.000000000 +1100
@@ -453,20 +453,10 @@ int fdt_node_check_compatible(const void
int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
const char *compatible)
{
- uint32_t tag;
- int offset, nextoffset;
- int err;
+ int offset, err;
CHECK_HEADER(fdt);
- if (startoffset >= 0) {
- tag = fdt_next_tag(fdt, startoffset, &nextoffset);
- if (tag != FDT_BEGIN_NODE)
- return -FDT_ERR_BADOFFSET;
- } else {
- nextoffset = 0;
- }
-
/* FIXME: The algorithm here is pretty horrible: we scan each
* property of a node in fdt_node_check_compatible(), then if
* that didn't find what we want, we scan over them again
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* libfdt: Trivial cleanup for CHECK_HEADER)
From: David Gibson @ 2008-02-18 7:06 UTC (permalink / raw)
To: Jon Loeliger; +Cc: linuxppc-dev
Currently the CHECK_HEADER() macro is defined local to fdt_ro.c.
However, there are a handful of functions (fdt_move, rw_check_header,
fdt_open_into) from other files which could also use it (currently
they open-code something more-or-less identical). Therefore, this
patch moves CHECK_HEADER() to libfdt_internal.h and uses it in those
places.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
libfdt/fdt.c | 5 +----
libfdt/fdt_ro.c | 7 -------
libfdt/fdt_rw.c | 8 ++------
libfdt/libfdt_internal.h | 7 +++++++
4 files changed, 10 insertions(+), 17 deletions(-)
Index: dtc/libfdt/fdt.c
===================================================================
--- dtc.orig/libfdt/fdt.c 2008-02-18 18:01:59.000000000 +1100
+++ dtc/libfdt/fdt.c 2008-02-18 18:02:01.000000000 +1100
@@ -184,10 +184,7 @@ const char *_fdt_find_string(const char
int fdt_move(const void *fdt, void *buf, int bufsize)
{
- int err = fdt_check_header(fdt);
-
- if (err)
- return err;
+ CHECK_HEADER(fdt);
if (fdt_totalsize(fdt) > bufsize)
return -FDT_ERR_NOSPACE;
Index: dtc/libfdt/fdt_ro.c
===================================================================
--- dtc.orig/libfdt/fdt_ro.c 2008-02-18 18:01:59.000000000 +1100
+++ dtc/libfdt/fdt_ro.c 2008-02-18 18:02:01.000000000 +1100
@@ -55,13 +55,6 @@
#include "libfdt_internal.h"
-#define CHECK_HEADER(fdt) \
- { \
- int err; \
- if ((err = fdt_check_header(fdt)) != 0) \
- return err; \
- }
-
static int nodename_eq(const void *fdt, int offset,
const char *s, int len)
{
Index: dtc/libfdt/libfdt_internal.h
===================================================================
--- dtc.orig/libfdt/libfdt_internal.h 2008-02-18 18:01:59.000000000 +1100
+++ dtc/libfdt/libfdt_internal.h 2008-02-18 18:02:01.000000000 +1100
@@ -58,6 +58,13 @@
#define memeq(p, q, n) (memcmp((p), (q), (n)) == 0)
#define streq(p, q) (strcmp((p), (q)) == 0)
+#define CHECK_HEADER(fdt) \
+ { \
+ int err; \
+ if ((err = fdt_check_header(fdt)) != 0) \
+ return err; \
+ }
+
uint32_t _fdt_next_tag(const void *fdt, int startoffset, int *nextoffset);
const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
int _fdt_node_end_offset(void *fdt, int nodeoffset);
Index: dtc/libfdt/fdt_rw.c
===================================================================
--- dtc.orig/libfdt/fdt_rw.c 2008-02-18 18:02:52.000000000 +1100
+++ dtc/libfdt/fdt_rw.c 2008-02-18 18:04:00.000000000 +1100
@@ -69,10 +69,8 @@ static int _blocks_misordered(const void
static int rw_check_header(void *fdt)
{
- int err;
+ CHECK_HEADER(fdt);
- if ((err = fdt_check_header(fdt)))
- return err;
if (fdt_version(fdt) < 17)
return -FDT_ERR_BADVERSION;
if (_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry),
@@ -399,9 +397,7 @@ int fdt_open_into(const void *fdt, void
int newsize;
void *tmp;
- err = fdt_check_header(fdt);
- if (err)
- return err;
+ CHECK_HEADER(fdt);
mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
* sizeof(struct fdt_reserve_entry);
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* [PATCH 8/8] pseries: phyp dump: config file
From: Manish Ahuja @ 2008-02-18 5:45 UTC (permalink / raw)
To: ppc-dev, paulus, Linas Vepstas; +Cc: mahuja
In-Reply-To: <47B90F55.2080606@austin.ibm.com>
Add hypervisor-assisted dump to kernel config
Signed-off-by: Linas Vepstas <linasvepstas@gmail.com>
-----
arch/powerpc/Kconfig | 11 +++++++++++
1 file changed, 11 insertions(+)
Index: 2.6.25-rc1/arch/powerpc/Kconfig
===================================================================
--- 2.6.25-rc1.orig/arch/powerpc/Kconfig 2008-02-18 03:22:06.000000000 -0600
+++ 2.6.25-rc1/arch/powerpc/Kconfig 2008-02-18 03:22:45.000000000 -0600
@@ -306,6 +306,17 @@ config CRASH_DUMP
Don't change this unless you know what you are doing.
+config PHYP_DUMP
+ bool "Hypervisor-assisted dump (EXPERIMENTAL)"
+ depends on PPC_PSERIES && EXPERIMENTAL
+ default y
+ help
+ Hypervisor-assisted dump is meant to be a kdump replacement
+ offering robustness and speed not possible without system
+ hypervisor assistence.
+
+ If unsure, say "Y"
+
config PPCBUG_NVRAM
bool "Enable reading PPCBUG NVRAM during boot" if PPLUS || LOPEC
default y if PPC_PREP
^ permalink raw reply
* [PATCH 7/8] pseries: phyp dump: Tracking memory range freed.
From: Manish Ahuja @ 2008-02-18 5:44 UTC (permalink / raw)
To: ppc-dev, paulus, Linas Vepstas; +Cc: mahuja
In-Reply-To: <47B90F55.2080606@austin.ibm.com>
This patch tracks the size freed. For now it does a simple
rudimentary calculation of the ranges freed. The idea is
to keep it simple at the external shell script level and
send in large chunks for now.
Signed-off-by: Manish Ahuja <mahuja@us.ibm.com>
-----
---
arch/powerpc/platforms/pseries/phyp_dump.c | 35 +++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
Index: 2.6.25-rc1/arch/powerpc/platforms/pseries/phyp_dump.c
===================================================================
--- 2.6.25-rc1.orig/arch/powerpc/platforms/pseries/phyp_dump.c 2008-02-18 03:31:22.000000000 -0600
+++ 2.6.25-rc1/arch/powerpc/platforms/pseries/phyp_dump.c 2008-02-18 03:31:30.000000000 -0600
@@ -260,6 +260,39 @@ void release_memory_range(unsigned long
}
}
+/**
+ * track_freed_range -- Counts the range being freed.
+ * Once the counter goes to zero, it re-registers dump for
+ * future use.
+ */
+static void
+track_freed_range(unsigned long addr, unsigned long length)
+{
+ static unsigned long scratch_area_size, reserved_area_size;
+
+ if (addr < phyp_dump_info->init_reserve_start)
+ return;
+
+ if ((addr >= phyp_dump_info->init_reserve_start) &&
+ (addr <= phyp_dump_info->init_reserve_start +
+ phyp_dump_info->init_reserve_size))
+ reserved_area_size += length;
+
+ if ((addr >= phyp_dump_info->reserved_scratch_addr) &&
+ (addr <= phyp_dump_info->reserved_scratch_addr +
+ phyp_dump_info->reserved_scratch_size))
+ scratch_area_size += length;
+
+ if ((reserved_area_size == phyp_dump_info->init_reserve_size) &&
+ (scratch_area_size == phyp_dump_info->reserved_scratch_size)) {
+
+ invalidate_last_dump(&phdr,
+ phyp_dump_info->reserved_scratch_addr);
+ register_dump_area(&phdr,
+ phyp_dump_info->reserved_scratch_addr);
+ }
+}
+
/* ------------------------------------------------- */
/**
* sysfs_release_region -- sysfs interface to release memory range.
@@ -284,6 +317,8 @@ static ssize_t store_release_region(stru
if (ret != 2)
return -EINVAL;
+ track_freed_range(start_addr, length);
+
/* Range-check - don't free any reserved memory that
* wasn't reserved for phyp-dump */
if (start_addr < phyp_dump_info->init_reserve_start)
^ permalink raw reply
* [PATCH 6/8] pseries: phyp dump: Invalidate and print dump areas.
From: Manish Ahuja @ 2008-02-18 5:42 UTC (permalink / raw)
To: ppc-dev, paulus, Linas Vepstas; +Cc: mahuja
In-Reply-To: <47B90F55.2080606@austin.ibm.com>
Routines to
a. invalidate dump
b. Calculate region that is reserved and needs to be freed. This is
exported through sysfs interface.
Unregister has been removed for now as it wasn't being used.
Signed-off-by: Manish Ahuja <mahuja@us.ibm.com>
-----
---
arch/powerpc/platforms/pseries/phyp_dump.c | 83 ++++++++++++++++++++++++++---
include/asm-powerpc/phyp_dump.h | 3 +
2 files changed, 80 insertions(+), 6 deletions(-)
Index: 2.6.25-rc1/arch/powerpc/platforms/pseries/phyp_dump.c
===================================================================
--- 2.6.25-rc1.orig/arch/powerpc/platforms/pseries/phyp_dump.c 2008-02-18 04:25:19.000000000 -0600
+++ 2.6.25-rc1/arch/powerpc/platforms/pseries/phyp_dump.c 2008-02-18 04:25:32.000000000 -0600
@@ -69,6 +69,10 @@ static struct phyp_dump_header phdr;
#define DUMP_SOURCE_CPU 0x0001
#define DUMP_SOURCE_HPTE 0x0002
#define DUMP_SOURCE_RMO 0x0011
+#define DUMP_ERROR_FLAG 0x2000
+#define DUMP_TRIGGERED 0x4000
+#define DUMP_PERFORMED 0x8000
+
/**
* init_dump_header() - initialize the header declaring a dump
@@ -180,9 +184,15 @@ static void print_dump_header(const stru
static void register_dump_area(struct phyp_dump_header *ph, unsigned long addr)
{
int rc;
- ph->cpu_data.destination_address += addr;
- ph->hpte_data.destination_address += addr;
- ph->kernel_data.destination_address += addr;
+
+ /* Add addr value if not initialized before */
+ if (ph->cpu_data.destination_address == 0) {
+ ph->cpu_data.destination_address += addr;
+ ph->hpte_data.destination_address += addr;
+ ph->kernel_data.destination_address += addr;
+ }
+
+ /* ToDo Invalidate kdump and free memory range. */
do {
rc = rtas_call(ibm_configure_kernel_dump, 3, 1, NULL,
@@ -196,6 +206,30 @@ static void register_dump_area(struct ph
}
}
+static
+void invalidate_last_dump(struct phyp_dump_header *ph, unsigned long addr)
+{
+ int rc;
+
+ /* Add addr value if not initialized before */
+ if (ph->cpu_data.destination_address == 0) {
+ ph->cpu_data.destination_address += addr;
+ ph->hpte_data.destination_address += addr;
+ ph->kernel_data.destination_address += addr;
+ }
+
+ do {
+ rc = rtas_call(ibm_configure_kernel_dump, 3, 1, NULL,
+ 2, ph, sizeof(struct phyp_dump_header));
+ } while (rtas_busy_delay(rc));
+
+ if (rc) {
+ printk(KERN_ERR "phyp-dump: unexpected error (%d) "
+ "on invalidate\n", rc);
+ print_dump_header(ph);
+ }
+}
+
/* ------------------------------------------------- */
/**
* release_memory_range -- release memory previously lmb_reserved
@@ -206,8 +240,8 @@ static void register_dump_area(struct ph
* lmb_reserved in early boot. The released memory becomes
* available for genreal use.
*/
-static void
-release_memory_range(unsigned long start_pfn, unsigned long nr_pages)
+static
+void release_memory_range(unsigned long start_pfn, unsigned long nr_pages)
{
struct page *rpage;
unsigned long end_pfn;
@@ -268,8 +302,29 @@ static ssize_t store_release_region(stru
return count;
}
+static ssize_t show_release_region(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ u64 second_addr_range;
+
+ /* total reserved size - start of scratch area */
+ second_addr_range = phyp_dump_info->init_reserve_size -
+ phyp_dump_info->reserved_scratch_size;
+ return sprintf(buf, "CPU:0x%lx-0x%lx: HPTE:0x%lx-0x%lx:"
+ " DUMP:0x%lx-0x%lx, 0x%lx-0x%lx:\n",
+ phdr.cpu_data.destination_address,
+ phdr.cpu_data.length_copied,
+ phdr.hpte_data.destination_address,
+ phdr.hpte_data.length_copied,
+ phdr.kernel_data.destination_address,
+ phdr.kernel_data.length_copied,
+ phyp_dump_info->init_reserve_start,
+ second_addr_range);
+}
+
static struct kobj_attribute rr = __ATTR(release_region, 0600,
- NULL, store_release_region);
+ show_release_region,
+ store_release_region);
static int __init phyp_dump_setup(void)
{
@@ -312,6 +367,22 @@ static int __init phyp_dump_setup(void)
return 0;
}
+ /* re-register the dump area, if old dump was invalid */
+ if ((dump_header) && (dump_header->status & DUMP_ERROR_FLAG)) {
+ invalidate_last_dump(&phdr, dump_area_start);
+ register_dump_area(&phdr, dump_area_start);
+ return 0;
+ }
+
+ if (dump_header) {
+ phyp_dump_info->reserved_scratch_addr =
+ dump_header->cpu_data.destination_address;
+ phyp_dump_info->reserved_scratch_size =
+ dump_header->cpu_data.source_length +
+ dump_header->hpte_data.source_length +
+ dump_header->kernel_data.source_length;
+ }
+
/* Should we create a dump_subsys, analogous to s390/ipl.c ? */
rc = sysfs_create_file(kernel_kobj, &rr.attr);
if (rc)
Index: 2.6.25-rc1/include/asm-powerpc/phyp_dump.h
===================================================================
--- 2.6.25-rc1.orig/include/asm-powerpc/phyp_dump.h 2008-02-18 04:24:16.000000000 -0600
+++ 2.6.25-rc1/include/asm-powerpc/phyp_dump.h 2008-02-18 04:25:32.000000000 -0600
@@ -30,6 +30,9 @@ struct phyp_dump {
/* store cpu & hpte size */
unsigned long cpu_state_size;
unsigned long hpte_region_size;
+ /* previous scratch area values */
+ unsigned long reserved_scratch_addr;
+ unsigned long reserved_scratch_size;
};
extern struct phyp_dump *phyp_dump_info;
^ permalink raw reply
* [PATCH 5/8] pseries: phyp dump: debugging print routines.
From: Manish Ahuja @ 2008-02-18 5:41 UTC (permalink / raw)
To: ppc-dev, paulus, Linas Vepstas; +Cc: mahuja
In-Reply-To: <47B90F55.2080606@austin.ibm.com>
Provide some basic debugging support.
Signed-off-by: Manish Ahuja <mahuja@us.ibm.com>
Signed-off-by: Linas Vepstas <linasvepstas@gmail.com>
-----
arch/powerpc/platforms/pseries/phyp_dump.c | 61 ++++++++++++++++++++++++++++-
1 file changed, 59 insertions(+), 2 deletions(-)
Index: 2.6.25-rc1/arch/powerpc/platforms/pseries/phyp_dump.c
===================================================================
--- 2.6.25-rc1.orig/arch/powerpc/platforms/pseries/phyp_dump.c 2008-02-18 03:30:53.000000000 -0600
+++ 2.6.25-rc1/arch/powerpc/platforms/pseries/phyp_dump.c 2008-02-18 04:25:19.000000000 -0600
@@ -122,6 +122,61 @@ static unsigned long init_dump_header(st
return addr_offset;
}
+static void print_dump_header(const struct phyp_dump_header *ph)
+{
+#ifdef DEBUG
+ printk(KERN_INFO "dump header:\n");
+ /* setup some ph->sections required */
+ printk(KERN_INFO "version = %d\n", ph->version);
+ printk(KERN_INFO "Sections = %d\n", ph->num_of_sections);
+ printk(KERN_INFO "Status = 0x%x\n", ph->status);
+
+ /* No ph->disk, so all should be set to 0 */
+ printk(KERN_INFO "Offset to first section 0x%x\n",
+ ph->first_offset_section);
+ printk(KERN_INFO "dump disk sections should be zero\n");
+ printk(KERN_INFO "dump disk section = %d\n", ph->dump_disk_section);
+ printk(KERN_INFO "block num = %ld\n", ph->block_num_dd);
+ printk(KERN_INFO "number of blocks = %ld\n", ph->num_of_blocks_dd);
+ printk(KERN_INFO "dump disk offset = %d\n", ph->offset_dd);
+ printk(KERN_INFO "Max auto time= %d\n", ph->maxtime_to_auto);
+
+ /*set cpu state and hpte states as well scratch pad area */
+ printk(KERN_INFO " CPU AREA \n");
+ printk(KERN_INFO "cpu dump_flags =%d\n", ph->cpu_data.dump_flags);
+ printk(KERN_INFO "cpu source_type =%d\n", ph->cpu_data.source_type);
+ printk(KERN_INFO "cpu error_flags =%d\n", ph->cpu_data.error_flags);
+ printk(KERN_INFO "cpu source_address =%lx\n",
+ ph->cpu_data.source_address);
+ printk(KERN_INFO "cpu source_length =%lx\n",
+ ph->cpu_data.source_length);
+ printk(KERN_INFO "cpu length_copied =%lx\n",
+ ph->cpu_data.length_copied);
+
+ printk(KERN_INFO " HPTE AREA \n");
+ printk(KERN_INFO "HPTE dump_flags =%d\n", ph->hpte_data.dump_flags);
+ printk(KERN_INFO "HPTE source_type =%d\n", ph->hpte_data.source_type);
+ printk(KERN_INFO "HPTE error_flags =%d\n", ph->hpte_data.error_flags);
+ printk(KERN_INFO "HPTE source_address =%lx\n",
+ ph->hpte_data.source_address);
+ printk(KERN_INFO "HPTE source_length =%lx\n",
+ ph->hpte_data.source_length);
+ printk(KERN_INFO "HPTE length_copied =%lx\n",
+ ph->hpte_data.length_copied);
+
+ printk(KERN_INFO " SRSD AREA \n");
+ printk(KERN_INFO "SRSD dump_flags =%d\n", ph->kernel_data.dump_flags);
+ printk(KERN_INFO "SRSD source_type =%d\n", ph->kernel_data.source_type);
+ printk(KERN_INFO "SRSD error_flags =%d\n", ph->kernel_data.error_flags);
+ printk(KERN_INFO "SRSD source_address =%lx\n",
+ ph->kernel_data.source_address);
+ printk(KERN_INFO "SRSD source_length =%lx\n",
+ ph->kernel_data.source_length);
+ printk(KERN_INFO "SRSD length_copied =%lx\n",
+ ph->kernel_data.length_copied);
+#endif
+}
+
static void register_dump_area(struct phyp_dump_header *ph, unsigned long addr)
{
int rc;
@@ -134,9 +189,11 @@ static void register_dump_area(struct ph
1, ph, sizeof(struct phyp_dump_header));
} while (rtas_busy_delay(rc));
- if (rc)
+ if (rc) {
printk(KERN_ERR "phyp-dump: unexpected error (%d) on "
"register\n", rc);
+ print_dump_header(ph);
+ }
}
/* ------------------------------------------------- */
@@ -245,8 +302,8 @@ static int __init phyp_dump_setup(void)
of_node_put(rtas);
}
+ print_dump_header(dump_header);
dump_area_length = init_dump_header(&phdr);
-
/* align down */
dump_area_start = phyp_dump_info->init_reserve_start & PAGE_MASK;
^ permalink raw reply
* [PATCH 4/8] pseries: phyp dump: register dump area.
From: Manish Ahuja @ 2008-02-18 5:40 UTC (permalink / raw)
To: ppc-dev, paulus, Linas Vepstas; +Cc: mahuja
In-Reply-To: <47B90F55.2080606@austin.ibm.com>
Set up the actual dump header, register it with the hypervisor.
Signed-off-by: Manish Ahuja <mahuja@us.ibm.com>
Signed-off-by: Linas Vepstas <linasvepstas@gmail.com>
------
arch/powerpc/platforms/pseries/phyp_dump.c | 137 +++++++++++++++++++++++++++--
1 file changed, 131 insertions(+), 6 deletions(-)
Index: 2.6.25-rc1/arch/powerpc/platforms/pseries/phyp_dump.c
===================================================================
--- 2.6.25-rc1.orig/arch/powerpc/platforms/pseries/phyp_dump.c 2008-02-18 03:26:56.000000000 -0600
+++ 2.6.25-rc1/arch/powerpc/platforms/pseries/phyp_dump.c 2008-02-18 04:30:28.000000000 -0600
@@ -28,6 +28,117 @@
static struct phyp_dump phyp_dump_global;
struct phyp_dump *phyp_dump_info = &phyp_dump_global;
+static int ibm_configure_kernel_dump;
+/* ------------------------------------------------- */
+/* RTAS interfaces to declare the dump regions */
+
+struct dump_section {
+ u32 dump_flags;
+ u16 source_type;
+ u16 error_flags;
+ u64 source_address;
+ u64 source_length;
+ u64 length_copied;
+ u64 destination_address;
+};
+
+struct phyp_dump_header {
+ u32 version;
+ u16 num_of_sections;
+ u16 status;
+
+ u32 first_offset_section;
+ u32 dump_disk_section;
+ u64 block_num_dd;
+ u64 num_of_blocks_dd;
+ u32 offset_dd;
+ u32 maxtime_to_auto;
+ /* No dump disk path string used */
+
+ struct dump_section cpu_data;
+ struct dump_section hpte_data;
+ struct dump_section kernel_data;
+};
+
+/* The dump header *must be* in low memory, so .bss it */
+static struct phyp_dump_header phdr;
+
+#define NUM_DUMP_SECTIONS 3
+#define DUMP_HEADER_VERSION 0x1
+#define DUMP_REQUEST_FLAG 0x1
+#define DUMP_SOURCE_CPU 0x0001
+#define DUMP_SOURCE_HPTE 0x0002
+#define DUMP_SOURCE_RMO 0x0011
+
+/**
+ * init_dump_header() - initialize the header declaring a dump
+ * Returns: length of dump save area.
+ *
+ * When the hypervisor saves crashed state, it needs to put
+ * it somewhere. The dump header tells the hypervisor where
+ * the data can be saved.
+ */
+static unsigned long init_dump_header(struct phyp_dump_header *ph)
+{
+ unsigned long addr_offset = 0;
+
+ /* Set up the dump header */
+ ph->version = DUMP_HEADER_VERSION;
+ ph->num_of_sections = NUM_DUMP_SECTIONS;
+ ph->status = 0;
+
+ ph->first_offset_section =
+ (u32)offsetof(struct phyp_dump_header, cpu_data);
+ ph->dump_disk_section = 0;
+ ph->block_num_dd = 0;
+ ph->num_of_blocks_dd = 0;
+ ph->offset_dd = 0;
+
+ ph->maxtime_to_auto = 0; /* disabled */
+
+ /* The first two sections are mandatory */
+ ph->cpu_data.dump_flags = DUMP_REQUEST_FLAG;
+ ph->cpu_data.source_type = DUMP_SOURCE_CPU;
+ ph->cpu_data.source_address = 0;
+ ph->cpu_data.source_length = phyp_dump_info->cpu_state_size;
+ ph->cpu_data.destination_address = addr_offset;
+ addr_offset += phyp_dump_info->cpu_state_size;
+
+ ph->hpte_data.dump_flags = DUMP_REQUEST_FLAG;
+ ph->hpte_data.source_type = DUMP_SOURCE_HPTE;
+ ph->hpte_data.source_address = 0;
+ ph->hpte_data.source_length = phyp_dump_info->hpte_region_size;
+ ph->hpte_data.destination_address = addr_offset;
+ addr_offset += phyp_dump_info->hpte_region_size;
+
+ /* This section describes the low kernel region */
+ ph->kernel_data.dump_flags = DUMP_REQUEST_FLAG;
+ ph->kernel_data.source_type = DUMP_SOURCE_RMO;
+ ph->kernel_data.source_address = PHYP_DUMP_RMR_START;
+ ph->kernel_data.source_length = PHYP_DUMP_RMR_END;
+ ph->kernel_data.destination_address = addr_offset;
+ addr_offset += ph->kernel_data.source_length;
+
+ return addr_offset;
+}
+
+static void register_dump_area(struct phyp_dump_header *ph, unsigned long addr)
+{
+ int rc;
+ ph->cpu_data.destination_address += addr;
+ ph->hpte_data.destination_address += addr;
+ ph->kernel_data.destination_address += addr;
+
+ do {
+ rc = rtas_call(ibm_configure_kernel_dump, 3, 1, NULL,
+ 1, ph, sizeof(struct phyp_dump_header));
+ } while (rtas_busy_delay(rc));
+
+ if (rc)
+ printk(KERN_ERR "phyp-dump: unexpected error (%d) on "
+ "register\n", rc);
+}
+
/* ------------------------------------------------- */
/**
* release_memory_range -- release memory previously lmb_reserved
@@ -106,7 +217,9 @@ static struct kobj_attribute rr = __ATTR
static int __init phyp_dump_setup(void)
{
struct device_node *rtas;
- const int *dump_header = NULL;
+ const struct phyp_dump_header *dump_header = NULL;
+ unsigned long dump_area_start;
+ unsigned long dump_area_length;
int header_len = 0;
int rc;
@@ -118,7 +231,13 @@ static int __init phyp_dump_setup(void)
if (!phyp_dump_info->phyp_dump_configured)
return -ENOSYS;
- /* Is there dump data waiting for us? */
+ /* Is there dump data waiting for us? If there isn't,
+ * then register a new dump area, and release all of
+ * the rest of the reserved ram.
+ *
+ * The /rtas/ibm,kernel-dump rtas node is present only
+ * if there is dump data waiting for us.
+ */
rtas = of_find_node_by_path("/rtas");
if (rtas) {
dump_header = of_get_property(rtas, "ibm,kernel-dump",
@@ -126,17 +245,23 @@ static int __init phyp_dump_setup(void)
of_node_put(rtas);
}
- if (dump_header == NULL)
+ dump_area_length = init_dump_header(&phdr);
+
+ /* align down */
+ dump_area_start = phyp_dump_info->init_reserve_start & PAGE_MASK;
+
+ if (dump_header == NULL) {
+ register_dump_area(&phdr, dump_area_start);
return 0;
+ }
/* Should we create a dump_subsys, analogous to s390/ipl.c ? */
rc = sysfs_create_file(kernel_kobj, &rr.attr);
- if (rc) {
+ if (rc)
printk(KERN_ERR "phyp-dump: unable to create sysfs file (%d)\n",
rc);
- return 0;
- }
+ /* ToDo: re-register the dump area, for next time. */
return 0;
}
machine_subsys_initcall(pseries, phyp_dump_setup);
^ permalink raw reply
* [PATCH 3/8] pseries: phyp dump: use sysfs to release reserved mem
From: Manish Ahuja @ 2008-02-18 5:38 UTC (permalink / raw)
To: ppc-dev, paulus, Linas Vepstas; +Cc: mahuja
In-Reply-To: <47B90F55.2080606@austin.ibm.com>
Check to see if there actually is data from a previously
crashed kernel waiting. If so, Allow user-sapce tools to
grab the data (by reading /proc/kcore). When user-space
finishes dumping a section, it must release that memory
by writing to sysfs. For example,
echo "0x40000000 0x10000000" > /sys/kernel/release_region
will release 256MB starting at the 1GB. The released memory
becomes free for general use.
Signed-off-by: Linas Vepstas <linasvepstas@gmail.com>
Signed-off-by: Manish Ahuja <mahuja@us.ibm.com>
------
arch/powerpc/platforms/pseries/phyp_dump.c | 81 +++++++++++++++++++++++++++--
1 file changed, 76 insertions(+), 5 deletions(-)
Index: 2.6.25-rc1/arch/powerpc/platforms/pseries/phyp_dump.c
===================================================================
--- 2.6.25-rc1.orig/arch/powerpc/platforms/pseries/phyp_dump.c 2008-02-18 03:23:47.000000000 -0600
+++ 2.6.25-rc1/arch/powerpc/platforms/pseries/phyp_dump.c 2008-02-18 04:32:13.000000000 -0600
@@ -12,18 +12,23 @@
*/
#include <linux/init.h>
+#include <linux/kobject.h>
#include <linux/mm.h>
+#include <linux/of.h>
#include <linux/pfn.h>
#include <linux/swap.h>
+#include <linux/sysfs.h>
#include <asm/page.h>
#include <asm/phyp_dump.h>
#include <asm/machdep.h>
+#include <asm/rtas.h>
/* Global, used to communicate data between early boot and late boot */
static struct phyp_dump phyp_dump_global;
struct phyp_dump *phyp_dump_info = &phyp_dump_global;
+/* ------------------------------------------------- */
/**
* release_memory_range -- release memory previously lmb_reserved
* @start_pfn: starting physical frame number
@@ -53,18 +58,84 @@ release_memory_range(unsigned long start
}
}
-static int __init phyp_dump_setup(void)
+/* ------------------------------------------------- */
+/**
+ * sysfs_release_region -- sysfs interface to release memory range.
+ *
+ * Usage:
+ * "echo <start addr> <length> > /sys/kernel/release_region"
+ *
+ * Example:
+ * "echo 0x40000000 0x10000000 > /sys/kernel/release_region"
+ *
+ * will release 256MB starting at 1GB.
+ */
+static ssize_t store_release_region(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
{
+ unsigned long start_addr, length, end_addr;
unsigned long start_pfn, nr_pages;
+ ssize_t ret;
+
+ ret = sscanf(buf, "%lx %lx", &start_addr, &length);
+ if (ret != 2)
+ return -EINVAL;
+
+ /* Range-check - don't free any reserved memory that
+ * wasn't reserved for phyp-dump */
+ if (start_addr < phyp_dump_info->init_reserve_start)
+ start_addr = phyp_dump_info->init_reserve_start;
+
+ end_addr = phyp_dump_info->init_reserve_start +
+ phyp_dump_info->init_reserve_size;
+ if (start_addr+length > end_addr)
+ length = end_addr - start_addr;
+
+ /* Release the region of memory assed in by user */
+ start_pfn = PFN_DOWN(start_addr);
+ nr_pages = PFN_DOWN(length);
+ release_memory_range(start_pfn, nr_pages);
+
+ return count;
+}
+
+static struct kobj_attribute rr = __ATTR(release_region, 0600,
+ NULL, store_release_region);
+
+static int __init phyp_dump_setup(void)
+{
+ struct device_node *rtas;
+ const int *dump_header = NULL;
+ int header_len = 0;
+ int rc;
/* If no memory was reserved in early boot, there is nothing to do */
if (phyp_dump_info->init_reserve_size == 0)
return 0;
- /* Release memory that was reserved in early boot */
- start_pfn = PFN_DOWN(phyp_dump_info->init_reserve_start);
- nr_pages = PFN_DOWN(phyp_dump_info->init_reserve_size);
- release_memory_range(start_pfn, nr_pages);
+ /* Return if phyp dump not supported */
+ if (!phyp_dump_info->phyp_dump_configured)
+ return -ENOSYS;
+
+ /* Is there dump data waiting for us? */
+ rtas = of_find_node_by_path("/rtas");
+ if (rtas) {
+ dump_header = of_get_property(rtas, "ibm,kernel-dump",
+ &header_len);
+ of_node_put(rtas);
+ }
+
+ if (dump_header == NULL)
+ return 0;
+
+ /* Should we create a dump_subsys, analogous to s390/ipl.c ? */
+ rc = sysfs_create_file(kernel_kobj, &rr.attr);
+ if (rc) {
+ printk(KERN_ERR "phyp-dump: unable to create sysfs file (%d)\n",
+ rc);
+ return 0;
+ }
return 0;
}
^ 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