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