Message ID | 20191004093747.31350-31-david@gibson.dropbear.id.au (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [PULL,01/53] pseries: do not allow memory-less/cpu-less NUMA node | expand |
On 04/10/2019 11:37, David Gibson wrote: > From: Alexey Kardashevskiy <aik@ozlabs.ru> > > The ibm,client-architecture-support call is a way for the guest to > negotiate capabilities with a hypervisor. It is implemented as: > - the guest calls SLOF via client interface; > - SLOF calls QEMU (H_CAS hypercall) with an options vector from the guest; > - QEMU returns a device tree diff (which uses FDT format with > an additional header before it); > - SLOF walks through the partial diff tree and updates its internal tree > with the values from the diff. > > This changes QEMU to simply re-render the entire tree and send it as > an update. SLOF can handle this already mostly, [1] is needed before this > can be applied. This stores the resulting tree in the spapr machine to have > the latest valid FDT copy possible (this should not matter much as > H_UPDATE_DT happens right after that but nevertheless). > > The benefit is reduced code size as there is no need for another set of > DT rendering helpers such as spapr_fixup_cpu_dt(). > > The downside is that the updates are bigger now (as they include all > nodes and properties) but the difference on a '-smp 256,threads=1' system > before/after is 2.35s vs. 2.5s. > > [1] https://patchwork.ozlabs.org/patch/1152915/ > > Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> > Signed-off-by: David Gibson <david@gibson.dropbear.id.au> > --- > hw/ppc/spapr.c | 88 ++++++-------------------------------------------- > 1 file changed, 9 insertions(+), 79 deletions(-) [Resend the comment I sent to another patch by mistake] This patch breaks pseries boot when we use a pci-bridge (since v4.2.0-rc0): ... -device pci-bridge,id=pci_bridge1,bus=pci.0,addr=0x3,chassis_nr=1 \ -device virtio-scsi-pci,bus=pci_bridge1 \ ... OF stdout device is: /vdevice/vty@71000000 Preparing to boot Linux version 5.4.0-rc3+ (lvivier@localhost) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)) #2 SMP Wed Nov 13 09:08:20 EST 2019 Detected machine type: 0000000000000101 command line: BOOT_IMAGE=/vmlinuz-5.4.0-rc3+ root=/dev/mapper/rhel-root ro crashkernel=auto rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap Max number of cores passed to firmware: 2048 (NR_CPUS = 2048) Calling ibm,client-architecture-support... ( 300 ) Data Storage Exception [ 1dc5f230 ] R0 .. R7 R8 .. R15 R16 .. R23 R24 .. R31 8000000000001000 000000001e477010 0000000000000000 000000001dc17500 000000001e67afe0 0000000020000004 0000000000000000 000000001dc1bf88 000000001dc21800 000000001dc5f248 000000001e477010 0000000000000003 000000001dc61000 000000001e78dc2d 000000001dc1c158 000000000000f001 0000000000000000 a000000000000001 0000000000008000 000000001e67b060 000000001dc5f230 0000000000000000 000000000000f003 ffffffffffffffff 000000001e745860 0000000000000000 0000000000000006 000000001dbf48f8 000000001dc5f248 0000000000000000 000000001e67b050 000000001dc1c350 CR / XER LR / CTR SRR0 / SRR1 DAR / DSISR 80000808 000000001dbf34d4 000000001dbf4194 0000000020000004 0000000020000000 000000001dbf48f8 8000000000001000 40000000 4a > Thanks, Laurent
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 3742a8cf06..43920c140d 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -295,64 +295,6 @@ static void spapr_populate_pa_features(SpaprMachineState *spapr, _FDT((fdt_setprop(fdt, offset, "ibm,pa-features", pa_features, pa_size))); } -static int spapr_fixup_cpu_dt(void *fdt, SpaprMachineState *spapr) -{ - MachineState *ms = MACHINE(spapr); - int ret = 0, offset, cpus_offset; - CPUState *cs; - char cpu_model[32]; - uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)}; - - CPU_FOREACH(cs) { - PowerPCCPU *cpu = POWERPC_CPU(cs); - DeviceClass *dc = DEVICE_GET_CLASS(cs); - int index = spapr_get_vcpu_id(cpu); - int compat_smt = MIN(ms->smp.threads, ppc_compat_max_vthreads(cpu)); - - if (!spapr_is_thread0_in_vcore(spapr, cpu)) { - continue; - } - - snprintf(cpu_model, 32, "%s@%x", dc->fw_name, index); - - cpus_offset = fdt_path_offset(fdt, "/cpus"); - if (cpus_offset < 0) { - cpus_offset = fdt_add_subnode(fdt, 0, "cpus"); - if (cpus_offset < 0) { - return cpus_offset; - } - } - offset = fdt_subnode_offset(fdt, cpus_offset, cpu_model); - if (offset < 0) { - offset = fdt_add_subnode(fdt, cpus_offset, cpu_model); - if (offset < 0) { - return offset; - } - } - - ret = fdt_setprop(fdt, offset, "ibm,pft-size", - pft_size_prop, sizeof(pft_size_prop)); - if (ret < 0) { - return ret; - } - - if (ms->numa_state->num_nodes > 1) { - ret = spapr_fixup_cpu_numa_dt(fdt, offset, cpu); - if (ret < 0) { - return ret; - } - } - - ret = spapr_fixup_cpu_smt_dt(fdt, offset, cpu, compat_smt); - if (ret < 0) { - return ret; - } - - spapr_populate_pa_features(spapr, cpu, fdt, offset); - } - return ret; -} - static hwaddr spapr_node0_size(MachineState *machine) { if (machine->numa_state->num_nodes) { @@ -983,11 +925,13 @@ static bool spapr_hotplugged_dev_before_cas(void) return false; } +static void *spapr_build_fdt(SpaprMachineState *spapr); + int spapr_h_cas_compose_response(SpaprMachineState *spapr, target_ulong addr, target_ulong size, SpaprOptionVector *ov5_updates) { - void *fdt, *fdt_skel; + void *fdt; SpaprDeviceTreeUpdateHeader hdr = { .version_id = 1 }; if (spapr_hotplugged_dev_before_cas()) { @@ -1003,25 +947,7 @@ int spapr_h_cas_compose_response(SpaprMachineState *spapr, size -= sizeof(hdr); - /* Create skeleton */ - fdt_skel = g_malloc0(size); - _FDT((fdt_create(fdt_skel, size))); - _FDT((fdt_finish_reservemap(fdt_skel))); - _FDT((fdt_begin_node(fdt_skel, ""))); - _FDT((fdt_end_node(fdt_skel))); - _FDT((fdt_finish(fdt_skel))); - fdt = g_malloc0(size); - _FDT((fdt_open_into(fdt_skel, fdt, size))); - g_free(fdt_skel); - - /* Fixup cpu nodes */ - _FDT((spapr_fixup_cpu_dt(fdt, spapr))); - - if (spapr_dt_cas_updates(spapr, fdt, ov5_updates)) { - return -1; - } - - /* Pack resulting tree */ + fdt = spapr_build_fdt(spapr); _FDT((fdt_pack(fdt))); if (fdt_totalsize(fdt) + sizeof(hdr) > size) { @@ -1033,7 +959,11 @@ int spapr_h_cas_compose_response(SpaprMachineState *spapr, cpu_physical_memory_write(addr, &hdr, sizeof(hdr)); cpu_physical_memory_write(addr + sizeof(hdr), fdt, fdt_totalsize(fdt)); trace_spapr_cas_continue(fdt_totalsize(fdt) + sizeof(hdr)); - g_free(fdt); + + g_free(spapr->fdt_blob); + spapr->fdt_size = fdt_totalsize(fdt); + spapr->fdt_initial_size = spapr->fdt_size; + spapr->fdt_blob = fdt; return 0; }