svn commit: r352497 - in stable/12/sys: arm64/acpica arm64/arm64 conf dev/acpica

Jayachandran C. jchandra at FreeBSD.org
Wed Sep 18 22:55:26 UTC 2019


Author: jchandra
Date: Wed Sep 18 22:55:24 2019
New Revision: 352497
URL: https://svnweb.freebsd.org/changeset/base/352497

Log:
  MFC r341743-r341744
  
  r341743:
  acpica: support parsing of arm64 affinity in acpi_pxm.c
  
  ACPI SRAT table on arm64 uses GICC entries to provide CPU locality
  information. These entries use an AcpiProcessorUid to identify the
  CPU (unlike on x86 where the entries have an APIC ID).
  
  Update acpi_pxm.c to extend the cpu_add/cpu_find/cpu_get_info
  functions to handle AcpiProcessorUid. Use the updated functions
  while parsing ACPI_SRAT_GICC_AFFINITY entry for arm64.
  
  Also update sys/conf/files.arm64 to build acpi_pxm.c when ACPI is
  enabled.
  
  Reviewed by:	markj (previous version)
  Differential Revision:	https://reviews.freebsd.org/D17942
  
  r341744:
  arm64: add ACPI based NUMA support
  
  Use the newly defined SRAT/SLIT parsing APIs in arm64 to support
  ACPI based NUMA.
  
  Reviewed by:	markj

Modified:
  stable/12/sys/arm64/acpica/acpi_machdep.c
  stable/12/sys/arm64/arm64/mp_machdep.c
  stable/12/sys/conf/files.arm64
  stable/12/sys/dev/acpica/acpi_pxm.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/arm64/acpica/acpi_machdep.c
==============================================================================
--- stable/12/sys/arm64/acpica/acpi_machdep.c	Wed Sep 18 22:44:59 2019	(r352496)
+++ stable/12/sys/arm64/acpica/acpi_machdep.c	Wed Sep 18 22:55:24 2019	(r352497)
@@ -233,3 +233,16 @@ acpi_map_addr(struct acpi_generic_address *addr, bus_s
 
 	return (bus_space_map(*tag, phys, size, 0, handle));
 }
+
+#if MAXMEMDOM > 1
+static void
+parse_pxm_tables(void *dummy)
+{
+
+	acpi_pxm_init(MAXCPU, (vm_paddr_t)1 << 40);
+	acpi_pxm_parse_tables();
+	acpi_pxm_set_mem_locality();
+}
+SYSINIT(parse_pxm_tables, SI_SUB_VM - 1, SI_ORDER_FIRST, parse_pxm_tables,
+    NULL);
+#endif

Modified: stable/12/sys/arm64/arm64/mp_machdep.c
==============================================================================
--- stable/12/sys/arm64/arm64/mp_machdep.c	Wed Sep 18 22:44:59 2019	(r352496)
+++ stable/12/sys/arm64/arm64/mp_machdep.c	Wed Sep 18 22:55:24 2019	(r352497)
@@ -520,13 +520,15 @@ madt_handler(ACPI_SUBTABLE_HEADER *entry, void *arg)
 {
 	ACPI_MADT_GENERIC_INTERRUPT *intr;
 	u_int *cpuid;
+	u_int id;
 
 	switch(entry->Type) {
 	case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
 		intr = (ACPI_MADT_GENERIC_INTERRUPT *)entry;
 		cpuid = arg;
-
-		start_cpu((*cpuid), intr->ArmMpidr);
+		id = *cpuid;
+		start_cpu(id, intr->ArmMpidr);
+		__pcpu[id].pc_acpi_id = intr->Uid;
 		(*cpuid)++;
 		break;
 	default:
@@ -556,6 +558,12 @@ cpu_init_acpi(void)
 	    madt_handler, &cpuid);
 
 	acpi_unmap_table(madt);
+
+#if MAXMEMDOM > 1
+	/* set proximity info */
+	acpi_pxm_set_cpu_locality();
+	acpi_pxm_free();
+#endif
 }
 #endif
 

Modified: stable/12/sys/conf/files.arm64
==============================================================================
--- stable/12/sys/conf/files.arm64	Wed Sep 18 22:44:59 2019	(r352496)
+++ stable/12/sys/conf/files.arm64	Wed Sep 18 22:55:24 2019	(r352497)
@@ -203,6 +203,7 @@ dev/acpica/acpi_bus_if.m	optional	acpi
 dev/acpica/acpi_if.m		optional	acpi
 dev/acpica/acpi_pci_link.c	optional	acpi pci
 dev/acpica/acpi_pcib.c		optional	acpi pci
+dev/acpica/acpi_pxm.c		optional	acpi
 dev/ahci/ahci_generic.c		optional	ahci
 dev/axgbe/if_axgbe.c		optional	axgbe
 dev/axgbe/xgbe-desc.c		optional	axgbe

Modified: stable/12/sys/dev/acpica/acpi_pxm.c
==============================================================================
--- stable/12/sys/dev/acpica/acpi_pxm.c	Wed Sep 18 22:44:59 2019	(r352496)
+++ stable/12/sys/dev/acpica/acpi_pxm.c	Wed Sep 18 22:55:24 2019	(r352497)
@@ -59,6 +59,7 @@ static struct cpu_info {
 	int enabled:1;
 	int has_memory:1;
 	int domain;
+	int id;
 } *cpus;
 
 static int max_cpus;
@@ -182,14 +183,33 @@ overlaps_phys_avail(vm_paddr_t start, vm_paddr_t end)
 }
 
 /*
- * Find CPU by processor ID (APIC ID on x86).
+ * On x86 we can use the cpuid to index the cpus array, but on arm64
+ * we have an ACPI Processor UID with a larger range.
+ *
+ * Use this variable to indicate if the cpus can be stored by index.
  */
+#ifdef __aarch64__
+static const int cpus_use_indexing = 0;
+#else
+static const int cpus_use_indexing = 1;
+#endif
+
+/*
+ * Find CPU by processor ID (APIC ID on x86, Processor UID on arm64)
+ */
 static struct cpu_info *
 cpu_find(int cpuid)
 {
+	int i;
 
-	if (cpuid <= last_cpu && cpus[cpuid].enabled)
-		return (&cpus[cpuid]);
+	if (cpus_use_indexing) {
+		if (cpuid <= last_cpu && cpus[cpuid].enabled)
+			return (&cpus[cpuid]);
+	} else {
+		for (i = 0; i <= last_cpu; i++)
+			if (cpus[i].id == cpuid)
+				return (&cpus[i]);
+	}
 	return (NULL);
 }
 
@@ -202,10 +222,14 @@ cpu_get_info(struct pcpu *pc)
 	struct cpu_info *cpup;
 	int id;
 
+#ifdef __aarch64__
+	id = pc->pc_acpi_id;
+#else
 	id = pc->pc_apic_id;
+#endif
 	cpup = cpu_find(id);
 	if (cpup == NULL)
-		panic("SRAT: CPU with APIC ID %u is not known", id);
+		panic("SRAT: CPU with ID %u is not known", id);
 	return (cpup);
 }
 
@@ -217,11 +241,18 @@ cpu_add(int cpuid, int domain)
 {
 	struct cpu_info *cpup;
 
-	if (cpuid >= max_cpus)
-		return (NULL);
-	last_cpu = imax(last_cpu, cpuid);
-	cpup = &cpus[cpuid];
+	if (cpus_use_indexing) {
+		if (cpuid >= max_cpus)
+			return (NULL);
+		last_cpu = imax(last_cpu, cpuid);
+		cpup = &cpus[cpuid];
+	} else {
+		if (last_cpu >= max_cpus - 1)
+			return (NULL);
+		cpup = &cpus[++last_cpu];
+	}
 	cpup->domain = domain;
+	cpup->id = cpuid;
 	cpup->enabled = 1;
 	return (cpup);
 }
@@ -232,6 +263,7 @@ srat_parse_entry(ACPI_SUBTABLE_HEADER *entry, void *ar
 	ACPI_SRAT_CPU_AFFINITY *cpu;
 	ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic;
 	ACPI_SRAT_MEM_AFFINITY *mem;
+	ACPI_SRAT_GICC_AFFINITY *gicc;
 	static struct cpu_info *cpup;
 	int domain, i, slot;
 
@@ -276,6 +308,22 @@ srat_parse_entry(ACPI_SUBTABLE_HEADER *entry, void *ar
 		if (cpup == NULL)
 			printf("SRAT: Ignoring local APIC ID %u (too high)\n",
 			    x2apic->ApicId);
+		break;
+	case ACPI_SRAT_TYPE_GICC_AFFINITY:
+		gicc = (ACPI_SRAT_GICC_AFFINITY *)entry;
+		if (bootverbose)
+			printf("SRAT: Found CPU UID %u domain %d: %s\n",
+			    gicc->AcpiProcessorUid, gicc->ProximityDomain,
+			    (gicc->Flags & ACPI_SRAT_GICC_ENABLED) ?
+			    "enabled" : "disabled");
+		if (!(gicc->Flags & ACPI_SRAT_GICC_ENABLED))
+			break;
+		KASSERT(cpu_find(gicc->AcpiProcessorUid) == NULL,
+		    ("Duplicate CPU UID %u", gicc->AcpiProcessorUid));
+		cpup = cpu_add(gicc->AcpiProcessorUid, gicc->ProximityDomain);
+		if (cpup == NULL)
+			printf("SRAT: Ignoring CPU UID %u (too high)\n",
+			    gicc->AcpiProcessorUid);
 		break;
 	case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
 		mem = (ACPI_SRAT_MEM_AFFINITY *)entry;


More information about the svn-src-stable-12 mailing list