From f713350f74dbeb333ff1ad2790cb60381ceaf463 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 9 Sep 2013 15:16:28 -0600 Subject: [PATCH] Fix broken requeue of io_us Suresh reports: ----- Does a requeued io_u work get submitted again through __get_io_u() ? If so, the io_u item is taken out of requeue list & then the io_u->file is set to NULL. We don't make a distinction about item being already setup Vs a new io_u in __get_io_u(). In get_io_u(), when an io_u may come out of requeue list, we depend on io_u->file to be non NULL to detect the work as old pending one. Am I missing something here or is this a bug? 1274 io_u = __get_io_u(td); 1275 if (!io_u) { 1276 dprint(FD_IO, "__get_io_u failed\n"); 1277 return NULL; 1278 } 1279 1280 if (check_get_verify(td, io_u)) 1281 goto out; 1282 if (check_get_trim(td, io_u)) 1283 goto out; 1284 1285 /* 1286 * from a requeue, io_u already setup 1287 */ 1288 if (io_u->file) 1289 goto out; 1290 "io_u.c" line 1286 of 1667 --77%-- col 3-10 1130 struct io_u *__get_io_u(struct thread_data *td) 1131 { 1132 struct io_u *io_u; 1133 1134 td_io_u_lock(td); 1135 1136 again: 1137 if (!io_u_rempty(&td->io_u_requeues)) 1138 io_u = io_u_rpop(&td->io_u_requeues); 1139 else if (!io_u_qempty(&td->io_u_freelist)) 1140 io_u = io_u_qpop(&td->io_u_freelist); 1141 1142 if (io_u) { 1143 io_u->buflen = 0; 1144 io_u->resid = 0; 1145 io_u->file = NULL; 1146 io_u->end_io = NULL; 1147 } "io_u.c" line 1130 of 1667 --67%-- col 1 ----- We want a retry of a requeue to be identical, not some new chunk (and drop the latter one on the floor). This got broken with the introduction of the rings instead of lists, where a single if section was split into two. Signed-off-by: Jens Axboe --- io_u.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/io_u.c b/io_u.c index c50a17df..7df57aa8 100644 --- a/io_u.c +++ b/io_u.c @@ -1136,10 +1136,9 @@ struct io_u *__get_io_u(struct thread_data *td) again: if (!io_u_rempty(&td->io_u_requeues)) io_u = io_u_rpop(&td->io_u_requeues); - else if (!io_u_qempty(&td->io_u_freelist)) + else if (!io_u_qempty(&td->io_u_freelist)) { io_u = io_u_qpop(&td->io_u_freelist); - if (io_u) { io_u->buflen = 0; io_u->resid = 0; io_u->file = NULL; -- 2.25.1