Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.2/patches/831066/?format=api
{ "id": 831066, "url": "http://patchwork.ozlabs.org/api/1.2/patches/831066/?format=api", "web_url": "http://patchwork.ozlabs.org/project/kvm-ppc/patch/1509079594-28977-6-git-send-email-paulus@ozlabs.org/", "project": { "id": 23, "url": "http://patchwork.ozlabs.org/api/1.2/projects/23/?format=api", "name": "KVM PowerPC development", "link_name": "kvm-ppc", "list_id": "kvm-ppc.vger.kernel.org", "list_email": "kvm-ppc@vger.kernel.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<1509079594-28977-6-git-send-email-paulus@ozlabs.org>", "list_archive_url": null, "date": "2017-10-27T04:46:33", "name": "[v2,5/6] KVM: PPC: Book3S HV: Allow for running POWER9 host in single-threaded mode", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "4c24ca59fe25c7c202567431576f6fc9ff762007", "submitter": { "id": 67079, "url": "http://patchwork.ozlabs.org/api/1.2/people/67079/?format=api", "name": "Paul Mackerras", "email": "paulus@ozlabs.org" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/kvm-ppc/patch/1509079594-28977-6-git-send-email-paulus@ozlabs.org/mbox/", "series": [ { "id": 10490, "url": "http://patchwork.ozlabs.org/api/1.2/series/10490/?format=api", "web_url": "http://patchwork.ozlabs.org/project/kvm-ppc/list/?series=10490", "date": "2017-10-27T04:46:28", "name": "KVM: PPC: Book3S HV: Run HPT guests on radix hosts", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/10490/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/831066/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/831066/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<kvm-ppc-owner@vger.kernel.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org", "Authentication-Results": [ "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=kvm-ppc-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)", "ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tsecure) header.d=ozlabs.org header.i=@ozlabs.org header.b=\"FHeyHW0v\";\n\tdkim-atps=neutral" ], "Received": [ "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3yNWYz0pvmz9t41\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 27 Oct 2017 15:47:03 +1100 (AEDT)", "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1752000AbdJ0Eq5 (ORCPT <rfc822;incoming@patchwork.ozlabs.org>);\n\tFri, 27 Oct 2017 00:46:57 -0400", "from ozlabs.org ([103.22.144.67]:54899 \"EHLO ozlabs.org\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S1751675AbdJ0Eqr (ORCPT <rfc822;kvm-ppc@vger.kernel.org>);\n\tFri, 27 Oct 2017 00:46:47 -0400", "from authenticated.ozlabs.org (localhost [127.0.0.1])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPSA id 3yNWYd4Jm6z9t2d;\n\tFri, 27 Oct 2017 15:46:45 +1100 (AEDT)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ozlabs.org; s=201707; \n\tt=1509079605; bh=M9/MOuNDCMtEX4WXvMxwpj9xSJ3gjSvT5BsO1ZLzm44=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=FHeyHW0vt4AGaukJo03VC+JVZAFopBfICXG8t+umzjtwV13ce0bCsGuKW8Wc9lwMK\n\t+ejECGsFoJjxaFLOjZIqw4vS7Ne6F1KZ5aS1VI4b3trMme2NLpzm/gXE7UHu45JzLN\n\tn/hLSX+bqNoBNWcuY/2YgjSy2tStU1l2u3vVjYeDFAIauBsEC2NHhs3KnUjvGre5d/\n\tr4UChWflQMWlCf+i07fCnx3lIBskRQqYTuLXtGUg6uXZtSPG2nHxzZqi0wG7VmEZol\n\txE2wOfLEgKgUHudKmTVxvLQs/a7aq8bjS2PRhxF5kDSsKgCJfVZmJwVMwcOOYjsBJY\n\twktXmn5XMiU+g==", "From": "Paul Mackerras <paulus@ozlabs.org>", "To": "kvm@vger.kernel.org, kvm-ppc@vger.kernel.org", "Cc": "david@gibson.dropbear.id.au", "Subject": "[PATCH v2 5/6] KVM: PPC: Book3S HV: Allow for running POWER9 host\n\tin single-threaded mode", "Date": "Fri, 27 Oct 2017 15:46:33 +1100", "Message-Id": "<1509079594-28977-6-git-send-email-paulus@ozlabs.org>", "X-Mailer": "git-send-email 2.7.4", "In-Reply-To": "<1509079594-28977-1-git-send-email-paulus@ozlabs.org>", "References": "<1509079594-28977-1-git-send-email-paulus@ozlabs.org>", "Sender": "kvm-ppc-owner@vger.kernel.org", "Precedence": "bulk", "List-ID": "<kvm-ppc.vger.kernel.org>", "X-Mailing-List": "kvm-ppc@vger.kernel.org" }, "content": "This patch allows for a mode on POWER9 hosts where we control all the\nthreads of a core, much as we do on POWER8. The mode is controlled by\na module parameter on the kvm_hv module, called \"indep_threads_mode\".\nThe normal mode on POWER9 is the \"independent threads\" mode, with\nindep_threads_mode=Y, where the host is in SMT4 mode (or in fact any\ndesired SMT mode) and each thread independently enters and exits from\nKVM guests without reference to what other threads in the core are\ndoing.\n\nIf indep_threads_mode is set to N at the point when a VM is started,\nKVM will expect every core that the guest runs on to be in single\nthreaded mode (that is, threads 1, 2 and 3 offline), and will set the\nflag that prevents secondary threads from coming online. We can still\nuse all four threads; the code that implements dynamic micro-threading\non POWER8 will become active in over-commit situations and will allow\nup to three other VCPUs to be run on the secondary threads of the core\nwhenever a VCPU is run.\n\nThe reason for wanting this mode is that this will allow us to run HPT\nguests on a radix host on a POWER9 machine that does not support\n\"mixed mode\", that is, having some threads in a core be in HPT mode\nwhile other threads are in radix mode. It will also make it possible\nto implement a \"strict threads\" mode in future, if desired.\n\nSigned-off-by: Paul Mackerras <paulus@ozlabs.org>\n---\n arch/powerpc/include/asm/kvm_host.h | 1 +\n arch/powerpc/kvm/book3s_hv.c | 87 ++++++++++++++++++++-------------\n arch/powerpc/kvm/book3s_hv_rmhandlers.S | 2 +\n 3 files changed, 57 insertions(+), 33 deletions(-)", "diff": "diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h\nindex d831a38..3aa5b57 100644\n--- a/arch/powerpc/include/asm/kvm_host.h\n+++ b/arch/powerpc/include/asm/kvm_host.h\n@@ -281,6 +281,7 @@ struct kvm_arch {\n \tcpumask_t cpu_in_guest;\n \tu8 radix;\n \tu8 fwnmi_enabled;\n+\tbool threads_indep;\n \tpgd_t *pgtable;\n \tu64 process_table;\n \tstruct dentry *debugfs_dir;\ndiff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c\nindex 040e102..b5fbf76 100644\n--- a/arch/powerpc/kvm/book3s_hv.c\n+++ b/arch/powerpc/kvm/book3s_hv.c\n@@ -98,6 +98,10 @@ static int target_smt_mode;\n module_param(target_smt_mode, int, S_IRUGO | S_IWUSR);\n MODULE_PARM_DESC(target_smt_mode, \"Target threads per core (0 = max)\");\n \n+static bool indep_threads_mode = true;\n+module_param(indep_threads_mode, bool, S_IRUGO | S_IWUSR);\n+MODULE_PARM_DESC(indep_threads_mode, \"Independent-threads mode (only on POWER9)\");\n+\n #ifdef CONFIG_KVM_XICS\n static struct kernel_param_ops module_param_ops = {\n \t.set = param_set_int,\n@@ -1734,9 +1738,9 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,\n * MMU mode (radix or HPT), unfortunately, but since we only support\n * HPT guests on a HPT host so far, that isn't an impediment yet.\n */\n-static int threads_per_vcore(void)\n+static int threads_per_vcore(struct kvm *kvm)\n {\n-\tif (cpu_has_feature(CPU_FTR_ARCH_300))\n+\tif (kvm->arch.threads_indep)\n \t\treturn 1;\n \treturn threads_per_subcore;\n }\n@@ -2228,11 +2232,10 @@ static void kvmppc_start_thread(struct kvm_vcpu *vcpu, struct kvmppc_vcore *vc)\n \t\tkvmppc_ipi_thread(cpu);\n }\n \n-static void kvmppc_wait_for_nap(void)\n+static void kvmppc_wait_for_nap(int n_threads)\n {\n \tint cpu = smp_processor_id();\n \tint i, loops;\n-\tint n_threads = threads_per_vcore();\n \n \tif (n_threads <= 1)\n \t\treturn;\n@@ -2319,7 +2322,7 @@ static void kvmppc_vcore_preempt(struct kvmppc_vcore *vc)\n \n \tvc->vcore_state = VCORE_PREEMPT;\n \tvc->pcpu = smp_processor_id();\n-\tif (vc->num_threads < threads_per_vcore()) {\n+\tif (vc->num_threads < threads_per_vcore(vc->kvm)) {\n \t\tspin_lock(&lp->lock);\n \t\tlist_add_tail(&vc->preempt_list, &lp->list);\n \t\tspin_unlock(&lp->lock);\n@@ -2357,7 +2360,7 @@ struct core_info {\n \n /*\n * This mapping means subcores 0 and 1 can use threads 0-3 and 4-7\n- * respectively in 2-way micro-threading (split-core) mode.\n+ * respectively in 2-way micro-threading (split-core) mode on POWER8.\n */\n static int subcore_thread_map[MAX_SUBCORES] = { 0, 4, 2, 6 };\n \n@@ -2373,7 +2376,14 @@ static void init_core_info(struct core_info *cip, struct kvmppc_vcore *vc)\n \n static bool subcore_config_ok(int n_subcores, int n_threads)\n {\n-\t/* Can only dynamically split if unsplit to begin with */\n+\t/*\n+\t * POWER9 \"SMT4\" cores are permanently in what is effectively a 4-way split-core\n+\t * mode, with one thread per subcore.\n+\t */\n+\tif (cpu_has_feature(CPU_FTR_ARCH_300))\n+\t\treturn n_subcores <= 4 && n_threads == 1;\n+\n+\t/* On POWER8, can only dynamically split if unsplit to begin with */\n \tif (n_subcores > 1 && threads_per_subcore < MAX_SMT_THREADS)\n \t\treturn false;\n \tif (n_subcores > MAX_SUBCORES)\n@@ -2632,6 +2642,7 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)\n \tint target_threads;\n \tint controlled_threads;\n \tint trap;\n+\tbool is_power8;\n \n \t/*\n \t * Remove from the list any threads that have a signal pending\n@@ -2654,7 +2665,7 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)\n \t * the number of threads per subcore, except on POWER9,\n \t * where it's 1 because the threads are (mostly) independent.\n \t */\n-\tcontrolled_threads = threads_per_vcore();\n+\tcontrolled_threads = threads_per_vcore(vc->kvm);\n \n \t/*\n \t * Make sure we are running on primary threads, and that secondary\n@@ -2725,32 +2736,40 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)\n \tcmd_bit = stat_bit = 0;\n \tsplit = core_info.n_subcores;\n \tsip = NULL;\n+\tis_power8 = cpu_has_feature(CPU_FTR_ARCH_207S)\n+\t\t&& !cpu_has_feature(CPU_FTR_ARCH_300);\n+\n \tif (split > 1) {\n-\t\t/* threads_per_subcore must be MAX_SMT_THREADS (8) here */\n-\t\tif (split == 2 && (dynamic_mt_modes & 2)) {\n-\t\t\tcmd_bit = HID0_POWER8_1TO2LPAR;\n-\t\t\tstat_bit = HID0_POWER8_2LPARMODE;\n-\t\t} else {\n-\t\t\tsplit = 4;\n-\t\t\tcmd_bit = HID0_POWER8_1TO4LPAR;\n-\t\t\tstat_bit = HID0_POWER8_4LPARMODE;\n-\t\t}\n-\t\tsubcore_size = MAX_SMT_THREADS / split;\n \t\tsip = &split_info;\n \t\tmemset(&split_info, 0, sizeof(split_info));\n-\t\tsplit_info.rpr = mfspr(SPRN_RPR);\n-\t\tsplit_info.pmmar = mfspr(SPRN_PMMAR);\n-\t\tsplit_info.ldbar = mfspr(SPRN_LDBAR);\n-\t\tsplit_info.subcore_size = subcore_size;\n \t\tfor (sub = 0; sub < core_info.n_subcores; ++sub)\n \t\t\tsplit_info.vc[sub] = core_info.vc[sub];\n+\n+\t\tif (is_power8) {\n+\t\t\tif (split == 2 && (dynamic_mt_modes & 2)) {\n+\t\t\t\tcmd_bit = HID0_POWER8_1TO2LPAR;\n+\t\t\t\tstat_bit = HID0_POWER8_2LPARMODE;\n+\t\t\t} else {\n+\t\t\t\tsplit = 4;\n+\t\t\t\tcmd_bit = HID0_POWER8_1TO4LPAR;\n+\t\t\t\tstat_bit = HID0_POWER8_4LPARMODE;\n+\t\t\t}\n+\t\t\tsubcore_size = MAX_SMT_THREADS / split;\n+\t\t\tsplit_info.rpr = mfspr(SPRN_RPR);\n+\t\t\tsplit_info.pmmar = mfspr(SPRN_PMMAR);\n+\t\t\tsplit_info.ldbar = mfspr(SPRN_LDBAR);\n+\t\t\tsplit_info.subcore_size = subcore_size;\n+\t\t} else {\n+\t\t\tsplit_info.subcore_size = 1;\n+\t\t}\n+\n \t\t/* order writes to split_info before kvm_split_mode pointer */\n \t\tsmp_wmb();\n \t}\n \tfor (thr = 0; thr < controlled_threads; ++thr)\n \t\tpaca[pcpu + thr].kvm_hstate.kvm_split_mode = sip;\n \n-\t/* Initiate micro-threading (split-core) if required */\n+\t/* Initiate micro-threading (split-core) on POWER8 if required */\n \tif (cmd_bit) {\n \t\tunsigned long hid0 = mfspr(SPRN_HID0);\n \n@@ -2769,7 +2788,7 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)\n \t/* Start all the threads */\n \tactive = 0;\n \tfor (sub = 0; sub < core_info.n_subcores; ++sub) {\n-\t\tthr = subcore_thread_map[sub];\n+\t\tthr = is_power8 ? subcore_thread_map[sub] : sub;\n \t\tthr0_done = false;\n \t\tactive |= 1 << thr;\n \t\tpvc = core_info.vc[sub];\n@@ -2796,18 +2815,18 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)\n \t * the vcore pointer in the PACA of the secondaries.\n \t */\n \tsmp_mb();\n-\tif (cmd_bit)\n-\t\tsplit_info.do_nap = 1;\t/* ask secondaries to nap when done */\n \n \t/*\n \t * When doing micro-threading, poke the inactive threads as well.\n \t * This gets them to the nap instruction after kvm_do_nap,\n \t * which reduces the time taken to unsplit later.\n \t */\n-\tif (split > 1)\n+\tif (cmd_bit) {\n+\t\tsplit_info.do_nap = 1;\t/* ask secondaries to nap when done */\n \t\tfor (thr = 1; thr < threads_per_subcore; ++thr)\n \t\t\tif (!(active & (1 << thr)))\n \t\t\t\tkvmppc_ipi_thread(pcpu + thr);\n+\t}\n \n \tvc->vcore_state = VCORE_RUNNING;\n \tpreempt_disable();\n@@ -2841,10 +2860,10 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)\n \tvc->vcore_state = VCORE_EXITING;\n \n \t/* wait for secondary threads to finish writing their state to memory */\n-\tkvmppc_wait_for_nap();\n+\tkvmppc_wait_for_nap(controlled_threads);\n \n \t/* Return to whole-core mode if we split the core earlier */\n-\tif (split > 1) {\n+\tif (cmd_bit) {\n \t\tunsigned long hid0 = mfspr(SPRN_HID0);\n \t\tunsigned long loops = 0;\n \n@@ -3822,10 +3841,12 @@ static int kvmppc_core_init_vm_hv(struct kvm *kvm)\n \t/*\n \t * Track that we now have a HV mode VM active. This blocks secondary\n \t * CPU threads from coming online.\n-\t * On POWER9, we only need to do this for HPT guests on a radix\n-\t * host, which is not yet supported.\n+\t * On POWER9, we only need to do this if the \"indep_threads_mode\"\n+\t * module parameter has been set to N.\n \t */\n-\tif (!cpu_has_feature(CPU_FTR_ARCH_300))\n+\tif (cpu_has_feature(CPU_FTR_ARCH_300))\n+\t\tkvm->arch.threads_indep = indep_threads_mode;\n+\tif (!kvm->arch.threads_indep)\n \t\tkvm_hv_vm_activated();\n \n \t/*\n@@ -3865,7 +3886,7 @@ static void kvmppc_core_destroy_vm_hv(struct kvm *kvm)\n {\n \tdebugfs_remove_recursive(kvm->arch.debugfs_dir);\n \n-\tif (!cpu_has_feature(CPU_FTR_ARCH_300))\n+\tif (!kvm->arch.threads_indep)\n \t\tkvm_hv_vm_deactivated();\n \n \tkvmppc_free_vcores(kvm);\ndiff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S\nindex fd2583d..ae6c616 100644\n--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S\n+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S\n@@ -385,6 +385,7 @@ kvm_secondary_got_guest:\n \tld\tr6, 0(r6)\n \tmtspr\tSPRN_HDEC, r6\n \t/* and set per-LPAR registers, if doing dynamic micro-threading */\n+BEGIN_FTR_SECTION\n \tld\tr6, HSTATE_SPLIT_MODE(r13)\n \tcmpdi\tr6, 0\n \tbeq\t63f\n@@ -395,6 +396,7 @@ kvm_secondary_got_guest:\n \tld\tr0, KVM_SPLIT_LDBAR(r6)\n \tmtspr\tSPRN_LDBAR, r0\n \tisync\n+END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300)\n 63:\n \t/* Order load of vcpu after load of vcore */\n \tlwsync\n", "prefixes": [ "v2", "5/6" ] }