Merge branch 'core/percpu' into x86/core
Conflicts: kernel/irq/handle.c
This commit is contained in:
@@ -80,4 +80,56 @@ extern void setup_per_cpu_areas(void);
|
||||
#define DECLARE_PER_CPU(type, name) extern PER_CPU_ATTRIBUTES \
|
||||
__typeof__(type) per_cpu_var(name)
|
||||
|
||||
/*
|
||||
* Optional methods for optimized non-lvalue per-cpu variable access.
|
||||
*
|
||||
* @var can be a percpu variable or a field of it and its size should
|
||||
* equal char, int or long. percpu_read() evaluates to a lvalue and
|
||||
* all others to void.
|
||||
*
|
||||
* These operations are guaranteed to be atomic w.r.t. preemption.
|
||||
* The generic versions use plain get/put_cpu_var(). Archs are
|
||||
* encouraged to implement single-instruction alternatives which don't
|
||||
* require preemption protection.
|
||||
*/
|
||||
#ifndef percpu_read
|
||||
# define percpu_read(var) \
|
||||
({ \
|
||||
typeof(per_cpu_var(var)) __tmp_var__; \
|
||||
__tmp_var__ = get_cpu_var(var); \
|
||||
put_cpu_var(var); \
|
||||
__tmp_var__; \
|
||||
})
|
||||
#endif
|
||||
|
||||
#define __percpu_generic_to_op(var, val, op) \
|
||||
do { \
|
||||
get_cpu_var(var) op val; \
|
||||
put_cpu_var(var); \
|
||||
} while (0)
|
||||
|
||||
#ifndef percpu_write
|
||||
# define percpu_write(var, val) __percpu_generic_to_op(var, (val), =)
|
||||
#endif
|
||||
|
||||
#ifndef percpu_add
|
||||
# define percpu_add(var, val) __percpu_generic_to_op(var, (val), +=)
|
||||
#endif
|
||||
|
||||
#ifndef percpu_sub
|
||||
# define percpu_sub(var, val) __percpu_generic_to_op(var, (val), -=)
|
||||
#endif
|
||||
|
||||
#ifndef percpu_and
|
||||
# define percpu_and(var, val) __percpu_generic_to_op(var, (val), &=)
|
||||
#endif
|
||||
|
||||
#ifndef percpu_or
|
||||
# define percpu_or(var, val) __percpu_generic_to_op(var, (val), |=)
|
||||
#endif
|
||||
|
||||
#ifndef percpu_xor
|
||||
# define percpu_xor(var, val) __percpu_generic_to_op(var, (val), ^=)
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_GENERIC_PERCPU_H_ */
|
||||
|
||||
@@ -9,7 +9,7 @@ extern char __bss_start[], __bss_stop[];
|
||||
extern char __init_begin[], __init_end[];
|
||||
extern char _sinittext[], _einittext[];
|
||||
extern char _end[];
|
||||
extern char __per_cpu_start[], __per_cpu_end[];
|
||||
extern char __per_cpu_load[], __per_cpu_start[], __per_cpu_end[];
|
||||
extern char __kprobes_text_start[], __kprobes_text_end[];
|
||||
extern char __initdata_begin[], __initdata_end[];
|
||||
extern char __start_rodata[], __end_rodata[];
|
||||
|
||||
@@ -430,12 +430,48 @@
|
||||
*(.initcall7.init) \
|
||||
*(.initcall7s.init)
|
||||
|
||||
#define PERCPU(align) \
|
||||
. = ALIGN(align); \
|
||||
VMLINUX_SYMBOL(__per_cpu_start) = .; \
|
||||
.data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { \
|
||||
/**
|
||||
* PERCPU_VADDR - define output section for percpu area
|
||||
* @vaddr: explicit base address (optional)
|
||||
* @phdr: destination PHDR (optional)
|
||||
*
|
||||
* Macro which expands to output section for percpu area. If @vaddr
|
||||
* is not blank, it specifies explicit base address and all percpu
|
||||
* symbols will be offset from the given address. If blank, @vaddr
|
||||
* always equals @laddr + LOAD_OFFSET.
|
||||
*
|
||||
* @phdr defines the output PHDR to use if not blank. Be warned that
|
||||
* output PHDR is sticky. If @phdr is specified, the next output
|
||||
* section in the linker script will go there too. @phdr should have
|
||||
* a leading colon.
|
||||
*
|
||||
* This macro defines three symbols, __per_cpu_load, __per_cpu_start
|
||||
* and __per_cpu_end. The first one is the vaddr of loaded percpu
|
||||
* init data. __per_cpu_start equals @vaddr and __per_cpu_end is the
|
||||
* end offset.
|
||||
*/
|
||||
#define PERCPU_VADDR(vaddr, phdr) \
|
||||
VMLINUX_SYMBOL(__per_cpu_load_abs) = .; \
|
||||
.data.percpu vaddr : AT(VMLINUX_SYMBOL(__per_cpu_load_abs) \
|
||||
- LOAD_OFFSET) { \
|
||||
VMLINUX_SYMBOL(__per_cpu_start) = .; \
|
||||
VMLINUX_SYMBOL(__per_cpu_load) = LOADADDR(.data.percpu) + LOAD_OFFSET;\
|
||||
*(.data.percpu.first) \
|
||||
*(.data.percpu.page_aligned) \
|
||||
*(.data.percpu) \
|
||||
*(.data.percpu.shared_aligned) \
|
||||
} \
|
||||
VMLINUX_SYMBOL(__per_cpu_end) = .;
|
||||
VMLINUX_SYMBOL(__per_cpu_end) = .; \
|
||||
} phdr \
|
||||
. = VMLINUX_SYMBOL(__per_cpu_load_abs) + SIZEOF(.data.percpu);
|
||||
|
||||
/**
|
||||
* PERCPU - define output section for percpu area, simple version
|
||||
* @align: required alignment
|
||||
*
|
||||
* Align to @align and outputs output section for percpu area. This
|
||||
* macro doesn't maniuplate @vaddr or @phdr and __per_cpu_load and
|
||||
* __per_cpu_start will be identical.
|
||||
*/
|
||||
#define PERCPU(align) \
|
||||
. = ALIGN(align); \
|
||||
PERCPU_VADDR( , )
|
||||
|
||||
@@ -467,6 +467,7 @@ int show_interrupts(struct seq_file *p, void *v);
|
||||
struct irq_desc;
|
||||
|
||||
extern int early_irq_init(void);
|
||||
extern int arch_probe_nr_irqs(void);
|
||||
extern int arch_early_irq_init(void);
|
||||
extern int arch_init_chip_data(struct irq_desc *desc, int cpu);
|
||||
|
||||
|
||||
+83
-3
@@ -182,11 +182,11 @@ struct irq_desc {
|
||||
unsigned int irqs_unhandled;
|
||||
spinlock_t lock;
|
||||
#ifdef CONFIG_SMP
|
||||
cpumask_t affinity;
|
||||
cpumask_var_t affinity;
|
||||
unsigned int cpu;
|
||||
#endif
|
||||
#ifdef CONFIG_GENERIC_PENDING_IRQ
|
||||
cpumask_t pending_mask;
|
||||
cpumask_var_t pending_mask;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CONFIG_PROC_FS
|
||||
struct proc_dir_entry *dir;
|
||||
@@ -422,4 +422,84 @@ extern int set_irq_msi(unsigned int irq, struct msi_desc *entry);
|
||||
|
||||
#endif /* !CONFIG_S390 */
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/**
|
||||
* init_alloc_desc_masks - allocate cpumasks for irq_desc
|
||||
* @desc: pointer to irq_desc struct
|
||||
* @cpu: cpu which will be handling the cpumasks
|
||||
* @boot: true if need bootmem
|
||||
*
|
||||
* Allocates affinity and pending_mask cpumask if required.
|
||||
* Returns true if successful (or not required).
|
||||
* Side effect: affinity has all bits set, pending_mask has all bits clear.
|
||||
*/
|
||||
static inline bool init_alloc_desc_masks(struct irq_desc *desc, int cpu,
|
||||
bool boot)
|
||||
{
|
||||
int node;
|
||||
|
||||
if (boot) {
|
||||
alloc_bootmem_cpumask_var(&desc->affinity);
|
||||
cpumask_setall(desc->affinity);
|
||||
|
||||
#ifdef CONFIG_GENERIC_PENDING_IRQ
|
||||
alloc_bootmem_cpumask_var(&desc->pending_mask);
|
||||
cpumask_clear(desc->pending_mask);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
node = cpu_to_node(cpu);
|
||||
|
||||
if (!alloc_cpumask_var_node(&desc->affinity, GFP_ATOMIC, node))
|
||||
return false;
|
||||
cpumask_setall(desc->affinity);
|
||||
|
||||
#ifdef CONFIG_GENERIC_PENDING_IRQ
|
||||
if (!alloc_cpumask_var_node(&desc->pending_mask, GFP_ATOMIC, node)) {
|
||||
free_cpumask_var(desc->affinity);
|
||||
return false;
|
||||
}
|
||||
cpumask_clear(desc->pending_mask);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* init_copy_desc_masks - copy cpumasks for irq_desc
|
||||
* @old_desc: pointer to old irq_desc struct
|
||||
* @new_desc: pointer to new irq_desc struct
|
||||
*
|
||||
* Insures affinity and pending_masks are copied to new irq_desc.
|
||||
* If !CONFIG_CPUMASKS_OFFSTACK the cpumasks are embedded in the
|
||||
* irq_desc struct so the copy is redundant.
|
||||
*/
|
||||
|
||||
static inline void init_copy_desc_masks(struct irq_desc *old_desc,
|
||||
struct irq_desc *new_desc)
|
||||
{
|
||||
#ifdef CONFIG_CPUMASKS_OFFSTACK
|
||||
cpumask_copy(new_desc->affinity, old_desc->affinity);
|
||||
|
||||
#ifdef CONFIG_GENERIC_PENDING_IRQ
|
||||
cpumask_copy(new_desc->pending_mask, old_desc->pending_mask);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#else /* !CONFIG_SMP */
|
||||
|
||||
static inline bool init_alloc_desc_masks(struct irq_desc *desc, int cpu,
|
||||
bool boot)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void init_copy_desc_masks(struct irq_desc *old_desc,
|
||||
struct irq_desc *new_desc)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
#endif /* _LINUX_IRQ_H */
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
# define for_each_irq_desc_reverse(irq, desc) \
|
||||
for (irq = nr_irqs - 1; irq >= 0; irq--)
|
||||
|
||||
#else /* CONFIG_GENERIC_HARDIRQS */
|
||||
|
||||
extern int nr_irqs;
|
||||
|
||||
@@ -49,4 +49,5 @@
|
||||
#define FUTEXFS_SUPER_MAGIC 0xBAD1DEA
|
||||
#define INOTIFYFS_SUPER_MAGIC 0x2BAD1DEA
|
||||
|
||||
#define STACK_END_MAGIC 0x57AC6E9D
|
||||
#endif /* __LINUX_MAGIC_H__ */
|
||||
|
||||
+24
-19
@@ -9,34 +9,39 @@
|
||||
#include <asm/percpu.h>
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define DEFINE_PER_CPU(type, name) \
|
||||
__attribute__((__section__(".data.percpu"))) \
|
||||
PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name
|
||||
#define PER_CPU_BASE_SECTION ".data.percpu"
|
||||
|
||||
#ifdef MODULE
|
||||
#define SHARED_ALIGNED_SECTION ".data.percpu"
|
||||
#define PER_CPU_SHARED_ALIGNED_SECTION ""
|
||||
#else
|
||||
#define SHARED_ALIGNED_SECTION ".data.percpu.shared_aligned"
|
||||
#define PER_CPU_SHARED_ALIGNED_SECTION ".shared_aligned"
|
||||
#endif
|
||||
#define PER_CPU_FIRST_SECTION ".first"
|
||||
|
||||
#else
|
||||
|
||||
#define PER_CPU_BASE_SECTION ".data"
|
||||
#define PER_CPU_SHARED_ALIGNED_SECTION ""
|
||||
#define PER_CPU_FIRST_SECTION ""
|
||||
|
||||
#endif
|
||||
|
||||
#define DEFINE_PER_CPU_SECTION(type, name, section) \
|
||||
__attribute__((__section__(PER_CPU_BASE_SECTION section))) \
|
||||
PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name
|
||||
|
||||
#define DEFINE_PER_CPU(type, name) \
|
||||
DEFINE_PER_CPU_SECTION(type, name, "")
|
||||
|
||||
#define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \
|
||||
__attribute__((__section__(SHARED_ALIGNED_SECTION))) \
|
||||
PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name \
|
||||
DEFINE_PER_CPU_SECTION(type, name, PER_CPU_SHARED_ALIGNED_SECTION) \
|
||||
____cacheline_aligned_in_smp
|
||||
|
||||
#define DEFINE_PER_CPU_PAGE_ALIGNED(type, name) \
|
||||
__attribute__((__section__(".data.percpu.page_aligned"))) \
|
||||
PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name
|
||||
#else
|
||||
#define DEFINE_PER_CPU(type, name) \
|
||||
PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name
|
||||
#define DEFINE_PER_CPU_PAGE_ALIGNED(type, name) \
|
||||
DEFINE_PER_CPU_SECTION(type, name, ".page_aligned")
|
||||
|
||||
#define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \
|
||||
DEFINE_PER_CPU(type, name)
|
||||
|
||||
#define DEFINE_PER_CPU_PAGE_ALIGNED(type, name) \
|
||||
DEFINE_PER_CPU(type, name)
|
||||
#endif
|
||||
#define DEFINE_PER_CPU_FIRST(type, name) \
|
||||
DEFINE_PER_CPU_SECTION(type, name, PER_CPU_FIRST_SECTION)
|
||||
|
||||
#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var)
|
||||
#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var)
|
||||
|
||||
+14
-2
@@ -1161,10 +1161,9 @@ struct task_struct {
|
||||
pid_t pid;
|
||||
pid_t tgid;
|
||||
|
||||
#ifdef CONFIG_CC_STACKPROTECTOR
|
||||
/* Canary value for the -fstack-protector gcc feature */
|
||||
unsigned long stack_canary;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* pointers to (original) parent process, youngest child, younger sibling,
|
||||
* older sibling, respectively. (p->father can be replaced with
|
||||
@@ -2070,6 +2069,19 @@ static inline int object_is_on_stack(void *obj)
|
||||
|
||||
extern void thread_info_cache_init(void);
|
||||
|
||||
#ifdef CONFIG_DEBUG_STACK_USAGE
|
||||
static inline unsigned long stack_not_used(struct task_struct *p)
|
||||
{
|
||||
unsigned long *n = end_of_stack(p);
|
||||
|
||||
do { /* Skip over canary */
|
||||
n++;
|
||||
} while (!*n);
|
||||
|
||||
return (unsigned long)n - (unsigned long)end_of_stack(p);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* set thread flags in other task's structures
|
||||
* - see asm/thread_info.h for TIF_xxxx flags available
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef _LINUX_STACKPROTECTOR_H
|
||||
#define _LINUX_STACKPROTECTOR_H 1
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
#ifdef CONFIG_CC_STACKPROTECTOR
|
||||
# include <asm/stackprotector.h>
|
||||
#else
|
||||
static inline void boot_init_stack_canary(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -193,5 +193,11 @@ int arch_update_cpu_topology(void);
|
||||
#ifndef topology_core_siblings
|
||||
#define topology_core_siblings(cpu) cpumask_of_cpu(cpu)
|
||||
#endif
|
||||
#ifndef topology_thread_cpumask
|
||||
#define topology_thread_cpumask(cpu) cpumask_of(cpu)
|
||||
#endif
|
||||
#ifndef topology_core_cpumask
|
||||
#define topology_core_cpumask(cpu) cpumask_of(cpu)
|
||||
#endif
|
||||
|
||||
#endif /* _LINUX_TOPOLOGY_H */
|
||||
|
||||
Reference in New Issue
Block a user