diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2009-12-15 06:47:56 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-12-15 07:01:57 -0500 |
commit | 186a25026c44d1bfa97671110ff14dcd0c99678e (patch) | |
tree | 363fa110d9f4a785abf26cd9979dd60c0ed92a99 /arch/x86/kernel/pci-swiotlb.c | |
parent | 873b5271f878a11729fb4602c6ce967d0ff81119 (diff) |
x86: Split swiotlb initialization into two stages
The commit f4780ca005404166cc40af77ef0e86132ab98a81 moves
swiotlb initialization before dma32_free_bootmem(). It's
supposed to fix a bug that the commit
75f1cdf1dda92cae037ec848ae63690d91913eac introduced, we
initialize SWIOTLB right after dma32_free_bootmem so we wrongly
steal memory area allocated for GART with broken BIOS earlier.
However, the above commit introduced another problem, which
likely breaks machines with huge amount of memory. Such a box
use the majority of DMA32_ZONE so there is no memory for
swiotlb.
With this patch, the x86 IOMMU initialization sequence are:
1. We set swiotlb to 1 in the case of (max_pfn > MAX_DMA32_PFN
&& !no_iommu). If swiotlb usage is forced by the boot option,
we go to the step 3 and finish (we don't try to detect IOMMUs).
2. We call the detection functions of all the IOMMUs. The
detection function sets x86_init.iommu.iommu_init to the IOMMU
initialization function (so we can avoid calling the
initialization functions of all the IOMMUs needlessly).
3. We initialize swiotlb (and set dma_ops to swiotlb_dma_ops) if
swiotlb is set to 1.
4. If the IOMMU initialization function doesn't need swiotlb
(e.g. the initialization is sucessful) then sets swiotlb to zero.
5. If we find that swiotlb is set to zero, we free swiotlb
resource.
Reported-by: Yinghai Lu <yinghai@kernel.org>
Reported-by: Roland Dreier <rdreier@cisco.com>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
LKML-Reference: <20091215204729A.fujita.tomonori@lab.ntt.co.jp>
Tested-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/pci-swiotlb.c')
-rw-r--r-- | arch/x86/kernel/pci-swiotlb.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c index e3c0a66b9e77..7d2829dde20e 100644 --- a/arch/x86/kernel/pci-swiotlb.c +++ b/arch/x86/kernel/pci-swiotlb.c | |||
@@ -43,12 +43,12 @@ static struct dma_map_ops swiotlb_dma_ops = { | |||
43 | }; | 43 | }; |
44 | 44 | ||
45 | /* | 45 | /* |
46 | * pci_swiotlb_init - initialize swiotlb if necessary | 46 | * pci_swiotlb_detect - set swiotlb to 1 if necessary |
47 | * | 47 | * |
48 | * This returns non-zero if we are forced to use swiotlb (by the boot | 48 | * This returns non-zero if we are forced to use swiotlb (by the boot |
49 | * option). | 49 | * option). |
50 | */ | 50 | */ |
51 | int __init pci_swiotlb_init(void) | 51 | int __init pci_swiotlb_detect(void) |
52 | { | 52 | { |
53 | int use_swiotlb = swiotlb | swiotlb_force; | 53 | int use_swiotlb = swiotlb | swiotlb_force; |
54 | 54 | ||
@@ -60,10 +60,13 @@ int __init pci_swiotlb_init(void) | |||
60 | if (swiotlb_force) | 60 | if (swiotlb_force) |
61 | swiotlb = 1; | 61 | swiotlb = 1; |
62 | 62 | ||
63 | return use_swiotlb; | ||
64 | } | ||
65 | |||
66 | void __init pci_swiotlb_init(void) | ||
67 | { | ||
63 | if (swiotlb) { | 68 | if (swiotlb) { |
64 | swiotlb_init(0); | 69 | swiotlb_init(0); |
65 | dma_ops = &swiotlb_dma_ops; | 70 | dma_ops = &swiotlb_dma_ops; |
66 | } | 71 | } |
67 | |||
68 | return use_swiotlb; | ||
69 | } | 72 | } |