提交 04dea516 编写于 作者: J Jens Axboe 提交者: Cheng Jian

io_uring: account fixed file references correctly in batch

mainline inclusion
from mainline-5.6-rc1
commit 10fef4be
category: feature
bugzilla: https://bugzilla.openeuler.org/show_bug.cgi?id=27
CVE: NA
---------------------------

We can't assume that the whole batch has fixed files in it. If it's a
mix, or none at all, then we can end up doing a ref put that either
messes up accounting, or causes an oops if we have no fixed files at
all.

Also ensure we free requests properly between inflight accounted and
normal requests.

Fixes: 82c721577011 ("io_uring: extend batch freeing to cover more cases")
Reported-by: NDmitrii Dolgov <9erthalion6@gmail.com>
Reported-by: NPavel Begunkov <asml.silence@gmail.com>
Tested-by: NDmitrii Dolgov <9erthalion6@gmail.com>
Signed-off-by: NJens Axboe <axboe@kernel.dk>
Signed-off-by: Nyangerkun <yangerkun@huawei.com>
Reviewed-by: Nzhangyi (F) <yi.zhang@huawei.com>
Signed-off-by: NCheng Jian <cj.chengjian@huawei.com>
上级 11967b48
...@@ -1202,21 +1202,24 @@ struct req_batch { ...@@ -1202,21 +1202,24 @@ struct req_batch {
static void io_free_req_many(struct io_ring_ctx *ctx, struct req_batch *rb) static void io_free_req_many(struct io_ring_ctx *ctx, struct req_batch *rb)
{ {
int fixed_refs = rb->to_free;
if (!rb->to_free) if (!rb->to_free)
return; return;
if (rb->need_iter) { if (rb->need_iter) {
int i, inflight = 0; int i, inflight = 0;
unsigned long flags; unsigned long flags;
fixed_refs = 0;
for (i = 0; i < rb->to_free; i++) { for (i = 0; i < rb->to_free; i++) {
struct io_kiocb *req = rb->reqs[i]; struct io_kiocb *req = rb->reqs[i];
if (req->flags & REQ_F_FIXED_FILE) if (req->flags & REQ_F_FIXED_FILE) {
req->file = NULL; req->file = NULL;
fixed_refs++;
}
if (req->flags & REQ_F_INFLIGHT) if (req->flags & REQ_F_INFLIGHT)
inflight++; inflight++;
else
rb->reqs[i] = NULL;
__io_req_aux_free(req); __io_req_aux_free(req);
} }
if (!inflight) if (!inflight)
...@@ -1226,7 +1229,7 @@ static void io_free_req_many(struct io_ring_ctx *ctx, struct req_batch *rb) ...@@ -1226,7 +1229,7 @@ static void io_free_req_many(struct io_ring_ctx *ctx, struct req_batch *rb)
for (i = 0; i < rb->to_free; i++) { for (i = 0; i < rb->to_free; i++) {
struct io_kiocb *req = rb->reqs[i]; struct io_kiocb *req = rb->reqs[i];
if (req) { if (req->flags & REQ_F_INFLIGHT) {
list_del(&req->inflight_entry); list_del(&req->inflight_entry);
if (!--inflight) if (!--inflight)
break; break;
...@@ -1239,8 +1242,9 @@ static void io_free_req_many(struct io_ring_ctx *ctx, struct req_batch *rb) ...@@ -1239,8 +1242,9 @@ static void io_free_req_many(struct io_ring_ctx *ctx, struct req_batch *rb)
} }
do_free: do_free:
kmem_cache_free_bulk(req_cachep, rb->to_free, rb->reqs); kmem_cache_free_bulk(req_cachep, rb->to_free, rb->reqs);
if (fixed_refs)
percpu_ref_put_many(&ctx->file_data->refs, fixed_refs);
percpu_ref_put_many(&ctx->refs, rb->to_free); percpu_ref_put_many(&ctx->refs, rb->to_free);
percpu_ref_put_many(&ctx->file_data->refs, rb->to_free);
rb->to_free = rb->need_iter = 0; rb->to_free = rb->need_iter = 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册