Commit 5b7aa38
io_uring: fix potential req refcount underflow
For multishot mode, there may be cases like:
iowq original context
io_poll_add
_arm_poll()
mask = vfs_poll() is not 0
if mask
(2) io_poll_complete()
compl_unlock
(interruption happens
tw queued to original
context)
io_poll_task_func()
compl_lock
(3) done = io_poll_complete() is true
compl_unlock
put req ref
(1) if (poll->flags & EPOLLONESHOT)
put req ref
EPOLLONESHOT flag in (1) may be from (2) or (3), so there are multiple
combinations that can cause ref underfow.
Let's address it by:
- check the return value in (2) as done
- change (1) to if (done)
in this way, we only do ref put in (1) if 'oneshot flag' is from
(2)
- do poll.done check in io_poll_task_func(), so that we won't put ref
for the second time.
Signed-off-by: Hao Xu <haoxu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20210922101238.7177-4-haoxu@linux.alibaba.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>1 parent a62682f commit 5b7aa38
1 file changed
Lines changed: 7 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5367 | 5367 | | |
5368 | 5368 | | |
5369 | 5369 | | |
| 5370 | + | |
| 5371 | + | |
| 5372 | + | |
| 5373 | + | |
5370 | 5374 | | |
5371 | 5375 | | |
5372 | 5376 | | |
| |||
5830 | 5834 | | |
5831 | 5835 | | |
5832 | 5836 | | |
| 5837 | + | |
5833 | 5838 | | |
5834 | 5839 | | |
5835 | 5840 | | |
| |||
5838 | 5843 | | |
5839 | 5844 | | |
5840 | 5845 | | |
5841 | | - | |
| 5846 | + | |
5842 | 5847 | | |
5843 | 5848 | | |
5844 | 5849 | | |
5845 | 5850 | | |
5846 | 5851 | | |
5847 | | - | |
| 5852 | + | |
5848 | 5853 | | |
5849 | 5854 | | |
5850 | 5855 | | |
| |||
0 commit comments