* [RFC] [PATCH] vmemmap fixes to use smaller pages
From: Benjamin Herrenschmidt @ 2008-04-30 5:41 UTC (permalink / raw)
To: linuxppc-dev list
This patch changes vmemmap to use a different region (region 0xf) of the
address space whose page size can be dynamically configured at boot.
The problem with the current approach of always using 16M pages is that
it's not well suited to machines that have small amounts of memory such
as small partitions on pseries, or PS3's.
In fact, on the PS3, failure to allocate the 16M page backing vmmemmap
tends to prevent hotplugging the HV's "additional" memory, thus limiting
the available memory even more, from my experience down to something
like 80M total, which makes it really not very useable.
The logic used by my match to choose the vmemmap page size is:
- If 16M pages are available and there's 1G or more RAM at boot, use that size.
- Else if 64K pages are available, use that
- Else use 4K pages
I've tested on a POWER6 (16M pages) and on an iSeries POWER3 (4K pages)
and it seems to work fine.
However, when attempting to test on a PS3, it didn't boot.
In fact, it doesn't boot without my patch with current upstream. I tried
booting 2.6.25 with a ps3_defconfig and that doesn't work neither
(though at least when doing the later, I do get a black screen & no
sync, like of ps3fb failed monitor detection, while with current
upstream, I just get the last kexec messages and nothing happens).
Since the PS3 boot failures are impossible to debug unless your email is
@sony* and you have the special magic tools, I'll let Geoff try the
patch out.
Note that I intend to change the way we organize the kernel regions &
SLBs so the actual region will change from 0xf back to something else at
one point, as I simplify the SLB miss handler, but that will be for a
later patch.
Index: linux-work/arch/powerpc/mm/hash_utils_64.c
===================================================================
--- linux-work.orig/arch/powerpc/mm/hash_utils_64.c 2008-04-30 15:00:54.000000000 +1000
+++ linux-work/arch/powerpc/mm/hash_utils_64.c 2008-04-30 15:01:00.000000000 +1000
@@ -94,6 +94,9 @@ unsigned long htab_hash_mask;
int mmu_linear_psize = MMU_PAGE_4K;
int mmu_virtual_psize = MMU_PAGE_4K;
int mmu_vmalloc_psize = MMU_PAGE_4K;
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+int mmu_vmemmap_psize = MMU_PAGE_4K;
+#endif
int mmu_io_psize = MMU_PAGE_4K;
int mmu_kernel_ssize = MMU_SEGSIZE_256M;
int mmu_highuser_ssize = MMU_SEGSIZE_256M;
@@ -387,11 +390,32 @@ static void __init htab_init_page_sizes(
}
#endif /* CONFIG_PPC_64K_PAGES */
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+ /* We try to use 16M pages for vmemmap if that is supported
+ * and we have at least 1G of RAM at boot
+ */
+ if (mmu_psize_defs[MMU_PAGE_16M].shift &&
+ lmb_phys_mem_size() >= 0x40000000)
+ mmu_vmemmap_psize = MMU_PAGE_16M;
+ else if (mmu_psize_defs[MMU_PAGE_64K].shift)
+ mmu_vmemmap_psize = MMU_PAGE_64K;
+ else
+ mmu_vmemmap_psize = MMU_PAGE_4K;
+#endif /* CONFIG_SPARSEMEM_VMEMMAP */
+
printk(KERN_DEBUG "Page orders: linear mapping = %d, "
- "virtual = %d, io = %d\n",
+ "virtual = %d, io = %d"
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+ ", vmemmap = %d"
+#endif
+ "\n",
mmu_psize_defs[mmu_linear_psize].shift,
mmu_psize_defs[mmu_virtual_psize].shift,
- mmu_psize_defs[mmu_io_psize].shift);
+ mmu_psize_defs[mmu_io_psize].shift
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+ ,mmu_psize_defs[mmu_vmemmap_psize].shift
+#endif
+ );
#ifdef CONFIG_HUGETLB_PAGE
/* Init large page size. Currently, we pick 16M or 1M depending
Index: linux-work/arch/powerpc/mm/init_64.c
===================================================================
--- linux-work.orig/arch/powerpc/mm/init_64.c 2008-04-30 15:00:54.000000000 +1000
+++ linux-work/arch/powerpc/mm/init_64.c 2008-04-30 15:05:02.000000000 +1000
@@ -19,6 +19,8 @@
*
*/
+#undef DEBUG
+
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -208,12 +210,12 @@ int __meminit vmemmap_populated(unsigned
}
int __meminit vmemmap_populate(struct page *start_page,
- unsigned long nr_pages, int node)
+ unsigned long nr_pages, int node)
{
unsigned long mode_rw;
unsigned long start = (unsigned long)start_page;
unsigned long end = (unsigned long)(start_page + nr_pages);
- unsigned long page_size = 1 << mmu_psize_defs[mmu_linear_psize].shift;
+ unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift;
mode_rw = _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX;
@@ -235,11 +237,11 @@ int __meminit vmemmap_populate(struct pa
start, p, __pa(p));
mapped = htab_bolt_mapping(start, start + page_size,
- __pa(p), mode_rw, mmu_linear_psize,
+ __pa(p), mode_rw, mmu_vmemmap_psize,
mmu_kernel_ssize);
BUG_ON(mapped < 0);
}
return 0;
}
-#endif
+#endif /* CONFIG_SPARSEMEM_VMEMMAP */
Index: linux-work/arch/powerpc/mm/slb.c
===================================================================
--- linux-work.orig/arch/powerpc/mm/slb.c 2008-04-30 15:00:54.000000000 +1000
+++ linux-work/arch/powerpc/mm/slb.c 2008-04-30 15:01:14.000000000 +1000
@@ -28,7 +28,7 @@
#include <asm/udbg.h>
#ifdef DEBUG
-#define DBG(fmt...) udbg_printf(fmt)
+#define DBG(fmt...) printk(fmt)
#else
#define DBG(fmt...)
#endif
@@ -263,13 +263,19 @@ void slb_initialize(void)
extern unsigned int *slb_miss_kernel_load_linear;
extern unsigned int *slb_miss_kernel_load_io;
extern unsigned int *slb_compare_rr_to_size;
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+ extern unsigned int *slb_miss_kernel_load_vmemmap;
+ unsigned long vmemmap_llp;
+#endif
/* Prepare our SLB miss handler based on our page size */
linear_llp = mmu_psize_defs[mmu_linear_psize].sllp;
io_llp = mmu_psize_defs[mmu_io_psize].sllp;
vmalloc_llp = mmu_psize_defs[mmu_vmalloc_psize].sllp;
get_paca()->vmalloc_sllp = SLB_VSID_KERNEL | vmalloc_llp;
-
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+ vmemmap_llp = mmu_psize_defs[mmu_vmemmap_psize].sllp;
+#endif
if (!slb_encoding_inited) {
slb_encoding_inited = 1;
patch_slb_encoding(slb_miss_kernel_load_linear,
@@ -279,8 +285,14 @@ void slb_initialize(void)
patch_slb_encoding(slb_compare_rr_to_size,
mmu_slb_size);
- DBG("SLB: linear LLP = %04x\n", linear_llp);
- DBG("SLB: io LLP = %04x\n", io_llp);
+ DBG("SLB: linear LLP = %04lx\n", linear_llp);
+ DBG("SLB: io LLP = %04lx\n", io_llp);
+
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+ patch_slb_encoding(slb_miss_kernel_load_vmemmap,
+ SLB_VSID_KERNEL | vmemmap_llp);
+ DBG("SLB: vmemmap LLP = %04lx\n", vmemmap_llp);
+#endif
}
get_paca()->stab_rr = SLB_NUM_BOLTED;
Index: linux-work/arch/powerpc/mm/slb_low.S
===================================================================
--- linux-work.orig/arch/powerpc/mm/slb_low.S 2008-04-30 15:00:54.000000000 +1000
+++ linux-work/arch/powerpc/mm/slb_low.S 2008-04-30 15:01:00.000000000 +1000
@@ -47,8 +47,7 @@ _GLOBAL(slb_allocate_realmode)
* it to VSID 0, which is reserved as a bad VSID - one which
* will never have any pages in it. */
- /* Check if hitting the linear mapping of the vmalloc/ioremap
- * kernel space
+ /* Check if hitting the linear mapping or some other kernel space
*/
bne cr7,1f
@@ -62,7 +61,18 @@ BEGIN_FTR_SECTION
END_FTR_SECTION_IFCLR(CPU_FTR_1T_SEGMENT)
b slb_finish_load_1T
-1: /* vmalloc/ioremap mapping encoding bits, the "li" instructions below
+1:
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+ /* Check virtual memmap region. To be patches at kernel boot */
+ cmpldi cr0,r9,0xf
+ bne 1f
+_GLOBAL(slb_miss_kernel_load_vmemmap)
+ li r11,0
+ b 6f
+1:
+#endif /* CONFIG_SPARSEMEM_VMEMMAP */
+
+ /* vmalloc/ioremap mapping encoding bits, the "li" instructions below
* will be patched by the kernel at boot
*/
BEGIN_FTR_SECTION
Index: linux-work/include/asm-powerpc/mmu-hash64.h
===================================================================
--- linux-work.orig/include/asm-powerpc/mmu-hash64.h 2008-04-30 15:00:54.000000000 +1000
+++ linux-work/include/asm-powerpc/mmu-hash64.h 2008-04-30 15:01:00.000000000 +1000
@@ -177,6 +177,7 @@ extern struct mmu_psize_def mmu_psize_de
extern int mmu_linear_psize;
extern int mmu_virtual_psize;
extern int mmu_vmalloc_psize;
+extern int mmu_vmemmap_psize;
extern int mmu_io_psize;
extern int mmu_kernel_ssize;
extern int mmu_highuser_ssize;
Index: linux-work/include/asm-powerpc/pgtable-ppc64.h
===================================================================
--- linux-work.orig/include/asm-powerpc/pgtable-ppc64.h 2008-04-30 15:00:54.000000000 +1000
+++ linux-work/include/asm-powerpc/pgtable-ppc64.h 2008-04-30 15:01:00.000000000 +1000
@@ -65,15 +65,15 @@
#define VMALLOC_REGION_ID (REGION_ID(VMALLOC_START))
#define KERNEL_REGION_ID (REGION_ID(PAGE_OFFSET))
+#define VMEMMAP_REGION_ID (0xfUL)
#define USER_REGION_ID (0UL)
/*
- * Defines the address of the vmemap area, in the top 16th of the
- * kernel region.
+ * Defines the address of the vmemap area, in its own region
*/
-#define VMEMMAP_BASE (ASM_CONST(CONFIG_KERNEL_START) + \
- (0xfUL << (REGION_SHIFT - 4)))
-#define vmemmap ((struct page *)VMEMMAP_BASE)
+#define VMEMMAP_BASE (VMEMMAP_REGION_ID << REGION_SHIFT)
+#define vmemmap ((struct page *)VMEMMAP_BASE)
+
/*
* Common bits in a linux-style PTE. These match the bits in the
^ permalink raw reply
* [PATCH] Merge Axon MSI trigger debugging
From: Michael Ellerman @ 2008-04-30 6:31 UTC (permalink / raw)
To: linuxppc-dev
I've forward-ported this patch three times now, so we should just put
it in the tree and save the trouble. It's all inside #ifdef DEBUG so
causes no harm unless it's enabled.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/cell/axon_msi.c | 58 ++++++++++++++++++++++++++++++++
1 files changed, 58 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index c39f5c2..8b055bc 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -14,6 +14,7 @@
#include <linux/pci.h>
#include <linux/msi.h>
#include <linux/of_platform.h>
+#include <linux/debugfs.h>
#include <asm/dcr.h>
#include <asm/machdep.h>
@@ -69,8 +70,19 @@ struct axon_msic {
dma_addr_t fifo_phys;
dcr_host_t dcr_host;
u32 read_offset;
+#ifdef DEBUG
+ u32 __iomem *trigger;
+#endif
};
+#ifdef DEBUG
+void axon_msi_debug_setup(struct device_node *dn, struct axon_msic *msic);
+#else
+static inline void axon_msi_debug_setup(struct device_node *dn,
+ struct axon_msic *msic) { }
+#endif
+
+
static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val)
{
pr_debug("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n);
@@ -381,6 +393,8 @@ static int axon_msi_probe(struct of_device *device,
ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs;
ppc_md.msi_check_device = axon_msi_check_device;
+ axon_msi_debug_setup(dn, msic);
+
printk(KERN_DEBUG "axon_msi: setup MSIC on %s\n", dn->full_name);
return 0;
@@ -418,3 +432,47 @@ static int __init axon_msi_init(void)
return of_register_platform_driver(&axon_msi_driver);
}
subsys_initcall(axon_msi_init);
+
+
+#ifdef DEBUG
+static int msic_set(void *data, u64 val)
+{
+ struct axon_msic *msic = data;
+ out_le32(msic->trigger, val);
+ return 0;
+}
+
+static int msic_get(void *data, u64 *val)
+{
+ *val = 0;
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(fops_msic, msic_get, msic_set, "%llu\n");
+
+void axon_msi_debug_setup(struct device_node *dn, struct axon_msic *msic)
+{
+ char name[8];
+ u64 addr;
+
+ addr = of_translate_address(dn, of_get_property(dn, "reg", NULL));
+ if (addr == OF_BAD_ADDR) {
+ pr_debug("axon_msi: couldn't translate reg property\n");
+ return;
+ }
+
+ msic->trigger = ioremap(addr, 0x4);
+ if (!msic->trigger) {
+ pr_debug("axon_msi: ioremap failed\n");
+ return;
+ }
+
+ snprintf(name, sizeof(name), "msic_%d", of_node_to_nid(dn));
+
+ if (!debugfs_create_file(name, 0600, powerpc_debugfs_root,
+ msic, &fops_msic)) {
+ pr_debug("axon_msi: debugfs_create_file failed!\n");
+ return;
+ }
+}
+#endif /* DEBUG */
--
1.5.5
^ permalink raw reply related
* Re: [PATCH] [POWERPC] convert transfer_to_handler into a macro
From: Benjamin Herrenschmidt @ 2008-04-30 6:32 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <73CD5806-5CE4-40A7-957B-8F164E26FAFB@kernel.crashing.org>
On Tue, 2008-04-29 at 18:52 -0500, Kumar Gala wrote:
> On Apr 29, 2008, at 4:28 PM, Paul Mackerras wrote:
> > Kumar Gala writes:
> >
> >> We need to have unique transfer_to_handler paths for each exception
> >> level
> >> that is supported. We need to use the proper xSRR0/1 depending on
> >> which
> >> exception level the interrupt was from. The macro conversion lets up
> >> templatize this code path.
> >
> > It seems to me that this implies you are assuming that you will never
> > ever get a synchronous normal interrupt such as a TLB miss while you
> > are in a critical or machine check handler.
>
> Grr.. one more thing to fix :)
>
> > Wouldn't it be better and safer to have the exception prolog for
> > critical interrupts save SRR0/1 in the stack frame, and have the
> > prolog for machine checks save SRR0/1 and CSRR0/1 likewise?
>
> If we do this I guess we can use SRR0/1 regardless of which level we
> came from.
Also consider saving/restoring MAS
Ben.
^ permalink raw reply
* [GIT PULL] Please pull spufs master branch
From: Jeremy Kerr @ 2008-04-30 6:44 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, cbe-oss-dev
Hi Paul,
Please do a:
git-pull git://git.kernel.org/pub/scm/linux/kernel/git/jk/spufs.git
For some updates for 2.6.26. This includes some sputrace updates and a
new switch_log for spufs contexts.
Cheers,
Jeremy
--- 6 commits:
[POWERPC] spufs: add context switch notification log
Christoph Hellwig <hch@lst.de>
arch/powerpc/platforms/cell/spufs/context.c | 1
arch/powerpc/platforms/cell/spufs/file.c | 166 ++++++++++
arch/powerpc/platforms/cell/spufs/run.c | 2
arch/powerpc/platforms/cell/spufs/sched.c | 2
arch/powerpc/platforms/cell/spufs/spufs.h | 29 +
5 files changed, 200 insertions(+)
[POWERPC] spufs: add sputrace marker parameter names
Julio M. Merino Vidal <jmerino@ac.upc.edu>
arch/powerpc/platforms/cell/spufs/spufs.h | 4 -
arch/powerpc/platforms/cell/spufs/sputrace.c | 36 +++++-----
2 files changed, 20 insertions(+), 20 deletions(-)
[POWERPC] spufs: add marker for destroy_spu_context
Julio M. Merino Vidal <jmerino@ac.upc.edu>
arch/powerpc/platforms/cell/spufs/context.c | 1 +
1 file changed, 1 insertion(+)
[POWERPC] spufs: fix marker name for find_victim
Julio M. Merino Vidal <jmerino@ac.upc.edu>
arch/powerpc/platforms/cell/spufs/sched.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
[POWERPC] spufs: trace spu_acquire_saved events
Julio M. Merino Vidal <jmerino@ac.upc.edu>
arch/powerpc/platforms/cell/spufs/context.c | 2 ++
1 file changed, 2 insertions(+)
[POWERPC] spufs: add .gitignore for spu_save_dump.h & spu_restore_dump.h
Kumar Gala <galak@kernel.crashing.org>
arch/powerpc/platforms/cell/spufs/.gitignore | 0
arch/powerpc/platforms/cell/spufs/.gitignore | 2 ++
2 files changed, 2 insertions(+)
^ permalink raw reply
* Re: [PATCH] [POWERPC] mpc5200: Allow for fixed speed MII configurations
From: Joakim Tjernlund @ 2008-04-30 7:36 UTC (permalink / raw)
To: Grant Likely; +Cc: netdev, linuxppc-dev, paulus, domen.puncer
In-Reply-To: <20080429230620.11248.25729.stgit@trillian.secretlab.ca>
On Tue, 2008-04-29 at 17:06 -0600, Grant Likely wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> Various improvements for configuring the MPC5200 MII link from the
> device tree:
> * Look for 'current-speed' property for fixed speed MII links
Not that I have looked, but why can't you use the fixed-link property?
Jocke
^ permalink raw reply
* [RFC] [PATCH 1/5] [POWERPC] dma: implement new dma_*map*_attrs() interfaces
From: markn @ 2008-04-30 7:46 UTC (permalink / raw)
To: olof; +Cc: Mark Nelson, linuxppc-dev
In-Reply-To: <20080430074621.104662132@au1.ibm.com>
Update powerpc to use the new dma_*map*_attrs() interfaces. In doing so
update struct dma_mapping_ops to accept a struct dma_attrs and propagate
these changes through to all users of the code (generic IOMMU and the
64bit DMA code, and the iseries and ps3 platform code).
The old dma_*map_*() interfaces are reimplemented as calls to the
corresponding new interfaces.
Signed-off-by: Mark Nelson <markn@au1.ibm.com>
---
arch/powerpc/Kconfig | 1
arch/powerpc/kernel/dma_64.c | 34 ++++++---
arch/powerpc/kernel/ibmebus.c | 12 ++-
arch/powerpc/kernel/iommu.c | 11 +--
arch/powerpc/platforms/iseries/iommu.c | 4 -
arch/powerpc/platforms/ps3/system-bus.c | 17 ++--
include/asm-powerpc/dma-mapping.h | 116 +++++++++++++++++++++++---------
include/asm-powerpc/iommu.h | 12 ++-
8 files changed, 144 insertions(+), 63 deletions(-)
Index: upstream/arch/powerpc/Kconfig
===================================================================
--- upstream.orig/arch/powerpc/Kconfig
+++ upstream/arch/powerpc/Kconfig
@@ -110,6 +110,7 @@ config PPC
select HAVE_KPROBES
select HAVE_KRETPROBES
select HAVE_LMB
+ select HAVE_DMA_ATTRS
config EARLY_PRINTK
bool
Index: upstream/arch/powerpc/kernel/dma_64.c
===================================================================
--- upstream.orig/arch/powerpc/kernel/dma_64.c
+++ upstream/arch/powerpc/kernel/dma_64.c
@@ -50,32 +50,38 @@ static void dma_iommu_free_coherent(stru
*/
static dma_addr_t dma_iommu_map_single(struct device *dev, void *vaddr,
size_t size,
- enum dma_data_direction direction)
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
return iommu_map_single(dev, dev->archdata.dma_data, vaddr, size,
- device_to_mask(dev), direction);
+ device_to_mask(dev), direction, attrs);
}
static void dma_iommu_unmap_single(struct device *dev, dma_addr_t dma_handle,
size_t size,
- enum dma_data_direction direction)
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
- iommu_unmap_single(dev->archdata.dma_data, dma_handle, size, direction);
+ iommu_unmap_single(dev->archdata.dma_data, dma_handle, size, direction,
+ attrs);
}
static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist,
- int nelems, enum dma_data_direction direction)
+ int nelems, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
return iommu_map_sg(dev, dev->archdata.dma_data, sglist, nelems,
- device_to_mask(dev), direction);
+ device_to_mask(dev), direction, attrs);
}
static void dma_iommu_unmap_sg(struct device *dev, struct scatterlist *sglist,
- int nelems, enum dma_data_direction direction)
+ int nelems, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
- iommu_unmap_sg(dev->archdata.dma_data, sglist, nelems, direction);
+ iommu_unmap_sg(dev->archdata.dma_data, sglist, nelems, direction,
+ attrs);
}
/* We support DMA to/from any memory page via the iommu */
@@ -148,19 +154,22 @@ static void dma_direct_free_coherent(str
static dma_addr_t dma_direct_map_single(struct device *dev, void *ptr,
size_t size,
- enum dma_data_direction direction)
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
return virt_to_abs(ptr) + get_dma_direct_offset(dev);
}
static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr,
size_t size,
- enum dma_data_direction direction)
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
}
static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
- int nents, enum dma_data_direction direction)
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
struct scatterlist *sg;
int i;
@@ -174,7 +183,8 @@ static int dma_direct_map_sg(struct devi
}
static void dma_direct_unmap_sg(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction direction)
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
}
Index: upstream/arch/powerpc/kernel/ibmebus.c
===================================================================
--- upstream.orig/arch/powerpc/kernel/ibmebus.c
+++ upstream/arch/powerpc/kernel/ibmebus.c
@@ -82,7 +82,8 @@ static void ibmebus_free_coherent(struct
static dma_addr_t ibmebus_map_single(struct device *dev,
void *ptr,
size_t size,
- enum dma_data_direction direction)
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
return (dma_addr_t)(ptr);
}
@@ -90,14 +91,16 @@ static dma_addr_t ibmebus_map_single(str
static void ibmebus_unmap_single(struct device *dev,
dma_addr_t dma_addr,
size_t size,
- enum dma_data_direction direction)
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
return;
}
static int ibmebus_map_sg(struct device *dev,
struct scatterlist *sgl,
- int nents, enum dma_data_direction direction)
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
struct scatterlist *sg;
int i;
@@ -112,7 +115,8 @@ static int ibmebus_map_sg(struct device
static void ibmebus_unmap_sg(struct device *dev,
struct scatterlist *sg,
- int nents, enum dma_data_direction direction)
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
return;
}
Index: upstream/arch/powerpc/kernel/iommu.c
===================================================================
--- upstream.orig/arch/powerpc/kernel/iommu.c
+++ upstream/arch/powerpc/kernel/iommu.c
@@ -269,7 +269,8 @@ static void iommu_free(struct iommu_tabl
int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
struct scatterlist *sglist, int nelems,
- unsigned long mask, enum dma_data_direction direction)
+ unsigned long mask, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
dma_addr_t dma_next = 0, dma_addr;
unsigned long flags;
@@ -411,7 +412,8 @@ int iommu_map_sg(struct device *dev, str
void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
- int nelems, enum dma_data_direction direction)
+ int nelems, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
struct scatterlist *sg;
unsigned long flags;
@@ -553,7 +555,7 @@ void iommu_free_table(struct iommu_table
*/
dma_addr_t iommu_map_single(struct device *dev, struct iommu_table *tbl,
void *vaddr, size_t size, unsigned long mask,
- enum dma_data_direction direction)
+ enum dma_data_direction direction, struct dma_attrs *attrs)
{
dma_addr_t dma_handle = DMA_ERROR_CODE;
unsigned long uaddr;
@@ -586,7 +588,8 @@ dma_addr_t iommu_map_single(struct devic
}
void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction direction)
+ size_t size, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
unsigned int npages;
Index: upstream/arch/powerpc/platforms/iseries/iommu.c
===================================================================
--- upstream.orig/arch/powerpc/platforms/iseries/iommu.c
+++ upstream/arch/powerpc/platforms/iseries/iommu.c
@@ -214,13 +214,13 @@ dma_addr_t iseries_hv_map(void *vaddr, s
enum dma_data_direction direction)
{
return iommu_map_single(NULL, &vio_iommu_table, vaddr, size,
- DMA_32BIT_MASK, direction);
+ DMA_32BIT_MASK, direction, NULL);
}
void iseries_hv_unmap(dma_addr_t dma_handle, size_t size,
enum dma_data_direction direction)
{
- iommu_unmap_single(&vio_iommu_table, dma_handle, size, direction);
+ iommu_unmap_single(&vio_iommu_table, dma_handle, size, direction, NULL);
}
void __init iommu_vio_init(void)
Index: upstream/arch/powerpc/platforms/ps3/system-bus.c
===================================================================
--- upstream.orig/arch/powerpc/platforms/ps3/system-bus.c
+++ upstream/arch/powerpc/platforms/ps3/system-bus.c
@@ -550,7 +550,7 @@ static void ps3_free_coherent(struct dev
*/
static dma_addr_t ps3_sb_map_single(struct device *_dev, void *ptr, size_t size,
- enum dma_data_direction direction)
+ enum dma_data_direction direction, struct dma_attrs *attrs)
{
struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
int result;
@@ -570,7 +570,8 @@ static dma_addr_t ps3_sb_map_single(stru
static dma_addr_t ps3_ioc0_map_single(struct device *_dev, void *ptr,
size_t size,
- enum dma_data_direction direction)
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
int result;
@@ -603,7 +604,7 @@ static dma_addr_t ps3_ioc0_map_single(st
}
static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr,
- size_t size, enum dma_data_direction direction)
+ size_t size, enum dma_data_direction direction, struct dma_attrs *attrs)
{
struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
int result;
@@ -617,7 +618,7 @@ static void ps3_unmap_single(struct devi
}
static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl,
- int nents, enum dma_data_direction direction)
+ int nents, enum dma_data_direction direction, struct dma_attrs *attrs)
{
#if defined(CONFIG_PS3_DYNAMIC_DMA)
BUG_ON("do");
@@ -646,14 +647,15 @@ static int ps3_sb_map_sg(struct device *
static int ps3_ioc0_map_sg(struct device *_dev, struct scatterlist *sg,
int nents,
- enum dma_data_direction direction)
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
BUG();
return 0;
}
static void ps3_sb_unmap_sg(struct device *_dev, struct scatterlist *sg,
- int nents, enum dma_data_direction direction)
+ int nents, enum dma_data_direction direction, struct dma_attrs *attrs)
{
#if defined(CONFIG_PS3_DYNAMIC_DMA)
BUG_ON("do");
@@ -661,7 +663,8 @@ static void ps3_sb_unmap_sg(struct devic
}
static void ps3_ioc0_unmap_sg(struct device *_dev, struct scatterlist *sg,
- int nents, enum dma_data_direction direction)
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
BUG();
}
Index: upstream/include/asm-powerpc/dma-mapping.h
===================================================================
--- upstream.orig/include/asm-powerpc/dma-mapping.h
+++ upstream/include/asm-powerpc/dma-mapping.h
@@ -13,6 +13,7 @@
/* need struct page definitions */
#include <linux/mm.h>
#include <linux/scatterlist.h>
+#include <linux/dma-attrs.h>
#include <asm/io.h>
#define DMA_ERROR_CODE (~(dma_addr_t)0x0)
@@ -53,13 +54,17 @@ struct dma_mapping_ops {
void (*free_coherent)(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
dma_addr_t (*map_single)(struct device *dev, void *ptr,
- size_t size, enum dma_data_direction direction);
+ size_t size, enum dma_data_direction direction,
+ struct dma_attrs *attrs);
void (*unmap_single)(struct device *dev, dma_addr_t dma_addr,
- size_t size, enum dma_data_direction direction);
+ size_t size, enum dma_data_direction direction,
+ struct dma_attrs *attrs);
int (*map_sg)(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction direction);
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs);
void (*unmap_sg)(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction direction);
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs);
int (*dma_supported)(struct device *dev, u64 mask);
int (*set_dma_mask)(struct device *dev, u64 dma_mask);
};
@@ -109,6 +114,77 @@ static inline int dma_set_mask(struct de
return 0;
}
+static inline dma_addr_t dma_map_single_attrs(struct device *dev,
+ void *cpu_addr,
+ size_t size,
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+ BUG_ON(!dma_ops);
+ return dma_ops->map_single(dev, cpu_addr, size, direction, attrs);
+}
+
+static inline void dma_unmap_single_attrs(struct device *dev,
+ dma_addr_t dma_addr,
+ size_t size,
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+ BUG_ON(!dma_ops);
+ dma_ops->unmap_single(dev, dma_addr, size, direction, attrs);
+}
+
+static inline dma_addr_t dma_map_page_attrs(struct device *dev,
+ struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+ BUG_ON(!dma_ops);
+ return dma_ops->map_single(dev, page_address(page) + offset, size,
+ direction, attrs);
+}
+
+static inline void dma_unmap_page_attrs(struct device *dev,
+ dma_addr_t dma_address,
+ size_t size,
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+ BUG_ON(!dma_ops);
+ dma_ops->unmap_single(dev, dma_address, size, direction, attrs);
+}
+
+static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+ BUG_ON(!dma_ops);
+ return dma_ops->map_sg(dev, sg, nents, direction, attrs);
+}
+
+static inline void dma_unmap_sg_attrs(struct device *dev,
+ struct scatterlist *sg,
+ int nhwentries,
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+ BUG_ON(!dma_ops);
+ dma_ops->unmap_sg(dev, sg, nhwentries, direction, attrs);
+}
+
static inline void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag)
{
@@ -131,63 +207,43 @@ static inline dma_addr_t dma_map_single(
size_t size,
enum dma_data_direction direction)
{
- struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
- BUG_ON(!dma_ops);
- return dma_ops->map_single(dev, cpu_addr, size, direction);
+ return dma_map_single_attrs(dev, cpu_addr, size, direction, NULL);
}
static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
size_t size,
enum dma_data_direction direction)
{
- struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
- BUG_ON(!dma_ops);
- dma_ops->unmap_single(dev, dma_addr, size, direction);
+ dma_unmap_single_attrs(dev, dma_addr, size, direction, NULL);
}
static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size,
enum dma_data_direction direction)
{
- struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
- BUG_ON(!dma_ops);
- return dma_ops->map_single(dev, page_address(page) + offset, size,
- direction);
+ return dma_map_page_attrs(dev, page, offset, size, direction, NULL);
}
static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
size_t size,
enum dma_data_direction direction)
{
- struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
- BUG_ON(!dma_ops);
- dma_ops->unmap_single(dev, dma_address, size, direction);
+ dma_unmap_page_attrs(dev, dma_address, size, direction, NULL);
}
static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
int nents, enum dma_data_direction direction)
{
- struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
- BUG_ON(!dma_ops);
- return dma_ops->map_sg(dev, sg, nents, direction);
+ return dma_map_sg_attrs(dev, sg, nents, direction, NULL);
}
static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
int nhwentries,
enum dma_data_direction direction)
{
- struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
- BUG_ON(!dma_ops);
- dma_ops->unmap_sg(dev, sg, nhwentries, direction);
+ dma_unmap_sg_attrs(dev, sg, nhwentries, direction, NULL);
}
-
/*
* Available generic sets of operations
*/
Index: upstream/include/asm-powerpc/iommu.h
===================================================================
--- upstream.orig/include/asm-powerpc/iommu.h
+++ upstream/include/asm-powerpc/iommu.h
@@ -81,9 +81,11 @@ extern struct iommu_table *iommu_init_ta
extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
struct scatterlist *sglist, int nelems,
- unsigned long mask, enum dma_data_direction direction);
+ unsigned long mask, enum dma_data_direction direction,
+ struct dma_attrs *attrs);
extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
- int nelems, enum dma_data_direction direction);
+ int nelems, enum dma_data_direction direction,
+ struct dma_attrs *attrs);
extern void *iommu_alloc_coherent(struct device *dev, struct iommu_table *tbl,
size_t size, dma_addr_t *dma_handle,
@@ -92,9 +94,11 @@ extern void iommu_free_coherent(struct i
void *vaddr, dma_addr_t dma_handle);
extern dma_addr_t iommu_map_single(struct device *dev, struct iommu_table *tbl,
void *vaddr, size_t size, unsigned long mask,
- enum dma_data_direction direction);
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs);
extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction direction);
+ size_t size, enum dma_data_direction direction,
+ struct dma_attrs *attrs);
extern void iommu_init_early_pSeries(void);
extern void iommu_init_early_iSeries(void);
--
^ permalink raw reply
* [RFC] [PATCH 2/5] [POWERPC] dma: use the struct dma_attrs in iommu code
From: markn @ 2008-04-30 7:46 UTC (permalink / raw)
To: olof; +Cc: Mark Nelson, linuxppc-dev
In-Reply-To: <20080430074621.104662132@au1.ibm.com>
Update iommu_alloc() to take the struct dma_attrs and pass them on to
tce_build(). This change propagates down to the tce_build functions of
all the platforms.
Signed-off-by: Mark Nelson <markn@au1.ibm.com>
---
arch/powerpc/kernel/iommu.c | 13 ++++++++-----
arch/powerpc/platforms/cell/iommu.c | 5 +++--
arch/powerpc/platforms/iseries/iommu.c | 3 ++-
arch/powerpc/platforms/pasemi/iommu.c | 3 ++-
arch/powerpc/platforms/pseries/iommu.c | 13 ++++++++-----
arch/powerpc/sysdev/dart_iommu.c | 3 ++-
include/asm-powerpc/machdep.h | 3 ++-
7 files changed, 27 insertions(+), 16 deletions(-)
Index: upstream/arch/powerpc/kernel/iommu.c
===================================================================
--- upstream.orig/arch/powerpc/kernel/iommu.c
+++ upstream/arch/powerpc/kernel/iommu.c
@@ -186,7 +186,8 @@ static unsigned long iommu_range_alloc(s
static dma_addr_t iommu_alloc(struct device *dev, struct iommu_table *tbl,
void *page, unsigned int npages,
enum dma_data_direction direction,
- unsigned long mask, unsigned int align_order)
+ unsigned long mask, unsigned int align_order,
+ struct dma_attrs *attrs)
{
unsigned long entry, flags;
dma_addr_t ret = DMA_ERROR_CODE;
@@ -205,7 +206,7 @@ static dma_addr_t iommu_alloc(struct dev
/* Put the TCEs in the HW table */
ppc_md.tce_build(tbl, entry, npages, (unsigned long)page & IOMMU_PAGE_MASK,
- direction);
+ direction, attrs);
/* Flush/invalidate TLB caches if necessary */
@@ -336,7 +337,8 @@ int iommu_map_sg(struct device *dev, str
npages, entry, dma_addr);
/* Insert into HW table */
- ppc_md.tce_build(tbl, entry, npages, vaddr & IOMMU_PAGE_MASK, direction);
+ ppc_md.tce_build(tbl, entry, npages, vaddr & IOMMU_PAGE_MASK,
+ direction, attrs);
/* If we are in an open segment, try merging */
if (segstart != s) {
@@ -573,7 +575,8 @@ dma_addr_t iommu_map_single(struct devic
align = PAGE_SHIFT - IOMMU_PAGE_SHIFT;
dma_handle = iommu_alloc(dev, tbl, vaddr, npages, direction,
- mask >> IOMMU_PAGE_SHIFT, align);
+ mask >> IOMMU_PAGE_SHIFT, align,
+ attrs);
if (dma_handle == DMA_ERROR_CODE) {
if (printk_ratelimit()) {
printk(KERN_INFO "iommu_alloc failed, "
@@ -642,7 +645,7 @@ void *iommu_alloc_coherent(struct device
nio_pages = size >> IOMMU_PAGE_SHIFT;
io_order = get_iommu_order(size);
mapping = iommu_alloc(dev, tbl, ret, nio_pages, DMA_BIDIRECTIONAL,
- mask >> IOMMU_PAGE_SHIFT, io_order);
+ mask >> IOMMU_PAGE_SHIFT, io_order, NULL);
if (mapping == DMA_ERROR_CODE) {
free_pages((unsigned long)ret, order);
return NULL;
Index: upstream/arch/powerpc/platforms/cell/iommu.c
===================================================================
--- upstream.orig/arch/powerpc/platforms/cell/iommu.c
+++ upstream/arch/powerpc/platforms/cell/iommu.c
@@ -173,7 +173,8 @@ static void invalidate_tce_cache(struct
}
static void tce_build_cell(struct iommu_table *tbl, long index, long npages,
- unsigned long uaddr, enum dma_data_direction direction)
+ unsigned long uaddr, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
int i;
unsigned long *io_pte, base_pte;
@@ -519,7 +520,7 @@ cell_iommu_setup_window(struct cbe_iommu
__set_bit(0, window->table.it_map);
tce_build_cell(&window->table, window->table.it_offset, 1,
- (unsigned long)iommu->pad_page, DMA_TO_DEVICE);
+ (unsigned long)iommu->pad_page, DMA_TO_DEVICE, NULL);
window->table.it_hint = window->table.it_blocksize;
return window;
Index: upstream/arch/powerpc/platforms/iseries/iommu.c
===================================================================
--- upstream.orig/arch/powerpc/platforms/iseries/iommu.c
+++ upstream/arch/powerpc/platforms/iseries/iommu.c
@@ -42,7 +42,8 @@
#include <asm/iseries/iommu.h>
static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages,
- unsigned long uaddr, enum dma_data_direction direction)
+ unsigned long uaddr, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
u64 rc;
u64 tce, rpn;
Index: upstream/arch/powerpc/platforms/pasemi/iommu.c
===================================================================
--- upstream.orig/arch/powerpc/platforms/pasemi/iommu.c
+++ upstream/arch/powerpc/platforms/pasemi/iommu.c
@@ -85,7 +85,8 @@ static int iommu_table_iobmap_inited;
static void iobmap_build(struct iommu_table *tbl, long index,
long npages, unsigned long uaddr,
- enum dma_data_direction direction)
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
u32 *ip;
u32 rpn;
Index: upstream/arch/powerpc/platforms/pseries/iommu.c
===================================================================
--- upstream.orig/arch/powerpc/platforms/pseries/iommu.c
+++ upstream/arch/powerpc/platforms/pseries/iommu.c
@@ -50,7 +50,8 @@
static void tce_build_pSeries(struct iommu_table *tbl, long index,
long npages, unsigned long uaddr,
- enum dma_data_direction direction)
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
u64 proto_tce;
u64 *tcep;
@@ -95,7 +96,8 @@ static unsigned long tce_get_pseries(str
static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
long npages, unsigned long uaddr,
- enum dma_data_direction direction)
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
u64 rc;
u64 proto_tce, tce;
@@ -127,7 +129,8 @@ static DEFINE_PER_CPU(u64 *, tce_page) =
static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
long npages, unsigned long uaddr,
- enum dma_data_direction direction)
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
u64 rc;
u64 proto_tce;
@@ -137,7 +140,7 @@ static void tce_buildmulti_pSeriesLP(str
if (npages == 1)
return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
- direction);
+ direction, attrs);
tcep = __get_cpu_var(tce_page);
@@ -149,7 +152,7 @@ static void tce_buildmulti_pSeriesLP(str
/* If allocation fails, fall back to the loop implementation */
if (!tcep)
return tce_build_pSeriesLP(tbl, tcenum, npages,
- uaddr, direction);
+ uaddr, direction, attrs);
__get_cpu_var(tce_page) = tcep;
}
Index: upstream/arch/powerpc/sysdev/dart_iommu.c
===================================================================
--- upstream.orig/arch/powerpc/sysdev/dart_iommu.c
+++ upstream/arch/powerpc/sysdev/dart_iommu.c
@@ -149,7 +149,8 @@ static void dart_flush(struct iommu_tabl
static void dart_build(struct iommu_table *tbl, long index,
long npages, unsigned long uaddr,
- enum dma_data_direction direction)
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
unsigned int *dp;
unsigned int rpn;
Index: upstream/include/asm-powerpc/machdep.h
===================================================================
--- upstream.orig/include/asm-powerpc/machdep.h
+++ upstream/include/asm-powerpc/machdep.h
@@ -80,7 +80,8 @@ struct machdep_calls {
long index,
long npages,
unsigned long uaddr,
- enum dma_data_direction direction);
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs);
void (*tce_free)(struct iommu_table *tbl,
long index,
long npages);
--
^ permalink raw reply
* [RFC] [PATCH 4/5] [POWERPC] Move device_to_mask() to dma-mapping.h
From: markn @ 2008-04-30 7:46 UTC (permalink / raw)
To: olof; +Cc: Mark Nelson, linuxppc-dev
In-Reply-To: <20080430074621.104662132@au1.ibm.com>
Move device_to_mask() to dma-mapping.h because we need to use it from
outside dma_64.c in a later patch.
Signed-off-by: Mark Nelson <markn@au1.ibm.com>
---
arch/powerpc/kernel/dma_64.c | 9 ---------
include/asm-powerpc/dma-mapping.h | 9 +++++++++
2 files changed, 9 insertions(+), 9 deletions(-)
Index: upstream/arch/powerpc/kernel/dma_64.c
===================================================================
--- upstream.orig/arch/powerpc/kernel/dma_64.c
+++ upstream/arch/powerpc/kernel/dma_64.c
@@ -15,15 +15,6 @@
* Generic iommu implementation
*/
-static inline unsigned long device_to_mask(struct device *dev)
-{
- if (dev->dma_mask && *dev->dma_mask)
- return *dev->dma_mask;
- /* Assume devices without mask can take 32 bit addresses */
- return 0xfffffffful;
-}
-
-
/* Allocates a contiguous real buffer and creates mappings over it.
* Returns the virtual address of the buffer and sets dma_handle
* to the dma address (mapping) of the first page.
Index: upstream/include/asm-powerpc/dma-mapping.h
===================================================================
--- upstream.orig/include/asm-powerpc/dma-mapping.h
+++ upstream/include/asm-powerpc/dma-mapping.h
@@ -45,6 +45,15 @@ extern void __dma_sync_page(struct page
#endif /* ! CONFIG_NOT_COHERENT_CACHE */
#ifdef CONFIG_PPC64
+
+static inline unsigned long device_to_mask(struct device *dev)
+{
+ if (dev->dma_mask && *dev->dma_mask)
+ return *dev->dma_mask;
+ /* Assume devices without mask can take 32 bit addresses */
+ return 0xfffffffful;
+}
+
/*
* DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO
*/
--
^ permalink raw reply
* [RFC] [PATCH 0/5] [POWERPC] Implement dma_*map*_attrs() and DMA_ATTR_WEAK_ORDERING and use on Cell
From: markn @ 2008-04-30 7:46 UTC (permalink / raw)
To: olof; +Cc: linuxppc-dev
--
Was Re: [PATCH] [POWERPC] Add struct iommu_table argument to iommu_map_sg()
Here's the patch series that follows on from the patch:
Add struct iommu_table argument to iommu_map_sg()
Thanks!
Mark.
^ permalink raw reply
* [RFC] [PATCH 5/5] [POWERPC] Add DMA_ATTR_WEAK_ORDERING dma attribute and use in Cell IOMMU code
From: markn @ 2008-04-30 7:46 UTC (permalink / raw)
To: olof; +Cc: Mark Nelson, linuxppc-dev
In-Reply-To: <20080430074621.104662132@au1.ibm.com>
Introduce a new dma attriblue DMA_ATTR_WEAK_ORDERING to use weak ordering
on DMA mappings in the Cell processor. Add the code to the Cell's IOMMU
implementation to use this code.
Dynamic mappings can be weakly or strongly ordered on an individual basis
but the fixed mapping has to be either completely strong or completely weak.
This is currently decided by a kernel boot option (pass iommu_fixed=weak
for a weakly ordered fixed linear mapping, strongly ordered is the default).
Signed-off-by: Mark Nelson <markn@au1.ibm.com>
---
Documentation/DMA-attributes.txt | 9 ++
arch/powerpc/platforms/cell/iommu.c | 113 ++++++++++++++++++++++++++++++++++--
include/linux/dma-attrs.h | 1
3 files changed, 118 insertions(+), 5 deletions(-)
Index: upstream/arch/powerpc/platforms/cell/iommu.c
===================================================================
--- upstream.orig/arch/powerpc/platforms/cell/iommu.c
+++ upstream/arch/powerpc/platforms/cell/iommu.c
@@ -199,6 +199,8 @@ static void tce_build_cell(struct iommu_
base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW |
(window->ioid & IOPTE_IOID_Mask);
#endif
+ if (unlikely(dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs)))
+ base_pte &= ~IOPTE_SO_RW;
io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset);
@@ -539,7 +541,9 @@ static struct cbe_iommu *cell_iommu_for_
static unsigned long cell_dma_direct_offset;
static unsigned long dma_iommu_fixed_base;
-struct dma_mapping_ops dma_iommu_fixed_ops;
+
+/* iommu_fixed_is_weak is set if booted with iommu_fixed=weak */
+static int iommu_fixed_is_weak;
static struct iommu_table *cell_get_iommu_table(struct device *dev)
{
@@ -563,6 +567,98 @@ static struct iommu_table *cell_get_iomm
return &window->table;
}
+/* A coherent allocation implies strong ordering */
+
+static void *dma_fixed_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag)
+{
+ if (iommu_fixed_is_weak)
+ return iommu_alloc_coherent(dev, cell_get_iommu_table(dev),
+ size, dma_handle,
+ device_to_mask(dev), flag,
+ dev->archdata.numa_node);
+ else
+ return dma_direct_ops.alloc_coherent(dev, size, dma_handle,
+ flag);
+}
+
+static void dma_fixed_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+ if (iommu_fixed_is_weak)
+ iommu_free_coherent(cell_get_iommu_table(dev), size, vaddr,
+ dma_handle);
+ else
+ dma_direct_ops.free_coherent(dev, size, vaddr, dma_handle);
+}
+
+static dma_addr_t dma_fixed_map_single(struct device *dev, void *ptr,
+ size_t size,
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ if (iommu_fixed_is_weak == dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs))
+ return dma_direct_ops.map_single(dev, ptr, size, direction,
+ attrs);
+ else
+ return iommu_map_single(dev, cell_get_iommu_table(dev), ptr,
+ size, device_to_mask(dev), direction,
+ attrs);
+}
+
+static void dma_fixed_unmap_single(struct device *dev, dma_addr_t dma_addr,
+ size_t size,
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ if (iommu_fixed_is_weak == dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs))
+ dma_direct_ops.unmap_single(dev, dma_addr, size, direction,
+ attrs);
+ else
+ iommu_unmap_single(cell_get_iommu_table(dev), dma_addr, size,
+ direction, attrs);
+}
+
+static int dma_fixed_map_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ if (iommu_fixed_is_weak == dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs))
+ return dma_direct_ops.map_sg(dev, sg, nents, direction, attrs);
+ else
+ return iommu_map_sg(dev, cell_get_iommu_table(dev), sg, nents,
+ device_to_mask(dev), direction, attrs);
+}
+
+static void dma_fixed_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ if (iommu_fixed_is_weak == dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs))
+ dma_direct_ops.unmap_sg(dev, sg, nents, direction, attrs);
+ else
+ iommu_unmap_sg(cell_get_iommu_table(dev), sg, nents, direction,
+ attrs);
+}
+
+static int dma_fixed_dma_supported(struct device *dev, u64 mask)
+{
+ return mask == DMA_64BIT_MASK;
+}
+
+static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask);
+
+struct dma_mapping_ops dma_iommu_fixed_ops = {
+ .alloc_coherent = dma_fixed_alloc_coherent,
+ .free_coherent = dma_fixed_free_coherent,
+ .map_single = dma_fixed_map_single,
+ .unmap_single = dma_fixed_unmap_single,
+ .map_sg = dma_fixed_map_sg,
+ .unmap_sg = dma_fixed_unmap_sg,
+ .dma_supported = dma_fixed_dma_supported,
+ .set_dma_mask = dma_set_mask_and_switch,
+};
+
static void cell_dma_dev_setup_fixed(struct device *dev);
static void cell_dma_dev_setup(struct device *dev)
@@ -919,9 +1015,16 @@ static void cell_iommu_setup_fixed_ptab(
pr_debug("iommu: mapping 0x%lx pages from 0x%lx\n", fsize, fbase);
- base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW
+ base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M
| (cell_iommu_get_ioid(np) & IOPTE_IOID_Mask);
+ if (iommu_fixed_is_weak)
+ pr_info("IOMMU: Using weak ordering for fixed mapping\n");
+ else {
+ pr_info("IOMMU: Using strong ordering for fixed mapping\n");
+ base_pte |= IOPTE_SO_RW;
+ }
+
for (uaddr = 0; uaddr < fsize; uaddr += (1 << 24)) {
/* Don't touch the dynamic region */
ioaddr = uaddr + fbase;
@@ -1037,9 +1140,6 @@ static int __init cell_iommu_fixed_mappi
cell_iommu_setup_window(iommu, np, dbase, dsize, 0);
}
- dma_iommu_fixed_ops = dma_direct_ops;
- dma_iommu_fixed_ops.set_dma_mask = dma_set_mask_and_switch;
-
dma_iommu_ops.set_dma_mask = dma_set_mask_and_switch;
set_pci_dma_ops(&dma_iommu_ops);
@@ -1053,6 +1153,9 @@ static int __init setup_iommu_fixed(char
if (strcmp(str, "off") == 0)
iommu_fixed_disabled = 1;
+ else if (strcmp(str, "weak") == 0)
+ iommu_fixed_is_weak = 1;
+
return 1;
}
__setup("iommu_fixed=", setup_iommu_fixed);
Index: upstream/Documentation/DMA-attributes.txt
===================================================================
--- upstream.orig/Documentation/DMA-attributes.txt
+++ upstream/Documentation/DMA-attributes.txt
@@ -22,3 +22,12 @@ ready and available in memory. The DMA
could race with data DMA. Mapping the memory used for completion
indications with DMA_ATTR_WRITE_BARRIER would prevent the race.
+DMA_ATTR_WEAK_ORDERING
+----------------------
+
+DMA_ATTR_WEAK_ORDERING specifies that reads and writes to the mapping
+may be weakly ordered, that is that reads and writes may pass each other.
+
+Since it is optional for platforms to implement DMA_ATTR_WEAK_ORDERING,
+those that do not will simply ignore the attribute and exhibit default
+behavior.
Index: upstream/include/linux/dma-attrs.h
===================================================================
--- upstream.orig/include/linux/dma-attrs.h
+++ upstream/include/linux/dma-attrs.h
@@ -12,6 +12,7 @@
*/
enum dma_attr {
DMA_ATTR_WRITE_BARRIER,
+ DMA_ATTR_WEAK_ORDERING,
DMA_ATTR_MAX,
};
--
^ permalink raw reply
* [RFC] [PATCH 3/5] [POWERPC] Make cell_dma_dev_setup_iommu() return the iommu table
From: markn @ 2008-04-30 7:46 UTC (permalink / raw)
To: olof; +Cc: Mark Nelson, linuxppc-dev
In-Reply-To: <20080430074621.104662132@au1.ibm.com>
Make cell_dma_dev_setup_iommu() return a pointer to the struct iommu_table
(or NULL if no table can be found) rather than putting this pointer into
dev->archdata.dma_data (let the caller do that), and rename this function
to cell_get_iommu_table() to reflect this change.
This will allow us to get the iommu table for a device that doesn't have
the table in the archdata.
Signed-off-by: Mark Nelson <markn@au1.ibm.com>
---
arch/powerpc/platforms/cell/iommu.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
Index: upstream/arch/powerpc/platforms/cell/iommu.c
===================================================================
--- upstream.orig/arch/powerpc/platforms/cell/iommu.c
+++ upstream/arch/powerpc/platforms/cell/iommu.c
@@ -541,7 +541,7 @@ static unsigned long cell_dma_direct_off
static unsigned long dma_iommu_fixed_base;
struct dma_mapping_ops dma_iommu_fixed_ops;
-static void cell_dma_dev_setup_iommu(struct device *dev)
+static struct iommu_table *cell_get_iommu_table(struct device *dev)
{
struct iommu_window *window;
struct cbe_iommu *iommu;
@@ -556,11 +556,11 @@ static void cell_dma_dev_setup_iommu(str
printk(KERN_ERR "iommu: missing iommu for %s (node %d)\n",
archdata->of_node ? archdata->of_node->full_name : "?",
archdata->numa_node);
- return;
+ return NULL;
}
window = list_entry(iommu->windows.next, struct iommu_window, list);
- archdata->dma_data = &window->table;
+ return &window->table;
}
static void cell_dma_dev_setup_fixed(struct device *dev);
@@ -573,7 +573,7 @@ static void cell_dma_dev_setup(struct de
if (get_dma_ops(dev) == &dma_iommu_fixed_ops)
cell_dma_dev_setup_fixed(dev);
else if (get_pci_dma_ops() == &dma_iommu_ops)
- cell_dma_dev_setup_iommu(dev);
+ archdata->dma_data = cell_get_iommu_table(dev);
else if (get_pci_dma_ops() == &dma_direct_ops)
archdata->dma_data = (void *)cell_dma_direct_offset;
else
--
^ permalink raw reply
* Re: [PATCH] [POWERPC] convert transfer_to_handler into a macro
From: Kumar Gala @ 2008-04-30 8:00 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <18455.59014.305281.949578@cargo.ozlabs.ibm.com>
On Apr 29, 2008, at 10:24 PM, Paul Mackerras wrote:
> Kumar Gala writes:
>
>>> Wouldn't it be better and safer to have the exception prolog for
>>> critical interrupts save SRR0/1 in the stack frame, and have the
>>> prolog for machine checks save SRR0/1 and CSRR0/1 likewise?
>>
>> If we do this I guess we can use SRR0/1 regardless of which level we
>> came from.
>
> That's the idea. I actually thought the booke exception prologs
> already did that, but it seems I'm wrong.
>
> What sort of things do you expect critical and machine-check handlers
> to be needing to do?
It varies on the parts but remember critical level can be anything
from watchdog, critical input (equivalent of external input, but at
the critical level), and debug. So there is a pretty wide set of
possibility.
- k
^ permalink raw reply
* Re: [PATCH] [POWERPC] convert transfer_to_handler into a macro
From: Kumar Gala @ 2008-04-30 8:02 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <1209537128.18023.225.camel@pasglop>
On Apr 30, 2008, at 1:32 AM, Benjamin Herrenschmidt wrote:
>
> On Tue, 2008-04-29 at 18:52 -0500, Kumar Gala wrote:
>> On Apr 29, 2008, at 4:28 PM, Paul Mackerras wrote:
>>> Kumar Gala writes:
>>>
>>>> We need to have unique transfer_to_handler paths for each exception
>>>> level
>>>> that is supported. We need to use the proper xSRR0/1 depending on
>>>> which
>>>> exception level the interrupt was from. The macro conversion
>>>> lets up
>>>> templatize this code path.
>>>
>>> It seems to me that this implies you are assuming that you will
>>> never
>>> ever get a synchronous normal interrupt such as a TLB miss while you
>>> are in a critical or machine check handler.
>>
>> Grr.. one more thing to fix :)
>>
>>> Wouldn't it be better and safer to have the exception prolog for
>>> critical interrupts save SRR0/1 in the stack frame, and have the
>>> prolog for machine checks save SRR0/1 and CSRR0/1 likewise?
>>
>> If we do this I guess we can use SRR0/1 regardless of which level we
>> came from.
>
> Also consider saving/restoring MAS
got that. Does 40x/44x have anything similar we need to save/restore?
^ permalink raw reply
* Re: MPC83xx Power Management support
From: Guennadi Liakhovetski @ 2008-04-30 8:31 UTC (permalink / raw)
To: Perrine MARTIGNONI; +Cc: linuxppc-dev
In-Reply-To: <1de232e40804300113k12a1f9cg277a8e3e2b52ee83@mail.gmail.com>
On Wed, 30 Apr 2008, Perrine MARTIGNONI wrote:
Please, in the future direct your questions to the respective mailing
list, thanks. Added to cc.
> Hello,
>
> Currently, I try to use the Power Management patches and I have some issues.
>
> With which version of linux the patches are written ?
> I try on linux-2.6.23 and there are some rejects.
The patches are against a recent powerpc git tree snapshot.
Thanks
Guennadi
---
Guennadi Liakhovetski
^ permalink raw reply
* Re: [PATCH 6/6] [POWERPC] booting-without-of: add FHCI USB, FSL MCU, FSL UPM and GPIO LEDs bindings
From: Wolfgang Grandegger @ 2008-04-30 8:36 UTC (permalink / raw)
To: Anton Vorontsov; +Cc: linuxppc-dev
In-Reply-To: <20080429190057.GF21203@polina.dev.rtsoft.ru>
Hi Anton,
Anton Vorontsov wrote:
> This patch adds few bindings for the new drivers to be submitted through
> appropriate maintainers.
>
> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
> ---
> Documentation/powerpc/booting-without-of.txt | 125 ++++++++++++++++++++++++++
> 1 files changed, 125 insertions(+), 0 deletions(-)
>
> diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
> index 4fefc44..6564e0a 100644
> --- a/Documentation/powerpc/booting-without-of.txt
> +++ b/Documentation/powerpc/booting-without-of.txt
> @@ -61,6 +61,10 @@ Table of Contents
> r) Freescale Display Interface Unit
> s) Freescale on board FPGA
> t) Freescale General-purpose Timers Module
> + u) Freescale QUICC Engine USB Controller
> + v) LEDs on GPIOs
> + w) Freescale MCU with MPC8349E-mITX compatible firmware
> + x) Freescale Localbus UPM programmed to work with NAND flash
>
> VII - Marvell Discovery mv64[345]6x System Controller chips
> 1) The /system-controller node
> @@ -2916,6 +2920,127 @@ platforms are moved over to use the flattened-device-tree model.
> clock-frequency = <0>;
> };
>
> + u) Freescale QUICC Engine USB Controller
> +
> + Required properties:
> + - compatible : should be "fsl,<chip>-qe-usb", "fsl,mpc8323-qe-usb";
> + - reg : the first two cells should contain gtm registers location and
> + length, the next two two cells should contain PRAM location and
> + length.
> + - interrupts : should contain USB interrupt.
> + - interrupt-parent : interrupt source phandle.
> + - fsl,fullspeed-clock : specifies the full speed USB clock source in
> + "clk<num>" or "brg<num>" format.
> + - fsl,lowspeed-clock : specifies the low speed USB clock source in
> + "clk<num>" or "brg<num>" format.
> + - fsl,usb-mode : should be "host".
> + - linux,hub-power-budget : optional, USB power budget for the root hub
> + in mA.
> + - gpios : should specify GPIOs in this order: USBOE, USBTP, USBTN, USBRP,
> + USBRN, SPEED (optional), and POWER (optional).
> +
> + Example:
> +
> + usb@6c0 {
> + compatible = "fsl,mpc8360-qe-usb", "fsl,mpc8323-qe-usb";
> + reg = <0x6c0 0x40 0x8b00 0x100>;
> + interrupts = <11>;
> + interrupt-parent = <&qeic>;
> + fsl,fullspeed-clock = "clk21";
> + fsl,usb-mode = "host";
> + gpios = <&qe_pio_b 2 0 /* USBOE */
> + &qe_pio_b 3 0 /* USBTP */
> + &qe_pio_b 8 0 /* USBTN */
> + &qe_pio_b 9 0 /* USBRP */
> + &qe_pio_b 11 0 /* USBRN */
> + &qe_pio_e 20 0 /* SPEED */
> + &qe_pio_e 21 0 /* POWER */>;
> + };
> +
> + v) LEDs on GPIOs
> +
> + Required properties:
> + - compatible : should be "linux,gpio-led".
> + - linux,name : LED name.
> + - linux,active-low : property should be present if LED wired as
> + active-low.
> + - linux,default-trigger : Linux default trigger for this LED.
> + - linux,brightness : default brightness.
> + - gpios : should specify LED GPIO.
> +
> + Example:
> +
> + led@0 {
> + compatible = "linux,gpio-led";
> + linux,name = "pwr";
> + linux,brightness = <1>;
> + linux,active-low;
> + gpios = <&mcu_pio 0>;
> + };
> +
> + led@1 {
> + compatible = "linux,gpio-led";
> + linux,name = "hdd";
> + linux,default-trigger = "ide-disk";
> + linux,active-low;
> + gpios = <&mcu_pio 1>;
> + };
> +
> + w) Freescale MCU with MPC8349E-mITX compatible firmware
> +
> + Required properties:
> + - compatible : "fsl,<mcu-chip>-<board>", "fsl,mcu-mpc8349emitx";
> + - reg : should specify I2C address (0x0a).
> + - #address-cells : should be 0.
> + - #size-cells : should be 0.
> + - #gpio-cells : should be 2.
> + - gpio-controller : should be present;
> +
> + Example:
> +
> + mcu_pio: mcu@0a {
> + #address-cells = <0>;
> + #size-cells = <0>;
> + #gpio-cells = <2>;
> + compatible = "fsl,mc9s08qg8-mpc8349emitx",
> + "fsl,mcu-mpc8349emitx";
> + reg = <0x0a>;
> + gpio-controller;
> + };
> +
> + x) Freescale Localbus UPM programmed to work with NAND flash
> +
> + Required properties:
> + - #address-cells : should be 0;
> + - #size-cells : should be 0;
> + - compatible : "fsl,upm-nand".
> + - reg : should specify localbus chip select and size used for the chip.
> + - fsl,upm-addr-offset : UPM pattern offset for the address latch.
> + - fsl,upm-cmd-offset : UPM pattern offset for the command latch.
> + - gpios : may specify optional GPIO connected to the Ready-Not-Busy pin.
> +
> + Example:
> +
> + upm@1,0 {
> + #address-cells = <0>;
> + #size-cells = <0>;
> + compatible = "fsl,upm-nand";
> + reg = <1 0 1>;
> + fsl,upm-addr-offset = <16>;
> + fsl,upm-cmd-offset = <8>;
> + gpios = <&qe_pio_e 18 0>;
> +
> + flash {
> + #address-cells = <1>;
> + #size-cells = <1>;
> + compatible = "stmicro,NAND512W3A2BN6E";
> +
> + partition@0 {
> + ...
> + };
> + };
> + };
Where can I find the code for that binding? fsl_upm_nand.c from
http://patchwork.ozlabs.org/linuxppc/patch?q=upm&id=17306 does not parse
OF partitions. Are there any plans to push the fsl_upm_nand driver
upstream? I'm currently implementing NAND support for the TQM8548 and
want to base it on common code.
Thanks,
Wolfgang.
^ permalink raw reply
* RE: SKB corruption on heavy traffic
From: Franca, Jose (NSN - PT/Portugal - MiniMD) @ 2008-04-30 8:43 UTC (permalink / raw)
To: ext Scott Wood; +Cc: linuxppc-dev, linuxppc-embedded
In-Reply-To: <20080429191510.GC8955@ld0162-tx32.am.freescale.net>
Hello!
Thank you for replying!
It't quite dificult to say if the problem exists without our changes, =
since the all software is dependent on this changes so to work with the =
hardware. I can't answer to that right now on that, but I forgot to add =
one thing: we have ring buffer full problems on our fcc_enet driver from =
time to time. So, I think the problem could be on linux configurations =
(related to hw) because there is a lot of posts on the web related to =
problems similar to this (none of them has really solved the bottom =
problem).=20
Regards,
Filipe=20
-----Original Message-----
From: ext Scott Wood [mailto:scottwood@freescale.com]=20
Sent: ter=E7a-feira, 29 de Abril de 2008 20:15
To: Franca, Jose (NSN - PT/Portugal - MiniMD)
Cc: linuxppc-dev@ozlabs.org; linuxppc-embedded@ozlabs.org
Subject: Re: SKB corruption on heavy traffic
On Tue, Apr 29, 2008 at 07:39:07PM +0100, Franca, Jose (NSN - =
PT/Portugal - MiniMD) wrote:
> We are developing a MPC8247 based telecom board (512MB), using
> linux 2.4 with some proprietary changes on IP stack and we are facing
> some problems when we have heavy traffic on our Ethernet interfaces...
Do you see these problems without the proprietary changes, and with a
current kernel?
-Scott
^ permalink raw reply
* [PATCH] [POWERPC] Move to runtime allocated exception stacks
From: Kumar Gala @ 2008-04-30 8:57 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
For the additonal exception levels (critical, debug, machine check) on
40x/book-e we were using "static" allocations of the stack in the
associated head.S.
Move to a runtime allocation to make the code a bit easier to read as
we mimic how we handle IRQ stacks. Its also a bit easier to setup the
stack with a "dummy" thread_info in C code.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
Josh, can you test this on 40x and 44x. (make sure gdb single step still
functions).
This is the first in a sequence of patches towards fixing up the exception
level stack functionality. I'm posting them in pieces to get review and
make it easier to bisect if the patches introduce issues in the future.
- k
arch/powerpc/kernel/head_40x.S | 14 ++------------
arch/powerpc/kernel/head_44x.S | 9 ---------
arch/powerpc/kernel/head_booke.h | 27 ++++++++++-----------------
arch/powerpc/kernel/head_fsl_booke.S | 9 ---------
arch/powerpc/kernel/irq.c | 33 +++++++++++++++++++++++++++++++++
arch/powerpc/kernel/setup_32.c | 24 ++++++++++++++++++++++++
include/asm-powerpc/irq.h | 13 +++++++++++++
7 files changed, 82 insertions(+), 47 deletions(-)
diff --git a/arch/powerpc/kernel/head_40x.S b/arch/powerpc/kernel/head_40x.S
index 8552e67..ca75eaf 100644
--- a/arch/powerpc/kernel/head_40x.S
+++ b/arch/powerpc/kernel/head_40x.S
@@ -148,8 +148,8 @@ _ENTRY(crit_r11)
mfcr r10; /* save CR in r10 for now */\
mfspr r11,SPRN_SRR3; /* check whether user or kernel */\
andi. r11,r11,MSR_PR; \
- lis r11,critical_stack_top@h; \
- ori r11,r11,critical_stack_top@l; \
+ lis r11,critirq_ctx@ha; \
+ lwz r11,critirq_ctx@l(r11); \
beq 1f; \
/* COMING FROM USER MODE */ \
mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\
@@ -996,16 +996,6 @@ empty_zero_page:
swapper_pg_dir:
.space PGD_TABLE_SIZE
-
-/* Stack for handling critical exceptions from kernel mode */
- .section .bss
- .align 12
-exception_stack_bottom:
- .space 4096
-critical_stack_top:
- .globl exception_stack_top
-exception_stack_top:
-
/* Room for two PTE pointers, usually the kernel and current user pointers
* to their respective root page table.
*/
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index b84ec6a..2041248 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -730,15 +730,6 @@ empty_zero_page:
swapper_pg_dir:
.space PGD_TABLE_SIZE
-/* Reserved 4k for the critical exception stack & 4k for the machine
- * check stack per CPU for kernel mode exceptions */
- .section .bss
- .align 12
-exception_stack_bottom:
- .space BOOKE_EXCEPTION_STACK_SIZE
- .globl exception_stack_top
-exception_stack_top:
-
/*
* Room for two PTE pointers, usually the kernel and current user pointers
* to their respective root page table.
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
index aefafc6..d647e05 100644
--- a/arch/powerpc/kernel/head_booke.h
+++ b/arch/powerpc/kernel/head_booke.h
@@ -43,9 +43,7 @@
SAVE_2GPRS(7, r11)
/* To handle the additional exception priority levels on 40x and Book-E
- * processors we allocate a 4k stack per additional priority level. The various
- * head_xxx.S files allocate space (exception_stack_top) for each priority's
- * stack times the number of CPUs
+ * processors we allocate a stack per additional priority level.
*
* On 40x critical is the only additional level
* On 44x/e500 we have critical and machine check
@@ -61,36 +59,31 @@
* going to critical or their own debug level we aren't currently
* providing configurations that micro-optimize space usage.
*/
-#ifdef CONFIG_44x
-#define NUM_EXCEPTION_LVLS 2
-#else
-#define NUM_EXCEPTION_LVLS 3
-#endif
-#define BOOKE_EXCEPTION_STACK_SIZE (4096 * NUM_EXCEPTION_LVLS)
/* CRIT_SPRG only used in critical exception handling */
#define CRIT_SPRG SPRN_SPRG2
/* MCHECK_SPRG only used in machine check exception handling */
#define MCHECK_SPRG SPRN_SPRG6W
-#define MCHECK_STACK_TOP (exception_stack_top - 4096)
-#define CRIT_STACK_TOP (exception_stack_top)
+#define MCHECK_STACK_TOP mcheckirq_ctx
+#define CRIT_STACK_TOP critirq_ctx
/* only on e200 for now */
-#define DEBUG_STACK_TOP (exception_stack_top - 8192)
+#define DEBUG_STACK_TOP dbgirq_ctx
#define DEBUG_SPRG SPRN_SPRG6W
#ifdef CONFIG_SMP
#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
mfspr r8,SPRN_PIR; \
- mulli r8,r8,BOOKE_EXCEPTION_STACK_SIZE; \
- neg r8,r8; \
+ slwi r8,r8,2; \
addis r8,r8,level##_STACK_TOP@ha; \
- addi r8,r8,level##_STACK_TOP@l
+ lwz r8,level##_STACK_TOP@l(r8); \
+ addi r8,r8,THREAD_SIZE;
#else
#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
- lis r8,level##_STACK_TOP@h; \
- ori r8,r8,level##_STACK_TOP@l
+ lis r8,level##_STACK_TOP@ha; \
+ lwz r8,level##_STACK_TOP@l(r8); \
+ addi r8,r8,THREAD_SIZE;
#endif
/*
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index e581524..503f860 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -1080,15 +1080,6 @@ empty_zero_page:
swapper_pg_dir:
.space PGD_TABLE_SIZE
-/* Reserved 4k for the critical exception stack & 4k for the machine
- * check stack per CPU for kernel mode exceptions */
- .section .bss
- .align 12
-exception_stack_bottom:
- .space BOOKE_EXCEPTION_STACK_SIZE * NR_CPUS
- .globl exception_stack_top
-exception_stack_top:
-
/*
* Room for two PTE pointers, usually the kernel and current user pointers
* to their respective root page table.
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 2f73f70..b519975 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -356,9 +356,42 @@ void __init init_IRQ(void)
{
if (ppc_md.init_IRQ)
ppc_md.init_IRQ();
+
+ exc_lvl_ctx_init();
+
irq_ctx_init();
}
+#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
+struct thread_info *critirq_ctx[NR_CPUS] __read_mostly;
+struct thread_info *dbgirq_ctx[NR_CPUS] __read_mostly;
+struct thread_info *mcheckirq_ctx[NR_CPUS] __read_mostly;
+
+void exc_lvl_ctx_init(void)
+{
+ struct thread_info *tp;
+ int i;
+
+ for_each_possible_cpu(i) {
+ memset((void *)critirq_ctx[i], 0, THREAD_SIZE);
+ tp = critirq_ctx[i];
+ tp->cpu = i;
+ tp->preempt_count = 0;
+
+#ifdef CONFIG_BOOKE
+ memset((void *)dbgirq_ctx[i], 0, THREAD_SIZE);
+ tp = dbgirq_ctx[i];
+ tp->cpu = i;
+ tp->preempt_count = 0;
+
+ memset((void *)mcheckirq_ctx[i], 0, THREAD_SIZE);
+ tp = mcheckirq_ctx[i];
+ tp->cpu = i;
+ tp->preempt_count = HARDIRQ_OFFSET;
+#endif
+ }
+}
+#endif
#ifdef CONFIG_IRQSTACKS
struct thread_info *softirq_ctx[NR_CPUS] __read_mostly;
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 5112a4a..bef0be3 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -248,6 +248,28 @@ static void __init irqstack_early_init(void)
#define irqstack_early_init()
#endif
+#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
+static void __init exc_lvl_early_init(void)
+{
+ unsigned int i;
+
+ /* interrupt stacks must be in lowmem, we get that for free on ppc32
+ * as the lmb is limited to lowmem by LMB_REAL_LIMIT */
+ for_each_possible_cpu(i) {
+ critirq_ctx[i] = (struct thread_info *)
+ __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
+#ifdef CONFIG_BOOKE
+ dbgirq_ctx[i] = (struct thread_info *)
+ __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
+ mcheckirq_ctx[i] = (struct thread_info *)
+ __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
+#endif
+ }
+}
+#else
+#define exc_lvl_early_init()
+#endif
+
/* Warning, IO base is not yet inited */
void __init setup_arch(char **cmdline_p)
{
@@ -305,6 +327,8 @@ void __init setup_arch(char **cmdline_p)
init_mm.end_data = (unsigned long) _edata;
init_mm.brk = klimit;
+ exc_lvl_early_init();
+
irqstack_early_init();
/* set up the bootmem stuff with available memory */
diff --git a/include/asm-powerpc/irq.h b/include/asm-powerpc/irq.h
index b5c0312..8892066 100644
--- a/include/asm-powerpc/irq.h
+++ b/include/asm-powerpc/irq.h
@@ -621,6 +621,19 @@ struct pt_regs;
extern void __do_softirq(void);
+#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
+/*
+ * Per-cpu stacks for handling critical, debug and machine check
+ * level interrupts.
+ */
+extern struct thread_info *critirq_ctx[NR_CPUS];
+extern struct thread_info *dbgirq_ctx[NR_CPUS];
+extern struct thread_info *mcheckirq_ctx[NR_CPUS];
+extern void exc_lvl_ctx_init(void);
+#else
+#define exc_lvl_ctx_init()
+#endif
+
#ifdef CONFIG_IRQSTACKS
/*
* Per-cpu stacks for handling hard and soft interrupts.
--
1.5.4.1
^ permalink raw reply related
* FW: SKB corruption on heavy traffic
From: Franca, Jose (NSN - PT/Portugal - MiniMD) @ 2008-04-30 9:07 UTC (permalink / raw)
To: linuxppc-dev, linuxppc-embedded
>From our latest debugs we found that the problem occurs mainly on skbuff =
code. After some variable time kfree or kalloc result in kernel oops.
-----Original Message-----
From: Franca, Jose (NSN - PT/Portugal - MiniMD)=20
Sent: quarta-feira, 30 de Abril de 2008 9:44
To: 'ext Scott Wood'
Cc: =09
Subject: RE: SKB corruption on heavy traffic
Hello!
Thank you for replying!
It't quite dificult to say if the problem exists without our changes, =
since the all software is dependent on this changes so to work with the =
hardware. I can't answer to that right now on that, but I forgot to add =
one thing: we have ring buffer full problems on our fcc_enet driver from =
time to time. So, I think the problem could be on linux configurations =
(related to hw) because there is a lot of posts on the web related to =
problems similar to this (none of them has really solved the bottom =
problem).=20
Regards,
Filipe=20
-----Original Message-----
From: ext Scott Wood [mailto:scottwood@freescale.com]=20
Sent: ter=E7a-feira, 29 de Abril de 2008 20:15
To: Franca, Jose (NSN - PT/Portugal - MiniMD)
Cc: linuxppc-dev@ozlabs.org; linuxppc-embedded@ozlabs.org
Subject: Re: SKB corruption on heavy traffic
On Tue, Apr 29, 2008 at 07:39:07PM +0100, Franca, Jose (NSN - =
PT/Portugal - MiniMD) wrote:
> We are developing a MPC8247 based telecom board (512MB), using
> linux 2.4 with some proprietary changes on IP stack and we are facing
> some problems when we have heavy traffic on our Ethernet interfaces...
Do you see these problems without the proprietary changes, and with a
current kernel?
-Scott
^ permalink raw reply
* [PATCH] [POWERPC] Rework EXC_LEVEL_EXCEPTION_PROLOG code
From: Kumar Gala @ 2008-04-30 9:27 UTC (permalink / raw)
To: Paul Mackerras, Benjamin Herrenschmidt; +Cc: linuxppc-dev
* Cleanup the code a bit my allocating an INT_FRAME on our exception
stack there by make references go from GPR11-INT_FRAME_SIZE(r8) to
just GPR(r8)
* simplify {lvl}_transfer_to_handler code by moving the copying of the
temp registers we use if we come from user space into the PROLOG
* If the exception came from kernel mode copy thread_info flags,
preempt, and task pointer from the process thread_info.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
I'm not sure if the copying of TI_FLAGS, TI_PREEMPT, and TI_TASK
are really needed. I'm a bit concerned what to do if we get a
CriticalInput while in kernel mode and the handler causes a reschedule.
arch/powerpc/kernel/entry_32.S | 13 ----------
arch/powerpc/kernel/head_booke.h | 47 ++++++++++++++++++++++++-------------
2 files changed, 30 insertions(+), 30 deletions(-)
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 0c8614d..816dd54 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -44,29 +44,16 @@
#endif
#ifdef CONFIG_BOOKE
-#include "head_booke.h"
-#define TRANSFER_TO_HANDLER_EXC_LEVEL(exc_level) \
- mtspr exc_level##_SPRG,r8; \
- BOOKE_LOAD_EXC_LEVEL_STACK(exc_level); \
- lwz r0,GPR10-INT_FRAME_SIZE(r8); \
- stw r0,GPR10(r11); \
- lwz r0,GPR11-INT_FRAME_SIZE(r8); \
- stw r0,GPR11(r11); \
- mfspr r8,exc_level##_SPRG
-
.globl mcheck_transfer_to_handler
mcheck_transfer_to_handler:
- TRANSFER_TO_HANDLER_EXC_LEVEL(MCHECK)
b transfer_to_handler_full
.globl debug_transfer_to_handler
debug_transfer_to_handler:
- TRANSFER_TO_HANDLER_EXC_LEVEL(DEBUG)
b transfer_to_handler_full
.globl crit_transfer_to_handler
crit_transfer_to_handler:
- TRANSFER_TO_HANDLER_EXC_LEVEL(CRIT)
/* fall through */
#endif
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
index d647e05..78baec5 100644
--- a/arch/powerpc/kernel/head_booke.h
+++ b/arch/powerpc/kernel/head_booke.h
@@ -78,12 +78,12 @@
slwi r8,r8,2; \
addis r8,r8,level##_STACK_TOP@ha; \
lwz r8,level##_STACK_TOP@l(r8); \
- addi r8,r8,THREAD_SIZE;
+ addi r8,r8,THREAD_SIZE-INT_FRAME_SIZE;
#else
#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
lis r8,level##_STACK_TOP@ha; \
lwz r8,level##_STACK_TOP@l(r8); \
- addi r8,r8,THREAD_SIZE;
+ addi r8,r8,THREAD_SIZE-INT_FRAME_SIZE;
#endif
/*
@@ -97,22 +97,35 @@
#define EXC_LEVEL_EXCEPTION_PROLOG(exc_level, exc_level_srr0, exc_level_srr1) \
mtspr exc_level##_SPRG,r8; \
BOOKE_LOAD_EXC_LEVEL_STACK(exc_level);/* r8 points to the exc_level stack*/ \
- stw r10,GPR10-INT_FRAME_SIZE(r8); \
- stw r11,GPR11-INT_FRAME_SIZE(r8); \
+ stw r9,GPR9(r8); /* save various registers */\
+ stw r10,GPR10(r8); \
+ stw r11,GPR11(r8); \
+ mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\
+ lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
+ addi r11,r11,THREAD_SIZE-INT_FRAME_SIZE; /* Alloc exception frm */\
mfcr r10; /* save CR in r10 for now */\
- mfspr r11,exc_level_srr1; /* check whether user or kernel */\
- andi. r11,r11,MSR_PR; \
- mr r11,r8; \
- mfspr r8,exc_level##_SPRG; \
+ mfspr r9,exc_level_srr1; /* check whether user or kernel */\
+ andi. r9,r9,MSR_PR; \
beq 1f; \
/* COMING FROM USER MODE */ \
- mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\
- lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
- addi r11,r11,THREAD_SIZE; \
-1: subi r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame */\
+ lwz r9,GPR9(r8); /* copy regs from exception stack */\
+ stw r9,GPR9(r11); \
+ lwz r9,GPR10(r8); \
+ stw r9,GPR10(r11); \
+ lwz r9,GPR11(r8); \
+ stw r9,GPR11(r11); \
+ b 2f; \
+ /* COMING FROM PRIV MODE */ \
+1: lwz r9,TI_FLAGS-THREAD_SIZE(r11); \
+ stw r9,TI_FLAGS-THREAD_SIZE(r8); \
+ lwz r9,TI_PREEMPT-THREAD_SIZE(r11); \
+ stw r9,TI_PREEMPT-THREAD_SIZE(r8); \
+ lwz r9,TI_TASK-THREAD_SIZE(r11); \
+ stw r9,TI_TASK-THREAD_SIZE(r8); \
+ mr r11,r8; \
+2: mfspr r8,exc_level##_SPRG; \
stw r10,_CCR(r11); /* save various registers */\
stw r12,GPR12(r11); \
- stw r9,GPR9(r11); \
mflr r10; \
stw r10,_LINK(r11); \
mfspr r12,SPRN_DEAR; /* save DEAR and ESR in the frame */\
@@ -255,8 +268,8 @@ label:
lwz r12,GPR12(r11); \
mtspr DEBUG_SPRG,r8; \
BOOKE_LOAD_EXC_LEVEL_STACK(DEBUG); /* r8 points to the debug stack */ \
- lwz r10,GPR10-INT_FRAME_SIZE(r8); \
- lwz r11,GPR11-INT_FRAME_SIZE(r8); \
+ lwz r10,GPR10(r8); \
+ lwz r11,GPR11(r8); \
mfspr r8,DEBUG_SPRG; \
\
RFDI; \
@@ -308,8 +321,8 @@ label:
lwz r12,GPR12(r11); \
mtspr CRIT_SPRG,r8; \
BOOKE_LOAD_EXC_LEVEL_STACK(CRIT); /* r8 points to the debug stack */ \
- lwz r10,GPR10-INT_FRAME_SIZE(r8); \
- lwz r11,GPR11-INT_FRAME_SIZE(r8); \
+ lwz r10,GPR10(r8); \
+ lwz r11,GPR11(r8); \
mfspr r8,CRIT_SPRG; \
\
rfci; \
--
1.5.4.1
^ permalink raw reply related
* [git pull] Please pull powerpc.git master branch
From: Paul Mackerras @ 2008-04-30 10:31 UTC (permalink / raw)
To: torvalds; +Cc: linuxppc-dev, akpm, linux-kernel
Linus,
Please do:
git pull \
git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc.git master
once more. There are a bunch of updates for the embedded MPC5200
based platforms, some spufs updates for Cell, and two bug fixes from
Michael Ellerman.
Sorry about missing the diffstat last time.
Thanks,
Paul.
.../powerpc/mpc52xx-device-tree-bindings.txt | 12
arch/powerpc/boot/dts/cm5200.dts | 98 +-
arch/powerpc/boot/dts/lite5200.dts | 132 +-
arch/powerpc/boot/dts/lite5200b.dts | 146 +-
arch/powerpc/boot/dts/motionpro.dts | 118 +-
arch/powerpc/boot/dts/pcm030.dts | 363 ++++++
arch/powerpc/boot/dts/tqm5200.dts | 80 +
arch/powerpc/configs/52xx/cm5200_defconfig | 1099 ++++++++++++++++++
arch/powerpc/configs/52xx/lite5200b_defconfig | 1049 +++++++++++++++++
arch/powerpc/configs/52xx/motionpro_defconfig | 1107 ++++++++++++++++++
arch/powerpc/configs/52xx/pcm030_defconfig | 1115 ++++++++++++++++++
arch/powerpc/configs/52xx/tqm5200_defconfig | 1214 ++++++++++++++++++++
arch/powerpc/kernel/machine_kexec.c | 12
arch/powerpc/kernel/setup_64.c | 9
arch/powerpc/platforms/52xx/Kconfig | 6
arch/powerpc/platforms/52xx/Makefile | 2
arch/powerpc/platforms/52xx/mpc5200_simple.c | 1
arch/powerpc/platforms/52xx/mpc52xx_gpio.c | 465 ++++++++
arch/powerpc/platforms/52xx/mpc52xx_pic.c | 38 +
arch/powerpc/platforms/cell/spufs/.gitignore | 2
arch/powerpc/platforms/cell/spufs/context.c | 4
arch/powerpc/platforms/cell/spufs/file.c | 166 +++
arch/powerpc/platforms/cell/spufs/run.c | 2
arch/powerpc/platforms/cell/spufs/sched.c | 4
arch/powerpc/platforms/cell/spufs/spufs.h | 33 +
arch/powerpc/platforms/cell/spufs/sputrace.c | 36 -
drivers/net/fec_mpc52xx.c | 23
drivers/serial/mpc52xx_uart.c | 2
28 files changed, 7009 insertions(+), 329 deletions(-)
create mode 100644 arch/powerpc/boot/dts/pcm030.dts
create mode 100644 arch/powerpc/configs/52xx/cm5200_defconfig
create mode 100644 arch/powerpc/configs/52xx/lite5200b_defconfig
create mode 100644 arch/powerpc/configs/52xx/motionpro_defconfig
create mode 100644 arch/powerpc/configs/52xx/pcm030_defconfig
create mode 100644 arch/powerpc/configs/52xx/tqm5200_defconfig
create mode 100644 arch/powerpc/platforms/52xx/mpc52xx_gpio.c
create mode 100644 arch/powerpc/platforms/cell/spufs/.gitignore
Bartlomiej Sieka (1):
[POWERPC] mpc5200: defconfigs for CM5200, Lite5200B, Motion-PRO and TQM5200
Christoph Hellwig (1):
[POWERPC] spufs: add context switch notification log
Grant Likely (2):
[POWERPC] mpc5200: Fix unterminated of_device_id table
[POWERPC] mpc5200: Switch mpc5200 dts files to dts-v1 format
Julio M. Merino Vidal (4):
[POWERPC] spufs: add sputrace marker parameter names
[POWERPC] spufs: add marker for destroy_spu_context
[POWERPC] spufs: fix marker name for find_victim
[POWERPC] spufs: trace spu_acquire_saved events
Kumar Gala (1):
[POWERPC] spufs: add .gitignore for spu_save_dump.h & spu_restore_dump.h
Michael Ellerman (2):
[POWERPC] Make emergency stack safe for current_thread_info() use
[POWERPC] Fix crashkernel= handling when no crashkernel= specified
Sascha Hauer (2):
[POWERPC] mpc5200: add interrupt type function
[POWERPC] mpc5200: Fix FEC error handling on FIFO errors
s.hauer@pengutronix.de (2):
[POWERPC] mpc5200: add gpiolib support for mpc5200
[POWERPC] mpc5200: add Phytec pcm030 board support
^ permalink raw reply
* Re: [PATCH 1/7] Implement arch disable/enable irq hooks.
From: Guennadi Liakhovetski @ 2008-04-30 10:33 UTC (permalink / raw)
To: Paul Mackerras; +Cc: Scott Wood, linuxppc-dev
In-Reply-To: <18454.42926.213374.977098@cargo.ozlabs.ibm.com>
On Tue, 29 Apr 2008, Paul Mackerras wrote:
> Scott Wood writes:
>
> > On Fri, Apr 25, 2008 at 02:57:24PM +0200, Guennadi Liakhovetski wrote:
> > > is there any specific reason, why out of these 7 patches only the first
> > > one made it into the mainline? AFAICS, there has been only one comment,
> > > suggesting to replace printk with dev_err on two occasions in one of
> > > the patches...
> >
> > A while ago Paul said on IRC he'd prefer to do the TLF_SLEEPING hack more
> > like the soft IRQ disabling that 64-bit uses. I haven't yet had a chance
> > to look into it, so the patch collects dust, despite the current
> > implementation of TLF_SLEEPING working just fine.
>
> I have taken a closer look at the TLF_SLEEPING patch and crystallized
> my thoughts about it a bit:
>
> 1. Too many ifdefs - it's only a few instructions extra, so if we're
> going to have the TLF_SLEEPING stuff we might as well have it
> unconditionally.
>
> 2. It seems convoluted to me to go through transfer_to_handler_cont
> and ret_from_except when we could just get out directly through
> fast_exception_return, given that we are not calling a handler. The
> only thing to watch out for there is that r7 and r8 haven't been
> modified (or have been restored if they have).
>
> 3. The style in all the assembly code is not to have spaces after
> commas separating instruction operands.
>
> The untested patch below is what I was thinking of. If you'd like to
> try it out, I'd be interested to hear how it goes.
The patch (with the _TLF_SLEEPING fix you mentioned in a later email)
works for me. Shall I submit it "From: <you>" or would you prefer to post
it yourself? But, I guess, you have to put your "S-o-b" under it yourself,
don't you?
Thanks
Guennadi
---
Guennadi Liakhovetski
^ permalink raw reply
* [PATCH] [POWERPC] 40x/Book-E: Save/restore volatile exception registers
From: Kumar Gala @ 2008-04-30 10:31 UTC (permalink / raw)
To: Paul Mackerras, Benjamin Herrenschmidt; +Cc: linuxppc-dev
On machines with more than one exception level any system register that
might be modified by the "normal" exception level needs to be saved and
restored on taking a higher level exception. We already are saving
and restoring ESR and DEAR.
For critical level add SRR0/1.
For debug level add CSRR0/1 and SRR0/1.
For machine check level add DSRR0/1, CSRR0/1, and SRR0/1.
On FSL Book-E parts we always save/restore the MAS registers for critical,
debug, and machine check level exceptions.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
I'm not sure if I got the 40x restore right. I'm also a bit concerned
about the path that returns via user_exc_return and uses SRR0/1. I think
this is ok because we have to ensure no SRR0/1 level exceptions occur at
this point already.
- k
arch/powerpc/kernel/asm-offsets.c | 20 +++++++++
arch/powerpc/kernel/entry_32.S | 85 ++++++++++++++++++++++++++++++++++++-
arch/powerpc/kernel/head_40x.S | 4 ++
arch/powerpc/kernel/head_booke.h | 24 ++++++++++-
4 files changed, 129 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index af1d2c8..0d1a36e 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -51,6 +51,10 @@
#include <asm/iseries/alpaca.h>
#endif
+#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
+#include "head_booke.h"
+#endif
+
#define DEFINE(sym, val) \
asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -246,6 +250,22 @@ int main(void)
DEFINE(_SRR1, STACK_FRAME_OVERHEAD+sizeof(struct pt_regs)+8);
#endif /* CONFIG_PPC64 */
+#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
+ DEFINE(EXC_LVL_SIZE, STACK_EXC_LVL_FRAME_SIZE);
+ DEFINE(MAS0, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, mas0));
+ DEFINE(MAS1, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, mas1));
+ DEFINE(MAS2, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, mas2));
+ DEFINE(MAS3, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, mas3));
+ DEFINE(MAS6, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, mas6));
+ DEFINE(MAS7, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, mas7));
+ DEFINE(_SRR0, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, srr0));
+ DEFINE(_SRR1, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, srr1));
+ DEFINE(_CSRR0, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, csrr0));
+ DEFINE(_CSRR1, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, csrr1));
+ DEFINE(_DSRR0, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, dsrr0));
+ DEFINE(_DSRR1, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, dsrr1));
+#endif
+
DEFINE(CLONE_VM, CLONE_VM);
DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 816dd54..ab86ab9 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -46,14 +46,42 @@
#ifdef CONFIG_BOOKE
.globl mcheck_transfer_to_handler
mcheck_transfer_to_handler:
- b transfer_to_handler_full
+ mfspr r0,SPRN_DSRR0
+ stw r0,_DSRR0(r11)
+ mfspr r0,SPRN_DSRR1
+ stw r0,_DSRR1(r11)
+ /* fall through */
.globl debug_transfer_to_handler
debug_transfer_to_handler:
- b transfer_to_handler_full
+ mfspr r0,SPRN_CSRR0
+ stw r0,_CSRR0(r11)
+ mfspr r0,SPRN_CSRR1
+ stw r0,_CSRR1(r11)
+ /* fall through */
.globl crit_transfer_to_handler
crit_transfer_to_handler:
+#ifdef CONFIG_FSL_BOOKE
+ mfspr r0,SPRN_MAS0
+ stw r0,MAS0(r11)
+ mfspr r0,SPRN_MAS1
+ stw r0,MAS1(r11)
+ mfspr r0,SPRN_MAS2
+ stw r0,MAS2(r11)
+ mfspr r0,SPRN_MAS3
+ stw r0,MAS3(r11)
+ mfspr r0,SPRN_MAS6
+ stw r0,MAS6(r11)
+#ifdef CONFIG_PHYS_64BIT
+ mfspr r0,SPRN_MAS7
+ stw r0,MAS7(r11)
+#endif /* CONFIG_PHYS_64BIT */
+#endif /* CONFIG_FSL_BOOKE */
+ mfspr r0,SPRN_SRR0
+ stw r0,_SRR0(r11)
+ mfspr r0,SPRN_SRR1
+ stw r0,_SRR1(r11)
/* fall through */
#endif
@@ -64,6 +92,10 @@ crit_transfer_to_handler:
stw r0,GPR10(r11)
lwz r0,crit_r11@l(0)
stw r0,GPR11(r11)
+ mfspr r0,SPRN_SRR0
+ stw r0,crit_srr0@l(0)
+ mfspr r0,SPRN_SRR1
+ stw r0,crit_srr1@l(0)
/* fall through */
#endif
@@ -846,17 +878,66 @@ exc_exit_restart_end:
exc_lvl_rfi; \
b .; /* prevent prefetch past exc_lvl_rfi */
+#define RESTORE_xSRR(exc_lvl_srr0, exc_lvl_srr1) \
+ lwz r9,_##exc_lvl_srr0(r1); \
+ lwz r10,_##exc_lvl_srr1(r1); \
+ mtspr SPRN_##exc_lvl_srr0,r9; \
+ mtspr SPRN_##exc_lvl_srr1,r10;
+
+#ifdef CONFIG_FSL_BOOKE
+#ifdef CONFIG_PHYS_64BIT
+#define RESTORE_MAS7 \
+ lwz r11,MAS7(r1); \
+ mtspr SPRN_MAS7,r11;
+#else
+#define RESTORE_MAS7
+#endif /* CONFIG_PHYS_64BIT */
+#define RESTORE_MAS_REGS \
+ lwz r9,MAS0(r1); \
+ lwz r10,MAS1(r1); \
+ lwz r11,MAS2(r1); \
+ mtspr SPRN_MAS0,r9; \
+ lwz r9,MAS3(r1); \
+ mtspr SPRN_MAS1,r10; \
+ lwz r10,MAS6(r1); \
+ mtspr SPRN_MAS2,r11; \
+ mtspr SPRN_MAS3,r9; \
+ mtspr SPRN_MAS6,r10; \
+ RESTORE_MAS7;
+#else
+#define RESTORE_MAS_REGS
+#endif
+
+#ifdef CONFIG_40x
.globl ret_from_crit_exc
ret_from_crit_exc:
+ lwz r9,crit_srr0@l(0);
+ lwz r10,crit_srr1@l(0);
+ mtspr SPRN_SRR0,r9;
+ mtspr SPRN_SRR1,r10;
RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI)
+#endif /* CONFIG_40x */
#ifdef CONFIG_BOOKE
+ .globl ret_from_crit_exc
+ret_from_crit_exc:
+ RESTORE_xSRR(SRR0,SRR1);
+ RESTORE_MAS_REGS;
+ RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI)
+
.globl ret_from_debug_exc
ret_from_debug_exc:
+ RESTORE_xSRR(SRR0,SRR1);
+ RESTORE_xSRR(CSRR0,CSRR1);
+ RESTORE_MAS_REGS;
RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, RFDI)
.globl ret_from_mcheck_exc
ret_from_mcheck_exc:
+ RESTORE_xSRR(SRR0,SRR1);
+ RESTORE_xSRR(CSRR0,CSRR1);
+ RESTORE_xSRR(DSRR0,DSRR1);
+ RESTORE_MAS_REGS;
RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, RFMCI)
#endif /* CONFIG_BOOKE */
diff --git a/arch/powerpc/kernel/head_40x.S b/arch/powerpc/kernel/head_40x.S
index ca75eaf..3c819a1 100644
--- a/arch/powerpc/kernel/head_40x.S
+++ b/arch/powerpc/kernel/head_40x.S
@@ -93,6 +93,10 @@ _ENTRY(crit_r10)
.space 4
_ENTRY(crit_r11)
.space 4
+_ENTRY(crit_srr0)
+ .space 4
+_ENTRY(crit_srr1)
+ .space 4
/*
* Exception vector entry code. This code runs with address translation
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
index 78baec5..5f5429f 100644
--- a/arch/powerpc/kernel/head_booke.h
+++ b/arch/powerpc/kernel/head_booke.h
@@ -78,12 +78,12 @@
slwi r8,r8,2; \
addis r8,r8,level##_STACK_TOP@ha; \
lwz r8,level##_STACK_TOP@l(r8); \
- addi r8,r8,THREAD_SIZE-INT_FRAME_SIZE;
+ addi r8,r8,THREAD_SIZE-INT_FRAME_SIZE-EXC_LVL_SIZE;
#else
#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
lis r8,level##_STACK_TOP@ha; \
lwz r8,level##_STACK_TOP@l(r8); \
- addi r8,r8,THREAD_SIZE-INT_FRAME_SIZE;
+ addi r8,r8,THREAD_SIZE-INT_FRAME_SIZE-EXC_LVL_SIZE;
#endif
/*
@@ -373,4 +373,24 @@ label:
addi r3,r1,STACK_FRAME_OVERHEAD; \
EXC_XFER_EE_LITE(0x800, kernel_fp_unavailable_exception)
+#ifndef __ASSEMBLY__
+/* ensure this structure is always sized to a multiple of the stack alignment */
+struct exception_regs {
+ unsigned long mas0;
+ unsigned long mas1;
+ unsigned long mas2;
+ unsigned long mas3;
+ unsigned long mas6;
+ unsigned long mas7;
+ unsigned long srr0;
+ unsigned long srr1;
+ unsigned long csrr0;
+ unsigned long csrr1;
+ unsigned long dsrr0;
+ unsigned long dsrr1;
+};
+
+#define STACK_EXC_LVL_FRAME_SIZE (sizeof (struct exception_regs))
+
+#endif /* __ASSEMBLY__ */
#endif /* __HEAD_BOOKE_H__ */
--
1.5.4.1
^ permalink raw reply related
* [PATCH] [POWERPC] Set lower flag bits in regs->trap to indicate debug level exception
From: Kumar Gala @ 2008-04-30 10:44 UTC (permalink / raw)
To: linuxppc-dev
We use the low bits of regs->trap as flag bits. We already indicate
critical and machine check level exceptions via this mechanism. Extend it
to indicate debug level exceptions.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
arch/powerpc/kernel/head_booke.h | 2 +-
include/asm-powerpc/ptrace.h | 1 +
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
index 5f5429f..24cc6b8 100644
--- a/arch/powerpc/kernel/head_booke.h
+++ b/arch/powerpc/kernel/head_booke.h
@@ -278,7 +278,7 @@ label:
/* continue normal handling for a critical exception... */ \
2: mfspr r4,SPRN_DBSR; \
addi r3,r1,STACK_FRAME_OVERHEAD; \
- EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, debug_transfer_to_handler, ret_from_debug_exc)
+ EXC_XFER_TEMPLATE(DebugException, 0x2008, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, debug_transfer_to_handler, ret_from_debug_exc)
#define DEBUG_CRIT_EXCEPTION \
START_EXCEPTION(DebugCrit); \
diff --git a/include/asm-powerpc/ptrace.h b/include/asm-powerpc/ptrace.h
index 39023dd..38d87e5 100644
--- a/include/asm-powerpc/ptrace.h
+++ b/include/asm-powerpc/ptrace.h
@@ -119,6 +119,7 @@ extern int ptrace_put_reg(struct task_struct *task, int regno,
#ifndef __powerpc64__
#define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) != 0)
#define IS_MCHECK_EXC(regs) (((regs)->trap & 4) != 0)
+#define IS_DEBUG_EXC(regs) (((regs)->trap & 8) != 0)
#endif /* ! __powerpc64__ */
#define TRAP(regs) ((regs)->trap & ~0xF)
#ifdef __powerpc64__
--
1.5.4.1
^ permalink raw reply related
* Re: [PATCH 6/6] [POWERPC] booting-without-of: add FHCI USB, FSL MCU, FSL UPM and GPIO LEDs bindings
From: Anton Vorontsov @ 2008-04-30 11:16 UTC (permalink / raw)
To: Wolfgang Grandegger; +Cc: linuxppc-dev
In-Reply-To: <48182FA6.5010900@grandegger.com>
On Wed, Apr 30, 2008 at 10:36:54AM +0200, Wolfgang Grandegger wrote:
> Hi Anton,
[...]
> > + upm@1,0 {
> > + #address-cells = <0>;
> > + #size-cells = <0>;
> > + compatible = "fsl,upm-nand";
> > + reg = <1 0 1>;
> > + fsl,upm-addr-offset = <16>;
> > + fsl,upm-cmd-offset = <8>;
> > + gpios = <&qe_pio_e 18 0>;
> > +
> > + flash {
> > + #address-cells = <1>;
> > + #size-cells = <1>;
> > + compatible = "stmicro,NAND512W3A2BN6E";
> > +
> > + partition@0 {
> > + ...
> > + };
> > + };
> > + };
>
> Where can I find the code for that binding? fsl_upm_nand.c from
> http://patchwork.ozlabs.org/linuxppc/patch?q=upm&id=17306 does not parse
> OF partitions. Are there any plans to push the fsl_upm_nand driver
> upstream?
David already pushed UPM NAND driver upstream, but true, it was an "old"
version, i.e. without approved bindings. I'll send the update (inlining
here) if/when these bindings will be applied to the powerpc tree.
- - - -
From: Anton Vorontsov <avorontsov@ru.mvista.com>
Subject: [NAND] update FSL UPM NAND driver for the new OF bindings
- get rid of fsl,wait-pattern and fsl,wait-write. I think this isn't
chip-specific, and we should always do waits. I saw one board that
didn't need fsl,wait-pattern, but I assume it was exception that
proves general rule;
- get rid of chip-delay. Today there are no users for this, and if
anyone really need this they should push the OF bindings beforehand;
- Now flash chips should be child nodes of the FSL UPM nand controller;
- Implement OF partition parsing.
Signed-off-by: not yet.
---
drivers/mtd/nand/fsl_upm.c | 62 +++++++++++++++++++++++++++-----------------
1 files changed, 38 insertions(+), 24 deletions(-)
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c
index 1ebfd87..f91c950 100644
--- a/drivers/mtd/nand/fsl_upm.c
+++ b/drivers/mtd/nand/fsl_upm.c
@@ -36,9 +36,6 @@ struct fsl_upm_nand {
uint8_t upm_cmd_offset;
void __iomem *io_base;
int rnb_gpio;
- const uint32_t *wait_pattern;
- const uint32_t *wait_write;
- int chip_delay;
};
#define to_fsl_upm_nand(mtd) container_of(mtd, struct fsl_upm_nand, mtd)
@@ -89,8 +86,7 @@ static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
fsl_upm_run_pattern(&fun->upm, fun->io_base, cmd);
- if (fun->wait_pattern)
- fun_wait_rnb(fun);
+ fun_wait_rnb(fun);
}
static uint8_t fun_read_byte(struct mtd_info *mtd)
@@ -116,14 +112,16 @@ static void fun_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
for (i = 0; i < len; i++) {
out_8(fun->chip.IO_ADDR_W, buf[i]);
- if (fun->wait_write)
- fun_wait_rnb(fun);
+ fun_wait_rnb(fun);
}
}
-static int __devinit fun_chip_init(struct fsl_upm_nand *fun)
+static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
+ const struct device_node *upm_np,
+ const struct resource *io_res)
{
int ret;
+ struct device_node *flash_np;
#ifdef CONFIG_MTD_PARTITIONS
static const char *part_types[] = { "cmdlinepart", NULL, };
#endif
@@ -131,7 +129,7 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun)
fun->chip.IO_ADDR_R = fun->io_base;
fun->chip.IO_ADDR_W = fun->io_base;
fun->chip.cmd_ctrl = fun_cmd_ctrl;
- fun->chip.chip_delay = fun->chip_delay;
+ fun->chip.chip_delay = 50;
fun->chip.read_byte = fun_read_byte;
fun->chip.read_buf = fun_read_buf;
fun->chip.write_buf = fun_write_buf;
@@ -143,18 +141,42 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun)
fun->mtd.priv = &fun->chip;
fun->mtd.owner = THIS_MODULE;
+ flash_np = of_get_next_child(upm_np, NULL);
+ if (!flash_np)
+ return -ENODEV;
+
+ fun->mtd.name = kasprintf(GFP_KERNEL, "%x.%s", io_res->start,
+ flash_np->name);
+ if (!fun->mtd.name) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
ret = nand_scan(&fun->mtd, 1);
if (ret)
- return ret;
-
- fun->mtd.name = fun->dev->bus_id;
+ goto err;
#ifdef CONFIG_MTD_PARTITIONS
ret = parse_mtd_partitions(&fun->mtd, part_types, &fun->parts, 0);
+
+#ifdef CONFIG_MTD_OF_PARTS
+ if (ret <= 0) {
+ ret = of_mtd_parse_partitions(fun->dev, &fun->mtd,
+ flash_np, &fun->parts);
+ if (ret < 0) {
+ ret = -EINVAL;
+ goto err;
+ }
+ }
+#endif
if (ret > 0)
- return add_mtd_partitions(&fun->mtd, fun->parts, ret);
+ ret = add_mtd_partitions(&fun->mtd, fun->parts, ret);
+ else
#endif
- return add_mtd_device(&fun->mtd);
+ ret = add_mtd_device(&fun->mtd);
+err:
+ of_node_put(flash_np);
+ return ret;
}
static int __devinit fun_probe(struct of_device *ofdev,
@@ -220,17 +242,8 @@ static int __devinit fun_probe(struct of_device *ofdev,
fun->dev = &ofdev->dev;
fun->last_ctrl = NAND_CLE;
- fun->wait_pattern = of_get_property(ofdev->node, "fsl,wait-pattern",
- NULL);
- fun->wait_write = of_get_property(ofdev->node, "fsl,wait-write", NULL);
-
- prop = of_get_property(ofdev->node, "chip-delay", NULL);
- if (prop)
- fun->chip_delay = *prop;
- else
- fun->chip_delay = 50;
- ret = fun_chip_init(fun);
+ ret = fun_chip_init(fun, ofdev->node, &io_res);
if (ret)
goto err2;
@@ -251,6 +264,7 @@ static int __devexit fun_remove(struct of_device *ofdev)
struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev);
nand_release(&fun->mtd);
+ kfree(fun->mtd.name);
if (fun->rnb_gpio >= 0)
gpio_free(fun->rnb_gpio);
--
1.5.5.1
^ permalink raw reply related
* Re: FW: SKB corruption on heavy traffic
From: Gerhard Pircher @ 2008-04-30 12:25 UTC (permalink / raw)
To: Franca, Jose (NSN - PT/Portugal - MiniMD), Scott Wood
Cc: linuxppc-dev, linuxppc-embedded
In-Reply-To: <56DEE2D3217CD946B290399093C8FA7C212E48@PTLIEXC001.nsn-intra.net>
Hi,
I think I have the same problem here with all versions of the 2.6.x kernel
series (tested with kernel v2.6.8/14/16/18/25 on a PPC7455 machine with
different PCI network cards by transferring a big file over NFS/SCP). Data
corruption occurs under high load, but I don't get any kernel oops.
regards,
Gerhard
-------- Original-Nachricht --------
> Datum: Wed, 30 Apr 2008 10:07:15 +0100
> Von: "Franca, Jose (NSN - PT/Portugal - MiniMD)" <jose.franca@nsn.com>
> An: linuxppc-dev@ozlabs.org, linuxppc-embedded@ozlabs.org
> Betreff: FW: SKB corruption on heavy traffic
> >From our latest debugs we found that the problem occurs mainly on skbuff
> code. After some variable time kfree or kalloc result in kernel oops.
>
> -----Original Message-----
> From: Franca, Jose (NSN - PT/Portugal - MiniMD)
> Sent: quarta-feira, 30 de Abril de 2008 9:44
> To: 'ext Scott Wood'
> Cc:
> Subject: RE: SKB corruption on heavy traffic
>
> Hello!
>
> Thank you for replying!
> It't quite dificult to say if the problem exists without our
> changes, since the all software is dependent on this changes so to work
> with the hardware. I can't answer to that right now on that, but I forgot
> to add one thing: we have ring buffer full problems on our fcc_enet
> driver from time to time. So, I think the problem could be on linux
> configurations (related to hw) because there is a lot of posts on the web
> related to problems similar to this (none of them has really solved the
> bottom problem).
>
> Regards,
> Filipe
>
> -----Original Message-----
> From: ext Scott Wood [mailto:scottwood@freescale.com]
> Sent: terça-feira, 29 de Abril de 2008 20:15
> To: Franca, Jose (NSN - PT/Portugal - MiniMD)
> Cc: linuxppc-dev@ozlabs.org; linuxppc-embedded@ozlabs.org
> Subject: Re: SKB corruption on heavy traffic
>
> On Tue, Apr 29, 2008 at 07:39:07PM +0100, Franca, Jose (NSN - PT/Portugal
> - MiniMD) wrote:
> > We are developing a MPC8247 based telecom board (512MB), using
> > linux 2.4 with some proprietary changes on IP stack and we are facing
> > some problems when we have heavy traffic on our Ethernet interfaces...
>
> Do you see these problems without the proprietary changes, and with a
> current kernel?
>
> -Scott
--
Psst! Geheimtipp: Online Games kostenlos spielen bei den GMX Free Games!
http://games.entertainment.gmx.net/de/entertainment/games/free
^ 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