Web lists-archives.com

Re: [PATCH v3] mm, page_alloc: find movable zone after kernel text




Hi Baoquan,

I love your patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v4.18-rc4 next-20180711]
[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/Baoquan-He/mm-page_alloc-find-movable-zone-after-kernel-text/20180711-234359
config: x86_64-randconfig-x007-201827 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All warnings (new ones prefixed by >>):

   In file included from include/asm-generic/bug.h:5:0,
                    from arch/x86/include/asm/bug.h:83,
                    from include/linux/bug.h:5,
                    from include/linux/mmdebug.h:5,
                    from include/linux/mm.h:9,
                    from mm/page_alloc.c:18:
   mm/page_alloc.c: In function 'find_zone_movable_pfns_for_nodes':
   include/linux/pfn.h:19:40: error: invalid operands to binary >> (have 'char *' and 'int')
    #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
                       ~~~~~~~~~~~~~~~~~~~ ^
   include/linux/compiler.h:58:30: note: in definition of macro '__trace_if'
     if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
                                 ^~~~
   mm/page_alloc.c:6689:4: note: in expansion of macro 'if'
       if (pfn_to_nid(PFN_UP(_etext)) == i)
       ^~
>> mm/page_alloc.c:6689:8: note: in expansion of macro 'pfn_to_nid'
       if (pfn_to_nid(PFN_UP(_etext)) == i)
           ^~~~~~~~~~
   mm/page_alloc.c:6689:19: note: in expansion of macro 'PFN_UP'
       if (pfn_to_nid(PFN_UP(_etext)) == i)
                      ^~~~~~
   include/linux/pfn.h:19:40: error: invalid operands to binary >> (have 'char *' and 'int')
    #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
                       ~~~~~~~~~~~~~~~~~~~ ^
   include/linux/compiler.h:58:42: note: in definition of macro '__trace_if'
     if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
                                             ^~~~
   mm/page_alloc.c:6689:4: note: in expansion of macro 'if'
       if (pfn_to_nid(PFN_UP(_etext)) == i)
       ^~
>> mm/page_alloc.c:6689:8: note: in expansion of macro 'pfn_to_nid'
       if (pfn_to_nid(PFN_UP(_etext)) == i)
           ^~~~~~~~~~
   mm/page_alloc.c:6689:19: note: in expansion of macro 'PFN_UP'
       if (pfn_to_nid(PFN_UP(_etext)) == i)
                      ^~~~~~
   include/linux/pfn.h:19:40: error: invalid operands to binary >> (have 'char *' and 'int')
    #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
                       ~~~~~~~~~~~~~~~~~~~ ^
   include/linux/compiler.h:69:16: note: in definition of macro '__trace_if'
      ______r = !!(cond);     \
                   ^~~~
   mm/page_alloc.c:6689:4: note: in expansion of macro 'if'
       if (pfn_to_nid(PFN_UP(_etext)) == i)
       ^~
>> mm/page_alloc.c:6689:8: note: in expansion of macro 'pfn_to_nid'
       if (pfn_to_nid(PFN_UP(_etext)) == i)
           ^~~~~~~~~~
   mm/page_alloc.c:6689:19: note: in expansion of macro 'PFN_UP'
       if (pfn_to_nid(PFN_UP(_etext)) == i)
                      ^~~~~~
   In file included from include/asm-generic/bug.h:18:0,
                    from arch/x86/include/asm/bug.h:83,
                    from include/linux/bug.h:5,
                    from include/linux/mmdebug.h:5,
                    from include/linux/mm.h:9,
                    from mm/page_alloc.c:18:
   include/linux/pfn.h:19:40: error: invalid operands to binary >> (have 'char *' and 'int')
    #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
                       ~~~~~~~~~~~~~~~~~~~ ^
   include/linux/kernel.h:812:40: note: in definition of macro '__typecheck'
      (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1)))
                                           ^
   include/linux/kernel.h:836:24: note: in expansion of macro '__safe_cmp'
     __builtin_choose_expr(__safe_cmp(x, y), \
                           ^~~~~~~~~~
   include/linux/kernel.h:852:19: note: in expansion of macro '__careful_cmp'
    #define max(x, y) __careful_cmp(x, y, >)
                      ^~~~~~~~~~~~~
   mm/page_alloc.c:6690:21: note: in expansion of macro 'max'
        real_startpfn = max(usable_startpfn,
                        ^~~
   mm/page_alloc.c:6691:7: note: in expansion of macro 'PFN_UP'
          PFN_UP(_etext))
          ^~~~~~
   include/linux/pfn.h:19:40: error: invalid operands to binary >> (have 'char *' and 'int')
    #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
                       ~~~~~~~~~~~~~~~~~~~ ^
   include/linux/kernel.h:820:48: note: in definition of macro '__is_constexpr'
     (sizeof(int) == sizeof(*(8 ? ((void *)((long)(x) * 0l)) : (int *)8)))
                                                   ^
   include/linux/kernel.h:826:25: note: in expansion of macro '__no_side_effects'
      (__typecheck(x, y) && __no_side_effects(x, y))
                            ^~~~~~~~~~~~~~~~~
   include/linux/kernel.h:836:24: note: in expansion of macro '__safe_cmp'
     __builtin_choose_expr(__safe_cmp(x, y), \
                           ^~~~~~~~~~
   include/linux/kernel.h:852:19: note: in expansion of macro '__careful_cmp'
    #define max(x, y) __careful_cmp(x, y, >)
                      ^~~~~~~~~~~~~
   mm/page_alloc.c:6690:21: note: in expansion of macro 'max'
        real_startpfn = max(usable_startpfn,
                        ^~~
   mm/page_alloc.c:6691:7: note: in expansion of macro 'PFN_UP'
          PFN_UP(_etext))
          ^~~~~~
   include/linux/pfn.h:19:40: error: invalid operands to binary >> (have 'char *' and 'int')
    #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
                       ~~~~~~~~~~~~~~~~~~~ ^
   include/linux/kernel.h:828:34: note: in definition of macro '__cmp'
    #define __cmp(x, y, op) ((x) op (y) ? (x) : (y))
                                     ^
   include/linux/kernel.h:852:19: note: in expansion of macro '__careful_cmp'
    #define max(x, y) __careful_cmp(x, y, >)
                      ^~~~~~~~~~~~~
   mm/page_alloc.c:6690:21: note: in expansion of macro 'max'
        real_startpfn = max(usable_startpfn,
                        ^~~
   mm/page_alloc.c:6691:7: note: in expansion of macro 'PFN_UP'
          PFN_UP(_etext))
          ^~~~~~
   include/linux/pfn.h:19:40: error: invalid operands to binary >> (have 'char *' and 'int')
    #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
                       ~~~~~~~~~~~~~~~~~~~ ^
   include/linux/kernel.h:828:46: note: in definition of macro '__cmp'
    #define __cmp(x, y, op) ((x) op (y) ? (x) : (y))
                                                 ^
   include/linux/kernel.h:852:19: note: in expansion of macro '__careful_cmp'
    #define max(x, y) __careful_cmp(x, y, >)
                      ^~~~~~~~~~~~~
   mm/page_alloc.c:6690:21: note: in expansion of macro 'max'
        real_startpfn = max(usable_startpfn,
                        ^~~
   mm/page_alloc.c:6691:7: note: in expansion of macro 'PFN_UP'
          PFN_UP(_etext))
          ^~~~~~
   include/linux/pfn.h:19:40: error: invalid operands to binary >> (have 'char *' and 'int')
    #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
                       ~~~~~~~~~~~~~~~~~~~ ^
   include/linux/kernel.h:832:10: note: in definition of macro '__cmp_once'
      typeof(y) unique_y = (y);  \
             ^
   include/linux/kernel.h:852:19: note: in expansion of macro '__careful_cmp'
    #define max(x, y) __careful_cmp(x, y, >)
                      ^~~~~~~~~~~~~
   mm/page_alloc.c:6690:21: note: in expansion of macro 'max'
        real_startpfn = max(usable_startpfn,
                        ^~~
   mm/page_alloc.c:6691:7: note: in expansion of macro 'PFN_UP'
          PFN_UP(_etext))
          ^~~~~~
   include/linux/pfn.h:19:40: error: invalid operands to binary >> (have 'char *' and 'int')
    #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
                       ~~~~~~~~~~~~~~~~~~~ ^
   include/linux/kernel.h:832:25: note: in definition of macro '__cmp_once'
      typeof(y) unique_y = (y);  \

vim +/pfn_to_nid +6689 mm/page_alloc.c

  6540	
  6541	/*
  6542	 * Find the PFN the Movable zone begins in each node. Kernel memory
  6543	 * is spread evenly between nodes as long as the nodes have enough
  6544	 * memory. When they don't, some nodes will have more kernelcore than
  6545	 * others
  6546	 */
  6547	static void __init find_zone_movable_pfns_for_nodes(void)
  6548	{
  6549		int i, nid;
  6550		unsigned long usable_startpfn, real_startpfn;
  6551		unsigned long kernelcore_node, kernelcore_remaining;
  6552		/* save the state before borrow the nodemask */
  6553		nodemask_t saved_node_state = node_states[N_MEMORY];
  6554		unsigned long totalpages = early_calculate_totalpages();
  6555		int usable_nodes = nodes_weight(node_states[N_MEMORY]);
  6556		struct memblock_region *r;
  6557	
  6558		/* Need to find movable_zone earlier when movable_node is specified. */
  6559		find_usable_zone_for_movable();
  6560	
  6561		/*
  6562		 * If movable_node is specified, ignore kernelcore and movablecore
  6563		 * options.
  6564		 */
  6565		if (movable_node_is_enabled()) {
  6566			for_each_memblock(memory, r) {
  6567				if (!memblock_is_hotpluggable(r))
  6568					continue;
  6569	
  6570				nid = r->nid;
  6571	
  6572				usable_startpfn = PFN_DOWN(r->base);
  6573				zone_movable_pfn[nid] = zone_movable_pfn[nid] ?
  6574					min(usable_startpfn, zone_movable_pfn[nid]) :
  6575					usable_startpfn;
  6576			}
  6577	
  6578			goto out2;
  6579		}
  6580	
  6581		/*
  6582		 * If kernelcore=mirror is specified, ignore movablecore option
  6583		 */
  6584		if (mirrored_kernelcore) {
  6585			bool mem_below_4gb_not_mirrored = false;
  6586	
  6587			for_each_memblock(memory, r) {
  6588				if (memblock_is_mirror(r))
  6589					continue;
  6590	
  6591				nid = r->nid;
  6592	
  6593				usable_startpfn = memblock_region_memory_base_pfn(r);
  6594	
  6595				if (usable_startpfn < 0x100000) {
  6596					mem_below_4gb_not_mirrored = true;
  6597					continue;
  6598				}
  6599	
  6600				zone_movable_pfn[nid] = zone_movable_pfn[nid] ?
  6601					min(usable_startpfn, zone_movable_pfn[nid]) :
  6602					usable_startpfn;
  6603			}
  6604	
  6605			if (mem_below_4gb_not_mirrored)
  6606				pr_warn("This configuration results in unmirrored kernel memory.");
  6607	
  6608			goto out2;
  6609		}
  6610	
  6611		/*
  6612		 * If kernelcore=nn% or movablecore=nn% was specified, calculate the
  6613		 * amount of necessary memory.
  6614		 */
  6615		if (required_kernelcore_percent)
  6616			required_kernelcore = (totalpages * 100 * required_kernelcore_percent) /
  6617					       10000UL;
  6618		if (required_movablecore_percent)
  6619			required_movablecore = (totalpages * 100 * required_movablecore_percent) /
  6620						10000UL;
  6621	
  6622		/*
  6623		 * If movablecore= was specified, calculate what size of
  6624		 * kernelcore that corresponds so that memory usable for
  6625		 * any allocation type is evenly spread. If both kernelcore
  6626		 * and movablecore are specified, then the value of kernelcore
  6627		 * will be used for required_kernelcore if it's greater than
  6628		 * what movablecore would have allowed.
  6629		 */
  6630		if (required_movablecore) {
  6631			unsigned long corepages;
  6632	
  6633			/*
  6634			 * Round-up so that ZONE_MOVABLE is at least as large as what
  6635			 * was requested by the user
  6636			 */
  6637			required_movablecore =
  6638				roundup(required_movablecore, MAX_ORDER_NR_PAGES);
  6639			required_movablecore = min(totalpages, required_movablecore);
  6640			corepages = totalpages - required_movablecore;
  6641	
  6642			required_kernelcore = max(required_kernelcore, corepages);
  6643		}
  6644	
  6645		/*
  6646		 * If kernelcore was not specified or kernelcore size is larger
  6647		 * than totalpages, there is no ZONE_MOVABLE.
  6648		 */
  6649		if (!required_kernelcore || required_kernelcore >= totalpages)
  6650			goto out;
  6651	
  6652		/* usable_startpfn is the lowest possible pfn ZONE_MOVABLE can be at */
  6653		usable_startpfn = arch_zone_lowest_possible_pfn[movable_zone];
  6654	
  6655	restart:
  6656		/* Spread kernelcore memory as evenly as possible throughout nodes */
  6657		kernelcore_node = required_kernelcore / usable_nodes;
  6658		for_each_node_state(nid, N_MEMORY) {
  6659			unsigned long start_pfn, end_pfn;
  6660	
  6661			/*
  6662			 * Recalculate kernelcore_node if the division per node
  6663			 * now exceeds what is necessary to satisfy the requested
  6664			 * amount of memory for the kernel
  6665			 */
  6666			if (required_kernelcore < kernelcore_node)
  6667				kernelcore_node = required_kernelcore / usable_nodes;
  6668	
  6669			/*
  6670			 * As the map is walked, we track how much memory is usable
  6671			 * by the kernel using kernelcore_remaining. When it is
  6672			 * 0, the rest of the node is usable by ZONE_MOVABLE
  6673			 */
  6674			kernelcore_remaining = kernelcore_node;
  6675	
  6676			/* Go through each range of PFNs within this node */
  6677			for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, NULL) {
  6678				unsigned long size_pages;
  6679	
  6680				start_pfn = max(start_pfn, zone_movable_pfn[nid]);
  6681				if (start_pfn >= end_pfn)
  6682					continue;
  6683	
  6684				/*
  6685				 * KASLR may put kernel near tail of node memory,
  6686				 * start after kernel on that node to find PFN
  6687				 * which zone begins.
  6688				 */
> 6689				if (pfn_to_nid(PFN_UP(_etext)) == i)
  6690					real_startpfn = max(usable_startpfn,
  6691							PFN_UP(_etext))
  6692				else
  6693					real_startpfn = usable_startpfn;
  6694				/* Account for what is only usable for kernelcore */
  6695				if (start_pfn < real_startpfn) {
  6696					unsigned long kernel_pages;
  6697					kernel_pages = min(end_pfn, real_startpfn)
  6698									- start_pfn;
  6699	
  6700					kernelcore_remaining -= min(kernel_pages,
  6701								kernelcore_remaining);
  6702					required_kernelcore -= min(kernel_pages,
  6703								required_kernelcore);
  6704	
  6705					/* Continue if range is now fully accounted */
  6706					if (end_pfn <= real_startpfn) {
  6707	
  6708						/*
  6709						 * Push zone_movable_pfn to the end so
  6710						 * that if we have to rebalance
  6711						 * kernelcore across nodes, we will
  6712						 * not double account here
  6713						 */
  6714						zone_movable_pfn[nid] = end_pfn;
  6715						continue;
  6716					}
  6717					start_pfn = real_startpfn;
  6718				}
  6719	
  6720				/*
  6721				 * The usable PFN range for ZONE_MOVABLE is from
  6722				 * start_pfn->end_pfn. Calculate size_pages as the
  6723				 * number of pages used as kernelcore
  6724				 */
  6725				size_pages = end_pfn - start_pfn;
  6726				if (size_pages > kernelcore_remaining)
  6727					size_pages = kernelcore_remaining;
  6728				zone_movable_pfn[nid] = start_pfn + size_pages;
  6729	
  6730				/*
  6731				 * Some kernelcore has been met, update counts and
  6732				 * break if the kernelcore for this node has been
  6733				 * satisfied
  6734				 */
  6735				required_kernelcore -= min(required_kernelcore,
  6736									size_pages);
  6737				kernelcore_remaining -= size_pages;
  6738				if (!kernelcore_remaining)
  6739					break;
  6740			}
  6741		}
  6742	
  6743		/*
  6744		 * If there is still required_kernelcore, we do another pass with one
  6745		 * less node in the count. This will push zone_movable_pfn[nid] further
  6746		 * along on the nodes that still have memory until kernelcore is
  6747		 * satisfied
  6748		 */
  6749		usable_nodes--;
  6750		if (usable_nodes && required_kernelcore > usable_nodes)
  6751			goto restart;
  6752	
  6753	out2:
  6754		/* Align start of ZONE_MOVABLE on all nids to MAX_ORDER_NR_PAGES */
  6755		for (nid = 0; nid < MAX_NUMNODES; nid++)
  6756			zone_movable_pfn[nid] =
  6757				roundup(zone_movable_pfn[nid], MAX_ORDER_NR_PAGES);
  6758	
  6759	out:
  6760		/* restore the node_state */
  6761		node_states[N_MEMORY] = saved_node_state;
  6762	}
  6763	

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

Attachment: .config.gz
Description: application/gzip