History

io_uring: fix counter inc/dec mismatch in async_list

We could queue a work for each req in defer and link list without increasing async_list->cnt, so we shouldn't decrease it while exiting from workqueue as well if we didn't process the req in async list. Thanks to Jens Axboe <axboe@kernel.dk> for his guidance.

Zhengyuan Liu committed 7 years ago

Commit f7b76ac1 parent c56cbfa1 file · +8 −1Browse files

Unified · Split

fs/io_uring.c+8−1
@@ -333,7 +333,8 @@ struct io_kiocb { · 332 unmodified lines
333333 #define REQ_F_IO_DRAIN 16 /* drain existing IO first */
334334 #define REQ_F_IO_DRAINED 32 /* drain done */
335335 #define REQ_F_LINK 64 /* linked sqes */
336−#define REQ_F_FAIL_LINK 128 /* fail rest of links */
336+#define REQ_F_LINK_DONE 128 /* linked sqes done */
337+#define REQ_F_FAIL_LINK 256 /* fail rest of links */
337338 u64 user_data;
338339 u32 result;
339340 u32 sequence;
@@ -632,6 +633,7 @@ static void io_req_link_next(struct io_kiocb *req) · 292 unmodified lines
632633 nxt->flags |= REQ_F_LINK;
633634 }
634635
636+ nxt->flags |= REQ_F_LINK_DONE;
635637 INIT_WORK(&nxt->work, io_sq_wq_submit_work);
636638 queue_work(req->ctx->sqo_wq, &nxt->work);
637639 }
@@ -1844,6 +1846,10 @@ restart: · 1206 unmodified lines
18441846 /* async context always use a copy of the sqe */
18451847 kfree(sqe);
18461848
1849+ /* req from defer and link list needn't decrease async cnt */
1850+ if (req->flags & (REQ_F_IO_DRAINED | REQ_F_LINK_DONE))
1851+ goto out;
1852+
18471853 if (!async_list)
18481854 break;
18491855 if (!list_empty(&req_list)) {
@@ -1891,6 +1897,7 @@ restart: · 41 unmodified lines
18911897 }
18921898 }
18931899
1900+out:
18941901 if (cur_mm) {
18951902 set_fs(old_fs);
18961903 unuse_mm(cur_mm);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t