----- Original Message -----
Hi Dave,
>but the following caliculation of NR_SECTION_ROOTS() looks suspicious
>to me.
>#define NR_SECTION_ROOTS() (NR_MEM_SECTIONS() / SECTIONS_PER_ROOT())
>
>Something like (((NR_MEM_SECTIONS() - 1)/ SECTIONS_PER_ROOT()) + 1) ?
Now I am quite sure the definition of NR_SECTION_ROOTS() is wrong.
In the upstream kernel, I found the following
include/linux/mmzone.h
...
994 #define SECTION_NR_TO_ROOT(sec) ((sec) / SECTIONS_PER_ROOT)
995 #define NR_SECTION_ROOTS DIV_ROUND_UP(NR_MEM_SECTIONS, SECTIONS_PER_ROOT)
996 #define SECTION_ROOT_MASK (SECTIONS_PER_ROOT - 1)
and include/kernel.h DIV_ROUND_UP is defined as follows,
58 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
I hope you can take care of this.
By the way, I think _SECTION_SIZE_BITS issue is a separate issue.
Best Regard,
Takuo
Hello Takuo,
Very interesting -- the change to the NR_SECTION_ROOTS() calculation was
only commited upstream *yesterday*:
commit 0faa56389c793cda7f967117415717bbab24fe4e
Author: Marcelo Roberto Jimenez <mroberto(a)cpti.cetuc.puc-rio.br>
Date: Mon May 24 14:32:47 2010 -0700
mm: fix NR_SECTION_ROOTS == 0 when using using sparsemem extreme.
Got this while compiling for ARM/SA1100:
mm/sparse.c: In function '__section_nr':
mm/sparse.c:135: warning: 'root' is used uninitialized in this function
This patch follows Russell King's suggestion for a new calculation for
NR_SECTION_ROOTS. Thanks also to Sergei Shtylyov for pointing out the
existence of the macro DIV_ROUND_UP.
Atsushi Nemoto observed:
: This fix doesn't just silence the warning - it fixes a real problem.
:
: Without this fix, mem_section[] might have 0 size so mem_section[0]
: will share other variable area. For example, I got:
:
: c030c700 b __warned.16478
: c030c700 B mem_section
: c030c701 b __warned.16483
:
: This might cause very strange behavior. Your patch actually fixes it.
Signed-off-by: Marcelo Roberto Jimenez <mroberto(a)cpti.cetuc.puc-rio.br>
Cc: Atsushi Nemoto <anemo(a)mba.ocn.ne.jp>
Cc: KOSAKI Motohiro <kosaki.motohiro(a)jp.fujitsu.com>
Cc: Christoph Lameter <cl(a)linux-foundation.org>
Cc: Mel Gorman <mel(a)csn.ul.ie>
Cc: Minchan Kim <minchan.kim(a)gmail.com>
Cc: Yinghai Lu <yinghai(a)kernel.org>
Cc: Sergei Shtylyov <sshtylyov(a)mvista.com>
Cc: Russell King <rmk(a)arm.linux.org.uk>
Signed-off-by: Andrew Morton <akpm(a)linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds(a)linux-foundation.org>
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index fd55f72..f6f2c50 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -981,7 +981,7 @@ struct mem_section {
#endif
#define SECTION_NR_TO_ROOT(sec) ((sec) / SECTIONS_PER_ROOT)
-#define NR_SECTION_ROOTS (NR_MEM_SECTIONS / SECTIONS_PER_ROOT)
+#define NR_SECTION_ROOTS DIV_ROUND_UP(NR_MEM_SECTIONS, SECTIONS_PER_ROOT)
#define SECTION_ROOT_MASK (SECTIONS_PER_ROOT - 1)
#ifdef CONFIG_SPARSEMEM_EXTREME
I'll test this out, and presuming that nothing breaks w/respect to
backwards compatibility, I'll change the crash version of NR_SECTION_ROOTS.
But, as you state, the _SECTION_SIZE_BITS is based upon whatever your
kernel is doing.
Thanks,
Dave