Skip to contentSkip to conversation

tip-queue 2015-10-19

PATCH New Borislav Petkov 2 participants 17 messages Oct 19, 2015 – Oct 21, 2015

Subsystems (4)
lore
Share & tools
lore

Borislav Petkov

author maintainer
#0 lore raw

cover tip-queue 2015-10-19

From: Borislav Petkov <[email protected]>

Hi Ingo,

a couple of fixes/cleanups this week. I even think each patch's commit message actually sufficiently explains each change. I know, it is unbelievable. :-)

Please apply,
thanks.

Andi Kleen (1):
x86/mce: Fix thermal throttling reporting after kexec

Aravind Gopalakrishnan (1):
x86/amd_nb, EDAC: Rename amd_get_node_id()

Baoquan He (1):
x86/setup: Do not reserve crashkernel high memory if low reservation
failed

Borislav Petkov (5):
x86/setup: Cleanup crashkernel reservation functions x86/setup/crash: Remove alignment variable x86/setup/crash: Cleanup some more x86/setup/crash: Check memblock_reserve() retval kexec/crash: Say which char is the unrecognized

author maintainer
#1 lore raw

PATCH 1/8 x86/setup: Do not reserve crashkernel high memory if low reservation failed

From: Baoquan He <[email protected]>

People reported that when allocating crashkernel memory using the ",high" and ",low" syntax, there were cases where the reservation of the high portion succeeds but the reservation of the low portion fails.

Then kexec can load the kdump kernel successfully, but booting the kdump kernel fails as there's no low memory.

The low memory allocation for the kdump kernel can fail on large systems for a couple of reasons. For example, the manually specified crashkernel low memory can be too large and thus no adequate memblock region would be found.

Therefore, we try to reserve low memory for the crash kernel *after* the high memory portion has been allocated. If that fails, we free crashkernel high memory too and return. The user can then take measures accordingly.

---
 arch/x86/kernel/setup.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)
arch/x86/kernel/setup.c +11 -9
index fdb7f2a2d328..1b36839e41eb 100644
@@ -493,7 +493,7 @@ static void __init memblock_x86_reserve_range_setup_data(void)
 # define CRASH_KERNEL_ADDR_HIGH_MAX	MAXMEM
 #endif
 
-static void __init reserve_crashkernel_low(void)
+static int __init reserve_crashkernel_low(void)
 {
 #ifdef CONFIG_X86_64
 	const unsigned long long alignment = 16<<20;	/* 16M */
@@ -522,17 +522,16 @@ static void __init reserve_crashkernel_low(void)
 	} else {
 		/* passed with crashkernel=0,low ? */
 		if (!low_size)
-			return;
+			return 0;
 	}
 
 	low_base = memblock_find_in_range(low_size, (1ULL<<32),
 					low_size, alignment);
 
 	if (!low_base) {
-		if (!auto_set)
-			pr_info("crashkernel low reservation failed - No suitable area found.\n");
-
-		return;
+		pr_err("Cannot reserve %ldMB crashkernel low memory, please try smaller size.\n",
+		       (unsigned long)(low_size >> 20));
+		return -ENOMEM;
 	}
 
 	memblock_reserve(low_base, low_size);
@@ -544,6 +543,7 @@ static void __init reserve_crashkernel_low(void)
 	crashk_low_res.end   = low_base + low_size - 1;
 	insert_resource(&iomem_resource, &crashk_low_res);
 #endif
+	return 0;
 }
 
 static void __init reserve_crashkernel(void)
@@ -595,6 +595,11 @@ static void __init reserve_crashkernel(void)
 	}
 	memblock_reserve(crash_base, crash_size);
 
+	if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) {
+		memblock_free(crash_base, crash_size);
+		return;
+	}
+
 	printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
 			"for crashkernel (System RAM: %ldMB)\n",
 			(unsigned long)(crash_size >> 20),
@@ -604,9 +609,6 @@ static void __init reserve_crashkernel(void)
 	crashk_res.start = crash_base;
 	crashk_res.end   = crash_base + crash_size - 1;
 	insert_resource(&iomem_resource, &crashk_res);
-
-	if (crash_base >= (1ULL<<32))
-		reserve_crashkernel_low();
 }
 #else
 static void __init reserve_crashkernel(void)
Signature · 1 line
2.3.5
#2 lore raw

[tip:ras/core] x86/setup: Do not reserve crashkernel high memory if low reservation failed

x86/setup: Do not reserve crashkernel high memory if low reservation failed
Commit-ID:  eb6db83d105914c246ac5875be76fd4b944833d5
Gitweb:     http://git.kernel.org/tip/eb6db83d105914c246ac5875be76fd4b944833d5
Author:     Baoquan He <[email protected]>
AuthorDate: Mon, 19 Oct 2015 11:17:41 +0200
Committer:  Ingo Molnar <[email protected]>
CommitDate: Wed, 21 Oct 2015 11:10:55 +0200

x86/setup: Do not reserve crashkernel high memory if low reservation failed

People reported that when allocating crashkernel memory using the ",high" and ",low" syntax, there were cases where the reservation of the high portion succeeds but the reservation of the low portion fails.

Then kexec can load the kdump kernel successfully, but booting the kdump kernel fails as there's no low memory.

The low memory allocation for the kdump kernel can fail on large systems for a couple of reasons. For example, the manually specified crashkernel low memory can be too large and thus no adequate memblock region would be found.

Therefore, we try to reserve low memory for the crash kernel *after* the high memory portion has been allocated. If that fails, we free crashkernel high memory too and return. The user can then take measures accordingly.

---
 arch/x86/kernel/setup.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)
arch/x86/kernel/setup.c +11 -9
index fdb7f2a..1b36839 100644
@@ -493,7 +493,7 @@ static void __init memblock_x86_reserve_range_setup_data(void)
 # define CRASH_KERNEL_ADDR_HIGH_MAX	MAXMEM
 #endif
 
-static void __init reserve_crashkernel_low(void)
+static int __init reserve_crashkernel_low(void)
 {
 #ifdef CONFIG_X86_64
 	const unsigned long long alignment = 16<<20;	/* 16M */
@@ -522,17 +522,16 @@ static void __init reserve_crashkernel_low(void)
 	} else {
 		/* passed with crashkernel=0,low ? */
 		if (!low_size)
-			return;
+			return 0;
 	}
 
 	low_base = memblock_find_in_range(low_size, (1ULL<<32),
 					low_size, alignment);
 
 	if (!low_base) {
-		if (!auto_set)
-			pr_info("crashkernel low reservation failed - No suitable area found.\n");
-
-		return;
+		pr_err("Cannot reserve %ldMB crashkernel low memory, please try smaller size.\n",
+		       (unsigned long)(low_size >> 20));
+		return -ENOMEM;
 	}
 
 	memblock_reserve(low_base, low_size);
@@ -544,6 +543,7 @@ static void __init reserve_crashkernel_low(void)
 	crashk_low_res.end   = low_base + low_size - 1;
 	insert_resource(&iomem_resource, &crashk_low_res);
 #endif
+	return 0;
 }
 
 static void __init reserve_crashkernel(void)
@@ -595,6 +595,11 @@ static void __init reserve_crashkernel(void)
 	}
 	memblock_reserve(crash_base, crash_size);
 
+	if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) {
+		memblock_free(crash_base, crash_size);
+		return;
+	}
+
 	printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
 			"for crashkernel (System RAM: %ldMB)\n",
 			(unsigned long)(crash_size >> 20),
@@ -604,9 +609,6 @@ static void __init reserve_crashkernel(void)
 	crashk_res.start = crash_base;
 	crashk_res.end   = crash_base + crash_size - 1;
 	insert_resource(&iomem_resource, &crashk_res);
-
-	if (crash_base >= (1ULL<<32))
-		reserve_crashkernel_low();
 }
 #else
 static void __init reserve_crashkernel(void)
author maintainer
#3 lore raw

PATCH 2/8 x86/amd_nb, EDAC: Rename amd_get_node_id()

In reply to Borislav Petkov

From: Aravind Gopalakrishnan <[email protected]>

This function doesn't give us the "Node ID" as the function name suggests. Rather, it receives a PCI device as argument, checks the available F3 PCI device IDs in the system and returns the index of the matching Bus/Device IDs.

Rename it to amd_pci_dev_to_node_id().

No functional change is introduced.

---
 arch/x86/include/asm/amd_nb.h | 2 +-
 drivers/edac/amd64_edac.c     | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)
arch/x86/include/asm/amd_nb.h +1 -1
index 1a5da2e63aee..3c56ef1ae068 100644
@@ -81,7 +81,7 @@ static inline struct amd_northbridge *node_to_amd_nb(int node)
 	return (node < amd_northbridges.num) ? &amd_northbridges.nb[node] : NULL;
 }
 
-static inline u16 amd_get_node_id(struct pci_dev *pdev)
+static inline u16 amd_pci_dev_to_node_id(struct pci_dev *pdev)
 {
 	struct pci_dev *misc;
 	int i;
drivers/edac/amd64_edac.c +3 -3
index 73aea40a9c89..d5fcdbfd99b8 100644
@@ -2770,7 +2770,7 @@ static int init_one_instance(struct pci_dev *F2)
 	struct mem_ctl_info *mci = NULL;
 	struct edac_mc_layer layers[2];
 	int err = 0, ret;
-	u16 nid = amd_get_node_id(F2);
+	u16 nid = amd_pci_dev_to_node_id(F2);
 
 	ret = -ENOMEM;
 	pvt = kzalloc(sizeof(struct amd64_pvt), GFP_KERNEL);
@@ -2860,7 +2860,7 @@ err_ret:
 static int probe_one_instance(struct pci_dev *pdev,
 			      const struct pci_device_id *mc_type)
 {
-	u16 nid = amd_get_node_id(pdev);
+	u16 nid = amd_pci_dev_to_node_id(pdev);
 	struct pci_dev *F3 = node_to_amd_nb(nid)->misc;
 	struct ecc_settings *s;
 	int ret = 0;
@@ -2910,7 +2910,7 @@ static void remove_one_instance(struct pci_dev *pdev)
 {
 	struct mem_ctl_info *mci;
 	struct amd64_pvt *pvt;
-	u16 nid = amd_get_node_id(pdev);
+	u16 nid = amd_pci_dev_to_node_id(pdev);
 	struct pci_dev *F3 = node_to_amd_nb(nid)->misc;
 	struct ecc_settings *s = ecc_stngs[nid];
 
Signature · 1 line
2.3.5
#4 lore raw

[tip:ras/core] x86/amd_nb, EDAC: Rename amd_get_node_id()

x86/amd_nb, EDAC: Rename amd_get_node_id()
Commit-ID:  1a6775c1a2c2ed863699403cda517916c22aeb72
Gitweb:     http://git.kernel.org/tip/1a6775c1a2c2ed863699403cda517916c22aeb72
Author:     Aravind Gopalakrishnan <[email protected]>
AuthorDate: Mon, 19 Oct 2015 11:17:42 +0200
Committer:  Ingo Molnar <[email protected]>
CommitDate: Wed, 21 Oct 2015 11:10:55 +0200

x86/amd_nb, EDAC: Rename amd_get_node_id()

This function doesn't give us the "Node ID" as the function name suggests. Rather, it receives a PCI device as argument, checks the available F3 PCI device IDs in the system and returns the index of the matching Bus/Device IDs.

Rename it to amd_pci_dev_to_node_id().

No functional change is introduced.

---
 arch/x86/include/asm/amd_nb.h | 2 +-
 drivers/edac/amd64_edac.c     | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)
arch/x86/include/asm/amd_nb.h +1 -1
index 1a5da2e..3c56ef1 100644
@@ -81,7 +81,7 @@ static inline struct amd_northbridge *node_to_amd_nb(int node)
 	return (node < amd_northbridges.num) ? &amd_northbridges.nb[node] : NULL;
 }
 
-static inline u16 amd_get_node_id(struct pci_dev *pdev)
+static inline u16 amd_pci_dev_to_node_id(struct pci_dev *pdev)
 {
 	struct pci_dev *misc;
 	int i;
drivers/edac/amd64_edac.c +3 -3
index 73aea40..d5fcdbf 100644
@@ -2770,7 +2770,7 @@ static int init_one_instance(struct pci_dev *F2)
 	struct mem_ctl_info *mci = NULL;
 	struct edac_mc_layer layers[2];
 	int err = 0, ret;
-	u16 nid = amd_get_node_id(F2);
+	u16 nid = amd_pci_dev_to_node_id(F2);
 
 	ret = -ENOMEM;
 	pvt = kzalloc(sizeof(struct amd64_pvt), GFP_KERNEL);
@@ -2860,7 +2860,7 @@ err_ret:
 static int probe_one_instance(struct pci_dev *pdev,
 			      const struct pci_device_id *mc_type)
 {
-	u16 nid = amd_get_node_id(pdev);
+	u16 nid = amd_pci_dev_to_node_id(pdev);
 	struct pci_dev *F3 = node_to_amd_nb(nid)->misc;
 	struct ecc_settings *s;
 	int ret = 0;
@@ -2910,7 +2910,7 @@ static void remove_one_instance(struct pci_dev *pdev)
 {
 	struct mem_ctl_info *mci;
 	struct amd64_pvt *pvt;
-	u16 nid = amd_get_node_id(pdev);
+	u16 nid = amd_pci_dev_to_node_id(pdev);
 	struct pci_dev *F3 = node_to_amd_nb(nid)->misc;
 	struct ecc_settings *s = ecc_stngs[nid];
 
author maintainer
#5 lore raw

PATCH 3/8 x86/setup: Cleanup crashkernel reservation functions

In reply to Borislav Petkov

From: Borislav Petkov <[email protected]>

* Shorten variable names
* Realign code, space out for better readability

No code changed:

# arch/x86/kernel/setup.o:

   text    data     bss     dec     hex filename
   4543    3096   69904   77543   12ee7 setup.o.before
   4543    3096   69904   77543   12ee7 setup.o.after

md5:
8a1b7c6738a553ca207b56bd84a8f359 setup.o.before.asm 8a1b7c6738a553ca207b56bd84a8f359 setup.o.after.asm

Cc Andrew Morton <[email protected]>
Cc Andy Lutomirski <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc Jiri Kosina <[email protected]>
Cc Juergen Gross <[email protected]>
Cc Mark Salter <[email protected]>
Cc Thomas Gleixner <[email protected]>
Cc WANG Chao <[email protected]>
Cc x86-ml <[email protected]>
---
 arch/x86/kernel/setup.c | 43 +++++++++++++++++++++----------------------
 1 file changed, 21 insertions(+), 22 deletions(-)
arch/x86/kernel/setup.c +21 -22
index 1b36839e41eb..fd9e178aa890 100644
@@ -486,11 +486,11 @@ static void __init memblock_x86_reserve_range_setup_data(void)
  * On 64bit, old kexec-tools need to under 896MiB.
  */
 #ifdef CONFIG_X86_32
-# define CRASH_KERNEL_ADDR_LOW_MAX	(512 << 20)
-# define CRASH_KERNEL_ADDR_HIGH_MAX	(512 << 20)
+# define CRASH_ADDR_LOW_MAX	(512 << 20)
+# define CRASH_ADDR_HIGH_MAX	(512 << 20)
 #else
-# define CRASH_KERNEL_ADDR_LOW_MAX	(896UL<<20)
-# define CRASH_KERNEL_ADDR_HIGH_MAX	MAXMEM
+# define CRASH_ADDR_LOW_MAX	(896UL << 20)
+# define CRASH_ADDR_HIGH_MAX	MAXMEM
 #endif
 
 static int __init reserve_crashkernel_low(void)
@@ -503,10 +503,10 @@ static int __init reserve_crashkernel_low(void)
 	bool auto_set = false;
 	int ret;
 
-	total_low_mem = memblock_mem_size(1UL<<(32-PAGE_SHIFT));
+	total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
+
 	/* crashkernel=Y,low */
-	ret = parse_crashkernel_low(boot_command_line, total_low_mem,
-						&low_size, &base);
+	ret = parse_crashkernel_low(boot_command_line, total_low_mem, &low_size, &base);
 	if (ret != 0) {
 		/*
 		 * two parts from lib/swiotlb.c:
@@ -517,7 +517,7 @@ static int __init reserve_crashkernel_low(void)
 		 * make sure we allocate enough extra low memory so that we
 		 * don't run out of DMA buffers for 32-bit devices.
 		 */
-		low_size = max(swiotlb_size_or_default() + (8UL<<20), 256UL<<20);
+		low_size = max(swiotlb_size_or_default() + (8UL << 20), 256UL << 20);
 		auto_set = true;
 	} else {
 		/* passed with crashkernel=0,low ? */
@@ -525,9 +525,7 @@ static int __init reserve_crashkernel_low(void)
 			return 0;
 	}
 
-	low_base = memblock_find_in_range(low_size, (1ULL<<32),
-					low_size, alignment);
-
+	low_base = memblock_find_in_range(low_size, 1ULL << 32, low_size, alignment);
 	if (!low_base) {
 		pr_err("Cannot reserve %ldMB crashkernel low memory, please try smaller size.\n",
 		       (unsigned long)(low_size >> 20));
@@ -535,10 +533,12 @@ static int __init reserve_crashkernel_low(void)
 	}
 
 	memblock_reserve(low_base, low_size);
+
 	pr_info("Reserving %ldMB of low memory at %ldMB for crashkernel (System low RAM: %ldMB)\n",
-			(unsigned long)(low_size >> 20),
-			(unsigned long)(low_base >> 20),
-			(unsigned long)(total_low_mem >> 20));
+		(unsigned long)(low_size >> 20),
+		(unsigned long)(low_base >> 20),
+		(unsigned long)(total_low_mem >> 20));
+
 	crashk_low_res.start = low_base;
 	crashk_low_res.end   = low_base + low_size - 1;
 	insert_resource(&iomem_resource, &crashk_low_res);
@@ -557,12 +557,11 @@ static void __init reserve_crashkernel(void)
 	total_mem = memblock_phys_mem_size();
 
 	/* crashkernel=XM */
-	ret = parse_crashkernel(boot_command_line, total_mem,
-			&crash_size, &crash_base);
+	ret = parse_crashkernel(boot_command_line, total_mem, &crash_size, &crash_base);
 	if (ret != 0 || crash_size <= 0) {
 		/* crashkernel=X,high */
 		ret = parse_crashkernel_high(boot_command_line, total_mem,
-				&crash_size, &crash_base);
+					     &crash_size, &crash_base);
 		if (ret != 0 || crash_size <= 0)
 			return;
 		high = true;
@@ -574,10 +573,9 @@ static void __init reserve_crashkernel(void)
 		 *  kexec want bzImage is below CRASH_KERNEL_ADDR_MAX
 		 */
 		crash_base = memblock_find_in_range(alignment,
-					high ? CRASH_KERNEL_ADDR_HIGH_MAX :
-					       CRASH_KERNEL_ADDR_LOW_MAX,
-					crash_size, alignment);
-
+						    high ? CRASH_ADDR_HIGH_MAX
+							 : CRASH_ADDR_LOW_MAX,
+						    crash_size, alignment);
 		if (!crash_base) {
 			pr_info("crashkernel reservation failed - No suitable area found.\n");
 			return;
@@ -587,7 +585,8 @@ static void __init reserve_crashkernel(void)
 		unsigned long long start;
 
 		start = memblock_find_in_range(crash_base,
-				 crash_base + crash_size, crash_size, 1<<20);
+					       crash_base + crash_size,
+					       crash_size, 1 << 20);
 		if (start != crash_base) {
 			pr_info("crashkernel reservation failed - memory is in use.\n");
 			return;
Signature · 1 line
2.3.5
#6 lore raw

[tip:ras/core] x86/setup: Cleanup crashkernel reservation functions

x86/setup: Cleanup crashkernel reservation functions
Commit-ID:  97eac21babe47e1a8ed4cac4f8874c5746cf6e36
Gitweb:     http://git.kernel.org/tip/97eac21babe47e1a8ed4cac4f8874c5746cf6e36
Author:     Borislav Petkov <[email protected]>
AuthorDate: Mon, 19 Oct 2015 11:17:43 +0200
Committer:  Ingo Molnar <[email protected]>
CommitDate: Wed, 21 Oct 2015 11:10:56 +0200

x86/setup: Cleanup crashkernel reservation functions

* Shorten variable names
* Realign code, space out for better readability

No code changed:

# arch/x86/kernel/setup.o:

   text    data     bss     dec     hex filename
   4543    3096   69904   77543   12ee7 setup.o.before
   4543    3096   69904   77543   12ee7 setup.o.after

md5:
8a1b7c6738a553ca207b56bd84a8f359 setup.o.before.asm 8a1b7c6738a553ca207b56bd84a8f359 setup.o.after.asm

---
 arch/x86/kernel/setup.c | 43 +++++++++++++++++++++----------------------
 1 file changed, 21 insertions(+), 22 deletions(-)
arch/x86/kernel/setup.c +21 -22
index 1b36839..fd9e178 100644
@@ -486,11 +486,11 @@ static void __init memblock_x86_reserve_range_setup_data(void)
  * On 64bit, old kexec-tools need to under 896MiB.
  */
 #ifdef CONFIG_X86_32
-# define CRASH_KERNEL_ADDR_LOW_MAX	(512 << 20)
-# define CRASH_KERNEL_ADDR_HIGH_MAX	(512 << 20)
+# define CRASH_ADDR_LOW_MAX	(512 << 20)
+# define CRASH_ADDR_HIGH_MAX	(512 << 20)
 #else
-# define CRASH_KERNEL_ADDR_LOW_MAX	(896UL<<20)
-# define CRASH_KERNEL_ADDR_HIGH_MAX	MAXMEM
+# define CRASH_ADDR_LOW_MAX	(896UL << 20)
+# define CRASH_ADDR_HIGH_MAX	MAXMEM
 #endif
 
 static int __init reserve_crashkernel_low(void)
@@ -503,10 +503,10 @@ static int __init reserve_crashkernel_low(void)
 	bool auto_set = false;
 	int ret;
 
-	total_low_mem = memblock_mem_size(1UL<<(32-PAGE_SHIFT));
+	total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
+
 	/* crashkernel=Y,low */
-	ret = parse_crashkernel_low(boot_command_line, total_low_mem,
-						&low_size, &base);
+	ret = parse_crashkernel_low(boot_command_line, total_low_mem, &low_size, &base);
 	if (ret != 0) {
 		/*
 		 * two parts from lib/swiotlb.c:
@@ -517,7 +517,7 @@ static int __init reserve_crashkernel_low(void)
 		 * make sure we allocate enough extra low memory so that we
 		 * don't run out of DMA buffers for 32-bit devices.
 		 */
-		low_size = max(swiotlb_size_or_default() + (8UL<<20), 256UL<<20);
+		low_size = max(swiotlb_size_or_default() + (8UL << 20), 256UL << 20);
 		auto_set = true;
 	} else {
 		/* passed with crashkernel=0,low ? */
@@ -525,9 +525,7 @@ static int __init reserve_crashkernel_low(void)
 			return 0;
 	}
 
-	low_base = memblock_find_in_range(low_size, (1ULL<<32),
-					low_size, alignment);
-
+	low_base = memblock_find_in_range(low_size, 1ULL << 32, low_size, alignment);
 	if (!low_base) {
 		pr_err("Cannot reserve %ldMB crashkernel low memory, please try smaller size.\n",
 		       (unsigned long)(low_size >> 20));
@@ -535,10 +533,12 @@ static int __init reserve_crashkernel_low(void)
 	}
 
 	memblock_reserve(low_base, low_size);
+
 	pr_info("Reserving %ldMB of low memory at %ldMB for crashkernel (System low RAM: %ldMB)\n",
-			(unsigned long)(low_size >> 20),
-			(unsigned long)(low_base >> 20),
-			(unsigned long)(total_low_mem >> 20));
+		(unsigned long)(low_size >> 20),
+		(unsigned long)(low_base >> 20),
+		(unsigned long)(total_low_mem >> 20));
+
 	crashk_low_res.start = low_base;
 	crashk_low_res.end   = low_base + low_size - 1;
 	insert_resource(&iomem_resource, &crashk_low_res);
@@ -557,12 +557,11 @@ static void __init reserve_crashkernel(void)
 	total_mem = memblock_phys_mem_size();
 
 	/* crashkernel=XM */
-	ret = parse_crashkernel(boot_command_line, total_mem,
-			&crash_size, &crash_base);
+	ret = parse_crashkernel(boot_command_line, total_mem, &crash_size, &crash_base);
 	if (ret != 0 || crash_size <= 0) {
 		/* crashkernel=X,high */
 		ret = parse_crashkernel_high(boot_command_line, total_mem,
-				&crash_size, &crash_base);
+					     &crash_size, &crash_base);
 		if (ret != 0 || crash_size <= 0)
 			return;
 		high = true;
@@ -574,10 +573,9 @@ static void __init reserve_crashkernel(void)
 		 *  kexec want bzImage is below CRASH_KERNEL_ADDR_MAX
 		 */
 		crash_base = memblock_find_in_range(alignment,
-					high ? CRASH_KERNEL_ADDR_HIGH_MAX :
-					       CRASH_KERNEL_ADDR_LOW_MAX,
-					crash_size, alignment);
-
+						    high ? CRASH_ADDR_HIGH_MAX
+							 : CRASH_ADDR_LOW_MAX,
+						    crash_size, alignment);
 		if (!crash_base) {
 			pr_info("crashkernel reservation failed - No suitable area found.\n");
 			return;
@@ -587,7 +585,8 @@ static void __init reserve_crashkernel(void)
 		unsigned long long start;
 
 		start = memblock_find_in_range(crash_base,
-				 crash_base + crash_size, crash_size, 1<<20);
+					       crash_base + crash_size,
+					       crash_size, 1 << 20);
 		if (start != crash_base) {
 			pr_info("crashkernel reservation failed - memory is in use.\n");
 			return;
author maintainer
#7 lore raw

PATCH 4/8 x86/setup/crash: Remove alignment variable

In reply to Borislav Petkov

From: Borislav Petkov <[email protected]>

Use a macro instead. No functionality change.

Cc Andrew Morton <[email protected]>
Cc Andy Lutomirski <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc Jiri Kosina <[email protected]>
Cc Juergen Gross <[email protected]>
Cc Mark Salter <[email protected]>
Cc Thomas Gleixner <[email protected]>
Cc WANG Chao <[email protected]>
Cc x86-ml <[email protected]>
---
 arch/x86/kernel/setup.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)
arch/x86/kernel/setup.c +6 -5
index fd9e178aa890..ea086dd8e821 100644
@@ -480,6 +480,9 @@ static void __init memblock_x86_reserve_range_setup_data(void)
 
 #ifdef CONFIG_KEXEC_CORE
 
+/* 16M alignment for crash kernel regions */
+#define CRASH_ALIGN		(16 << 20)
+
 /*
  * Keep the crash kernel below this limit.  On 32 bits earlier kernels
  * would limit the kernel to the low 512 MiB due to mapping restrictions.
@@ -496,7 +499,6 @@ static void __init memblock_x86_reserve_range_setup_data(void)
 static int __init reserve_crashkernel_low(void)
 {
 #ifdef CONFIG_X86_64
-	const unsigned long long alignment = 16<<20;	/* 16M */
 	unsigned long long low_base = 0, low_size = 0;
 	unsigned long total_low_mem;
 	unsigned long long base;
@@ -525,7 +527,7 @@ static int __init reserve_crashkernel_low(void)
 			return 0;
 	}
 
-	low_base = memblock_find_in_range(low_size, 1ULL << 32, low_size, alignment);
+	low_base = memblock_find_in_range(low_size, 1ULL << 32, low_size, CRASH_ALIGN);
 	if (!low_base) {
 		pr_err("Cannot reserve %ldMB crashkernel low memory, please try smaller size.\n",
 		       (unsigned long)(low_size >> 20));
@@ -548,7 +550,6 @@ static int __init reserve_crashkernel_low(void)
 
 static void __init reserve_crashkernel(void)
 {
-	const unsigned long long alignment = 16<<20;	/* 16M */
 	unsigned long long total_mem;
 	unsigned long long crash_size, crash_base;
 	bool high = false;
@@ -572,10 +573,10 @@ static void __init reserve_crashkernel(void)
 		/*
 		 *  kexec want bzImage is below CRASH_KERNEL_ADDR_MAX
 		 */
-		crash_base = memblock_find_in_range(alignment,
+		crash_base = memblock_find_in_range(CRASH_ALIGN,
 						    high ? CRASH_ADDR_HIGH_MAX
 							 : CRASH_ADDR_LOW_MAX,
-						    crash_size, alignment);
+						    crash_size, CRASH_ALIGN);
 		if (!crash_base) {
 			pr_info("crashkernel reservation failed - No suitable area found.\n");
 			return;
Signature · 1 line
2.3.5
#8 lore raw

[tip:ras/core] x86/setup/crash: Remove alignment variable

x86/setup/crash: Remove alignment variable
Commit-ID:  606134f77ce22997fd2800d5937698d85c6990d9
Gitweb:     http://git.kernel.org/tip/606134f77ce22997fd2800d5937698d85c6990d9
Author:     Borislav Petkov <[email protected]>
AuthorDate: Mon, 19 Oct 2015 11:17:44 +0200
Committer:  Ingo Molnar <[email protected]>
CommitDate: Wed, 21 Oct 2015 11:10:56 +0200

x86/setup/crash: Remove alignment variable

Use a macro instead. No functionality change.

---
 arch/x86/kernel/setup.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)
arch/x86/kernel/setup.c +6 -5
index fd9e178..ea086dd 100644
@@ -480,6 +480,9 @@ static void __init memblock_x86_reserve_range_setup_data(void)
 
 #ifdef CONFIG_KEXEC_CORE
 
+/* 16M alignment for crash kernel regions */
+#define CRASH_ALIGN		(16 << 20)
+
 /*
  * Keep the crash kernel below this limit.  On 32 bits earlier kernels
  * would limit the kernel to the low 512 MiB due to mapping restrictions.
@@ -496,7 +499,6 @@ static void __init memblock_x86_reserve_range_setup_data(void)
 static int __init reserve_crashkernel_low(void)
 {
 #ifdef CONFIG_X86_64
-	const unsigned long long alignment = 16<<20;	/* 16M */
 	unsigned long long low_base = 0, low_size = 0;
 	unsigned long total_low_mem;
 	unsigned long long base;
@@ -525,7 +527,7 @@ static int __init reserve_crashkernel_low(void)
 			return 0;
 	}
 
-	low_base = memblock_find_in_range(low_size, 1ULL << 32, low_size, alignment);
+	low_base = memblock_find_in_range(low_size, 1ULL << 32, low_size, CRASH_ALIGN);
 	if (!low_base) {
 		pr_err("Cannot reserve %ldMB crashkernel low memory, please try smaller size.\n",
 		       (unsigned long)(low_size >> 20));
@@ -548,7 +550,6 @@ static int __init reserve_crashkernel_low(void)
 
 static void __init reserve_crashkernel(void)
 {
-	const unsigned long long alignment = 16<<20;	/* 16M */
 	unsigned long long total_mem;
 	unsigned long long crash_size, crash_base;
 	bool high = false;
@@ -572,10 +573,10 @@ static void __init reserve_crashkernel(void)
 		/*
 		 *  kexec want bzImage is below CRASH_KERNEL_ADDR_MAX
 		 */
-		crash_base = memblock_find_in_range(alignment,
+		crash_base = memblock_find_in_range(CRASH_ALIGN,
 						    high ? CRASH_ADDR_HIGH_MAX
 							 : CRASH_ADDR_LOW_MAX,
-						    crash_size, alignment);
+						    crash_size, CRASH_ALIGN);
 		if (!crash_base) {
 			pr_info("crashkernel reservation failed - No suitable area found.\n");
 			return;
author maintainer
#9 lore raw

PATCH 5/8 x86/setup/crash: Cleanup some more

In reply to Borislav Petkov

From: Borislav Petkov <[email protected]>

* Remove unused auto_set variable
* Cleanup local function variable declarations
* Reformat printk string and use pr_info()

No functionality change.

Cc Andrew Morton <[email protected]>
Cc Andy Lutomirski <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc Jiri Kosina <[email protected]>
Cc Juergen Gross <[email protected]>
Cc Mark Salter <[email protected]>
Cc Thomas Gleixner <[email protected]>
Cc WANG Chao <[email protected]>
Cc x86-ml <[email protected]>
---
 arch/x86/kernel/setup.c | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)
arch/x86/kernel/setup.c +7 -12
index ea086dd8e821..d4788719a1e2 100644
@@ -499,17 +499,15 @@ static void __init memblock_x86_reserve_range_setup_data(void)
 static int __init reserve_crashkernel_low(void)
 {
 #ifdef CONFIG_X86_64
-	unsigned long long low_base = 0, low_size = 0;
+	unsigned long long base, low_base = 0, low_size = 0;
 	unsigned long total_low_mem;
-	unsigned long long base;
-	bool auto_set = false;
 	int ret;
 
 	total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
 
 	/* crashkernel=Y,low */
 	ret = parse_crashkernel_low(boot_command_line, total_low_mem, &low_size, &base);
-	if (ret != 0) {
+	if (ret) {
 		/*
 		 * two parts from lib/swiotlb.c:
 		 * -swiotlb size: user-specified with swiotlb= or default.
@@ -520,7 +518,6 @@ static int __init reserve_crashkernel_low(void)
 		 * don't run out of DMA buffers for 32-bit devices.
 		 */
 		low_size = max(swiotlb_size_or_default() + (8UL << 20), 256UL << 20);
-		auto_set = true;
 	} else {
 		/* passed with crashkernel=0,low ? */
 		if (!low_size)
@@ -550,8 +547,7 @@ static int __init reserve_crashkernel_low(void)
 
 static void __init reserve_crashkernel(void)
 {
-	unsigned long long total_mem;
-	unsigned long long crash_size, crash_base;
+	unsigned long long crash_size, crash_base, total_mem;
 	bool high = false;
 	int ret;
 
@@ -600,11 +596,10 @@ static void __init reserve_crashkernel(void)
 		return;
 	}
 
-	printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
-			"for crashkernel (System RAM: %ldMB)\n",
-			(unsigned long)(crash_size >> 20),
-			(unsigned long)(crash_base >> 20),
-			(unsigned long)(total_mem >> 20));
+	pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System RAM: %ldMB)\n",
+		(unsigned long)(crash_size >> 20),
+		(unsigned long)(crash_base >> 20),
+		(unsigned long)(total_mem >> 20));
 
 	crashk_res.start = crash_base;
 	crashk_res.end   = crash_base + crash_size - 1;
Signature · 1 line
2.3.5
#10 lore raw

[tip:ras/core] x86/setup/crash: Cleanup some more

x86/setup/crash: Cleanup some more
Commit-ID:  f56d55781c1ff5663874775d0672ba954fe5634c
Gitweb:     http://git.kernel.org/tip/f56d55781c1ff5663874775d0672ba954fe5634c
Author:     Borislav Petkov <[email protected]>
AuthorDate: Mon, 19 Oct 2015 11:17:45 +0200
Committer:  Ingo Molnar <[email protected]>
CommitDate: Wed, 21 Oct 2015 11:10:56 +0200

x86/setup/crash: Cleanup some more

* Remove unused auto_set variable
* Cleanup local function variable declarations
* Reformat printk string and use pr_info()

No functionality change.

---
 arch/x86/kernel/setup.c | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)
arch/x86/kernel/setup.c +7 -12
index ea086dd..d478871 100644
@@ -499,17 +499,15 @@ static void __init memblock_x86_reserve_range_setup_data(void)
 static int __init reserve_crashkernel_low(void)
 {
 #ifdef CONFIG_X86_64
-	unsigned long long low_base = 0, low_size = 0;
+	unsigned long long base, low_base = 0, low_size = 0;
 	unsigned long total_low_mem;
-	unsigned long long base;
-	bool auto_set = false;
 	int ret;
 
 	total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
 
 	/* crashkernel=Y,low */
 	ret = parse_crashkernel_low(boot_command_line, total_low_mem, &low_size, &base);
-	if (ret != 0) {
+	if (ret) {
 		/*
 		 * two parts from lib/swiotlb.c:
 		 * -swiotlb size: user-specified with swiotlb= or default.
@@ -520,7 +518,6 @@ static int __init reserve_crashkernel_low(void)
 		 * don't run out of DMA buffers for 32-bit devices.
 		 */
 		low_size = max(swiotlb_size_or_default() + (8UL << 20), 256UL << 20);
-		auto_set = true;
 	} else {
 		/* passed with crashkernel=0,low ? */
 		if (!low_size)
@@ -550,8 +547,7 @@ static int __init reserve_crashkernel_low(void)
 
 static void __init reserve_crashkernel(void)
 {
-	unsigned long long total_mem;
-	unsigned long long crash_size, crash_base;
+	unsigned long long crash_size, crash_base, total_mem;
 	bool high = false;
 	int ret;
 
@@ -600,11 +596,10 @@ static void __init reserve_crashkernel(void)
 		return;
 	}
 
-	printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
-			"for crashkernel (System RAM: %ldMB)\n",
-			(unsigned long)(crash_size >> 20),
-			(unsigned long)(crash_base >> 20),
-			(unsigned long)(total_mem >> 20));
+	pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System RAM: %ldMB)\n",
+		(unsigned long)(crash_size >> 20),
+		(unsigned long)(crash_base >> 20),
+		(unsigned long)(total_mem >> 20));
 
 	crashk_res.start = crash_base;
 	crashk_res.end   = crash_base + crash_size - 1;
author maintainer
#11 lore raw

PATCH 6/8 x86/setup/crash: Check memblock_reserve() retval

In reply to Borislav Petkov

From: Borislav Petkov <[email protected]>

memblock_reserve() can fail but the crashkernel reservation code doesn't check that and this can lead the user into believing that the crashkernel region was actually reserved. Make sure we check that return value and we exit early with a failure message in the error case.

Cc Andrew Morton <[email protected]>
Cc Andy Lutomirski <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc Jiri Kosina <[email protected]>
Cc Juergen Gross <[email protected]>
Cc Mark Salter <[email protected]>
Cc Thomas Gleixner <[email protected]>
Cc WANG Chao <[email protected]>
Cc x86-ml <[email protected]>
---
 arch/x86/kernel/setup.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
arch/x86/kernel/setup.c +10 -2
index d4788719a1e2..3f75297d5fd0 100644
@@ -531,7 +531,11 @@ static int __init reserve_crashkernel_low(void)
 		return -ENOMEM;
 	}
 
-	memblock_reserve(low_base, low_size);
+	ret = memblock_reserve(low_base, low_size);
+	if (ret) {
+		pr_err("%s: Error reserving crashkernel low memblock.\n", __func__);
+		return ret;
+	}
 
 	pr_info("Reserving %ldMB of low memory at %ldMB for crashkernel (System low RAM: %ldMB)\n",
 		(unsigned long)(low_size >> 20),
@@ -589,7 +593,11 @@ static void __init reserve_crashkernel(void)
 			return;
 		}
 	}
-	memblock_reserve(crash_base, crash_size);
+	ret = memblock_reserve(crash_base, crash_size);
+	if (ret) {
+		pr_err("%s: Error reserving crashkernel memblock.\n", __func__);
+		return;
+	}
 
 	if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) {
 		memblock_free(crash_base, crash_size);
Signature · 1 line
2.3.5
#12 lore raw

[tip:ras/core] x86/setup/crash: Check memblock_reserve() retval

x86/setup/crash: Check memblock_reserve() retval
Commit-ID:  6f3760570e26eefc214e641b6daeddb7106240bb
Gitweb:     http://git.kernel.org/tip/6f3760570e26eefc214e641b6daeddb7106240bb
Author:     Borislav Petkov <[email protected]>
AuthorDate: Mon, 19 Oct 2015 11:17:46 +0200
Committer:  Ingo Molnar <[email protected]>
CommitDate: Wed, 21 Oct 2015 11:10:56 +0200

x86/setup/crash: Check memblock_reserve() retval

memblock_reserve() can fail but the crashkernel reservation code doesn't check that and this can lead the user into believing that the crashkernel region was actually reserved. Make sure we check that return value and we exit early with a failure message in the error case.

---
 arch/x86/kernel/setup.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
arch/x86/kernel/setup.c +10 -2
index d478871..3f75297 100644
@@ -531,7 +531,11 @@ static int __init reserve_crashkernel_low(void)
 		return -ENOMEM;
 	}
 
-	memblock_reserve(low_base, low_size);
+	ret = memblock_reserve(low_base, low_size);
+	if (ret) {
+		pr_err("%s: Error reserving crashkernel low memblock.\n", __func__);
+		return ret;
+	}
 
 	pr_info("Reserving %ldMB of low memory at %ldMB for crashkernel (System low RAM: %ldMB)\n",
 		(unsigned long)(low_size >> 20),
@@ -589,7 +593,11 @@ static void __init reserve_crashkernel(void)
 			return;
 		}
 	}
-	memblock_reserve(crash_base, crash_size);
+	ret = memblock_reserve(crash_base, crash_size);
+	if (ret) {
+		pr_err("%s: Error reserving crashkernel memblock.\n", __func__);
+		return;
+	}
 
 	if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) {
 		memblock_free(crash_base, crash_size);
author maintainer
#13 lore raw

PATCH 7/8 kexec/crash: Say which char is the unrecognized

In reply to Borislav Petkov

From: Borislav Petkov <[email protected]>

It is helpful when the crashkernel cmdline parsing routines actually say which character is the unrecognized one. Make them do so.

Cc Andrew Morton <[email protected]>
Cc Andy Lutomirski <[email protected]>
Cc Baoquan He <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc Jiri Kosina <[email protected]>
Cc Juergen Gross <[email protected]>
Cc Mark Salter <[email protected]>
Cc Thomas Gleixner <[email protected]>
Cc Vivek Goyal <[email protected]>
Cc WANG Chao <[email protected]>
Cc x86-ml <[email protected]>
---
 kernel/kexec_core.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
kernel/kexec_core.c +3 -3
index 201b45327804..bd9f8a03cefa 100644
@@ -1149,7 +1149,7 @@ static int __init parse_crashkernel_simple(char *cmdline,
 	if (*cur == '@')
 		*crash_base = memparse(cur+1, &cur);
 	else if (*cur != ' ' && *cur != '\0') {
-		pr_warn("crashkernel: unrecognized char\n");
+		pr_warn("crashkernel: unrecognized char: %c\n", *cur);
 		return -EINVAL;
 	}
 
@@ -1186,12 +1186,12 @@ static int __init parse_crashkernel_suffix(char *cmdline,
 
 	/* check with suffix */
 	if (strncmp(cur, suffix, strlen(suffix))) {
-		pr_warn("crashkernel: unrecognized char\n");
+		pr_warn("crashkernel: unrecognized char: %c\n", *cur);
 		return -EINVAL;
 	}
 	cur += strlen(suffix);
 	if (*cur != ' ' && *cur != '\0') {
-		pr_warn("crashkernel: unrecognized char\n");
+		pr_warn("crashkernel: unrecognized char: %c\n", *cur);
 		return -EINVAL;
 	}
 
Signature · 1 line
2.3.5
#14 lore raw

[tip:ras/core] kexec/crash: Say which char is the unrecognized

kexec/crash: Say which char is the unrecognized
Commit-ID:  53b90c0c56b502056da83d768047dcf765bac9fb
Gitweb:     http://git.kernel.org/tip/53b90c0c56b502056da83d768047dcf765bac9fb
Author:     Borislav Petkov <[email protected]>
AuthorDate: Mon, 19 Oct 2015 11:17:47 +0200
Committer:  Ingo Molnar <[email protected]>
CommitDate: Wed, 21 Oct 2015 11:10:57 +0200

kexec/crash: Say which char is the unrecognized

It is helpful when the crashkernel cmdline parsing routines actually say which character is the unrecognized one. Make them do so.

Cc Andrew Morton <[email protected]>
Cc Andy Lutomirski <[email protected]>
Cc Baoquan He <[email protected]>
Cc H. Peter Anvin <[email protected]>
Cc Jiri Kosina <[email protected]>
Cc Juergen Gross <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Mark Salter <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
Cc Vivek Goyal <[email protected]>
Cc WANG Chao <[email protected]>
---
 kernel/kexec_core.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
kernel/kexec_core.c +3 -3
index 201b453..bd9f8a0 100644
@@ -1149,7 +1149,7 @@ static int __init parse_crashkernel_simple(char *cmdline,
 	if (*cur == '@')
 		*crash_base = memparse(cur+1, &cur);
 	else if (*cur != ' ' && *cur != '\0') {
-		pr_warn("crashkernel: unrecognized char\n");
+		pr_warn("crashkernel: unrecognized char: %c\n", *cur);
 		return -EINVAL;
 	}
 
@@ -1186,12 +1186,12 @@ static int __init parse_crashkernel_suffix(char *cmdline,
 
 	/* check with suffix */
 	if (strncmp(cur, suffix, strlen(suffix))) {
-		pr_warn("crashkernel: unrecognized char\n");
+		pr_warn("crashkernel: unrecognized char: %c\n", *cur);
 		return -EINVAL;
 	}
 	cur += strlen(suffix);
 	if (*cur != ' ' && *cur != '\0') {
-		pr_warn("crashkernel: unrecognized char\n");
+		pr_warn("crashkernel: unrecognized char: %c\n", *cur);
 		return -EINVAL;
 	}
 
author maintainer
#15 lore raw

PATCH 8/8 x86/mce: Fix thermal throttling reporting after kexec

In reply to Borislav Petkov

From: Andi Kleen <[email protected]>

The per CPU thermal vector init code checks if the thermal vector is already installed and complains and bails out if it is.

This happens after kexec, as kernel shut down does not clear the thermal vector APIC register.

This causes two problems:

1. So we always do not fully initialize thermal reports after kexec. The CPU is still likely initialized, as the previous kernel should have done it. But we don't set up the software pointer to the thermal vector, so reporting may end up with a unknown thermal interrupt message.

2. Also it complains for every logical CPU, even though the value is actually derived from BP only.

The problem is that we end up with one message per CPU, so on larger systems it becomes very noisy and messes up the otherwise nicely formatted CPU bootup numbers in the kernel log.

Just remove the check. I checked the code and there's no valid code paths where the thermal init code for a CPU could be called multiple times.

Why the kernel does not clean up this value on shutdown:

The thermal monitoring is controlled per logical CPU thread. Normal shutdown code is just running on one CPU. To disable it we would need a broadcast NMI to all CPUs on shut down. That's overkill for this. So we just ignore it after kexec.

---
 arch/x86/kernel/cpu/mcheck/therm_throt.c | 8 --------
 1 file changed, 8 deletions(-)
arch/x86/kernel/cpu/mcheck/therm_throt.c +0 -8
index 1af51b1586d7..2c5aaf8c2e2f 100644
@@ -503,14 +503,6 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
 		return;
 	}
 
-	/* Check whether a vector already exists */
-	if (h & APIC_VECTOR_MASK) {
-		printk(KERN_DEBUG
-		       "CPU%d: Thermal LVT vector (%#x) already installed\n",
-		       cpu, (h & APIC_VECTOR_MASK));
-		return;
-	}
-
 	/* early Pentium M models use different method for enabling TM2 */
 	if (cpu_has(c, X86_FEATURE_TM2)) {
 		if (c->x86 == 6 && (c->x86_model == 9 || c->x86_model == 13)) {
Signature · 1 line
2.3.5
#16 lore raw

[tip:ras/core] x86/mce: Fix thermal throttling reporting after kexec

x86/mce: Fix thermal throttling reporting after kexec
Commit-ID:  81ffdcdd97d94110627caa81c23d5d780083731d
Gitweb:     http://git.kernel.org/tip/81ffdcdd97d94110627caa81c23d5d780083731d
Author:     Andi Kleen <[email protected]>
AuthorDate: Mon, 19 Oct 2015 11:17:48 +0200
Committer:  Ingo Molnar <[email protected]>
CommitDate: Wed, 21 Oct 2015 11:10:57 +0200

x86/mce: Fix thermal throttling reporting after kexec

The per CPU thermal vector init code checks if the thermal vector is already installed and complains and bails out if it is.

This happens after kexec, as kernel shut down does not clear the thermal vector APIC register.

This causes two problems:

1. So we always do not fully initialize thermal reports after kexec. The CPU is still likely initialized, as the previous kernel should have done it. But we don't set up the software pointer to the thermal vector, so reporting may end up with a unknown thermal interrupt message.

2. Also it complains for every logical CPU, even though the value is actually derived from BP only.

The problem is that we end up with one message per CPU, so on larger systems it becomes very noisy and messes up the otherwise nicely formatted CPU bootup numbers in the kernel log.

Just remove the check. I checked the code and there's no valid code paths where the thermal init code for a CPU could be called multiple times.

Why the kernel does not clean up this value on shutdown:

The thermal monitoring is controlled per logical CPU thread. Normal shutdown code is just running on one CPU. To disable it we would need a broadcast NMI to all CPUs on shut down. That's overkill for this. So we just ignore it after kexec.

---
 arch/x86/kernel/cpu/mcheck/therm_throt.c | 8 --------
 1 file changed, 8 deletions(-)
arch/x86/kernel/cpu/mcheck/therm_throt.c +0 -8
index 1af51b1..2c5aaf8 100644
@@ -503,14 +503,6 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
 		return;
 	}
 
-	/* Check whether a vector already exists */
-	if (h & APIC_VECTOR_MASK) {
-		printk(KERN_DEBUG
-		       "CPU%d: Thermal LVT vector (%#x) already installed\n",
-		       cpu, (h & APIC_VECTOR_MASK));
-		return;
-	}
-
 	/* early Pentium M models use different method for enabling TM2 */
 	if (cpu_has(c, X86_FEATURE_TM2)) {
 		if (c->x86 == 6 && (c->x86_model == 9 || c->x86_model == 13)) {