mirror of
https://github.com/torvalds/linux.git
synced 2024-12-13 14:43:03 +00:00
35000870fc
Add two optimisations to enable_kernel_altivec: - enable_kernel_altivec has already determined if we need to save the previous task's state but we call giveup_altivec in both cases, requiring an extra branch in giveup_altivec. Create giveup_altivec_notask which only turns on the VMX bit in the MSR. - We write the VMX MSR bit each time we call enable_kernel_altivec even it was already set. Check the bit and branch out if we have already set it. The classic case for this is vectored IO where we have to copy multiple buffers to or from userspace. The following testcase was used to confirm this patch improves performance: http://ozlabs.org/~anton/junkcode/copy_to_user.c Since the current breakpoint for using VMX in copy_tofrom_user is 4096 bytes, I'm using buffers of 4096 + 1 cacheline (4224) bytes. A benchmark of 16 entry readvs (-s 16): time copy_to_user -l 4224 -s 16 -i 1000000 completes 5.2% faster on a POWER7 PS700. Signed-off-by: Anton Blanchard <anton@samba.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
70 lines
1.8 KiB
C
70 lines
1.8 KiB
C
/*
|
|
* Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
|
|
*/
|
|
#ifndef _ASM_POWERPC_SWITCH_TO_H
|
|
#define _ASM_POWERPC_SWITCH_TO_H
|
|
|
|
struct thread_struct;
|
|
struct task_struct;
|
|
struct pt_regs;
|
|
|
|
extern struct task_struct *__switch_to(struct task_struct *,
|
|
struct task_struct *);
|
|
#define switch_to(prev, next, last) ((last) = __switch_to((prev), (next)))
|
|
|
|
struct thread_struct;
|
|
extern struct task_struct *_switch(struct thread_struct *prev,
|
|
struct thread_struct *next);
|
|
|
|
extern void giveup_fpu(struct task_struct *);
|
|
extern void disable_kernel_fp(void);
|
|
extern void enable_kernel_fp(void);
|
|
extern void flush_fp_to_thread(struct task_struct *);
|
|
extern void enable_kernel_altivec(void);
|
|
extern void load_up_altivec(struct task_struct *);
|
|
extern int emulate_altivec(struct pt_regs *);
|
|
extern void __giveup_vsx(struct task_struct *);
|
|
extern void giveup_vsx(struct task_struct *);
|
|
extern void enable_kernel_spe(void);
|
|
extern void giveup_spe(struct task_struct *);
|
|
extern void load_up_spe(struct task_struct *);
|
|
|
|
#ifndef CONFIG_SMP
|
|
extern void discard_lazy_cpu_state(void);
|
|
#else
|
|
static inline void discard_lazy_cpu_state(void)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_ALTIVEC
|
|
extern void flush_altivec_to_thread(struct task_struct *);
|
|
extern void giveup_altivec(struct task_struct *);
|
|
extern void giveup_altivec_notask(void);
|
|
#else
|
|
static inline void flush_altivec_to_thread(struct task_struct *t)
|
|
{
|
|
}
|
|
static inline void giveup_altivec(struct task_struct *t)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_VSX
|
|
extern void flush_vsx_to_thread(struct task_struct *);
|
|
#else
|
|
static inline void flush_vsx_to_thread(struct task_struct *t)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_SPE
|
|
extern void flush_spe_to_thread(struct task_struct *);
|
|
#else
|
|
static inline void flush_spe_to_thread(struct task_struct *t)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
#endif /* _ASM_POWERPC_SWITCH_TO_H */
|