From patchwork Mon Jul 16 17:44:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Tatashin X-Patchwork-Id: 10527377 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 69D646037E for ; Mon, 16 Jul 2018 17:45:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 55B7228421 for ; Mon, 16 Jul 2018 17:45:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 49BB328DEF; Mon, 16 Jul 2018 17:45:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-3.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5BD1D28421 for ; Mon, 16 Jul 2018 17:45:22 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 10F936B026A; Mon, 16 Jul 2018 13:45:17 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 0C1A86B026B; Mon, 16 Jul 2018 13:45:17 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id EA1F66B026C; Mon, 16 Jul 2018 13:45:16 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-it0-f70.google.com (mail-it0-f70.google.com [209.85.214.70]) by kanga.kvack.org (Postfix) with ESMTP id BB6F46B026A for ; Mon, 16 Jul 2018 13:45:16 -0400 (EDT) Received: by mail-it0-f70.google.com with SMTP id a10-v6so5288251itc.9 for ; Mon, 16 Jul 2018 10:45:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:dkim-signature:from:to:subject:date:message-id :in-reply-to:references; bh=smbnwxvxDS1GzbcgwK5AYgm8Xz5c26gXK951l1upcHU=; b=RRrqPhQbeyLiaViGP8tceWztS8dZenDVM4AEIuIPoCn3Ko17K/e4mw+46UEbZlbGcP bsfN0046/kwJJnaeOD63dEP1vWM+QhQT75hke8fiHR4ImpPVYptLQsdMfuhoTMmX1NPh j8SmqqqGIOA+Qynh2V7koq6d48yeJYukxqX7PoSgp5VWiriQeq5C2cHyhl/emBea7hZk v8vC78FQ3v91HyQvf9lv9iWXLD+dRUWlylfYR2SeR30VOi7eH2R+xnwTwkRdPxkazZ+9 u+ZeloM42GDdwE+0AW0LiST9mw8uWy/my5Z4eWCKIXyfQRL2HI1LzNu0jui2C5GvQb9q Lc0Q== X-Gm-Message-State: AOUpUlGMKwbmrVkqQoPn8KofNwGnbtxyeFDFpuYBN4uUJ24kMM2NXWlw u3Vdm//DP3syMUInANd6gxF6hfl68x/f1AX7s8MBTAeHSZErPoLONzeNnLux5wUUD9VcHdYljmX 1tOO1XU/0/fr3x3oX9G/q55kly8hVclwz8F6l3w8i5LXPHElicr4ni3Xp+8/Q1PyKDg== X-Received: by 2002:a24:9787:: with SMTP id k129-v6mr14043439ite.51.1531763116534; Mon, 16 Jul 2018 10:45:16 -0700 (PDT) X-Google-Smtp-Source: AAOMgpc1I6c3MCW05bAluoB/Pk0Sp1aC30UvHQFO9Xjf7Fi1FlLWBTSe7VIcLWHDm02IRWThUrHt X-Received: by 2002:a24:9787:: with SMTP id k129-v6mr14043382ite.51.1531763115459; Mon, 16 Jul 2018 10:45:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1531763115; cv=none; d=google.com; s=arc-20160816; b=cQwfu+AEB54CfyH9B8fqclryP6DRJWthEodzpMkBZ+fEZtLmn/Bw8BcW3mLKXq3gb3 tdk10GhIHmg12pKcgTkMRRAwfLAi2x3T32J1vA8LlgKpVa+rYQC8IkAT/J9KvIiAdbn2 X9Qp80oTNssRBDW/bGMMlrLJKKorjvsZLvXLKH462g23io8tfqpOFIyh0AEozDT9TZuU OKeiuozbZJ4I6ZqMKsoY2kFw02yp0iBXfFYOB4Ns6maMKyJMzig5jawgFzZVZKh735Dz lcpanCztOtRCc0bIYo8nBbI7N982hHKvOIToahmIkW4dWiJ1mm3F/JpaWkI2XynW0/lL 3mJg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from :dkim-signature:arc-authentication-results; bh=smbnwxvxDS1GzbcgwK5AYgm8Xz5c26gXK951l1upcHU=; b=ZYHlv3ERArKZFCcW6N4pYoYVjCmMt38a7w2z07NBsK+uGmcCUqDcq0342wUCnkaeM5 3VG2xwoYx+v8Atu1VrThxcVwvuuD8gCzmzstDh0lakAu0xaA7fLdQbXPG0vZNfv6s8xO 1CjoyG+IMTNDxfzccoqBSRpiF0jtfUqxsav1yFW/uS9AIPvYNlzaBKQZLbJMCqpcqY/g uZx0kUZqWtcUbHuNmls40KMeSuPFSqeeeOr3T+Llrc4MIUGx5o26W/GXGrq8oRpRghqI 0yG8YI5lOFfOEpB47Jrb4y/xQr0G2VSvvVIkxZbbVDJa+72MPK/QjU6yLCA0/XimQ1iE R5rQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@oracle.com header.s=corp-2018-07-02 header.b=tDJi2UH0; spf=pass (google.com: domain of pasha.tatashin@oracle.com designates 156.151.31.86 as permitted sender) smtp.mailfrom=pasha.tatashin@oracle.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=oracle.com Received: from userp2130.oracle.com (userp2130.oracle.com. [156.151.31.86]) by mx.google.com with ESMTPS id q77-v6si23112244iod.253.2018.07.16.10.45.15 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 16 Jul 2018 10:45:15 -0700 (PDT) Received-SPF: pass (google.com: domain of pasha.tatashin@oracle.com designates 156.151.31.86 as permitted sender) client-ip=156.151.31.86; Authentication-Results: mx.google.com; dkim=pass header.i=@oracle.com header.s=corp-2018-07-02 header.b=tDJi2UH0; spf=pass (google.com: domain of pasha.tatashin@oracle.com designates 156.151.31.86 as permitted sender) smtp.mailfrom=pasha.tatashin@oracle.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=oracle.com Received: from pps.filterd (userp2130.oracle.com [127.0.0.1]) by userp2130.oracle.com (8.16.0.22/8.16.0.22) with SMTP id w6GHiTKS167369; Mon, 16 Jul 2018 17:45:07 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : subject : date : message-id : in-reply-to : references; s=corp-2018-07-02; bh=smbnwxvxDS1GzbcgwK5AYgm8Xz5c26gXK951l1upcHU=; b=tDJi2UH0k8kuZEqxjO7dx7DzQZEoOlt84X1cKuod1QTjbA9at8sO+1Fmsiqvhl5Xldwv 4fZjmIHVlWAzSmyOalGWOmTspcK8tcZmXXCSF9TeShhlG+/HiAkIvGPOeW+2MWQs3tcq yz6SgbdyaRe7jWRcgJHu4T/z06cbkR36OExE/bbKO7njXAP8ZMLmPdOCqXRYJ2SbzcIM mdSHmLcZjnEQNiE30H/HMMUL+q0D5xBEgXmSwVCs5BEgxxelpzWAmBPjG5bykZaJrmVo 6bmTFdl8T3kuAc6x4U6+PqlGkWYS/t0ZDPpe8oDvqZQ7N/IzhMUEShD6HFO/WG/bu/Ls PQ== Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp2130.oracle.com with ESMTP id 2k7a3t5hhb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 16 Jul 2018 17:45:07 +0000 Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0022.oracle.com (8.14.4/8.14.4) with ESMTP id w6GHj6nR027125 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 16 Jul 2018 17:45:06 GMT Received: from abhmp0013.oracle.com (abhmp0013.oracle.com [141.146.116.19]) by userv0121.oracle.com (8.14.4/8.13.8) with ESMTP id w6GHj5bL010389; Mon, 16 Jul 2018 17:45:05 GMT Received: from localhost.localdomain (/73.69.118.222) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 16 Jul 2018 10:45:04 -0700 From: Pavel Tatashin To: steven.sistare@oracle.com, daniel.m.jordan@oracle.com, linux-kernel@vger.kernel.org, akpm@linux-foundation.org, kirill.shutemov@linux.intel.com, mhocko@suse.com, linux-mm@kvack.org, dan.j.williams@intel.com, jack@suse.cz, jglisse@redhat.com, jrdr.linux@gmail.com, bhe@redhat.com, gregkh@linuxfoundation.org, vbabka@suse.cz, richard.weiyang@gmail.com, dave.hansen@intel.com, rientjes@google.com, mingo@kernel.org, osalvador@techadventures.net, pasha.tatashin@oracle.com, abdhalee@linux.vnet.ibm.com, mpe@ellerman.id.au Subject: [PATCH v6 5/5] mm/sparse: delete old sparse_init and enable new one Date: Mon, 16 Jul 2018 13:44:47 -0400 Message-Id: <20180716174447.14529-6-pasha.tatashin@oracle.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180716174447.14529-1-pasha.tatashin@oracle.com> References: <20180716174447.14529-1-pasha.tatashin@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=8956 signatures=668706 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=2 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1806210000 definitions=main-1807160202 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: X-Virus-Scanned: ClamAV using ClamSMTP Rename new_sparse_init() to sparse_init() which enables it. Delete old sparse_init() and all the code that became obsolete with. Signed-off-by: Pavel Tatashin Tested-by: Michael Ellerman (powerpc) Reviewed-by: Oscar Salvador --- include/linux/mm.h | 6 -- mm/Kconfig | 4 - mm/sparse-vmemmap.c | 21 ---- mm/sparse.c | 237 +------------------------------------------- 4 files changed, 1 insertion(+), 267 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index 99d8c50adef6..726e71475144 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2649,12 +2649,6 @@ extern int randomize_va_space; const char * arch_vma_name(struct vm_area_struct *vma); void print_vma_addr(char *prefix, unsigned long rip); -void sparse_mem_maps_populate_node(struct page **map_map, - unsigned long pnum_begin, - unsigned long pnum_end, - unsigned long map_count, - int nodeid); - void *sparse_buffer_alloc(unsigned long size); struct page *sparse_mem_map_populate(unsigned long pnum, int nid, struct vmem_altmap *altmap); diff --git a/mm/Kconfig b/mm/Kconfig index 28fcf54946ea..b78e7cd4e9fe 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -115,10 +115,6 @@ config SPARSEMEM_EXTREME config SPARSEMEM_VMEMMAP_ENABLE bool -config SPARSEMEM_ALLOC_MEM_MAP_TOGETHER - def_bool y - depends on SPARSEMEM && X86_64 - config SPARSEMEM_VMEMMAP bool "Sparse Memory virtual memmap" depends on SPARSEMEM && SPARSEMEM_VMEMMAP_ENABLE diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c index cd15f3d252c3..8301293331a2 100644 --- a/mm/sparse-vmemmap.c +++ b/mm/sparse-vmemmap.c @@ -261,24 +261,3 @@ struct page * __meminit sparse_mem_map_populate(unsigned long pnum, int nid, return map; } - -void __init sparse_mem_maps_populate_node(struct page **map_map, - unsigned long pnum_begin, - unsigned long pnum_end, - unsigned long map_count, int nodeid) -{ - unsigned long pnum; - int nr_consumed_maps = 0; - - for (pnum = pnum_begin; pnum < pnum_end; pnum++) { - if (!present_section_nr(pnum)) - continue; - - map_map[nr_consumed_maps] = - sparse_mem_map_populate(pnum, nodeid, NULL); - if (map_map[nr_consumed_maps++]) - continue; - pr_err("%s: sparsemem memory map backing failed some memory will not be available\n", - __func__); - } -} diff --git a/mm/sparse.c b/mm/sparse.c index 248d5d7bbf55..10b07eea9a6e 100644 --- a/mm/sparse.c +++ b/mm/sparse.c @@ -205,12 +205,6 @@ static inline unsigned long first_present_section_nr(void) return next_present_section_nr(-1); } -/* - * Record how many memory sections are marked as present - * during system bootup. - */ -static int __initdata nr_present_sections; - /* Record a memory area against a node. */ void __init memory_present(int nid, unsigned long start, unsigned long end) { @@ -240,7 +234,6 @@ void __init memory_present(int nid, unsigned long start, unsigned long end) ms->section_mem_map = sparse_encode_early_nid(nid) | SECTION_IS_ONLINE; section_mark_present(ms); - nr_present_sections++; } } } @@ -377,37 +370,8 @@ static void __init check_usemap_section_nr(int nid, unsigned long *usemap) } #endif /* CONFIG_MEMORY_HOTREMOVE */ -static void __init sparse_early_usemaps_alloc_node(void *data, - unsigned long pnum_begin, - unsigned long pnum_end, - unsigned long usemap_count, int nodeid) -{ - void *usemap; - unsigned long pnum; - unsigned long **usemap_map = (unsigned long **)data; - int size = usemap_size(); - int nr_consumed_maps = 0; - - usemap = sparse_early_usemaps_alloc_pgdat_section(NODE_DATA(nodeid), - size * usemap_count); - if (!usemap) { - pr_warn("%s: allocation failed\n", __func__); - return; - } - - for (pnum = pnum_begin; pnum < pnum_end; pnum++) { - if (!present_section_nr(pnum)) - continue; - usemap_map[nr_consumed_maps] = usemap; - usemap += size; - check_usemap_section_nr(nodeid, usemap_map[nr_consumed_maps]); - nr_consumed_maps++; - } -} - #ifdef CONFIG_SPARSEMEM_VMEMMAP static unsigned long __init section_map_size(void) - { return ALIGN(sizeof(struct page) * PAGES_PER_SECTION, PMD_SIZE); } @@ -432,25 +396,6 @@ struct page __init *sparse_mem_map_populate(unsigned long pnum, int nid, BOOTMEM_ALLOC_ACCESSIBLE, nid); return map; } -void __init sparse_mem_maps_populate_node(struct page **map_map, - unsigned long pnum_begin, - unsigned long pnum_end, - unsigned long map_count, int nodeid) -{ - unsigned long pnum; - int nr_consumed_maps = 0; - - for (pnum = pnum_begin; pnum < pnum_end; pnum++) { - if (!present_section_nr(pnum)) - continue; - map_map[nr_consumed_maps] = - sparse_mem_map_populate(pnum, nodeid, NULL); - if (map_map[nr_consumed_maps++]) - continue; - pr_err("%s: sparsemem memory map backing failed some memory will not be available\n", - __func__); - } -} #endif /* !CONFIG_SPARSEMEM_VMEMMAP */ static void *sparsemap_buf __meminitdata; @@ -489,190 +434,10 @@ void * __meminit sparse_buffer_alloc(unsigned long size) return ptr; } -#ifdef CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER -static void __init sparse_early_mem_maps_alloc_node(void *data, - unsigned long pnum_begin, - unsigned long pnum_end, - unsigned long map_count, int nodeid) -{ - struct page **map_map = (struct page **)data; - - sparse_buffer_init(section_map_size() * map_count, nodeid); - sparse_mem_maps_populate_node(map_map, pnum_begin, pnum_end, - map_count, nodeid); - sparse_buffer_fini(); -} -#else -static struct page __init *sparse_early_mem_map_alloc(unsigned long pnum) -{ - struct page *map; - struct mem_section *ms = __nr_to_section(pnum); - int nid = sparse_early_nid(ms); - - map = sparse_mem_map_populate(pnum, nid, NULL); - if (map) - return map; - - pr_err("%s: sparsemem memory map backing failed some memory will not be available\n", - __func__); - return NULL; -} -#endif - void __weak __meminit vmemmap_populate_print_last(void) { } -/** - * alloc_usemap_and_memmap - memory alloction for pageblock flags and vmemmap - * @map: usemap_map for pageblock flags or mmap_map for vmemmap - * @unit_size: size of map unit - */ -static void __init alloc_usemap_and_memmap(void (*alloc_func) - (void *, unsigned long, unsigned long, - unsigned long, int), void *data, - int data_unit_size) -{ - unsigned long pnum; - unsigned long map_count; - int nodeid_begin = 0; - unsigned long pnum_begin = 0; - - for_each_present_section_nr(0, pnum) { - struct mem_section *ms; - - ms = __nr_to_section(pnum); - nodeid_begin = sparse_early_nid(ms); - pnum_begin = pnum; - break; - } - map_count = 1; - for_each_present_section_nr(pnum_begin + 1, pnum) { - struct mem_section *ms; - int nodeid; - - ms = __nr_to_section(pnum); - nodeid = sparse_early_nid(ms); - if (nodeid == nodeid_begin) { - map_count++; - continue; - } - /* ok, we need to take cake of from pnum_begin to pnum - 1*/ - alloc_func(data, pnum_begin, pnum, - map_count, nodeid_begin); - /* new start, update count etc*/ - nodeid_begin = nodeid; - pnum_begin = pnum; - data += map_count * data_unit_size; - map_count = 1; - } - /* ok, last chunk */ - alloc_func(data, pnum_begin, __highest_present_section_nr+1, - map_count, nodeid_begin); -} - -/* - * Allocate the accumulated non-linear sections, allocate a mem_map - * for each and record the physical to section mapping. - */ -void __init sparse_init(void) -{ - unsigned long pnum; - struct page *map; - unsigned long *usemap; - unsigned long **usemap_map; - int size; - int nr_consumed_maps = 0; -#ifdef CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER - int size2; - struct page **map_map; -#endif - - /* see include/linux/mmzone.h 'struct mem_section' definition */ - BUILD_BUG_ON(!is_power_of_2(sizeof(struct mem_section))); - - /* Setup pageblock_order for HUGETLB_PAGE_SIZE_VARIABLE */ - set_pageblock_order(); - - /* - * map is using big page (aka 2M in x86 64 bit) - * usemap is less one page (aka 24 bytes) - * so alloc 2M (with 2M align) and 24 bytes in turn will - * make next 2M slip to one more 2M later. - * then in big system, the memory will have a lot of holes... - * here try to allocate 2M pages continuously. - * - * powerpc need to call sparse_init_one_section right after each - * sparse_early_mem_map_alloc, so allocate usemap_map at first. - */ - size = sizeof(unsigned long *) * nr_present_sections; - usemap_map = memblock_virt_alloc(size, 0); - if (!usemap_map) - panic("can not allocate usemap_map\n"); - alloc_usemap_and_memmap(sparse_early_usemaps_alloc_node, - (void *)usemap_map, - sizeof(usemap_map[0])); - -#ifdef CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER - size2 = sizeof(struct page *) * nr_present_sections; - map_map = memblock_virt_alloc(size2, 0); - if (!map_map) - panic("can not allocate map_map\n"); - alloc_usemap_and_memmap(sparse_early_mem_maps_alloc_node, - (void *)map_map, - sizeof(map_map[0])); -#endif - - /* - * The number of present sections stored in nr_present_sections - * are kept the same since mem sections are marked as present in - * memory_present(). In this for loop, we need check which sections - * failed to allocate memmap or usemap, then clear its - * ->section_mem_map accordingly. During this process, we need - * increase 'nr_consumed_maps' whether its allocation of memmap - * or usemap failed or not, so that after we handle the i-th - * memory section, can get memmap and usemap of (i+1)-th section - * correctly. - */ - for_each_present_section_nr(0, pnum) { - struct mem_section *ms; - - if (nr_consumed_maps >= nr_present_sections) { - pr_err("nr_consumed_maps goes beyond nr_present_sections\n"); - break; - } - ms = __nr_to_section(pnum); - usemap = usemap_map[nr_consumed_maps]; - if (!usemap) { - ms->section_mem_map = 0; - nr_consumed_maps++; - continue; - } - -#ifdef CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER - map = map_map[nr_consumed_maps]; -#else - map = sparse_early_mem_map_alloc(pnum); -#endif - if (!map) { - ms->section_mem_map = 0; - nr_consumed_maps++; - continue; - } - - sparse_init_one_section(__nr_to_section(pnum), pnum, map, - usemap); - nr_consumed_maps++; - } - - vmemmap_populate_print_last(); - -#ifdef CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER - memblock_free_early(__pa(map_map), size2); -#endif - memblock_free_early(__pa(usemap_map), size); -} - /* * Initialize sparse on a specific node. The node spans [pnum_begin, pnum_end) * And number of present sections in this node is map_count. @@ -726,7 +491,7 @@ static void __init sparse_init_nid(int nid, unsigned long pnum_begin, * Allocate the accumulated non-linear sections, allocate a mem_map * for each and record the physical to section mapping. */ -void __init new_sparse_init(void) +void __init sparse_init(void) { unsigned long pnum_begin = first_present_section_nr(); int nid_begin = sparse_early_nid(__nr_to_section(pnum_begin));