On 1/9/2020 4:17 PM, Dmitrii Dolgov wrote: > With combination of --fixedbufs and an old version of fio I've managed > to get a strange situation, when doing io_iopoll_complete NULL pointer > dereference on file_data was caused in io_free_req_many. Interesting > enough, the very same configuration doesn't fail on a newest version of > fio (the old one is fc220349e4514, the new one is 2198a6b5a9f4), but I > guess it still makes sense to have this check if it's possible to craft > such request to io_uring. I didn't looked up why it could become NULL in the first place, but the problem is probably deeper. 1. I don't see why it puts @rb->to_free @file_data->refs, even though there could be non-fixed reqs. It needs to count REQ_F_FIXED_FILE reqs and put only as much. 2. Jens, there is another line bothering me, could you take a look? io_free_req_many() { ... if (req->flags & REQ_F_INFLIGHT) ...; else rb->reqs[i] = NULL; ... } It zeroes rb->reqs[i], calls __io_req_aux_free(), but did not free memory for the request itself. Is it as intended? > > More details about configuration: > > [global] > filename=/dev/vda > rw=randread > bs=256k > direct=1 > time_based=1 > randrepeat=1 > gtod_reduce=1 > > [fiotest] > > fio test.fio \ > --readonly \ > --ioengine=io_uring \ > --iodepth 1024 \ > --fixedbufs \ > --hipri \ > --numjobs=1 \ > --runtime=10 > > Signed-off-by: Dmitrii Dolgov <9erthalion6@xxxxxxxxx> > --- > fs/io_uring.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > I'm not entirely sure if my analysis is correct, but since this change > fixes the issue for me, I've decided to post it. > > diff --git a/fs/io_uring.c b/fs/io_uring.c > index c770c2c0eb52..c5e69dfc0221 100644 > --- a/fs/io_uring.c > +++ b/fs/io_uring.c > @@ -1232,7 +1232,8 @@ static void io_free_req_many(struct io_ring_ctx *ctx, struct req_batch *rb) > do_free: > kmem_cache_free_bulk(req_cachep, rb->to_free, rb->reqs); > percpu_ref_put_many(&ctx->refs, rb->to_free); > - percpu_ref_put_many(&ctx->file_data->refs, rb->to_free); > + if (ctx->file_data) > + percpu_ref_put_many(&ctx->file_data->refs, rb->to_free); > rb->to_free = rb->need_iter = 0; > } > > -- Pavel Begunkov