linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Anshuman Khandual <khandual@linux.vnet.ibm.com>
To: linux-kernel@vger.kernel.org, linux-mm@kvack.org
Cc: mhocko@suse.com, vbabka@suse.cz, mgorman@suse.de,
	minchan@kernel.org, aneesh.kumar@linux.vnet.ibm.com,
	bsingharora@gmail.com, srikar@linux.vnet.ibm.com,
	haren@linux.vnet.ibm.com, jglisse@redhat.com,
	dave.hansen@intel.com, dan.j.williams@intel.com,
	zi.yan@cs.rutgers.edu
Subject: [PATCH 3/6] mm/migrate: Add copy_pages_mthread function
Date: Thu,  9 Mar 2017 11:55:32 +0530	[thread overview]
Message-ID: <20170309062532.30913-1-khandual@linux.vnet.ibm.com> (raw)
In-Reply-To: <20170217112453.307-4-khandual@linux.vnet.ibm.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>
---
* Updated cthread calculations, taking care of divide by zero issues,
  picking up the right single thread, defining NR_COPYTHREADS, fixing
  the build problem on i386 etc.

 include/linux/highmem.h |  2 ++
 mm/Makefile             |  2 ++
 mm/copy_pages_mthread.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 99 insertions(+)
 create mode 100644 mm/copy_pages_mthread.c

diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index bb3f329..e1f4f1b 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 295bd7a..cc27e76 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -41,6 +41,8 @@ obj-y			:= filemap.o mempool.o oom_kill.o \
 
 obj-y += init-mm.o
 
+obj-y += copy_pages_mthread.o
+
 ifdef CONFIG_NO_BOOTMEM
 	obj-y		+= nobootmem.o
 else
diff --git a/mm/copy_pages_mthread.c b/mm/copy_pages_mthread.c
new file mode 100644
index 0000000..5af861c
--- /dev/null
+++ b/mm/copy_pages_mthread.c
@@ -0,0 +1,95 @@
+/*
+ * This implements parallel page copy function through multi
+ * threaded work queues.
+ *
+ * Copyright (C) Zi Yan <ziy@nvidia.com>, Nov 2016
+ *
+ * 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.
+ */
+#define 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)
+{
+	struct cpumask *cpumask;
+	struct copy_info *work_items;
+	char *vto, *vfrom;
+	unsigned long i, cthreads, cpu, node, chunk_size;
+	int cpu_id_list[NR_COPYTHREADS] = {0};
+
+	node = page_to_nid(to);
+	cpumask = (struct cpumask *) cpumask_of_node(node);
+	cthreads = min_t(unsigned int, NR_COPYTHREADS, cpumask_weight(cpumask));
+	cthreads = (cthreads / 2) * 2;
+	if (!cthreads)
+		cthreads = 1;
+
+	work_items = kcalloc(cthreads, sizeof(struct copy_info), GFP_KERNEL);
+	if (!work_items)
+		return -ENOMEM;
+
+	/*
+	 * XXX: On a memory-only CPU-less NUMA node it will
+	 * just fallback using cpu[0] in a single threaded
+	 * manner to do the page copy. On single CPU target
+	 * node that CPU will be used for the page copy.
+	 */
+	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.1.4

  parent reply	other threads:[~2017-03-09  7:11 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-17 11:24 [PATCH 0/6] Enable parallel page migration Anshuman Khandual
2017-02-17 11:24 ` [PATCH 1/6] mm/migrate: Add new mode parameter to migrate_page_copy() function Anshuman Khandual
2017-03-09  6:24   ` Anshuman Khandual
2017-02-17 11:24 ` [PATCH 2/6] mm/migrate: Make migrate_mode types non-exclusive Anshuman Khandual
2017-02-17 11:24 ` [PATCH 3/6] mm/migrate: Add copy_pages_mthread function Anshuman Khandual
2017-02-17 12:27   ` kbuild test robot
2017-03-08 15:40     ` Anshuman Khandual
2017-03-09  6:25   ` Anshuman Khandual [this message]
2017-02-17 11:24 ` [PATCH 4/6] mm/migrate: Add new migrate mode MIGRATE_MT Anshuman Khandual
2017-02-17 11:24 ` [PATCH 5/6] mm/migrate: Add new migration flag MPOL_MF_MOVE_MT for syscalls Anshuman Khandual
2017-03-09  6:26   ` Anshuman Khandual
2017-02-17 11:24 ` [PATCH 6/6] sysctl: Add global tunable mt_page_copy Anshuman Khandual
2017-02-17 15:30   ` kbuild test robot
2017-03-08 15:37     ` Anshuman Khandual
2017-03-10  1:12       ` [kbuild-all] " Ye Xiaolong
2017-03-10 12:11         ` Anshuman Khandual
2017-02-22  5:04 ` [PATCH 0/6] Enable parallel page migration Balbir Singh
2017-02-22  5:55   ` Anshuman Khandual
2017-02-22 10:52     ` Balbir Singh
2017-03-08 16:04 ` Anshuman Khandual
2017-03-09 15:09   ` Mel Gorman
2017-03-09 17:38     ` David Nellans
2017-03-09 22:15       ` Mel Gorman
2017-03-09 23:46         ` Zi Yan
2017-03-10 14:07           ` Mel Gorman
2017-03-10 14:45             ` Michal Hocko
2017-03-10 13:05     ` Michal Hocko

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=20170309062532.30913-1-khandual@linux.vnet.ibm.com \
    --to=khandual@linux.vnet.ibm.com \
    --cc=aneesh.kumar@linux.vnet.ibm.com \
    --cc=bsingharora@gmail.com \
    --cc=dan.j.williams@intel.com \
    --cc=dave.hansen@intel.com \
    --cc=haren@linux.vnet.ibm.com \
    --cc=jglisse@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mgorman@suse.de \
    --cc=mhocko@suse.com \
    --cc=minchan@kernel.org \
    --cc=srikar@linux.vnet.ibm.com \
    --cc=vbabka@suse.cz \
    --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;
as well as URLs for NNTP newsgroup(s).