diff options
author | Jens Axboe <axboe@kernel.dk> | 2020-12-17 17:53:33 +0300 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2020-12-17 17:53:33 +0300 |
commit | 4bc4a912534a72f1c96f483448f0be16e5a48063 (patch) | |
tree | 9db2abd90af8c6c3c3c9ec9d94fbf649ba7d7b34 /fs/io_uring.c | |
parent | a146468d76e0462393a3e15b77b8b3ede60e2d06 (diff) | |
download | linux-4bc4a912534a72f1c96f483448f0be16e5a48063.tar.xz |
io_uring: hold mmap_sem for mm->locked_vm manipulation
The kernel doesn't seem to have clear rules around this, but various
spots are using the mmap_sem to serialize access to modifying the
locked_vm count. Play it safe and lock the mm for write when accounting
or unaccounting locked memory.
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'fs/io_uring.c')
-rw-r--r-- | fs/io_uring.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c index 6a4560c9ed9a..2d07d35e7262 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -8157,10 +8157,13 @@ static void io_unaccount_mem(struct io_ring_ctx *ctx, unsigned long nr_pages, __io_unaccount_mem(ctx->user, nr_pages); if (ctx->mm_account) { - if (acct == ACCT_LOCKED) + if (acct == ACCT_LOCKED) { + mmap_write_lock(ctx->mm_account); ctx->mm_account->locked_vm -= nr_pages; - else if (acct == ACCT_PINNED) + mmap_write_unlock(ctx->mm_account); + }else if (acct == ACCT_PINNED) { atomic64_sub(nr_pages, &ctx->mm_account->pinned_vm); + } } } @@ -8176,10 +8179,13 @@ static int io_account_mem(struct io_ring_ctx *ctx, unsigned long nr_pages, } if (ctx->mm_account) { - if (acct == ACCT_LOCKED) + if (acct == ACCT_LOCKED) { + mmap_write_lock(ctx->mm_account); ctx->mm_account->locked_vm += nr_pages; - else if (acct == ACCT_PINNED) + mmap_write_unlock(ctx->mm_account); + } else if (acct == ACCT_PINNED) { atomic64_add(nr_pages, &ctx->mm_account->pinned_vm); + } } return 0; |