diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2019-10-16 15:03:50 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2022-10-03 22:49:30 -0400 |
commit | d7d089aeab4b3f0f0d54a54b695d747bd930f731 (patch) | |
tree | a87e760265456f1a7d74345b663abae49f366b90 | |
parent | 32d6a6d3629acc5614e166c8d2ec9a4fecadf6d8 (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 e7b2f8a5c711..4def6fae37b8 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 ff6c4b9bfe6b..f703116e0523 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, }, |