From patchwork Fri Jun 10 00:59:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bharata B Rao X-Patchwork-Id: 9168723 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id CBB6D604DB for ; Fri, 10 Jun 2016 01:05:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BE63C28367 for ; Fri, 10 Jun 2016 01:05:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B2EC42836A; Fri, 10 Jun 2016 01:05:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C255728367 for ; Fri, 10 Jun 2016 01:05:48 +0000 (UTC) Received: from localhost ([::1]:37823 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bBAtP-0006Dh-QN for patchwork-qemu-devel@patchwork.kernel.org; Thu, 09 Jun 2016 21:05:47 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53815) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bBAnf-0001ba-6U for qemu-devel@nongnu.org; Thu, 09 Jun 2016 20:59:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bBAnX-0008Gx-Rk for qemu-devel@nongnu.org; Thu, 09 Jun 2016 20:59:50 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:4569) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bBAnX-0008Gd-IG for qemu-devel@nongnu.org; Thu, 09 Jun 2016 20:59:43 -0400 Received: from pps.filterd (m0098404.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.11/8.16.0.11) with SMTP id u5A0wxdb128754 for ; Thu, 9 Jun 2016 20:59:42 -0400 Received: from e28smtp07.in.ibm.com (e28smtp07.in.ibm.com [125.16.236.7]) by mx0a-001b2d01.pphosted.com with ESMTP id 23eqnbkkmj-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Thu, 09 Jun 2016 20:59:42 -0400 Received: from localhost by e28smtp07.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 10 Jun 2016 06:29:39 +0530 Received: from d28dlp03.in.ibm.com (9.184.220.128) by e28smtp07.in.ibm.com (192.168.1.137) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 10 Jun 2016 06:29:37 +0530 X-IBM-Helo: d28dlp03.in.ibm.com X-IBM-MailFrom: bharata@linux.vnet.ibm.com X-IBM-RcptTo: qemu-devel@nongnu.org;qemu-ppc@nongnu.org Received: from d28relay10.in.ibm.com (d28relay10.in.ibm.com [9.184.220.161]) by d28dlp03.in.ibm.com (Postfix) with ESMTP id BF7541258062; Fri, 10 Jun 2016 06:32:04 +0530 (IST) Received: from d28av05.in.ibm.com (d28av05.in.ibm.com [9.184.220.67]) by d28relay10.in.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u5A0xadL29622412; Fri, 10 Jun 2016 06:29:36 +0530 Received: from d28av05.in.ibm.com (localhost [127.0.0.1]) by d28av05.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id u5A0xXYC025524; Fri, 10 Jun 2016 06:29:35 +0530 Received: from bharata.in.ibm.com ([9.79.185.199]) by d28av05.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id u5A0xCpi024706; Fri, 10 Jun 2016 06:29:25 +0530 From: Bharata B Rao To: qemu-devel@nongnu.org Date: Fri, 10 Jun 2016 06:29:03 +0530 X-Mailer: git-send-email 2.1.0 In-Reply-To: <1465520348-13964-1-git-send-email-bharata@linux.vnet.ibm.com> References: <1465520348-13964-1-git-send-email-bharata@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16061000-0052-0000-0000-0000027423F3 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16061000-0053-0000-0000-00000CC728D0 Message-Id: <1465520348-13964-5-git-send-email-bharata@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2016-06-09_09:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=3 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1604210000 definitions=main-1606100011 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] X-Received-From: 148.163.156.1 Subject: [Qemu-devel] [PATCH v4 4/9] spapr: convert boot CPUs into CPU core devices X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mjrosato@linux.vnet.ibm.com, thuth@redhat.com, pkrempa@redhat.com, ehabkost@redhat.com, aik@ozlabs.ru, Bharata B Rao , agraf@suse.de, mdroth@linux.vnet.ibm.com, borntraeger@de.ibm.com, qemu-ppc@nongnu.org, pbonzini@redhat.com, imammedo@redhat.com, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Introduce sPAPRMachineClass.dr_cpu_enabled to indicate support for CPU core hotplug. Initialize boot time CPUs as core deivces and prevent topologies that result in partially filled cores. Both of these are done only if CPU core hotplug is supported. Note: An unrelated change in the call to xics_system_init() is done in this patch as it makes sense to use the local variable smt introduced in this patch instead of kvmppc_smt_threads() call here. TODO: We derive sPAPR core type by looking at -cpu . However we don't take care of "compat=" feature yet for boot time as well as hotplug CPUs. Signed-off-by: Bharata B Rao Reviewed-by: David Gibson --- hw/ppc/spapr.c | 73 +++++++++++++++++++++++++++++++++++------ hw/ppc/spapr_cpu_core.c | 58 ++++++++++++++++++++++++++++++++ include/hw/ppc/spapr.h | 2 ++ include/hw/ppc/spapr_cpu_core.h | 3 ++ 4 files changed, 126 insertions(+), 10 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index adaca42..1435e38 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -66,6 +66,7 @@ #include "hw/compat.h" #include "qemu/cutils.h" +#include "hw/ppc/spapr_cpu_core.h" #include @@ -1665,7 +1666,6 @@ static void ppc_spapr_init(MachineState *machine) const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; - PowerPCCPU *cpu; PCIHostState *phb; int i; MemoryRegion *sysmem = get_system_memory(); @@ -1679,6 +1679,22 @@ static void ppc_spapr_init(MachineState *machine) long load_limit, fw_size; bool kernel_le = false; char *filename; + int smt = kvmppc_smt_threads(); + int spapr_cores = smp_cpus / smp_threads; + int spapr_max_cores = max_cpus / smp_threads; + + if (smc->dr_cpu_enabled) { + if (smp_cpus % smp_threads) { + error_report("smp_cpus (%u) must be multiple of threads (%u)", + smp_cpus, smp_threads); + exit(1); + } + if (max_cpus % smp_threads) { + error_report("max_cpus (%u) must be multiple of threads (%u)", + max_cpus, smp_threads); + exit(1); + } + } msi_nonbroken = true; @@ -1725,8 +1741,7 @@ static void ppc_spapr_init(MachineState *machine) /* Set up Interrupt Controller before we create the VCPUs */ spapr->icp = xics_system_init(machine, - DIV_ROUND_UP(max_cpus * kvmppc_smt_threads(), - smp_threads), + DIV_ROUND_UP(max_cpus * smt, smp_threads), XICS_IRQS, &error_fatal); if (smc->dr_lmb_enabled) { @@ -1737,13 +1752,37 @@ static void ppc_spapr_init(MachineState *machine) if (machine->cpu_model == NULL) { machine->cpu_model = kvm_enabled() ? "host" : "POWER7"; } - for (i = 0; i < smp_cpus; i++) { - cpu = cpu_ppc_init(machine->cpu_model); - if (cpu == NULL) { - error_report("Unable to find PowerPC CPU definition"); - exit(1); + + if (smc->dr_cpu_enabled) { + char *type = spapr_get_cpu_core_type(machine->cpu_model); + + spapr->cores = g_new0(Object *, spapr_max_cores); + for (i = 0; i < spapr_cores; i++) { + int core_dt_id = i * smt; + Object *core; + + if (!object_class_by_name(type)) { + error_report("Unable to find sPAPR CPU Core definition"); + exit(1); + } + + core = object_new(type); + object_property_set_int(core, smp_threads, "nr-threads", + &error_fatal); + object_property_set_int(core, core_dt_id, CPU_CORE_PROP_CORE_ID, + &error_fatal); + object_property_set_bool(core, true, "realized", &error_fatal); } - spapr_cpu_init(spapr, cpu, &error_fatal); + g_free(type); + } else { + for (i = 0; i < smp_cpus; i++) { + PowerPCCPU *cpu = cpu_ppc_init(machine->cpu_model); + if (cpu == NULL) { + error_report("Unable to find PowerPC CPU definition"); + exit(1); + } + spapr_cpu_init(spapr, cpu, &error_fatal); + } } if (kvm_enabled()) { @@ -2209,10 +2248,19 @@ static void spapr_machine_device_unplug(HotplugHandler *hotplug_dev, } } +static void spapr_machine_device_pre_plug(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE)) { + spapr_core_pre_plug(hotplug_dev, dev, errp); + } +} + static HotplugHandler *spapr_get_hotpug_handler(MachineState *machine, DeviceState *dev) { - if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { + if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) || + object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE)) { return HOTPLUG_HANDLER(machine); } return NULL; @@ -2251,11 +2299,13 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) mc->has_dynamic_sysbus = true; mc->pci_allow_0_address = true; mc->get_hotplug_handler = spapr_get_hotpug_handler; + hc->pre_plug = spapr_machine_device_pre_plug; hc->plug = spapr_machine_device_plug; hc->unplug = spapr_machine_device_unplug; mc->cpu_index_to_socket_id = spapr_cpu_index_to_socket_id; smc->dr_lmb_enabled = true; + smc->dr_cpu_enabled = true; fwc->get_dev_path = spapr_get_fw_dev_path; nc->nmi_monitor_handler = spapr_nmi; } @@ -2331,7 +2381,10 @@ static void spapr_machine_2_6_instance_options(MachineState *machine) static void spapr_machine_2_6_class_options(MachineClass *mc) { + sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); + spapr_machine_2_7_class_options(mc); + smc->dr_cpu_enabled = false; SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_6); } diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index e9eb754..6eb2a25 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -63,6 +63,64 @@ void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu, Error **errp) qemu_register_reset(spapr_cpu_reset, cpu); } +/* + * Return the sPAPR CPU core type for @model which essentially is the CPU + * model specified with -cpu cmdline option. + */ +char *spapr_get_cpu_core_type(const char *model) +{ + char *core_type; + gchar **model_pieces = g_strsplit(model, ",", 2); + + core_type = g_strdup_printf("%s-%s", model_pieces[0], TYPE_SPAPR_CPU_CORE); + g_strfreev(model_pieces); + return core_type; +} + +void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, + Error **errp) +{ + MachineState *machine = MACHINE(OBJECT(hotplug_dev)); + sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev)); + int spapr_max_cores = max_cpus / smp_threads; + int index; + int smt = kvmppc_smt_threads(); + Error *local_err = NULL; + CPUCore *cc = CPU_CORE(dev); + char *base_core_type = spapr_get_cpu_core_type(machine->cpu_model); + const char *type = object_get_typename(OBJECT(dev)); + + if (strcmp(base_core_type, type)) { + error_setg(&local_err, "CPU core type should be %s", base_core_type); + goto out; + } + + if (cc->nr_threads != smp_threads) { + error_setg(&local_err, "threads must be %d", smp_threads); + goto out; + } + + if (cc->core_id % smt) { + error_setg(&local_err, "invalid core id %d\n", cc->core_id); + goto out; + } + + index = cc->core_id / smt; + if (index < 0 || index >= spapr_max_cores) { + error_setg(&local_err, "core id %d out of range", cc->core_id); + goto out; + } + + if (spapr->cores[index]) { + error_setg(&local_err, "core %d already populated", cc->core_id); + goto out; + } + +out: + g_free(base_core_type); + error_propagate(errp, local_err); +} + static int spapr_cpu_core_realize_child(Object *child, void *opaque) { Error **errp = opaque; diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index e372dae..ab393fd 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -38,6 +38,7 @@ struct sPAPRMachineClass { /*< public >*/ bool dr_lmb_enabled; /* enable dynamic-reconfig/hotplug of LMBs */ + bool dr_cpu_enabled; /* enable dynamic-reconfig/hotplug of CPUs */ bool use_ohci_by_default; /* use USB-OHCI instead of XHCI */ }; @@ -81,6 +82,7 @@ struct sPAPRMachineState { /*< public >*/ char *kvm_type; MemoryHotplugState hotplug_memory; + Object **cores; }; #define H_SUCCESS 0 diff --git a/include/hw/ppc/spapr_cpu_core.h b/include/hw/ppc/spapr_cpu_core.h index 424edec..401381b 100644 --- a/include/hw/ppc/spapr_cpu_core.h +++ b/include/hw/ppc/spapr_cpu_core.h @@ -26,4 +26,7 @@ typedef struct sPAPRCPUCore { ObjectClass *cpu_class; } sPAPRCPUCore; +void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, + Error **errp); +char *spapr_get_cpu_core_type(const char *model); #endif