timeout.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785
  1. #include "../config-host.h"
  2. /* SPDX-License-Identifier: MIT */
  3. /*
  4. * Description: run various timeout tests
  5. *
  6. */
  7. #include <errno.h>
  8. #include <stdio.h>
  9. #include <unistd.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <fcntl.h>
  13. #include <sys/time.h>
  14. #include <sys/wait.h>
  15. #include <sys/types.h>
  16. #include <sys/stat.h>
  17. #include "helpers.h"
  18. #include "liburing.h"
  19. #include "../src/syscall.h"
  20. #define TIMEOUT_MSEC 200
  21. static int not_supported;
  22. static int no_modify;
  23. static int no_multishot;
  24. static void msec_to_ts(struct __kernel_timespec *ts, unsigned int msec)
  25. {
  26. ts->tv_sec = msec / 1000;
  27. ts->tv_nsec = (msec % 1000) * 1000000;
  28. }
  29. /*
  30. * Test that we return to userspace if a timeout triggers, even if we
  31. * don't satisfy the number of events asked for.
  32. */
  33. static int test_single_timeout_many(struct io_uring *ring)
  34. {
  35. struct io_uring_cqe *cqe;
  36. struct io_uring_sqe *sqe;
  37. unsigned long long exp;
  38. struct __kernel_timespec ts;
  39. struct timeval tv;
  40. int ret;
  41. sqe = io_uring_get_sqe(ring);
  42. if (!sqe) {
  43. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  44. goto err;
  45. }
  46. msec_to_ts(&ts, TIMEOUT_MSEC);
  47. io_uring_prep_timeout(sqe, &ts, 0, 0);
  48. ret = io_uring_submit(ring);
  49. if (ret <= 0) {
  50. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  51. goto err;
  52. }
  53. gettimeofday(&tv, NULL);
  54. ret = __sys_io_uring_enter(ring->ring_fd, 0, 4, IORING_ENTER_GETEVENTS,
  55. NULL);
  56. if (ret < 0) {
  57. fprintf(stderr, "%s: io_uring_enter %d\n", __FUNCTION__, ret);
  58. goto err;
  59. }
  60. ret = io_uring_wait_cqe(ring, &cqe);
  61. if (ret < 0) {
  62. fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
  63. goto err;
  64. }
  65. ret = cqe->res;
  66. io_uring_cqe_seen(ring, cqe);
  67. if (ret == -EINVAL) {
  68. fprintf(stdout, "Timeout not supported, ignored\n");
  69. not_supported = 1;
  70. return 0;
  71. } else if (ret != -ETIME) {
  72. fprintf(stderr, "Timeout: %s\n", strerror(-ret));
  73. goto err;
  74. }
  75. exp = mtime_since_now(&tv);
  76. if (exp >= TIMEOUT_MSEC / 2 && exp <= (TIMEOUT_MSEC * 3) / 2)
  77. return 0;
  78. fprintf(stderr, "%s: Timeout seems wonky (got %llu)\n", __FUNCTION__, exp);
  79. err:
  80. return 1;
  81. }
  82. /*
  83. * Test numbered trigger of timeout
  84. */
  85. static int test_single_timeout_nr(struct io_uring *ring, int nr)
  86. {
  87. struct io_uring_cqe *cqe;
  88. struct io_uring_sqe *sqe;
  89. struct __kernel_timespec ts;
  90. int i, ret;
  91. sqe = io_uring_get_sqe(ring);
  92. if (!sqe) {
  93. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  94. goto err;
  95. }
  96. msec_to_ts(&ts, TIMEOUT_MSEC);
  97. io_uring_prep_timeout(sqe, &ts, nr, 0);
  98. sqe = io_uring_get_sqe(ring);
  99. io_uring_prep_nop(sqe);
  100. io_uring_sqe_set_data(sqe, (void *) 1);
  101. sqe = io_uring_get_sqe(ring);
  102. io_uring_prep_nop(sqe);
  103. io_uring_sqe_set_data(sqe, (void *) 1);
  104. ret = io_uring_submit_and_wait(ring, 3);
  105. if (ret <= 0) {
  106. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  107. goto err;
  108. }
  109. i = 0;
  110. while (i < 3) {
  111. ret = io_uring_wait_cqe(ring, &cqe);
  112. if (ret < 0) {
  113. fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
  114. goto err;
  115. }
  116. ret = cqe->res;
  117. /*
  118. * NOP commands have user_data as 1. Check that we get the
  119. * at least 'nr' NOPs first, then the successfully removed timeout.
  120. */
  121. if (io_uring_cqe_get_data(cqe) == NULL) {
  122. if (i < nr) {
  123. fprintf(stderr, "%s: timeout received too early\n", __FUNCTION__);
  124. goto err;
  125. }
  126. if (ret) {
  127. fprintf(stderr, "%s: timeout triggered by passage of"
  128. " time, not by events completed\n", __FUNCTION__);
  129. goto err;
  130. }
  131. }
  132. io_uring_cqe_seen(ring, cqe);
  133. if (ret) {
  134. fprintf(stderr, "res: %d\n", ret);
  135. goto err;
  136. }
  137. i++;
  138. }
  139. return 0;
  140. err:
  141. return 1;
  142. }
  143. static int test_single_timeout_wait(struct io_uring *ring,
  144. struct io_uring_params *p)
  145. {
  146. struct io_uring_cqe *cqe;
  147. struct io_uring_sqe *sqe;
  148. struct __kernel_timespec ts;
  149. int i, ret;
  150. sqe = io_uring_get_sqe(ring);
  151. io_uring_prep_nop(sqe);
  152. io_uring_sqe_set_data(sqe, (void *) 1);
  153. sqe = io_uring_get_sqe(ring);
  154. io_uring_prep_nop(sqe);
  155. io_uring_sqe_set_data(sqe, (void *) 1);
  156. /* no implied submit for newer kernels */
  157. if (p->features & IORING_FEAT_EXT_ARG) {
  158. ret = io_uring_submit(ring);
  159. if (ret != 2) {
  160. fprintf(stderr, "%s: submit %d\n", __FUNCTION__, ret);
  161. return 1;
  162. }
  163. }
  164. msec_to_ts(&ts, 1000);
  165. i = 0;
  166. do {
  167. ret = io_uring_wait_cqes(ring, &cqe, 2, &ts, NULL);
  168. if (ret == -ETIME)
  169. break;
  170. if (ret < 0) {
  171. fprintf(stderr, "%s: wait timeout failed: %d\n", __FUNCTION__, ret);
  172. goto err;
  173. }
  174. ret = cqe->res;
  175. io_uring_cqe_seen(ring, cqe);
  176. if (ret < 0) {
  177. fprintf(stderr, "res: %d\n", ret);
  178. goto err;
  179. }
  180. i++;
  181. } while (1);
  182. if (i != 2) {
  183. fprintf(stderr, "got %d completions\n", i);
  184. goto err;
  185. }
  186. return 0;
  187. err:
  188. return 1;
  189. }
  190. /*
  191. * Test single timeout waking us up
  192. */
  193. static int test_single_timeout(struct io_uring *ring)
  194. {
  195. struct io_uring_cqe *cqe;
  196. struct io_uring_sqe *sqe;
  197. unsigned long long exp;
  198. struct __kernel_timespec ts;
  199. struct timeval tv;
  200. int ret;
  201. sqe = io_uring_get_sqe(ring);
  202. if (!sqe) {
  203. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  204. goto err;
  205. }
  206. msec_to_ts(&ts, TIMEOUT_MSEC);
  207. io_uring_prep_timeout(sqe, &ts, 0, 0);
  208. ret = io_uring_submit(ring);
  209. if (ret <= 0) {
  210. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  211. goto err;
  212. }
  213. gettimeofday(&tv, NULL);
  214. ret = io_uring_wait_cqe(ring, &cqe);
  215. if (ret < 0) {
  216. fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
  217. goto err;
  218. }
  219. ret = cqe->res;
  220. io_uring_cqe_seen(ring, cqe);
  221. if (ret == -EINVAL) {
  222. fprintf(stdout, "%s: Timeout not supported, ignored\n", __FUNCTION__);
  223. not_supported = 1;
  224. return 0;
  225. } else if (ret != -ETIME) {
  226. fprintf(stderr, "%s: Timeout: %s\n", __FUNCTION__, strerror(-ret));
  227. goto err;
  228. }
  229. exp = mtime_since_now(&tv);
  230. if (exp >= TIMEOUT_MSEC / 2 && exp <= (TIMEOUT_MSEC * 3) / 2)
  231. return 0;
  232. fprintf(stderr, "%s: Timeout seems wonky (got %llu)\n", __FUNCTION__, exp);
  233. err:
  234. return 1;
  235. }
  236. static int test_single_timeout_remove_notfound(struct io_uring *ring)
  237. {
  238. struct io_uring_cqe *cqe;
  239. struct io_uring_sqe *sqe;
  240. struct __kernel_timespec ts;
  241. int ret, i;
  242. if (no_modify)
  243. return 0;
  244. sqe = io_uring_get_sqe(ring);
  245. if (!sqe) {
  246. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  247. goto err;
  248. }
  249. msec_to_ts(&ts, TIMEOUT_MSEC);
  250. io_uring_prep_timeout(sqe, &ts, 2, 0);
  251. sqe->user_data = 1;
  252. ret = io_uring_submit(ring);
  253. if (ret <= 0) {
  254. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  255. goto err;
  256. }
  257. sqe = io_uring_get_sqe(ring);
  258. if (!sqe) {
  259. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  260. goto err;
  261. }
  262. io_uring_prep_timeout_remove(sqe, 2, 0);
  263. sqe->user_data = 2;
  264. ret = io_uring_submit(ring);
  265. if (ret <= 0) {
  266. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  267. goto err;
  268. }
  269. /*
  270. * We should get two completions. One is our modify request, which should
  271. * complete with -ENOENT. The other is the timeout that will trigger after
  272. * TIMEOUT_MSEC.
  273. */
  274. for (i = 0; i < 2; i++) {
  275. ret = io_uring_wait_cqe(ring, &cqe);
  276. if (ret < 0) {
  277. fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
  278. goto err;
  279. }
  280. if (cqe->user_data == 2) {
  281. if (cqe->res != -ENOENT) {
  282. fprintf(stderr, "%s: modify ret %d, wanted ENOENT\n", __FUNCTION__, cqe->res);
  283. break;
  284. }
  285. } else if (cqe->user_data == 1) {
  286. if (cqe->res != -ETIME) {
  287. fprintf(stderr, "%s: timeout ret %d, wanted -ETIME\n", __FUNCTION__, cqe->res);
  288. break;
  289. }
  290. }
  291. io_uring_cqe_seen(ring, cqe);
  292. }
  293. return 0;
  294. err:
  295. return 1;
  296. }
  297. static int test_single_timeout_remove(struct io_uring *ring)
  298. {
  299. struct io_uring_cqe *cqe;
  300. struct io_uring_sqe *sqe;
  301. struct __kernel_timespec ts;
  302. int ret, i;
  303. sqe = io_uring_get_sqe(ring);
  304. if (!sqe) {
  305. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  306. goto err;
  307. }
  308. msec_to_ts(&ts, TIMEOUT_MSEC);
  309. io_uring_prep_timeout(sqe, &ts, 0, 0);
  310. sqe->user_data = 1;
  311. ret = io_uring_submit(ring);
  312. if (ret <= 0) {
  313. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  314. goto err;
  315. }
  316. sqe = io_uring_get_sqe(ring);
  317. if (!sqe) {
  318. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  319. goto err;
  320. }
  321. io_uring_prep_timeout_remove(sqe, 1, 0);
  322. sqe->user_data = 2;
  323. ret = io_uring_submit(ring);
  324. if (ret <= 0) {
  325. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  326. goto err;
  327. }
  328. /*
  329. * We should have two completions ready. One is for the original timeout
  330. * request, user_data == 1, that should have a ret of -ECANCELED. The other
  331. * is for our modify request, user_data == 2, that should have a ret of 0.
  332. */
  333. for (i = 0; i < 2; i++) {
  334. ret = io_uring_wait_cqe(ring, &cqe);
  335. if (ret < 0) {
  336. fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
  337. goto err;
  338. }
  339. if (no_modify)
  340. goto seen;
  341. if (cqe->res == -EINVAL && cqe->user_data == 2) {
  342. fprintf(stdout, "Timeout modify not supported, ignoring\n");
  343. no_modify = 1;
  344. goto seen;
  345. }
  346. if (cqe->user_data == 1) {
  347. if (cqe->res != -ECANCELED) {
  348. fprintf(stderr, "%s: timeout ret %d, wanted canceled\n", __FUNCTION__, cqe->res);
  349. break;
  350. }
  351. } else if (cqe->user_data == 2) {
  352. if (cqe->res) {
  353. fprintf(stderr, "%s: modify ret %d, wanted 0\n", __FUNCTION__, cqe->res);
  354. break;
  355. }
  356. }
  357. seen:
  358. io_uring_cqe_seen(ring, cqe);
  359. }
  360. return 0;
  361. err:
  362. return 1;
  363. }
  364. /*
  365. * Test single absolute timeout waking us up
  366. */
  367. static int test_single_timeout_abs(struct io_uring *ring)
  368. {
  369. struct io_uring_cqe *cqe;
  370. struct io_uring_sqe *sqe;
  371. unsigned long long exp;
  372. struct __kernel_timespec ts;
  373. struct timespec abs_ts;
  374. struct timeval tv;
  375. int ret;
  376. sqe = io_uring_get_sqe(ring);
  377. if (!sqe) {
  378. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  379. goto err;
  380. }
  381. clock_gettime(CLOCK_MONOTONIC, &abs_ts);
  382. ts.tv_sec = abs_ts.tv_sec + 1;
  383. ts.tv_nsec = abs_ts.tv_nsec;
  384. io_uring_prep_timeout(sqe, &ts, 0, IORING_TIMEOUT_ABS);
  385. ret = io_uring_submit(ring);
  386. if (ret <= 0) {
  387. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  388. goto err;
  389. }
  390. gettimeofday(&tv, NULL);
  391. ret = io_uring_wait_cqe(ring, &cqe);
  392. if (ret < 0) {
  393. fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
  394. goto err;
  395. }
  396. ret = cqe->res;
  397. io_uring_cqe_seen(ring, cqe);
  398. if (ret == -EINVAL) {
  399. fprintf(stdout, "Absolute timeouts not supported, ignored\n");
  400. return 0;
  401. } else if (ret != -ETIME) {
  402. fprintf(stderr, "Timeout: %s\n", strerror(-ret));
  403. goto err;
  404. }
  405. exp = mtime_since_now(&tv);
  406. if (exp >= 1000 / 2 && exp <= (1000 * 3) / 2)
  407. return 0;
  408. fprintf(stderr, "%s: Timeout seems wonky (got %llu)\n", __FUNCTION__, exp);
  409. err:
  410. return 1;
  411. }
  412. /*
  413. * Test that timeout is canceled on exit
  414. */
  415. static int test_single_timeout_exit(struct io_uring *ring)
  416. {
  417. struct io_uring_sqe *sqe;
  418. struct __kernel_timespec ts;
  419. int ret;
  420. sqe = io_uring_get_sqe(ring);
  421. if (!sqe) {
  422. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  423. goto err;
  424. }
  425. msec_to_ts(&ts, 30000);
  426. io_uring_prep_timeout(sqe, &ts, 0, 0);
  427. ret = io_uring_submit(ring);
  428. if (ret <= 0) {
  429. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  430. goto err;
  431. }
  432. io_uring_queue_exit(ring);
  433. return 0;
  434. err:
  435. io_uring_queue_exit(ring);
  436. return 1;
  437. }
  438. /*
  439. * Test multi timeouts waking us up
  440. */
  441. static int test_multi_timeout(struct io_uring *ring)
  442. {
  443. struct io_uring_sqe *sqe;
  444. struct io_uring_cqe *cqe;
  445. struct __kernel_timespec ts[2];
  446. unsigned int timeout[2];
  447. unsigned long long exp;
  448. struct timeval tv;
  449. int ret, i;
  450. /* req_1: timeout req, count = 1, time = (TIMEOUT_MSEC * 2) */
  451. timeout[0] = TIMEOUT_MSEC * 2;
  452. msec_to_ts(&ts[0], timeout[0]);
  453. sqe = io_uring_get_sqe(ring);
  454. if (!sqe) {
  455. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  456. goto err;
  457. }
  458. io_uring_prep_timeout(sqe, &ts[0], 1, 0);
  459. sqe->user_data = 1;
  460. /* req_2: timeout req, count = 1, time = TIMEOUT_MSEC */
  461. timeout[1] = TIMEOUT_MSEC;
  462. msec_to_ts(&ts[1], timeout[1]);
  463. sqe = io_uring_get_sqe(ring);
  464. if (!sqe) {
  465. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  466. goto err;
  467. }
  468. io_uring_prep_timeout(sqe, &ts[1], 1, 0);
  469. sqe->user_data = 2;
  470. ret = io_uring_submit(ring);
  471. if (ret <= 0) {
  472. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  473. goto err;
  474. }
  475. gettimeofday(&tv, NULL);
  476. for (i = 0; i < 2; i++) {
  477. unsigned int time = 0;
  478. __u64 user_data = 0;
  479. ret = io_uring_wait_cqe(ring, &cqe);
  480. if (ret < 0) {
  481. fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
  482. goto err;
  483. }
  484. /*
  485. * Both of these two reqs should timeout, but req_2 should
  486. * return before req_1.
  487. */
  488. switch (i) {
  489. case 0:
  490. user_data = 2;
  491. time = timeout[1];
  492. break;
  493. case 1:
  494. user_data = 1;
  495. time = timeout[0];
  496. break;
  497. }
  498. if (cqe->user_data != user_data) {
  499. fprintf(stderr, "%s: unexpected timeout req %d sequence\n",
  500. __FUNCTION__, i+1);
  501. goto err;
  502. }
  503. if (cqe->res != -ETIME) {
  504. fprintf(stderr, "%s: Req %d timeout: %s\n",
  505. __FUNCTION__, i+1, strerror(cqe->res));
  506. goto err;
  507. }
  508. exp = mtime_since_now(&tv);
  509. if (exp < time / 2 || exp > (time * 3) / 2) {
  510. fprintf(stderr, "%s: Req %d timeout seems wonky (got %llu)\n",
  511. __FUNCTION__, i+1, exp);
  512. goto err;
  513. }
  514. io_uring_cqe_seen(ring, cqe);
  515. }
  516. return 0;
  517. err:
  518. return 1;
  519. }
  520. /*
  521. * Test multi timeout req with different count
  522. */
  523. static int test_multi_timeout_nr(struct io_uring *ring)
  524. {
  525. struct io_uring_sqe *sqe;
  526. struct io_uring_cqe *cqe;
  527. struct __kernel_timespec ts;
  528. int ret, i;
  529. msec_to_ts(&ts, TIMEOUT_MSEC);
  530. /* req_1: timeout req, count = 2 */
  531. sqe = io_uring_get_sqe(ring);
  532. if (!sqe) {
  533. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  534. goto err;
  535. }
  536. io_uring_prep_timeout(sqe, &ts, 2, 0);
  537. sqe->user_data = 1;
  538. /* req_2: timeout req, count = 1 */
  539. sqe = io_uring_get_sqe(ring);
  540. if (!sqe) {
  541. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  542. goto err;
  543. }
  544. io_uring_prep_timeout(sqe, &ts, 1, 0);
  545. sqe->user_data = 2;
  546. /* req_3: nop req */
  547. sqe = io_uring_get_sqe(ring);
  548. if (!sqe) {
  549. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  550. goto err;
  551. }
  552. io_uring_prep_nop(sqe);
  553. io_uring_sqe_set_data(sqe, (void *) 1);
  554. ret = io_uring_submit(ring);
  555. if (ret <= 0) {
  556. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  557. goto err;
  558. }
  559. /*
  560. * req_2 (count=1) should return without error and req_1 (count=2)
  561. * should timeout.
  562. */
  563. for (i = 0; i < 3; i++) {
  564. ret = io_uring_wait_cqe(ring, &cqe);
  565. if (ret < 0) {
  566. fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
  567. goto err;
  568. }
  569. switch (i) {
  570. case 0:
  571. /* Should be nop req */
  572. if (io_uring_cqe_get_data(cqe) != (void *) 1) {
  573. fprintf(stderr, "%s: nop not seen as 1 or 2\n", __FUNCTION__);
  574. goto err;
  575. }
  576. break;
  577. case 1:
  578. /* Should be timeout req_2 */
  579. if (cqe->user_data != 2) {
  580. fprintf(stderr, "%s: unexpected timeout req %d sequence\n",
  581. __FUNCTION__, i+1);
  582. goto err;
  583. }
  584. if (cqe->res < 0) {
  585. fprintf(stderr, "%s: Req %d res %d\n",
  586. __FUNCTION__, i+1, cqe->res);
  587. goto err;
  588. }
  589. break;
  590. case 2:
  591. /* Should be timeout req_1 */
  592. if (cqe->user_data != 1) {
  593. fprintf(stderr, "%s: unexpected timeout req %d sequence\n",
  594. __FUNCTION__, i+1);
  595. goto err;
  596. }
  597. if (cqe->res != -ETIME) {
  598. fprintf(stderr, "%s: Req %d timeout: %s\n",
  599. __FUNCTION__, i+1, strerror(cqe->res));
  600. goto err;
  601. }
  602. break;
  603. }
  604. io_uring_cqe_seen(ring, cqe);
  605. }
  606. return 0;
  607. err:
  608. return 1;
  609. }
  610. /*
  611. * Test timeout <link> timeout <drain> timeout
  612. */
  613. static int test_timeout_flags1(struct io_uring *ring)
  614. {
  615. struct io_uring_sqe *sqe;
  616. struct io_uring_cqe *cqe;
  617. struct __kernel_timespec ts;
  618. int ret, i;
  619. msec_to_ts(&ts, TIMEOUT_MSEC);
  620. sqe = io_uring_get_sqe(ring);
  621. if (!sqe) {
  622. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  623. goto err;
  624. }
  625. io_uring_prep_timeout(sqe, &ts, 0, 0);
  626. sqe->user_data = 1;
  627. sqe->flags |= IOSQE_IO_LINK;
  628. sqe = io_uring_get_sqe(ring);
  629. if (!sqe) {
  630. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  631. goto err;
  632. }
  633. io_uring_prep_timeout(sqe, &ts, 0, 0);
  634. sqe->user_data = 2;
  635. sqe->flags |= IOSQE_IO_DRAIN;
  636. sqe = io_uring_get_sqe(ring);
  637. if (!sqe) {
  638. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  639. goto err;
  640. }
  641. io_uring_prep_timeout(sqe, &ts, 0, 0);
  642. sqe->user_data = 3;
  643. ret = io_uring_submit(ring);
  644. if (ret <= 0) {
  645. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  646. goto err;
  647. }
  648. for (i = 0; i < 3; i++) {
  649. ret = io_uring_wait_cqe(ring, &cqe);
  650. if (ret < 0) {
  651. fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
  652. goto err;
  653. }
  654. if (cqe->res == -EINVAL) {
  655. if (!i)
  656. fprintf(stdout, "%s: timeout flags not supported\n",
  657. __FUNCTION__);
  658. io_uring_cqe_seen(ring, cqe);
  659. continue;
  660. }
  661. switch (cqe->user_data) {
  662. case 1:
  663. if (cqe->res != -ETIME) {
  664. fprintf(stderr, "%s: got %d, wanted %d\n",
  665. __FUNCTION__, cqe->res, -ETIME);
  666. goto err;
  667. }
  668. break;
  669. case 2:
  670. if (cqe->res != -ECANCELED) {
  671. fprintf(stderr, "%s: got %d, wanted %d\n",
  672. __FUNCTION__, cqe->res,
  673. -ECANCELED);
  674. goto err;
  675. }
  676. break;
  677. case 3:
  678. if (cqe->res != -ETIME) {
  679. fprintf(stderr, "%s: got %d, wanted %d\n",
  680. __FUNCTION__, cqe->res, -ETIME);
  681. goto err;
  682. }
  683. break;
  684. }
  685. io_uring_cqe_seen(ring, cqe);
  686. }
  687. return 0;
  688. err:
  689. return 1;
  690. }
  691. /*
  692. * Test timeout <link> timeout <link> timeout
  693. */
  694. static int test_timeout_flags2(struct io_uring *ring)
  695. {
  696. struct io_uring_sqe *sqe;
  697. struct io_uring_cqe *cqe;
  698. struct __kernel_timespec ts;
  699. int ret, i;
  700. msec_to_ts(&ts, TIMEOUT_MSEC);
  701. sqe = io_uring_get_sqe(ring);
  702. if (!sqe) {
  703. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  704. goto err;
  705. }
  706. io_uring_prep_timeout(sqe, &ts, 0, 0);
  707. sqe->user_data = 1;
  708. sqe->flags |= IOSQE_IO_LINK;
  709. sqe = io_uring_get_sqe(ring);
  710. if (!sqe) {
  711. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  712. goto err;
  713. }
  714. io_uring_prep_timeout(sqe, &ts, 0, 0);
  715. sqe->user_data = 2;
  716. sqe->flags |= IOSQE_IO_LINK;
  717. sqe = io_uring_get_sqe(ring);
  718. if (!sqe) {
  719. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  720. goto err;
  721. }
  722. io_uring_prep_timeout(sqe, &ts, 0, 0);
  723. sqe->user_data = 3;
  724. ret = io_uring_submit(ring);
  725. if (ret <= 0) {
  726. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  727. goto err;
  728. }
  729. for (i = 0; i < 3; i++) {
  730. ret = io_uring_wait_cqe(ring, &cqe);
  731. if (ret < 0) {
  732. fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
  733. goto err;
  734. }
  735. if (cqe->res == -EINVAL) {
  736. if (!i)
  737. fprintf(stdout, "%s: timeout flags not supported\n",
  738. __FUNCTION__);
  739. io_uring_cqe_seen(ring, cqe);
  740. continue;
  741. }
  742. switch (cqe->user_data) {
  743. case 1:
  744. if (cqe->res != -ETIME) {
  745. fprintf(stderr, "%s: got %d, wanted %d\n",
  746. __FUNCTION__, cqe->res, -ETIME);
  747. goto err;
  748. }
  749. break;
  750. case 2:
  751. case 3:
  752. if (cqe->res != -ECANCELED) {
  753. fprintf(stderr, "%s: got %d, wanted %d\n",
  754. __FUNCTION__, cqe->res,
  755. -ECANCELED);
  756. goto err;
  757. }
  758. break;
  759. }
  760. io_uring_cqe_seen(ring, cqe);
  761. }
  762. return 0;
  763. err:
  764. return 1;
  765. }
  766. /*
  767. * Test timeout <drain> timeout <link> timeout
  768. */
  769. static int test_timeout_flags3(struct io_uring *ring)
  770. {
  771. struct io_uring_sqe *sqe;
  772. struct io_uring_cqe *cqe;
  773. struct __kernel_timespec ts;
  774. int ret, i;
  775. msec_to_ts(&ts, TIMEOUT_MSEC);
  776. sqe = io_uring_get_sqe(ring);
  777. if (!sqe) {
  778. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  779. goto err;
  780. }
  781. io_uring_prep_timeout(sqe, &ts, 0, 0);
  782. sqe->user_data = 1;
  783. sqe->flags |= IOSQE_IO_DRAIN;
  784. sqe = io_uring_get_sqe(ring);
  785. if (!sqe) {
  786. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  787. goto err;
  788. }
  789. io_uring_prep_timeout(sqe, &ts, 0, 0);
  790. sqe->user_data = 2;
  791. sqe->flags |= IOSQE_IO_LINK;
  792. sqe = io_uring_get_sqe(ring);
  793. if (!sqe) {
  794. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  795. goto err;
  796. }
  797. io_uring_prep_timeout(sqe, &ts, 0, 0);
  798. sqe->user_data = 3;
  799. ret = io_uring_submit(ring);
  800. if (ret <= 0) {
  801. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  802. goto err;
  803. }
  804. for (i = 0; i < 3; i++) {
  805. ret = io_uring_wait_cqe(ring, &cqe);
  806. if (ret < 0) {
  807. fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
  808. goto err;
  809. }
  810. if (cqe->res == -EINVAL) {
  811. if (!i)
  812. fprintf(stdout, "%s: timeout flags not supported\n",
  813. __FUNCTION__);
  814. io_uring_cqe_seen(ring, cqe);
  815. continue;
  816. }
  817. switch (cqe->user_data) {
  818. case 1:
  819. case 2:
  820. if (cqe->res != -ETIME) {
  821. fprintf(stderr, "%s: got %d, wanted %d\n",
  822. __FUNCTION__, cqe->res, -ETIME);
  823. goto err;
  824. }
  825. break;
  826. case 3:
  827. if (cqe->res != -ECANCELED) {
  828. fprintf(stderr, "%s: got %d, wanted %d\n",
  829. __FUNCTION__, cqe->res,
  830. -ECANCELED);
  831. goto err;
  832. }
  833. break;
  834. }
  835. io_uring_cqe_seen(ring, cqe);
  836. }
  837. return 0;
  838. err:
  839. return 1;
  840. }
  841. static int test_update_timeout(struct io_uring *ring, unsigned long ms,
  842. bool abs, bool async, bool linked)
  843. {
  844. struct io_uring_sqe *sqe;
  845. struct io_uring_cqe *cqe;
  846. struct __kernel_timespec ts, ts_upd;
  847. unsigned long long exp_ms, base_ms = 10000;
  848. bool update_ealready = false;
  849. struct timeval tv;
  850. int ret, i, nr = 2;
  851. __u32 mode = abs ? IORING_TIMEOUT_ABS : 0;
  852. msec_to_ts(&ts_upd, ms);
  853. gettimeofday(&tv, NULL);
  854. sqe = io_uring_get_sqe(ring);
  855. if (!sqe) {
  856. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  857. goto err;
  858. }
  859. msec_to_ts(&ts, base_ms);
  860. io_uring_prep_timeout(sqe, &ts, 0, 0);
  861. sqe->user_data = 1;
  862. if (linked) {
  863. sqe = io_uring_get_sqe(ring);
  864. if (!sqe) {
  865. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  866. goto err;
  867. }
  868. io_uring_prep_nop(sqe);
  869. sqe->user_data = 3;
  870. sqe->flags = IOSQE_IO_LINK;
  871. if (async)
  872. sqe->flags |= IOSQE_ASYNC;
  873. nr++;
  874. }
  875. sqe = io_uring_get_sqe(ring);
  876. if (!sqe) {
  877. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  878. goto err;
  879. }
  880. io_uring_prep_timeout_update(sqe, &ts_upd, 1, mode);
  881. sqe->user_data = 2;
  882. if (async)
  883. sqe->flags |= IOSQE_ASYNC;
  884. ret = io_uring_submit(ring);
  885. if (ret != nr) {
  886. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  887. goto err;
  888. }
  889. for (i = 0; i < nr; i++) {
  890. ret = io_uring_wait_cqe(ring, &cqe);
  891. if (ret < 0) {
  892. fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
  893. goto err;
  894. }
  895. switch (cqe->user_data) {
  896. case 1:
  897. if (cqe->res != -ETIME) {
  898. fprintf(stderr, "%s: got %d, wanted %d\n",
  899. __FUNCTION__, cqe->res, -ETIME);
  900. goto err;
  901. }
  902. break;
  903. case 2:
  904. /*
  905. * We should not be hitting this case, but for
  906. * a kernel with PREEMPT_RT, even an instant attempt
  907. * to remove a timer will return that the timer is
  908. * already running... Deal with it.
  909. */
  910. if (cqe->res == -EALREADY) {
  911. update_ealready = true;
  912. break;
  913. }
  914. if (cqe->res != 0) {
  915. fprintf(stderr, "%s: got %d, wanted %d\n",
  916. __FUNCTION__, cqe->res,
  917. 0);
  918. goto err;
  919. }
  920. break;
  921. case 3:
  922. if (cqe->res != 0) {
  923. fprintf(stderr, "nop failed\n");
  924. goto err;
  925. }
  926. break;
  927. default:
  928. goto err;
  929. }
  930. io_uring_cqe_seen(ring, cqe);
  931. }
  932. exp_ms = mtime_since_now(&tv);
  933. if (!update_ealready && exp_ms >= base_ms / 2) {
  934. fprintf(stderr, "too long, timeout wasn't updated\n");
  935. goto err;
  936. }
  937. if (ms >= 1000 && !abs && exp_ms < ms / 2) {
  938. fprintf(stderr, "fired too early, potentially updated to 0 ms"
  939. "instead of %lu\n", ms);
  940. goto err;
  941. }
  942. return 0;
  943. err:
  944. return 1;
  945. }
  946. static int test_update_nonexistent_timeout(struct io_uring *ring)
  947. {
  948. struct io_uring_sqe *sqe;
  949. struct io_uring_cqe *cqe;
  950. struct __kernel_timespec ts;
  951. int ret;
  952. sqe = io_uring_get_sqe(ring);
  953. if (!sqe) {
  954. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  955. goto err;
  956. }
  957. msec_to_ts(&ts, 0);
  958. io_uring_prep_timeout_update(sqe, &ts, 42, 0);
  959. ret = io_uring_submit(ring);
  960. if (ret != 1) {
  961. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  962. goto err;
  963. }
  964. ret = io_uring_wait_cqe(ring, &cqe);
  965. if (ret < 0) {
  966. fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
  967. goto err;
  968. }
  969. ret = cqe->res;
  970. if (ret == -ENOENT)
  971. ret = 0;
  972. io_uring_cqe_seen(ring, cqe);
  973. return ret;
  974. err:
  975. return 1;
  976. }
  977. static int test_update_invalid_flags(struct io_uring *ring)
  978. {
  979. struct io_uring_sqe *sqe;
  980. struct io_uring_cqe *cqe;
  981. struct __kernel_timespec ts;
  982. int ret;
  983. sqe = io_uring_get_sqe(ring);
  984. if (!sqe) {
  985. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  986. goto err;
  987. }
  988. io_uring_prep_timeout_remove(sqe, 0, IORING_TIMEOUT_ABS);
  989. ret = io_uring_submit(ring);
  990. if (ret != 1) {
  991. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  992. goto err;
  993. }
  994. ret = io_uring_wait_cqe(ring, &cqe);
  995. if (ret < 0) {
  996. fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
  997. goto err;
  998. }
  999. if (cqe->res != -EINVAL) {
  1000. fprintf(stderr, "%s: got %d, wanted %d\n",
  1001. __FUNCTION__, cqe->res, -EINVAL);
  1002. goto err;
  1003. }
  1004. io_uring_cqe_seen(ring, cqe);
  1005. sqe = io_uring_get_sqe(ring);
  1006. if (!sqe) {
  1007. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  1008. goto err;
  1009. }
  1010. msec_to_ts(&ts, 0);
  1011. io_uring_prep_timeout_update(sqe, &ts, 0, -1);
  1012. ret = io_uring_submit(ring);
  1013. if (ret != 1) {
  1014. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  1015. goto err;
  1016. }
  1017. ret = io_uring_wait_cqe(ring, &cqe);
  1018. if (ret < 0) {
  1019. fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
  1020. goto err;
  1021. }
  1022. if (cqe->res != -EINVAL) {
  1023. fprintf(stderr, "%s: got %d, wanted %d\n",
  1024. __FUNCTION__, cqe->res, -EINVAL);
  1025. goto err;
  1026. }
  1027. io_uring_cqe_seen(ring, cqe);
  1028. return 0;
  1029. err:
  1030. return 1;
  1031. }
  1032. static int fill_exec_target(char *dst, char *path)
  1033. {
  1034. struct stat sb;
  1035. /*
  1036. * Should either be ./exec-target.t or test/exec-target.t
  1037. */
  1038. sprintf(dst, "%s", path);
  1039. return stat(dst, &sb);
  1040. }
  1041. static int test_timeout_link_cancel(void)
  1042. {
  1043. struct io_uring ring;
  1044. struct io_uring_cqe *cqe;
  1045. char prog_path[PATH_MAX];
  1046. pid_t p;
  1047. int ret, i, wstatus;
  1048. if (fill_exec_target(prog_path, "./exec-target.t") &&
  1049. fill_exec_target(prog_path, "test/exec-target.t")) {
  1050. fprintf(stdout, "Can't find exec-target, skipping\n");
  1051. return 0;
  1052. }
  1053. ret = io_uring_queue_init(8, &ring, 0);
  1054. if (ret) {
  1055. fprintf(stderr, "ring create failed: %d\n", ret);
  1056. return 1;
  1057. }
  1058. p = fork();
  1059. if (p == -1) {
  1060. fprintf(stderr, "fork() failed\n");
  1061. return 1;
  1062. }
  1063. if (p == 0) {
  1064. struct io_uring_sqe *sqe;
  1065. struct __kernel_timespec ts;
  1066. msec_to_ts(&ts, 10000);
  1067. sqe = io_uring_get_sqe(&ring);
  1068. io_uring_prep_timeout(sqe, &ts, 0, 0);
  1069. sqe->flags |= IOSQE_IO_LINK;
  1070. sqe->user_data = 0;
  1071. sqe = io_uring_get_sqe(&ring);
  1072. io_uring_prep_nop(sqe);
  1073. sqe->user_data = 1;
  1074. ret = io_uring_submit(&ring);
  1075. if (ret != 2) {
  1076. fprintf(stderr, "%s: got %d, wanted 1\n", __FUNCTION__, ret);
  1077. exit(1);
  1078. }
  1079. /* trigger full cancelation */
  1080. ret = execl(prog_path, prog_path, NULL);
  1081. if (ret) {
  1082. fprintf(stderr, "exec failed %i\n", errno);
  1083. exit(1);
  1084. }
  1085. exit(0);
  1086. }
  1087. if (waitpid(p, &wstatus, 0) == (pid_t)-1) {
  1088. perror("waitpid()");
  1089. return 1;
  1090. }
  1091. if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus)) {
  1092. fprintf(stderr, "child failed %i\n", WEXITSTATUS(wstatus));
  1093. return 1;
  1094. }
  1095. for (i = 0; i < 2; ++i) {
  1096. ret = io_uring_wait_cqe(&ring, &cqe);
  1097. if (ret) {
  1098. fprintf(stderr, "wait_cqe=%d\n", ret);
  1099. return 1;
  1100. }
  1101. if (cqe->res != -ECANCELED) {
  1102. fprintf(stderr, "invalid result, user_data: %i res: %i\n",
  1103. (int)cqe->user_data, cqe->res);
  1104. return 1;
  1105. }
  1106. io_uring_cqe_seen(&ring, cqe);
  1107. }
  1108. io_uring_queue_exit(&ring);
  1109. return 0;
  1110. }
  1111. static int test_not_failing_links(void)
  1112. {
  1113. struct io_uring ring;
  1114. struct io_uring_sqe *sqe;
  1115. struct io_uring_cqe *cqe;
  1116. struct __kernel_timespec ts;
  1117. int ret;
  1118. ret = io_uring_queue_init(8, &ring, 0);
  1119. if (ret) {
  1120. fprintf(stderr, "ring create failed: %d\n", ret);
  1121. return 1;
  1122. }
  1123. msec_to_ts(&ts, 1);
  1124. sqe = io_uring_get_sqe(&ring);
  1125. io_uring_prep_timeout(sqe, &ts, 0, IORING_TIMEOUT_ETIME_SUCCESS);
  1126. sqe->user_data = 1;
  1127. sqe->flags |= IOSQE_IO_LINK;
  1128. sqe = io_uring_get_sqe(&ring);
  1129. io_uring_prep_nop(sqe);
  1130. sqe->user_data = 2;
  1131. ret = io_uring_submit(&ring);
  1132. if (ret != 2) {
  1133. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  1134. return 1;
  1135. }
  1136. ret = io_uring_wait_cqe(&ring, &cqe);
  1137. if (ret < 0) {
  1138. fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
  1139. return 1;
  1140. } else if (cqe->user_data == 1 && cqe->res == -EINVAL) {
  1141. goto done;
  1142. } else if (cqe->res != -ETIME || cqe->user_data != 1) {
  1143. fprintf(stderr, "timeout failed %i %i\n", cqe->res,
  1144. (int)cqe->user_data);
  1145. return 1;
  1146. }
  1147. io_uring_cqe_seen(&ring, cqe);
  1148. ret = io_uring_wait_cqe(&ring, &cqe);
  1149. if (ret < 0) {
  1150. fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
  1151. return 1;
  1152. } else if (cqe->res || cqe->user_data != 2) {
  1153. fprintf(stderr, "nop failed %i %i\n", cqe->res,
  1154. (int)cqe->user_data);
  1155. return 1;
  1156. }
  1157. done:
  1158. io_uring_cqe_seen(&ring, cqe);
  1159. io_uring_queue_exit(&ring);
  1160. return 0;
  1161. }
  1162. static int test_timeout_multishot(struct io_uring *ring)
  1163. {
  1164. struct io_uring_cqe *cqe;
  1165. struct io_uring_sqe *sqe;
  1166. struct __kernel_timespec ts;
  1167. int ret;
  1168. sqe = io_uring_get_sqe(ring);
  1169. if (!sqe) {
  1170. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  1171. goto err;
  1172. }
  1173. msec_to_ts(&ts, TIMEOUT_MSEC);
  1174. io_uring_prep_timeout(sqe, &ts, 0, IORING_TIMEOUT_MULTISHOT);
  1175. io_uring_sqe_set_data(sqe, (void *) 1);
  1176. ret = io_uring_submit(ring);
  1177. if (ret <= 0) {
  1178. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  1179. goto err;
  1180. }
  1181. for (int i = 0; i < 2; i++) {
  1182. ret = io_uring_wait_cqe(ring, &cqe);
  1183. if (ret < 0) {
  1184. fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
  1185. goto err;
  1186. }
  1187. ret = cqe->res;
  1188. if (ret == -EINVAL) {
  1189. no_multishot = 1;
  1190. return T_EXIT_SKIP;
  1191. }
  1192. if (!(cqe->flags & IORING_CQE_F_MORE)) {
  1193. fprintf(stderr, "%s: flag not set in cqe\n", __FUNCTION__);
  1194. goto err;
  1195. }
  1196. if (ret != -ETIME) {
  1197. fprintf(stderr, "%s: Timeout: %s\n", __FUNCTION__, strerror(-ret));
  1198. goto err;
  1199. }
  1200. io_uring_cqe_seen(ring, cqe);
  1201. }
  1202. sqe = io_uring_get_sqe(ring);
  1203. if (!sqe) {
  1204. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  1205. goto err;
  1206. }
  1207. io_uring_prep_timeout_remove(sqe, 1, 0);
  1208. io_uring_sqe_set_data(sqe, (void *) 2);
  1209. ret = io_uring_submit(ring);
  1210. if (ret <= 0) {
  1211. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  1212. goto err;
  1213. }
  1214. ret = io_uring_wait_cqe(ring, &cqe);
  1215. if (ret < 0) {
  1216. fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
  1217. goto err;
  1218. }
  1219. ret = cqe->res;
  1220. if (ret < 0) {
  1221. fprintf(stderr, "%s: remove failed: %s\n", __FUNCTION__, strerror(-ret));
  1222. goto err;
  1223. }
  1224. io_uring_cqe_seen(ring, cqe);
  1225. ret = io_uring_wait_cqe(ring, &cqe);
  1226. if (ret < 0) {
  1227. fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
  1228. goto err;
  1229. }
  1230. ret = cqe->res;
  1231. if (ret != -ECANCELED) {
  1232. fprintf(stderr, "%s: timeout canceled: %s %llu\n", __FUNCTION__, strerror(-ret), cqe->user_data);
  1233. goto err;
  1234. }
  1235. io_uring_cqe_seen(ring, cqe);
  1236. return 0;
  1237. err:
  1238. return 1;
  1239. }
  1240. static int test_timeout_multishot_nr(struct io_uring *ring)
  1241. {
  1242. struct io_uring_cqe *cqe;
  1243. struct io_uring_sqe *sqe;
  1244. struct __kernel_timespec ts;
  1245. int ret;
  1246. if (no_multishot)
  1247. return T_EXIT_SKIP;
  1248. sqe = io_uring_get_sqe(ring);
  1249. if (!sqe) {
  1250. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  1251. goto err;
  1252. }
  1253. msec_to_ts(&ts, TIMEOUT_MSEC);
  1254. io_uring_prep_timeout(sqe, &ts, 3, IORING_TIMEOUT_MULTISHOT);
  1255. io_uring_sqe_set_data(sqe, (void *) 1);
  1256. ret = io_uring_submit(ring);
  1257. if (ret <= 0) {
  1258. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  1259. goto err;
  1260. }
  1261. for (int i = 0; i < 3; i++) {
  1262. ret = io_uring_wait_cqe(ring, &cqe);
  1263. if (ret < 0) {
  1264. fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
  1265. goto err;
  1266. }
  1267. if (i < 2 && !(cqe->flags & IORING_CQE_F_MORE)) {
  1268. fprintf(stderr, "%s: flag not set in cqe\n", __FUNCTION__);
  1269. goto err;
  1270. }
  1271. if (i == 3 && (cqe->flags & IORING_CQE_F_MORE)) {
  1272. fprintf(stderr, "%s: flag set in cqe\n", __FUNCTION__);
  1273. goto err;
  1274. }
  1275. ret = cqe->res;
  1276. if (ret != -ETIME) {
  1277. fprintf(stderr, "%s: Timeout: %s\n", __FUNCTION__, strerror(-ret));
  1278. goto err;
  1279. }
  1280. io_uring_cqe_seen(ring, cqe);
  1281. }
  1282. msec_to_ts(&ts, 2 * TIMEOUT_MSEC);
  1283. ret = io_uring_wait_cqe_timeout(ring, &cqe, &ts);
  1284. if (ret != -ETIME) {
  1285. fprintf(stderr, "%s: wait completion timeout %s\n", __FUNCTION__, strerror(-ret));
  1286. goto err;
  1287. }
  1288. return 0;
  1289. err:
  1290. return 1;
  1291. }
  1292. static int test_timeout_multishot_overflow(struct io_uring *ring)
  1293. {
  1294. struct io_uring_cqe *cqe;
  1295. struct io_uring_sqe *sqe;
  1296. struct __kernel_timespec ts;
  1297. int ret;
  1298. if (no_multishot)
  1299. return T_EXIT_SKIP;
  1300. sqe = io_uring_get_sqe(ring);
  1301. if (!sqe) {
  1302. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  1303. goto err;
  1304. }
  1305. msec_to_ts(&ts, 10);
  1306. io_uring_prep_timeout(sqe, &ts, 0, IORING_TIMEOUT_MULTISHOT);
  1307. io_uring_sqe_set_data(sqe, (void *) 1);
  1308. ret = io_uring_submit(ring);
  1309. if (ret <= 0) {
  1310. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  1311. goto err;
  1312. }
  1313. ret = io_uring_wait_cqe(ring, &cqe);
  1314. if (ret < 0) {
  1315. fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
  1316. goto err;
  1317. }
  1318. ret = cqe->res;
  1319. if (ret != -ETIME) {
  1320. fprintf(stderr, "%s: Timeout: %s\n", __FUNCTION__, strerror(-ret));
  1321. goto err;
  1322. }
  1323. io_uring_cqe_seen(ring, cqe);
  1324. sleep(1);
  1325. if (!((*ring->sq.kflags) & IORING_SQ_CQ_OVERFLOW)) {
  1326. goto err;
  1327. }
  1328. /* multishot timer should be gone */
  1329. sqe = io_uring_get_sqe(ring);
  1330. if (!sqe) {
  1331. fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
  1332. goto err;
  1333. }
  1334. io_uring_prep_timeout_remove(sqe, 1, 0);
  1335. ret = io_uring_submit(ring);
  1336. if (ret <= 0) {
  1337. fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
  1338. goto err;
  1339. }
  1340. ret = io_uring_wait_cqe(ring, &cqe);
  1341. if (ret < 0) {
  1342. fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
  1343. goto err;
  1344. }
  1345. ret = cqe->res;
  1346. io_uring_cqe_seen(ring, cqe);
  1347. if (ret != -ETIME) {
  1348. fprintf(stderr, "%s: remove failed: %d %s\n", __FUNCTION__, ret, strerror(-ret));
  1349. goto err;
  1350. }
  1351. return 0;
  1352. err:
  1353. return 1;
  1354. }
  1355. int main(int argc, char *argv[])
  1356. {
  1357. struct io_uring ring, sqpoll_ring;
  1358. bool has_timeout_update, sqpoll;
  1359. struct io_uring_params p = { };
  1360. int ret;
  1361. if (argc > 1)
  1362. return 0;
  1363. ret = io_uring_queue_init_params(8, &ring, &p);
  1364. if (ret) {
  1365. fprintf(stderr, "ring setup failed\n");
  1366. return 1;
  1367. }
  1368. ret = io_uring_queue_init(8, &sqpoll_ring, IORING_SETUP_SQPOLL);
  1369. sqpoll = !ret;
  1370. ret = test_single_timeout(&ring);
  1371. if (ret) {
  1372. fprintf(stderr, "test_single_timeout failed\n");
  1373. return ret;
  1374. }
  1375. if (not_supported)
  1376. return 0;
  1377. ret = test_multi_timeout(&ring);
  1378. if (ret) {
  1379. fprintf(stderr, "test_multi_timeout failed\n");
  1380. return ret;
  1381. }
  1382. ret = test_single_timeout_abs(&ring);
  1383. if (ret) {
  1384. fprintf(stderr, "test_single_timeout_abs failed\n");
  1385. return ret;
  1386. }
  1387. ret = test_single_timeout_remove(&ring);
  1388. if (ret) {
  1389. fprintf(stderr, "test_single_timeout_remove failed\n");
  1390. return ret;
  1391. }
  1392. ret = test_single_timeout_remove_notfound(&ring);
  1393. if (ret) {
  1394. fprintf(stderr, "test_single_timeout_remove_notfound failed\n");
  1395. return ret;
  1396. }
  1397. ret = test_single_timeout_many(&ring);
  1398. if (ret) {
  1399. fprintf(stderr, "test_single_timeout_many failed\n");
  1400. return ret;
  1401. }
  1402. ret = test_single_timeout_nr(&ring, 1);
  1403. if (ret) {
  1404. fprintf(stderr, "test_single_timeout_nr(1) failed\n");
  1405. return ret;
  1406. }
  1407. ret = test_single_timeout_nr(&ring, 2);
  1408. if (ret) {
  1409. fprintf(stderr, "test_single_timeout_nr(2) failed\n");
  1410. return ret;
  1411. }
  1412. ret = test_multi_timeout_nr(&ring);
  1413. if (ret) {
  1414. fprintf(stderr, "test_multi_timeout_nr failed\n");
  1415. return ret;
  1416. }
  1417. ret = test_timeout_flags1(&ring);
  1418. if (ret) {
  1419. fprintf(stderr, "test_timeout_flags1 failed\n");
  1420. return ret;
  1421. }
  1422. ret = test_timeout_flags2(&ring);
  1423. if (ret) {
  1424. fprintf(stderr, "test_timeout_flags2 failed\n");
  1425. return ret;
  1426. }
  1427. ret = test_timeout_flags3(&ring);
  1428. if (ret) {
  1429. fprintf(stderr, "test_timeout_flags3 failed\n");
  1430. return ret;
  1431. }
  1432. ret = test_timeout_multishot(&ring);
  1433. if (ret && ret != T_EXIT_SKIP) {
  1434. fprintf(stderr, "test_timeout_multishot failed\n");
  1435. return ret;
  1436. }
  1437. ret = test_timeout_multishot_nr(&ring);
  1438. if (ret && ret != T_EXIT_SKIP) {
  1439. fprintf(stderr, "test_timeout_multishot_nr failed\n");
  1440. return ret;
  1441. }
  1442. /* io_uring_wait_cqe_timeout() may have left a timeout, reinit ring */
  1443. io_uring_queue_exit(&ring);
  1444. ret = io_uring_queue_init(8, &ring, 0);
  1445. if (ret) {
  1446. fprintf(stderr, "ring setup failed\n");
  1447. return 1;
  1448. }
  1449. ret = test_timeout_multishot_overflow(&ring);
  1450. if (ret && ret != T_EXIT_SKIP) {
  1451. fprintf(stderr, "test_timeout_multishot_overflow failed\n");
  1452. return ret;
  1453. }
  1454. /* io_uring_wait_cqe_timeout() may have left a timeout, reinit ring */
  1455. io_uring_queue_exit(&ring);
  1456. ret = io_uring_queue_init(8, &ring, 0);
  1457. if (ret) {
  1458. fprintf(stderr, "ring setup failed\n");
  1459. return 1;
  1460. }
  1461. ret = test_single_timeout_wait(&ring, &p);
  1462. if (ret) {
  1463. fprintf(stderr, "test_single_timeout_wait failed\n");
  1464. return ret;
  1465. }
  1466. /* io_uring_wait_cqes() may have left a timeout, reinit ring */
  1467. io_uring_queue_exit(&ring);
  1468. ret = io_uring_queue_init(8, &ring, 0);
  1469. if (ret) {
  1470. fprintf(stderr, "ring setup failed\n");
  1471. return 1;
  1472. }
  1473. ret = test_update_nonexistent_timeout(&ring);
  1474. has_timeout_update = (ret != -EINVAL);
  1475. if (has_timeout_update) {
  1476. if (ret) {
  1477. fprintf(stderr, "test_update_nonexistent_timeout failed\n");
  1478. return ret;
  1479. }
  1480. ret = test_update_invalid_flags(&ring);
  1481. if (ret) {
  1482. fprintf(stderr, "test_update_invalid_flags failed\n");
  1483. return ret;
  1484. }
  1485. ret = test_update_timeout(&ring, 0, false, false, false);
  1486. if (ret) {
  1487. fprintf(stderr, "test_update_timeout failed\n");
  1488. return ret;
  1489. }
  1490. ret = test_update_timeout(&ring, 1, false, false, false);
  1491. if (ret) {
  1492. fprintf(stderr, "test_update_timeout 1ms failed\n");
  1493. return ret;
  1494. }
  1495. ret = test_update_timeout(&ring, 1000, false, false, false);
  1496. if (ret) {
  1497. fprintf(stderr, "test_update_timeout 1s failed\n");
  1498. return ret;
  1499. }
  1500. ret = test_update_timeout(&ring, 0, true, true, false);
  1501. if (ret) {
  1502. fprintf(stderr, "test_update_timeout abs failed\n");
  1503. return ret;
  1504. }
  1505. ret = test_update_timeout(&ring, 0, false, true, false);
  1506. if (ret) {
  1507. fprintf(stderr, "test_update_timeout async failed\n");
  1508. return ret;
  1509. }
  1510. ret = test_update_timeout(&ring, 0, false, false, true);
  1511. if (ret) {
  1512. fprintf(stderr, "test_update_timeout linked failed\n");
  1513. return ret;
  1514. }
  1515. if (sqpoll) {
  1516. ret = test_update_timeout(&sqpoll_ring, 0, false, false,
  1517. false);
  1518. if (ret) {
  1519. fprintf(stderr, "test_update_timeout sqpoll"
  1520. "failed\n");
  1521. return ret;
  1522. }
  1523. }
  1524. }
  1525. /*
  1526. * this test must go last, it kills the ring
  1527. */
  1528. ret = test_single_timeout_exit(&ring);
  1529. if (ret) {
  1530. fprintf(stderr, "test_single_timeout_exit failed\n");
  1531. return ret;
  1532. }
  1533. ret = test_timeout_link_cancel();
  1534. if (ret) {
  1535. fprintf(stderr, "test_timeout_link_cancel failed\n");
  1536. return ret;
  1537. }
  1538. ret = test_not_failing_links();
  1539. if (ret) {
  1540. fprintf(stderr, "test_not_failing_links failed\n");
  1541. return ret;
  1542. }
  1543. if (sqpoll)
  1544. io_uring_queue_exit(&sqpoll_ring);
  1545. return 0;
  1546. }