This post discusses balance_pgdat().
reference code base
LA.BF64.1.1-06510-8×94.0 with Android 5.0.0_r2(LRX21M) and Linux kernel 3.10.49.
reference kernel config
call flow of background reclaim
balance_pgdat()
balance_pgdat() returns (order, classzone_idx).
If input order is 3, and balance_pgdat() returns (3, 2), then it implies that balance_pgdat() successfully rebalance all zones from dma to normal and highmem with order-3 high watermark checking.
If input order is 3, and balance_pgdat() returns (0, 2) then it implies that balance_pgdat() fails to rebalance all zones from dma to normal and highmem with order-3 high watermark checking. But it successfully rebalance all zones from dma to normal and highmem with order-0 high watermark checking.
kswapd() checks return value of balance_pgdat(). If the return order is less than input order, then kswapd() knows that the rebalance fails, so it avoids updating (new_order, new_classzone_idx) to make kswapd possible to sleep after rebalance failure.
Simple code flow of balance_pgdat:
conclusion
This post discusses balance_pgdat(). It gives a simplified code flow of balance_pgdat(). The return order of balance_pgdat() indicates if rebalance succeeds or not. balance_pgdat() also returns classzone_idx. If classzone_idx is 2, then it balance_pgdat() shrinks dma, normal, and highmem zones. The loop in balance_pgdat() repeats until pgdat_balanced() return trues. But the pgdat_balance() might be due to updating order as 0.