Skip to contentSkip to conversation

local_t for IA64

PATCH Rusty Russell 1 participant 1 message Jul 16, 2003 Atomic infrastructure

lore
Share & tools
lore
#0 lore raw

And then David M-T was second.

Rusty.

Name: local_t ia64 support
Author: David Mosberger <[email protected]>
Status: Tested on 2.6.0-test1
Depends: Percpu/local_t.patch.gz
Depends: Misc/i386_linker_symbols.patch.gz

D: There are others who wanted atomic64 for some time (on 64-bit
D: platforms), so I added it to asm-ia64/atomic.h as well.
D:
D: I attached the percpu.h and local.h which I'm using on ia64.
D: It all seems to work very nicely.
D:
D: __get_cpu_var() now returns the canonical address, so there is no
D: source of confusion (if someone really knows what they're doing, they
D: can still use __ia64_per_cpu_var() to get the aliased variable).
D: To avoid an array-lookup, I defined a per-CPU variable which holds
D: the per-CPU offset of the current CPU. WIth that, __get_cpu_var()
D: becomes:
D:
D: #define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __ia64_per_cpu_var(local_per_cpu_offset))) D:
D: (Yeah, it runs the risk of messing with your head, but if you think
D: about it the right way, it's entirely obvious... ;-).

===== include/asm-ia64/percpu.h 1.8 vs edited =====

include/asm-ia64/percpu.h +39 -16
@@ -1,42 +1,65 @@
 #ifndef _ASM_IA64_PERCPU_H
 #define _ASM_IA64_PERCPU_H
 
-#include <linux/config.h>
-#include <linux/compiler.h>
-
 /*
  * Copyright (C) 2002-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <[email protected]>
  */
+
 #define PERCPU_ENOUGH_ROOM PERCPU_PAGE_SIZE
 
 #ifdef __ASSEMBLY__
-
-#define THIS_CPU(var)	(var##__per_cpu)  /* use this to mark accesses to per-CPU variables... */
-
+# define THIS_CPU(var)	(per_cpu__##var)  /* use this to mark accesses to per-CPU variables... */
 #else /* !__ASSEMBLY__ */
 
+#include <linux/config.h>
+
 #include <linux/threads.h>
 
+#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
+
+/*
+ * Pretty much a literal copy of asm-generic/percpu.h, except that percpu_modcopy() is an
+ * external routine, to avoid include-hell.
+ */
+#ifdef CONFIG_SMP
+
 extern unsigned long __per_cpu_offset[NR_CPUS];
 
+/* Equal to __per_cpu_offset[smp_processor_id()], but faster to access: */
+DECLARE_PER_CPU(unsigned long, local_per_cpu_offset);
+
+/* Separate out the type, so (int[3], foo) works. */
 #define DEFINE_PER_CPU(type, name) \
-    __attribute__((__section__(".data.percpu"))) __typeof__(type) name##__per_cpu
-#define DECLARE_PER_CPU(type, name) extern __typeof__(type) name##__per_cpu
+    __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name
 
-#define __get_cpu_var(var)	(var##__per_cpu)
-#ifdef CONFIG_SMP
-# define per_cpu(var, cpu)	(*RELOC_HIDE(&var##__per_cpu, __per_cpu_offset[cpu]))
+#define per_cpu(var, cpu)  (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]))
+#define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __ia64_per_cpu_var(local_per_cpu_offset)))
 
 extern void percpu_modcopy(void *pcpudst, const void *src, unsigned long size);
-#else
-# define per_cpu(var, cpu)	((void)cpu, __get_cpu_var(var))
-#endif
 
-#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(var##__per_cpu)
-#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(var##__per_cpu)
+#else /* ! SMP */
+
+#define DEFINE_PER_CPU(type, name)		__typeof__(type) per_cpu__##name
+#define per_cpu(var, cpu)			((void)cpu, per_cpu__##var)
+#define __get_cpu_var(var)			per_cpu__##var
+
+#endif	/* SMP */
+
+#define EXPORT_PER_CPU_SYMBOL(var)		EXPORT_SYMBOL(per_cpu__##var)
+#define EXPORT_PER_CPU_SYMBOL_GPL(var)		EXPORT_SYMBOL_GPL(per_cpu__##var)
+
+/* ia64-specific part: */
 
 extern void setup_per_cpu_areas (void);
+
+/*
+ * Be extremely careful when taking the address of this variable!  Due to virtual
+ * remapping, it is different from the canonical address returned by __get_cpu_var(var)!
+ * On the positive side, using __ia64_per_cpu_var() instead of __get_cpu_var() is slightly
+ * more efficient.
+ */
+#define __ia64_per_cpu_var(var)	(per_cpu__##var)
 
 #endif /* !__ASSEMBLY__ */
 

===== include/asm-ia64/atomic.h 1.6 vs edited =====

include/asm-ia64/atomic.h +75 -2

135 lines not on this page · raw message

asm-ia64/local.h new file +50 -0

50 lines not on this page · raw message

--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.