DSP

uclinux-2008R1.5-RC3(bf561)到VDSP5的移植(47):per_cpu的奇

2019-07-13 15:40发布

  快乐虾 http://blog.csdn.net/lights_joy/ lights@hb165.com   本文适用于 ADI bf561 DSP 优视BF561EVB开发板 uclinux-2008r1.5-rc3(smp patch) Visual DSP++ 5.0(update 5)   欢迎转载,但请保留作者信息   有一个错误: "../../linux-2.6.x/include/linux/rcupdate.h", line 124: cc0144:  error: a           value of type "volatile __typeof__(struct rcu_data) *" cannot be           used to initialize an entity of type "struct rcu_data *"   struct rcu_data *rdp = &per_cpu(rcu_data, cpu);                          ^ 错误指向的代码为: DECLARE_PER_CPU(struct rcu_data, rcu_data); /*  * Increment the quiescent state counter.  * The counter is a bit degenerated: We do not need to know  * how many quiescent states passed, just if there was at least  * one since the start of the grace period. Thus just a flag.  */ static inline void rcu_qsctr_inc(int cpu) {      struct rcu_data *rdp = &per_cpu(rcu_data, cpu);      rdp->passed_quiesc = 1; } 先看一下DECLARE_PER_CPU的定义: #define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name 代入第一行就是: extern struct rcu_data per_cpu__ rcu_data; 再看看per_cpu的定义: /* var is in discarded region: offset to particular copy we want */ #define per_cpu(var, cpu) (*({                 /      extern int simple_identifier_##var(void); /      RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]); }))   /* This macro obfuscates arithmetic on a variable address so that gcc    shouldn't recognize the original var, and make assumptions about it */ /*  * Versions of the ppc64 compiler before 4.1 had a bug where use of  * RELOC_HIDE could trash r30. The bug can be worked around by changing  * the inline assembly constraint from =g to =r, in this particular  * case either is valid.  */ #define RELOC_HIDE(ptr, off)                       /   ({ unsigned long __ptr;                      /     __asm__ ("" : "=r"(__ptr) : "0"(ptr));         /     (__typeof__(ptr)) (__ptr + (off)); }) 从头到尾都没有出现volatile,奇怪? 再看看rcu_data实际定义的地方: DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L }; 使用了DEFINE_PER_CPU宏,看看它的定义: #define DEFINE_PER_CPU(type, name) /     __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name 只不过是把这个结构体放在.data.percpu这个段里,也没有特别的地方。 百思不得其解,先放过它,直接强制转换: /*  * Increment the quiescent state counter.  * The counter is a bit degenerated: We do not need to know  * how many quiescent states passed, just if there was at least  * one since the start of the grace period. Thus just a flag.  */ static inline void rcu_qsctr_inc(int cpu) {      struct rcu_data *rdp = (struct rcu_data *)&per_cpu(rcu_data, cpu);      rdp->passed_quiesc = 1; }

1       参考资料

uclinux-2008R1.5-RC3(bf561)VDSP5的移植(41)bfin_write_EVT15(2009-1-17) uclinux-2008R1.5-RC3(bf561)VDSP5的移植(42).macro(2009-1-17) uclinux-2008R1.5-RC3(bf561)VDSP5的移植(43)exception_stacks(2009-1-18) uclinux-2008R1.5-RC3(bf561)VDSP5的移(44)Out of memory(2009-01-19) uclinux-2008R1.5-RC3(bf561)VDSP5的移植(45):未命名union的后遗症(2009-01-21) uclinux-2008R1.5-RC3(bf561)VDSP5的移植(46)fls_long的问题(2009-1-21)