From: Marcelo Tosatti <marcelo.tosatti@cyclades•com>
To: Dan Malek <dan@embeddededge•com>,
linux-ppc-embedded <linuxppc-embedded@ozlabs•org>
Subject: [PATCH] 8xx: fix usage of pinned 8Mbyte TLB entries
Date: Thu, 5 May 2005 14:20:35 -0300 [thread overview]
Message-ID: <20050505172035.GB3339@logos.cnet> (raw)
Hi,
As can be seen by BDI output from previous messages, the 8Mbyte TLB
pinned entry is not being actually used.
The manual says, in section "9.3.2 Translation Enabled" (MMU section):
"A TLB hit in multiple entries is avoided when a TLB is being reloaded.
When TLB logic detects that a new effective page number (EPN) overlaps
one in the TLB (when taking into account pages sizes, subpage validity,
user/supervisor state, address space ID,and the SH values of the TLB
entries), the new EPN is written and the old one is invalidated."
The following patch changes "mmu_mapin_ram" (hook used by mapin_ram), to
begin creation of pagetables after the first 8Megs, preserving the
8Mbyte TLB entry.
This changes the assumption that DMA allocations can start at the first
kernel address, given that those need to be marked uncached due to DMA
cache coherency issues.
The bootmem allocator, used to allocate DMA regions at bootup,uses
MAX_DMA_ADDRESS as its goal parameter. The algorithm searches for
pages above 'goal' first, for then to search lower pages.
So change MAX_DMA_ADDRESS to avoid bootmem collisions with lower 8Megs.
Drivers which allocate directly from __get_free_pages() and tweak the
pte's directly also need to be fixed. For example
Panto: FEC currently does
mem_addr = __get_free_page(GFP_KERNEL);
cbd_base = (cbd_t *)mem_addr;
/* XXX: missing check for allocation failure */
fec_uncache(mem_addr);
That needs to be changed to avoid the lower 8Megs.
We are still using v2.4 FEC driver, so this fixed it:
// mem_addr = __get_free_page(GFP_KERNEL);
mem_addr = dma_alloc_coherent(NULL, PAGE_SIZE, &physaddr,
GFP_KERNEL);
cbd_base = (cbd_t *)mem_addr;
Allocateing from the coherent memory DMA region. Which sits at, I suppose,
after initial 8Megs in all configurations (should be always).
TLB miss stat output now looks like this on 2.6.11:
[root@CAS root]# time dd if=/dev/zero of=file bs=4k count=3840
3840+0 records in
3840+0 records out
real 0m3.723s
user 0m0.150s
sys 0m3.560s
I-TLB userspace misses: 1904
I-TLB kernel misses: 0
D-TLB userspace misses: 160272
D-TLB kernel misses: 135098
instead of
[root@CAS root]# time dd if=/dev/zero of=file bs=4k count=3840
3840+0 records in
3840+0 records out
real 0m4.328s
user 0m0.128s
sys 0m4.170s
I-TLB userspace misses: 162651
I-TLB kernel misses: 138100
D-TLB userspace misses: 255294
D-TLB kernel misses: 238129
Dan: Maybe the pinning should be mandatory, getting rid of CONFIG_PIN_TLB?
diff -Nur --show-c-function linux-2.6.12-rc3.orig/arch/ppc/mm/mmu_decl.h linux-2.6.12-rc3/arch/ppc/mm/mmu_decl.h
--- linux-2.6.12-rc3.orig/arch/ppc/mm/mmu_decl.h 2005-05-05 17:21:55.000000000 -0300
+++ linux-2.6.12-rc3/arch/ppc/mm/mmu_decl.h 2005-05-05 17:31:20.000000000 -0300
@@ -49,7 +49,8 @@ extern unsigned long Hash_size, Hash_mas
#if defined(CONFIG_8xx)
#define flush_HPTE(X, va, pg) _tlbie(va)
#define MMU_init_hw() do { } while(0)
-#define mmu_mapin_ram() (0UL)
+/* There is a 8Mbyte pinned TLB entry covering the first 8Megs, so skip it */
+#define mmu_mapin_ram() (0x00800000)
#elif defined(CONFIG_4xx)
#define flush_HPTE(X, va, pg) _tlbie(va)
diff -Nur --show-c-function linux-2.6.12-rc3.orig/include/asm-ppc/dma.h linux-2.6.12-rc3/include/asm-ppc/dma.h
--- linux-2.6.12-rc3.orig/include/asm-ppc/dma.h 2005-05-05 17:21:59.000000000 -0300
+++ linux-2.6.12-rc3/include/asm-ppc/dma.h 2005-05-05 17:53:07.000000000 -0300
@@ -32,9 +32,16 @@
#define MAX_DMA_CHANNELS 8
#endif
+#ifdef CONFIG_8xx
+/* DMA pages are uncached on 8xx due to cache coherency issues.
+* Avoid bootmem from trying to allocate pages from first 8Megs.
+*/
+#define MAX_DMA_ADDRESS (KERNELBASE + 0x01000000)
+#else
/* The maximum address that we can perform a DMA transfer to on this platform */
/* Doesn't really apply... */
#define MAX_DMA_ADDRESS 0xFFFFFFFF
+#endif
/* in arch/ppc/kernel/setup.c -- Cort */
extern unsigned long DMA_MODE_WRITE, DMA_MODE_READ;
next reply other threads:[~2005-05-05 21:51 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-05-05 17:20 Marcelo Tosatti [this message]
2005-05-06 13:04 ` [PATCH] 8xx: fix usage of pinned 8Mbyte TLB entries Jason McMullan
2005-05-06 11:39 ` Marcelo Tosatti
2005-05-06 16:43 ` Dan Malek
2005-05-06 13:38 ` Marcelo Tosatti
2005-05-06 22:49 ` Dan Malek
2005-05-06 20:03 ` Marcelo Tosatti
2005-05-07 3:09 ` Dan Malek
2005-05-06 23:05 ` Marcelo Tosatti
2005-05-07 4:39 ` Dan Malek
2005-05-07 5:16 ` Dan Malek
2005-05-07 13:16 ` Marcelo Tosatti
2005-05-07 20:02 ` Dan Malek
2005-05-07 15:47 ` Marcelo Tosatti
2005-05-07 14:05 ` Marcelo Tosatti
2005-05-09 6:09 ` Pantelis Antoniou
2005-05-07 14:59 ` Wolfgang Denk
2005-05-07 5:27 ` Dan Malek
2005-05-07 5:55 ` Dan Malek
2005-05-06 23:10 ` Dan Malek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20050505172035.GB3339@logos.cnet \
--to=marcelo.tosatti@cyclades$(echo .)com \
--cc=dan@embeddededge$(echo .)com \
--cc=linuxppc-embedded@ozlabs$(echo .)org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox