From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-m49211.qiye.163.com (mail-m49211.qiye.163.com [45.254.49.211]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A7C2342B728 for ; Tue, 16 Jun 2026 10:56:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.254.49.211 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781607394; cv=none; b=DVeVj/X83llkAcwwWERVKPbOomQWb/CBq+K3CNVe7WruF/xPyBm1IIU9WkMSmBx+JPOvYVC5xDMRo7FrEuS5h5g9XoRojqJzVpnAYKjSVV0mt42MuMhSaT8hjsbD23TEILYFDxG5CwuVWtf3H3+rv0gIKYAALnZcV1usnxHYAbA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781607394; c=relaxed/simple; bh=vy5KpyDRtFM72MtlAGWyz+UuDX1+p3gan822+rTl3qI=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=kzEne6oTx2Qsjge8UvK190t/ZsdCTi3cKS4MV68j+N608FcV2ApRrJiULKM8AEjEesxYesRwxzytQQvgIgqdd4qFcWQVDk5xiKZDQm6L8JrqErZk9BRSa99wtPOwLBeSWL++JpLYk2EXhFMZhXZqgc7iJylsTyyTcdJGfLfe9k0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=easystack.cn; spf=pass smtp.mailfrom=easystack.cn; arc=none smtp.client-ip=45.254.49.211 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=easystack.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=easystack.cn Received: from localhost.localdomain (unknown [218.94.118.90]) by smtp.qiye.163.com (Hmail) with ESMTP id 1b7c757ec; Tue, 16 Jun 2026 10:59:52 +0800 (GMT+08:00) From: Zhen Ni To: Andrew Morton , Kairui Song , Qi Zheng , Shakeel Butt , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, Zhen Ni Subject: [PATCH] mm/sparse: Optimize section number calculations using bit shifts Date: Tue, 16 Jun 2026 10:59:42 +0800 Message-Id: <20260616025942.3572473-1-zhen.ni@easystack.cn> X-Mailer: git-send-email 2.20.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-HM-Tid: 0a9ece5efc390229kunm8a3940772c26c X-HM-MType: 1 X-HM-Spam-Status: e1kfGhgUHx5ZQUpXWQgPGg8OCBgUHx5ZQUlOS1dZFg8aDwILHllBWSg2Ly tZV1koWUFJQjdXWRgWCB1ZQUpXWS1ZQUlXWQ8JGhUIEh9ZQVlDHhlCVhhNHkMYQ0JISUhKTVYVFA kWGhdVGRETFhoSFyQUDg9ZV1kYEgtZQVlJSkNVQk9VSkpDVUJLWVdZFhoPEhUdFFlBWU9LSFVKS0 lPT09IVUpLS1VKQktLWQY+ Add SECTIONS_PER_ROOT_SHIFT = ilog2(SECTIONS_PER_ROOT) with correctness guaranteed by BUILD_BUG_ON in sparse_init(). Convert SECTION_NR_TO_ROOT to use right shift instead of division for better performance. Add SECTION_NR_IN_ROOT() macro to improve code readability. This improves code efficiency in hot paths where __nr_to_section() is frequently called, such as sparse_init() and memory section management operations. Performance verification in sparse_init() on ARM (8GB RAM, 4 NUMA nodes): sparse_init() | +----> memblocks_present() | +----> section initialization (sparse_init_nid loop) Time measurement points: [T1] sparse_init start | v [T2] memblocks_present() complete | v [T3] sparse_init_nid() loop complete / sparse_init end Measurement values: memblocks_present_cycles = T2 - T1 section_initialization_cycles = T3 - T2 total_cycles = T3 - T1 Before (division): [ 0.000000] sparse_init: total 7538 cycles [ 0.000000] memblocks_present: 4232 cycles [ 0.000000] section initialization: 3261 cycles After (bit shift): [ 0.000000] sparse_init: total 5641 cycles [ 0.000000] memblocks_present: 3562 cycles [ 0.000000] section initialization: 2057 cycles Performance improvement: Total: (7538-5641)/7538 = 25.2% faster memblocks_present: (4232-3562)/4232 = 15.8% faster section initialization: (3261-2057)/3261 = 36.9% faster Signed-off-by: Zhen Ni --- include/linux/mmzone.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 9adb2ad21da5..5daf471f6823 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -2035,11 +2035,14 @@ struct mem_section { #ifdef CONFIG_SPARSEMEM_EXTREME #define SECTIONS_PER_ROOT (PAGE_SIZE / sizeof (struct mem_section)) +#define SECTIONS_PER_ROOT_SHIFT ilog2(SECTIONS_PER_ROOT) #else #define SECTIONS_PER_ROOT 1 +#define SECTIONS_PER_ROOT_SHIFT 0 #endif -#define SECTION_NR_TO_ROOT(sec) ((sec) / SECTIONS_PER_ROOT) +#define SECTION_NR_TO_ROOT(sec) ((sec) >> SECTIONS_PER_ROOT_SHIFT) +#define SECTION_NR_IN_ROOT(sec) ((sec) & SECTION_ROOT_MASK) #define NR_SECTION_ROOTS DIV_ROUND_UP(NR_MEM_SECTIONS, SECTIONS_PER_ROOT) #define SECTION_ROOT_MASK (SECTIONS_PER_ROOT - 1) @@ -2065,7 +2068,7 @@ static inline struct mem_section *__nr_to_section(unsigned long nr) if (!mem_section || !mem_section[root]) return NULL; #endif - return &mem_section[root][nr & SECTION_ROOT_MASK]; + return &mem_section[root][SECTION_NR_IN_ROOT(nr)]; } extern size_t mem_section_usage_size(void); -- 2.20.1