diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 14 | ||||
-rw-r--r-- | arch/x86/kernel/setup.c | 21 | ||||
-rw-r--r-- | include/linux/swiotlb.h | 1 | ||||
-rw-r--r-- | lib/swiotlb.c | 19 |
4 files changed, 45 insertions, 10 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 4609e81dbc37..cff672da2486 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -596,9 +596,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
596 | is selected automatically. Check | 596 | is selected automatically. Check |
597 | Documentation/kdump/kdump.txt for further details. | 597 | Documentation/kdump/kdump.txt for further details. |
598 | 598 | ||
599 | crashkernel_low=size[KMG] | ||
600 | [KNL, x86] parts under 4G. | ||
601 | |||
602 | crashkernel=range1:size1[,range2:size2,...][@offset] | 599 | crashkernel=range1:size1[,range2:size2,...][@offset] |
603 | [KNL] Same as above, but depends on the memory | 600 | [KNL] Same as above, but depends on the memory |
604 | in the running system. The syntax of range is | 601 | in the running system. The syntax of range is |
@@ -606,6 +603,17 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
606 | a memory unit (amount[KMG]). See also | 603 | a memory unit (amount[KMG]). See also |
607 | Documentation/kdump/kdump.txt for an example. | 604 | Documentation/kdump/kdump.txt for an example. |
608 | 605 | ||
606 | crashkernel_low=size[KMG] | ||
607 | [KNL, x86_64] range under 4G. When crashkernel= is | ||
608 | passed, kernel allocate physical memory region | ||
609 | above 4G, that cause second kernel crash on system | ||
610 | that require some amount of low memory, e.g. swiotlb | ||
611 | requires at least 64M+32K low memory. Kernel would | ||
612 | try to allocate 72M below 4G automatically. | ||
613 | This one let user to specify own low range under 4G | ||
614 | for second kernel instead. | ||
615 | 0: to disable low allocation. | ||
616 | |||
609 | cs89x0_dma= [HW,NET] | 617 | cs89x0_dma= [HW,NET] |
610 | Format: <dma> | 618 | Format: <dma> |
611 | 619 | ||
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 90d8cc930f5e..12349202cae7 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -521,19 +521,34 @@ static void __init reserve_crashkernel_low(void) | |||
521 | unsigned long long low_base = 0, low_size = 0; | 521 | unsigned long long low_base = 0, low_size = 0; |
522 | unsigned long total_low_mem; | 522 | unsigned long total_low_mem; |
523 | unsigned long long base; | 523 | unsigned long long base; |
524 | bool auto_set = false; | ||
524 | int ret; | 525 | int ret; |
525 | 526 | ||
526 | total_low_mem = memblock_mem_size(1UL<<(32-PAGE_SHIFT)); | 527 | total_low_mem = memblock_mem_size(1UL<<(32-PAGE_SHIFT)); |
527 | ret = parse_crashkernel_low(boot_command_line, total_low_mem, | 528 | ret = parse_crashkernel_low(boot_command_line, total_low_mem, |
528 | &low_size, &base); | 529 | &low_size, &base); |
529 | if (ret != 0 || low_size <= 0) | 530 | if (ret != 0) { |
530 | return; | 531 | /* |
532 | * two parts from lib/swiotlb.c: | ||
533 | * swiotlb size: user specified with swiotlb= or default. | ||
534 | * swiotlb overflow buffer: now is hardcoded to 32k. | ||
535 | * We round it to 8M for other buffers that | ||
536 | * may need to stay low too. | ||
537 | */ | ||
538 | low_size = swiotlb_size_or_default() + (8UL<<20); | ||
539 | auto_set = true; | ||
540 | } else { | ||
541 | /* passed with crashkernel_low=0 ? */ | ||
542 | if (!low_size) | ||
543 | return; | ||
544 | } | ||
531 | 545 | ||
532 | low_base = memblock_find_in_range(low_size, (1ULL<<32), | 546 | low_base = memblock_find_in_range(low_size, (1ULL<<32), |
533 | low_size, alignment); | 547 | low_size, alignment); |
534 | 548 | ||
535 | if (!low_base) { | 549 | if (!low_base) { |
536 | pr_info("crashkernel low reservation failed - No suitable area found.\n"); | 550 | if (!auto_set) |
551 | pr_info("crashkernel low reservation failed - No suitable area found.\n"); | ||
537 | 552 | ||
538 | return; | 553 | return; |
539 | } | 554 | } |
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index 2de42f9401d2..a5ffd32642fd 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h | |||
@@ -25,6 +25,7 @@ extern int swiotlb_force; | |||
25 | extern void swiotlb_init(int verbose); | 25 | extern void swiotlb_init(int verbose); |
26 | int swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose); | 26 | int swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose); |
27 | extern unsigned long swiotlb_nr_tbl(void); | 27 | extern unsigned long swiotlb_nr_tbl(void); |
28 | unsigned long swiotlb_size_or_default(void); | ||
28 | extern int swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs); | 29 | extern int swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs); |
29 | 30 | ||
30 | /* | 31 | /* |
diff --git a/lib/swiotlb.c b/lib/swiotlb.c index bfe02b8fc55b..d23762e6652c 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c | |||
@@ -105,9 +105,9 @@ setup_io_tlb_npages(char *str) | |||
105 | if (!strcmp(str, "force")) | 105 | if (!strcmp(str, "force")) |
106 | swiotlb_force = 1; | 106 | swiotlb_force = 1; |
107 | 107 | ||
108 | return 1; | 108 | return 0; |
109 | } | 109 | } |
110 | __setup("swiotlb=", setup_io_tlb_npages); | 110 | early_param("swiotlb", setup_io_tlb_npages); |
111 | /* make io_tlb_overflow tunable too? */ | 111 | /* make io_tlb_overflow tunable too? */ |
112 | 112 | ||
113 | unsigned long swiotlb_nr_tbl(void) | 113 | unsigned long swiotlb_nr_tbl(void) |
@@ -115,6 +115,18 @@ unsigned long swiotlb_nr_tbl(void) | |||
115 | return io_tlb_nslabs; | 115 | return io_tlb_nslabs; |
116 | } | 116 | } |
117 | EXPORT_SYMBOL_GPL(swiotlb_nr_tbl); | 117 | EXPORT_SYMBOL_GPL(swiotlb_nr_tbl); |
118 | |||
119 | /* default to 64MB */ | ||
120 | #define IO_TLB_DEFAULT_SIZE (64UL<<20) | ||
121 | unsigned long swiotlb_size_or_default(void) | ||
122 | { | ||
123 | unsigned long size; | ||
124 | |||
125 | size = io_tlb_nslabs << IO_TLB_SHIFT; | ||
126 | |||
127 | return size ? size : (IO_TLB_DEFAULT_SIZE); | ||
128 | } | ||
129 | |||
118 | /* Note that this doesn't work with highmem page */ | 130 | /* Note that this doesn't work with highmem page */ |
119 | static dma_addr_t swiotlb_virt_to_bus(struct device *hwdev, | 131 | static dma_addr_t swiotlb_virt_to_bus(struct device *hwdev, |
120 | volatile void *address) | 132 | volatile void *address) |
@@ -188,8 +200,7 @@ int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose) | |||
188 | void __init | 200 | void __init |
189 | swiotlb_init(int verbose) | 201 | swiotlb_init(int verbose) |
190 | { | 202 | { |
191 | /* default to 64MB */ | 203 | size_t default_size = IO_TLB_DEFAULT_SIZE; |
192 | size_t default_size = 64UL<<20; | ||
193 | unsigned char *vstart; | 204 | unsigned char *vstart; |
194 | unsigned long bytes; | 205 | unsigned long bytes; |
195 | 206 | ||