atomic64_cmpxchg、atomic_cmpxchg是宏定义,第一个参数使用强制类型转换,移植代码到64位系统时容易入坑。
问题代码
以下代码移植到arm64后,出现BUG,64位的指针,低32位为想要的值,高32位还是原先的值。
struct property *property = NULL;
struct property *result;
result = kmalloc(sizeof(struct property), GFP_KERNEL);
if (atomic_cmpxchg((atomic_t *)&property, 0, (int)result) != 0) {
free(result);
}
atomic[64]_t
include/linux/types.h
174 typedef struct {
175 int counter;
176 } atomic_t;
177
178 #ifdef CONFIG_64BIT
179 typedef struct {
180 long counter;
181 } atomic64_t;
182 #endif
arm
arch/arm/include/asm/atomic.h
268 #ifndef CONFIG_GENERIC_ATOMIC64
269 typedef struct {
270 long long counter;
271 } atomic64_t;
272
273 #define ATOMIC64_INIT(i) { (i) }
atomic[64]_cmpxchg
arm64
atomic64_cmpxchg、atomic_cmpxchg实际上是相同的,宏定义位于arch/arm64/include/asm/atomic.h文件。# CONFIG_ARM64_LSE_ATOMICS is not set,使用arch/arm64/include/asm/atomic_ll_sc.h。atomic64_cmpxchg cmpxchg都是宏定义,第一个参数(指针指向的内容),决定按32位还是64位操作。
120 #define atomic_cmpxchg(v, old, new) cmpxchg(&((v)->counter), (old), (new))
196 #define atomic64_cmpxchg atomic_cmpxchg
cmpxchg[64]
cmpxchg64、cmpxchg也是相同的,宏定义位于arch/arm64/include/asm/cmpxchg.h文件。
155 /* cmpxchg */
156 #define cmpxchg_relaxed(...) __cmpxchg_wrapper( , __VA_ARGS__)
157 #define cmpxchg_acquire(...) __cmpxchg_wrapper(_acq, __VA_ARGS__)
158 #define cmpxchg_release(...) __cmpxchg_wrapper(_rel, __VA_ARGS__)
159 #define cmpxchg(...) __cmpxchg_wrapper( _mb, __VA_ARGS__)
160 #define cmpxchg_local cmpxchg_relaxed
161
162 /* cmpxchg64 */
163 #define cmpxchg64_relaxed cmpxchg_relaxed
164 #d