Commit a2314817 authored by Rusty Russell's avatar Rusty Russell Committed by Linus Torvalds

[PATCH] DECLARE_PER_CPU/DEFINE_PER_CPU patch

This old __per_cpu_data define wasn't enough if an arch wants to
use the gcc __thread prefix (thread local storage), which needs to
go *before* the type in the definition.  So we have to go for a
DECLARE macro, and while we're there, separate DECLARE and DEFINE,
as definitions of per-cpu data cannot live in modules.  This also
means that accidental direct references to per-cpu variables will
be caught at compile time.
parent 466e44bb
......@@ -375,8 +375,8 @@ static pmu_config_t pmu_conf; /* PMU configuration */
static pfm_session_t pfm_sessions; /* global sessions information */
static struct proc_dir_entry *perfmon_dir; /* for debug only */
static pfm_stats_t pfm_stats;
int __per_cpu_data pfm_syst_wide;
static int __per_cpu_data pfm_dcr_pp;
DEFINE_PER_CPU(int, pfm_syst_wide);
static DEFINE_PER_CPU(int, pfm_dcr_pp);
/* sysctl() controls */
static pfm_sysctl_t pfm_sysctl;
......
......@@ -58,7 +58,7 @@ extern char _end;
unsigned long __per_cpu_offset[NR_CPUS];
#endif
struct cpuinfo_ia64 cpu_info __per_cpu_data;
DECLARE_PER_CPU(struct cpuinfo_ia64, cpu_info);
unsigned long ia64_phys_stacked_size_p8;
unsigned long ia64_cycles_per_usec;
......
......@@ -80,7 +80,7 @@ static volatile struct call_data_struct *call_data;
#define IPI_CPU_STOP 1
/* This needs to be cacheline aligned because it is written to by *other* CPUs. */
static __u64 ipi_operation __per_cpu_data ____cacheline_aligned;
static DECLARE_PER_CPU(__u64, ipi_operation) ____cacheline_aligned;
static void
stop_this_cpu (void)
......
#ifndef _ASM_GENERIC_PERCPU_H_
#define _ASM_GENERIC_PERCPU_H_
#include <linux/compiler.h>
#define __GENERIC_PER_CPU
#include <linux/compiler.h>
#ifdef CONFIG_SMP
extern unsigned long __per_cpu_offset[NR_CPUS];
/* Separate out the type, so (int[3], foo) works. */
#ifndef MODULE
#define DEFINE_PER_CPU(type, name) \
__attribute__((__section__(".percpu"))) __typeof__(type) name##__per_cpu
#endif
/* var is in discarded region: offset to particular copy we want */
#define per_cpu(var, cpu) (*RELOC_HIDE(&var, __per_cpu_offset[cpu]))
#define per_cpu(var, cpu) (*RELOC_HIDE(&var##__per_cpu, __per_cpu_offset[cpu]))
#define __get_cpu_var(var) per_cpu(var, smp_processor_id())
#else /* ! SMP */
/* Can't define per-cpu variables in modules. Sorry --RR */
#ifndef MODULE
#define DEFINE_PER_CPU(type, name) \
__typeof__(type) name##__per_cpu
#endif
#define per_cpu(var, cpu) var##__per_cpu
#define __get_cpu_var(var) var##__per_cpu
#endif
#define DECLARE_PER_CPU(type, name) extern __typeof__(type) name##__per_cpu
#endif /* _ASM_GENERIC_PERCPU_H_ */
......@@ -8,7 +8,7 @@
#ifdef __ASSEMBLY__
#define THIS_CPU(var) (var) /* use this to mark accesses to per-CPU variables... */
#define THIS_CPU(var) (var##__per_cpu) /* use this to mark accesses to per-CPU variables... */
#else /* !__ASSEMBLY__ */
......@@ -16,8 +16,14 @@
extern unsigned long __per_cpu_offset[NR_CPUS];
#define per_cpu(var, cpu) (*(__typeof__(&(var))) ((void *) &(var) + __per_cpu_offset[cpu]))
#define __get_cpu_var(var) (var)
#ifndef MODULE
#define DEFINE_PER_CPU(type, name) \
__attribute__((__section__(".data.percpu"))) __typeof__(type) name##__per_cpu
#endif
#define DECLARE_PER_CPU(type, name) extern __typeof__(type) name##__per_cpu
#define per_cpu(var, cpu) (*RELOC_HIDE(&var##__per_cpu, __per_cpu_offset[cpu]))
#define __get_cpu_var(var) (var##__per_cpu)
#endif /* !__ASSEMBLY__ */
......
......@@ -134,7 +134,7 @@ struct ia64_psr {
* CPU type, hardware bug flags, and per-CPU state. Frequently used
* state comes earlier:
*/
extern struct cpuinfo_ia64 {
struct cpuinfo_ia64 {
/* irq_stat must be 64-bit aligned */
union {
struct {
......@@ -175,7 +175,9 @@ extern struct cpuinfo_ia64 {
__u64 prof_counter;
__u64 prof_multiplier;
#endif
} cpu_info __per_cpu_data;
};
DECLARE_PER_CPU(struct cpuinfo_ia64, cpu_info);
/*
* The "local" data pointer. It points to the per-CPU data of the currently executing
......
#ifndef __LINUX_PERCPU_H
#define __LINUX_PERCPU_H
#include <linux/config.h>
#ifdef CONFIG_SMP
#define __per_cpu_data __attribute__((section(".data.percpu")))
#include <linux/spinlock.h> /* For preempt_disable() */
#include <asm/percpu.h>
#else
#define __per_cpu_data
#define per_cpu(var, cpu) var
#define __get_cpu_var(var) var
#endif
#define get_cpu_var(var) ({ preempt_disable(); __get_cpu_var(var); })
#define put_cpu_var(var) preempt_enable()
#endif /* __LINUX_PERCPU_H */
......@@ -151,8 +151,8 @@ struct tasklet_head
/* Some compilers disobey section attribute on statics when not
initialized -- RR */
static struct tasklet_head tasklet_vec __per_cpu_data = { NULL };
static struct tasklet_head tasklet_hi_vec __per_cpu_data = { NULL };
static DEFINE_PER_CPU(struct tasklet_head, tasklet_vec) = { NULL };
static DEFINE_PER_CPU(struct tasklet_head, tasklet_hi_vec) = { NULL };
void __tasklet_schedule(struct tasklet_struct *t)
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment