2874c5fd28426 (Thomas Gleixner 2019-05-27 08:55:01 +0200 1) // SPDX-License-Identifier: GPL-2.0-or-later
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 2) /*
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 3) * Testsuite for atomic64_t functions
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 4) *
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 5) * Copyright © 2010 Luca Barbieri
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 6) */
b3b16d284a412 (Fabian Frederick 2014-06-04 16:12:00 -0700 7)
b3b16d284a412 (Fabian Frederick 2014-06-04 16:12:00 -0700 8) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
b3b16d284a412 (Fabian Frederick 2014-06-04 16:12:00 -0700 9)
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 10) #include <linux/init.h>
50af5ead3b44c (Paul Gortmaker 2012-01-20 18:35:53 -0500 11) #include <linux/bug.h>
0dbdd1bfe0b83 (Peter Huewe 2010-05-24 12:13:20 -0700 12) #include <linux/kernel.h>
60063497a95e7 (Arun Sharma 2011-07-26 16:09:06 -0700 13) #include <linux/atomic.h>
55ded9551f9a6 (Geert Uytterhoeven 2017-02-24 15:00:55 -0800 14) #include <linux/module.h>
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 15)
153a4334c439c (Andi Kleen 2015-12-01 17:00:57 -0800 16) #ifdef CONFIG_X86
cd4d09ec6f6c1 (Borislav Petkov 2016-01-26 22:12:04 +0100 17) #include <asm/cpufeature.h> /* for boot_cpu_has below */
153a4334c439c (Andi Kleen 2015-12-01 17:00:57 -0800 18) #endif
153a4334c439c (Andi Kleen 2015-12-01 17:00:57 -0800 19)
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 20) #define TEST(bit, op, c_op, val) \
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 21) do { \
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 22) atomic##bit##_set(&v, v0); \
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 23) r = v0; \
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 24) atomic##bit##_##op(val, &v); \
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 25) r c_op val; \
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 26) WARN(atomic##bit##_read(&v) != r, "%Lx != %Lx\n", \
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 27) (unsigned long long)atomic##bit##_read(&v), \
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 28) (unsigned long long)r); \
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 29) } while (0)
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 30)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 31) /*
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 32) * Test for a atomic operation family,
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 33) * @test should be a macro accepting parameters (bit, op, ...)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 34) */
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 35)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 36) #define FAMILY_TEST(test, bit, op, args...) \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 37) do { \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 38) test(bit, op, ##args); \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 39) test(bit, op##_acquire, ##args); \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 40) test(bit, op##_release, ##args); \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 41) test(bit, op##_relaxed, ##args); \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 42) } while (0)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 43)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 44) #define TEST_RETURN(bit, op, c_op, val) \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 45) do { \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 46) atomic##bit##_set(&v, v0); \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 47) r = v0; \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 48) r c_op val; \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 49) BUG_ON(atomic##bit##_##op(val, &v) != r); \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 50) BUG_ON(atomic##bit##_read(&v) != r); \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 51) } while (0)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 52)
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 53) #define TEST_FETCH(bit, op, c_op, val) \
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 54) do { \
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 55) atomic##bit##_set(&v, v0); \
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 56) r = v0; \
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 57) r c_op val; \
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 58) BUG_ON(atomic##bit##_##op(val, &v) != v0); \
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 59) BUG_ON(atomic##bit##_read(&v) != r); \
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 60) } while (0)
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 61)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 62) #define RETURN_FAMILY_TEST(bit, op, c_op, val) \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 63) do { \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 64) FAMILY_TEST(TEST_RETURN, bit, op, c_op, val); \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 65) } while (0)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 66)
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 67) #define FETCH_FAMILY_TEST(bit, op, c_op, val) \
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 68) do { \
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 69) FAMILY_TEST(TEST_FETCH, bit, op, c_op, val); \
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 70) } while (0)
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 71)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 72) #define TEST_ARGS(bit, op, init, ret, expect, args...) \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 73) do { \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 74) atomic##bit##_set(&v, init); \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 75) BUG_ON(atomic##bit##_##op(&v, ##args) != ret); \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 76) BUG_ON(atomic##bit##_read(&v) != expect); \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 77) } while (0)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 78)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 79) #define XCHG_FAMILY_TEST(bit, init, new) \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 80) do { \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 81) FAMILY_TEST(TEST_ARGS, bit, xchg, init, init, new, new); \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 82) } while (0)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 83)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 84) #define CMPXCHG_FAMILY_TEST(bit, init, new, wrong) \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 85) do { \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 86) FAMILY_TEST(TEST_ARGS, bit, cmpxchg, \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 87) init, init, new, init, new); \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 88) FAMILY_TEST(TEST_ARGS, bit, cmpxchg, \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 89) init, init, init, wrong, new); \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 90) } while (0)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 91)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 92) #define INC_RETURN_FAMILY_TEST(bit, i) \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 93) do { \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 94) FAMILY_TEST(TEST_ARGS, bit, inc_return, \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 95) i, (i) + one, (i) + one); \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 96) } while (0)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 97)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 98) #define DEC_RETURN_FAMILY_TEST(bit, i) \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 99) do { \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 100) FAMILY_TEST(TEST_ARGS, bit, dec_return, \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 101) i, (i) - one, (i) - one); \
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 102) } while (0)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 103)
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 104) static __init void test_atomic(void)
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 105) {
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 106) int v0 = 0xaaa31337;
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 107) int v1 = 0xdeadbeef;
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 108) int onestwos = 0x11112222;
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 109) int one = 1;
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 110)
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 111) atomic_t v;
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 112) int r;
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 113)
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 114) TEST(, add, +=, onestwos);
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 115) TEST(, add, +=, -one);
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 116) TEST(, sub, -=, onestwos);
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 117) TEST(, sub, -=, -one);
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 118) TEST(, or, |=, v1);
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 119) TEST(, and, &=, v1);
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 120) TEST(, xor, ^=, v1);
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 121) TEST(, andnot, &= ~, v1);
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 122)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 123) RETURN_FAMILY_TEST(, add_return, +=, onestwos);
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 124) RETURN_FAMILY_TEST(, add_return, +=, -one);
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 125) RETURN_FAMILY_TEST(, sub_return, -=, onestwos);
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 126) RETURN_FAMILY_TEST(, sub_return, -=, -one);
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 127)
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 128) FETCH_FAMILY_TEST(, fetch_add, +=, onestwos);
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 129) FETCH_FAMILY_TEST(, fetch_add, +=, -one);
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 130) FETCH_FAMILY_TEST(, fetch_sub, -=, onestwos);
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 131) FETCH_FAMILY_TEST(, fetch_sub, -=, -one);
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 132)
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 133) FETCH_FAMILY_TEST(, fetch_or, |=, v1);
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 134) FETCH_FAMILY_TEST(, fetch_and, &=, v1);
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 135) FETCH_FAMILY_TEST(, fetch_andnot, &= ~, v1);
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 136) FETCH_FAMILY_TEST(, fetch_xor, ^=, v1);
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 137)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 138) INC_RETURN_FAMILY_TEST(, v0);
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 139) DEC_RETURN_FAMILY_TEST(, v0);
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 140)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 141) XCHG_FAMILY_TEST(, v0, v1);
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 142) CMPXCHG_FAMILY_TEST(, v0, v1, onestwos);
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 143)
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 144) }
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 145)
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 146) #define INIT(c) do { atomic64_set(&v, c); r = c; } while (0)
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 147) static __init void test_atomic64(void)
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 148) {
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 149) long long v0 = 0xaaa31337c001d00dLL;
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 150) long long v1 = 0xdeadbeefdeafcafeLL;
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 151) long long v2 = 0xfaceabadf00df001LL;
ffba19ccae8d9 (Michael Ellerman 2017-07-14 14:49:41 -0700 152) long long v3 = 0x8000000000000000LL;
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 153) long long onestwos = 0x1111111122222222LL;
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 154) long long one = 1LL;
ffba19ccae8d9 (Michael Ellerman 2017-07-14 14:49:41 -0700 155) int r_int;
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 156)
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 157) atomic64_t v = ATOMIC64_INIT(v0);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 158) long long r = v0;
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 159) BUG_ON(v.counter != r);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 160)
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 161) atomic64_set(&v, v1);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 162) r = v1;
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 163) BUG_ON(v.counter != r);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 164) BUG_ON(atomic64_read(&v) != r);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 165)
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 166) TEST(64, add, +=, onestwos);
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 167) TEST(64, add, +=, -one);
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 168) TEST(64, sub, -=, onestwos);
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 169) TEST(64, sub, -=, -one);
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 170) TEST(64, or, |=, v1);
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 171) TEST(64, and, &=, v1);
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 172) TEST(64, xor, ^=, v1);
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 173) TEST(64, andnot, &= ~, v1);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 174)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 175) RETURN_FAMILY_TEST(64, add_return, +=, onestwos);
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 176) RETURN_FAMILY_TEST(64, add_return, +=, -one);
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 177) RETURN_FAMILY_TEST(64, sub_return, -=, onestwos);
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 178) RETURN_FAMILY_TEST(64, sub_return, -=, -one);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 179)
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 180) FETCH_FAMILY_TEST(64, fetch_add, +=, onestwos);
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 181) FETCH_FAMILY_TEST(64, fetch_add, +=, -one);
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 182) FETCH_FAMILY_TEST(64, fetch_sub, -=, onestwos);
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 183) FETCH_FAMILY_TEST(64, fetch_sub, -=, -one);
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 184)
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 185) FETCH_FAMILY_TEST(64, fetch_or, |=, v1);
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 186) FETCH_FAMILY_TEST(64, fetch_and, &=, v1);
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 187) FETCH_FAMILY_TEST(64, fetch_andnot, &= ~, v1);
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 188) FETCH_FAMILY_TEST(64, fetch_xor, ^=, v1);
28aa2bda2211f (Peter Zijlstra 2016-04-18 00:54:38 +0200 189)
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 190) INIT(v0);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 191) atomic64_inc(&v);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 192) r += one;
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 193) BUG_ON(v.counter != r);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 194)
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 195) INIT(v0);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 196) atomic64_dec(&v);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 197) r -= one;
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 198) BUG_ON(v.counter != r);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 199)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 200) INC_RETURN_FAMILY_TEST(64, v0);
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 201) DEC_RETURN_FAMILY_TEST(64, v0);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 202)
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 203) XCHG_FAMILY_TEST(64, v0, v1);
978e5a3692c3b (Boqun Feng 2015-11-04 18:52:45 +0800 204) CMPXCHG_FAMILY_TEST(64, v0, v1, v2);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 205)
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 206) INIT(v0);
9efbcd5902430 (Luca Barbieri 2010-03-01 19:55:45 +0100 207) BUG_ON(atomic64_add_unless(&v, one, v0));
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 208) BUG_ON(v.counter != r);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 209)
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 210) INIT(v0);
9efbcd5902430 (Luca Barbieri 2010-03-01 19:55:45 +0100 211) BUG_ON(!atomic64_add_unless(&v, one, v1));
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 212) r += one;
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 213) BUG_ON(v.counter != r);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 214)
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 215) INIT(onestwos);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 216) BUG_ON(atomic64_dec_if_positive(&v) != (onestwos - 1));
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 217) r -= one;
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 218) BUG_ON(v.counter != r);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 219)
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 220) INIT(0);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 221) BUG_ON(atomic64_dec_if_positive(&v) != -one);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 222) BUG_ON(v.counter != r);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 223)
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 224) INIT(-one);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 225) BUG_ON(atomic64_dec_if_positive(&v) != (-one - one));
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 226) BUG_ON(v.counter != r);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 227)
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 228) INIT(onestwos);
25a304f277ad7 (Luca Barbieri 2010-03-01 19:55:48 +0100 229) BUG_ON(!atomic64_inc_not_zero(&v));
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 230) r += one;
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 231) BUG_ON(v.counter != r);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 232)
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 233) INIT(0);
25a304f277ad7 (Luca Barbieri 2010-03-01 19:55:48 +0100 234) BUG_ON(atomic64_inc_not_zero(&v));
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 235) BUG_ON(v.counter != r);
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 236)
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 237) INIT(-one);
25a304f277ad7 (Luca Barbieri 2010-03-01 19:55:48 +0100 238) BUG_ON(!atomic64_inc_not_zero(&v));
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 239) r += one;
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 240) BUG_ON(v.counter != r);
ffba19ccae8d9 (Michael Ellerman 2017-07-14 14:49:41 -0700 241)
ffba19ccae8d9 (Michael Ellerman 2017-07-14 14:49:41 -0700 242) /* Confirm the return value fits in an int, even if the value doesn't */
ffba19ccae8d9 (Michael Ellerman 2017-07-14 14:49:41 -0700 243) INIT(v3);
ffba19ccae8d9 (Michael Ellerman 2017-07-14 14:49:41 -0700 244) r_int = atomic64_inc_not_zero(&v);
ffba19ccae8d9 (Michael Ellerman 2017-07-14 14:49:41 -0700 245) BUG_ON(!r_int);
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 246) }
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 247)
55ded9551f9a6 (Geert Uytterhoeven 2017-02-24 15:00:55 -0800 248) static __init int test_atomics_init(void)
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 249) {
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 250) test_atomic();
41b9e9fcc1c44 (Peter Zijlstra 2015-07-13 12:55:58 +0200 251) test_atomic64();
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 252)
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 253) #ifdef CONFIG_X86
b3b16d284a412 (Fabian Frederick 2014-06-04 16:12:00 -0700 254) pr_info("passed for %s platform %s CX8 and %s SSE\n",
a5c9161f27c3e (H. Peter Anvin 2010-03-01 11:49:23 -0800 255) #ifdef CONFIG_X86_64
b3b16d284a412 (Fabian Frederick 2014-06-04 16:12:00 -0700 256) "x86-64",
a5c9161f27c3e (H. Peter Anvin 2010-03-01 11:49:23 -0800 257) #elif defined(CONFIG_X86_CMPXCHG64)
b3b16d284a412 (Fabian Frederick 2014-06-04 16:12:00 -0700 258) "i586+",
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 259) #else
b3b16d284a412 (Fabian Frederick 2014-06-04 16:12:00 -0700 260) "i386+",
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 261) #endif
a5c9161f27c3e (H. Peter Anvin 2010-03-01 11:49:23 -0800 262) boot_cpu_has(X86_FEATURE_CX8) ? "with" : "without",
a5c9161f27c3e (H. Peter Anvin 2010-03-01 11:49:23 -0800 263) boot_cpu_has(X86_FEATURE_XMM) ? "with" : "without");
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 264) #else
b3b16d284a412 (Fabian Frederick 2014-06-04 16:12:00 -0700 265) pr_info("passed\n");
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 266) #endif
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 267)
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 268) return 0;
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 269) }
86a8938078a8b (Luca Barbieri 2010-02-24 10:54:24 +0100 270)
55ded9551f9a6 (Geert Uytterhoeven 2017-02-24 15:00:55 -0800 271) static __exit void test_atomics_exit(void) {}
55ded9551f9a6 (Geert Uytterhoeven 2017-02-24 15:00:55 -0800 272)
55ded9551f9a6 (Geert Uytterhoeven 2017-02-24 15:00:55 -0800 273) module_init(test_atomics_init);
55ded9551f9a6 (Geert Uytterhoeven 2017-02-24 15:00:55 -0800 274) module_exit(test_atomics_exit);
55ded9551f9a6 (Geert Uytterhoeven 2017-02-24 15:00:55 -0800 275)
55ded9551f9a6 (Geert Uytterhoeven 2017-02-24 15:00:55 -0800 276) MODULE_LICENSE("GPL");