Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1524140 > unrolled thread

Re: [RFC 2/8] mm: Add specialized fallback zonelist for coherent device memory nodes

Started byAnshuman Khandual <khandual@linux.vnet.ibm.com>
First post2016-11-17 08:50 +0100
Last post2016-11-17 09:30 +0100
Articles 4 — 2 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: [RFC 2/8] mm: Add specialized fallback zonelist for coherent  device memory nodes Anshuman Khandual <khandual@linux.vnet.ibm.com> - 2016-11-17 08:50 +0100
    [DRAFT 1/2] mm/cpuset: Exclude CDM nodes from each task's mems_allowed node mask Anshuman Khandual <khandual@linux.vnet.ibm.com> - 2016-11-17 09:00 +0100
      [DRAFT 2/2] mm/hugetlb: Restrict HugeTLB allocations only to the system RAM nodes Anshuman Khandual <khandual@linux.vnet.ibm.com> - 2016-11-17 09:00 +0100
      Re: [DRAFT 1/2] mm/cpuset: Exclude CDM nodes from each task's  mems_allowed node mask kbuild test robot <lkp@intel.com> - 2016-11-17 09:30 +0100

#1524140 — Re: [RFC 2/8] mm: Add specialized fallback zonelist for coherent device memory nodes

FromAnshuman Khandual <khandual@linux.vnet.ibm.com>
Date2016-11-17 08:50 +0100
SubjectRe: [RFC 2/8] mm: Add specialized fallback zonelist for coherent device memory nodes
Message-ID<sEpCh-66D-1@gated-at.bofh.it>
On 10/24/2016 10:01 AM, Anshuman Khandual wrote:
> This change is part of the isolation requiring coherent device memory
> node's implementation.
> 
> Isolation seeking coherent memory node requires isolation from implicit
> memory allocations from user space but at the same time there should also
> have an explicit way to do the allocation. Kernel allocation to this memory
> can be prevented by putting the entire memory in ZONE_MOVABLE for example.
> 
> Platform node's both zonelists are fundamental to where the memory comes
> when there is an allocation request. In order to achieve the two objectives
> stated above, zonelists building process has to change as both zonelists
> (FALLBACK and NOFALLBACK) gives access to the node's memory zones during
> any kind of memory allocation. The following changes are implemented in
> this regard.
> 
> (1) Coherent node's zones are not part of any other node's FALLBACK list
> (2) Coherent node's FALLBACK list contains it's own memory zones followed
>     by all system RAM zones in normal order
> (3) Coherent node's zones are part of it's own NOFALLBACK list
> 
> The above changes which will ensure the following which in turn isolates
> the coherent memory node as desired.
> 
> (1) There wont be any implicit allocation ending up in the coherent node
> (2) __GFP_THISNODE marked allocations will come from the coherent node
> (3) Coherent memory can also be allocated through MPOL_BIND interface
> 
> Sample zonelist configuration:
> 
> [NODE (0)]						System RAM node
>         ZONELIST_FALLBACK (0xc00000000140da00)
>                 (0) (node 0) (DMA     0xc00000000140c000)
>                 (1) (node 1) (DMA     0xc000000100000000)
>         ZONELIST_NOFALLBACK (0xc000000001411a10)
>                 (0) (node 0) (DMA     0xc00000000140c000)
> [NODE (1)]						System RAM node
>         ZONELIST_FALLBACK (0xc000000100001a00)
>                 (0) (node 1) (DMA     0xc000000100000000)
>                 (1) (node 0) (DMA     0xc00000000140c000)
>         ZONELIST_NOFALLBACK (0xc000000100005a10)
>                 (0) (node 1) (DMA     0xc000000100000000)
> [NODE (2)]						Coherent memory
>         ZONELIST_FALLBACK (0xc000000001427700)
>                 (0) (node 2) (Movable 0xc000000001427080)
>                 (1) (node 0) (DMA     0xc00000000140c000)
>                 (2) (node 1) (DMA     0xc000000100000000)
>         ZONELIST_NOFALLBACK (0xc00000000142b710)
>                 (0) (node 2) (Movable 0xc000000001427080)
> [NODE (3)]						Coherent memory
>         ZONELIST_FALLBACK (0xc000000001431400)
>                 (0) (node 3) (Movable 0xc000000001430d80)
>                 (1) (node 0) (DMA     0xc00000000140c000)
>                 (2) (node 1) (DMA     0xc000000100000000)
>         ZONELIST_NOFALLBACK (0xc000000001435410)
>                 (0) (node 3) (Movable 0xc000000001430d80)
> [NODE (4)]						Coherent memory
>         ZONELIST_FALLBACK (0xc00000000143b100)
>                 (0) (node 4) (Movable 0xc00000000143aa80)
>                 (1) (node 0) (DMA     0xc00000000140c000)
>                 (2) (node 1) (DMA     0xc000000100000000)
>         ZONELIST_NOFALLBACK (0xc00000000143f110)
>                 (0) (node 4) (Movable 0xc00000000143aa80)
> 
> Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
> ---

Another way of achieving isolation of the CDM nodes from user space
allocations would be through cpuset changes. Will be sending out
couple of draft patches in this direction. Then we can look into
whether the current method or the cpuset method is a better way to
go forward.

[toc] | [next] | [standalone]


#1524151 — [DRAFT 1/2] mm/cpuset: Exclude CDM nodes from each task's mems_allowed node mask

FromAnshuman Khandual <khandual@linux.vnet.ibm.com>
Date2016-11-17 09:00 +0100
Subject[DRAFT 1/2] mm/cpuset: Exclude CDM nodes from each task's mems_allowed node mask
Message-ID<sEpLY-69J-19@gated-at.bofh.it>
In reply to#1524140
task->mems_allowed decides the final node mask of nodes from which memory
can be allocated irrespective of process or VMA based memory policy. CDM
nodes should not be used for any user space memory allocation, hence they
should not be part of any mems_allowed mask in user space to begin with.
This adds a function system_ram() which computes system RAM only nodes
and excludes all the CDM nodes on the platform. This resultant system RAM
nodemask is used instead of N_MEMORY mask during cpuset and mems_allowed
initialization. This achieves isolation of the coherent device memory
from userspace allocations.

Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
This completely isolates CDM nodes from user space allocations. Hence
explicit allocation to the CDM nodes would not be possible any more.
To again enable explicit allocation capability from user space, cpuset
needs to be changed to accommodate CDM nodes into task's mems_allowed.

 include/linux/mm.h |  9 +++++++++
 kernel/cpuset.c    | 12 +++++++-----
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index a92c8d7..f338492 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -446,6 +446,15 @@ static inline int put_page_testzero(struct page *page)
 	return page_ref_dec_and_test(page);
 }
 
+static inline nodemask_t system_ram(void)
+{
+	nodemask_t ram_nodes;
+
+	nodes_clear(ram_nodes);
+	nodes_andnot(ram_nodes, node_states[N_MEMORY], node_states[N_COHERENT_DEVICE]);
+	return ram_nodes;
+}
+
 /*
  * Try to grab a ref unless the page has a refcount of zero, return false if
  * that is the case.
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 29f815d..78c6fa3 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -364,9 +364,11 @@ static void guarantee_online_cpus(struct cpuset *cs, struct cpumask *pmask)
  */
 static void guarantee_online_mems(struct cpuset *cs, nodemask_t *pmask)
 {
-	while (!nodes_intersects(cs->effective_mems, node_states[N_MEMORY]))
+	nodemask_t nodes = system_ram();
+
+	while (!nodes_intersects(cs->effective_mems, nodes))
 		cs = parent_cs(cs);
-	nodes_and(*pmask, cs->effective_mems, node_states[N_MEMORY]);
+	nodes_and(*pmask, cs->effective_mems, nodes);
 }
 
 /*
@@ -2301,7 +2303,7 @@ static void cpuset_hotplug_workfn(struct work_struct *work)
 
 	/* fetch the available cpus/mems and find out which changed how */
 	cpumask_copy(&new_cpus, cpu_active_mask);
-	new_mems = node_states[N_MEMORY];
+	new_mems = system_ram();
 
 	cpus_updated = !cpumask_equal(top_cpuset.effective_cpus, &new_cpus);
 	mems_updated = !nodes_equal(top_cpuset.effective_mems, new_mems);
@@ -2393,11 +2395,11 @@ static int cpuset_track_online_nodes(struct notifier_block *self,
 void __init cpuset_init_smp(void)
 {
 	cpumask_copy(top_cpuset.cpus_allowed, cpu_active_mask);
-	top_cpuset.mems_allowed = node_states[N_MEMORY];
+	top_cpuset.mems_allowed = system_ram();
 	top_cpuset.old_mems_allowed = top_cpuset.mems_allowed;
 
 	cpumask_copy(top_cpuset.effective_cpus, cpu_active_mask);
-	top_cpuset.effective_mems = node_states[N_MEMORY];
+	top_cpuset.effective_mems = system_ram();
 
 	register_hotmemory_notifier(&cpuset_track_online_nodes_nb);
 
-- 
1.8.3.1

[toc] | [prev] | [next] | [standalone]


#1524152 — [DRAFT 2/2] mm/hugetlb: Restrict HugeTLB allocations only to the system RAM nodes

FromAnshuman Khandual <khandual@linux.vnet.ibm.com>
Date2016-11-17 09:00 +0100
Subject[DRAFT 2/2] mm/hugetlb: Restrict HugeTLB allocations only to the system RAM nodes
Message-ID<sEpLY-69J-23@gated-at.bofh.it>
In reply to#1524151
HugeTLB allocation/release/accounting currently spans across all the nodes
under N_MEMORY mask. CDM nodes should not be part of these. So use
system_ram() call to fetch system RAM only nodes on the platform which can
then be used for HugeTLB purpose instead of N_MEMORY. This isolates CDM
nodes from HugeTLB allocation.

Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
This also completely isolates CDM nodes from user space HugeTLB allocations
. Hence explicit allocation to the CDM nodes would not be possible any more
. To again enable explicit HugeTLB allocation capability from user space,
HugeTLB subsystem needs to be changed.

 mm/hugetlb.c | 32 +++++++++++++++++++++++---------
 1 file changed, 23 insertions(+), 9 deletions(-)

diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 418bf01..1936c5a 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1782,6 +1782,9 @@ static void return_unused_surplus_pages(struct hstate *h,
 					unsigned long unused_resv_pages)
 {
 	unsigned long nr_pages;
+	nodemask_t nodes;
+
+	nodes = system_ram();
 
 	/* Uncommit the reservation */
 	h->resv_huge_pages -= unused_resv_pages;
@@ -1801,7 +1804,7 @@ static void return_unused_surplus_pages(struct hstate *h,
 	 * on-line nodes with memory and will handle the hstate accounting.
 	 */
 	while (nr_pages--) {
-		if (!free_pool_huge_page(h, &node_states[N_MEMORY], 1))
+		if (!free_pool_huge_page(h, &nodes, 1))
 			break;
 		cond_resched_lock(&hugetlb_lock);
 	}
@@ -2088,8 +2091,10 @@ int __weak alloc_bootmem_huge_page(struct hstate *h)
 {
 	struct huge_bootmem_page *m;
 	int nr_nodes, node;
+	nodemask_t nodes;
 
-	for_each_node_mask_to_alloc(h, nr_nodes, node, &node_states[N_MEMORY]) {
+	nodes = system_ram();
+	for_each_node_mask_to_alloc(h, nr_nodes, node, &nodes) {
 		void *addr;
 
 		addr = memblock_virt_alloc_try_nid_nopanic(
@@ -2158,13 +2163,15 @@ static void __init gather_bootmem_prealloc(void)
 static void __init hugetlb_hstate_alloc_pages(struct hstate *h)
 {
 	unsigned long i;
+	nodemask_t nodes;
+
 
+	nodes = system_ram();
 	for (i = 0; i < h->max_huge_pages; ++i) {
 		if (hstate_is_gigantic(h)) {
 			if (!alloc_bootmem_huge_page(h))
 				break;
-		} else if (!alloc_fresh_huge_page(h,
-					 &node_states[N_MEMORY]))
+		} else if (!alloc_fresh_huge_page(h, &nodes))
 			break;
 	}
 	h->max_huge_pages = i;
@@ -2401,8 +2408,11 @@ static ssize_t __nr_hugepages_store_common(bool obey_mempolicy,
 					   unsigned long count, size_t len)
 {
 	int err;
+	nodemask_t ram_nodes;
+
 	NODEMASK_ALLOC(nodemask_t, nodes_allowed, GFP_KERNEL | __GFP_NORETRY);
 
+	ram_nodes = system_ram();
 	if (hstate_is_gigantic(h) && !gigantic_page_supported()) {
 		err = -EINVAL;
 		goto out;
@@ -2415,7 +2425,7 @@ static ssize_t __nr_hugepages_store_common(bool obey_mempolicy,
 		if (!(obey_mempolicy &&
 				init_nodemask_of_mempolicy(nodes_allowed))) {
 			NODEMASK_FREE(nodes_allowed);
-			nodes_allowed = &node_states[N_MEMORY];
+			nodes_allowed = &ram_nodes;
 		}
 	} else if (nodes_allowed) {
 		/*
@@ -2425,11 +2435,11 @@ static ssize_t __nr_hugepages_store_common(bool obey_mempolicy,
 		count += h->nr_huge_pages - h->nr_huge_pages_node[nid];
 		init_nodemask_of_node(nodes_allowed, nid);
 	} else
-		nodes_allowed = &node_states[N_MEMORY];
+		nodes_allowed = &ram_nodes;
 
 	h->max_huge_pages = set_max_huge_pages(h, count, nodes_allowed);
 
-	if (nodes_allowed != &node_states[N_MEMORY])
+	if (nodes_allowed != &ram_nodes)
 		NODEMASK_FREE(nodes_allowed);
 
 	return len;
@@ -2726,9 +2736,11 @@ static void hugetlb_register_node(struct node *node)
  */
 static void __init hugetlb_register_all_nodes(void)
 {
+	nodemask_t nodes;
 	int nid;
 
-	for_each_node_state(nid, N_MEMORY) {
+	nodes = system_ram();
+	for_each_node_mask(nid, nodes) {
 		struct node *node = node_devices[nid];
 		if (node->dev.id == nid)
 			hugetlb_register_node(node);
@@ -2998,13 +3010,15 @@ int hugetlb_report_node_meminfo(int nid, char *buf)
 
 void hugetlb_show_meminfo(void)
 {
+	nodemask_t nodes;
 	struct hstate *h;
 	int nid;
 
 	if (!hugepages_supported())
 		return;
 
-	for_each_node_state(nid, N_MEMORY)
+	nodes = system_ram();
+	for_each_node_mask(nid, nodes)
 		for_each_hstate(h)
 			pr_info("Node %d hugepages_total=%u hugepages_free=%u hugepages_surp=%u hugepages_size=%lukB\n",
 				nid,
-- 
1.8.3.1

[toc] | [prev] | [next] | [standalone]


#1524160 — Re: [DRAFT 1/2] mm/cpuset: Exclude CDM nodes from each task's mems_allowed node mask

Fromkbuild test robot <lkp@intel.com>
Date2016-11-17 09:30 +0100
SubjectRe: [DRAFT 1/2] mm/cpuset: Exclude CDM nodes from each task's mems_allowed node mask
Message-ID<sEqf0-6CB-5@gated-at.bofh.it>
In reply to#1524151

[Multipart message — attachments visible in raw view] — view raw

Hi Anshuman,

[auto build test ERROR on mmotm/master]
[also build test ERROR on v4.9-rc5 next-20161117]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Anshuman-Khandual/mm-cpuset-Exclude-CDM-nodes-from-each-task-s-mems_allowed-node-mask/20161117-160736
base:   git://git.cmpxchg.org/linux-mmotm.git master
config: i386-tinyconfig (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   In file included from include/linux/mmzone.h:16:0,
                    from include/linux/gfp.h:5,
                    from include/linux/slab.h:14,
                    from include/linux/crypto.h:24,
                    from arch/x86/kernel/asm-offsets.c:8:
   include/linux/mm.h: In function 'system_ram':
>> include/linux/mm.h:454:61: error: 'N_COHERENT_DEVICE' undeclared (first use in this function)
     nodes_andnot(ram_nodes, node_states[N_MEMORY], node_states[N_COHERENT_DEVICE]);
                                                                ^
   include/linux/nodemask.h:176:38: note: in definition of macro 'nodes_andnot'
       __nodes_andnot(&(dst), &(src1), &(src2), MAX_NUMNODES)
                                         ^~~~
   include/linux/mm.h:454:61: note: each undeclared identifier is reported only once for each function it appears in
     nodes_andnot(ram_nodes, node_states[N_MEMORY], node_states[N_COHERENT_DEVICE]);
                                                                ^
   include/linux/nodemask.h:176:38: note: in definition of macro 'nodes_andnot'
       __nodes_andnot(&(dst), &(src1), &(src2), MAX_NUMNODES)
                                         ^~~~
   make[2]: *** [arch/x86/kernel/asm-offsets.s] Error 1
   make[2]: Target '__build' not remade because of errors.
   make[1]: *** [prepare0] Error 2
   make[1]: Target 'prepare' not remade because of errors.
   make: *** [sub-make] Error 2

vim +/N_COHERENT_DEVICE +454 include/linux/mm.h

   448	
   449	static inline nodemask_t system_ram(void)
   450	{
   451		nodemask_t ram_nodes;
   452	
   453		nodes_clear(ram_nodes);
 > 454		nodes_andnot(ram_nodes, node_states[N_MEMORY], node_states[N_COHERENT_DEVICE]);
   455		return ram_nodes;
   456	}
   457	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web