mm: move ->mremap() from file_operations to vm_operations_struct
Subsystems (5)
cover mm: move ->mremap() from file_operations to vm_operations_struct
Quoted 7 lines · Andy Lutomirski
Quoted 5 lines · Oleg Nesterov
I never understood why ->mremap() lives in
file_operations, not invm_operations_struct. To mevma->vm_file->f_opinmove_vma()just looks strange,vma->vm_ops->mremap(new_vma)looks "obviously better".
Quoted 8 lines
Quoted 5 lines
And afaics more useful. CRIU remaps vdso, but this does not update
mm->context.vdso. OK, probably this does not matter currently, CRIU can't c/r the compat tasks, and 64-bit apps do not use context.vdso. Afaics. Still, I think we might want to havespecial_mapping_remap()and we can't do this because ->vm_file == NULL.I would like this. Then I could clean up and resubmit my patch to keep context.vdso up to date.
Cough... where can I find this patch ? ;)
Quoted 1 line
Oleg, can you let me know what patch, if any, I should be reviewing?
This one, it looks really trivial. And of course I will appreciate it if you can review the special_mapping_fault() fixes.
The change in move_vma() textually depends on another patch I sent,
[PATCH 1/4] mremap: don't leak new_vma if f_op->mremap() fails http://marc.info/?l=linux-kernel&m=143475603713622
Oleg.
PATCH 1/1 mm: move ->mremap() from file_operations to vm_operations_struct
vma->vm_ops->mremap() looks more natural and clean in move_vma(), and this way ->mremap() can have more users. Say, vdso.
--- fs/aio.c | 25 ++++++++++++++++--------- include/linux/fs.h | 1 - include/linux/mm.h | 1 + mm/mremap.c | 4 ++-- 4 files changed, 19 insertions(+), 12 deletions(-)
fs/aio.c +16 -9
@@ -308,15 +308,9 @@ static void aio_free_ring(struct kioctx *ctx) } } -static int aio_ring_mmap (struct file *file,struct vm_area_struct *vma) -{ - vma->vm_flags |=VM_DONTEXPAND ; - vma->vm_ops = &generic_file_vm_ops; -return 0 ; -} - -static int aio_ring_remap (struct file *file,struct vm_area_struct *vma) +static int aio_ring_remap (struct vm_area_struct *vma) { +struct file *file = vma->vm_file;struct mm_struct *mm = vma->vm_mm;struct kioctx_table *table;int i, res = -EINVAL ;
@@ -339,9 +333,22 @@ static int aio_ring_remap(struct file *file, struct vm_area_struct *vma)return res; } +static const struct vm_operations_struct aio_ring_vm_ops = { + .mremap = aio_ring_remap, + .fault = filemap_fault, + .map_pages = filemap_map_pages, + .page_mkwrite = filemap_page_mkwrite, +}; + +static int aio_ring_mmap (struct file *file,struct vm_area_struct *vma) +{ + vma->vm_flags |=VM_DONTEXPAND ; + vma->vm_ops = &aio_ring_vm_ops; +return 0 ; +} +static const struct file_operations aio_ring_fops = { .mmap = aio_ring_mmap, - .mremap = aio_ring_remap, };#if IS_ENABLED (CONFIG_MIGRATION )
include/linux/fs.h +0 -1
@@ -1582,7 +1582,6 @@ struct file_operations {long (*unlocked_ioctl) (struct file *,unsigned int ,unsigned long );long (*compat_ioctl) (struct file *,unsigned int ,unsigned long );int (*mmap) (struct file *,struct vm_area_struct *); -int (*mremap)(struct file *,struct vm_area_struct *);int (*open) (struct inode *,struct file *);int (*flush) (struct file *,fl_owner_t id);int (*release) (struct inode *,struct file *);
include/linux/mm.h +1 -0
@@ -244,6 +244,7 @@ struct vm_fault {struct vm_operations_struct {void (*open)(struct vm_area_struct * area);void (*close)(struct vm_area_struct * area); +int (*mremap)(struct vm_area_struct * area);int (*fault)(struct vm_area_struct *vma,struct vm_fault *vmf);void (*map_pages)(struct vm_area_struct *vma,struct vm_fault *vmf);
mm/mremap.c +2 -2
@@ -276,8 +276,8 @@ static unsigned long move_vma(struct vm_area_struct *vma, need_rmap_locks);if (moved_len < old_len) { err = -ENOMEM ; - }else if (vma->vm_file && vma->vm_file->f_op->mremap) { - err = vma->vm_file->f_op->mremap (vma->vm_file, new_vma); + }else if (vma->vm_ops && vma->vm_ops->mremap) { + err = vma->vm_ops->mremap (new_vma); }if (unlikely (err)) {
Signature · 1 line
1.5.5.1
Quoted 9 lines · Oleg Nesterov
vma->vm_ops->mremap()looks more natural and clean inmove_vma(), and this way ->mremap() can have more users. Say, vdso.Signed-off-by Oleg Nesterov <[email protected]>--- fs/aio.c | 25 ++++++++++++++++--------- include/linux/fs.h | 1 - include/linux/mm.h | 1 + mm/mremap.c | 4 ++--
Please, update Documentation/filesystems/Locking.
Quoted 9 lines
4 files changed, 19 insertions(+), 12 deletions(-)fs/aio.c +0
-0@@ -308,15 +308,9 @@ static void aio_free_ring(struct kioctx *ctx) } }
fs/aio.c static void aio_free_ring(struct kioctx *ctx) · line 311
Quoted 10 lines
fs/aio.c +1
-8-static int aio_ring_mmap (struct file *file,struct vm_area_struct *vma) -{ - vma->vm_flags |=VM_DONTEXPAND ; - vma->vm_ops = &generic_file_vm_ops; -return 0 ; -} - -static int aio_ring_remap (struct file *file,struct vm_area_struct *vma) +static int aio_ring_remap (struct vm_area_struct *vma)
I guess aio_ring_mremap() would be a better name.
Quoted 5 lines
fs/aio.c +1
-0{ +struct file *file = vma->vm_file;struct mm_struct *mm = vma->vm_mm;struct kioctx_table *table;int i, res = -EINVAL ;
Signature · 1 line
Kirill A. Shutemov
Quoted 5 lines · Kirill A. Shutemov
Quoted 3 lines · Oleg Nesterov
vma->vm_ops->mremap()looks more natural and clean inmove_vma(), and this way ->mremap() can have more users. Say, vdso.
Quoted 8 lines
Quoted 6 lines
Signed-off-by Oleg Nesterov <[email protected]>--- fs/aio.c | 25 ++++++++++++++++--------- include/linux/fs.h | 1 - include/linux/mm.h | 1 + mm/mremap.c | 4 ++--Please, update
Documentation/filesystems/Locking.
OK, thanks, will do.
Quoted 4 lines
fs/aio.c static void aio_free_ring(struct kioctx *ctx) · line 311
Quoted 2 lines
fs/aio.c +1
-1-static int aio_ring_remap (struct file *file,struct vm_area_struct *vma) +static int aio_ring_remap (struct vm_area_struct *vma)I guess
aio_ring_mremap()would be a better name.
Yes, agreed.
OK, I'll wait for other comments then send v2 with these changes.
Oleg.
Quoted 14 lines · Oleg Nesterov
Quoted 13 lines · Andy Lutomirski
Quoted 10 lines · Oleg Nesterov
I never understood why ->mremap() lives in
file_operations, not invm_operations_struct. To mevma->vm_file->f_opinmove_vma()just looks strange,vma->vm_ops->mremap(new_vma)looks "obviously better".And afaics more useful. CRIU remaps vdso, but this does not update
mm->context.vdso. OK, probably this does not matter currently, CRIU can't c/r the compat tasks, and 64-bit apps do not use context.vdso. Afaics. Still, I think we might want to havespecial_mapping_remap()and we can't do this because ->vm_file == NULL.
Quoted 5 lines
Quoted 2 lines
I would like this. Then I could clean up and resubmit my patch to keep context.vdso up to date.
Cough... where can I find this patch ? ;)
https://git.kernel.org/cgit/linux/kernel/git/luto/linux.git/log/?h=vdso/vma_tracking
--Andy
Quoted 3 lines · Oleg Nesterov
vma->vm_ops->mremap()looks more natural and clean inmove_vma(), and this way ->mremap() can have more users. Say, vdso.
Looks generally reasonable.
--Andy
Quoted 4 lines · Oleg Nesterov
vma->vm_ops->mremap()looks more natural and clean inmove_vma(), and this way ->mremap() can have more users. Say, vdso.Signed-off-by Oleg Nesterov <[email protected]>
Looks-good-to: /me :) Thanks!
Quoted 16 lines · Andy Lutomirski
Quoted 14 lines · Oleg Nesterov
Quoted 13 lines · Andy Lutomirski
Quoted 10 lines · Oleg Nesterov
I never understood why ->mremap() lives in
file_operations, not invm_operations_struct. To mevma->vm_file->f_opinmove_vma()just looks strange,vma->vm_ops->mremap(new_vma)looks "obviously better".And afaics more useful. CRIU remaps vdso, but this does not update
mm->context.vdso. OK, probably this does not matter currently, CRIU can't c/r the compat tasks, and 64-bit apps do not use context.vdso. Afaics. Still, I think we might want to havespecial_mapping_remap()and we can't do this because ->vm_file == NULL.
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
I would like this. Then I could clean up and resubmit my patch to keep context.vdso up to date.
Cough... where can I find this patch ? ;)
https://git.kernel.org/cgit/linux/kernel/git/luto/linux.git/log/?h=vdso/vma_tracking
Aha, thanks. So yes, looks like your "Add a mechanism to track the current address of a special mapping" can rely on vm_ops->mremap().
Oleg.
Quoted 14 lines · Oleg Nesterov
Quoted 12 lines · Kirill A. Shutemov
Quoted 9 lines · Oleg Nesterov
vma->vm_ops->mremap()looks more natural and clean inmove_vma(), and this way ->mremap() can have more users. Say, vdso.Signed-off-by Oleg Nesterov <[email protected]>--- fs/aio.c | 25 ++++++++++++++++--------- include/linux/fs.h | 1 - include/linux/mm.h | 1 + mm/mremap.c | 4 ++--
Quoted 3 lines
Quoted 1 line
Please, update
Documentation/filesystems/Locking.OK, thanks, will do.
Wait... Documentation/filesystems/Locking doesn't mention ->mremap() at all.
So you actually ask me to add the new documentation? ;)
Oh well... OK, I'll try if you think this is necessary.
I tried to make the minimal change before ->mremap() finds another user in file_operations. I thinks it needs more arguments, at least new_addr and new_len, otherwise it is not easy to document it. The same for f_op->mremap() of course.
Currently this does not matter, the only user is aio.c and VM_DONTEXPAND means that it is not mergeable, so mremap() always creates the new vma.
Hmm. Can't we do this change and add the documentation later?
Oleg.
Quoted 15 lines · Oleg Nesterov
Quoted 14 lines · Oleg Nesterov
Quoted 12 lines · Kirill A. Shutemov
Quoted 9 lines · Oleg Nesterov
vma->vm_ops->mremap()looks more natural and clean inmove_vma(), and this way ->mremap() can have more users. Say, vdso.Signed-off-by Oleg Nesterov <[email protected]>--- fs/aio.c | 25 ++++++++++++++++--------- include/linux/fs.h | 1 - include/linux/mm.h | 1 + mm/mremap.c | 4 ++--
Quoted 8 lines
Quoted 3 lines
Quoted 1 line
Please, update
Documentation/filesystems/Locking.OK, thanks, will do.
Wait...
Documentation/filesystems/Lockingdoesn't mention ->mremap() at all.So you actually ask me to add the new documentation? ;)
I tried ;)
Quoted 7 lines
Oh well... OK, I'll try if you think this is necessary.
I tried to make the minimal change before ->mremap() finds another user in
file_operations. I thinks it needs more arguments, at leastnew_addrandnew_len, otherwise it is not easy to document it. The same forf_op->mremap()of course.
Quoted 5 lines
Currently this does not matter, the only user is
aio.candVM_DONTEXPANDmeans that it is not mergeable, somremap()always creates the new vma.Hmm. Can't we do this change and add the documentation later?
I'm fine with that.
Signature · 1 line
Kirill A. Shutemov
Quoted 9 lines · Kirill A. Shutemov
Quoted 5 lines · Oleg Nesterov
Wait...
Documentation/filesystems/Lockingdoesn't mention ->mremap() at all.So you actually ask me to add the new documentation? ;)
I tried ;)
Understand ;) but I failed to do this. Serisouly, I simply don't know what can I add into this (outadted anyway) section except "called when move_page_tables() targets this vma".
Quoted 5 lines
Quoted 5 lines
I tried to make the minimal change before ->mremap() finds another user in
file_operations. I thinks it needs more arguments, at leastnew_addrandnew_len, otherwise it is not easy to document it. The same forf_op->mremap()of course.
Quoted 7 lines
Quoted 5 lines
Currently this does not matter, the only user is
aio.candVM_DONTEXPANDmeans that it is not mergeable, somremap()always creates the new vma.Hmm. Can't we do this change and add the documentation later?
I'm fine with that.
OK, so I am sending v2 with the only change: rename aio_ring_remap to aio_ring_mremap as you suggested.
Oleg.
PATCH v2 1/1 mm: move ->mremap() from file_operations to vm_operations_struct
In reply to Oleg Nesterovvma->vm_ops->mremap() looks more natural and clean in move_vma(), and this way ->mremap() can have more users. Say, vdso.
While at it, s/aio_ring_remap/aio_ring_mremap/.
--- fs/aio.c | 25 ++++++++++++++++--------- include/linux/fs.h | 1 - include/linux/mm.h | 1 + mm/mremap.c | 4 ++-- 4 files changed, 19 insertions(+), 12 deletions(-)
fs/aio.c +16 -9
@@ -308,15 +308,9 @@ static void aio_free_ring(struct kioctx *ctx) } } -static int aio_ring_mmap (struct file *file,struct vm_area_struct *vma) -{ - vma->vm_flags |=VM_DONTEXPAND ; - vma->vm_ops = &generic_file_vm_ops; -return 0 ; -} - -static int aio_ring_remap (struct file *file,struct vm_area_struct *vma) +static int aio_ring_mremap (struct vm_area_struct *vma) { +struct file *file = vma->vm_file;struct mm_struct *mm = vma->vm_mm;struct kioctx_table *table;int i, res = -EINVAL ;
@@ -339,9 +333,22 @@ static int aio_ring_remap(struct file *file, struct vm_area_struct *vma)return res; } +static const struct vm_operations_struct aio_ring_vm_ops = { + .mremap = aio_ring_mremap, + .fault = filemap_fault, + .map_pages = filemap_map_pages, + .page_mkwrite = filemap_page_mkwrite, +}; + +static int aio_ring_mmap (struct file *file,struct vm_area_struct *vma) +{ + vma->vm_flags |=VM_DONTEXPAND ; + vma->vm_ops = &aio_ring_vm_ops; +return 0 ; +} +static const struct file_operations aio_ring_fops = { .mmap = aio_ring_mmap, - .mremap = aio_ring_remap, };#if IS_ENABLED (CONFIG_MIGRATION )
include/linux/fs.h +0 -1
@@ -1582,7 +1582,6 @@ struct file_operations {long (*unlocked_ioctl) (struct file *,unsigned int ,unsigned long );long (*compat_ioctl) (struct file *,unsigned int ,unsigned long );int (*mmap) (struct file *,struct vm_area_struct *); -int (*mremap)(struct file *,struct vm_area_struct *);int (*open) (struct inode *,struct file *);int (*flush) (struct file *,fl_owner_t id);int (*release) (struct inode *,struct file *);
include/linux/mm.h +1 -0
@@ -244,6 +244,7 @@ struct vm_fault {struct vm_operations_struct {void (*open)(struct vm_area_struct * area);void (*close)(struct vm_area_struct * area); +int (*mremap)(struct vm_area_struct * area);int (*fault)(struct vm_area_struct *vma,struct vm_fault *vmf);void (*map_pages)(struct vm_area_struct *vma,struct vm_fault *vmf);
mm/mremap.c +2 -2
@@ -276,8 +276,8 @@ static unsigned long move_vma(struct vm_area_struct *vma, need_rmap_locks);if (moved_len < old_len) { err = -ENOMEM ; - }else if (vma->vm_file && vma->vm_file->f_op->mremap) { - err = vma->vm_file->f_op->mremap (vma->vm_file, new_vma); + }else if (vma->vm_ops && vma->vm_ops->mremap) { + err = vma->vm_ops->mremap (new_vma); }if (unlikely (err)) {
Signature · 1 line
1.5.5.1
Quoted 88 lines · Oleg Nesterov
vma->vm_ops->mremap()looks more natural and clean inmove_vma(), and this way ->mremap() can have more users. Say, vdso.While at it, s/aio_ring_remap/aio_ring_mremap/.
Signed-off-by Oleg Nesterov <[email protected]>--- fs/aio.c | 25 ++++++++++++++++--------- include/linux/fs.h | 1 - include/linux/mm.h | 1 + mm/mremap.c | 4 ++-- 4 files changed, 19 insertions(+), 12 deletions(-)fs/aio.c +16
-9@@ -308,15 +308,9 @@ static void aio_free_ring(struct kioctx *ctx) } } -static int aio_ring_mmap (struct file *file,struct vm_area_struct *vma) -{ - vma->vm_flags |=VM_DONTEXPAND ; - vma->vm_ops = &generic_file_vm_ops; -return 0 ; -} - -static int aio_ring_remap (struct file *file,struct vm_area_struct *vma) +static int aio_ring_mremap (struct vm_area_struct *vma) { +struct file *file = vma->vm_file;struct mm_struct *mm = vma->vm_mm;struct kioctx_table *table;int i, res = -EINVAL ;@@ -339,9 +333,22 @@ static int aio_ring_remap(struct file *file, struct vm_area_struct *vma)return res; } +static const struct vm_operations_struct aio_ring_vm_ops = { + .mremap = aio_ring_mremap, + .fault = filemap_fault, + .map_pages = filemap_map_pages, + .page_mkwrite = filemap_page_mkwrite, +}; + +static int aio_ring_mmap (struct file *file,struct vm_area_struct *vma) +{ + vma->vm_flags |=VM_DONTEXPAND ; + vma->vm_ops = &aio_ring_vm_ops; +return 0 ; +} +static const struct file_operations aio_ring_fops = { .mmap = aio_ring_mmap, - .mremap = aio_ring_remap, };#if IS_ENABLED (CONFIG_MIGRATION )include/linux/fs.h +0
-1@@ -1582,7 +1582,6 @@ struct file_operations {long (*unlocked_ioctl) (struct file *,unsigned int ,unsigned long );long (*compat_ioctl) (struct file *,unsigned int ,unsigned long );int (*mmap) (struct file *,struct vm_area_struct *); -int (*mremap)(struct file *,struct vm_area_struct *);int (*open) (struct inode *,struct file *);int (*flush) (struct file *,fl_owner_t id);int (*release) (struct inode *,struct file *);include/linux/mm.h +1
-0@@ -244,6 +244,7 @@ struct vm_fault {struct vm_operations_struct {void (*open)(struct vm_area_struct * area);void (*close)(struct vm_area_struct * area); +int (*mremap)(struct vm_area_struct * area);int (*fault)(struct vm_area_struct *vma,struct vm_fault *vmf);void (*map_pages)(struct vm_area_struct *vma,struct vm_fault *vmf);mm/mremap.c +0
-0
mm/mremap.c static unsigned long move_vma(struct vm_area_struct *vma, · line 283
Quoted 10 lines
mm/mremap.c +2
-2@@ -276,8 +276,8 @@ static unsigned long move_vma(struct vm_area_struct *vma, need_rmap_locks);if (moved_len < old_len) { err = -ENOMEM ; - }else if (vma->vm_file && vma->vm_file->f_op->mremap) { - err = vma->vm_file->f_op->mremap (vma->vm_file, new_vma); + }else if (vma->vm_ops && vma->vm_ops->mremap) { + err = vma->vm_ops->mremap (new_vma); }if (unlikely (err)) {
I'm not sure what is target tree for the patch. Last hunk is not going to apply on Linus' tree or -next. Hm?
Otherwise, looks good.
Signature · 1 line
Kirill A. Shutemov
Quoted 13 lines · Kirill A. Shutemov
Quoted 13 lines
mm/mremap.c +2
-2@@ -276,8 +276,8 @@ static unsigned long move_vma(struct vm_area_struct *vma, need_rmap_locks);if (moved_len < old_len) { err = -ENOMEM ; - }else if (vma->vm_file && vma->vm_file->f_op->mremap) { - err = vma->vm_file->f_op->mremap (vma->vm_file, new_vma); + }else if (vma->vm_ops && vma->vm_ops->mremap) { + err = vma->vm_ops->mremap (new_vma); }
Quoted 3 lines
mm/mremap.c static unsigned long move_vma(struct vm_area_struct *vma, · line 283
Quoted 1 line
mm/mremap.c +0
-0if (unlikely (err)) {I'm not sure what is target tree for the patch.
I hope akpm can take this patch into -mm,
Quoted 2 lines
Last hunk is not going to
apply on Linus' tree or -next. Hm?
Yes, this depends on another fix I sent to Andrew (and you ;), as 0/1 explains the change in move_vma() textually depends on another patch I sent,
[PATCH 1/4] mremap: don't leak new_vma if f_op->mremap() fails http://marc.info/?l=linux-kernel&m=143475603713622
Quoted 3 lines
Otherwise, looks good.
Thanks!
Oleg.
Quoted 6 lines · Oleg Nesterov
vma->vm_ops->mremap()looks more natural and clean inmove_vma(), and this way ->mremap() can have more users. Say, vdso.While at it, s/aio_ring_remap/aio_ring_mremap/.
Signed-off-by Oleg Nesterov <[email protected]>