From: marc.zyngier@arm.com (Marc Zyngier)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 09/33] arm64: fpsimd: Eliminate task->mm checks
Date: Fri, 1 Jun 2018 16:27:23 +0100 [thread overview]
Message-ID: <20180601152747.23613-10-marc.zyngier@arm.com> (raw)
In-Reply-To: <20180601152747.23613-1-marc.zyngier@arm.com>
From: Dave Martin <Dave.Martin@arm.com>
Currently the FPSIMD handling code uses the condition task->mm ==
NULL as a hint that task has no FPSIMD register context.
The ->mm check is only there to filter out tasks that cannot
possibly have FPSIMD context loaded, for optimisation purposes.
Also, TIF_FOREIGN_FPSTATE must always be checked anyway before
saving FPSIMD context back to memory. For these reasons, the ->mm
checks are not useful, providing that TIF_FOREIGN_FPSTATE is
maintained in a consistent way for all threads.
The context switch logic is already deliberately optimised to defer
reloads of the regs until ret_to_user (or sigreturn as a special
case), and save them only if they have been previously loaded.
These paths are the only places where the wrong_task and wrong_cpu
conditions can be made false, by calling fpsimd_bind_task_to_cpu().
Kernel threads by definition never reach these paths. As a result,
the wrong_task and wrong_cpu tests in fpsimd_thread_switch() will
always yield true for kernel threads.
This patch removes the redundant checks and special-case code,
ensuring that TIF_FOREIGN_FPSTATE is set whenever a kernel thread
is scheduled in, and ensures that this flag is set for the init
task. The fpsimd_flush_task_state() call already present in
copy_thread() ensures the same for any new task.
With TIF_FOREIGN_FPSTATE always set for kernel threads, this patch
ensures that no extra context save work is added for kernel
threads, and eliminates the redundant context saving that may
currently occur for kernel threads that have acquired an mm via
use_mm().
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Alex Benn?e <alex.bennee@linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm64/include/asm/processor.h | 4 ++-
arch/arm64/kernel/fpsimd.c | 40 ++++++++++++------------------
2 files changed, 19 insertions(+), 25 deletions(-)
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 767598932549..36d64f83cdfb 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -156,7 +156,9 @@ static inline void arch_thread_struct_whitelist(unsigned long *offset,
/* Sync TPIDR_EL0 back to thread_struct for current */
void tls_preserve_current_state(void);
-#define INIT_THREAD { }
+#define INIT_THREAD { \
+ .fpsimd_cpu = NR_CPUS, \
+}
static inline void start_thread_common(struct pt_regs *regs, unsigned long pc)
{
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 2d9a9e8ed826..d736b6c412ef 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -892,31 +892,25 @@ asmlinkage void do_fpsimd_exc(unsigned int esr, struct pt_regs *regs)
void fpsimd_thread_switch(struct task_struct *next)
{
+ bool wrong_task, wrong_cpu;
+
if (!system_supports_fpsimd())
return;
+
+ /* Save unsaved fpsimd state, if any: */
+ fpsimd_save();
+
/*
- * Save the current FPSIMD state to memory, but only if whatever is in
- * the registers is in fact the most recent userland FPSIMD state of
- * 'current'.
+ * Fix up TIF_FOREIGN_FPSTATE to correctly describe next's
+ * state. For kernel threads, FPSIMD registers are never loaded
+ * and wrong_task and wrong_cpu will always be true.
*/
- if (current->mm)
- fpsimd_save();
-
- if (next->mm) {
- /*
- * If we are switching to a task whose most recent userland
- * FPSIMD state is already in the registers of *this* cpu,
- * we can skip loading the state from memory. Otherwise, set
- * the TIF_FOREIGN_FPSTATE flag so the state will be loaded
- * upon the next return to userland.
- */
- bool wrong_task = __this_cpu_read(fpsimd_last_state.st) !=
+ wrong_task = __this_cpu_read(fpsimd_last_state.st) !=
&next->thread.uw.fpsimd_state;
- bool wrong_cpu = next->thread.fpsimd_cpu != smp_processor_id();
+ wrong_cpu = next->thread.fpsimd_cpu != smp_processor_id();
- update_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE,
- wrong_task || wrong_cpu);
- }
+ update_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE,
+ wrong_task || wrong_cpu);
}
void fpsimd_flush_thread(void)
@@ -1121,9 +1115,8 @@ void kernel_neon_begin(void)
__this_cpu_write(kernel_neon_busy, true);
- /* Save unsaved task fpsimd state, if any: */
- if (current->mm)
- fpsimd_save();
+ /* Save unsaved fpsimd state, if any: */
+ fpsimd_save();
/* Invalidate any task state remaining in the fpsimd regs: */
fpsimd_flush_cpu_state();
@@ -1245,8 +1238,7 @@ static int fpsimd_cpu_pm_notifier(struct notifier_block *self,
{
switch (cmd) {
case CPU_PM_ENTER:
- if (current->mm)
- fpsimd_save();
+ fpsimd_save();
fpsimd_flush_cpu_state();
break;
case CPU_PM_EXIT:
--
2.17.1
next prev parent reply other threads:[~2018-06-01 15:27 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-01 15:27 [GIT PULL] KVM/ARM updates for 4.18 Marc Zyngier
2018-06-01 15:27 ` [PATCH 01/33] arm64: KVM: Use lm_alias() for kvm_ksym_ref() Marc Zyngier
2018-06-01 15:27 ` [PATCH 02/33] arm64: fpsimd: Fix TIF_FOREIGN_FPSTATE after invalidating cpu regs Marc Zyngier
2018-06-01 15:27 ` [PATCH 03/33] thread_info: Add update_thread_flag() helpers Marc Zyngier
2018-06-01 15:27 ` [PATCH 04/33] arm64: Use update{,_tsk}_thread_flag() Marc Zyngier
2018-06-01 15:27 ` [PATCH 05/33] KVM: arm/arm64: Introduce kvm_arch_vcpu_run_pid_change Marc Zyngier
2018-06-01 15:27 ` [PATCH 06/33] KVM: arm64: Convert lazy FPSIMD context switch trap to C Marc Zyngier
2018-06-01 15:27 ` [PATCH 07/33] arm64: fpsimd: Generalise context saving for non-task contexts Marc Zyngier
2018-06-01 15:27 ` [PATCH 08/33] arm64: fpsimd: Avoid FPSIMD context leakage for the init task Marc Zyngier
2018-06-01 15:27 ` Marc Zyngier [this message]
2018-06-01 15:27 ` [PATCH 10/33] arm64/sve: Refactor user SVE trap maintenance for external use Marc Zyngier
2018-06-01 15:27 ` [PATCH 11/33] KVM: arm64: Repurpose vcpu_arch.debug_flags for general-purpose flags Marc Zyngier
2018-06-01 15:27 ` [PATCH 12/33] KVM: arm64: Optimise FPSIMD handling to reduce guest/host thrashing Marc Zyngier
2018-06-01 15:27 ` [PATCH 13/33] arm64/sve: Move read_zcr_features() out of cpufeature.h Marc Zyngier
2018-06-01 15:27 ` [PATCH 14/33] arm64/sve: Switch sve_pffr() argument from task to thread Marc Zyngier
2018-06-01 15:27 ` [PATCH 15/33] arm64/sve: Move sve_pffr() to fpsimd.h and make inline Marc Zyngier
2018-06-01 15:27 ` [PATCH 16/33] KVM: arm64: Save host SVE context as appropriate Marc Zyngier
2018-06-01 15:27 ` [PATCH 17/33] KVM: arm64: Remove eager host SVE state saving Marc Zyngier
2018-06-01 15:27 ` [PATCH 18/33] KVM: arm64: Remove redundant *exit_code changes in fpsimd_guest_exit() Marc Zyngier
2018-06-01 15:27 ` [PATCH 19/33] KVM: arm64: Fold redundant exit code checks out of fixup_guest_exit() Marc Zyngier
2018-06-01 15:27 ` [PATCH 20/33] KVM: arm64: Invoke FPSIMD context switch trap from C Marc Zyngier
2018-06-01 15:27 ` [PATCH 21/33] KVM: arm/arm64: Set dist->spis to NULL after kfree Marc Zyngier
2018-06-01 15:27 ` [PATCH 22/33] KVM: arm/arm64: Document KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION Marc Zyngier
2018-06-01 15:27 ` [PATCH 23/33] KVM: arm/arm64: Replace the single rdist region by a list Marc Zyngier
2018-06-01 15:27 ` [PATCH 24/33] KVM: arm/arm64: Helper to locate free rdist index Marc Zyngier
2018-06-01 15:27 ` [PATCH 25/33] KVM: arm/arm64: Revisit Redistributor TYPER last bit computation Marc Zyngier
2018-06-01 15:27 ` [PATCH 26/33] KVM: arm/arm64: Adapt vgic_v3_check_base to multiple rdist regions Marc Zyngier
2018-06-01 15:27 ` [PATCH 27/33] KVM: arm/arm64: Helper to register a new redistributor region Marc Zyngier
2018-06-01 15:27 ` [PATCH 28/33] KVM: arm/arm64: Remove kvm_vgic_vcpu_early_init Marc Zyngier
2018-06-01 15:27 ` [PATCH 29/33] KVM: arm/arm64: Check vcpu redist base before registering an iodev Marc Zyngier
2018-06-01 15:27 ` [PATCH 30/33] KVM: arm/arm64: Check all vcpu redistributors are set on map_resources Marc Zyngier
2018-06-01 15:27 ` [PATCH 31/33] KVM: arm/arm64: Add KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION Marc Zyngier
2018-06-01 15:27 ` [PATCH 32/33] KVM: arm/arm64: Implement KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION Marc Zyngier
2018-06-01 15:27 ` [PATCH 33/33] KVM: arm/arm64: Bump VGIC_V3_MAX_CPUS to 512 Marc Zyngier
2018-06-01 17:18 ` [GIT PULL] KVM/ARM updates for 4.18 Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180601152747.23613-10-marc.zyngier@arm.com \
--to=marc.zyngier@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox