From: Sebastian Siewior <bigeasy@linux.vnet.ibm.com>
To: linuxppc-dev@ozlabs.org
Subject: [RFC 2/3] PowerPC: lazy altivec enabling in kernel
Date: Tue, 17 Apr 2007 13:52:08 +0200 [thread overview]
Message-ID: <20070417120925.263638000@linux.vnet.ibm.com> (raw)
In-Reply-To: 20070417115206.709701000@linux.vnet.ibm.com
This patch works only for 64bit kernel and will break any 32bit kernel.
Switching on altivec takes some time due to the MSR access. The speed-up is
about 50% in my aes-code. It might be usefull for the raid module as well.
Signed-off-by: Sebastian Siewior <bigeasy@linux.vnet.ibm.com>
Index: linux/arch/powerpc/kernel/head_64.S
===================================================================
--- linux.orig/arch/powerpc/kernel/head_64.S
+++ linux/arch/powerpc/kernel/head_64.S
@@ -1229,6 +1229,14 @@ altivec_unavailable_common:
#ifdef CONFIG_ALTIVEC
BEGIN_FTR_SECTION
bne .load_up_altivec /* if from user, just load it up */
+ /*
+ * the kernel is going to use AltiVec.
+ * hopefully enable_kernel_altivec() has been called
+ */
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl .altivec_enable_for_kernel_exception
+ b .ret_from_except
+
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
#endif
bl .save_nvgprs
Index: linux/arch/powerpc/kernel/misc_64.S
===================================================================
--- linux.orig/arch/powerpc/kernel/misc_64.S
+++ linux/arch/powerpc/kernel/misc_64.S
@@ -493,6 +493,8 @@ _GLOBAL(giveup_altivec)
mfmsr r5
oris r5,r5,MSR_VEC@h
mtmsrd r5 /* enable use of VMX now */
+
+giveup_user_altivec_save_vmx:
isync
cmpdi 0,r3,0
beqlr- /* if no previous owner, done */
@@ -516,6 +518,14 @@ _GLOBAL(giveup_altivec)
#endif /* CONFIG_SMP */
blr
+/*
+ * giveup_user_altivec(tsk)
+ * Same as giveup_altivec() but lets the exception handler
+ * enable AltiVec
+ */
+_GLOBAL(giveup_user_altivec)
+ b giveup_user_altivec_save_vmx
+
#endif /* CONFIG_ALTIVEC */
_GLOBAL(kernel_execve)
Index: linux/arch/powerpc/kernel/process.c
===================================================================
--- linux.orig/arch/powerpc/kernel/process.c
+++ linux/arch/powerpc/kernel/process.c
@@ -119,15 +119,21 @@ int dump_task_fpu(struct task_struct *ts
#ifdef CONFIG_ALTIVEC
void enable_kernel_altivec(void)
{
- WARN_ON(preemptible());
+ BUG_ON(preemptible());
+ /*
+ * enable_kernel_altivec() will just save current AltiVec registers (if needed) and
+ * return to caller (with MSR_VEC unchanged (probably not set)). The first AltiVec
+ * instruction will raise an exception and the exception will enable the AltiVec for
+ * the kernel. This is done to avoid the expensive "enable altivec" operation if it
+ * is allready enabled. However, you have to disable preemtion while you are using
+ * AltiVec.
+ */
#ifdef CONFIG_SMP
if (current->thread.regs && (current->thread.regs->msr & MSR_VEC))
- giveup_altivec(current);
- else
- giveup_altivec(NULL); /* just enable AltiVec for kernel - force */
+ giveup_user_altivec(current);
#else
- giveup_altivec(last_task_used_altivec);
+ giveup_user_altivec(last_task_used_altivec);
#endif /* CONFIG_SMP */
}
EXPORT_SYMBOL(enable_kernel_altivec);
Index: linux/arch/powerpc/kernel/traps.c
===================================================================
--- linux.orig/arch/powerpc/kernel/traps.c
+++ linux/arch/powerpc/kernel/traps.c
@@ -886,6 +886,12 @@ void altivec_unavailable_exception(struc
die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT);
}
+void altivec_enable_for_kernel_exception(struct pt_regs *regs)
+{
+ printk("altivec_enable_for_kernel_exception: AltiVec mode on for kernel\n");
+ regs->msr |= MSR_VEC;
+}
+
void performance_monitor_exception(struct pt_regs *regs)
{
perf_irq(regs);
Index: linux/include/asm-powerpc/system.h
===================================================================
--- linux.orig/include/asm-powerpc/system.h
+++ linux/include/asm-powerpc/system.h
@@ -129,6 +129,7 @@ extern void enable_kernel_fp(void);
extern void flush_fp_to_thread(struct task_struct *);
extern void enable_kernel_altivec(void);
extern void giveup_altivec(struct task_struct *);
+extern void giveup_user_altivec(struct task_struct *);
extern void load_up_altivec(struct task_struct *);
extern int emulate_altivec(struct pt_regs *);
extern void giveup_spe(struct task_struct *);
--
next prev parent reply other threads:[~2007-04-17 12:24 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-04-17 11:52 [RFC 0/3] Experiments with AES-AltiVec, part 2 Sebastian Siewior
2007-04-17 11:52 ` [RFC 1/3] cryptoapi: AES with AltiVec support Sebastian Siewior
2007-04-17 11:52 ` Sebastian Siewior [this message]
2007-04-24 0:52 ` [RFC 2/3] PowerPC: lazy altivec enabling in kernel Paul Mackerras
2007-04-24 8:32 ` Arnd Bergmann
2007-04-17 11:52 ` [RFC 3/3] cryptoapi: speed test Sebastian Siewior
-- strict thread matches above, loose matches on Subject: below --
2007-04-11 16:49 [RFC 0/3] Experiments with AES-AltiVec Sebastian Siewior
2007-04-11 16:49 ` [RFC 2/3] PowerPC: lazy altivec enabling in kernel Sebastian Siewior
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=20070417120925.263638000@linux.vnet.ibm.com \
--to=bigeasy@linux.vnet.ibm.com \
--cc=linuxppc-dev@ozlabs.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;
as well as URLs for NNTP newsgroup(s).