[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH for-4.9 v3 2/3] x86/atomic: fix clang build



The current code in dm_op breaks clang build with:

dm.c:411:21: error: 'break' is bound to loop, GCC binds it to switch 
[-Werror,-Wgcc-compat]
            while ( read_atomic(&p2m->ioreq.entry_count) &&
                    ^
xen/include/asm/atomic.h:53:43: note: expanded from macro 'read_atomic'
    default: x_ = 0; __bad_atomic_size(); break;          \
                                          ^

Introduce a readatomic static inline helper function in order to solve this.

Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
Cc: Jan Beulich <jbeulich@xxxxxxxx>
Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
Changes since v2:
 - Introduce a readatomic static inline helper in order to prevent moving the
   read_atomic check.

Changes since v1:
 - New in this version.
---
 xen/include/asm-x86/atomic.h | 44 +++++++++++++++++++++++++++++++++-----------
 1 file changed, 33 insertions(+), 11 deletions(-)

diff --git a/xen/include/asm-x86/atomic.h b/xen/include/asm-x86/atomic.h
index 2fbe705518..ae87a0dcf5 100644
--- a/xen/include/asm-x86/atomic.h
+++ b/xen/include/asm-x86/atomic.h
@@ -41,20 +41,42 @@ build_add_sized(add_u64_sized, "q", uint64_t, "ri")
 #undef build_write_atomic
 #undef build_add_sized
 
-void __bad_atomic_size(void);
+/*
+ * NB: read_atomic needs to be a static inline function because clang doesn't
+ * like breaks inside of expressions, even when there's an inner switch where
+ * those breaks should apply, and complains with "'break' is bound to loop, GCC
+ * binds it to switch", so the following code:
+ *
+ * while ( read_atomic(&foo) ) { ... }
+ *
+ * Doesn't work if read_atomic is a macro with an inner switch.
+ */
+static inline unsigned long readatomic(const void *p, size_t s)
+{
+    switch ( s )
+    {
+    case 1:
+        return read_u8_atomic((uint8_t *)p);
+    case 2:
+        return read_u16_atomic((uint16_t *)p);
+    case 4:
+        return read_u32_atomic((uint32_t *)p);
+    case 8:
+        return read_u64_atomic((uint64_t *)p);
+    default:
+        ASSERT_UNREACHABLE();
+        return 0;
+    }
+}
 
-#define read_atomic(p) ({                                 \
-    unsigned long x_;                                     \
-    switch ( sizeof(*(p)) ) {                             \
-    case 1: x_ = read_u8_atomic((uint8_t *)(p)); break;   \
-    case 2: x_ = read_u16_atomic((uint16_t *)(p)); break; \
-    case 4: x_ = read_u32_atomic((uint32_t *)(p)); break; \
-    case 8: x_ = read_u64_atomic((uint64_t *)(p)); break; \
-    default: x_ = 0; __bad_atomic_size(); break;          \
-    }                                                     \
-    (typeof(*(p)))x_;                                     \
+#define read_atomic(p) ({                                  \
+    BUILD_BUG_ON(sizeof(*(p)) != 1 && sizeof(*(p)) != 2 && \
+                 sizeof(*(p)) != 4 && sizeof(*(p)) != 8);  \
+    (typeof(*(p)))readatomic(p, sizeof(*(p)));             \
 })
 
+void __bad_atomic_size(void);
+
 #define write_atomic(p, x) ({                             \
     typeof(*(p)) __x = (x);                               \
     unsigned long x_ = (unsigned long)__x;                \
-- 
2.11.0 (Apple Git-81)


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.