History

Merge branch 'x86-kdump-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull kdump fixes from Peter Anvin: "The kexec/kdump people have found several problems with the support for loading over 4 GiB that was introduced in this merge cycle. This is partly due to a number of design problems inherent in the way the various pieces of kdump fit together (it is pretty horrifically manual in many places.) After a *lot* of iterations this is the patchset that was agreed upon, but of course it is now very late in the cycle. However, because it changes both the syntax and semantics of the crashkernel option, it would be desirable to avoid a stable release with the broken interfaces." I'm not happy with the timing, since originally the plan was to release the final 3.9 tomorrow. But apparently I'm doing an -rc8 instead... * 'x86-kdump-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: kexec: use Crash kernel for Crash kernel low x86, kdump: Change crashkernel_high/low= to crashkernel=,high/low x86, kdump: Retore crashkernel= to allocate under 896M x86, kdump: Set crashkernel_low automatically

Linus Torvalds committed 13 years ago

Commit 830ac852 parents db93f8b 157752d6 files · +180 −28Browse files

Unified · Split

6 files
  1. Documentation/kernel-parameters.txt +20 −3
  2. arch/x86/kernel/setup.c +37 −8
  3. include/linux/kexec.h +2 −0
  4. include/linux/swiotlb.h +1 −0
  5. kernel/kexec.c +105 −13
  6. lib/swiotlb.c +15 −4
Documentation/kernel-parameters.txt+20−3
@@ -596,9 +596,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. · 595 unmodified lines
596596 is selected automatically. Check
597597 Documentation/kdump/kdump.txt for further details.
598598
599− crashkernel_low=size[KMG]
600− [KNL, x86] parts under 4G.
601−
602599 crashkernel=range1:size1[,range2:size2,...][@offset]
603600 [KNL] Same as above, but depends on the memory
604601 in the running system. The syntax of range is
@@ -606,6 +603,26 @@ bytes respectively. Such letter suffixes can also be entirely omitted. · 1 unmodified line
606603 a memory unit (amount[KMG]). See also
607604 Documentation/kdump/kdump.txt for an example.
608605
606+ crashkernel=size[KMG],high
607+ [KNL, x86_64] range could be above 4G. Allow kernel
608+ to allocate physical memory region from top, so could
609+ be above 4G if system have more than 4G ram installed.
610+ Otherwise memory region will be allocated below 4G, if
611+ available.
612+ It will be ignored if crashkernel=X is specified.
613+ crashkernel=size[KMG],low
614+ [KNL, x86_64] range under 4G. When crashkernel=X,high
615+ is passed, kernel could allocate physical memory region
616+ above 4G, that cause second kernel crash on system
617+ that require some amount of low memory, e.g. swiotlb
618+ requires at least 64M+32K low memory. Kernel would
619+ try to allocate 72M below 4G automatically.
620+ This one let user to specify own low range under 4G
621+ for second kernel instead.
622+ 0: to disable low allocation.
623+ It will be ignored when crashkernel=X,high is not used
624+ or memory reserved is below 4G.
625+
609626 cs89x0_dma= [HW,NET]
610627 Format: <dma>
611628
arch/x86/kernel/setup.c+37−8
@@ -507,11 +507,14 @@ static void __init memblock_x86_reserve_range_setup_data(void) · 506 unmodified lines
507507 /*
508508 * Keep the crash kernel below this limit. On 32 bits earlier kernels
509509 * would limit the kernel to the low 512 MiB due to mapping restrictions.
510+ * On 64bit, old kexec-tools need to under 896MiB.
510511 */
511512 #ifdef CONFIG_X86_32
512−# define CRASH_KERNEL_ADDR_MAX (512 << 20)
513+# define CRASH_KERNEL_ADDR_LOW_MAX (512 << 20)
514+# define CRASH_KERNEL_ADDR_HIGH_MAX (512 << 20)
513515 #else
514−# define CRASH_KERNEL_ADDR_MAX MAXMEM
516+# define CRASH_KERNEL_ADDR_LOW_MAX (896UL<<20)
517+# define CRASH_KERNEL_ADDR_HIGH_MAX MAXMEM
515518 #endif
516519
517520 static void __init reserve_crashkernel_low(void)
@@ -521,19 +524,35 @@ static void __init reserve_crashkernel_low(void) · 3 unmodified lines
521524 unsigned long long low_base = 0, low_size = 0;
522525 unsigned long total_low_mem;
523526 unsigned long long base;
527+ bool auto_set = false;
524528 int ret;
525529
526530 total_low_mem = memblock_mem_size(1UL<<(32-PAGE_SHIFT));
531+ /* crashkernel=Y,low */
527532 ret = parse_crashkernel_low(boot_command_line, total_low_mem,
528533 &low_size, &base);
529− if (ret != 0 || low_size <= 0)
530− return;
534+ if (ret != 0) {
535+ /*
536+ * two parts from lib/swiotlb.c:
537+ * swiotlb size: user specified with swiotlb= or default.
538+ * swiotlb overflow buffer: now is hardcoded to 32k.
539+ * We round it to 8M for other buffers that
540+ * may need to stay low too.
541+ */
542+ low_size = swiotlb_size_or_default() + (8UL<<20);
543+ auto_set = true;
544+ } else {
545+ /* passed with crashkernel=0,low ? */
546+ if (!low_size)
547+ return;
548+ }
531549
532550 low_base = memblock_find_in_range(low_size, (1ULL<<32),
533551 low_size, alignment);
534552
535553 if (!low_base) {
536− pr_info("crashkernel low reservation failed - No suitable area found.\n");
554+ if (!auto_set)
555+ pr_info("crashkernel low reservation failed - No suitable area found.\n");
537556
538557 return;
539558 }
@@ -554,14 +573,22 @@ static void __init reserve_crashkernel(void) · 14 unmodified lines
554573 const unsigned long long alignment = 16<<20; /* 16M */
555574 unsigned long long total_mem;
556575 unsigned long long crash_size, crash_base;
576+ bool high = false;
557577 int ret;
558578
559579 total_mem = memblock_phys_mem_size();
560580
581+ /* crashkernel=XM */
561582 ret = parse_crashkernel(boot_command_line, total_mem,
562583 &crash_size, &crash_base);
563− if (ret != 0 || crash_size <= 0)
564− return;
584+ if (ret != 0 || crash_size <= 0) {
585+ /* crashkernel=X,high */
586+ ret = parse_crashkernel_high(boot_command_line, total_mem,
587+ &crash_size, &crash_base);
588+ if (ret != 0 || crash_size <= 0)
589+ return;
590+ high = true;
591+ }
565592
566593 /* 0 means: find the address automatically */
567594 if (crash_base <= 0) {
@@ -569,7 +596,9 @@ static void __init reserve_crashkernel(void) · 1 unmodified line
569596 * kexec want bzImage is below CRASH_KERNEL_ADDR_MAX
570597 */
571598 crash_base = memblock_find_in_range(alignment,
572− CRASH_KERNEL_ADDR_MAX, crash_size, alignment);
599+ high ? CRASH_KERNEL_ADDR_HIGH_MAX :
600+ CRASH_KERNEL_ADDR_LOW_MAX,
601+ crash_size, alignment);
573602
574603 if (!crash_base) {
575604 pr_info("crashkernel reservation failed - No suitable area found.\n");
include/linux/kexec.h+2−0
@@ -200,6 +200,8 @@ extern size_t vmcoreinfo_max_size; · 199 unmodified lines
200200
201201 int __init parse_crashkernel(char *cmdline, unsigned long long system_ram,
202202 unsigned long long *crash_size, unsigned long long *crash_base);
203+int parse_crashkernel_high(char *cmdline, unsigned long long system_ram,
204+ unsigned long long *crash_size, unsigned long long *crash_base);
203205 int parse_crashkernel_low(char *cmdline, unsigned long long system_ram,
204206 unsigned long long *crash_size, unsigned long long *crash_base);
205207 int crash_shrink_memory(unsigned long new_size);
include/linux/swiotlb.h+1−0
@@ -25,6 +25,7 @@ extern int swiotlb_force; · 24 unmodified lines
2525 extern void swiotlb_init(int verbose);
2626 int swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose);
2727 extern unsigned long swiotlb_nr_tbl(void);
28+unsigned long swiotlb_size_or_default(void);
2829 extern int swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs);
2930
3031 /*
kernel/kexec.c+105−13
@@ -55,7 +55,7 @@ struct resource crashk_res = { · 54 unmodified lines
5555 .flags = IORESOURCE_BUSY | IORESOURCE_MEM
5656 };
5757 struct resource crashk_low_res = {
58− .name = "Crash kernel low",
58+ .name = "Crash kernel",
5959 .start = 0,
6060 .end = 0,
6161 .flags = IORESOURCE_BUSY | IORESOURCE_MEM
@@ -1368,35 +1368,114 @@ static int __init parse_crashkernel_simple(char *cmdline, · 1306 unmodified lines
13681368 return 0;
13691369 }
13701370
1371+#define SUFFIX_HIGH 0
1372+#define SUFFIX_LOW 1
1373+#define SUFFIX_NULL 2
1374+static __initdata char *suffix_tbl[] = {
1375+ [SUFFIX_HIGH] = ",high",
1376+ [SUFFIX_LOW] = ",low",
1377+ [SUFFIX_NULL] = NULL,
1378+};
1379+
13711380 /*
1372− * That function is the entry point for command line parsing and should be
1373− * called from the arch-specific code.
1381+ * That function parses "suffix" crashkernel command lines like
1382+ *
1383+ * crashkernel=size,[high|low]
1384+ *
1385+ * It returns 0 on success and -EINVAL on failure.
13741386 */
1387+static int __init parse_crashkernel_suffix(char *cmdline,
1388+ unsigned long long *crash_size,
1389+ unsigned long long *crash_base,
1390+ const char *suffix)
1391+{
1392+ char *cur = cmdline;
1393+
1394+ *crash_size = memparse(cmdline, &cur);
1395+ if (cmdline == cur) {
1396+ pr_warn("crashkernel: memory value expected\n");
1397+ return -EINVAL;
1398+ }
1399+
1400+ /* check with suffix */
1401+ if (strncmp(cur, suffix, strlen(suffix))) {
1402+ pr_warn("crashkernel: unrecognized char\n");
1403+ return -EINVAL;
1404+ }
1405+ cur += strlen(suffix);
1406+ if (*cur != ' ' && *cur != '\0') {
1407+ pr_warn("crashkernel: unrecognized char\n");
1408+ return -EINVAL;
1409+ }
1410+
1411+ return 0;
1412+}
1413+
1414+static __init char *get_last_crashkernel(char *cmdline,
1415+ const char *name,
1416+ const char *suffix)
1417+{
1418+ char *p = cmdline, *ck_cmdline = NULL;
1419+
1420+ /* find crashkernel and use the last one if there are more */
1421+ p = strstr(p, name);
1422+ while (p) {
1423+ char *end_p = strchr(p, ' ');
1424+ char *q;
1425+
1426+ if (!end_p)
1427+ end_p = p + strlen(p);
1428+
1429+ if (!suffix) {
1430+ int i;
1431+
1432+ /* skip the one with any known suffix */
1433+ for (i = 0; suffix_tbl[i]; i++) {
1434+ q = end_p - strlen(suffix_tbl[i]);
1435+ if (!strncmp(q, suffix_tbl[i],
1436+ strlen(suffix_tbl[i])))
1437+ goto next;
1438+ }
1439+ ck_cmdline = p;
1440+ } else {
1441+ q = end_p - strlen(suffix);
1442+ if (!strncmp(q, suffix, strlen(suffix)))
1443+ ck_cmdline = p;
1444+ }
1445+next:
1446+ p = strstr(p+1, name);
1447+ }
1448+
1449+ if (!ck_cmdline)
1450+ return NULL;
1451+
1452+ return ck_cmdline;
1453+}
1454+
13751455 static int __init __parse_crashkernel(char *cmdline,
13761456 unsigned long long system_ram,
13771457 unsigned long long *crash_size,
13781458 unsigned long long *crash_base,
1379− const char *name)
1459+ const char *name,
1460+ const char *suffix)
13801461 {
1381− char *p = cmdline, *ck_cmdline = NULL;
13821462 char *first_colon, *first_space;
1463+ char *ck_cmdline;
13831464
13841465 BUG_ON(!crash_size || !crash_base);
13851466 *crash_size = 0;
13861467 *crash_base = 0;
13871468
1388− /* find crashkernel and use the last one if there are more */
1389− p = strstr(p, name);
1390− while (p) {
1391− ck_cmdline = p;
1392− p = strstr(p+1, name);
1393− }
1469+ ck_cmdline = get_last_crashkernel(cmdline, name, suffix);
13941470
13951471 if (!ck_cmdline)
13961472 return -EINVAL;
13971473
13981474 ck_cmdline += strlen(name);
13991475
1476+ if (suffix)
1477+ return parse_crashkernel_suffix(ck_cmdline, crash_size,
1478+ crash_base, suffix);
14001479 /*
14011480 * if the commandline contains a ':', then that's the extended
14021481 * syntax -- if not, it must be the classic syntax
@@ -1413,13 +1492,26 @@ static int __init __parse_crashkernel(char *cmdline, · 10 unmodified lines
14131492 return 0;
14141493 }
14151494
1495+/*
1496+ * That function is the entry point for command line parsing and should be
1497+ * called from the arch-specific code.
1498+ */
14161499 int __init parse_crashkernel(char *cmdline,
14171500 unsigned long long system_ram,
14181501 unsigned long long *crash_size,
14191502 unsigned long long *crash_base)
14201503 {
14211504 return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base,
1422− "crashkernel=");
1505+ "crashkernel=", NULL);
1506+}
1507+
1508+int __init parse_crashkernel_high(char *cmdline,
1509+ unsigned long long system_ram,
1510+ unsigned long long *crash_size,
1511+ unsigned long long *crash_base)
1512+{
1513+ return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base,
1514+ "crashkernel=", suffix_tbl[SUFFIX_HIGH]);
14231515 }
14241516
14251517 int __init parse_crashkernel_low(char *cmdline,
@@ -1428,7 +1520,7 @@ int __init parse_crashkernel_low(char *cmdline, · 2 unmodified lines
14281520 unsigned long long *crash_base)
14291521 {
14301522 return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base,
1431− "crashkernel_low=");
1523+ "crashkernel=", suffix_tbl[SUFFIX_LOW]);
14321524 }
14331525
14341526 static void update_vmcoreinfo_note(void)
lib/swiotlb.c+15−4
@@ -105,9 +105,9 @@ setup_io_tlb_npages(char *str) · 104 unmodified lines
105105 if (!strcmp(str, "force"))
106106 swiotlb_force = 1;
107107
108− return 1;
108+ return 0;
109109 }
110−__setup("swiotlb=", setup_io_tlb_npages);
110+early_param("swiotlb", setup_io_tlb_npages);
111111 /* make io_tlb_overflow tunable too? */
112112
113113 unsigned long swiotlb_nr_tbl(void)
@@ -115,6 +115,18 @@ unsigned long swiotlb_nr_tbl(void) · 1 unmodified line
115115 return io_tlb_nslabs;
116116 }
117117 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+
118130 /* Note that this doesn't work with highmem page */
119131 static dma_addr_t swiotlb_virt_to_bus(struct device *hwdev,
120132 volatile void *address)
@@ -188,8 +200,7 @@ int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose) · 67 unmodified lines
188200 void __init
189201 swiotlb_init(int verbose)
190202 {
191− /* default to 64MB */
192− size_t default_size = 64UL<<20;
203+ size_t default_size = IO_TLB_DEFAULT_SIZE;
193204 unsigned char *vstart;
194205 unsigned long bytes;
195206

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t