![Davidlohr Bueso](/assets/img/avatar_default.png)
The arch_mutex_cpu_relax() function, introduced by 34b133f
, is
hacky and ugly. It was added a few years ago to address the fact
that common cpu_relax() calls include yielding on s390, and thus
impact the optimistic spinning functionality of mutexes. Nowadays
we use this function well beyond mutexes: rwsem, qrwlock, mcs and
lockref. Since the macro that defines the call is in the mutex header,
any users must include mutex.h and the naming is misleading as well.
This patch (i) renames the call to cpu_relax_lowlatency ("relax, but
only if you can do it with very low latency") and (ii) defines it in
each arch's asm/processor.h local header, just like for regular cpu_relax
functions. On all archs, except s390, cpu_relax_lowlatency is simply cpu_relax,
and thus we can take it out of mutex.h. While this can seem redundant,
I believe it is a good choice as it allows us to move out arch specific
logic from generic locking primitives and enables future(?) archs to
transparently define it, similarly to System Z.
Signed-off-by: Davidlohr Bueso <davidlohr@hp.com>
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Anton Blanchard <anton@samba.org>
Cc: Aurelien Jacquiot <a-jacquiot@ti.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Bharat Bhushan <r65777@freescale.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Chen Liqin <liqin.linux@gmail.com>
Cc: Chris Metcalf <cmetcalf@tilera.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Chris Zankel <chris@zankel.net>
Cc: David Howells <dhowells@redhat.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
Cc: Dominik Dingel <dingel@linux.vnet.ibm.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Guan Xuetao <gxt@mprc.pku.edu.cn>
Cc: Haavard Skinnemoen <hskinnemoen@gmail.com>
Cc: Hans-Christian Egtvedt <egtvedt@samfundet.no>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Helge Deller <deller@gmx.de>
Cc: Hirokazu Takata <takata@linux-m32r.org>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: James E.J. Bottomley <jejb@parisc-linux.org>
Cc: James Hogan <james.hogan@imgtec.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Joe Perches <joe@perches.com>
Cc: Jonas Bonn <jonas@southpole.se>
Cc: Joseph Myers <joseph@codesourcery.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Koichi Yasutake <yasutake.koichi@jp.panasonic.com>
Cc: Lennox Wu <lennox.wu@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mark Salter <msalter@redhat.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Max Filippov <jcmvbkbc@gmail.com>
Cc: Michael Neuling <mikey@neuling.org>
Cc: Michal Simek <monstr@monstr.eu>
Cc: Mikael Starvik <starvik@axis.com>
Cc: Nicolas Pitre <nico@linaro.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Qais Yousef <qais.yousef@imgtec.com>
Cc: Qiaowei Ren <qiaowei.ren@intel.com>
Cc: Rafael Wysocki <rafael.j.wysocki@intel.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Richard Kuo <rkuo@codeaurora.org>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Steven Miao <realmz6@gmail.com>
Cc: Steven Rostedt <srostedt@redhat.com>
Cc: Stratos Karafotis <stratosk@semaphore.gr>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Vasily Kulikov <segoon@openwall.com>
Cc: Vineet Gupta <vgupta@synopsys.com>
Cc: Vineet Gupta <Vineet.Gupta1@synopsys.com>
Cc: Waiman Long <Waiman.Long@hp.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Wolfram Sang <wsa@the-dreams.de>
Cc: adi-buildroot-devel@lists.sourceforge.net
Cc: linux390@de.ibm.com
Cc: linux-alpha@vger.kernel.org
Cc: linux-am33-list@redhat.com
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-c6x-dev@linux-c6x.org
Cc: linux-cris-kernel@axis.com
Cc: linux-hexagon@vger.kernel.org
Cc: linux-ia64@vger.kernel.org
Cc: linux@lists.openrisc.net
Cc: linux-m32r-ja@ml.linux-m32r.org
Cc: linux-m32r@ml.linux-m32r.org
Cc: linux-m68k@lists.linux-m68k.org
Cc: linux-metag@vger.kernel.org
Cc: linux-mips@linux-mips.org
Cc: linux-parisc@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-s390@vger.kernel.org
Cc: linux-sh@vger.kernel.org
Cc: linux-xtensa@linux-xtensa.org
Cc: sparclinux@vger.kernel.org
Link: http://lkml.kernel.org/r/1404079773.2619.4.camel@buesod1.americas.hpqcorp.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>
168 lines
3.8 KiB
C
168 lines
3.8 KiB
C
/*
|
|
* Copyright (C) 2004-2006 Atmel Corporation
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*/
|
|
#ifndef __ASM_AVR32_PROCESSOR_H
|
|
#define __ASM_AVR32_PROCESSOR_H
|
|
|
|
#include <asm/page.h>
|
|
#include <asm/cache.h>
|
|
|
|
#define TASK_SIZE 0x80000000
|
|
|
|
#ifdef __KERNEL__
|
|
#define STACK_TOP TASK_SIZE
|
|
#define STACK_TOP_MAX STACK_TOP
|
|
#endif
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
static inline void *current_text_addr(void)
|
|
{
|
|
register void *pc asm("pc");
|
|
return pc;
|
|
}
|
|
|
|
enum arch_type {
|
|
ARCH_AVR32A,
|
|
ARCH_AVR32B,
|
|
ARCH_MAX
|
|
};
|
|
|
|
enum cpu_type {
|
|
CPU_MORGAN,
|
|
CPU_AT32AP,
|
|
CPU_MAX
|
|
};
|
|
|
|
enum tlb_config {
|
|
TLB_NONE,
|
|
TLB_SPLIT,
|
|
TLB_UNIFIED,
|
|
TLB_INVALID
|
|
};
|
|
|
|
#define AVR32_FEATURE_RMW (1 << 0)
|
|
#define AVR32_FEATURE_DSP (1 << 1)
|
|
#define AVR32_FEATURE_SIMD (1 << 2)
|
|
#define AVR32_FEATURE_OCD (1 << 3)
|
|
#define AVR32_FEATURE_PCTR (1 << 4)
|
|
#define AVR32_FEATURE_JAVA (1 << 5)
|
|
#define AVR32_FEATURE_FPU (1 << 6)
|
|
|
|
struct avr32_cpuinfo {
|
|
struct clk *clk;
|
|
unsigned long loops_per_jiffy;
|
|
enum arch_type arch_type;
|
|
enum cpu_type cpu_type;
|
|
unsigned short arch_revision;
|
|
unsigned short cpu_revision;
|
|
enum tlb_config tlb_config;
|
|
unsigned long features;
|
|
u32 device_id;
|
|
|
|
struct cache_info icache;
|
|
struct cache_info dcache;
|
|
};
|
|
|
|
static inline unsigned int avr32_get_manufacturer_id(struct avr32_cpuinfo *cpu)
|
|
{
|
|
return (cpu->device_id >> 1) & 0x7f;
|
|
}
|
|
static inline unsigned int avr32_get_product_number(struct avr32_cpuinfo *cpu)
|
|
{
|
|
return (cpu->device_id >> 12) & 0xffff;
|
|
}
|
|
static inline unsigned int avr32_get_chip_revision(struct avr32_cpuinfo *cpu)
|
|
{
|
|
return (cpu->device_id >> 28) & 0x0f;
|
|
}
|
|
|
|
extern struct avr32_cpuinfo boot_cpu_data;
|
|
|
|
/* No SMP support so far */
|
|
#define current_cpu_data boot_cpu_data
|
|
|
|
/* This decides where the kernel will search for a free chunk of vm
|
|
* space during mmap's
|
|
*/
|
|
#define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
|
|
|
|
#define cpu_relax() barrier()
|
|
#define cpu_relax_lowlatency() cpu_relax()
|
|
#define cpu_sync_pipeline() asm volatile("sub pc, -2" : : : "memory")
|
|
|
|
struct cpu_context {
|
|
unsigned long sr;
|
|
unsigned long pc;
|
|
unsigned long ksp; /* Kernel stack pointer */
|
|
unsigned long r7;
|
|
unsigned long r6;
|
|
unsigned long r5;
|
|
unsigned long r4;
|
|
unsigned long r3;
|
|
unsigned long r2;
|
|
unsigned long r1;
|
|
unsigned long r0;
|
|
};
|
|
|
|
/* This struct contains the CPU context as stored by switch_to() */
|
|
struct thread_struct {
|
|
struct cpu_context cpu_context;
|
|
unsigned long single_step_addr;
|
|
u16 single_step_insn;
|
|
};
|
|
|
|
#define INIT_THREAD { \
|
|
.cpu_context = { \
|
|
.ksp = sizeof(init_stack) + (long)&init_stack, \
|
|
}, \
|
|
}
|
|
|
|
/*
|
|
* Do necessary setup to start up a newly executed thread.
|
|
*/
|
|
#define start_thread(regs, new_pc, new_sp) \
|
|
do { \
|
|
memset(regs, 0, sizeof(*regs)); \
|
|
regs->sr = MODE_USER; \
|
|
regs->pc = new_pc & ~1; \
|
|
regs->sp = new_sp; \
|
|
} while(0)
|
|
|
|
struct task_struct;
|
|
|
|
/* Free all resources held by a thread */
|
|
extern void release_thread(struct task_struct *);
|
|
|
|
/* Return saved PC of a blocked thread */
|
|
#define thread_saved_pc(tsk) ((tsk)->thread.cpu_context.pc)
|
|
|
|
struct pt_regs;
|
|
extern unsigned long get_wchan(struct task_struct *p);
|
|
extern void show_regs_log_lvl(struct pt_regs *regs, const char *log_lvl);
|
|
extern void show_stack_log_lvl(struct task_struct *tsk, unsigned long sp,
|
|
struct pt_regs *regs, const char *log_lvl);
|
|
|
|
#define task_pt_regs(p) \
|
|
((struct pt_regs *)(THREAD_SIZE + task_stack_page(p)) - 1)
|
|
|
|
#define KSTK_EIP(tsk) ((tsk)->thread.cpu_context.pc)
|
|
#define KSTK_ESP(tsk) ((tsk)->thread.cpu_context.ksp)
|
|
|
|
#define ARCH_HAS_PREFETCH
|
|
|
|
static inline void prefetch(const void *x)
|
|
{
|
|
const char *c = x;
|
|
asm volatile("pref %0" : : "r"(c));
|
|
}
|
|
#define PREFETCH_STRIDE L1_CACHE_BYTES
|
|
|
|
#endif /* __ASSEMBLY__ */
|
|
|
|
#endif /* __ASM_AVR32_PROCESSOR_H */
|