Commit 86a8938078a8bb518c5376de493e348c7490d506

Authored by Luca Barbieri
Committed by H. Peter Anvin
1 parent 9c76b38476

lib: Add self-test for atomic64_t

This patch adds self-test on boot code for atomic64_t.

This has been used to test the later changes in this patchset.

Signed-off-by: Luca Barbieri <luca@luca-barbieri.com>
LKML-Reference: <1267005265-27958-4-git-send-email-luca@luca-barbieri.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>

Showing 3 changed files with 167 additions and 0 deletions Side-by-side Diff

... ... @@ -1054,6 +1054,13 @@
1054 1054 This option causes a performance degredation. Use only if you want
1055 1055 to debug device drivers. If unsure, say N.
1056 1056  
  1057 +config ATOMIC64_SELFTEST
  1058 + bool "Perform an atomic64_t self-test at boot"
  1059 + help
  1060 + Enable this option to test the atomic64_t functions at boot.
  1061 +
  1062 + If unsure, say N.
  1063 +
1057 1064 source "samples/Kconfig"
1058 1065  
1059 1066 source "lib/Kconfig.kgdb"
... ... @@ -99,6 +99,8 @@
99 99  
100 100 obj-$(CONFIG_GENERIC_ATOMIC64) += atomic64.o
101 101  
  102 +obj-$(CONFIG_ATOMIC64_SELFTEST) += atomic64_test.o
  103 +
102 104 hostprogs-y := gen_crc32table
103 105 clean-files := crc32table.h
104 106  
  1 +/*
  2 + * Testsuite for atomic64_t functions
  3 + *
  4 + * Copyright © 2010 Luca Barbieri
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify
  7 + * it under the terms of the GNU General Public License as published by
  8 + * the Free Software Foundation; either version 2 of the License, or
  9 + * (at your option) any later version.
  10 + */
  11 +#include <linux/init.h>
  12 +#include <asm/atomic.h>
  13 +
  14 +#define INIT(c) do { atomic64_set(&v, c); r = c; } while (0)
  15 +static __init int test_atomic64(void)
  16 +{
  17 + long long v0 = 0xaaa31337c001d00dLL;
  18 + long long v1 = 0xdeadbeefdeafcafeLL;
  19 + long long v2 = 0xfaceabadf00df001LL;
  20 + long long onestwos = 0x1111111122222222LL;
  21 + long long one = 1LL;
  22 +
  23 + atomic64_t v = ATOMIC64_INIT(v0);
  24 + long long r = v0;
  25 + BUG_ON(v.counter != r);
  26 +
  27 + atomic64_set(&v, v1);
  28 + r = v1;
  29 + BUG_ON(v.counter != r);
  30 + BUG_ON(atomic64_read(&v) != r);
  31 +
  32 + INIT(v0);
  33 + atomic64_add(onestwos, &v);
  34 + r += onestwos;
  35 + BUG_ON(v.counter != r);
  36 +
  37 + INIT(v0);
  38 + atomic64_add(-one, &v);
  39 + r += -one;
  40 + BUG_ON(v.counter != r);
  41 +
  42 + INIT(v0);
  43 + r += onestwos;
  44 + BUG_ON(atomic64_add_return(onestwos, &v) != r);
  45 + BUG_ON(v.counter != r);
  46 +
  47 + INIT(v0);
  48 + r += -one;
  49 + BUG_ON(atomic64_add_return(-one, &v) != r);
  50 + BUG_ON(v.counter != r);
  51 +
  52 + INIT(v0);
  53 + atomic64_sub(onestwos, &v);
  54 + r -= onestwos;
  55 + BUG_ON(v.counter != r);
  56 +
  57 + INIT(v0);
  58 + atomic64_sub(-one, &v);
  59 + r -= -one;
  60 + BUG_ON(v.counter != r);
  61 +
  62 + INIT(v0);
  63 + r -= onestwos;
  64 + BUG_ON(atomic64_sub_return(onestwos, &v) != r);
  65 + BUG_ON(v.counter != r);
  66 +
  67 + INIT(v0);
  68 + r -= -one;
  69 + BUG_ON(atomic64_sub_return(-one, &v) != r);
  70 + BUG_ON(v.counter != r);
  71 +
  72 + INIT(v0);
  73 + atomic64_inc(&v);
  74 + r += one;
  75 + BUG_ON(v.counter != r);
  76 +
  77 + INIT(v0);
  78 + r += one;
  79 + BUG_ON(atomic64_inc_return(&v) != r);
  80 + BUG_ON(v.counter != r);
  81 +
  82 + INIT(v0);
  83 + atomic64_dec(&v);
  84 + r -= one;
  85 + BUG_ON(v.counter != r);
  86 +
  87 + INIT(v0);
  88 + r -= one;
  89 + BUG_ON(atomic64_dec_return(&v) != r);
  90 + BUG_ON(v.counter != r);
  91 +
  92 + INIT(v0);
  93 + BUG_ON(atomic64_xchg(&v, v1) != v0);
  94 + r = v1;
  95 + BUG_ON(v.counter != r);
  96 +
  97 + INIT(v0);
  98 + BUG_ON(atomic64_cmpxchg(&v, v0, v1) != v0);
  99 + r = v1;
  100 + BUG_ON(v.counter != r);
  101 +
  102 + INIT(v0);
  103 + BUG_ON(atomic64_cmpxchg(&v, v2, v1) != v0);
  104 + BUG_ON(v.counter != r);
  105 +
  106 + INIT(v0);
  107 + BUG_ON(!atomic64_add_unless(&v, one, v0));
  108 + BUG_ON(v.counter != r);
  109 +
  110 + INIT(v0);
  111 + BUG_ON(atomic64_add_unless(&v, one, v1));
  112 + r += one;
  113 + BUG_ON(v.counter != r);
  114 +
  115 + INIT(onestwos);
  116 + BUG_ON(atomic64_dec_if_positive(&v) != (onestwos - 1));
  117 + r -= one;
  118 + BUG_ON(v.counter != r);
  119 +
  120 + INIT(0);
  121 + BUG_ON(atomic64_dec_if_positive(&v) != -one);
  122 + BUG_ON(v.counter != r);
  123 +
  124 + INIT(-one);
  125 + BUG_ON(atomic64_dec_if_positive(&v) != (-one - one));
  126 + BUG_ON(v.counter != r);
  127 +
  128 + INIT(onestwos);
  129 + BUG_ON(atomic64_inc_not_zero(&v));
  130 + r += one;
  131 + BUG_ON(v.counter != r);
  132 +
  133 + INIT(0);
  134 + BUG_ON(!atomic64_inc_not_zero(&v));
  135 + BUG_ON(v.counter != r);
  136 +
  137 + INIT(-one);
  138 + BUG_ON(atomic64_inc_not_zero(&v));
  139 + r += one;
  140 + BUG_ON(v.counter != r);
  141 +
  142 +#ifdef CONFIG_X86
  143 + printk(KERN_INFO "atomic64 test passed for %s+ platform %s CX8 and %s SSE\n",
  144 +#ifdef CONFIG_X86_CMPXCHG64
  145 + "586",
  146 +#else
  147 + "386",
  148 +#endif
  149 + boot_cpu_has(X86_FEATURE_CX8) ? "with" : "without",
  150 + boot_cpu_has(X86_FEATURE_XMM) ? "with" : "without");
  151 +#else
  152 + printk(KERN_INFO "atomic64 test passed\n");
  153 +#endif
  154 +
  155 + return 0;
  156 +}
  157 +
  158 +core_initcall(test_atomic64);