Patchwork [seabios,2/2] acpi: change numa data format from fw_cfg interface

login
register
mail settings
Submitter liguang
Date Feb. 4, 2013, 2:28 a.m.
Message ID <1359944880-6039-9-git-send-email-lig.fnst@cn.fujitsu.com>
Download mbox | patch
Permalink /patch/217819/
State New
Headers show

Comments

liguang - Feb. 4, 2013, 2:28 a.m.
the old numa format got form fw_cfg is:
number of nodes
node id of cpu (array)
node memory size (array)

now, format it like array of:
apci_map,
memory_size,

it has the advantage of simple and clear.

Signed-off-by: liguang <lig.fnst@cn.fujitsu.com>
---
 src/acpi.c     |   57 ++++++++++++++++++++++++++++++++++++-------------------
 src/acpi.h     |    5 ++++
 src/paravirt.c |    2 +-
 src/paravirt.h |    1 +
 4 files changed, 44 insertions(+), 21 deletions(-)
Kevin O'Connor - Feb. 7, 2013, 4:18 a.m.
On Mon, Feb 04, 2013 at 10:28:00AM +0800, liguang wrote:
> the old numa format got form fw_cfg is:
> number of nodes
> node id of cpu (array)
> node memory size (array)
> 
> now, format it like array of:
> apci_map,
> memory_size,
> 
> it has the advantage of simple and clear.

With this change, will old versions of seabios work with new versions
of qemu, and old versions of qemu work with new versions of seabios?

Also, can you provide a high-level summary of why this change is
useful to an end-user?

-Kevin
liguang - Feb. 15, 2013, 1:09 a.m.
Sorry for late reply

在 2013-02-06三的 23:18 -0500,Kevin O'Connor写道:
> On Mon, Feb 04, 2013 at 10:28:00AM +0800, liguang wrote:
> > the old numa format got form fw_cfg is:
> > number of nodes
> > node id of cpu (array)
> > node memory size (array)
> > 
> > now, format it like array of:
> > apci_map,
> > memory_size,
> > 
> > it has the advantage of simple and clear.
> 
> With this change, will old versions of seabios work with new versions
> of qemu, and old versions of qemu work with new versions of seabios?

may be not.

> 
> Also, can you provide a high-level summary of why this change is
> useful to an end-user?

This change have nothing to do with end-user,
just for clear design.

> 
> -Kevin
>

Patch

diff --git a/src/acpi.c b/src/acpi.c
index fde37e5..7004a60 100644
--- a/src/acpi.c
+++ b/src/acpi.c
@@ -473,44 +473,57 @@  acpi_build_srat_memory(struct srat_memory_affinity *numamem,
 static void *
 build_srat(void)
 {
-    int nb_numa_nodes = qemu_cfg_get_numa_nodes();
+    int nr_nodes = qemu_cfg_get_numa_nodes();
+    int *node_cpu = malloc_tmp(sizeof(int));
 
-    if (nb_numa_nodes == 0)
+    if (nr_nodes == 0)
         return NULL;
 
-    u64 *numadata = malloc_tmphigh(sizeof(u64) * (MaxCountCPUs + nb_numa_nodes));
-    if (!numadata) {
+    if (!node_cpu)
+        return NULL;
+
+    struct srat_data *sd = malloc_tmp(sizeof(struct srat_data)*nr_nodes);
+    if (!sd) {
         warn_noalloc();
         return NULL;
     }
 
-    qemu_cfg_get_numa_data(numadata, MaxCountCPUs + nb_numa_nodes);
+    qemu_cfg_get_numa_data((u64 *)sd, nr_nodes);
 
     struct system_resource_affinity_table *srat;
     int srat_size = sizeof(*srat) +
         sizeof(struct srat_processor_affinity) * MaxCountCPUs +
-        sizeof(struct srat_memory_affinity) * (nb_numa_nodes + 2);
+        sizeof(struct srat_memory_affinity) * (nr_nodes + 2);
 
     srat = malloc_high(srat_size);
     if (!srat) {
         warn_noalloc();
-        free(numadata);
+        free(srat);
         return NULL;
     }
 
     memset(srat, 0, srat_size);
-    srat->reserved1=1;
+    srat->reserved1 = 1;
     struct srat_processor_affinity *core = (void*)(srat + 1);
-    int i;
+    int i, j;
     u64 curnode;
 
+    for (i = 0; i < nr_nodes; i++) {
+        if (sd[i].apic_map == 0)
+            continue;
+        for (j = 0; j < MaxCountCPUs; j++) {
+            if (sd[i].apic_map & 1 << j)
+                node_cpu[j] = i;
+        }
+    }
+
     for (i = 0; i < MaxCountCPUs; ++i) {
         core->type = SRAT_PROCESSOR;
         core->length = sizeof(*core);
         core->local_apic_id = i;
-        curnode = *numadata++;
+        curnode = i;
         core->proximity_lo = curnode;
-        memset(core->proximity_hi, 0, 3);
+        memset(core->proximity_hi, 0, sizeof(core->proximity_hi));
         core->local_sapic_eid = 0;
         if (apic_id_is_present(i))
             core->flags = cpu_to_le32(1);
@@ -527,15 +540,19 @@  build_srat(void)
     int slots = 0;
     u64 mem_len, mem_base, next_base = 0;
 
-    acpi_build_srat_memory(numamem, 0, 640*1024, 0, 1);
-    next_base = 1024 * 1024;
+#define MEM_1K (1UL << 10)
+#define MEM_1M (1UL << 20)
+#define MEM_1G (1ULL << 30)
+
+    acpi_build_srat_memory(numamem, 0, 640*MEM_1K, 0, 1);
+    next_base = MEM_1M;
     numamem++;
     slots++;
-    for (i = 1; i < nb_numa_nodes + 1; ++i) {
+    for (i = 1; i < nr_nodes + 1; ++i) {
         mem_base = next_base;
-        mem_len = *numadata++;
+        mem_len = sd[i].memory_size;
         if (i == 1)
-            mem_len -= 1024 * 1024;
+            mem_len -= MEM_1M;
         next_base = mem_base + mem_len;
 
         /* Cut out the PCI hole */
@@ -546,22 +563,22 @@  build_srat(void)
                 numamem++;
                 slots++;
             }
-            mem_base = 1ULL << 32;
+            mem_base = MEM_1G;
             mem_len = next_base - RamSize;
-            next_base += (1ULL << 32) - RamSize;
+            next_base += MEM_1G - RamSize;
         }
         acpi_build_srat_memory(numamem, mem_base, mem_len, i-1, 1);
         numamem++;
         slots++;
     }
-    for (; slots < nb_numa_nodes + 2; slots++) {
+    for (; slots < nr_nodes + 2; slots++) {
         acpi_build_srat_memory(numamem, 0, 0, 0, 0);
         numamem++;
     }
 
     build_header((void*)srat, SRAT_SIGNATURE, srat_size, 1);
 
-    free(numadata);
+    free(sd);
     return srat;
 }
 
diff --git a/src/acpi.h b/src/acpi.h
index 996edcb..bfa2c79 100644
--- a/src/acpi.h
+++ b/src/acpi.h
@@ -321,6 +321,11 @@  struct srat_memory_affinity
     u32    reserved3[2];
 } PACKED;
 
+struct srat_data {
+    u64 apic_map;
+    u64 memory_size;
+};
+
 #include "acpi-dsdt.hex"
 
 
diff --git a/src/paravirt.c b/src/paravirt.c
index 4b5c441..e143ca7 100644
--- a/src/paravirt.c
+++ b/src/paravirt.c
@@ -291,7 +291,7 @@  void qemu_cfg_get_numa_data(u64 *data, int n)
     int i;
 
     for (i = 0; i < n; i++)
-        qemu_cfg_read((u8*)(data + i), sizeof(u64));
+        qemu_cfg_read((u8*)(data + i), sizeof(struct srat_data));
 }
 
 u16 qemu_cfg_get_max_cpus(void)
diff --git a/src/paravirt.h b/src/paravirt.h
index a284c41..2b25c4f 100644
--- a/src/paravirt.h
+++ b/src/paravirt.h
@@ -3,6 +3,7 @@ 
 
 #include "config.h" // CONFIG_COREBOOT
 #include "util.h"
+#include "acpi.h"
 
 /* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx.  It
  * should be used to determine that a VM is running under KVM.