* Re: Unable to boot kernel 2.6 from u-boot 1.1.4 in Xilinx ML403
From: Wolfgang Denk @ 2006-09-01 7:35 UTC (permalink / raw)
To: Aleck Lin; +Cc: linuxppc-embedded
In-Reply-To: <000a01c6cd6e$5e1970a0$800101df@monstertop>
In message <000a01c6cd6e$5e1970a0$800101df@monstertop> you wrote:
>
> 1. When I directly download zImage.elf to the RAM and boot from there, I see
...
> 2. When I tried to boot the zImage (sitting in the flash) from u-boot file
When you use U-Boot, you should use the correct image (uImage).
Best regards,
Wolfgang Denk
--
Software Engineering: Embedded and Realtime Systems, Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
Every little picofarad has a nanohenry all its own. - Don Vonada
^ permalink raw reply
* Re: pci error recovery procedure
From: Zhang, Yanmin @ 2006-09-01 3:42 UTC (permalink / raw)
To: Linas Vepstas
Cc: linuxppc-dev, linux-pci maillist, Yanmin Zhang, LKML, Rajesh Shah
In-Reply-To: <20060831175001.GE8704@austin.ibm.com>
On Fri, 2006-09-01 at 01:50, Linas Vepstas wrote:
> On Thu, Aug 31, 2006 at 03:10:12PM +0800, Zhang, Yanmin wrote:
> > Linas,
> >
> > I am reviewing the error handlers of e1000 driver and got some ideas. My
> > startpoint is to simplify the err handler implementations for drivers, or
> > driver developers are *not willing* to add it if it's too complicated.
>
> I don't see that its to complicated ...
Originally, I didn't think so, but after I try to add err_handlers to some
drivers, I feel it's too complicated.
>
> > 1) Callback mmio_enabled looks useless. Documentation/pci-error-recovery.txt
> > says the current powerpc implementation does not implement this callback.
>
> I don't know if its useless or not. I have not needed it yet for the
> symbios, ipr and e1000 drivers, but its possible that some more
> sophisticated device may want it. I'm tempted to keep it a while
> longer befoe discarding it.
>
> The scenario is this: the device driver decides that, rather than asking
> for a full electical reset of the card, instead, it wants to perform
> its own recovery. It can do this as follows:
>
> a) enable MMIO
> b) issue reset command to adapter
> c) enable DMA.
>
> If we enabled both DMA and MMIO at the same time, there are mnay cases
> where the card will immediately trap again -- for example, if its
> DMA'ing to some crazy address. Thus, typically, one wants DMA disabled
> until after the card reset. Withouth the mmio_enabled() reset, there
> is no way of doing this.
The new error_resume, or the old slot_reset could take care of it. The specific
device driver knows all the details about how to initiate the devices. The
error_resume could call the step a) b) c) sequencially while doing checking among
steps.
If there is really a device having specific requirement to reinitiate it (very rarely),
it could use walkaround, such like schedule a WORKER. No need to provide a generic
mmio_enabled.
>
> > 2) Callback slot_reset could be merged with resume. The new resume could be:
> > int (*error_resume)(struct pci_dev *dev); I checked e1000 and e100 drivers and
> > think there is no actual reason to have both slot_reset and resume.
>
> The idea here was to handle multi-function cards. On a multi-function card,
> *all* devices need to indicate that they were able to reset. Once all devices
> have been successfuly reset, then operation can be resumed. If the reset
> of one function fails, then operation is not resumed for any f the
> functions.
I don't think we need slot_reset to coordinate multi-function devices. The new
error_resume could take care of multi-function card. 'reset' here means driver
need do I/O to detect if the device (function) still works well. If a function
of a multi-function device couldn't reset while other functions could reset,
other functions could just go on to reinitiate. In the end, the error recovery
procedure (handle_eeh_events in PowerPC implementation) could check all the
returning values of error_resume. If there is a failure value, then removes
all the functions' pci_dev of the device from the bus.
>
> > 3) link_reset is not used in pci express aer implementation, so it could be
> > deleted also.
>
> OK. Link reset was added explicitly to support PCI-E, so if its not wanted,
> we can eliminate it.
>
> > How did you test e1000 err_handler?
>
> We have three methods (I thought these were documented). In one, a
> technician brushes a grounding strap to some of the signal pins.
> In the second, slots are populated with known-bad cards. The third test
> involes sending a command down to the pci bridge chip, telling it to
> behave as if it detected an error. For development, the last is
> quick-n-easy.
Thanks for your explanation.
>
> > In the simulated enviroment, the testing might be
> > incorrect.
>
> Why would it be incorrect? I mean, we don't simulate having someone pour a
> cup of coffee into the guts of the machine ... but my understanding is
> the machines do get standard vibration/thermal/humidity testing, which
> is good enough for me.
>
> > For example, e1000_io_error_detected would call e1000_down to reset NIC.
>
> Why would that be incorrect?
>
> > During
> > our last discussion on LKML, you said PowerPC will block further I/O if the platform captures
> > a pci error, so the all I/O in e1000_down will be blocked. Later on, e1000_io_slot_reset
> > will reenable pci device and initiate NIC. I guess late initiate might fail because prior
> > e1000_down I/O don't reach NIC.
>
> Why would it fail? The e1000_down serves primarily to get the Linux
> kernel into a known state. It doesn't matter what happens to the card,
> since the next step will be to perform an electrical reset of the card.
Who will perform the electrical reset of the card? Function e1000_reset or the platform?
If it's the platform, I agree with you, but if it's e1000_reset, it might not work because
e1000_reset uses a e1000-specific approach to reset the card. I'm not sure if the e1000_reset
will restore the NIC to fresh system power-on state. At least, from the source codes, e1000_reset
couldn't.
Yanmin
^ permalink raw reply
* Re: pci error recovery procedure
From: Zhang, Yanmin @ 2006-09-01 3:33 UTC (permalink / raw)
To: Linas Vepstas
Cc: linuxppc-dev, linux-pci maillist, Yanmin Zhang, inux-kernel,
Rajesh Shah
In-Reply-To: <20060831175001.GE8704@austin.ibm.com>
On Fri, 2006-09-01 at 01:50, Linas Vepstas wrote:
> On Thu, Aug 31, 2006 at 03:10:12PM +0800, Zhang, Yanmin wrote:
> > Linas,
> >
> > I am reviewing the error handlers of e1000 driver and got some ideas. My
> > startpoint is to simplify the err handler implementations for drivers, or
> > driver developers are *not willing* to add it if it's too complicated.
>
> I don't see that its to complicated ...
Originally, I didn't think so, but after I try to add err_handlers to some
drivers, I feel it's too complicated.
>
> > 1) Callback mmio_enabled looks useless. Documentation/pci-error-recovery.txt
> > says the current powerpc implementation does not implement this callback.
>
> I don't know if its useless or not. I have not needed it yet for the
> symbios, ipr and e1000 drivers, but its possible that some more
> sophisticated device may want it. I'm tempted to keep it a while
> longer befoe discarding it.
>
> The scenario is this: the device driver decides that, rather than asking
> for a full electical reset of the card, instead, it wants to perform
> its own recovery. It can do this as follows:
>
> a) enable MMIO
> b) issue reset command to adapter
> c) enable DMA.
>
> If we enabled both DMA and MMIO at the same time, there are mnay cases
> where the card will immediately trap again -- for example, if its
> DMA'ing to some crazy address. Thus, typically, one wants DMA disabled
> until after the card reset. Withouth the mmio_enabled() reset, there
> is no way of doing this.
The new error_resume, or the old slot_reset could take care of it. The specific
device driver knows all the details about how to initiate the devices. The
error_resume could call the step a) b) c) sequencially while doing checking among
steps.
If there is really a device having specific requirement to reinitiate it (very rarely),
it could use walkaround, such like schedule a WORKER. No need to provide a generic
mmio_enabled.
> > 2) Callback slot_reset could be merged with resume. The new resume could be:
> > int (*error_resume)(struct pci_dev *dev); I checked e1000 and e100 drivers and
> > think there is no actual reason to have both slot_reset and resume.
>
> The idea here was to handle multi-function cards. On a multi-function card,
> *all* devices need to indicate that they were able to reset. Once all devices
> have been successfuly reset, then operation can be resumed. If the reset
> of one function fails, then operation is not resumed for any f the
> functions.
I don't think we need slot_reset to coordinate multi-function devices. The new
error_resume could take care of multi-function card. 'reset' here means driver
need do I/O to detect if the device (function) still works well. If a function
of a multi-function device couldn't reset while other functions could reset,
other functions could just go on to reinitiate. In the end, the error recovery
procedure (handle_eeh_events in PowerPC implementation) could check all the
returning values of error_resume. If there is a failure value, then removes
all the functions' pci_dev of the device from the bus.
>
> > 3) link_reset is not used in pci express aer implementation, so it could be
> > deleted also.
>
> OK. Link reset was added explicitly to support PCI-E, so if its not wanted,
> we can eliminate it.
>
> > How did you test e1000 err_handler?
>
> We have three methods (I thought these were documented). In one, a
> technician brushes a grounding strap to some of the signal pins.
> In the second, slots are populated with known-bad cards. The third test
> involes sending a command down to the pci bridge chip, telling it to
> behave as if it detected an error. For development, the last is
> quick-n-easy.
Thanks for your explanation.
>
> > In the simulated enviroment, the testing might be
> > incorrect.
>
> Why would it be incorrect? I mean, we don't simulate having someone pour a
> cup of coffee into the guts of the machine ... but my understanding is
> the machines do get standard vibration/thermal/humidity testing, which
> is good enough for me.
>
> > For example, e1000_io_error_detected would call e1000_down to reset NIC.
>
> Why would that be incorrect?
>
> > During
> > our last discussion on LKML, you said PowerPC will block further I/O if the platform captures
> > a pci error, so the all I/O in e1000_down will be blocked. Later on, e1000_io_slot_reset
> > will reenable pci device and initiate NIC. I guess late initiate might fail because prior
> > e1000_down I/O don't reach NIC.
>
> Why would it fail? The e1000_down serves primarily to get the Linux
> kernel into a known state. It doesn't matter what happens to the card,
> since the next step will be to perform an electrical reset of the card.
Who will perform the electrical reset of the card? Function e1000_reset or the platform?
If it's the platform, I agree with you, but if it's e1000_reset, it might not work because
e1000_reset uses a e1000-specific approach to reset the card. I'm not sure if the e1000_reset
will restore the NIC to fresh system power-on state. At least, from the source codes, e1000_reset
couldn't.
^ permalink raw reply
* Re: [PATCH 4/6] Have x86_64 use add_active_range() and free_area_init_nodes
From: Keith Mannthey @ 2006-09-01 3:08 UTC (permalink / raw)
To: Mel Gorman
Cc: akpm, tony.luck, linuxppc-dev, ak, bob.picco,
Linux Kernel Mailing List, Linux Memory Management List
In-Reply-To: <Pine.LNX.4.64.0608311906300.13392@skynet.skynet.ie>
On 8/31/06, Mel Gorman <mel@csn.ul.ie> wrote:
> On Thu, 31 Aug 2006, Keith Mannthey wrote:
> > On 8/31/06, Mel Gorman <mel@skynet.ie> wrote:
> >> On (30/08/06 13:57), Keith Mannthey didst pronounce:
> >> > On 8/21/06, Mel Gorman <mel@csn.ul.ie> wrote:
> >> > >
> Can you confirm that happens by applying the patch I sent to you and
> checking the output? When the reserve fails, it should print out what
> range it actually checked. I want to be sure it's not checking the
> addresses 0->0x1070000000
See below
> >> > >@@ -329,6 +330,8 @@ acpi_numa_memory_affinity_init(struct ac
> >> > >
> >> > > printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm,
> >> > > nd->start, nd->end);
> >> > >+ e820_register_active_regions(node, nd->start >> PAGE_SHIFT,
> >> > >+ nd->end >> PAGE_SHIFT);
> >> >
> >> > A node chunk in this section of code may be a hot-pluggable zone. With
> >> > MEMORY_HOTPLUG_SPARSE we don't want to register these regions.
> >> >
> >>
> >> The ranges should not get registered as active memory by
> >> e820_register_active_regions() unless they are marked E820_RAM. My
> >> understanding is that the regions for hotadd would be marked "reserved"
> >> in the e820 map. Is that wrong?
> >
> > This is wrong. In a mult-node system that last node add area will not
> > be marked reserved by the e820. The e820 only defines memory <
> > end_pfn. the last node add area is > end_pfn.
> >
>
> ok, that should still be fine. As long as the ranges are not marked
> "usable", add_active_range() will not be called and the holes should be
> counted correctly with the patch I sent you.
>
> > With RESERVE based add-memory you want the add-areas repored by the
> > srat to be setup during boot like all the other pages.
> >
>
> So, do you actally expect a lot of unused mem_map to be allocated with
> struct pages that are inactive until memory is hot-added in an
> x86_64-specific manner? The arch-independent stuff currently will not do
> that. It sets up memmap for where memory really exists. If that is not
> what you expect, it will hit issues at hotadd time which is not the
> current issue but one that can be fixed.
Yes. RESERVED based is a big waste of mem_map space. The add areas
are marked as RESERVED during boot and then later onlined during add.
It might be ok. I will play with tomorrow. I might just need to
call add_active_range in the right spot :)
> >> > > if (ma->flags.hot_pluggable && !reserve_hotadd(node, start, end)
> >> <
> >> > > 0) {
> >> > > /* Ignore hotadd region. Undo damage */
> >> >
> >> > I have but the e820_register_active_regions as a else to this
> >> > statment the absent pages check fails.
> >> >
> >>
> >> The patch below omits this change because I think
> >> e820_register_active_regions() will still have got called by the time
> >> you encounter a hotplug area.
> >
> > called but then removed in setup arch.
>
> By "removed", I assume you mean the active regions removed by the call
> to remove_all_active_regions() in setup_arch(). Before reserve_hotadd() is
> called, e820_register_active_regions() will have reregistered the active
> regions with the NUMA node id.
I see e820_register_active_regions is acting as a filter against the e820
> >> > Also nodes_cover_memory and alot of these check were based against
> >> > comparing the srat data against the e820. Now all this code is
> >> > comparing SRAT against SRAT....
> >> >
> >>
> >> I don't see why. The SRAT table passes a range to
> >> e820_register_active_regions() so should be comparing SRAT to e820
> >
> > let me go off and look at e820_register_active_regions() some more.
Things get clear :)
Should be ok.
> > Sure thing. It is just the hot-add area I am guessing it is an off by
> > one error of some sort.
> >
See below. I do my e820_register_active_area as an else to to if
(hotplug.....!reserve) and the prink is easy to sort out.
I see your pfn are in base 10. Looks like it considers the last
addres to be a present page. (off by one thing).
Thanks,
Keith
Output below
disabling early console
Linux version 2.6.18-rc4-mm3-smp (root@elm3a153) (gcc version 4.1.0
(SUSE Linux)) #6 SMP Thu Aug 31 22:06:00 EDT 2006
Command line: root=/dev/sda3
ip=9.47.66.153:9.47.66.169:9.47.66.1:255.255.255.0 resume=/dev/sda2
showopts earlyprintk=ttyS0,115200 console=ttyS0,115200 console=tty0
debug numa=hotadd=100
BIOS-provided physical RAM map:
BIOS-e820: 0000000000000000 - 0000000000098400 (usable)
BIOS-e820: 0000000000098400 - 00000000000a0000 (reserved)
BIOS-e820: 00000000000e0000 - 0000000000100000 (reserved)
BIOS-e820: 0000000000100000 - 000000007ff85e00 (usable)
BIOS-e820: 000000007ff85e00 - 000000007ff98880 (ACPI data)
BIOS-e820: 000000007ff98880 - 0000000080000000 (reserved)
BIOS-e820: 00000000fec00000 - 0000000100000000 (reserved)
BIOS-e820: 0000000100000000 - 0000000470000000 (usable)
BIOS-e820: 0000001070000000 - 0000001160000000 (usable)
Entering add_active_range(0, 0, 152) 0 entries of 3200 used
Entering add_active_range(0, 256, 524165) 1 entries of 3200 used
Entering add_active_range(0, 1048576, 4653056) 2 entries of 3200 used
Entering add_active_range(0, 17235968, 18219008) 3 entries of 3200 used
end_pfn_map = 18219008
DMI 2.3 present.
ACPI: RSDP (v000 IBM ) @ 0x00000000000fdcf0
ACPI: RSDT (v001 IBM EXA01ZEU 0x00001000 IBM 0x45444f43) @
0x000000007ff98800
ACPI: FADT (v001 IBM EXA01ZEU 0x00001000 IBM 0x45444f43) @
0x000000007ff98780
ACPI: MADT (v001 IBM EXA01ZEU 0x00001000 IBM 0x45444f43) @
0x000000007ff98600
ACPI: SRAT (v001 IBM EXA01ZEU 0x00001000 IBM 0x45444f43) @
0x000000007ff983c0
ACPI: HPET (v001 IBM EXA01ZEU 0x00001000 IBM 0x45444f43) @
0x000000007ff98380
ACPI: SSDT (v001 IBM VIGSSDT0 0x00001000 INTL 0x20030122) @
0x000000007ff90780
ACPI: SSDT (v001 IBM VIGSSDT1 0x00001000 INTL 0x20030122) @
0x000000007ff88bc0
ACPI: DSDT (v001 IBM EXA01ZEU 0x00001000 INTL 0x20030122) @
0x0000000000000000
SRAT: PXM 0 -> APIC 0 -> Node 0
SRAT: PXM 0 -> APIC 1 -> Node 0
SRAT: PXM 0 -> APIC 2 -> Node 0
SRAT: PXM 0 -> APIC 3 -> Node 0
SRAT: PXM 0 -> APIC 38 -> Node 0
SRAT: PXM 0 -> APIC 39 -> Node 0
SRAT: PXM 0 -> APIC 36 -> Node 0
SRAT: PXM 0 -> APIC 37 -> Node 0
SRAT: PXM 1 -> APIC 64 -> Node 1
SRAT: PXM 1 -> APIC 65 -> Node 1
SRAT: PXM 1 -> APIC 66 -> Node 1
SRAT: PXM 1 -> APIC 67 -> Node 1
SRAT: PXM 1 -> APIC 102 -> Node 1
SRAT: PXM 1 -> APIC 103 -> Node 1
SRAT: PXM 1 -> APIC 100 -> Node 1
SRAT: PXM 1 -> APIC 101 -> Node 1
SRAT: Node 0 PXM 0 0-80000000
Entering add_active_range(0, 0, 152) 0 entries of 3200 used
Entering add_active_range(0, 256, 524165) 1 entries of 3200 used
SRAT: Node 0 PXM 0 0-470000000
Entering add_active_range(0, 0, 152) 2 entries of 3200 used
Entering add_active_range(0, 256, 524165) 2 entries of 3200 used
Entering add_active_range(0, 1048576, 4653056) 2 entries of 3200 used
SRAT: Node 0 PXM 0 0-1070000000
reserve_hotadd called with node 0 sart 470000000 end 1070000000
SRAT: Hotplug area has existing memory
Entering add_active_range(0, 0, 152) 3 entries of 3200 used
Entering add_active_range(0, 256, 524165) 3 entries of 3200 used
Entering add_active_range(0, 1048576, 4653056) 3 entries of 3200 used
SRAT: Node 1 PXM 1 1070000000-1160000000
Entering add_active_range(1, 17235968, 18219008) 3 entries of 3200 used
SRAT: Node 1 PXM 1 1070000000-3200000000
reserve_hotadd called with node 1 sart 1160000000 end 3200000000
SRAT: Hotplug area has existing memory
Entering add_active_range(1, 17235968, 18219008) 4 entries of 3200 used
NUMA: Using 28 for the hash shift.
Bootmem setup node 0 0000000000000000-0000001070000000
Bootmem setup node 1 0000001070000000-0000001160000000
Zone PFN ranges:
DMA 0 -> 4096
DMA32 4096 -> 1048576
Normal 1048576 -> 18219008
early_node_map[4] active PFN ranges
0: 0 -> 152
0: 256 -> 524165
0: 1048576 -> 4653056
1: 17235968 -> 18219008
On node 0 totalpages: 4128541
0 pages used for SPARSE memmap
1149 pages DMA reserved
DMA zone: 2843 pages, LIFO batch:0
0 pages used for SPARSE memmap
DMA32 zone: 520069 pages, LIFO batch:31
0 pages used for SPARSE memmap
Normal zone: 3604480 pages, LIFO batch:31
On node 1 totalpages: 983040
0 pages used for SPARSE memmap
0 pages used for SPARSE memmap
0 pages used for SPARSE memmap
Normal zone: 983040 pages, LIFO batch:31
^ permalink raw reply
* Unable to boot kernel 2.6 from u-boot 1.1.4 in Xilinx ML403
From: Aleck Lin @ 2006-09-01 2:28 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <mailman.5.1157076003.7568.linuxppc-embedded@ozlabs.org>
Hi,
I'm working on booting kernel 2.6 on Xilinx. And I'm encountering a few
problems.=20
1. When I directly download zImage.elf to the RAM and boot from there, I =
see
the kernel starts booting, but it complains about not being able to =
mount
/dev/sysace/disc0/part2 and thus kernel panic happens.
The following is the output
---------------------------------------------------------------
loaded at: 00400000 004D313C
board data at: 004D1124 004D113C
relocated to: 004050F8 00405110
zimage at: 0040580D 004D0AA8
avail ram: 004D4000 04000000
Linux/PPC load: console=3DttyS0,9600 ip=3Doff =
root=3D/dev/xsysace/disc0/part2 rw
Uncompressing Linux...done.
Now booting the kernel
[ 0.000000] Linux version 2.6.17.8 (aleck@sac.gdatech.com) (gcc =
version
4.0.0 (DENX ELDK 4.0 4.0.0)) #2 Thu Aug 31 11:49:40 PDT 2006
[ 0.000000] Xilinx ML403 Reference System (Virtex-4 FX)
[ 0.000000] Built 1 zonelists
[ 0.000000] Kernel command line: console=3DttyS0,9600 ip=3Doff
root=3D/dev/xsysace/disc0/part2 rw
[ 0.000000] Xilinx INTC #0 at 0xD1000FC0 mapped to 0xFDFFEFC0
[ 0.000000] PID hash table entries: 512 (order: 9, 2048 bytes)
[ 0.000176] Console: colour dummy device 80x25
[ 0.000676] Dentry cache hash table entries: 8192 (order: 3, 32768 =
bytes)
[ 0.001452] Inode-cache hash table entries: 4096 (order: 2, 16384 =
bytes)
[ 0.015453] Memory: 63104k available (1268k kernel code, 468k data, =
80k
init, 0k highmem)
[ 0.204374] Mount-cache hash table entries: 512
[ 0.209943] NET: Registered protocol family 16
[ 0.218843] NET: Registered protocol family 2
[ 0.264481] IP route cache hash table entries: 512 (order: -1, 2048
bytes)
[ 0.265267] TCP established hash table entries: 2048 (order: 1, 8192
bytes)
[ 0.265465] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.265569] TCP: Hash tables configured (established 2048 bind 1024)
[ 0.265599] TCP reno registered
[ 0.272471] io scheduler noop registered
[ 0.272558] io scheduler anticipatory registered (default)
[ 0.272626] io scheduler deadline registered
[ 0.272759] io scheduler cfq registered
[ 0.318755] Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ
sharing disabled
[ 0.323749] serial8250.0: ttyS0 at MMIO 0xa0001003 (irq =3D 9) is a =
16450
[ 2.026296] RAMDISK driver initialized: 16 RAM disks of 65536K size =
1024
blocksize
[ 2.117598] tun: Universal TUN/TAP device driver, 1.6
[ 2.177338] tun: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
[ 2.252474] mice: PS/2 mouse device common for all mice
[ 2.314381] TCP bic registered
[ 2.350802] NET: Registered protocol family 1
[ 2.402825] NET: Registered protocol family 17
[ 2.458051] VFS: Cannot open root device "xsysace/disc0/part2" or
unknown-block(0,0)
[ 2.549979] Please append a correct "root=3D" boot option
[ 2.612426] Kernel panic - not syncing: VFS: Unable to mount root fs =
on
unknown-block(0,0)
[ 2.711373] <0>Rebooting in 180 seconds..<NULL>
-----------------------------------------------------------
2. When I tried to boot the zImage (sitting in the flash) from u-boot =
file
(generated from the same source code as uImage.elf), as soon as it gives =
the
control to the kernel, no messages would come. I checked to make sure =
that I
had the right serial port setting (console=3DttyS0,9600), but still =
nothing
shows up.
Here's the output of what I had (I turned on some extra debug msg in =
u-boot)
-------------------------------------------
### No HW ID - assuming ML403
DRAM: 64 MB
FLASH: 8 MB
In: serial
Out: serial
Err: serial
Hit any key to stop autoboot: 5 =08=08=08 4 =08=08=08 3 =08=08=08 2 =
=08=08=08 0=20
=3D> bootm 0xffa00000
## Booting image at ffa00000 ...
Image Name: Linux-2.6.17.8
Image Type: PowerPC Linux Kernel Image (gzip compressed)
Data Size: 832155 Bytes =3D 812.7 kB
Load Address: 00000000
Entry Point: 00000000
Verifying Checksum ... OK
Uncompressing Kernel Image ... OK
## Current stack ends at 0x03E62B70 =3D> set upper limit to 0x00800000
## cmdline at 0x007FFF00 ... 0x007FFF3A
memstart =3D 0x00000000
memsize =3D 0x04000000
flashstart =3D 0xFF800000
flashsize =3D 0x00800000
flashoffset =3D 0x00000000
sramstart =3D 0x00000000
sramsize =3D 0x00000000
bootflags =3D 0x40401003
procfreq =3D 300 MHz
plb_busfreq =3D 100 MHz
ethaddr =3D 00:0A:35:00:22:01
IP addr =3D 192.168.10.111
baudrate =3D 9600 bps
No initrd
## Transferring control to Linux (at address 00000000) ...
------------------------------------------------------------
3. Lastly, whenever I issue a reset command in u-boot, it just locks up =
and
hangs. I have to do a hardware reset every time. I'm wondering if the =
reset
vector is going to a wrong place. How would I check that?
I'm fairly new to the whole embedded domain. Please feel free to help. =
It
would be much appreciated! Thanks.
Aleck
^ permalink raw reply
* RE: Rattler 8347 and USB 2.0
From: Li Yang-r58472 @ 2006-09-01 2:54 UTC (permalink / raw)
To: Jamie Guinan, linuxppc-embedded
In-Reply-To: <Pine.LNX.4.64.0608291535260.23035@gemini.home.net>
> -----Original Message-----
> From:=20
> linuxppc-embedded-bounces+leoli=3Dfreescale.com@ozlabs.org=20
> [mailto:linuxppc-embedded-bounces+leoli=3Dfreescale.com@ozlabs.o
> rg] On Behalf Of Jamie Guinan
> Sent: Friday, September 01, 2006 12:14 AM
> To: linuxppc-embedded@ozlabs.org
> Subject: Rattler 8347 and USB 2.0
>=20
>=20
> Greetings,
>=20
> I have an mpc8347 board here (A&M Rattler 8347). It shipped with a
> 2.6.16 patched enough to boot the board, but support for=20
> freescale USB 2.0 (ehci) is not present.
>=20
> Working my way backwards in the mainline kernel tree=20
> (2.6.18-rc5), I found drivers/usb/host/ehci-fsl.c, for=20
> FreeScale/PPC EHCI support.
>=20
> In that module, usb_hcd_fsl_probe() requires an initialized=20
> "struct fsl_usb2_platform_data", which only appears in=20
> arch/powerpc/sysdev/fsl_soc.c, yet the 2.6.16 patch provided=20
> puts the board in arch/ppc.
>=20
> My question is, what would be the best way to go about=20
> getting ehci-fsl.c working with this board?
>=20
> 1) Nudge the Rattler port from arch/ppc to arch/powerpc. One=20
> problem with this is that the rattler uses RedBoot, and reading this,
>=20
> http://ozlabs.org/pipermail/linuxppc-embedded/2006-August/024116.html
>=20
> it looks like arch/powerpc wants to boot from=20
> OpenFirmware-like "flattened device tree" (does RedBoot=20
> support this?).
Use a shim which directly builds FDT in kernel to use powerpc arch.
>=20
> 2) Support ehci-fsl.c from arch/ppc. If arch/ppc is=20
> deprecated, that's a bad long-term solution. And since=20
> fsl_soc.c lives under arch/powerpc, that doesn't look good either.
Actually you don't need fsl_soc.c in ppc arch. There are predefined
platform_device and platform_data in arch/ppc/syslib/mpc83xx_devices.c.
You can add your usb platform_data there easily.
^ permalink raw reply
* Simple module, but won't build
From: Steven Kaiser @ 2006-08-31 22:55 UTC (permalink / raw)
To: linuxppc-embedded
Hi gurus:
Newbie here. I am using ELDK 3.1.1, 2.4.25 kernel, and a Lite5200b board.
I run the kernel in RAM, and mount a filesystem via NFS. So far so good,
and I move on to trying to build a simple module to write to a few LEDs.
Simple hello world modules compile and insmod/rmmod fine, but when I try to
#include <asm/io.h>, here I have the exact same problem as Richard Danter
did: CONFIG_KERNEL_START and CONFIG_TASK_SIZE are not defined anywhere in
any headers-- just in the config files.
http://ozlabs.org/pipermail/linuxppc-embedded/2004-May/014037.html
My little wrinkle to add to this problem is I have recompiled the kernel, as
advised in the replies to Richard's post, with the 'Set Custom Kernel Base
Address' and 'Set Custom user task size' options enabled, but in my case I
still I cannot find CONFIG_KERNEL_START and CONFIG_TASK_SIZE defined
anywhere noteworthy.
My 'include/linux/autoconf.h' file is empty, and I don't even have an
'include/config/' directory at all. Where in the steps of recompiling the
kernel should these files and directories get generated?
My process for building the kernel is:
$ cd /opt/eldk/usr/src/linuxppc_2_4_devel
$ make mrproper
$ make lite5200b_config
$ make menuconfig
$ make dep
$ make uImage
$ cp arch/ppc/boot/images/uImage /tftpboot/MPC5200/uImage
I can manually include CONFIG_KERNEL_START and CONFIG_TASK_SIZE in my module
source, compile, insmod, and all goes well (except my LEDs don't light up
but first things first).
When my kernel boots, I get a few gripes which I think are related to this
issue:
Finding module dependencies: depmod: Can't open
/lib/modules/2.4.25/modules.deg [FAILED]
modprobe: Can't open dependencies file /lib/modules/2.4.25/modules.dep (No
such)
Young and foolish, I figured maybe I should try:
$ make modules
$ make modules_install
Oops. That was bad. Now I cannot even compile the simplest hello.c module
without a page of errors, the first being a complaint of not being able to
find linux/autoconf.h. Before I only had trouble when I tried to #include
<asm/io.h>, now it happens 100% of the time.
So I went back and turned off module support, recompiled the kernel, and
still cannot compile hello.c. I also tried recompiling the kernel after
doing a "make oldconfig", and still cannot compile a simple module anymore.
I think I am going to have to go back to square 1 and reinstall ELDK and
everything from scratch. But before I do:
Any insight into the generation of autoconf.h, and whereabouts this file
should come from? I will watch for it when I redo the whole process.
Steven Kaiser
Chemistry Electronics Facility
University of California, Irvine
2347 Natural Sciences 2
Irvine, CA 92697-2025
(949)824-7520
^ permalink raw reply
* Re: 2 Ethernet port operating in a PPC405EP system
From: Otto Solares @ 2006-08-31 22:08 UTC (permalink / raw)
To: Matt Porter; +Cc: linuxppc-embedded
In-Reply-To: <20060831011903.GB8863@gate.crashing.org>
On Wed, Aug 30, 2006 at 08:19:03PM -0500, Matt Porter wrote:
> On Wed, Aug 30, 2006 at 01:23:03PM -0500, Otto Solares wrote:
> > Don't repeat the same mistake as the MediaMVP, it uses the same
> > processor and same kernel version, it sucks badly...
>
> FWIW, MediaMVP doesn't use the same processor. It has an
> STBx25xx which is quite different from a 405EP. It is
> the same 405 core at least.
You're right. And kernel is 2.4.17 not 2.4.19 as I stated.
-otto
^ permalink raw reply
* Re: 2 Ethernet port operating in a PPC405EP system
From: Otto Solares @ 2006-08-31 22:07 UTC (permalink / raw)
To: Chun Chung Lo; +Cc: linuxppc-embedded
In-Reply-To: <A7B1E4DD46AA7046A4398F745240F29402737D5F@ASPROEXG.astri.local>
On Thu, Aug 31, 2006 at 08:54:19AM +0800, Chun Chung Lo wrote:
> Hi,
Hi.
> I really do not know what happened about MediaMVP, could you mind giving
> me a review?
Sure, the problem with the MediaMVP is that it ships with a real old
and buggy kernel (specially the NIC driver) and with propietary kernel
modules, so you can't really upgrade the kernel.
I was succesful in booting a 2.6 kernel but without drivers for the
special hw I lost interest.
So I really hate vendors shipping buggy old kernels, that's all. :)
-otto
^ permalink raw reply
* Re: PCIe enhanced configuration mechanism support on ppc arch
From: Segher Boessenkool @ 2006-08-31 21:31 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Milton Miller
In-Reply-To: <1157025771.12526.133.camel@localhost.localdomain>
>> The U3/U4 HT config access code never returns the error though; it
>> happily accesses the config space of the next device instead. Got
>> a patch, will send it later -- it's not a regression, there's no big
>> hurry for 2.6.18.
>
> Better to have it in if possible though. Thanks
I'm more worried about having 2.6.18 work at all, sorry. I might
be fast enough of course (ahem), but no promises :-)
Segher
^ permalink raw reply
* Need help with TLB settings in Linux -System ACE
From: Junita Joseph @ 2006-08-31 20:56 UTC (permalink / raw)
To: linuxppc-embedded; +Cc: a.sudheer
[-- Attachment #1: Type: text/plain, Size: 2217 bytes --]
Hi all,
I am currently working on a PPC440SPe based custom board to bring up the
System ACE interface from Linux.
I am using linux-2.6.16 with the patch applied as per Ameet's suggestion
from the following link
https://www.cs.york.ac.uk/rtslab/demos/amos/xupv2pro/patches/linuxppc-2.6.17
.1-sysace-1.1.patch
We are able to access the controller registers from u-boot, but kernel
throws a "Data Machine Check exception" while accessing the registers.
1. I have set up System ACE base address as 0xE000_0000 (which is the
same as in u-boot).
2. As far as I understand, kernel should pick-up TLB settings from
u-boot.
3. But , while debugging through BDI this is what I observe:
TLB entry Listings from u-boot:
IDX TID EPN SIZE VTS RPN USER WIMGE USRSVC
0 : 00 ff000000 16MB V0 -> 4_ff000000 U:0000 WI-G- XWRXWR
1 : 00 00000000 256MB V0 -> 0_00000000 U:0000 -I-G- XWRXWR
2 : 00 10000000 256MB V0 -> 0_10000000 U:0000 -I-G- XWRXWR
3 : 00 20000000 256MB V0 -> 0_20000000 U:0000 -I-G- XWRXWR
4 : 00 30000000 256MB V0 -> 0_30000000 U:0000 -I-G- XWRXWR
5 : 00 90000000 256KB V0 -> 4_00000000 U:0000 -I--- XWRXWR
6 : 00 e0000000 1KB V0 -> 4_e0000000 U:0000 -I-G- XWRXWR
Note : 6th entry is for system ACE.
TLB entry Listings from Kernel:
IDX TID EPN SIZE VTS RPN USER WIMGE USRSVC
0 : 00 00000000 1KB -0 -> 4_ff000000 U:0000 WI-G- XWRXWR
1 : 00 fdfff000 4KB V0 -> 4_f0000000 U:0000 -IMG- ----WR
2 : 00 fdffe000 4KB V0 -> 4_f0000000 U:0000 -IMG- ----WR
3 : 00 fdffd000 4KB V0 -> 4_f0000000 U:0000 -IMG- ----WR
4 : 00 e1000000 4KB V0 -> 0_e0000000 U:0000 -IMG- ----WR
5 : 00 00000000 1KB -0 -> 4_00000000 U:0000 -I--- XWRXWR
6 : 00 00000000 1KB -0 -> 4_e0000000 U:0000 -I-G- XWRXWR
Note: 4th entry is system ACE.
The RPN and access permissions are totally different for System ACE from
u-boot and kernel. I u-boot it is - 4_e0000000 , and in kernel it is
0_e0000000
I think this is the issue, causing exception during writes to registers from
kernel.
Could someone throw some light on this area? This is very critical for us
now.
Or am I missing something?
Any help would be appreciated.
Thanks in advance
Junita
[-- Attachment #2: Type: text/html, Size: 16286 bytes --]
^ permalink raw reply
* Re: Unable to build ELDK 4.0
From: Wolfgang Denk @ 2006-08-31 20:00 UTC (permalink / raw)
To: Mathews, Phil; +Cc: Linuxppc-embedded
In-Reply-To: <3E8081396F6B524BA2854E7FA3F16438042EB1DF@mail.innocon.com>
In message <3E8081396F6B524BA2854E7FA3F16438042EB1DF@mail.innocon.com> you wrote:
>
> mathews@mathews:~/ELDK/ppc_6xx/usr/src/linux-2.6.15> make O=/home/name/build/kernel menuconfig
> HOSTCC scripts/basic/fixdep
> In file included from /home/mathews/ELDK/usr/../ppc_6xx/usr/include/sys/socket.h:35,
> from /home/mathews/ELDK/usr/../ppc_6xx/usr/include/netinet/in.h:24,
> from /home/mathews/ELDK/usr/../ppc_6xx/usr/include/arpa/inet.h:23,
> from /home/mathews/ELDK/ppc_6xx/usr/src/linux-2.6.15/scripts/basic/fixdep.c:115:
> /home/mathews/ELDK/usr/../ppc_6xx/usr/include/bits/socket.h:304:24: error: asm/socket.h: No such file or directory
> make[2]: *** [scripts/basic/fixdep] Error 1
> make[1]: *** [scripts_basic] Error 2
> make: *** [menuconfig] Error 2
It's working fine here. Did you install from CDROM or from a down-
load? Did you verify the downloaded files? Were there any error
messages dureing installation? Did you try a fresh reinstall?
Best regards,
Wolfgang Denk
--
Software Engineering: Embedded and Realtime Systems, Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
I used to be indecisive, now I'm not sure.
^ permalink raw reply
* Re: [PATCH 4/6] Have x86_64 use add_active_range() and free_area_init_nodes
From: Mel Gorman @ 2006-08-31 18:40 UTC (permalink / raw)
To: Keith Mannthey
Cc: akpm, tony.luck, linuxppc-dev, ak, bob.picco,
Linux Kernel Mailing List, Linux Memory Management List
In-Reply-To: <a762e240608311052h28843b2ege651e9fa82c49f2a@mail.gmail.com>
On Thu, 31 Aug 2006, Keith Mannthey wrote:
> On 8/31/06, Mel Gorman <mel@skynet.ie> wrote:
>> On (30/08/06 13:57), Keith Mannthey didst pronounce:
>> > On 8/21/06, Mel Gorman <mel@csn.ul.ie> wrote:
>> > >
>
>> ok, great. How much physical memory is installed on the machine? I want to
>> determine if the "usable" entries in the e820 map contain physical memory
>> or not.
>
> Usable entries in the e820 contian memory. I have about 20-24gb
> depending on config.
>
ok, that seems to match the (usable) regions in the e820 map.
>
>> When the SRAT is bad, the information is discarded and discovered by an
>> alternative method later in the boot process.
>>
>> In this case, numa_initmem_init() is called after acpi_numa_init(). It
>> calls acpi_scan_nodes() which returns -1 because the SRAT is bad. Once
>> that happens, either k8_scan_nodes() will be called and the regions
>> discovered there or if that is not possible, it'll fall through and
>> e820_register_active_regions will be called without any node awareness.
>
> sorry I have missed some of the logic in this patch.
>
> I see now in numa_initmem_init that if no numa setup is found it calls
> e820_register_active_regions(0, start_pfn, end_pfn) again.
>
right.
> So if the srat is discard it runs the e820 code again.
>
yes.
>
>> > >diff -rup -X /usr/src/patchset-0.6/bin//dontdiff
>> > >linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/x86_64/mm/srat.c
>> > >linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/arch/x86_64/mm/srat.c
>> > >--- linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/x86_64/mm/srat.c
>> > >2006-08-21 09:23:50.000000000 +0100
>> > >+++ linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/arch/x86_64/mm/srat.c
>> > >2006-08-21 10:15:58.000000000 +0100
>> > >@@ -84,6 +84,7 @@ static __init void bad_srat(void)
>> > > apicid_to_node[i] = NUMA_NO_NODE;
>> > > for (i = 0; i < MAX_NUMNODES; i++)
>> > > nodes_add[i].start = nodes[i].end = 0;
>> > >+ remove_all_active_ranges();
>> > > }
>> >
>> > We go back to setup_arch with no active areas?
>> >
>>
>> Yes, and it'll be discovered using an alternative method later. There is
>> no point returning to setup_arch with known bad information about active
>> areas.
>
> Totally agreeded! I just didn't the the fallback path.
grand.
>>
>> > > static __init inline int srat_disabled(void)
>> > >@@ -166,7 +167,7 @@ static int hotadd_enough_memory(struct b
>> > >
>> > > if (mem < 0)
>> > > return 0;
>> > >- allowed = (end_pfn - e820_hole_size(0, end_pfn)) * PAGE_SIZE;
>> > >+ allowed = (end_pfn - absent_pages_in_range(0, end_pfn)) *
>> > >PAGE_SIZE;
>> > > allowed = (allowed / 100) * hotadd_percent;
>> > > if (allocated + mem > allowed) {
>> > > unsigned long range;
>> > >@@ -238,7 +239,7 @@ static int reserve_hotadd(int node, unsi
>> > > }
>> > >
>> > > /* This check might be a bit too strict, but I'm keeping it for
>> > > now. */
>> > >- if (e820_hole_size(s_pfn, e_pfn) != e_pfn - s_pfn) {
>> > >+ if (absent_pages_in_range(s_pfn, e_pfn) != e_pfn - s_pfn) {
>> > > printk(KERN_ERR "SRAT: Hotplug area has existing
>> > > memory\n");
>> > > return -1;
>> > > }
>> > We really do want to to compare against the e820 map at it contains
>> > the memory that is really present (this info was blown away before
>> > acpi_numa)
>>
>> The information used by absent_pages_in_range() should match what was
>> available to e820_hole_size().
>
> Is absent_pages_in_range a check against the e820 or the
> add_pages_to_range calls?
>
absent_pages_in_range() uses information provided via add_active_range()
and on x86_64, add_active_range() is called based on information in the
e820.
>> > Anyway I fixed up to have the current chunk added
>> > (e820_register_active_regions) after calling this code so it logicaly
>> > makes sense but it still trip over the check.
>> > I am not sure what you
>> > are printing out in you debug code but dosen't look like pfns or
>> > phys_addresses but maybe it can tell us why the check fails.
>> >
>>
>> My debug code for add_active_range() printing out pfns but I spotted one
>> case where absent_pages_in_range(I) does not do what one would expect.
>> Lets say the ranges with physical memory was 0->1000 and 2000-3000 (in
>> pfns). absent_pages_in_range(0, 3000) would return 1000 as you'd expect
>> but
>> absent_pages_in_range(5000-6000) would return 0! I have a patch that might
>> fix this at the end of the mail but I'm not sure it's the problem you are
>> hitting. In the bootlog, I see;
>>
>> SRAT: Node 0 PXM 0 0-80000000
>> Entering add_active_range(0, 0, 152) 0 entries of 3200 used
>> Entering add_active_range(0, 256, 524165) 1 entries of 3200 used
>> SRAT: Node 0 PXM 0 0-470000000
>> Entering add_active_range(0, 0, 152) 2 entries of 3200 used
>> Entering add_active_range(0, 256, 524165) 2 entries of 3200 used
>> Entering add_active_range(0, 1048576, 4653056) 2 entries of 3200 used
>> SRAT: Node 0 PXM 0 0-1070000000
>> SRAT: Hotplug area has existing memory
>>
>
>> The last part (0-1070000000) is checked as a hotplug area but it's clear
>> that memory exists in that range. As reserve_hotadd() requires that the
>> whole range be a hole, I'm having trouble seeing how it ever successfully
>> reserved unless the ranges going into reserve_hotadd() are something other
>> than the pfn range for 0-1070000000). The patch later will print out the
>> range used by reserve_hotadd() so we can see.
>
> No the whole node is 0-1070000000 the hot add range is 470000000-1070000000
> reserve_hotadd is called with start and end not nd->start nd->end.
> 470000000-1070000000 sould be empty.
>
Can you confirm that happens by applying the patch I sent to you and
checking the output? When the reserve fails, it should print out what
range it actually checked. I want to be sure it's not checking the
addresses 0->0x1070000000
>
>> > >@@ -329,6 +330,8 @@ acpi_numa_memory_affinity_init(struct ac
>> > >
>> > > printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm,
>> > > nd->start, nd->end);
>> > >+ e820_register_active_regions(node, nd->start >> PAGE_SHIFT,
>> > >+ nd->end >> PAGE_SHIFT);
>> >
>> > A node chunk in this section of code may be a hot-pluggable zone. With
>> > MEMORY_HOTPLUG_SPARSE we don't want to register these regions.
>> >
>>
>> The ranges should not get registered as active memory by
>> e820_register_active_regions() unless they are marked E820_RAM. My
>> understanding is that the regions for hotadd would be marked "reserved"
>> in the e820 map. Is that wrong?
>
> This is wrong. In a mult-node system that last node add area will not
> be marked reserved by the e820. The e820 only defines memory <
> end_pfn. the last node add area is > end_pfn.
>
ok, that should still be fine. As long as the ranges are not marked
"usable", add_active_range() will not be called and the holes should be
counted correctly with the patch I sent you.
> With RESERVE based add-memory you want the add-areas repored by the
> srat to be setup during boot like all the other pages.
>
So, do you actally expect a lot of unused mem_map to be allocated with
struct pages that are inactive until memory is hot-added in an
x86_64-specific manner? The arch-independent stuff currently will not do
that. It sets up memmap for where memory really exists. If that is not
what you expect, it will hit issues at hotadd time which is not the
current issue but one that can be fixed.
>> > > if (ma->flags.hot_pluggable && !reserve_hotadd(node, start, end)
>> <
>> > > 0) {
>> > > /* Ignore hotadd region. Undo damage */
>> >
>> > I have but the e820_register_active_regions as a else to this
>> > statment the absent pages check fails.
>> >
>>
>> The patch below omits this change because I think
>> e820_register_active_regions() will still have got called by the time
>> you encounter a hotplug area.
>
> called but then removed in setup arch.
By "removed", I assume you mean the active regions removed by the call
to remove_all_active_regions() in setup_arch(). Before reserve_hotadd() is
called, e820_register_active_regions() will have reregistered the active
regions with the NUMA node id.
>> > Also nodes_cover_memory and alot of these check were based against
>> > comparing the srat data against the e820. Now all this code is
>> > comparing SRAT against SRAT....
>> >
>>
>> I don't see why. The SRAT table passes a range to
>> e820_register_active_regions() so should be comparing SRAT to e820
>
> let me go off and look at e820_register_active_regions() some more.
>
Cool
>> > I am willing to help here but we should compare the SRAT against to
>> > e820. Table v. Table.
>> >
>> > What to you think should be done?
>> >
>>
>> Can you read through this patch and see does it address the problem in any
>> way? If it doesn't, can you send a complete bootlog so I can see what is
>> being sent to reserve_hotadd()? Thanks
>
> Sure thing. It is just the hot-add area I am guessing it is an off by
> one error of some sort.
>
Possible, the change to reserve_hotadd() should tell me.
> What is all this code buying us?
Less architecture-specific code across a number of architectures is the
main one.
> Since this code dosen't appear to do
> anything to help the arch out (just increases it's vm boot code
> complexity a little) maybe insead of weaving
> e820_register_active_regions() calls throught out the boot process you
> should just waint untill things are sorted out and do a quick scan of
> node data that has been setup at the end?
>
That would defeat the purpose of sizing zones and holes in an architecture
independent manner.
> What are the future plans for this api?
>
In the future, I will be releasing patches that set aside a zone (similar
to the Solaris Kernel Cage) used for easily-reclaimed pages that can be
used for growing the huge page pool at runtime (it comes under the heading
of anti-fragmentation) work. The same zone could also be used to give
memory hot-remove a better success rate than 0%. These patches make the
creation of the zone relatively trivial. Without them, the
architecture-specific code is really hairy.
Other possibilities are doing stuff like handling the mem= boot parameter
in an architecture-independent manner. My understanding is that some NUMA
architectures get the handling of that arguement wrong.
--
Mel Gorman
Part-time Phd Student Linux Technology Center
University of Limerick IBM Dublin Software Lab
^ permalink raw reply
* common flatdevtree code
From: Mark A. Greer @ 2006-08-31 18:40 UTC (permalink / raw)
To: hollisb; +Cc: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 842 bytes --]
Hi Hollis,
I'm doing some fairly massive rework to my patches so it'll take
another day or two (plus 4 day weekend for me). In the meantime,
this is what I've done to your code. :)
I still plan on changing it a bit to use ft_next in a few more routines
(e.g., ft_dump_blob). ft_next has a clumsy interface but I like the fact
that it separates the "how to traverse the nodes/properties in the tree"
knowledge from the "what do I want to do with this particular node/property"
knowledge. Also, if/when version 0x11 (or whatever) comes along, we only
have to change one routine to be able to correctly traverse the tree.
I've included flatdevtree.[ch] and the flatdevtree_env.h for the
bootwrapper for reference. I didn't make one for you but I can.
Its a work in progress but let me know if you have any issues so far.
Thanks,
Mark
[-- Attachment #2: flatdevtree.c --]
[-- Type: text/x-csrc, Size: 15586 bytes --]
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright Pantelis Antoniou 2006
* Copyright (C) IBM Corporation 2006
*
* Authors: Pantelis Antoniou <pantelis@embeddedalley.com>
* Hollis Blanchard <hollisb@us.ibm.com>
*/
#include "flatdevtree.h"
static void ft_put_word(struct ft_cxt *cxt, u32 v)
{
if (cxt->overflow) /* do nothing */
return;
/* check for overflow */
if (cxt->p + 4 > cxt->pstr) {
cxt->overflow = 1;
return;
}
*(u32 *) cxt->p = cpu_to_be32(v);
cxt->p += 4;
}
static inline void ft_put_bin(struct ft_cxt *cxt, const void *data, int sz)
{
char *p;
if (cxt->overflow) /* do nothing */
return;
/* next pointer pos */
p = (char *) _ALIGN((unsigned long)cxt->p + sz, 4);
/* check for overflow */
if (p > cxt->pstr) {
cxt->overflow = 1;
return;
}
memcpy(cxt->p, data, sz);
if ((sz & 3) != 0)
memset(cxt->p + sz, 0, 4 - (sz & 3));
cxt->p = p;
}
void ft_begin_node(struct ft_cxt *cxt, const char *name)
{
ft_put_word(cxt, OF_DT_BEGIN_NODE);
ft_put_bin(cxt, name, strlen(name) + 1);
}
void ft_end_node(struct ft_cxt *cxt)
{
ft_put_word(cxt, OF_DT_END_NODE);
}
void ft_nop(struct ft_cxt *cxt)
{
ft_put_word(cxt, OF_DT_NOP);
}
static int lookup_string(struct ft_cxt *cxt, const char *name)
{
char *p;
p = cxt->pstr;
while (p < cxt->pstr_begin) {
if (strcmp(p, (char *)name) == 0)
return p - cxt->p_begin;
p += strlen(p) + 1;
}
return -1;
}
void ft_prop(struct ft_cxt *cxt, const char *name,
const void *data, unsigned int sz)
{
int len, off;
if (cxt->overflow)
return;
len = strlen(name) + 1;
off = lookup_string(cxt, name);
if (off == -1) {
/* check if we have space */
if (cxt->p + 12 + sz + len > cxt->pstr) {
cxt->overflow = 1;
return;
}
cxt->pstr -= len;
memcpy(cxt->pstr, name, len);
off = cxt->pstr - cxt->p_begin;
}
/* now put offset from beginning of *STRUCTURE* */
/* will be fixed up at the end */
ft_put_word(cxt, OF_DT_PROP);
ft_put_word(cxt, sz);
ft_put_word(cxt, off);
ft_put_bin(cxt, data, sz);
}
void ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str)
{
ft_prop(cxt, name, str, strlen(str) + 1);
}
void ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val)
{
u32 v = cpu_to_be32((u32) val);
ft_prop(cxt, name, &v, 4);
}
/* start construction of the flat OF tree */
void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size)
{
struct boot_param_header *bph = blob;
u32 off;
/* clear the cxt */
memset(cxt, 0, sizeof(*cxt));
cxt->bph = bph;
cxt->max_size = max_size;
/* zero everything in the header area */
memset(bph, 0, sizeof(*bph));
bph->magic = cpu_to_be32(OF_DT_HEADER);
bph->version = cpu_to_be32(0x10);
bph->last_comp_version = cpu_to_be32(0x10);
/* start pointers */
cxt->pres_begin = (char *) _ALIGN((unsigned long)(bph + 1), 8);
cxt->pres = cxt->pres_begin;
off = (unsigned long)cxt->pres_begin - (unsigned long)bph;
bph->off_mem_rsvmap = cpu_to_be32(off);
((u64 *) cxt->pres)[0] = 0; /* phys = 0, size = 0, terminate */
((u64 *) cxt->pres)[1] = 0;
cxt->p_anchor = cxt->pres + 16; /* over the terminator */
}
/* add a reserver physical area to the rsvmap */
void ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size)
{
((u64 *) cxt->pres)[0] = cpu_to_be64(physaddr); /* phys = 0, size = 0, terminate */
((u64 *) cxt->pres)[1] = cpu_to_be64(size);
cxt->pres += 18; /* advance */
((u64 *) cxt->pres)[0] = 0; /* phys = 0, size = 0, terminate */
((u64 *) cxt->pres)[1] = 0;
/* keep track of size */
cxt->res_size = cxt->pres + 16 - cxt->pres_begin;
cxt->p_anchor = cxt->pres + 16; /* over the terminator */
}
void ft_begin_tree(struct ft_cxt *cxt)
{
cxt->p_begin = cxt->p_anchor;
cxt->pstr_begin = (char *)cxt->bph + cxt->max_size; /* point at the end */
cxt->p = cxt->p_begin;
cxt->pstr = cxt->pstr_begin;
}
int ft_end_tree(struct ft_cxt *cxt)
{
struct boot_param_header *bph = cxt->bph;
int off, sz, sz1;
u32 tag, v;
char *p;
ft_put_word(cxt, OF_DT_END);
if (cxt->overflow)
return -ENOMEM;
/* size of the areas */
cxt->struct_size = cxt->p - cxt->p_begin;
cxt->strings_size = cxt->pstr_begin - cxt->pstr;
/* the offset we must move */
off = (cxt->pstr_begin - cxt->p_begin) - cxt->strings_size;
/* the new strings start */
cxt->pstr_begin = cxt->p_begin + cxt->struct_size;
/* move the whole string area */
memmove(cxt->pstr_begin, cxt->pstr, cxt->strings_size);
/* now perform the fixup of the strings */
p = cxt->p_begin;
while ((tag = be32_to_cpu(*(u32 *) p)) != OF_DT_END) {
p += 4;
if (tag == OF_DT_BEGIN_NODE) {
p = (char *) _ALIGN((unsigned long)p + strlen(p) + 1, 4);
continue;
}
if (tag == OF_DT_END_NODE || tag == OF_DT_NOP)
continue;
if (tag != OF_DT_PROP)
return -EINVAL;
sz = be32_to_cpu(*(u32 *) p);
p += 4;
v = be32_to_cpu(*(u32 *) p);
v -= off;
*(u32 *) p = cpu_to_be32(v); /* move down */
p += 4;
p = (char *) _ALIGN((unsigned long)p + sz, 4);
}
/* fix sizes */
p = (char *)cxt->bph;
sz = (cxt->pstr_begin + cxt->strings_size) - p;
sz1 = _ALIGN(sz, 16); /* align at 16 bytes */
if (sz != sz1)
memset(p + sz, 0, sz1 - sz);
bph->totalsize = cpu_to_be32(sz1);
bph->off_dt_struct = cpu_to_be32(cxt->p_begin - p);
bph->off_dt_strings = cpu_to_be32(cxt->pstr_begin - p);
/* the new strings start */
cxt->pstr_begin = cxt->p_begin + cxt->struct_size;
cxt->pstr = cxt->pstr_begin + cxt->strings_size;
return 0;
}
/**********************************************************************/
static inline int isprint(int c)
{
return c >= 0x20 && c <= 0x7e;
}
static int is_printable_string(const void *data, int len)
{
const char *s = data;
const char *ss;
/* zero length is not */
if (len == 0)
return 0;
/* must terminate with zero */
if (s[len - 1] != '\0')
return 0;
ss = s;
while (*s && isprint(*s))
s++;
/* not zero, or not done yet */
if (*s != '\0' || (s + 1 - ss) < len)
return 0;
return 1;
}
static void print_data(const void *data, int len)
{
int i;
const char *s;
/* no data, don't print */
if (len == 0)
return;
if (is_printable_string(data, len)) {
printf(" = \"%s\"", (char *)data);
return;
}
switch (len) {
case 1: /* byte */
printf(" = <0x%02x>", (*(char *) data) & 0xff);
break;
case 2: /* half-word */
printf(" = <0x%04x>", be16_to_cpu(*(u16 *) data) & 0xffff);
break;
case 4: /* word */
printf(" = <0x%08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
break;
case 8: /* double-word */
printf(" = <0x%16llx>", be64_to_cpu(*(u64 *) data));
break;
default: /* anything else... hexdump */
printf(" = [");
for (i = 0, s = data; i < len; i++)
printf("%02x%s", s[i], i < len - 1 ? " " : "");
printf("]");
break;
}
}
void ft_dump_blob(const void *bphp)
{
const struct boot_param_header *bph = bphp;
const u64 *p_rsvmap = (const u64 *)
((const char *)bph + be32_to_cpu(bph->off_mem_rsvmap));
const u32 *p_struct = (const u32 *)
((const char *)bph + be32_to_cpu(bph->off_dt_struct));
const u32 *p_strings = (const u32 *)
((const char *)bph + be32_to_cpu(bph->off_dt_strings));
u32 tag;
const u32 *p;
const char *s, *t;
int depth, sz, shift;
int i;
u64 addr, size;
if (be32_to_cpu(bph->magic) != OF_DT_HEADER) {
/* not valid tree */
return;
}
depth = 0;
shift = 4;
for (i = 0;; i++) {
addr = be64_to_cpu(p_rsvmap[i * 2]);
size = be64_to_cpu(p_rsvmap[i * 2 + 1]);
if (addr == 0 && size == 0)
break;
printf("/memreserve/ 0x%llx 0x%llx;\n", addr, size);
}
p = p_struct;
while ((tag = be32_to_cpu(*p++)) != OF_DT_END) {
/* printf("tag: 0x%08x (%d)\n", tag, p - p_struct); */
if (tag == OF_DT_BEGIN_NODE) {
s = (const char *)p;
p = (u32 *) _ALIGN((unsigned long)p + strlen(s) + 1, 4);
printf("%*s%s {\n", depth * shift, "", s);
depth++;
continue;
}
if (tag == OF_DT_END_NODE) {
depth--;
printf("%*s};\n", depth * shift, "");
continue;
}
if (tag == OF_DT_NOP) {
printf("%*s[NOP]\n", depth * shift, "");
continue;
}
if (tag != OF_DT_PROP) {
fprintf(stderr, "%*s ** Unknown tag 0x%08x\n",
depth * shift, "", tag);
break;
}
sz = be32_to_cpu(*p++);
s = (const char *)p_strings + be32_to_cpu(*p++);
t = (const char *)p;
p = (const u32 *)_ALIGN((unsigned long)p + sz, 4);
printf("%*s%s", depth * shift, "", s);
print_data(t, sz);
printf(";\n");
}
}
void ft_backtrack_node(struct ft_cxt *cxt)
{
if (be32_to_cpu(*(u32 *) (cxt->p - 4)) != OF_DT_END_NODE)
return; /* XXX only for node */
cxt->p -= 4;
}
/* note that the root node of the blob is "peeled" off */
void ft_merge_blob(struct ft_cxt *cxt, void *blob)
{
struct boot_param_header *bph = (struct boot_param_header *)blob;
u32 *p_struct = (u32 *) ((char *)bph + be32_to_cpu(bph->off_dt_struct));
u32 *p_strings =
(u32 *) ((char *)bph + be32_to_cpu(bph->off_dt_strings));
u32 tag, *p;
char *s, *t;
int depth, sz;
if (be32_to_cpu(*(u32 *) (cxt->p - 4)) != OF_DT_END_NODE)
return; /* XXX only for node */
cxt->p -= 4;
depth = 0;
p = p_struct;
while ((tag = be32_to_cpu(*p++)) != OF_DT_END) {
/* printf("tag: 0x%08x (%d) - %d\n", tag, p - p_struct, depth); */
if (tag == OF_DT_BEGIN_NODE) {
s = (char *)p;
p = (u32 *) _ALIGN((unsigned long)p + strlen(s) + 1, 4);
if (depth++ > 0)
ft_begin_node(cxt, s);
continue;
}
if (tag == OF_DT_END_NODE) {
ft_end_node(cxt);
if (--depth == 0)
break;
continue;
}
if (tag == OF_DT_NOP)
continue;
if (tag != OF_DT_PROP)
break;
sz = be32_to_cpu(*p++);
s = (char *)p_strings + be32_to_cpu(*p++);
t = (char *)p;
p = (u32 *) _ALIGN((unsigned long)p + sz, 4);
ft_prop(cxt, s, t, sz);
}
}
/* Set ptrs to current one's info; return addr of next one */
static inline u32 *ft_next(u32 *p, u32 *p_strings, u32 version,
u32 **tagpp, char **namepp, char **datapp, u32 **sizepp)
{
u32 sz;
*namepp = NULL;
*datapp = NULL;
*sizepp = NULL;
*tagpp = p;
switch (be32_to_cpu(*p++)) { /* Tag */
case OF_DT_BEGIN_NODE:
*namepp = (char *)p;
p = (u32 *)_ALIGN((u32)p + strlen((char *)p) + 1, 4);
break;
case OF_DT_PROP:
sz = be32_to_cpu(*p);
*sizepp = p++;
*namepp = (char *)p_strings + be32_to_cpu(*p++);
if ((version < 0x10) && (sz >= 8))
p = (u32 *)_ALIGN((unsigned long)p, 8);
*datapp = (char *)p;
p = (u32 *)_ALIGN((unsigned long)p + sz, 4);
break;
case OF_DT_END_NODE:
case OF_DT_NOP:
break;
case OF_DT_END:
default:
p = NULL;
break;
}
return p;
}
void *ft_find_device(const void *bphp, const char *srch_path)
{
const struct boot_param_header *bph = bphp;
u32 *p_struct = (u32 *)((char *)bph + be32_to_cpu(bph->off_dt_struct));
u32 *p_strings= (u32 *)((char *)bph + be32_to_cpu(bph->off_dt_strings));
u32 version = be32_to_cpu(bph->version);
u32 *p, *tagp, *sizep;
char *pathp, *datap;
static char path[MAX_PATH_LEN];
path[0] = '\0';
p = p_struct;
while ((p = ft_next(p, p_strings, version, &tagp, &pathp, &datap,
&sizep)) != NULL)
switch (be32_to_cpu(*tagp)) {
case OF_DT_BEGIN_NODE:
strcat(path, pathp);
if (!strcmp(path, srch_path))
return tagp;
strcat(path, "/");
break;
case OF_DT_END_NODE:
ft_parentize(path, 1);
break;
}
return NULL;
}
int ft_get_prop(const void *bphp, const void *node, const char *propname,
void *buf, const unsigned int buflen)
{
const struct boot_param_header *bph = bphp;
u32 *p_strings= (u32 *)((char *)bph + be32_to_cpu(bph->off_dt_strings));
u32 version = be32_to_cpu(bph->version);
u32 *p, *tagp, *sizep, size;
char *propnmp, *datap;
int level;
level = 0;
p = (u32 *)node;
while ((p = ft_next(p, p_strings, version, &tagp, &propnmp, &datap,
&sizep)) != NULL)
switch (be32_to_cpu(*tagp)) {
case OF_DT_BEGIN_NODE:
level++;
break;
case OF_DT_PROP:
if ((level == 1) && !strcmp(propnmp, propname)) {
size = min(be32_to_cpu(*sizep), (u32)buflen);
memcpy(buf, datap, size);
return size;
}
break;
case OF_DT_END_NODE:
if (--level <= 0)
return -1;
break;
}
return -1;
}
static void ft_modify_prop(void **bphpp, char *datap, u32 *old_prop_sizep,
const char *buf, const unsigned int buflen)
{
u32 old_prop_data_len, new_prop_data_len;
old_prop_data_len = _ALIGN(be32_to_cpu(*old_prop_sizep), 4);
new_prop_data_len = _ALIGN(buflen, 4);
/* Check if new prop data fits in old prop data area */
if (new_prop_data_len == old_prop_data_len) {
memcpy(datap, buf, buflen);
*old_prop_sizep = cpu_to_be32(buflen);
}
else { /* Need to alloc new area to put larger or smaller ft */
struct boot_param_header *old_bph = *bphpp, *new_bph;
u32 *old_tailp, *new_tailp, *new_datap;
u32 old_total_size, new_total_size, head_len, tail_len, diff, v;
old_total_size = be32_to_cpu(old_bph->totalsize);
head_len = (u32)datap - (u32)old_bph;
tail_len = old_total_size - (head_len + old_prop_data_len);
old_tailp = (u32 *)((u32)datap + old_prop_data_len);
new_total_size = head_len + new_prop_data_len + tail_len;
if (!(new_bph = malloc(new_total_size))) {
printf("Can't alloc space for new ft\n\r");
exit();
}
new_datap = (u32 *)((u32)new_bph + head_len);
new_tailp = (u32 *)((u32)new_datap + new_prop_data_len);
memcpy(new_bph, *bphpp, head_len);
memcpy(new_datap, buf, buflen);
memcpy(new_tailp, old_tailp, tail_len);
*(new_datap - 2) = cpu_to_be32(buflen); /* Set prop size */
new_bph->totalsize = cpu_to_be32(new_total_size);
diff = new_prop_data_len - old_prop_data_len;
if (be32_to_cpu(old_bph->off_dt_strings)
> be32_to_cpu(old_bph->off_dt_struct)) {
v = be32_to_cpu(new_bph->off_dt_strings);
new_bph->off_dt_strings = cpu_to_be32(v + diff);
}
if (be32_to_cpu(old_bph->off_mem_rsvmap)
> be32_to_cpu(old_bph->off_dt_struct)) {
v = be32_to_cpu(new_bph->off_mem_rsvmap);
new_bph->off_mem_rsvmap = cpu_to_be32(v + diff);
}
free(*bphpp, old_total_size);
*bphpp = new_bph;
}
}
/*
* - Only modifies existing properties.
* - The dev tree passed in may be freed and a new one allocated
* (and *bphpp set to location of new dev tree).
*/
int ft_set_prop(void **bphpp, void *node, const char *propname,
const void *buf, const unsigned int buflen)
{
struct boot_param_header *bph = *bphpp;
u32 *p_strings= (u32 *)((char *)bph + be32_to_cpu(bph->off_dt_strings));
u32 version = be32_to_cpu(bph->version);
u32 *p, *tagp, *sizep;
char *propnmp, *datap;
int level;
level = 0;
p = node;
while ((p = ft_next(p, p_strings, version, &tagp, &propnmp, &datap,
&sizep)) != NULL)
switch (be32_to_cpu(*tagp)) {
case OF_DT_BEGIN_NODE:
level++;
break;
case OF_DT_PROP:
if ((level == 1) && !strcmp(propnmp, propname)) {
ft_modify_prop(bphpp, datap, sizep, buf,
buflen);
return be32_to_cpu(*sizep);
}
break;
case OF_DT_END_NODE:
if (--level <= 0)
return -1;
break;
}
return -1;
}
[-- Attachment #3: flatdevtree.h --]
[-- Type: text/x-chdr, Size: 3650 bytes --]
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef FLATDEVTREE_H
#define FLATDEVTREE_H
#include <flatdevtree_env.h>
/* Definitions used by the flattened device tree */
#define OF_DT_HEADER 0xd00dfeed /* marker */
#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */
#define OF_DT_END_NODE 0x2 /* End node */
#define OF_DT_PROP 0x3 /* Property: name off, size, content */
#define OF_DT_NOP 0x4 /* nop */
#define OF_DT_END 0x9
#define OF_DT_VERSION 0x10
struct boot_param_header {
u32 magic; /* magic word OF_DT_HEADER */
u32 totalsize; /* total size of DT block */
u32 off_dt_struct; /* offset to structure */
u32 off_dt_strings; /* offset to strings */
u32 off_mem_rsvmap; /* offset to memory reserve map */
u32 version; /* format version */
u32 last_comp_version; /* last compatible version */
/* version 2 fields below */
u32 boot_cpuid_phys; /* Physical CPU id we're booting on */
/* version 3 fields below */
u32 dt_strings_size; /* size of the DT strings block */
};
struct ft_cxt {
struct boot_param_header *bph;
int max_size; /* maximum size of tree */
int overflow; /* set when this happens */
char *p, *pstr, *pres; /* running pointers */
char *p_begin, *pstr_begin, *pres_begin; /* starting pointers */
char *p_anchor; /* start of constructed area */
int struct_size, strings_size, res_size;
};
void ft_begin_node(struct ft_cxt *cxt, const char *name);
void ft_end_node(struct ft_cxt *cxt);
void ft_begin_tree(struct ft_cxt *cxt);
int ft_end_tree(struct ft_cxt *cxt);
void ft_nop(struct ft_cxt *cxt);
void ft_prop(struct ft_cxt *cxt, const char *name,
const void *data, unsigned int sz);
void ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str);
void ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val);
void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size);
void ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size);
void ft_dump_blob(const void *bphp);
void ft_merge_blob(struct ft_cxt *cxt, void *blob);
void *ft_find_device(const void *bphp, const char *srch_path);
int ft_get_prop(const void *bphp, const void *node, const char *propname,
void *buf, const unsigned int buflen);
int ft_set_prop(void **bphp, void *node, const char *propname,
const void *buf, const unsigned int buflen);
static inline char *ft_strrchr(const char *s, int c)
{
const char *p = s + strlen(s);
do {
if (*p == (char)c)
return (char *)p;
} while (--p >= s);
return NULL;
}
/* 'path' is modified */
static inline void ft_parentize(char *path, u8 leave_slash)
{
char *s = &path[strlen(path) - 1];
if (*s == '/')
*s = '\0';
s = ft_strrchr(path, '/');
if (s != NULL) {
if (leave_slash)
s[1] = '\0';
else if (s[0] == '/')
s[0] = '\0';
}
}
#endif /* FLATDEVTREE_H */
[-- Attachment #4: flatdevtree_env.h --]
[-- Type: text/x-chdr, Size: 1142 bytes --]
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _PPC_BOOT_FLATDEVTREE_ENV_H_
#define _PPC_BOOT_FLATDEVTREE_ENV_H_
#include <stdarg.h>
#include <stddef.h>
#include "types.h"
#include "page.h"
#include "string.h"
#include "stdio.h"
#include "ops.h"
#define be16_to_cpu(x) (x)
#define cpu_to_be16(x) (x)
#define be32_to_cpu(x) (x)
#define cpu_to_be32(x) (x)
#define be64_to_cpu(x) (x)
#define cpu_to_be64(x) (x)
#endif /* _PPC_BOOT_FLATDEVTREE_ENV_H_ */
^ permalink raw reply
* 82xx fcc_enet problem between Linux 2.4 and 2.6
From: Laurent Lagrange @ 2006-08-31 17:46 UTC (permalink / raw)
To: linuxppc-embedded
Hello,
I work on several custom 82xx boards with Linux 2.4 and 2.6.
I have ported Linux 2.6.9 on different boards and I noticed
that I have tx carrier errors on my FCC ports. Almost one
error per xmit.
I reinstalled Linux 2.4.18 on these boards and I have NO ERROR.
The errors arise with PHY configured in 100M full duplex (or autoneg).
The FCC has the same duplex as PHY.
I found on web another mail concerning a problem on PQ2FADS Linux2.6.8
when mounting a NFS. The writer has also noticed that he has
tx carrier errors but the mail focused on mount and not FCC.
> # ifconfig
> eth0 Link encap:Ethernet HWaddr 08:00:17:40:00:03
> inet addr:192.168.0.5 Bcast:192.168.0.255 Mask:255.255.255.0
> UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
> RX packets:122 errors:0 dropped:0 overruns:0 frame:0
> TX packets:114 errors:0 dropped:0 overruns:0 carrier:114
> collisions:0 txqueuelen:1000
> RX bytes:20747 (20.2 kb) TX bytes:14320 (13.9 kb)
> Base address:0x8500
I think this is not a phy or hardware problem but rather a FCC configuration
mismatch in fcc_enet.c.
Thanks for any tips
Laurent
^ permalink raw reply
* Re: [PATCH 4/6] Have x86_64 use add_active_range() and free_area_init_nodes
From: Keith Mannthey @ 2006-08-31 17:52 UTC (permalink / raw)
To: Mel Gorman
Cc: akpm, tony.luck, linuxppc-dev, ak, bob.picco, linux-kernel,
linux-mm
In-Reply-To: <20060831154903.GA7011@skynet.ie>
On 8/31/06, Mel Gorman <mel@skynet.ie> wrote:
> On (30/08/06 13:57), Keith Mannthey didst pronounce:
> > On 8/21/06, Mel Gorman <mel@csn.ul.ie> wrote:
> > >
> ok, great. How much physical memory is installed on the machine? I want to
> determine if the "usable" entries in the e820 map contain physical memory
> or not.
Usable entries in the e820 contian memory. I have about 20-24gb
depending on config.
> When the SRAT is bad, the information is discarded and discovered by an
> alternative method later in the boot process.
>
> In this case, numa_initmem_init() is called after acpi_numa_init(). It
> calls acpi_scan_nodes() which returns -1 because the SRAT is bad. Once
> that happens, either k8_scan_nodes() will be called and the regions
> discovered there or if that is not possible, it'll fall through and
> e820_register_active_regions will be called without any node awareness.
sorry I have missed some of the logic in this patch.
I see now in numa_initmem_init that if no numa setup is found it calls
e820_register_active_regions(0, start_pfn, end_pfn) again.
So if the srat is discard it runs the e820 code again.
> > >diff -rup -X /usr/src/patchset-0.6/bin//dontdiff
> > >linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/x86_64/mm/srat.c
> > >linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/arch/x86_64/mm/srat.c
> > >--- linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/x86_64/mm/srat.c
> > >2006-08-21 09:23:50.000000000 +0100
> > >+++ linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/arch/x86_64/mm/srat.c
> > >2006-08-21 10:15:58.000000000 +0100
> > >@@ -84,6 +84,7 @@ static __init void bad_srat(void)
> > > apicid_to_node[i] = NUMA_NO_NODE;
> > > for (i = 0; i < MAX_NUMNODES; i++)
> > > nodes_add[i].start = nodes[i].end = 0;
> > >+ remove_all_active_ranges();
> > > }
> >
> > We go back to setup_arch with no active areas?
> >
>
> Yes, and it'll be discovered using an alternative method later. There is
> no point returning to setup_arch with known bad information about active
> areas.
Totally agreeded! I just didn't the the fallback path.
>
> > > static __init inline int srat_disabled(void)
> > >@@ -166,7 +167,7 @@ static int hotadd_enough_memory(struct b
> > >
> > > if (mem < 0)
> > > return 0;
> > >- allowed = (end_pfn - e820_hole_size(0, end_pfn)) * PAGE_SIZE;
> > >+ allowed = (end_pfn - absent_pages_in_range(0, end_pfn)) *
> > >PAGE_SIZE;
> > > allowed = (allowed / 100) * hotadd_percent;
> > > if (allocated + mem > allowed) {
> > > unsigned long range;
> > >@@ -238,7 +239,7 @@ static int reserve_hotadd(int node, unsi
> > > }
> > >
> > > /* This check might be a bit too strict, but I'm keeping it for
> > > now. */
> > >- if (e820_hole_size(s_pfn, e_pfn) != e_pfn - s_pfn) {
> > >+ if (absent_pages_in_range(s_pfn, e_pfn) != e_pfn - s_pfn) {
> > > printk(KERN_ERR "SRAT: Hotplug area has existing
> > > memory\n");
> > > return -1;
> > > }
> > We really do want to to compare against the e820 map at it contains
> > the memory that is really present (this info was blown away before
> > acpi_numa)
>
> The information used by absent_pages_in_range() should match what was
> available to e820_hole_size().
Is absent_pages_in_range a check against the e820 or the
add_pages_to_range calls?
> > Anyway I fixed up to have the current chunk added
> > (e820_register_active_regions) after calling this code so it logicaly
> > makes sense but it still trip over the check.
> > I am not sure what you
> > are printing out in you debug code but dosen't look like pfns or
> > phys_addresses but maybe it can tell us why the check fails.
> >
>
> My debug code for add_active_range() printing out pfns but I spotted one
> case where absent_pages_in_range(I) does not do what one would expect.
> Lets say the ranges with physical memory was 0->1000 and 2000-3000 (in
> pfns). absent_pages_in_range(0, 3000) would return 1000 as you'd expect but
> absent_pages_in_range(5000-6000) would return 0! I have a patch that might
> fix this at the end of the mail but I'm not sure it's the problem you are
> hitting. In the bootlog, I see;
>
> SRAT: Node 0 PXM 0 0-80000000
> Entering add_active_range(0, 0, 152) 0 entries of 3200 used
> Entering add_active_range(0, 256, 524165) 1 entries of 3200 used
> SRAT: Node 0 PXM 0 0-470000000
> Entering add_active_range(0, 0, 152) 2 entries of 3200 used
> Entering add_active_range(0, 256, 524165) 2 entries of 3200 used
> Entering add_active_range(0, 1048576, 4653056) 2 entries of 3200 used
> SRAT: Node 0 PXM 0 0-1070000000
> SRAT: Hotplug area has existing memory
>
> The last part (0-1070000000) is checked as a hotplug area but it's clear
> that memory exists in that range. As reserve_hotadd() requires that the
> whole range be a hole, I'm having trouble seeing how it ever successfully
> reserved unless the ranges going into reserve_hotadd() are something other
> than the pfn range for 0-1070000000). The patch later will print out the
> range used by reserve_hotadd() so we can see.
No the whole node is 0-1070000000 the hot add range is 470000000-1070000000
reserve_hotadd is called with start and end not nd->start nd->end.
470000000-1070000000 sould be empty.
> > >@@ -329,6 +330,8 @@ acpi_numa_memory_affinity_init(struct ac
> > >
> > > printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm,
> > > nd->start, nd->end);
> > >+ e820_register_active_regions(node, nd->start >> PAGE_SHIFT,
> > >+ nd->end >> PAGE_SHIFT);
> >
> > A node chunk in this section of code may be a hot-pluggable zone. With
> > MEMORY_HOTPLUG_SPARSE we don't want to register these regions.
> >
>
> The ranges should not get registered as active memory by
> e820_register_active_regions() unless they are marked E820_RAM. My
> understanding is that the regions for hotadd would be marked "reserved"
> in the e820 map. Is that wrong?
This is wrong. In a mult-node system that last node add area will not
be marked reserved by the e820. The e820 only defines memory <
end_pfn. the last node add area is > end_pfn.
With RESERVE based add-memory you want the add-areas repored by the
srat to be setup during boot like all the other pages.
> > > if (ma->flags.hot_pluggable && !reserve_hotadd(node, start, end) <
> > > 0) {
> > > /* Ignore hotadd region. Undo damage */
> >
> > I have but the e820_register_active_regions as a else to this
> > statment the absent pages check fails.
> >
>
> The patch below omits this change because I think
> e820_register_active_regions() will still have got called by the time
> you encounter a hotplug area.
called but then removed in setup arch.
> > Also nodes_cover_memory and alot of these check were based against
> > comparing the srat data against the e820. Now all this code is
> > comparing SRAT against SRAT....
> >
>
> I don't see why. The SRAT table passes a range to
> e820_register_active_regions() so should be comparing SRAT to e820
let me go off and look at e820_register_active_regions() some more.
> > I am willing to help here but we should compare the SRAT against to
> > e820. Table v. Table.
> >
> > What to you think should be done?
> >
>
> Can you read through this patch and see does it address the problem in any
> way? If it doesn't, can you send a complete bootlog so I can see what is
> being sent to reserve_hotadd()? Thanks
Sure thing. It is just the hot-add area I am guessing it is an off by
one error of some sort.
What is all this code buying us? Since this code dosen't appear to do
anything to help the arch out (just increases it's vm boot code
complexity a little) maybe insead of weaving
e820_register_active_regions() calls throught out the boot process you
should just waint untill things are sorted out and do a quick scan of
node data that has been setup at the end?
What are the future plans for this api?
Thanks,
Keith u
^ permalink raw reply
* Re: pci error recovery procedure
From: Linas Vepstas @ 2006-08-31 17:50 UTC (permalink / raw)
To: Zhang, Yanmin
Cc: linuxppc-dev, linux-pci, Yanmin Zhang, inux-kernel, Rajesh Shah
In-Reply-To: <1157008212.20092.36.camel@ymzhang-perf.sh.intel.com>
On Thu, Aug 31, 2006 at 03:10:12PM +0800, Zhang, Yanmin wrote:
> Linas,
>
> I am reviewing the error handlers of e1000 driver and got some ideas. My
> startpoint is to simplify the err handler implementations for drivers, or
> driver developers are *not willing* to add it if it's too complicated.
I don't see that its to complicated ...
> 1) Callback mmio_enabled looks useless. Documentation/pci-error-recovery.txt
> says the current powerpc implementation does not implement this callback.
I don't know if its useless or not. I have not needed it yet for the
symbios, ipr and e1000 drivers, but its possible that some more
sophisticated device may want it. I'm tempted to keep it a while
longer befoe discarding it.
The scenario is this: the device driver decides that, rather than asking
for a full electical reset of the card, instead, it wants to perform
its own recovery. It can do this as follows:
a) enable MMIO
b) issue reset command to adapter
c) enable DMA.
If we enabled both DMA and MMIO at the same time, there are mnay cases
where the card will immediately trap again -- for example, if its
DMA'ing to some crazy address. Thus, typically, one wants DMA disabled
until after the card reset. Withouth the mmio_enabled() reset, there
is no way of doing this.
> 2) Callback slot_reset could be merged with resume. The new resume could be:
> int (*error_resume)(struct pci_dev *dev); I checked e1000 and e100 drivers and
> think there is no actual reason to have both slot_reset and resume.
The idea here was to handle multi-function cards. On a multi-function card,
*all* devices need to indicate that they were able to reset. Once all devices
have been successfuly reset, then operation can be resumed. If the reset
of one function fails, then operation is not resumed for any f the
functions.
> 3) link_reset is not used in pci express aer implementation, so it could be
> deleted also.
OK. Link reset was added explicitly to support PCI-E, so if its not wanted,
we can eliminate it.
> How did you test e1000 err_handler?
We have three methods (I thought these were documented). In one, a
technician brushes a grounding strap to some of the signal pins.
In the second, slots are populated with known-bad cards. The third test
involes sending a command down to the pci bridge chip, telling it to
behave as if it detected an error. For development, the last is
quick-n-easy.
> In the simulated enviroment, the testing might be
> incorrect.
Why would it be incorrect? I mean, we don't simulate having someone pour a
cup of coffee into the guts of the machine ... but my understanding is
the machines do get standard vibration/thermal/humidity testing, which
is good enough for me.
> For example, e1000_io_error_detected would call e1000_down to reset NIC.
Why would that be incorrect?
> During
> our last discussion on LKML, you said PowerPC will block further I/O if the platform captures
> a pci error, so the all I/O in e1000_down will be blocked. Later on, e1000_io_slot_reset
> will reenable pci device and initiate NIC. I guess late initiate might fail because prior
> e1000_down I/O don't reach NIC.
Why would it fail? The e1000_down serves primarily to get the Linux
kernel into a known state. It doesn't matter what happens to the card,
since the next step will be to perform an electrical reset of the card.
--linas
^ permalink raw reply
* Re: [PATCH] fix NUMA interleaving for huge pages (was RE: libnuma interleaving oddness)
From: Christoph Lameter @ 2006-08-31 16:37 UTC (permalink / raw)
To: Nishanth Aravamudan; +Cc: akpm, linuxppc-dev, Andi Kleen, linux-mm, lnxninja
In-Reply-To: <20060831160052.GB23990@us.ibm.com>
On Thu, 31 Aug 2006, Nishanth Aravamudan wrote:
> Andrew, can we get this into 2.6.18?
Acked-by: Christoph Lameter <clameter@sgi.con>
^ permalink raw reply
* Rattler 8347 and USB 2.0
From: Jamie Guinan @ 2006-08-31 16:14 UTC (permalink / raw)
To: linuxppc-embedded
Greetings,
I have an mpc8347 board here (A&M Rattler 8347). It shipped with a
2.6.16 patched enough to boot the board, but support for freescale USB
2.0 (ehci) is not present.
Working my way backwards in the mainline kernel tree (2.6.18-rc5), I
found drivers/usb/host/ehci-fsl.c, for FreeScale/PPC EHCI support.
In that module, usb_hcd_fsl_probe() requires an initialized "struct
fsl_usb2_platform_data", which only appears in
arch/powerpc/sysdev/fsl_soc.c, yet the 2.6.16 patch provided puts the
board in arch/ppc.
My question is, what would be the best way to go about getting
ehci-fsl.c working with this board?
1) Nudge the Rattler port from arch/ppc to arch/powerpc. One problem
with this is that the rattler uses RedBoot, and reading this,
http://ozlabs.org/pipermail/linuxppc-embedded/2006-August/024116.html
it looks like arch/powerpc wants to boot from OpenFirmware-like
"flattened device tree" (does RedBoot support this?).
2) Support ehci-fsl.c from arch/ppc. If arch/ppc is deprecated,
that's a bad long-term solution. And since fsl_soc.c lives
under arch/powerpc, that doesn't look good either.
Thoughts?
-Jamie
^ permalink raw reply
* Re: mvme
From: Matt Porter @ 2006-08-31 16:38 UTC (permalink / raw)
To: Loïc Damm; +Cc: linuxppc-embedded
In-Reply-To: <E3141661-C539-4A0D-A342-EDDD18A4E27D@college-de-france.fr>
On Thu, Aug 31, 2006 at 02:25:58PM +0200, Loïc Damm wrote:
> Hello,
>
> I found a page about MVME cards on the web posted by you... I was
> trying to fix a problem with a machine running OS9, so I was asking
> to myself if you could help me. I would be very happy if you took few
> minutes to consider this mail...
>
> So, my problem is about booting a Motorola MVME 162-223 card. I have
MVME162 is a 68k board. Wrong list. Go see http://www.linux-m68k.org
-Matt
^ permalink raw reply
* Re: [PATCH] fix NUMA interleaving for huge pages (was RE: libnuma interleaving oddness)
From: Tim Pepper @ 2006-08-31 16:19 UTC (permalink / raw)
To: Nishanth Aravamudan
Cc: akpm, linux-mm, Andi Kleen, linuxppc-dev, Christoph Lameter
In-Reply-To: <20060831160052.GB23990@us.ibm.com>
On 8/31/06, Nishanth Aravamudan <nacc@us.ibm.com> wrote:
>
> Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
Acked-by: Tim Pepper <lnxninja@us.ibm.com>
^ permalink raw reply
* Re: [PATCH 4/6] Have x86_64 use add_active_range() and free_area_init_nodes
From: Mel Gorman @ 2006-08-31 15:49 UTC (permalink / raw)
To: Keith Mannthey
Cc: akpm, tony.luck, linuxppc-dev, ak, bob.picco, linux-kernel,
linux-mm
In-Reply-To: <a762e240608301357n3915250bk8546dd340d5d4d77@mail.gmail.com>
On (30/08/06 13:57), Keith Mannthey didst pronounce:
> On 8/21/06, Mel Gorman <mel@csn.ul.ie> wrote:
> >
> >Size zones and holes in an architecture independent manner for x86_64.
>
>
> Hey Mel,
Hi Keith.
> I am having some trouble with the srat.c changes. I keep running into
> "SRAT: Hotplug area has existing memory" so am am taking more throught
> look at this patch.
> I am working on 2.6.18-rc4-mm3 x86_64.
>
ok, great. How much physical memory is installed on the machine? I want to
determine if the "usable" entries in the e820 map contain physical memory
or not.
> srat.c is doing some sanity checking against the e820 and hot-add
> memory ranges. BIOS folk aren't to be trusted with the SRAT. Calling
> remove_all_active_ranges before acpi_numa_init leaves nothing to fall
> back onto if the SRAT is bad. (see bad_srat()). What should happen
> when we discard the srat info?
>
When the SRAT is bad, the information is discarded and discovered by an
alternative method later in the boot process.
In this case, numa_initmem_init() is called after acpi_numa_init(). It
calls acpi_scan_nodes() which returns -1 because the SRAT is bad. Once
that happens, either k8_scan_nodes() will be called and the regions
discovered there or if that is not possible, it'll fall through and
e820_register_active_regions will be called without any node awareness.
> i386 code may have similar fallback logic (haven't been there in a while)
>
There is fallback logic in the i386 code as well.
> also
>
> >diff -rup -X /usr/src/patchset-0.6/bin//dontdiff
> >linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/x86_64/mm/srat.c
> >linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/arch/x86_64/mm/srat.c
> >--- linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/x86_64/mm/srat.c
> >2006-08-21 09:23:50.000000000 +0100
> >+++ linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/arch/x86_64/mm/srat.c
> >2006-08-21 10:15:58.000000000 +0100
> >@@ -84,6 +84,7 @@ static __init void bad_srat(void)
> > apicid_to_node[i] = NUMA_NO_NODE;
> > for (i = 0; i < MAX_NUMNODES; i++)
> > nodes_add[i].start = nodes[i].end = 0;
> >+ remove_all_active_ranges();
> > }
>
> We go back to setup_arch with no active areas?
>
Yes, and it'll be discovered using an alternative method later. There is
no point returning to setup_arch with known bad information about active
areas.
> > static __init inline int srat_disabled(void)
> >@@ -166,7 +167,7 @@ static int hotadd_enough_memory(struct b
> >
> > if (mem < 0)
> > return 0;
> >- allowed = (end_pfn - e820_hole_size(0, end_pfn)) * PAGE_SIZE;
> >+ allowed = (end_pfn - absent_pages_in_range(0, end_pfn)) *
> >PAGE_SIZE;
> > allowed = (allowed / 100) * hotadd_percent;
> > if (allocated + mem > allowed) {
> > unsigned long range;
> >@@ -238,7 +239,7 @@ static int reserve_hotadd(int node, unsi
> > }
> >
> > /* This check might be a bit too strict, but I'm keeping it for
> > now. */
> >- if (e820_hole_size(s_pfn, e_pfn) != e_pfn - s_pfn) {
> >+ if (absent_pages_in_range(s_pfn, e_pfn) != e_pfn - s_pfn) {
> > printk(KERN_ERR "SRAT: Hotplug area has existing
> > memory\n");
> > return -1;
> > }
> We really do want to to compare against the e820 map at it contains
> the memory that is really present (this info was blown away before
> acpi_numa)
The information used by absent_pages_in_range() should match what was
available to e820_hole_size().
> Anyway I fixed up to have the current chunk added
> (e820_register_active_regions) after calling this code so it logicaly
> makes sense but it still trip over the check.
> I am not sure what you
> are printing out in you debug code but dosen't look like pfns or
> phys_addresses but maybe it can tell us why the check fails.
>
My debug code for add_active_range() printing out pfns but I spotted one
case where absent_pages_in_range(I) does not do what one would expect.
Lets say the ranges with physical memory was 0->1000 and 2000-3000 (in
pfns). absent_pages_in_range(0, 3000) would return 1000 as you'd expect but
absent_pages_in_range(5000-6000) would return 0! I have a patch that might
fix this at the end of the mail but I'm not sure it's the problem you are
hitting. In the bootlog, I see;
SRAT: Node 0 PXM 0 0-80000000
Entering add_active_range(0, 0, 152) 0 entries of 3200 used
Entering add_active_range(0, 256, 524165) 1 entries of 3200 used
SRAT: Node 0 PXM 0 0-470000000
Entering add_active_range(0, 0, 152) 2 entries of 3200 used
Entering add_active_range(0, 256, 524165) 2 entries of 3200 used
Entering add_active_range(0, 1048576, 4653056) 2 entries of 3200 used
SRAT: Node 0 PXM 0 0-1070000000
SRAT: Hotplug area has existing memory
The last part (0-1070000000) is checked as a hotplug area but it's clear
that memory exists in that range. As reserve_hotadd() requires that the
whole range be a hole, I'm having trouble seeing how it ever successfully
reserved unless the ranges going into reserve_hotadd() are something other
than the pfn range for 0-1070000000). The patch later will print out the
range used by reserve_hotadd() so we can see.
> >@@ -329,6 +330,8 @@ acpi_numa_memory_affinity_init(struct ac
> >
> > printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm,
> > nd->start, nd->end);
> >+ e820_register_active_regions(node, nd->start >> PAGE_SHIFT,
> >+ nd->end >> PAGE_SHIFT);
>
> A node chunk in this section of code may be a hot-pluggable zone. With
> MEMORY_HOTPLUG_SPARSE we don't want to register these regions.
>
The ranges should not get registered as active memory by
e820_register_active_regions() unless they are marked E820_RAM. My
understanding is that the regions for hotadd would be marked "reserved"
in the e820 map. Is that wrong?
> > if (ma->flags.hot_pluggable && !reserve_hotadd(node, start, end) <
> > 0) {
> > /* Ignore hotadd region. Undo damage */
>
> I have but the e820_register_active_regions as a else to this
> statment the absent pages check fails.
>
The patch below omits this change because I think
e820_register_active_regions() will still have got called by the time
you encounter a hotplug area.
> Also nodes_cover_memory and alot of these check were based against
> comparing the srat data against the e820. Now all this code is
> comparing SRAT against SRAT....
>
I don't see why. The SRAT table passes a range to
e820_register_active_regions() so should be comparing SRAT to e820
> I am willing to help here but we should compare the SRAT against to
> e820. Table v. Table.
>
> What to you think should be done?
>
Can you read through this patch and see does it address the problem in any
way? If it doesn't, can you send a complete bootlog so I can see what is
being sent to reserve_hotadd()? Thanks
Signed-off-by: Mel Gorman <mel@csn.ul.ie>
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff linux-2.6.18-rc4-mm3-clean/arch/x86_64/mm/srat.c linux-2.6.18-rc4-mm3-fix_x8664_hotadd/arch/x86_64/mm/srat.c
--- linux-2.6.18-rc4-mm3-clean/arch/x86_64/mm/srat.c 2006-08-29 16:25:10.000000000 +0100
+++ linux-2.6.18-rc4-mm3-fix_x8664_hotadd/arch/x86_64/mm/srat.c 2006-08-31 16:17:26.000000000 +0100
@@ -240,7 +240,8 @@ static int reserve_hotadd(int node, unsi
/* This check might be a bit too strict, but I'm keeping it for now. */
if (absent_pages_in_range(s_pfn, e_pfn) != e_pfn - s_pfn) {
- printk(KERN_ERR "SRAT: Hotplug area has existing memory\n");
+ printk(KERN_ERR "SRAT: Hotplug area %lu -> %lu has existing memory\n",
+ s_pfn, e_pfn);
return -1;
}
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff linux-2.6.18-rc4-mm3-clean/mm/page_alloc.c linux-2.6.18-rc4-mm3-fix_x8664_hotadd/mm/page_alloc.c
--- linux-2.6.18-rc4-mm3-clean/mm/page_alloc.c 2006-08-29 16:25:31.000000000 +0100
+++ linux-2.6.18-rc4-mm3-fix_x8664_hotadd/mm/page_alloc.c 2006-08-31 14:52:38.000000000 +0100
@@ -2280,6 +2280,10 @@ unsigned long __init __absent_pages_in_r
prev_end_pfn = early_node_map[i].end_pfn;
}
+ /* If the range is outside of physical memory, return the range */
+ if (range_start_pfn > prev_end_pfn)
+ hole_pages = range_end_pfn - range_start_pfn;
+
return hole_pages;
}
^ permalink raw reply
* RE: Unable to build ELDK 4.0
From: Mathews, Phil @ 2006-08-31 16:13 UTC (permalink / raw)
To: Wolfgang Denk; +Cc: Linuxppc-embedded
In-Reply-To: <20060831155857.35812352640@atlas.denx.de>
[-- Attachment #1: Type: text/plain, Size: 2469 bytes --]
-----Original Message-----
From: Wolfgang Denk [mailto:wd@denx.de]
Sent: Thu 8/31/2006 11:58 AM
To: Mathews, Phil
Cc: Linuxppc-embedded@ozlabs.org
Subject: Re: Unable to build ELDK 4.0
Dear Phil,
in message <3E8081396F6B524BA2854E7FA3F16438042EB1DB@mail.innocon.com> you wrote:
>
> I am attempting to build the ELDK kernel using the directions in
> /home/mathews/ELDK/ppc_6xx/usr/src/linux-2.6.15/README. The makefile is
Please also RTFM: http://www.denx.de/wiki/DULG/Manual?stickboard=yosemite ,
especially section "6.2. Kernel Configuration and Compilation":
http://www.denx.de/wiki/view/DULG/LinuxConfiguration#Section_6.2.
Note that I selected the DULG-version for a board for which 2.6
kernel support is available.
> trying to execute powerPC code (fixdep) on my Pentium box. Where can I
> get a X86 version of this program?
This is a consequence of wrong make commands.
> ##### Make attempt:
> mathews@mathews:~/ELDK/ppc_6xx/usr/src/linux-2.6.15> make
> O=/home/name/build/kernel menuconfig
You must pass correct ARCH= and CROSS_COMPILE= arguments when running
make, i. e.
make ARCH=ppc CROSS_COMPILE=ppc_6xx- ... menuconfig
etc. Also make sure to start from a clean source tree, i. e. run
"make mrproper" to clean up before configuring your board.
Best regards,
Wolfgang Denk
--
Software Engineering: Embedded and Realtime Systems, Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
A modem is a baudy house.
====================
------Follow Up-----
====================
After doing "make mrproper" and again following the README file that came with ELDK:
env | grep -e ARCH -e COMPILE
ARCH=ppc
CROSS_COMPILE=ppc_6xx-
mathews@mathews:~/ELDK/ppc_6xx/usr/src/linux-2.6.15> make O=/home/name/build/kernel menuconfig
HOSTCC scripts/basic/fixdep
In file included from /home/mathews/ELDK/usr/../ppc_6xx/usr/include/sys/socket.h:35,
from /home/mathews/ELDK/usr/../ppc_6xx/usr/include/netinet/in.h:24,
from /home/mathews/ELDK/usr/../ppc_6xx/usr/include/arpa/inet.h:23,
from /home/mathews/ELDK/ppc_6xx/usr/src/linux-2.6.15/scripts/basic/fixdep.c:115:
/home/mathews/ELDK/usr/../ppc_6xx/usr/include/bits/socket.h:304:24: error: asm/socket.h: No such file or directory
make[2]: *** [scripts/basic/fixdep] Error 1
make[1]: *** [scripts_basic] Error 2
make: *** [menuconfig] Error 2
[-- Attachment #2: Type: text/html, Size: 3718 bytes --]
^ permalink raw reply
* Re: [PATCH] fix NUMA interleaving for huge pages (was RE: libnuma interleaving oddness)
From: Adam Litke @ 2006-08-31 16:08 UTC (permalink / raw)
To: Nishanth Aravamudan
Cc: akpm, linux-mm, Andi Kleen, linuxppc-dev, lnxninja,
Christoph Lameter
In-Reply-To: <20060831160052.GB23990@us.ibm.com>
On Thu, 2006-08-31 at 09:00 -0700, Nishanth Aravamudan wrote:
> Since vma->vm_pgoff is in units of smallpages, VMAs for huge pages have
> the lower HPAGE_SHIFT - PAGE_SHIFT bits always cleared, which results in
> badd offsets to the interleave functions. Take this difference from
> small pages into account when calculating the offset. This does add a
> 0-bit shift into the small-page path (via alloc_page_vma()), but I think
> that is negligible. Also add a BUG_ON to prevent the offset from growing
> due to a negative right-shift, which probably shouldn't be allowed
> anyways.
>
> Tested on an 8-memory node ppc64 NUMA box and got the interleaving I
> expected.
>
> Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
Acked-by: Adam Litke <agl@us.ibm.com>
--
Adam Litke - (agl at us.ibm.com)
IBM Linux Technology Center
^ permalink raw reply
* [PATCH] fix NUMA interleaving for huge pages (was RE: libnuma interleaving oddness)
From: Nishanth Aravamudan @ 2006-08-31 16:00 UTC (permalink / raw)
To: Christoph Lameter; +Cc: akpm, linuxppc-dev, Andi Kleen, linux-mm, lnxninja
In-Reply-To: <20060831060036.GA18661@us.ibm.com>
On 30.08.2006 [23:00:36 -0700], Nishanth Aravamudan wrote:
> On 30.08.2006 [14:04:40 -0700], Christoph Lameter wrote:
> > > I took out the mlock() call, and I get the same results, FWIW.
> >
> > What zones are available on your box? Any with HIGHMEM?
>
> How do I tell the available zones from userspace? This is ppc64 with
> about 64GB of memory total, it looks like. So, none of the nodes
> (according to /sys/devices/system/node/*/meminfo) have highmem.
>
> > Also what kernel version are we talking about? Before 2.6.18?
>
> The SuSE default, 2.6.16.21 -- I thought I mentioned that in one of my
> replies, sorry.
>
> Tim and I spent most of this afternoon debugging the huge_zonelist()
> callpath with kprobes and jprobes. We found the following via a jprobe
> to offset_li_node():
<snip lengthy previous discussion>
Since vma->vm_pgoff is in units of smallpages, VMAs for huge pages have
the lower HPAGE_SHIFT - PAGE_SHIFT bits always cleared, which results in
badd offsets to the interleave functions. Take this difference from
small pages into account when calculating the offset. This does add a
0-bit shift into the small-page path (via alloc_page_vma()), but I think
that is negligible. Also add a BUG_ON to prevent the offset from growing
due to a negative right-shift, which probably shouldn't be allowed
anyways.
Tested on an 8-memory node ppc64 NUMA box and got the interleaving I
expected.
Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
---
Results with this patch applied, which shouldn't go into the changelog,
I don't think:
for the 4-hugepages at a time case:
20000000 interleave=0-7 file=/hugetlbfs/libhugetlbfs.tmp.r1YKfL huge dirty=4 N0=1 N1=1 N2=1 N3=1
24000000 interleave=0-7 file=/hugetlbfs/libhugetlbfs.tmp.r1YKfL huge dirty=4 N4=1 N5=1 N6=1 N7=1
28000000 interleave=0-7 file=/hugetlbfs/libhugetlbfs.tmp.r1YKfL huge dirty=4 N0=1 N1=1 N2=1 N3=1
for the 1-hugepage at a time case:
20000000 interleave=0-7 file=/hugetlbfs/libhugetlbfs.tmp.LeSnPN huge dirty=1 N0=1
21000000 interleave=0-7 file=/hugetlbfs/libhugetlbfs.tmp.LeSnPN huge dirty=1 N1=1
22000000 interleave=0-7 file=/hugetlbfs/libhugetlbfs.tmp.LeSnPN huge dirty=1 N2=1
23000000 interleave=0-7 file=/hugetlbfs/libhugetlbfs.tmp.LeSnPN huge dirty=1 N3=1
24000000 interleave=0-7 file=/hugetlbfs/libhugetlbfs.tmp.LeSnPN huge dirty=1 N4=1
25000000 interleave=0-7 file=/hugetlbfs/libhugetlbfs.tmp.LeSnPN huge dirty=1 N5=1
26000000 interleave=0-7 file=/hugetlbfs/libhugetlbfs.tmp.LeSnPN huge dirty=1 N6=1
27000000 interleave=0-7 file=/hugetlbfs/libhugetlbfs.tmp.LeSnPN huge dirty=1 N7=1
28000000 interleave=0-7 file=/hugetlbfs/libhugetlbfs.tmp.LeSnPN huge dirty=1 N0=1
Andrew, can we get this into 2.6.18?
diff -urpN 2.6.18-rc5/mm/mempolicy.c 2.6.18-rc5-dev/mm/mempolicy.c
--- 2.6.18-rc5/mm/mempolicy.c 2006-08-30 22:55:33.000000000 -0700
+++ 2.6.18-rc5-dev/mm/mempolicy.c 2006-08-31 08:46:22.000000000 -0700
@@ -1176,7 +1176,15 @@ static inline unsigned interleave_nid(st
if (vma) {
unsigned long off;
- off = vma->vm_pgoff;
+ /*
+ * for small pages, there is no difference between
+ * shift and PAGE_SHIFT, so the bit-shift is safe.
+ * for huge pages, since vm_pgoff is in units of small
+ * pages, we need to shift off the always 0 bits to get
+ * a useful offset.
+ */
+ BUG_ON(shift < PAGE_SHIFT);
+ off = vma->vm_pgoff >> (shift - PAGE_SHIFT);
off += (addr - vma->vm_start) >> shift;
return offset_il_node(pol, vma, off);
} else
--
Nishanth Aravamudan <nacc@us.ibm.com>
IBM Linux Technology Center
^ 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