Skip to content

Commit c1ef57a

Browse files
committed
Merge tag 'io_uring-5.6-2020-02-05' of git://git.kernel.dk/linux-block
Pull io_uring updates from Jens Axboe: "Some later fixes for io_uring: - Small cleanup series from Pavel - Belt and suspenders build time check of sqe size and layout (Stefan) - Addition of ->show_fdinfo() on request of Jann Horn, to aid in understanding mapped personalities - eventfd recursion/deadlock fix, for both io_uring and aio - Fixup for send/recv handling - Fixup for double deferral of read/write request - Fix for potential double completion event for close request - Adjust fadvise advice async/inline behavior - Fix for shutdown hang with SQPOLL thread - Fix for potential use-after-free of fixed file table" * tag 'io_uring-5.6-2020-02-05' of git://git.kernel.dk/linux-block: io_uring: cleanup fixed file data table references io_uring: spin for sq thread to idle on shutdown aio: prevent potential eventfd recursion on poll io_uring: put the flag changing code in the same spot io_uring: iterate req cache backwards io_uring: punt even fadvise() WILLNEED to async context io_uring: fix sporadic double CQE entry for close io_uring: remove extra ->file check io_uring: don't map read/write iovec potentially twice io_uring: use the proper helpers for io_send/recv io_uring: prevent potential eventfd recursion on poll eventfd: track eventfd_signal() recursion depth io_uring: add BUILD_BUG_ON() to assert the layout of struct io_uring_sqe io_uring: add ->show_fdinfo() for the io_uring file descriptor
2 parents ed535f2 + 2faf852 commit c1ef57a

File tree

4 files changed

+251
-52
lines changed

4 files changed

+251
-52
lines changed

fs/aio.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1610,6 +1610,14 @@ static int aio_fsync(struct fsync_iocb *req, const struct iocb *iocb,
16101610
return 0;
16111611
}
16121612

1613+
static void aio_poll_put_work(struct work_struct *work)
1614+
{
1615+
struct poll_iocb *req = container_of(work, struct poll_iocb, work);
1616+
struct aio_kiocb *iocb = container_of(req, struct aio_kiocb, poll);
1617+
1618+
iocb_put(iocb);
1619+
}
1620+
16131621
static void aio_poll_complete_work(struct work_struct *work)
16141622
{
16151623
struct poll_iocb *req = container_of(work, struct poll_iocb, work);
@@ -1674,6 +1682,8 @@ static int aio_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
16741682
list_del_init(&req->wait.entry);
16751683

16761684
if (mask && spin_trylock_irqsave(&iocb->ki_ctx->ctx_lock, flags)) {
1685+
struct kioctx *ctx = iocb->ki_ctx;
1686+
16771687
/*
16781688
* Try to complete the iocb inline if we can. Use
16791689
* irqsave/irqrestore because not all filesystems (e.g. fuse)
@@ -1683,8 +1693,14 @@ static int aio_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
16831693
list_del(&iocb->ki_list);
16841694
iocb->ki_res.res = mangle_poll(mask);
16851695
req->done = true;
1686-
spin_unlock_irqrestore(&iocb->ki_ctx->ctx_lock, flags);
1687-
iocb_put(iocb);
1696+
if (iocb->ki_eventfd && eventfd_signal_count()) {
1697+
iocb = NULL;
1698+
INIT_WORK(&req->work, aio_poll_put_work);
1699+
schedule_work(&req->work);
1700+
}
1701+
spin_unlock_irqrestore(&ctx->ctx_lock, flags);
1702+
if (iocb)
1703+
iocb_put(iocb);
16881704
} else {
16891705
schedule_work(&req->work);
16901706
}

fs/eventfd.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include <linux/seq_file.h>
2525
#include <linux/idr.h>
2626

27+
DEFINE_PER_CPU(int, eventfd_wake_count);
28+
2729
static DEFINE_IDA(eventfd_ida);
2830

2931
struct eventfd_ctx {
@@ -60,12 +62,25 @@ __u64 eventfd_signal(struct eventfd_ctx *ctx, __u64 n)
6062
{
6163
unsigned long flags;
6264

65+
/*
66+
* Deadlock or stack overflow issues can happen if we recurse here
67+
* through waitqueue wakeup handlers. If the caller users potentially
68+
* nested waitqueues with custom wakeup handlers, then it should
69+
* check eventfd_signal_count() before calling this function. If
70+
* it returns true, the eventfd_signal() call should be deferred to a
71+
* safe context.
72+
*/
73+
if (WARN_ON_ONCE(this_cpu_read(eventfd_wake_count)))
74+
return 0;
75+
6376
spin_lock_irqsave(&ctx->wqh.lock, flags);
77+
this_cpu_inc(eventfd_wake_count);
6478
if (ULLONG_MAX - ctx->count < n)
6579
n = ULLONG_MAX - ctx->count;
6680
ctx->count += n;
6781
if (waitqueue_active(&ctx->wqh))
6882
wake_up_locked_poll(&ctx->wqh, EPOLLIN);
83+
this_cpu_dec(eventfd_wake_count);
6984
spin_unlock_irqrestore(&ctx->wqh.lock, flags);
7085

7186
return n;

0 commit comments

Comments
 (0)