From: Andrew Morton <akpm@osdl.org>
To: Andi Kleen <ak@suse.de>
Cc: kiran@scalex86.org, linux-kernel@vger.kernel.org,
discuss@x86-64.org, tglx@linutronix.de, torvalds@osdl.org,
shai@scalex86.org
Subject: Re: x86_64: 2.6.14-rc4 swiotlb broken
Date: Mon, 17 Oct 2005 13:44:01 -0700 [thread overview]
Message-ID: <20051017134401.3b0d861d.akpm@osdl.org> (raw)
In-Reply-To: <200510171743.47926.ak@suse.de>
Andi Kleen <ak@suse.de> wrote:
>
> On Monday 17 October 2005 17:30, Ravikiran G Thirumalai wrote:
>
> > Yes, I just saw Yasunori-san's patch. Would that be merged for 2.6.14?
>
> I think both are too risky at this point.
>
Maybe.
There seem to be a lot of proposed solutions floating about and I fear that
different people will try to fix this in different ways. Do we all agree
that this patch is the correct solution to this problem, or is something
more needed?
From: Yasunori Goto <y-goto@jp.fujitsu.com>
This is a patch to guarantee that alloc_bootmem_low() allocate DMA area.
Current alloc_bootmem_low() is just specify "goal=0". And it is used for
__alloc_bootmem_core() to decide which address is better. However, there
is no guarantee that __alloc_bootmem_core() allocate DMA area when goal=0
is specified. Even if there is no DMA'ble area in searching node, it
allocates higher address than MAX_DMA_ADDRESS.
__alloc_bootmem_core() is called by order of for_each_pgdat() in
__alloc_bootmem(). So, if first node (node_id = 0) has DMA'ble area, no
trouble will occur. However, our new Itanium2 server can change which node
has lower address. And panic really occurred on it. The message was
"bounce buffer is not DMA'ble" in swiothl_map_single().
To avoid this panic, following patch confirms allocated area, and retry if
it is not in DMA. I tested this patch on my Tiger 4 and our new server.
Signed-off-by Yasunori Goto <y-goto@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---
include/linux/bootmem.h | 16 ++++++++++++----
mm/bootmem.c | 43 +++++++++++++++++++++++++++++++++++++++----
2 files changed, 51 insertions(+), 8 deletions(-)
diff -puN include/linux/bootmem.h~guarantee-dma-area-for-alloc_bootmem_low include/linux/bootmem.h
--- devel/include/linux/bootmem.h~guarantee-dma-area-for-alloc_bootmem_low 2005-10-11 00:34:32.000000000 -0700
+++ devel-akpm/include/linux/bootmem.h 2005-10-11 00:34:32.000000000 -0700
@@ -40,6 +40,14 @@ typedef struct bootmem_data {
* up searching */
} bootmem_data_t;
+static inline unsigned long max_dma_physaddr(void)
+{
+
+ if (MAX_DMA_ADDRESS == ~0UL)
+ return MAX_DMA_ADDRESS;
+ return __pa(MAX_DMA_ADDRESS);
+}
+
extern unsigned long __init bootmem_bootmap_pages (unsigned long);
extern unsigned long __init init_bootmem (unsigned long addr, unsigned long memend);
extern void __init free_bootmem (unsigned long addr, unsigned long size);
@@ -47,11 +55,11 @@ extern void * __init __alloc_bootmem (un
#ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE
extern void __init reserve_bootmem (unsigned long addr, unsigned long size);
#define alloc_bootmem(x) \
- __alloc_bootmem((x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
+ __alloc_bootmem((x), SMP_CACHE_BYTES, max_dma_physaddr())
#define alloc_bootmem_low(x) \
__alloc_bootmem((x), SMP_CACHE_BYTES, 0)
#define alloc_bootmem_pages(x) \
- __alloc_bootmem((x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
+ __alloc_bootmem((x), PAGE_SIZE, max_dma_physaddr())
#define alloc_bootmem_low_pages(x) \
__alloc_bootmem((x), PAGE_SIZE, 0)
#endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */
@@ -64,9 +72,9 @@ extern unsigned long __init free_all_boo
extern void * __init __alloc_bootmem_node (pg_data_t *pgdat, unsigned long size, unsigned long align, unsigned long goal);
#ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE
#define alloc_bootmem_node(pgdat, x) \
- __alloc_bootmem_node((pgdat), (x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
+ __alloc_bootmem_node((pgdat), (x), SMP_CACHE_BYTES, max_dma_physaddr())
#define alloc_bootmem_pages_node(pgdat, x) \
- __alloc_bootmem_node((pgdat), (x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
+ __alloc_bootmem_node((pgdat), (x), PAGE_SIZE, max_dma_physaddr())
#define alloc_bootmem_low_pages_node(pgdat, x) \
__alloc_bootmem_node((pgdat), (x), PAGE_SIZE, 0)
#endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */
diff -puN mm/bootmem.c~guarantee-dma-area-for-alloc_bootmem_low mm/bootmem.c
--- devel/mm/bootmem.c~guarantee-dma-area-for-alloc_bootmem_low 2005-10-11 00:34:32.000000000 -0700
+++ devel-akpm/mm/bootmem.c 2005-10-11 00:34:32.000000000 -0700
@@ -382,19 +382,54 @@ unsigned long __init free_all_bootmem (v
return(free_all_bootmem_core(NODE_DATA(0)));
}
+static int __init is_dma_required(unsigned long goal)
+{
+ return goal < max_dma_physaddr() ? 1 : 0;
+}
+
+static int __init unmatch_dma_required(void *ptr, unsigned long goal)
+{
+
+ if(is_dma_required(goal) && (unsigned long)ptr >= MAX_DMA_ADDRESS)
+ return 1;
+
+ return 0;
+}
+
void * __init __alloc_bootmem (unsigned long size, unsigned long align, unsigned long goal)
{
pg_data_t *pgdat = pgdat_list;
void *ptr;
+ int retried = 0;
+
+retry:
+ for_each_pgdat(pgdat){
- for_each_pgdat(pgdat)
- if ((ptr = __alloc_bootmem_core(pgdat->bdata, size,
- align, goal)))
- return(ptr);
+ ptr = __alloc_bootmem_core(pgdat->bdata, size,
+ align, goal);
+ if (!ptr)
+ continue;
+
+ if (unmatch_dma_required(ptr, goal) && !retried){
+ /* DMA is required, but normal area is allocated.
+ Other node might have DMA, should try it. */
+ free_bootmem_core(pgdat->bdata, virt_to_phys(ptr), size);
+ continue;
+ }
+
+ return ptr;
+ }
/*
* Whoops, we cannot satisfy the allocation request.
*/
+ if (is_dma_required(goal) && !retried){
+ printk(KERN_WARNING "bootmem alloc DMA of %lu bytes failed, retry normal area!\n", size);
+ dump_stack();
+ retried++;
+ goto retry;
+ }
+
printk(KERN_ALERT "bootmem alloc of %lu bytes failed!\n", size);
panic("Out of memory");
return NULL;
_
next prev parent reply other threads:[~2005-10-17 20:44 UTC|newest]
Thread overview: 64+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-10-17 9:36 Ravikiran G Thirumalai
2005-10-17 9:50 ` Andrew Morton
2005-10-17 9:53 ` Andi Kleen
2005-10-17 10:54 ` Yasunori Goto
2005-10-17 15:27 ` Linus Torvalds
2005-10-17 15:37 ` Ravikiran G Thirumalai
2005-10-17 15:40 ` Andi Kleen
2005-10-17 15:56 ` Muli Ben-Yehuda
2005-10-17 16:02 ` Andi Kleen
2005-10-17 18:53 ` [discuss] " Russell King
2005-10-17 16:02 ` Linus Torvalds
2005-10-17 16:26 ` Andi Kleen
2005-10-17 16:42 ` Linus Torvalds
2005-10-17 17:09 ` Andi Kleen
2005-10-17 17:52 ` Ravikiran G Thirumalai
2005-10-17 18:08 ` [discuss] " Andi Kleen
2005-10-17 18:27 ` Muli Ben-Yehuda
2005-10-17 18:32 ` Andi Kleen
2005-10-17 18:45 ` Muli Ben-Yehuda
2005-10-17 19:04 ` Linus Torvalds
2005-10-17 19:09 ` Andi Kleen
2005-10-17 19:15 ` Arjan van de Ven
2005-10-17 19:47 ` Ravikiran G Thirumalai
2005-10-17 23:50 ` David Lang
2005-10-18 2:29 ` Yasunori Goto
2005-10-18 3:20 ` Ravikiran G Thirumalai
2005-10-18 4:28 ` Yasunori Goto
2005-10-18 6:13 ` Ravikiran G Thirumalai
2005-10-18 10:09 ` Yasunori Goto
2005-10-18 18:51 ` Ravikiran G Thirumalai
2005-10-19 17:18 ` Jon Mason
2005-10-20 7:27 ` Andi Kleen
2005-10-17 18:38 ` Ravikiran G Thirumalai
2005-10-17 18:20 ` Christoph Lameter
2005-10-17 19:04 ` Alex Williamson
2005-10-17 19:26 ` Ravikiran G Thirumalai
2005-10-17 19:52 ` Alex Williamson
2005-10-17 15:30 ` Ravikiran G Thirumalai
2005-10-17 15:43 ` Andi Kleen
2005-10-17 20:44 ` Andrew Morton [this message]
2005-10-17 21:11 ` Linus Torvalds
2005-10-18 0:16 ` Ravikiran G Thirumalai
2005-10-18 8:23 ` Andi Kleen
2005-10-18 19:07 ` [discuss] " Ravikiran G Thirumalai
2005-10-18 15:48 ` Linus Torvalds
2005-10-18 15:50 ` Linus Torvalds
2005-10-18 19:54 ` [discuss] " Ravikiran G Thirumalai
2005-10-18 21:28 ` Alex Williamson
2005-10-18 21:53 ` Ravikiran G Thirumalai
2005-10-18 22:04 ` Alex Williamson
2005-10-18 22:37 ` Alex Williamson
2005-10-18 23:22 ` Ravikiran G Thirumalai
2005-10-19 1:22 ` Alex Williamson
2005-10-19 2:02 ` Alex Williamson
2005-10-19 12:47 ` Yasunori Goto
2005-10-19 14:19 ` Alex Williamson
2005-10-19 18:07 ` Ravikiran G Thirumalai
2005-10-19 20:45 ` Linus Torvalds
2005-10-19 22:52 ` Ravikiran G Thirumalai
2005-10-20 0:51 ` Yasunori Goto
2005-10-20 7:45 ` Andi Kleen
2005-10-18 22:47 ` Ravikiran G Thirumalai
2005-10-17 10:02 ` Muli Ben-Yehuda
2005-10-17 19:07 ` Tony Luck
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=20051017134401.3b0d861d.akpm@osdl.org \
--to=akpm@osdl.org \
--cc=ak@suse.de \
--cc=discuss@x86-64.org \
--cc=kiran@scalex86.org \
--cc=linux-kernel@vger.kernel.org \
--cc=shai@scalex86.org \
--cc=tglx@linutronix.de \
--cc=torvalds@osdl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
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
all inboxes | Powered by JetHome®