diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2019-10-16 15:03:50 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2022-04-17 15:18:37 -0400 |
commit | d2f11a20a0dc3ea7ad4365ea806ebeda53df8afd (patch) | |
tree | 98567a5872470924d9156104075be3baa134233b | |
parent | ec262709d3e46ff85e0e0de4d1c5d48580aab6e2 (diff) |
sched: Add task_struct->faults_disabled_mapping
This is needed to fix a page cache coherency issue with O_DIRECT writes.
O_DIRECT writes (and other filesystem operations that modify file data
while bypassing the page cache) need to shoot down ranges of the page
cache - and additionally, need locking to prevent those pages from
pulled back in.
But O_DIRECT writes invoke the page fault handler (via get_user_pages),
and the page fault handler will need to take that same lock - this is a
classic recursive deadlock if userspace has mmaped the file they're DIO
writing to and uses those pages for the buffer to write from, and it's a
lock ordering deadlock in general.
Thus we need a way to signal from the dio code to the page fault handler
when we already are holding the pagecache add lock on an address space -
this patch just adds a member to task_struct for this purpose. For now
only bcachefs is implementing this locking, though it may be moved out
of bcachefs and made available to other filesystems in the future.
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r-- | include/linux/sched.h | 1 | ||||
-rw-r--r-- | init/init_task.c | 1 |
2 files changed, 2 insertions, 0 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index 75ba8aa60248..85e51ba9714b 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -859,6 +859,7 @@ struct task_struct { struct mm_struct *mm; struct mm_struct *active_mm; + struct address_space *faults_disabled_mapping; /* Per-thread vma caching: */ struct vmacache vmacache; diff --git a/init/init_task.c b/init/init_task.c index 73cc8f03511a..3e3aed110153 100644 --- a/init/init_task.c +++ b/init/init_task.c @@ -85,6 +85,7 @@ struct task_struct init_task .nr_cpus_allowed= NR_CPUS, .mm = NULL, .active_mm = &init_mm, + .faults_disabled_mapping = NULL, .restart_block = { .fn = do_no_restart_syscall, }, |