@@ -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)
@@ -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)
@@ -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 */
@@ -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)
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(+)