io_uring: file set registration should use interruptible waits
authorJens Axboe <axboe@kernel.dk>
Wed, 8 Jan 2020 15:26:07 +0000 (08:26 -0700)
committerJens Axboe <axboe@kernel.dk>
Tue, 21 Jan 2020 00:04:04 +0000 (17:04 -0700)
If an application attempts to register a set with unbounded requests
pending, we can be stuck here forever if they don't complete. We can
make this wait interruptible, and just abort if we get signaled.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
fs/io_uring.c

index 00426b686092b36e9c476e1de9efc50293c46e9d..2c036972930fee5ee0218abb50b063350c0775c2 100644 (file)
@@ -6524,8 +6524,13 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
                 * after we've killed the percpu ref.
                 */
                mutex_unlock(&ctx->uring_lock);
-               wait_for_completion(&ctx->completions[0]);
+               ret = wait_for_completion_interruptible(&ctx->completions[0]);
                mutex_lock(&ctx->uring_lock);
+               if (ret) {
+                       percpu_ref_resurrect(&ctx->refs);
+                       ret = -EINTR;
+                       goto out;
+               }
        }
 
        switch (opcode) {
@@ -6571,8 +6576,9 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
        if (opcode != IORING_UNREGISTER_FILES &&
            opcode != IORING_REGISTER_FILES_UPDATE) {
                /* bring the ctx back to life */
-               reinit_completion(&ctx->completions[0]);
                percpu_ref_reinit(&ctx->refs);
+out:
+               reinit_completion(&ctx->completions[0]);
        }
        return ret;
 }