aboutsummaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
authorMichel Lespinasse <walken@google.com>2013-02-22 19:32:37 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-23 20:50:10 -0500
commitbebeb3d68b24bb4132d452c5707fe321208bcbcd (patch)
tree6e609cb7323fb1b4b7026fa0e35867145a181094 /ipc
parent940e7da5163029978c2f6b5bbe213607add59062 (diff)
mm: introduce mm_populate() for populating new vmas
When creating new mappings using the MAP_POPULATE / MAP_LOCKED flags (or with MCL_FUTURE in effect), we want to populate the pages within the newly created vmas. This may take a while as we may have to read pages from disk, so ideally we want to do this outside of the write-locked mmap_sem region. This change introduces mm_populate(), which is used to defer populating such mappings until after the mmap_sem write lock has been released. This is implemented as a generalization of the former do_mlock_pages(), which accomplished the same task but was using during mlock() / mlockall(). Signed-off-by: Michel Lespinasse <walken@google.com> Reported-by: Andy Lutomirski <luto@amacapital.net> Acked-by: Rik van Riel <riel@redhat.com> Tested-by: Andy Lutomirski <luto@amacapital.net> Cc: Greg Ungerer <gregungerer@westnet.com.au> Cc: David Howells <dhowells@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'ipc')
-rw-r--r--ipc/shm.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/ipc/shm.c b/ipc/shm.c
index 4fa6d8fee730..9f047ba69e62 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -967,11 +967,11 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
967 unsigned long flags; 967 unsigned long flags;
968 unsigned long prot; 968 unsigned long prot;
969 int acc_mode; 969 int acc_mode;
970 unsigned long user_addr;
971 struct ipc_namespace *ns; 970 struct ipc_namespace *ns;
972 struct shm_file_data *sfd; 971 struct shm_file_data *sfd;
973 struct path path; 972 struct path path;
974 fmode_t f_mode; 973 fmode_t f_mode;
974 bool populate = false;
975 975
976 err = -EINVAL; 976 err = -EINVAL;
977 if (shmid < 0) 977 if (shmid < 0)
@@ -1070,13 +1070,15 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
1070 goto invalid; 1070 goto invalid;
1071 } 1071 }
1072 1072
1073 user_addr = do_mmap_pgoff(file, addr, size, prot, flags, 0); 1073 addr = do_mmap_pgoff(file, addr, size, prot, flags, 0, &populate);
1074 *raddr = user_addr; 1074 *raddr = addr;
1075 err = 0; 1075 err = 0;
1076 if (IS_ERR_VALUE(user_addr)) 1076 if (IS_ERR_VALUE(addr))
1077 err = (long)user_addr; 1077 err = (long)addr;
1078invalid: 1078invalid:
1079 up_write(&current->mm->mmap_sem); 1079 up_write(&current->mm->mmap_sem);
1080 if (populate)
1081 mm_populate(addr, size);
1080 1082
1081out_fput: 1083out_fput:
1082 fput(file); 1084 fput(file);