Commit 5e9a0f023bee02bfb94e08590d998660c01f5a49

Authored by Brice Goglin
Committed by Linus Torvalds
1 parent 2f007e74bb

mm: extract do_pages_move() out of sys_move_pages()

To prepare the chunking, move the sys_move_pages() code that is used when
nodes!=NULL into do_pages_move().  And rename do_move_pages() into
do_move_page_to_node_array().

Signed-off-by: Brice Goglin <Brice.Goglin@inria.fr>
Acked-by: Christoph Lameter <cl@linux-foundation.org>
Cc: Nick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 1 changed file with 86 additions and 66 deletions Side-by-side Diff

... ... @@ -826,9 +826,11 @@
826 826 * Move a set of pages as indicated in the pm array. The addr
827 827 * field must be set to the virtual address of the page to be moved
828 828 * and the node number must contain a valid target node.
  829 + * The pm array ends with node = MAX_NUMNODES.
829 830 */
830   -static int do_move_pages(struct mm_struct *mm, struct page_to_node *pm,
831   - int migrate_all)
  831 +static int do_move_page_to_node_array(struct mm_struct *mm,
  832 + struct page_to_node *pm,
  833 + int migrate_all)
832 834 {
833 835 int err;
834 836 struct page_to_node *pp;
... ... @@ -906,6 +908,81 @@
906 908 }
907 909  
908 910 /*
  911 + * Migrate an array of page address onto an array of nodes and fill
  912 + * the corresponding array of status.
  913 + */
  914 +static int do_pages_move(struct mm_struct *mm, struct task_struct *task,
  915 + unsigned long nr_pages,
  916 + const void __user * __user *pages,
  917 + const int __user *nodes,
  918 + int __user *status, int flags)
  919 +{
  920 + struct page_to_node *pm = NULL;
  921 + nodemask_t task_nodes;
  922 + int err = 0;
  923 + int i;
  924 +
  925 + task_nodes = cpuset_mems_allowed(task);
  926 +
  927 + /* Limit nr_pages so that the multiplication may not overflow */
  928 + if (nr_pages >= ULONG_MAX / sizeof(struct page_to_node) - 1) {
  929 + err = -E2BIG;
  930 + goto out;
  931 + }
  932 +
  933 + pm = vmalloc((nr_pages + 1) * sizeof(struct page_to_node));
  934 + if (!pm) {
  935 + err = -ENOMEM;
  936 + goto out;
  937 + }
  938 +
  939 + /*
  940 + * Get parameters from user space and initialize the pm
  941 + * array. Return various errors if the user did something wrong.
  942 + */
  943 + for (i = 0; i < nr_pages; i++) {
  944 + const void __user *p;
  945 +
  946 + err = -EFAULT;
  947 + if (get_user(p, pages + i))
  948 + goto out_pm;
  949 +
  950 + pm[i].addr = (unsigned long)p;
  951 + if (nodes) {
  952 + int node;
  953 +
  954 + if (get_user(node, nodes + i))
  955 + goto out_pm;
  956 +
  957 + err = -ENODEV;
  958 + if (!node_state(node, N_HIGH_MEMORY))
  959 + goto out_pm;
  960 +
  961 + err = -EACCES;
  962 + if (!node_isset(node, task_nodes))
  963 + goto out_pm;
  964 +
  965 + pm[i].node = node;
  966 + } else
  967 + pm[i].node = 0; /* anything to not match MAX_NUMNODES */
  968 + }
  969 + /* End marker */
  970 + pm[nr_pages].node = MAX_NUMNODES;
  971 +
  972 + err = do_move_page_to_node_array(mm, pm, flags & MPOL_MF_MOVE_ALL);
  973 + if (err >= 0)
  974 + /* Return status information */
  975 + for (i = 0; i < nr_pages; i++)
  976 + if (put_user(pm[i].status, status + i))
  977 + err = -EFAULT;
  978 +
  979 +out_pm:
  980 + vfree(pm);
  981 +out:
  982 + return err;
  983 +}
  984 +
  985 +/*
909 986 * Determine the nodes of an array of pages and store it in an array of status.
910 987 */
911 988 static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages,
912 989  
913 990  
... ... @@ -963,12 +1040,9 @@
963 1040 const int __user *nodes,
964 1041 int __user *status, int flags)
965 1042 {
966   - int err = 0;
967   - int i;
968 1043 struct task_struct *task;
969   - nodemask_t task_nodes;
970 1044 struct mm_struct *mm;
971   - struct page_to_node *pm = NULL;
  1045 + int err;
972 1046  
973 1047 /* Check flags */
974 1048 if (flags & ~(MPOL_MF_MOVE|MPOL_MF_MOVE_ALL))
975 1049  
976 1050  
977 1051  
978 1052  
979 1053  
... ... @@ -1000,75 +1074,21 @@
1000 1074 (current->uid != task->suid) && (current->uid != task->uid) &&
1001 1075 !capable(CAP_SYS_NICE)) {
1002 1076 err = -EPERM;
1003   - goto out2;
  1077 + goto out;
1004 1078 }
1005 1079  
1006 1080 err = security_task_movememory(task);
1007 1081 if (err)
1008   - goto out2;
  1082 + goto out;
1009 1083  
1010   - if (!nodes) {
  1084 + if (nodes) {
  1085 + err = do_pages_move(mm, task, nr_pages, pages, nodes, status,
  1086 + flags);
  1087 + } else {
1011 1088 err = do_pages_stat(mm, nr_pages, pages, status);
1012   - goto out2;
1013 1089 }
1014 1090  
1015   - task_nodes = cpuset_mems_allowed(task);
1016   -
1017   - /* Limit nr_pages so that the multiplication may not overflow */
1018   - if (nr_pages >= ULONG_MAX / sizeof(struct page_to_node) - 1) {
1019   - err = -E2BIG;
1020   - goto out2;
1021   - }
1022   -
1023   - pm = vmalloc((nr_pages + 1) * sizeof(struct page_to_node));
1024   - if (!pm) {
1025   - err = -ENOMEM;
1026   - goto out2;
1027   - }
1028   -
1029   - /*
1030   - * Get parameters from user space and initialize the pm
1031   - * array. Return various errors if the user did something wrong.
1032   - */
1033   - for (i = 0; i < nr_pages; i++) {
1034   - const void __user *p;
1035   -
1036   - err = -EFAULT;
1037   - if (get_user(p, pages + i))
1038   - goto out;
1039   -
1040   - pm[i].addr = (unsigned long)p;
1041   - if (nodes) {
1042   - int node;
1043   -
1044   - if (get_user(node, nodes + i))
1045   - goto out;
1046   -
1047   - err = -ENODEV;
1048   - if (!node_state(node, N_HIGH_MEMORY))
1049   - goto out;
1050   -
1051   - err = -EACCES;
1052   - if (!node_isset(node, task_nodes))
1053   - goto out;
1054   -
1055   - pm[i].node = node;
1056   - } else
1057   - pm[i].node = 0; /* anything to not match MAX_NUMNODES */
1058   - }
1059   - /* End marker */
1060   - pm[nr_pages].node = MAX_NUMNODES;
1061   -
1062   - err = do_move_pages(mm, pm, flags & MPOL_MF_MOVE_ALL);
1063   - if (err >= 0)
1064   - /* Return status information */
1065   - for (i = 0; i < nr_pages; i++)
1066   - if (put_user(pm[i].status, status + i))
1067   - err = -EFAULT;
1068   -
1069 1091 out:
1070   - vfree(pm);
1071   -out2:
1072 1092 mmput(mm);
1073 1093 return err;
1074 1094 }