Currently there is no interface to be called by a driver for user process virtual range migration. This adds one function and exports to be then used by drivers. Signed-off-by: Anshuman Khandual <khandual@xxxxxxxxxxxxxxxxxx> --- include/linux/mempolicy.h | 2 ++ mm/mempolicy.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h index ff0c6bc..b07d6dc 100644 --- a/include/linux/mempolicy.h +++ b/include/linux/mempolicy.h @@ -153,6 +153,8 @@ extern bool init_nodemask_of_mempolicy(nodemask_t *mask); extern bool mempolicy_nodemask_intersects(struct task_struct *tsk, const nodemask_t *mask); extern unsigned int mempolicy_slab_node(void); +extern int migrate_virtual_range(int pid, unsigned long vaddr, + unsigned long size, int nid); extern enum zone_type policy_zone; diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 4482140..13cd5eb 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -2919,3 +2919,48 @@ void mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol) p += scnprintf(p, buffer + maxlen - p, ":%*pbl", nodemask_pr_args(&nodes)); } + +/* + * migrate_virtual_range - migrate all pages of a process faulted within + * a virtual address range to a specified node. This function is also + * exported to be used by device drivers dealing with CDM memory. + * + * @pid: Process ID of the target process + * @start: Start address of virtual range + * @end: End address of virtual range + * @nid: Target node for migration + * + * Returns number of pages that were not migrated in case of failure else + * returns 0 when its successful. + */ +int migrate_virtual_range(int pid, unsigned long start, + unsigned long end, int nid) +{ + struct mm_struct *mm; + int ret = 0; + + LIST_HEAD(mlist); + + if ((!start) || (!end)) { + ret = -EINVAL; + goto out; + } + + rcu_read_lock(); + mm = find_task_by_vpid(pid)->mm; + rcu_read_unlock(); + + down_write(&mm->mmap_sem); + queue_pages_range(mm, start, end, &node_states[N_MEMORY], + MPOL_MF_MOVE_ALL | MPOL_MF_DISCONTIG_OK, &mlist); + if (!list_empty(&mlist)) { + ret = migrate_pages(&mlist, new_node_page, NULL, + nid, MIGRATE_SYNC, MR_NUMA_MISPLACED); + if (ret) + putback_movable_pages(&mlist); + } + up_write(&mm->mmap_sem); +out: + return ret; +} +EXPORT_SYMBOL(migrate_virtual_range); -- 2.9.3 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>