From: Zi Yan <zi.yan@sent.com>
To: linux-mm@kvack.org
Cc: dnellans@nvidia.com, apopple@au1.ibm.com,
paulmck@linux.vnet.ibm.com, khandual@linux.vnet.ibm.com,
zi.yan@cs.rutgers.edu
Subject: [RFC PATCH 03/14] mm/migrate: Add copy_pages_mthread function
Date: Fri, 17 Feb 2017 10:05:40 -0500 [thread overview]
Message-ID: <20170217150551.117028-4-zi.yan@sent.com> (raw)
In-Reply-To: <20170217150551.117028-1-zi.yan@sent.com>
From: Zi Yan <ziy@nvidia.com>
This change adds a new function copy_pages_mthread to enable multi threaded
page copy which can be utilized during migration. This function splits the
page copy request into multiple threads which will handle individual chunk
and send them as jobs to system_highpri_wq work queue.
Signed-off-by: Zi Yan <zi.yan@cs.rutgers.edu>
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
include/linux/highmem.h | 2 ++
mm/Makefile | 2 ++
mm/copy_pages.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 90 insertions(+)
create mode 100644 mm/copy_pages.c
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index bb3f3297062a..e1f4f1b82812 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -236,6 +236,8 @@ static inline void copy_user_highpage(struct page *to, struct page *from,
#endif
+int copy_pages_mthread(struct page *to, struct page *from, int nr_pages);
+
static inline void copy_highpage(struct page *to, struct page *from)
{
char *vfrom, *vto;
diff --git a/mm/Makefile b/mm/Makefile
index aa0aa17cb413..cdd4bab9cc66 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -43,6 +43,8 @@ obj-y := filemap.o mempool.o oom_kill.o \
obj-y += init-mm.o
+obj-y += copy_pages.o
+
ifdef CONFIG_NO_BOOTMEM
obj-y += nobootmem.o
else
diff --git a/mm/copy_pages.c b/mm/copy_pages.c
new file mode 100644
index 000000000000..c357e7b01042
--- /dev/null
+++ b/mm/copy_pages.c
@@ -0,0 +1,86 @@
+/*
+ * This implements parallel page copy function through multi threaded
+ * work queues.
+ *
+ * Zi Yan <ziy@nvidia.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ */
+#include <linux/highmem.h>
+#include <linux/workqueue.h>
+#include <linux/slab.h>
+#include <linux/freezer.h>
+
+/*
+ * nr_copythreads can be the highest number of threads for given node
+ * on any architecture. The actual number of copy threads will be
+ * limited by the cpumask weight of the target node.
+ */
+unsigned int nr_copythreads = 8;
+
+struct copy_info {
+ struct work_struct copy_work;
+ char *to;
+ char *from;
+ unsigned long chunk_size;
+};
+
+static void copy_pages(char *vto, char *vfrom, unsigned long size)
+{
+ memcpy(vto, vfrom, size);
+}
+
+static void copythread(struct work_struct *work)
+{
+ struct copy_info *info = (struct copy_info *) work;
+
+ copy_pages(info->to, info->from, info->chunk_size);
+}
+
+int copy_pages_mthread(struct page *to, struct page *from, int nr_pages)
+{
+ unsigned int node = page_to_nid(to);
+ const struct cpumask *cpumask = cpumask_of_node(node);
+ struct copy_info *work_items;
+ char *vto, *vfrom;
+ unsigned long i, cthreads, cpu, chunk_size;
+ int cpu_id_list[32] = {0};
+
+ cthreads = nr_copythreads;
+ cthreads = min_t(unsigned int, cthreads, cpumask_weight(cpumask));
+ cthreads = (cthreads / 2) * 2;
+ work_items = kcalloc(cthreads, sizeof(struct copy_info), GFP_KERNEL);
+ if (!work_items)
+ return -ENOMEM;
+
+ i = 0;
+ for_each_cpu(cpu, cpumask) {
+ if (i >= cthreads)
+ break;
+ cpu_id_list[i] = cpu;
+ ++i;
+ }
+
+ vfrom = kmap(from);
+ vto = kmap(to);
+ chunk_size = PAGE_SIZE * nr_pages / cthreads;
+
+ for (i = 0; i < cthreads; ++i) {
+ INIT_WORK((struct work_struct *) &work_items[i], copythread);
+
+ work_items[i].to = vto + i * chunk_size;
+ work_items[i].from = vfrom + i * chunk_size;
+ work_items[i].chunk_size = chunk_size;
+
+ queue_work_on(cpu_id_list[i], system_highpri_wq,
+ (struct work_struct *) &work_items[i]);
+ }
+
+ for (i = 0; i < cthreads; ++i)
+ flush_work((struct work_struct *) &work_items[i]);
+
+ kunmap(to);
+ kunmap(from);
+ kfree(work_items);
+ return 0;
+}
--
2.11.0
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2017-02-17 15:06 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-02-17 15:05 [RFC PATCH 00/14] Accelerating page migrations Zi Yan
2017-02-17 15:05 ` [RFC PATCH 01/14] mm/migrate: Add new mode parameter to migrate_page_copy() function Zi Yan
2017-02-17 15:05 ` [RFC PATCH 02/14] mm/migrate: Make migrate_mode types non-exclussive Zi Yan
2017-02-17 15:05 ` Zi Yan [this message]
2017-02-23 6:06 ` [RFC PATCH 03/14] mm/migrate: Add copy_pages_mthread function Naoya Horiguchi
2017-02-23 7:50 ` Anshuman Khandual
2017-02-23 8:02 ` Naoya Horiguchi
2017-03-09 5:35 ` Anshuman Khandual
2017-02-17 15:05 ` [RFC PATCH 04/14] mm/migrate: Add new migrate mode MIGRATE_MT Zi Yan
2017-02-23 6:54 ` Naoya Horiguchi
2017-02-23 7:54 ` Anshuman Khandual
2017-02-17 15:05 ` [RFC PATCH 05/14] mm/migrate: Add new migration flag MPOL_MF_MOVE_MT for syscalls Zi Yan
2017-02-17 15:05 ` [RFC PATCH 06/14] sysctl: Add global tunable mt_page_copy Zi Yan
2017-02-17 15:05 ` [RFC PATCH 07/14] migrate: Add copy_page_lists_mthread() function Zi Yan
2017-02-23 8:54 ` Naoya Horiguchi
2017-03-09 13:02 ` Anshuman Khandual
2017-02-17 15:05 ` [RFC PATCH 08/14] mm: migrate: Add concurrent page migration into move_pages syscall Zi Yan
2017-02-24 8:25 ` Naoya Horiguchi
2017-02-24 15:05 ` Zi Yan
2017-02-17 15:05 ` [RFC PATCH 09/14] mm: migrate: Add exchange_page_mthread() and exchange_page_lists_mthread() to exchange two pages or two page lists Zi Yan
2017-02-17 15:05 ` [RFC PATCH 10/14] mm: Add exchange_pages and exchange_pages_concur functions to exchange two lists of pages instead of two migrate_pages() Zi Yan
2017-02-17 15:05 ` [RFC PATCH 11/14] mm: migrate: Add exchange_pages syscall to exchange two page lists Zi Yan
2017-02-17 15:05 ` [RFC PATCH 12/14] migrate: Add copy_page_dma to use DMA Engine to copy pages Zi Yan
2017-02-17 15:05 ` [RFC PATCH 13/14] mm: migrate: Add copy_page_dma into migrate_page_copy Zi Yan
2017-02-17 15:05 ` [RFC PATCH 14/14] mm: Add copy_page_lists_dma_always to support copy a list of pages Zi Yan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170217150551.117028-4-zi.yan@sent.com \
--to=zi.yan@sent.com \
--cc=apopple@au1.ibm.com \
--cc=dnellans@nvidia.com \
--cc=khandual@linux.vnet.ibm.com \
--cc=linux-mm@kvack.org \
--cc=paulmck@linux.vnet.ibm.com \
--cc=zi.yan@cs.rutgers.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox