Skip to content

Commit 3905136

Browse files
isilenceaxboe
authored andcommitted
io_uring: always do atomic put from iowq
io_uring always switches requests to atomic refcounting for iowq execution before there is any parallilism by setting REQ_F_REFCOUNT, and the flag is not cleared until the request completes. That should be fine as long as the compiler doesn't make up a non existing value for the flags, however KCSAN still complains when the request owner changes oter flag bits: BUG: KCSAN: data-race in io_req_task_cancel / io_wq_free_work ... read to 0xffff888117207448 of 8 bytes by task 3871 on cpu 0: req_ref_put_and_test io_uring/refs.h:22 [inline] Skip REQ_F_REFCOUNT checks for iowq, we know it's set. Reported-by: [email protected] Signed-off-by: Pavel Begunkov <[email protected]> Link: https://lore.kernel.org/r/d880bc27fb8c3209b54641be4ff6ac02b0e5789a.1743679736.git.asml.silence@gmail.com Signed-off-by: Jens Axboe <[email protected]>
1 parent 57ed58c commit 3905136

File tree

2 files changed

+8
-1
lines changed

2 files changed

+8
-1
lines changed

io_uring/io_uring.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1796,7 +1796,7 @@ struct io_wq_work *io_wq_free_work(struct io_wq_work *work)
17961796
struct io_kiocb *req = container_of(work, struct io_kiocb, work);
17971797
struct io_kiocb *nxt = NULL;
17981798

1799-
if (req_ref_put_and_test(req)) {
1799+
if (req_ref_put_and_test_atomic(req)) {
18001800
if (req->flags & IO_REQ_LINK_FLAGS)
18011801
nxt = io_req_find_next(req);
18021802
io_free_req(req);

io_uring/refs.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ static inline bool req_ref_inc_not_zero(struct io_kiocb *req)
1717
return atomic_inc_not_zero(&req->refs);
1818
}
1919

20+
static inline bool req_ref_put_and_test_atomic(struct io_kiocb *req)
21+
{
22+
WARN_ON_ONCE(!(data_race(req->flags) & REQ_F_REFCOUNT));
23+
WARN_ON_ONCE(req_ref_zero_or_close_to_overflow(req));
24+
return atomic_dec_and_test(&req->refs);
25+
}
26+
2027
static inline bool req_ref_put_and_test(struct io_kiocb *req)
2128
{
2229
if (likely(!(req->flags & REQ_F_REFCOUNT)))

0 commit comments

Comments
 (0)