Author: hselasky
Date: Mon Sep 18 13:37:14 2017
New Revision: 323705
URL: https://svnweb.freebsd.org/changeset/base/323705

Log:
  The LinuxKPI atomics do not have acquire nor release semantics unless
  specified. Fix code to use READ_ONCE() and WRITE_ONCE() where appropriate.
  
  Suggested by:         kib @
  MFC after:            1 week
  Sponsored by:         Mellanox Technologies

Modified:
  head/sys/compat/linuxkpi/common/include/asm/atomic-long.h
  head/sys/compat/linuxkpi/common/include/asm/atomic.h
  head/sys/compat/linuxkpi/common/include/asm/atomic64.h
  head/sys/compat/linuxkpi/common/include/linux/bitops.h
  head/sys/compat/linuxkpi/common/src/linux_tasklet.c

Modified: head/sys/compat/linuxkpi/common/include/asm/atomic-long.h
==============================================================================
--- head/sys/compat/linuxkpi/common/include/asm/atomic-long.h   Mon Sep 18 
13:23:59 2017        (r323704)
+++ head/sys/compat/linuxkpi/common/include/asm/atomic-long.h   Mon Sep 18 
13:37:14 2017        (r323705)
@@ -2,7 +2,7 @@
  * Copyright (c) 2010 Isilon Systems, Inc.
  * Copyright (c) 2010 iX Systems, Inc.
  * Copyright (c) 2010 Panasas, Inc.
- * Copyright (c) 2013, 2014 Mellanox Technologies, Ltd.
+ * Copyright (c) 2013-2017 Mellanox Technologies, Ltd.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
 #ifndef        _ATOMIC_LONG_H_
 #define        _ATOMIC_LONG_H_
 
-#include <sys/cdefs.h>
+#include <linux/compiler.h>
 #include <sys/types.h>
 #include <machine/atomic.h>
 
@@ -54,13 +54,13 @@ atomic_long_add_return(long i, atomic_long_t *v)
 static inline void
 atomic_long_set(atomic_long_t *v, long i)
 {
-       atomic_store_rel_long(&v->counter, i);
+       WRITE_ONCE(v->counter, i);
 }
 
 static inline long
 atomic_long_read(atomic_long_t *v)
 {
-       return atomic_load_acq_long(&v->counter);
+       return READ_ONCE(v->counter);
 }
 
 static inline long

Modified: head/sys/compat/linuxkpi/common/include/asm/atomic.h
==============================================================================
--- head/sys/compat/linuxkpi/common/include/asm/atomic.h        Mon Sep 18 
13:23:59 2017        (r323704)
+++ head/sys/compat/linuxkpi/common/include/asm/atomic.h        Mon Sep 18 
13:37:14 2017        (r323705)
@@ -2,7 +2,7 @@
  * Copyright (c) 2010 Isilon Systems, Inc.
  * Copyright (c) 2010 iX Systems, Inc.
  * Copyright (c) 2010 Panasas, Inc.
- * Copyright (c) 2013-2016 Mellanox Technologies, Ltd.
+ * Copyright (c) 2013-2017 Mellanox Technologies, Ltd.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -32,9 +32,8 @@
 #ifndef _ASM_ATOMIC_H_
 #define        _ASM_ATOMIC_H_
 
-#include <sys/cdefs.h>
+#include <linux/compiler.h>
 #include <sys/types.h>
-
 #include <machine/atomic.h>
 
 #define        ATOMIC_INIT(x)  { .counter = (x) }
@@ -73,7 +72,7 @@ atomic_sub_return(int i, atomic_t *v)
 static inline void
 atomic_set(atomic_t *v, int i)
 {
-       atomic_store_rel_int(&v->counter, i);
+       WRITE_ONCE(v->counter, i);
 }
 
 static inline void
@@ -91,7 +90,7 @@ atomic_set_mask(unsigned int mask, atomic_t *v)
 static inline int
 atomic_read(const atomic_t *v)
 {
-       return atomic_load_acq_int(&__DECONST(atomic_t *, v)->counter);
+       return READ_ONCE(v->counter);
 }
 
 static inline int
@@ -137,7 +136,7 @@ atomic_xchg(atomic_t *v, int i)
 #else
        int ret;
        for (;;) {
-               ret = atomic_load_acq_int(&v->counter);
+               ret = READ_ONCE(v->counter);
                if (atomic_cmpset_int(&v->counter, ret, i))
                        break;
        }
@@ -153,7 +152,7 @@ atomic_cmpxchg(atomic_t *v, int old, int new)
        for (;;) {
                if (atomic_cmpset_int(&v->counter, old, new))
                        break;
-               ret = atomic_load_acq_int(&v->counter);
+               ret = READ_ONCE(v->counter);
                if (ret != old)
                        break;
        }

Modified: head/sys/compat/linuxkpi/common/include/asm/atomic64.h
==============================================================================
--- head/sys/compat/linuxkpi/common/include/asm/atomic64.h      Mon Sep 18 
13:23:59 2017        (r323704)
+++ head/sys/compat/linuxkpi/common/include/asm/atomic64.h      Mon Sep 18 
13:37:14 2017        (r323705)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2016 Mellanox Technologies, Ltd.
+ * Copyright (c) 2016-2017 Mellanox Technologies, Ltd.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,7 @@
 #ifndef        _ASM_ATOMIC64_H_
 #define        _ASM_ATOMIC64_H_
 
-#include <sys/cdefs.h>
+#include <linux/compiler.h>
 #include <sys/types.h>
 #include <machine/atomic.h>
 
@@ -74,7 +74,7 @@ atomic64_set(atomic64_t *v, int64_t i)
 static inline int64_t
 atomic64_read(atomic64_t *v)
 {
-       return atomic_load_acq_64(&v->counter);
+       return READ_ONCE(v->counter);
 }
 
 static inline int64_t
@@ -114,7 +114,7 @@ atomic64_xchg(atomic64_t *v, int64_t i)
 #else
        int64_t ret;
        for (;;) {
-               ret = atomic_load_acq_64(&v->counter);
+               ret = READ_ONCE(v->counter);
                if (atomic_cmpset_64(&v->counter, ret, i))
                        break;
        }
@@ -130,7 +130,7 @@ atomic64_cmpxchg(atomic64_t *v, int64_t old, int64_t n
        for (;;) {
                if (atomic_cmpset_64(&v->counter, old, new))
                        break;
-               ret = atomic_load_acq_64(&v->counter);
+               ret = READ_ONCE(v->counter);
                if (ret != old)
                        break;
        }

Modified: head/sys/compat/linuxkpi/common/include/linux/bitops.h
==============================================================================
--- head/sys/compat/linuxkpi/common/include/linux/bitops.h      Mon Sep 18 
13:23:59 2017        (r323704)
+++ head/sys/compat/linuxkpi/common/include/linux/bitops.h      Mon Sep 18 
13:37:14 2017        (r323705)
@@ -269,8 +269,7 @@ find_next_zero_bit(const unsigned long *addr, unsigned
     atomic_clear_long(&((volatile unsigned long *)(a))[BIT_WORD(i)], 
BIT_MASK(i))
 
 #define        test_bit(i, a)                                                  
\
-    !!(atomic_load_acq_long(&((volatile unsigned long *)(a))[BIT_WORD(i)]) &   
\
-    BIT_MASK(i))
+    !!(READ_ONCE(((volatile unsigned long *)(a))[BIT_WORD(i)]) & BIT_MASK(i))
 
 static inline int
 test_and_clear_bit(long bit, volatile unsigned long *var)

Modified: head/sys/compat/linuxkpi/common/src/linux_tasklet.c
==============================================================================
--- head/sys/compat/linuxkpi/common/src/linux_tasklet.c Mon Sep 18 13:23:59 
2017        (r323704)
+++ head/sys/compat/linuxkpi/common/src/linux_tasklet.c Mon Sep 18 13:37:14 
2017        (r323705)
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/proc.h>
 #include <sys/sched.h>
 
+#include <linux/compiler.h>
 #include <linux/interrupt.h>
 #include <linux/compat.h>
 
@@ -45,10 +46,10 @@ __FBSDID("$FreeBSD$");
        atomic_cmpset_ptr((volatile uintptr_t *)&(ts)->entry.tqe_prev, old, new)
 
 #define        TASKLET_ST_SET(ts, new) \
-       atomic_store_rel_ptr((volatile uintptr_t *)&(ts)->entry.tqe_prev, new)
+       WRITE_ONCE(*(volatile uintptr_t *)&(ts)->entry.tqe_prev, new)
 
 #define        TASKLET_ST_GET(ts) \
-       atomic_load_acq_ptr((volatile uintptr_t *)&(ts)->entry.tqe_prev)
+       READ_ONCE(*(volatile uintptr_t *)&(ts)->entry.tqe_prev)
 
 struct tasklet_worker {
        struct mtx mtx;
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to