test_xarray.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * test_xarray.c: Test the XArray API
  4. * Copyright (c) 2017-2018 Microsoft Corporation
  5. * Author: Matthew Wilcox <willy@infradead.org>
  6. */
  7. #include <linux/xarray.h>
  8. #include <linux/module.h>
  9. static unsigned int tests_run;
  10. static unsigned int tests_passed;
  11. #ifndef XA_DEBUG
  12. # ifdef __KERNEL__
  13. void xa_dump(const struct xarray *xa) { }
  14. # endif
  15. #undef XA_BUG_ON
  16. #define XA_BUG_ON(xa, x) do { \
  17. tests_run++; \
  18. if (x) { \
  19. printk("BUG at %s:%d\n", __func__, __LINE__); \
  20. xa_dump(xa); \
  21. dump_stack(); \
  22. } else { \
  23. tests_passed++; \
  24. } \
  25. } while (0)
  26. #endif
  27. static void *xa_store_index(struct xarray *xa, unsigned long index, gfp_t gfp)
  28. {
  29. return xa_store(xa, index, xa_mk_value(index & LONG_MAX), gfp);
  30. }
  31. static void xa_erase_index(struct xarray *xa, unsigned long index)
  32. {
  33. XA_BUG_ON(xa, xa_erase(xa, index) != xa_mk_value(index & LONG_MAX));
  34. XA_BUG_ON(xa, xa_load(xa, index) != NULL);
  35. }
  36. /*
  37. * If anyone needs this, please move it to xarray.c. We have no current
  38. * users outside the test suite because all current multislot users want
  39. * to use the advanced API.
  40. */
  41. static void *xa_store_order(struct xarray *xa, unsigned long index,
  42. unsigned order, void *entry, gfp_t gfp)
  43. {
  44. XA_STATE_ORDER(xas, xa, index, order);
  45. void *curr;
  46. do {
  47. xas_lock(&xas);
  48. curr = xas_store(&xas, entry);
  49. xas_unlock(&xas);
  50. } while (xas_nomem(&xas, gfp));
  51. return curr;
  52. }
  53. static noinline void check_xa_err(struct xarray *xa)
  54. {
  55. XA_BUG_ON(xa, xa_err(xa_store_index(xa, 0, GFP_NOWAIT)) != 0);
  56. XA_BUG_ON(xa, xa_err(xa_erase(xa, 0)) != 0);
  57. #ifndef __KERNEL__
  58. /* The kernel does not fail GFP_NOWAIT allocations */
  59. XA_BUG_ON(xa, xa_err(xa_store_index(xa, 1, GFP_NOWAIT)) != -ENOMEM);
  60. XA_BUG_ON(xa, xa_err(xa_store_index(xa, 1, GFP_NOWAIT)) != -ENOMEM);
  61. #endif
  62. XA_BUG_ON(xa, xa_err(xa_store_index(xa, 1, GFP_KERNEL)) != 0);
  63. XA_BUG_ON(xa, xa_err(xa_store(xa, 1, xa_mk_value(0), GFP_KERNEL)) != 0);
  64. XA_BUG_ON(xa, xa_err(xa_erase(xa, 1)) != 0);
  65. // kills the test-suite :-(
  66. // XA_BUG_ON(xa, xa_err(xa_store(xa, 0, xa_mk_internal(0), 0)) != -EINVAL);
  67. }
  68. static noinline void check_xas_retry(struct xarray *xa)
  69. {
  70. XA_STATE(xas, xa, 0);
  71. void *entry;
  72. xa_store_index(xa, 0, GFP_KERNEL);
  73. xa_store_index(xa, 1, GFP_KERNEL);
  74. rcu_read_lock();
  75. XA_BUG_ON(xa, xas_find(&xas, ULONG_MAX) != xa_mk_value(0));
  76. xa_erase_index(xa, 1);
  77. XA_BUG_ON(xa, !xa_is_retry(xas_reload(&xas)));
  78. XA_BUG_ON(xa, xas_retry(&xas, NULL));
  79. XA_BUG_ON(xa, xas_retry(&xas, xa_mk_value(0)));
  80. xas_reset(&xas);
  81. XA_BUG_ON(xa, xas.xa_node != XAS_RESTART);
  82. XA_BUG_ON(xa, xas_next_entry(&xas, ULONG_MAX) != xa_mk_value(0));
  83. XA_BUG_ON(xa, xas.xa_node != NULL);
  84. XA_BUG_ON(xa, xa_store_index(xa, 1, GFP_KERNEL) != NULL);
  85. XA_BUG_ON(xa, !xa_is_internal(xas_reload(&xas)));
  86. xas.xa_node = XAS_RESTART;
  87. XA_BUG_ON(xa, xas_next_entry(&xas, ULONG_MAX) != xa_mk_value(0));
  88. rcu_read_unlock();
  89. /* Make sure we can iterate through retry entries */
  90. xas_lock(&xas);
  91. xas_set(&xas, 0);
  92. xas_store(&xas, XA_RETRY_ENTRY);
  93. xas_set(&xas, 1);
  94. xas_store(&xas, XA_RETRY_ENTRY);
  95. xas_set(&xas, 0);
  96. xas_for_each(&xas, entry, ULONG_MAX) {
  97. xas_store(&xas, xa_mk_value(xas.xa_index));
  98. }
  99. xas_unlock(&xas);
  100. xa_erase_index(xa, 0);
  101. xa_erase_index(xa, 1);
  102. }
  103. static noinline void check_xa_load(struct xarray *xa)
  104. {
  105. unsigned long i, j;
  106. for (i = 0; i < 1024; i++) {
  107. for (j = 0; j < 1024; j++) {
  108. void *entry = xa_load(xa, j);
  109. if (j < i)
  110. XA_BUG_ON(xa, xa_to_value(entry) != j);
  111. else
  112. XA_BUG_ON(xa, entry);
  113. }
  114. XA_BUG_ON(xa, xa_store_index(xa, i, GFP_KERNEL) != NULL);
  115. }
  116. for (i = 0; i < 1024; i++) {
  117. for (j = 0; j < 1024; j++) {
  118. void *entry = xa_load(xa, j);
  119. if (j >= i)
  120. XA_BUG_ON(xa, xa_to_value(entry) != j);
  121. else
  122. XA_BUG_ON(xa, entry);
  123. }
  124. xa_erase_index(xa, i);
  125. }
  126. XA_BUG_ON(xa, !xa_empty(xa));
  127. }
  128. static noinline void check_xa_mark_1(struct xarray *xa, unsigned long index)
  129. {
  130. unsigned int order;
  131. unsigned int max_order = IS_ENABLED(CONFIG_XARRAY_MULTI) ? 8 : 1;
  132. /* NULL elements have no marks set */
  133. XA_BUG_ON(xa, xa_get_mark(xa, index, XA_MARK_0));
  134. xa_set_mark(xa, index, XA_MARK_0);
  135. XA_BUG_ON(xa, xa_get_mark(xa, index, XA_MARK_0));
  136. /* Storing a pointer will not make a mark appear */
  137. XA_BUG_ON(xa, xa_store_index(xa, index, GFP_KERNEL) != NULL);
  138. XA_BUG_ON(xa, xa_get_mark(xa, index, XA_MARK_0));
  139. xa_set_mark(xa, index, XA_MARK_0);
  140. XA_BUG_ON(xa, !xa_get_mark(xa, index, XA_MARK_0));
  141. /* Setting one mark will not set another mark */
  142. XA_BUG_ON(xa, xa_get_mark(xa, index + 1, XA_MARK_0));
  143. XA_BUG_ON(xa, xa_get_mark(xa, index, XA_MARK_1));
  144. /* Storing NULL clears marks, and they can't be set again */
  145. xa_erase_index(xa, index);
  146. XA_BUG_ON(xa, !xa_empty(xa));
  147. XA_BUG_ON(xa, xa_get_mark(xa, index, XA_MARK_0));
  148. xa_set_mark(xa, index, XA_MARK_0);
  149. XA_BUG_ON(xa, xa_get_mark(xa, index, XA_MARK_0));
  150. /*
  151. * Storing a multi-index entry over entries with marks gives the
  152. * entire entry the union of the marks
  153. */
  154. BUG_ON((index % 4) != 0);
  155. for (order = 2; order < max_order; order++) {
  156. unsigned long base = round_down(index, 1UL << order);
  157. unsigned long next = base + (1UL << order);
  158. unsigned long i;
  159. XA_BUG_ON(xa, xa_store_index(xa, index + 1, GFP_KERNEL));
  160. xa_set_mark(xa, index + 1, XA_MARK_0);
  161. XA_BUG_ON(xa, xa_store_index(xa, index + 2, GFP_KERNEL));
  162. xa_set_mark(xa, index + 2, XA_MARK_1);
  163. XA_BUG_ON(xa, xa_store_index(xa, next, GFP_KERNEL));
  164. xa_store_order(xa, index, order, xa_mk_value(index),
  165. GFP_KERNEL);
  166. for (i = base; i < next; i++) {
  167. XA_BUG_ON(xa, !xa_get_mark(xa, i, XA_MARK_0));
  168. XA_BUG_ON(xa, !xa_get_mark(xa, i, XA_MARK_1));
  169. XA_BUG_ON(xa, xa_get_mark(xa, i, XA_MARK_2));
  170. }
  171. XA_BUG_ON(xa, xa_get_mark(xa, next, XA_MARK_0));
  172. XA_BUG_ON(xa, xa_get_mark(xa, next, XA_MARK_1));
  173. XA_BUG_ON(xa, xa_get_mark(xa, next, XA_MARK_2));
  174. xa_erase_index(xa, index);
  175. xa_erase_index(xa, next);
  176. XA_BUG_ON(xa, !xa_empty(xa));
  177. }
  178. XA_BUG_ON(xa, !xa_empty(xa));
  179. }
  180. static noinline void check_xa_mark(struct xarray *xa)
  181. {
  182. unsigned long index;
  183. for (index = 0; index < 16384; index += 4)
  184. check_xa_mark_1(xa, index);
  185. }
  186. static noinline void check_xa_shrink(struct xarray *xa)
  187. {
  188. XA_STATE(xas, xa, 1);
  189. struct xa_node *node;
  190. XA_BUG_ON(xa, !xa_empty(xa));
  191. XA_BUG_ON(xa, xa_store_index(xa, 0, GFP_KERNEL) != NULL);
  192. XA_BUG_ON(xa, xa_store_index(xa, 1, GFP_KERNEL) != NULL);
  193. /*
  194. * Check that erasing the entry at 1 shrinks the tree and properly
  195. * marks the node as being deleted.
  196. */
  197. xas_lock(&xas);
  198. XA_BUG_ON(xa, xas_load(&xas) != xa_mk_value(1));
  199. node = xas.xa_node;
  200. XA_BUG_ON(xa, xa_entry_locked(xa, node, 0) != xa_mk_value(0));
  201. XA_BUG_ON(xa, xas_store(&xas, NULL) != xa_mk_value(1));
  202. XA_BUG_ON(xa, xa_load(xa, 1) != NULL);
  203. XA_BUG_ON(xa, xas.xa_node != XAS_BOUNDS);
  204. XA_BUG_ON(xa, xa_entry_locked(xa, node, 0) != XA_RETRY_ENTRY);
  205. XA_BUG_ON(xa, xas_load(&xas) != NULL);
  206. xas_unlock(&xas);
  207. XA_BUG_ON(xa, xa_load(xa, 0) != xa_mk_value(0));
  208. xa_erase_index(xa, 0);
  209. XA_BUG_ON(xa, !xa_empty(xa));
  210. }
  211. static noinline void check_cmpxchg(struct xarray *xa)
  212. {
  213. void *FIVE = xa_mk_value(5);
  214. void *SIX = xa_mk_value(6);
  215. void *LOTS = xa_mk_value(12345678);
  216. XA_BUG_ON(xa, !xa_empty(xa));
  217. XA_BUG_ON(xa, xa_store_index(xa, 12345678, GFP_KERNEL) != NULL);
  218. XA_BUG_ON(xa, xa_insert(xa, 12345678, xa, GFP_KERNEL) != -EEXIST);
  219. XA_BUG_ON(xa, xa_cmpxchg(xa, 12345678, SIX, FIVE, GFP_KERNEL) != LOTS);
  220. XA_BUG_ON(xa, xa_cmpxchg(xa, 12345678, LOTS, FIVE, GFP_KERNEL) != LOTS);
  221. XA_BUG_ON(xa, xa_cmpxchg(xa, 12345678, FIVE, LOTS, GFP_KERNEL) != FIVE);
  222. XA_BUG_ON(xa, xa_cmpxchg(xa, 5, FIVE, NULL, GFP_KERNEL) != NULL);
  223. XA_BUG_ON(xa, xa_cmpxchg(xa, 5, NULL, FIVE, GFP_KERNEL) != NULL);
  224. xa_erase_index(xa, 12345678);
  225. xa_erase_index(xa, 5);
  226. XA_BUG_ON(xa, !xa_empty(xa));
  227. }
  228. static noinline void check_reserve(struct xarray *xa)
  229. {
  230. void *entry;
  231. unsigned long index = 0;
  232. /* An array with a reserved entry is not empty */
  233. XA_BUG_ON(xa, !xa_empty(xa));
  234. xa_reserve(xa, 12345678, GFP_KERNEL);
  235. XA_BUG_ON(xa, xa_empty(xa));
  236. XA_BUG_ON(xa, xa_load(xa, 12345678));
  237. xa_release(xa, 12345678);
  238. XA_BUG_ON(xa, !xa_empty(xa));
  239. /* Releasing a used entry does nothing */
  240. xa_reserve(xa, 12345678, GFP_KERNEL);
  241. XA_BUG_ON(xa, xa_store_index(xa, 12345678, GFP_NOWAIT) != NULL);
  242. xa_release(xa, 12345678);
  243. xa_erase_index(xa, 12345678);
  244. XA_BUG_ON(xa, !xa_empty(xa));
  245. /* cmpxchg sees a reserved entry as NULL */
  246. xa_reserve(xa, 12345678, GFP_KERNEL);
  247. XA_BUG_ON(xa, xa_cmpxchg(xa, 12345678, NULL, xa_mk_value(12345678),
  248. GFP_NOWAIT) != NULL);
  249. xa_release(xa, 12345678);
  250. xa_erase_index(xa, 12345678);
  251. XA_BUG_ON(xa, !xa_empty(xa));
  252. /* Can iterate through a reserved entry */
  253. xa_store_index(xa, 5, GFP_KERNEL);
  254. xa_reserve(xa, 6, GFP_KERNEL);
  255. xa_store_index(xa, 7, GFP_KERNEL);
  256. xa_for_each(xa, entry, index, ULONG_MAX, XA_PRESENT) {
  257. XA_BUG_ON(xa, index != 5 && index != 7);
  258. }
  259. xa_destroy(xa);
  260. }
  261. static noinline void check_xas_erase(struct xarray *xa)
  262. {
  263. XA_STATE(xas, xa, 0);
  264. void *entry;
  265. unsigned long i, j;
  266. for (i = 0; i < 200; i++) {
  267. for (j = i; j < 2 * i + 17; j++) {
  268. xas_set(&xas, j);
  269. do {
  270. xas_lock(&xas);
  271. xas_store(&xas, xa_mk_value(j));
  272. xas_unlock(&xas);
  273. } while (xas_nomem(&xas, GFP_KERNEL));
  274. }
  275. xas_set(&xas, ULONG_MAX);
  276. do {
  277. xas_lock(&xas);
  278. xas_store(&xas, xa_mk_value(0));
  279. xas_unlock(&xas);
  280. } while (xas_nomem(&xas, GFP_KERNEL));
  281. xas_lock(&xas);
  282. xas_store(&xas, NULL);
  283. xas_set(&xas, 0);
  284. j = i;
  285. xas_for_each(&xas, entry, ULONG_MAX) {
  286. XA_BUG_ON(xa, entry != xa_mk_value(j));
  287. xas_store(&xas, NULL);
  288. j++;
  289. }
  290. xas_unlock(&xas);
  291. XA_BUG_ON(xa, !xa_empty(xa));
  292. }
  293. }
  294. static noinline void check_multi_store(struct xarray *xa)
  295. {
  296. #ifdef CONFIG_XARRAY_MULTI
  297. unsigned long i, j, k;
  298. unsigned int max_order = (sizeof(long) == 4) ? 30 : 60;
  299. /* Loading from any position returns the same value */
  300. xa_store_order(xa, 0, 1, xa_mk_value(0), GFP_KERNEL);
  301. XA_BUG_ON(xa, xa_load(xa, 0) != xa_mk_value(0));
  302. XA_BUG_ON(xa, xa_load(xa, 1) != xa_mk_value(0));
  303. XA_BUG_ON(xa, xa_load(xa, 2) != NULL);
  304. rcu_read_lock();
  305. XA_BUG_ON(xa, xa_to_node(xa_head(xa))->count != 2);
  306. XA_BUG_ON(xa, xa_to_node(xa_head(xa))->nr_values != 2);
  307. rcu_read_unlock();
  308. /* Storing adjacent to the value does not alter the value */
  309. xa_store(xa, 3, xa, GFP_KERNEL);
  310. XA_BUG_ON(xa, xa_load(xa, 0) != xa_mk_value(0));
  311. XA_BUG_ON(xa, xa_load(xa, 1) != xa_mk_value(0));
  312. XA_BUG_ON(xa, xa_load(xa, 2) != NULL);
  313. rcu_read_lock();
  314. XA_BUG_ON(xa, xa_to_node(xa_head(xa))->count != 3);
  315. XA_BUG_ON(xa, xa_to_node(xa_head(xa))->nr_values != 2);
  316. rcu_read_unlock();
  317. /* Overwriting multiple indexes works */
  318. xa_store_order(xa, 0, 2, xa_mk_value(1), GFP_KERNEL);
  319. XA_BUG_ON(xa, xa_load(xa, 0) != xa_mk_value(1));
  320. XA_BUG_ON(xa, xa_load(xa, 1) != xa_mk_value(1));
  321. XA_BUG_ON(xa, xa_load(xa, 2) != xa_mk_value(1));
  322. XA_BUG_ON(xa, xa_load(xa, 3) != xa_mk_value(1));
  323. XA_BUG_ON(xa, xa_load(xa, 4) != NULL);
  324. rcu_read_lock();
  325. XA_BUG_ON(xa, xa_to_node(xa_head(xa))->count != 4);
  326. XA_BUG_ON(xa, xa_to_node(xa_head(xa))->nr_values != 4);
  327. rcu_read_unlock();
  328. /* We can erase multiple values with a single store */
  329. xa_store_order(xa, 0, 63, NULL, GFP_KERNEL);
  330. XA_BUG_ON(xa, !xa_empty(xa));
  331. /* Even when the first slot is empty but the others aren't */
  332. xa_store_index(xa, 1, GFP_KERNEL);
  333. xa_store_index(xa, 2, GFP_KERNEL);
  334. xa_store_order(xa, 0, 2, NULL, GFP_KERNEL);
  335. XA_BUG_ON(xa, !xa_empty(xa));
  336. for (i = 0; i < max_order; i++) {
  337. for (j = 0; j < max_order; j++) {
  338. xa_store_order(xa, 0, i, xa_mk_value(i), GFP_KERNEL);
  339. xa_store_order(xa, 0, j, xa_mk_value(j), GFP_KERNEL);
  340. for (k = 0; k < max_order; k++) {
  341. void *entry = xa_load(xa, (1UL << k) - 1);
  342. if ((i < k) && (j < k))
  343. XA_BUG_ON(xa, entry != NULL);
  344. else
  345. XA_BUG_ON(xa, entry != xa_mk_value(j));
  346. }
  347. xa_erase(xa, 0);
  348. XA_BUG_ON(xa, !xa_empty(xa));
  349. }
  350. }
  351. #endif
  352. }
  353. static noinline void __check_store_iter(struct xarray *xa, unsigned long start,
  354. unsigned int order, unsigned int present)
  355. {
  356. XA_STATE_ORDER(xas, xa, start, order);
  357. void *entry;
  358. unsigned int count = 0;
  359. retry:
  360. xas_lock(&xas);
  361. xas_for_each_conflict(&xas, entry) {
  362. XA_BUG_ON(xa, !xa_is_value(entry));
  363. XA_BUG_ON(xa, entry < xa_mk_value(start));
  364. XA_BUG_ON(xa, entry > xa_mk_value(start + (1UL << order) - 1));
  365. count++;
  366. }
  367. xas_store(&xas, xa_mk_value(start));
  368. xas_unlock(&xas);
  369. if (xas_nomem(&xas, GFP_KERNEL)) {
  370. count = 0;
  371. goto retry;
  372. }
  373. XA_BUG_ON(xa, xas_error(&xas));
  374. XA_BUG_ON(xa, count != present);
  375. XA_BUG_ON(xa, xa_load(xa, start) != xa_mk_value(start));
  376. XA_BUG_ON(xa, xa_load(xa, start + (1UL << order) - 1) !=
  377. xa_mk_value(start));
  378. xa_erase_index(xa, start);
  379. }
  380. static noinline void check_store_iter(struct xarray *xa)
  381. {
  382. unsigned int i, j;
  383. unsigned int max_order = IS_ENABLED(CONFIG_XARRAY_MULTI) ? 20 : 1;
  384. for (i = 0; i < max_order; i++) {
  385. unsigned int min = 1 << i;
  386. unsigned int max = (2 << i) - 1;
  387. __check_store_iter(xa, 0, i, 0);
  388. XA_BUG_ON(xa, !xa_empty(xa));
  389. __check_store_iter(xa, min, i, 0);
  390. XA_BUG_ON(xa, !xa_empty(xa));
  391. xa_store_index(xa, min, GFP_KERNEL);
  392. __check_store_iter(xa, min, i, 1);
  393. XA_BUG_ON(xa, !xa_empty(xa));
  394. xa_store_index(xa, max, GFP_KERNEL);
  395. __check_store_iter(xa, min, i, 1);
  396. XA_BUG_ON(xa, !xa_empty(xa));
  397. for (j = 0; j < min; j++)
  398. xa_store_index(xa, j, GFP_KERNEL);
  399. __check_store_iter(xa, 0, i, min);
  400. XA_BUG_ON(xa, !xa_empty(xa));
  401. for (j = 0; j < min; j++)
  402. xa_store_index(xa, min + j, GFP_KERNEL);
  403. __check_store_iter(xa, min, i, min);
  404. XA_BUG_ON(xa, !xa_empty(xa));
  405. }
  406. #ifdef CONFIG_XARRAY_MULTI
  407. xa_store_index(xa, 63, GFP_KERNEL);
  408. xa_store_index(xa, 65, GFP_KERNEL);
  409. __check_store_iter(xa, 64, 2, 1);
  410. xa_erase_index(xa, 63);
  411. #endif
  412. XA_BUG_ON(xa, !xa_empty(xa));
  413. }
  414. static noinline void check_multi_find(struct xarray *xa)
  415. {
  416. #ifdef CONFIG_XARRAY_MULTI
  417. unsigned long index;
  418. xa_store_order(xa, 12, 2, xa_mk_value(12), GFP_KERNEL);
  419. XA_BUG_ON(xa, xa_store_index(xa, 16, GFP_KERNEL) != NULL);
  420. index = 0;
  421. XA_BUG_ON(xa, xa_find(xa, &index, ULONG_MAX, XA_PRESENT) !=
  422. xa_mk_value(12));
  423. XA_BUG_ON(xa, index != 12);
  424. index = 13;
  425. XA_BUG_ON(xa, xa_find(xa, &index, ULONG_MAX, XA_PRESENT) !=
  426. xa_mk_value(12));
  427. XA_BUG_ON(xa, (index < 12) || (index >= 16));
  428. XA_BUG_ON(xa, xa_find_after(xa, &index, ULONG_MAX, XA_PRESENT) !=
  429. xa_mk_value(16));
  430. XA_BUG_ON(xa, index != 16);
  431. xa_erase_index(xa, 12);
  432. xa_erase_index(xa, 16);
  433. XA_BUG_ON(xa, !xa_empty(xa));
  434. #endif
  435. }
  436. static noinline void check_multi_find_2(struct xarray *xa)
  437. {
  438. unsigned int max_order = IS_ENABLED(CONFIG_XARRAY_MULTI) ? 10 : 1;
  439. unsigned int i, j;
  440. void *entry;
  441. for (i = 0; i < max_order; i++) {
  442. unsigned long index = 1UL << i;
  443. for (j = 0; j < index; j++) {
  444. XA_STATE(xas, xa, j + index);
  445. xa_store_index(xa, index - 1, GFP_KERNEL);
  446. xa_store_order(xa, index, i, xa_mk_value(index),
  447. GFP_KERNEL);
  448. rcu_read_lock();
  449. xas_for_each(&xas, entry, ULONG_MAX) {
  450. xa_erase_index(xa, index);
  451. }
  452. rcu_read_unlock();
  453. xa_erase_index(xa, index - 1);
  454. XA_BUG_ON(xa, !xa_empty(xa));
  455. }
  456. }
  457. }
  458. static noinline void check_find(struct xarray *xa)
  459. {
  460. unsigned long i, j, k;
  461. XA_BUG_ON(xa, !xa_empty(xa));
  462. /*
  463. * Check xa_find with all pairs between 0 and 99 inclusive,
  464. * starting at every index between 0 and 99
  465. */
  466. for (i = 0; i < 100; i++) {
  467. XA_BUG_ON(xa, xa_store_index(xa, i, GFP_KERNEL) != NULL);
  468. xa_set_mark(xa, i, XA_MARK_0);
  469. for (j = 0; j < i; j++) {
  470. XA_BUG_ON(xa, xa_store_index(xa, j, GFP_KERNEL) !=
  471. NULL);
  472. xa_set_mark(xa, j, XA_MARK_0);
  473. for (k = 0; k < 100; k++) {
  474. unsigned long index = k;
  475. void *entry = xa_find(xa, &index, ULONG_MAX,
  476. XA_PRESENT);
  477. if (k <= j)
  478. XA_BUG_ON(xa, index != j);
  479. else if (k <= i)
  480. XA_BUG_ON(xa, index != i);
  481. else
  482. XA_BUG_ON(xa, entry != NULL);
  483. index = k;
  484. entry = xa_find(xa, &index, ULONG_MAX,
  485. XA_MARK_0);
  486. if (k <= j)
  487. XA_BUG_ON(xa, index != j);
  488. else if (k <= i)
  489. XA_BUG_ON(xa, index != i);
  490. else
  491. XA_BUG_ON(xa, entry != NULL);
  492. }
  493. xa_erase_index(xa, j);
  494. XA_BUG_ON(xa, xa_get_mark(xa, j, XA_MARK_0));
  495. XA_BUG_ON(xa, !xa_get_mark(xa, i, XA_MARK_0));
  496. }
  497. xa_erase_index(xa, i);
  498. XA_BUG_ON(xa, xa_get_mark(xa, i, XA_MARK_0));
  499. }
  500. XA_BUG_ON(xa, !xa_empty(xa));
  501. check_multi_find(xa);
  502. check_multi_find_2(xa);
  503. }
  504. static noinline void check_move_small(struct xarray *xa, unsigned long idx)
  505. {
  506. XA_STATE(xas, xa, 0);
  507. unsigned long i;
  508. xa_store_index(xa, 0, GFP_KERNEL);
  509. xa_store_index(xa, idx, GFP_KERNEL);
  510. rcu_read_lock();
  511. for (i = 0; i < idx * 4; i++) {
  512. void *entry = xas_next(&xas);
  513. if (i <= idx)
  514. XA_BUG_ON(xa, xas.xa_node == XAS_RESTART);
  515. XA_BUG_ON(xa, xas.xa_index != i);
  516. if (i == 0 || i == idx)
  517. XA_BUG_ON(xa, entry != xa_mk_value(i));
  518. else
  519. XA_BUG_ON(xa, entry != NULL);
  520. }
  521. xas_next(&xas);
  522. XA_BUG_ON(xa, xas.xa_index != i);
  523. do {
  524. void *entry = xas_prev(&xas);
  525. i--;
  526. if (i <= idx)
  527. XA_BUG_ON(xa, xas.xa_node == XAS_RESTART);
  528. XA_BUG_ON(xa, xas.xa_index != i);
  529. if (i == 0 || i == idx)
  530. XA_BUG_ON(xa, entry != xa_mk_value(i));
  531. else
  532. XA_BUG_ON(xa, entry != NULL);
  533. } while (i > 0);
  534. xas_set(&xas, ULONG_MAX);
  535. XA_BUG_ON(xa, xas_next(&xas) != NULL);
  536. XA_BUG_ON(xa, xas.xa_index != ULONG_MAX);
  537. XA_BUG_ON(xa, xas_next(&xas) != xa_mk_value(0));
  538. XA_BUG_ON(xa, xas.xa_index != 0);
  539. XA_BUG_ON(xa, xas_prev(&xas) != NULL);
  540. XA_BUG_ON(xa, xas.xa_index != ULONG_MAX);
  541. rcu_read_unlock();
  542. xa_erase_index(xa, 0);
  543. xa_erase_index(xa, idx);
  544. XA_BUG_ON(xa, !xa_empty(xa));
  545. }
  546. static noinline void check_move(struct xarray *xa)
  547. {
  548. XA_STATE(xas, xa, (1 << 16) - 1);
  549. unsigned long i;
  550. for (i = 0; i < (1 << 16); i++)
  551. XA_BUG_ON(xa, xa_store_index(xa, i, GFP_KERNEL) != NULL);
  552. rcu_read_lock();
  553. do {
  554. void *entry = xas_prev(&xas);
  555. i--;
  556. XA_BUG_ON(xa, entry != xa_mk_value(i));
  557. XA_BUG_ON(xa, i != xas.xa_index);
  558. } while (i != 0);
  559. XA_BUG_ON(xa, xas_prev(&xas) != NULL);
  560. XA_BUG_ON(xa, xas.xa_index != ULONG_MAX);
  561. do {
  562. void *entry = xas_next(&xas);
  563. XA_BUG_ON(xa, entry != xa_mk_value(i));
  564. XA_BUG_ON(xa, i != xas.xa_index);
  565. i++;
  566. } while (i < (1 << 16));
  567. rcu_read_unlock();
  568. for (i = (1 << 8); i < (1 << 15); i++)
  569. xa_erase_index(xa, i);
  570. i = xas.xa_index;
  571. rcu_read_lock();
  572. do {
  573. void *entry = xas_prev(&xas);
  574. i--;
  575. if ((i < (1 << 8)) || (i >= (1 << 15)))
  576. XA_BUG_ON(xa, entry != xa_mk_value(i));
  577. else
  578. XA_BUG_ON(xa, entry != NULL);
  579. XA_BUG_ON(xa, i != xas.xa_index);
  580. } while (i != 0);
  581. XA_BUG_ON(xa, xas_prev(&xas) != NULL);
  582. XA_BUG_ON(xa, xas.xa_index != ULONG_MAX);
  583. do {
  584. void *entry = xas_next(&xas);
  585. if ((i < (1 << 8)) || (i >= (1 << 15)))
  586. XA_BUG_ON(xa, entry != xa_mk_value(i));
  587. else
  588. XA_BUG_ON(xa, entry != NULL);
  589. XA_BUG_ON(xa, i != xas.xa_index);
  590. i++;
  591. } while (i < (1 << 16));
  592. rcu_read_unlock();
  593. xa_destroy(xa);
  594. for (i = 0; i < 16; i++)
  595. check_move_small(xa, 1UL << i);
  596. for (i = 2; i < 16; i++)
  597. check_move_small(xa, (1UL << i) - 1);
  598. }
  599. static noinline void xa_store_many_order(struct xarray *xa,
  600. unsigned long index, unsigned order)
  601. {
  602. XA_STATE_ORDER(xas, xa, index, order);
  603. unsigned int i = 0;
  604. do {
  605. xas_lock(&xas);
  606. XA_BUG_ON(xa, xas_find_conflict(&xas));
  607. xas_create_range(&xas);
  608. if (xas_error(&xas))
  609. goto unlock;
  610. for (i = 0; i < (1U << order); i++) {
  611. XA_BUG_ON(xa, xas_store(&xas, xa_mk_value(index + i)));
  612. xas_next(&xas);
  613. }
  614. unlock:
  615. xas_unlock(&xas);
  616. } while (xas_nomem(&xas, GFP_KERNEL));
  617. XA_BUG_ON(xa, xas_error(&xas));
  618. }
  619. static noinline void check_create_range_1(struct xarray *xa,
  620. unsigned long index, unsigned order)
  621. {
  622. unsigned long i;
  623. xa_store_many_order(xa, index, order);
  624. for (i = index; i < index + (1UL << order); i++)
  625. xa_erase_index(xa, i);
  626. XA_BUG_ON(xa, !xa_empty(xa));
  627. }
  628. static noinline void check_create_range_2(struct xarray *xa, unsigned order)
  629. {
  630. unsigned long i;
  631. unsigned long nr = 1UL << order;
  632. for (i = 0; i < nr * nr; i += nr)
  633. xa_store_many_order(xa, i, order);
  634. for (i = 0; i < nr * nr; i++)
  635. xa_erase_index(xa, i);
  636. XA_BUG_ON(xa, !xa_empty(xa));
  637. }
  638. static noinline void check_create_range_3(void)
  639. {
  640. XA_STATE(xas, NULL, 0);
  641. xas_set_err(&xas, -EEXIST);
  642. xas_create_range(&xas);
  643. XA_BUG_ON(NULL, xas_error(&xas) != -EEXIST);
  644. }
  645. static noinline void check_create_range_4(struct xarray *xa,
  646. unsigned long index, unsigned order)
  647. {
  648. XA_STATE_ORDER(xas, xa, index, order);
  649. unsigned long base = xas.xa_index;
  650. unsigned long i = 0;
  651. xa_store_index(xa, index, GFP_KERNEL);
  652. do {
  653. xas_lock(&xas);
  654. xas_create_range(&xas);
  655. if (xas_error(&xas))
  656. goto unlock;
  657. for (i = 0; i < (1UL << order); i++) {
  658. void *old = xas_store(&xas, xa_mk_value(base + i));
  659. if (xas.xa_index == index)
  660. XA_BUG_ON(xa, old != xa_mk_value(base + i));
  661. else
  662. XA_BUG_ON(xa, old != NULL);
  663. xas_next(&xas);
  664. }
  665. unlock:
  666. xas_unlock(&xas);
  667. } while (xas_nomem(&xas, GFP_KERNEL));
  668. XA_BUG_ON(xa, xas_error(&xas));
  669. for (i = base; i < base + (1UL << order); i++)
  670. xa_erase_index(xa, i);
  671. XA_BUG_ON(xa, !xa_empty(xa));
  672. }
  673. static noinline void check_create_range(struct xarray *xa)
  674. {
  675. unsigned int order;
  676. unsigned int max_order = IS_ENABLED(CONFIG_XARRAY_MULTI) ? 12 : 1;
  677. for (order = 0; order < max_order; order++) {
  678. check_create_range_1(xa, 0, order);
  679. check_create_range_1(xa, 1U << order, order);
  680. check_create_range_1(xa, 2U << order, order);
  681. check_create_range_1(xa, 3U << order, order);
  682. check_create_range_1(xa, 1U << 24, order);
  683. if (order < 10)
  684. check_create_range_2(xa, order);
  685. check_create_range_4(xa, 0, order);
  686. check_create_range_4(xa, 1U << order, order);
  687. check_create_range_4(xa, 2U << order, order);
  688. check_create_range_4(xa, 3U << order, order);
  689. check_create_range_4(xa, 1U << 24, order);
  690. check_create_range_4(xa, 1, order);
  691. check_create_range_4(xa, (1U << order) + 1, order);
  692. check_create_range_4(xa, (2U << order) + 1, order);
  693. check_create_range_4(xa, (2U << order) - 1, order);
  694. check_create_range_4(xa, (3U << order) + 1, order);
  695. check_create_range_4(xa, (3U << order) - 1, order);
  696. check_create_range_4(xa, (1U << 24) + 1, order);
  697. }
  698. check_create_range_3();
  699. }
  700. static noinline void check_destroy(struct xarray *xa)
  701. {
  702. unsigned long index;
  703. XA_BUG_ON(xa, !xa_empty(xa));
  704. /* Destroying an empty array is a no-op */
  705. xa_destroy(xa);
  706. XA_BUG_ON(xa, !xa_empty(xa));
  707. /* Destroying an array with a single entry */
  708. for (index = 0; index < 1000; index++) {
  709. xa_store_index(xa, index, GFP_KERNEL);
  710. XA_BUG_ON(xa, xa_empty(xa));
  711. xa_destroy(xa);
  712. XA_BUG_ON(xa, !xa_empty(xa));
  713. }
  714. /* Destroying an array with a single entry at ULONG_MAX */
  715. xa_store(xa, ULONG_MAX, xa, GFP_KERNEL);
  716. XA_BUG_ON(xa, xa_empty(xa));
  717. xa_destroy(xa);
  718. XA_BUG_ON(xa, !xa_empty(xa));
  719. #ifdef CONFIG_XARRAY_MULTI
  720. /* Destroying an array with a multi-index entry */
  721. xa_store_order(xa, 1 << 11, 11, xa, GFP_KERNEL);
  722. XA_BUG_ON(xa, xa_empty(xa));
  723. xa_destroy(xa);
  724. XA_BUG_ON(xa, !xa_empty(xa));
  725. #endif
  726. }
  727. static DEFINE_XARRAY(array);
  728. static int xarray_checks(void)
  729. {
  730. check_xa_err(&array);
  731. check_xas_retry(&array);
  732. check_xa_load(&array);
  733. check_xa_mark(&array);
  734. check_xa_shrink(&array);
  735. check_xas_erase(&array);
  736. check_cmpxchg(&array);
  737. check_reserve(&array);
  738. check_multi_store(&array);
  739. check_find(&array);
  740. check_destroy(&array);
  741. check_move(&array);
  742. check_create_range(&array);
  743. check_store_iter(&array);
  744. printk("XArray: %u of %u tests passed\n", tests_passed, tests_run);
  745. return (tests_run == tests_passed) ? 0 : -EINVAL;
  746. }
  747. static void xarray_exit(void)
  748. {
  749. }
  750. module_init(xarray_checks);
  751. module_exit(xarray_exit);
  752. MODULE_AUTHOR("Matthew Wilcox <willy@infradead.org>");
  753. MODULE_LICENSE("GPL");