[RFC,19/24] mm: add field to annotate vm_operations that support range locking
diff mbox series

Message ID 20200224203057.162467-20-walken@google.com
State New
Headers show
Series
  • Fine grained MM locking
Related show

Commit Message

Michel Lespinasse Feb. 24, 2020, 8:30 p.m. UTC
Add a fine_grained field to struct vm_operations_struct,
and set it in the filesystems we have converted to support range locking.

Signed-off-by: Michel Lespinasse <walken@google.com>
---
 fs/ext4/file.c     |  1 +
 include/linux/mm.h | 16 ++++++++++++++++
 mm/filemap.c       |  1 +
 mm/shmem.c         |  1 +
 4 files changed, 19 insertions(+)

Patch
diff mbox series

diff --git fs/ext4/file.c fs/ext4/file.c
index 6a7293a5cda2..8167fc7cc6ca 100644
--- fs/ext4/file.c
+++ fs/ext4/file.c
@@ -626,6 +626,7 @@  static const struct vm_operations_struct ext4_file_vm_ops = {
 	.fault		= ext4_filemap_fault,
 	.map_pages	= filemap_map_pages,
 	.page_mkwrite   = ext4_page_mkwrite,
+	.fine_grained	= true,
 };
 
 static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma)
diff --git include/linux/mm.h include/linux/mm.h
index 43b7121ae005..28b6af200214 100644
--- include/linux/mm.h
+++ include/linux/mm.h
@@ -526,6 +526,22 @@  struct vm_operations_struct {
 	 */
 	struct page *(*find_special_page)(struct vm_area_struct *vma,
 					  unsigned long addr);
+
+	/*
+	 * fine_grained indicates that the vm_operations support
+	 * fine grained mm locking.
+	 * - The methods may be called with a fine grained range lock
+	 *   covering a PMD sized region around the fault address;
+	 * - The range lock does not  protect against concurrent access
+	 *   to per-mmmm structures, so an appropriate lock must be used
+	 *   for such cases
+	 *   (such as mm_vma_lock() for accessing the vma rbtree);
+	 * - if dropping mmap_sem, the vmf->range must be used
+	 *   to release the specific locked range only;
+	 * - vmf->vma only holds a copy of the original vma.
+	 *   Any persistent vma updates must first look up the actual vma.
+	 */
+	bool fine_grained;
 };
 
 static inline void vma_init(struct vm_area_struct *vma, struct mm_struct *mm)
diff --git mm/filemap.c mm/filemap.c
index 7827de7b356c..c9f95ca5737c 100644
--- mm/filemap.c
+++ mm/filemap.c
@@ -2699,6 +2699,7 @@  const struct vm_operations_struct generic_file_vm_ops = {
 	.fault		= filemap_fault,
 	.map_pages	= filemap_map_pages,
 	.page_mkwrite	= filemap_page_mkwrite,
+	.fine_grained	= true,
 };
 
 /* This is used for a general mmap of a disk file */
diff --git mm/shmem.c mm/shmem.c
index 8793e8cc1a48..32ec4ad05df5 100644
--- mm/shmem.c
+++ mm/shmem.c
@@ -3865,6 +3865,7 @@  static const struct vm_operations_struct shmem_vm_ops = {
 	.set_policy     = shmem_set_policy,
 	.get_policy     = shmem_get_policy,
 #endif
+	.fine_grained	= true,
 };
 
 int shmem_init_fs_context(struct fs_context *fc)