PowerPC platform only supports ZONE_DMA zone for 64bit kernel, so all the
memory will be put into this zone. If the memory size is greater than
the device's DMA capability and device uses dma_alloc_coherent to allocate
memory, it will get an address which is over the device's DMA addressing,
the device will fail.
So we split the memory to two zones: zone ZONE_DMA32 & ZONE_NORMAL, since
we already allocate PCICSRBAR/PEXCSRBAR right below the 4G boundary (if the
lowest PCI address is above 4G), so we constrain the DMA zone ZONE_DMA32
to 2GB, also, we clear flag __GFP_DMA & __GFP_DMA32 and set __GFP_DMA32 only
if the device's dma_mask < total memory size. By doing this, devices which
cannot DMA all the memory will be limited to ZONE_DMA32, but devices which
can DMA all the memory will not be affected by this limitation.
Signed-off-by: Shaohui Xie <redacted>
Signed-off-by: Mingkai Hu <redacted>
Signed-off-by: Chen Yuanquan <redacted>
---
changes for v2:
1. use a config option for using two zones (ZONE_DMA32 & ZONE_NORMAL) in
freescale 64 bit kernel.
arch/powerpc/Kconfig | 3 +++
arch/powerpc/kernel/dma.c | 15 +++++++++++++++
arch/powerpc/mm/mem.c | 4 ++++
3 files changed, 22 insertions(+), 0 deletions(-)
From: Kumar Gala <hidden> Date: 2012-08-30 20:50:02
On Aug 24, 2012, at 5:50 AM, Shaohui Xie wrote:
PowerPC platform only supports ZONE_DMA zone for 64bit kernel, so all =
the
memory will be put into this zone. If the memory size is greater than
the device's DMA capability and device uses dma_alloc_coherent to =
allocate
memory, it will get an address which is over the device's DMA =
addressing,
the device will fail.
=20
So we split the memory to two zones: zone ZONE_DMA32 & ZONE_NORMAL, =
since
we already allocate PCICSRBAR/PEXCSRBAR right below the 4G boundary =
(if the
lowest PCI address is above 4G), so we constrain the DMA zone =
ZONE_DMA32
to 2GB, also, we clear flag __GFP_DMA & __GFP_DMA32 and set =
__GFP_DMA32 only
if the device's dma_mask < total memory size. By doing this, devices =
which
cannot DMA all the memory will be limited to ZONE_DMA32, but devices =
which
can DMA all the memory will not be affected by this limitation.
=20
Signed-off-by: Shaohui Xie <redacted>
Signed-off-by: Mingkai Hu <redacted>
Signed-off-by: Chen Yuanquan <redacted>
---
changes for v2:
1. use a config option for using two zones (ZONE_DMA32 & ZONE_NORMAL) =
#else
struct page *page;
int node =3D dev_to_node(dev);
+#ifdef CONFIG_ZONE_DMA32
+ phys_addr_t top_ram_pfn =3D memblock_end_of_DRAM();
=20
+ /*
+ * check for crappy device which has dma_mask < ZONE_DMA, and
+ * we are not going to support it, just warn and fail.
+ */
+ if (*dev->dma_mask < DMA_BIT_MASK(31)) {
+ dev_err(dev, "Unsupported dma_mask 0x%llx\n", =
*dev->dma_mask);
quoted hunk
+ return NULL;
+ }
/* ignore region specifiers */
+ flag &=3D ~(__GFP_HIGHMEM | __GFP_DMA | __GFP_DMA32);
+ if (*dev->dma_mask < top_ram_pfn - 1)
+ flag |=3D __GFP_DMA32;
+#else
flag &=3D ~(__GFP_HIGHMEM);
+#endif
=20
page =3D alloc_pages_node(node, flag, get_order(size));
if (page =3D=3D NULL)
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2012-09-09 23:38:01
On Thu, 2012-08-30 at 15:49 -0500, Kumar Gala wrote:
On Aug 24, 2012, at 5:50 AM, Shaohui Xie wrote:
quoted
PowerPC platform only supports ZONE_DMA zone for 64bit kernel, so all the
memory will be put into this zone. If the memory size is greater than
the device's DMA capability and device uses dma_alloc_coherent to allocate
memory, it will get an address which is over the device's DMA addressing,
the device will fail.
So we split the memory to two zones: zone ZONE_DMA32 & ZONE_NORMAL, since
we already allocate PCICSRBAR/PEXCSRBAR right below the 4G boundary (if the
lowest PCI address is above 4G), so we constrain the DMA zone ZONE_DMA32
to 2GB, also, we clear flag __GFP_DMA & __GFP_DMA32 and set __GFP_DMA32 only
if the device's dma_mask < total memory size. By doing this, devices which
cannot DMA all the memory will be limited to ZONE_DMA32, but devices which
can DMA all the memory will not be affected by this limitation.
Signed-off-by: Shaohui Xie <redacted>
Signed-off-by: Mingkai Hu <redacted>
Signed-off-by: Chen Yuanquan <redacted>
---
changes for v2:
1. use a config option for using two zones (ZONE_DMA32 & ZONE_NORMAL) in
freescale 64 bit kernel.
There must have been a misunderstanding. I think this should be a
runtime choice, possibly by the platform code. Any reason that can't be
done ?
Also how does Intel do it ? Do they have iommu and ZONE_DMA32 co-exist ?
Cheers,
Ben.
From: Kumar Gala <hidden> Date: 2012-09-20 13:36:44
On Sep 20, 2012, at 5:14 AM, Xie Shaohui-B21989 wrote:
quoted
quoted
On Thu, 2012-08-30 at 15:49 -0500, Kumar Gala wrote:
quoted
On Aug 24, 2012, at 5:50 AM, Shaohui Xie wrote:
=20
quoted
PowerPC platform only supports ZONE_DMA zone for 64bit kernel, so
all the memory will be put into this zone. If the memory size is
greater than the device's DMA capability and device uses
dma_alloc_coherent to allocate memory, it will get an address
which is over the device's DMA addressing, the device will fail.
=20
So we split the memory to two zones: zone ZONE_DMA32 &
ZONE_NORMAL, since we already allocate PCICSRBAR/PEXCSRBAR right
below the 4G boundary (if the lowest PCI address is above 4G), so
we constrain the DMA zone ZONE_DMA32 to 2GB, also, we clear flag
__GFP_DMA &
__GFP_DMA32 and set __GFP_DMA32 only if the device's dma_mask <
total memory size. By doing this, devices which cannot DMA all the
memory will be limited to ZONE_DMA32, but devices which can DMA
all
the memory will not be affected by this limitation.
quoted
quoted
=20
Signed-off-by: Shaohui Xie <redacted>
Signed-off-by: Mingkai Hu <redacted>
Signed-off-by: Chen Yuanquan <redacted>
---
changes for v2:
1. use a config option for using two zones (ZONE_DMA32 &
ZONE_NORMAL) in freescale 64 bit kernel.
=20
=20
There must have been a misunderstanding. I think this should be a
runtime choice, possibly by the platform code. Any reason that can't =
be
quoted
done ?
quoted
=20
[S.H] Do you mean this:
=20
phys_addr_t platform_dma_size (maybe a default value should be used, =
then
quoted
platform code will change it)
=20
if (top_of_ram > platform_dma_size)
max_zone_pfns[ZONE_DMA] =3D platform_dma_size >> PAGE_SHIFT; =
[S.H] below are codes in Intel:
=20
403 void __init zone_sizes_init(void)
404 {
405 unsigned long max_zone_pfns[MAX_NR_ZONES];
406
407 memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
408
409 #ifdef CONFIG_ZONE_DMA
410 max_zone_pfns[ZONE_DMA] =3D MAX_DMA_PFN;
411 #endif
412 #ifdef CONFIG_ZONE_DMA32
413 max_zone_pfns[ZONE_DMA32] =3D MAX_DMA32_PFN;
414 #endif
415 max_zone_pfns[ZONE_NORMAL] =3D max_low_pfn;
416 #ifdef CONFIG_HIGHMEM
417 max_zone_pfns[ZONE_HIGHMEM] =3D max_pfn;
418 #endif
419
=20
For x86_64, there is no CONFIG_HIGHMEM, so there will be three zones:
ZONE_DMA/ZONE_DMA32/ZONE_NORMAL.
=20
[S.H] Hello, Ben,
=20
I have some questions, though I'm still expecting your comments.
PPC does not have ZONE_DMA32 by default, if we want to use it, we need =
to add "config ZONE_DMA32" in Kconfig first.
If setting multiple zones without ZONE_DMA, kmalloc in =
"include/linux/slab_def.h" will fail if it uses flag GFP_DMA.
For the runtime choice in 64-bit kernel, what exactly multiple zones =
should be used?
"ZONE_DMA & ZONE_NORMAL" or "ZONE_DMA & ZONE_DMA32 & ZONE_NORMAL"?
Then what the size should be set for them respectively?
=20
Please comment, Thanks!
I think Ben is saying that Kconfig would enable ZONE_DMA32 for all =
PPC64, but make it runtime/per platform how we setup the zone's such =
that either ZONE_DMA32 is set to MAX_DMA32_PFN or it set to same value =
as ZONE_DMA.
However that's just a guess.
- k=
From: Kumar Gala <hidden> Date: 2012-09-24 12:31:56
On Sep 20, 2012, at 8:36 AM, Kumar Gala wrote:
=20
On Sep 20, 2012, at 5:14 AM, Xie Shaohui-B21989 wrote:
=20
quoted
quoted
quoted
On Thu, 2012-08-30 at 15:49 -0500, Kumar Gala wrote:
quoted
On Aug 24, 2012, at 5:50 AM, Shaohui Xie wrote:
=20
quoted
PowerPC platform only supports ZONE_DMA zone for 64bit kernel, so
all the memory will be put into this zone. If the memory size is
greater than the device's DMA capability and device uses
dma_alloc_coherent to allocate memory, it will get an address
which is over the device's DMA addressing, the device will fail.
=20
So we split the memory to two zones: zone ZONE_DMA32 &
ZONE_NORMAL, since we already allocate PCICSRBAR/PEXCSRBAR right
below the 4G boundary (if the lowest PCI address is above 4G), so
we constrain the DMA zone ZONE_DMA32 to 2GB, also, we clear flag
__GFP_DMA &
__GFP_DMA32 and set __GFP_DMA32 only if the device's dma_mask <
total memory size. By doing this, devices which cannot DMA all =
the
quoted
quoted
quoted
quoted
quoted
memory will be limited to ZONE_DMA32, but devices which can DMA
all
the memory will not be affected by this limitation.
quoted
quoted
=20
Signed-off-by: Shaohui Xie <redacted>
Signed-off-by: Mingkai Hu <redacted>
Signed-off-by: Chen Yuanquan <redacted>
---
changes for v2:
1. use a config option for using two zones (ZONE_DMA32 &
ZONE_NORMAL) in freescale 64 bit kernel.
=20
=20
There must have been a misunderstanding. I think this should be a
runtime choice, possibly by the platform code. Any reason that =
can't be
quoted
quoted
done ?
quoted
=20
[S.H] Do you mean this:
=20
phys_addr_t platform_dma_size (maybe a default value should be used, =
then
quoted
quoted
platform code will change it)
=20
if (top_of_ram > platform_dma_size)
max_zone_pfns[ZONE_DMA] =3D platform_dma_size >> PAGE_SHIFT; =
[S.H] below are codes in Intel:
=20
403 void __init zone_sizes_init(void)
404 {
405 unsigned long max_zone_pfns[MAX_NR_ZONES];
406
407 memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
408
409 #ifdef CONFIG_ZONE_DMA
410 max_zone_pfns[ZONE_DMA] =3D MAX_DMA_PFN;
411 #endif
412 #ifdef CONFIG_ZONE_DMA32
413 max_zone_pfns[ZONE_DMA32] =3D MAX_DMA32_PFN;
414 #endif
415 max_zone_pfns[ZONE_NORMAL] =3D max_low_pfn;
416 #ifdef CONFIG_HIGHMEM
417 max_zone_pfns[ZONE_HIGHMEM] =3D max_pfn;
418 #endif
419
=20
For x86_64, there is no CONFIG_HIGHMEM, so there will be three =
zones:
quoted
quoted
ZONE_DMA/ZONE_DMA32/ZONE_NORMAL.
=20
[S.H] Hello, Ben,
=20
I have some questions, though I'm still expecting your comments.
PPC does not have ZONE_DMA32 by default, if we want to use it, we =
need to add "config ZONE_DMA32" in Kconfig first.
quoted
If setting multiple zones without ZONE_DMA, kmalloc in =
"include/linux/slab_def.h" will fail if it uses flag GFP_DMA.
quoted
For the runtime choice in 64-bit kernel, what exactly multiple zones =
should be used?
quoted
"ZONE_DMA & ZONE_NORMAL" or "ZONE_DMA & ZONE_DMA32 & ZONE_NORMAL"?
Then what the size should be set for them respectively?
=20
Please comment, Thanks!
=20
I think Ben is saying that Kconfig would enable ZONE_DMA32 for all =
PPC64, but make it runtime/per platform how we setup the zone's such =
that either ZONE_DMA32 is set to MAX_DMA32_PFN or it set to same value =
as ZONE_DMA.
=20
However that's just a guess.
Ben,
Can you help clarify your thoughts here.
thanks
- k=
From: Kumar Gala <hidden> Date: 2012-09-27 12:37:21
On Sep 24, 2012, at 7:31 AM, Kumar Gala wrote:
=20
On Sep 20, 2012, at 8:36 AM, Kumar Gala wrote:
=20
quoted
=20
On Sep 20, 2012, at 5:14 AM, Xie Shaohui-B21989 wrote:
=20
quoted
quoted
quoted
On Thu, 2012-08-30 at 15:49 -0500, Kumar Gala wrote:
quoted
On Aug 24, 2012, at 5:50 AM, Shaohui Xie wrote:
=20
quoted
PowerPC platform only supports ZONE_DMA zone for 64bit kernel, =
so
quoted
quoted
quoted
quoted
quoted
quoted
all the memory will be put into this zone. If the memory size is
greater than the device's DMA capability and device uses
dma_alloc_coherent to allocate memory, it will get an address
which is over the device's DMA addressing, the device will fail.
=20
So we split the memory to two zones: zone ZONE_DMA32 &
ZONE_NORMAL, since we already allocate PCICSRBAR/PEXCSRBAR right
below the 4G boundary (if the lowest PCI address is above 4G), =
so
quoted
quoted
quoted
quoted
quoted
quoted
we constrain the DMA zone ZONE_DMA32 to 2GB, also, we clear flag
__GFP_DMA &
__GFP_DMA32 and set __GFP_DMA32 only if the device's dma_mask <
total memory size. By doing this, devices which cannot DMA all =
the
quoted
quoted
quoted
quoted
quoted
quoted
memory will be limited to ZONE_DMA32, but devices which can DMA
all
the memory will not be affected by this limitation.
quoted
quoted
=20
Signed-off-by: Shaohui Xie <redacted>
Signed-off-by: Mingkai Hu <redacted>
Signed-off-by: Chen Yuanquan <redacted>
---
changes for v2:
1. use a config option for using two zones (ZONE_DMA32 &
ZONE_NORMAL) in freescale 64 bit kernel.
=20
=20
There must have been a misunderstanding. I think this should be a
runtime choice, possibly by the platform code. Any reason that =
can't be
quoted
quoted
quoted
done ?
quoted
=20
[S.H] Do you mean this:
=20
phys_addr_t platform_dma_size (maybe a default value should be =
used, then
quoted
quoted
quoted
platform code will change it)
=20
if (top_of_ram > platform_dma_size)
max_zone_pfns[ZONE_DMA] =3D platform_dma_size >> PAGE_SHIFT; =
[S.H] below are codes in Intel:
=20
403 void __init zone_sizes_init(void)
404 {
405 unsigned long max_zone_pfns[MAX_NR_ZONES];
406
407 memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
408
409 #ifdef CONFIG_ZONE_DMA
410 max_zone_pfns[ZONE_DMA] =3D MAX_DMA_PFN;
411 #endif
412 #ifdef CONFIG_ZONE_DMA32
413 max_zone_pfns[ZONE_DMA32] =3D MAX_DMA32_PFN;
414 #endif
415 max_zone_pfns[ZONE_NORMAL] =3D max_low_pfn;
416 #ifdef CONFIG_HIGHMEM
417 max_zone_pfns[ZONE_HIGHMEM] =3D max_pfn;
418 #endif
419
=20
For x86_64, there is no CONFIG_HIGHMEM, so there will be three =
zones:
quoted
quoted
quoted
ZONE_DMA/ZONE_DMA32/ZONE_NORMAL.
=20
[S.H] Hello, Ben,
=20
I have some questions, though I'm still expecting your comments.
PPC does not have ZONE_DMA32 by default, if we want to use it, we =
need to add "config ZONE_DMA32" in Kconfig first.
quoted
quoted
If setting multiple zones without ZONE_DMA, kmalloc in =
"include/linux/slab_def.h" will fail if it uses flag GFP_DMA.
quoted
quoted
For the runtime choice in 64-bit kernel, what exactly multiple zones =
should be used?
quoted
quoted
"ZONE_DMA & ZONE_NORMAL" or "ZONE_DMA & ZONE_DMA32 & ZONE_NORMAL"?
Then what the size should be set for them respectively?
=20
Please comment, Thanks!
=20
I think Ben is saying that Kconfig would enable ZONE_DMA32 for all =
PPC64, but make it runtime/per platform how we setup the zone's such =
that either ZONE_DMA32 is set to MAX_DMA32_PFN or it set to same value =
as ZONE_DMA.
quoted
=20
However that's just a guess.
=20
Ben,
=20
Can you help clarify your thoughts here.
=20
thanks