Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 095adbb6 authored by Thomas Renninger's avatar Thomas Renninger Committed by Len Brown
Browse files

ACPI: Only count valid srat memory structures

Otherwise you could run into:
WARN_ON in numa_register_memblks(), because node_possible_map is zero

References: https://bugzilla.novell.com/show_bug.cgi?id=757888



On this machine (ProLiant ML570 G3) the SRAT table contains:
  - No processor affinities
  - One memory affinity structure (which is set disabled)

CC: Per Jessen <per@opensuse.org>
CC: Andi Kleen <andi@firstfloor.org>
Signed-off-by: default avatarThomas Renninger <trenn@suse.de>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent f3946fb6
Loading
Loading
Loading
Loading
+3 −2
Original line number Original line Diff line number Diff line
@@ -497,7 +497,7 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
	srat_num_cpus++;
	srat_num_cpus++;
}
}


void __init
int __init
acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
{
{
	unsigned long paddr, size;
	unsigned long paddr, size;
@@ -512,7 +512,7 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)


	/* Ignore disabled entries */
	/* Ignore disabled entries */
	if (!(ma->flags & ACPI_SRAT_MEM_ENABLED))
	if (!(ma->flags & ACPI_SRAT_MEM_ENABLED))
		return;
		return -1;


	/* record this node in proximity bitmap */
	/* record this node in proximity bitmap */
	pxm_bit_set(pxm);
	pxm_bit_set(pxm);
@@ -531,6 +531,7 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
	p->size = size;
	p->size = size;
	p->nid = pxm;
	p->nid = pxm;
	num_node_memblks++;
	num_node_memblks++;
	return 0;
}
}


void __init acpi_numa_arch_fixup(void)
void __init acpi_numa_arch_fixup(void)
+8 −7
Original line number Original line Diff line number Diff line
@@ -142,23 +142,23 @@ static inline int save_add_info(void) {return 0;}
#endif
#endif


/* Callback for parsing of the Proximity Domain <-> Memory Area mappings */
/* Callback for parsing of the Proximity Domain <-> Memory Area mappings */
void __init
int __init
acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
{
{
	u64 start, end;
	u64 start, end;
	int node, pxm;
	int node, pxm;


	if (srat_disabled())
	if (srat_disabled())
		return;
		return -1;
	if (ma->header.length != sizeof(struct acpi_srat_mem_affinity)) {
	if (ma->header.length != sizeof(struct acpi_srat_mem_affinity)) {
		bad_srat();
		bad_srat();
		return;
		return -1;
	}
	}
	if ((ma->flags & ACPI_SRAT_MEM_ENABLED) == 0)
	if ((ma->flags & ACPI_SRAT_MEM_ENABLED) == 0)
		return;
		return -1;


	if ((ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) && !save_add_info())
	if ((ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) && !save_add_info())
		return;
		return -1;
	start = ma->base_address;
	start = ma->base_address;
	end = start + ma->length;
	end = start + ma->length;
	pxm = ma->proximity_domain;
	pxm = ma->proximity_domain;
@@ -168,12 +168,12 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
	if (node < 0) {
	if (node < 0) {
		printk(KERN_ERR "SRAT: Too many proximity domains.\n");
		printk(KERN_ERR "SRAT: Too many proximity domains.\n");
		bad_srat();
		bad_srat();
		return;
		return -1;
	}
	}


	if (numa_add_memblk(node, start, end) < 0) {
	if (numa_add_memblk(node, start, end) < 0) {
		bad_srat();
		bad_srat();
		return;
		return -1;
	}
	}


	node_set(node, numa_nodes_parsed);
	node_set(node, numa_nodes_parsed);
@@ -181,6 +181,7 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
	printk(KERN_INFO "SRAT: Node %u PXM %u [mem %#010Lx-%#010Lx]\n",
	printk(KERN_INFO "SRAT: Node %u PXM %u [mem %#010Lx-%#010Lx]\n",
	       node, pxm,
	       node, pxm,
	       (unsigned long long) start, (unsigned long long) end - 1);
	       (unsigned long long) start, (unsigned long long) end - 1);
	return 0;
}
}


void __init acpi_numa_arch_fixup(void) {}
void __init acpi_numa_arch_fixup(void) {}
+5 −3
Original line number Original line Diff line number Diff line
@@ -237,6 +237,8 @@ acpi_parse_processor_affinity(struct acpi_subtable_header *header,
	return 0;
	return 0;
}
}


static int __initdata parsed_numa_memblks;

static int __init
static int __init
acpi_parse_memory_affinity(struct acpi_subtable_header * header,
acpi_parse_memory_affinity(struct acpi_subtable_header * header,
			   const unsigned long end)
			   const unsigned long end)
@@ -250,8 +252,8 @@ acpi_parse_memory_affinity(struct acpi_subtable_header * header,
	acpi_table_print_srat_entry(header);
	acpi_table_print_srat_entry(header);


	/* let architecture-dependent part to do it */
	/* let architecture-dependent part to do it */
	acpi_numa_memory_affinity_init(memory_affinity);
	if (!acpi_numa_memory_affinity_init(memory_affinity))

		parsed_numa_memblks++;
	return 0;
	return 0;
}
}


@@ -306,7 +308,7 @@ int __init acpi_numa_init(void)


	if (cnt < 0)
	if (cnt < 0)
		return cnt;
		return cnt;
	else if (cnt == 0)
	else if (!parsed_numa_memblks)
		return -ENOENT;
		return -ENOENT;
	return 0;
	return 0;
}
}
+1 −1
Original line number Original line Diff line number Diff line
@@ -96,7 +96,7 @@ void acpi_table_print_madt_entry (struct acpi_subtable_header *madt);
void acpi_numa_slit_init (struct acpi_table_slit *slit);
void acpi_numa_slit_init (struct acpi_table_slit *slit);
void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa);
void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa);
void acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa);
void acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa);
void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);
int acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);
void acpi_numa_arch_fixup(void);
void acpi_numa_arch_fixup(void);


#ifdef CONFIG_ACPI_HOTPLUG_CPU
#ifdef CONFIG_ACPI_HOTPLUG_CPU