[Crash-utility] Incorrect HighMem statistics

Petr Tesarik ptesarik at suse.cz
Thu Jan 12 22:10:25 UTC 2012


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".

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.

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?

Petr Tesarik
SUSE Linux




More information about the Crash-utility mailing list