----- Original Message -----
Dne Čt 12. ledna 2012 22:38:38 Petr Tesarik napsal(a):
> Hi all,
>
> it seems crash shows incorrect HighMem stats with recent kernels.
> E.g.:
>
> crash> kmem -i
> [...]
> TOTAL HIGH 1821682 6.9 GB 93% of TOTAL MEM
> FREE HIGH 0 0 0% of TOTAL HIGH
> TOTAL LOW 132983 519.5 MB 6% of TOTAL MEM
> FREE LOW 1333474 5.1 GB 1002% of TOTAL LOW
>
> BTW note that total low is smaller than free low, which is obviously
> incorrect. I believe that this is somehow related to the Movable zone,
> because the code that counts free low pages checks for pages which belong
> to ZONE_HIGHMEM, which is initialized as:
>
> vt->ZONE_HIGHMEM = vt->nr_zones - 1;
>
> My system has 4 zones:
>
> ZONE NAME SIZE MEM_MAP START_PADDR START_MAPNR
> 0 DMA 4080 f4a02200 10000 0
> 1 Normal 221694 f4a22000 1000000 4080
> 2 HighMem 790002 f50e5fc0 371fe000 225774
> 3 Movable 0 0 0 0
>
> And indeed, "help -v" shows:
> [...]
> dump_free_pages: dump_free_pages_zones_v2()
> [...]
> ZONE_HIGHMEM: 3
>
> I don't know yet how to fix this, but maybe somebody can push me in
> the
> right direction.
Maybe we should check the names in zone_names[]. AFAICS this array has existed
ever since the dawn of time, and the HIGHMEM_ZONE has always been called
"HighMem".
I agree -- I'm sure my original intent was based upon paranoia that it
might change.
That already covers a lot of cases, but not the Movable zone, if it
exists.
nr_free_highpages() contains:
if (zone_movable_is_highmem())
pages += zone_page_state(
&pgdat->node_zones[ZONE_MOVABLE],
NR_FREE_PAGES);
zone_movable_is_highmem() is defined as:
static inline int zone_movable_is_highmem(void)
{
#if defined(CONFIG_HIGHMEM) &&
defined(CONFIG_ARCH_POPULATES_NODE_MAP)
return movable_zone == ZONE_HIGHMEM;
#else
return 0;
#endif
}
Now, I think we don't have to take the preprocessor directives into account,
because movable_zone is automatically initialized to zero, and ZONE_HIGHMEM
can never be numerically equal to zero, so the test would be always false in
that case anyway.
Maybe you could first determine whether the kernel symbol "movable_zone" exists,
and if so, what it contains:
...
int movable_zone;
EXPORT_SYMBOL(movable_zone);
#endif /* CONFIG_HAVE_MEMBLOCK_NODE_MAP */
We should only set vt->HIGHMEM_ZONE to something special (such as -1) if
CONFIG_HIGHMEM is not defined, and there is no highmem zone, because otherwise
we might hit a false positive for zone_movable_is_highmem.
Comments? Should I make the idea into a patch?
Absolutely -- I'm waiting... ;-)
Thanks,
Dave