Messages in this thread | | | From | pacman@manson ... | Subject | swapping problem 2.4.16 | Date | Tue, 18 Dec 2001 11:25:09 -0500 (EST) |
| |
My machine (8 MB RAM, please hold the applause) hangs with 2.4.16 whenever it needs to swap (which usually coincides with the launching of gettys).
AltGr+ScrollLock during the freeze shows a call trace like this: sys_newstat->getname->kmalloc->try_to_free_pages->shrink_caches->shrink_cache (some entries omitted; all this data is from pencil-and-paper notes, there may be some transcription errors)
Shift+ScrollLock says this:
Mem-info: Free pages: 84 kB (0kB HighMem) Zone:DMA freepages: 84kB min: 80kB low: 160kB high: 240kB Zone:Normal freepages: 0kB min: 0kB low: 0kB high: 0kB Zone:HighMem freepages: 0kB min: 0kB low: 0kB high: 0kB ( Active: 84, inactive: 1360, free: 21 ) 1*4kB 0*8kB 1*16kB 0*32kB 1*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB = 84 kB) = 0 kB) = 0 kB) Swap cache: add 0, delete 0, find 0/0, race 0+0 Free swap: 31076 kB 2048 pages of RAM 0 pages of HIGHMEM 394 reserved pages 877 pages shared 0 pages swap cached 8 pages in page table cache Buffer memory: 92kB
Loading up shrink_cache with printks was very revealing. shrink_cache is called repeatedly, with nr_pages=32 with priority looping from 6 down to 1, and it returns 32 every time. I don't understand exactly how shrink_cache is supposed to work, but I assume that what I need it to do is call swap_out(). That call is never being reached, because of these formulae:
int max_scan = nr_inactive_pages / priority; int max_mapped = nr_pages << (9 - priority);
max_scan is the number of iterations of the big loop that surrounds most of the function. max_mapped is decremented at most once per iteration of that outer loop, and swap_out will never be called until max_mapped reaches 0. Therefore if the initial value of max_mapped is greater than the initial value of max_scan, there is no chance of reaching the swap_out() call. And using my numbers:
max_scan = max_mapped = priority | nr_inactive_pages / priority | nr_pages << (9 - priority) 6 | 1360 / 6 = 226 | 32 << 3 = 256 5 | 1360 / 5 = 272 | 32 << 4 = 512 4 | 1360 / 4 = 340 | 32 << 5 = 1024 3 | 1360 / 3 = 453 | 32 << 6 = 2048 2 | 1360 / 2 = 680 | 32 << 7 = 4096 1 | 1360 / 1 = 1360 | 32 << 8 = 8192
Not only is max_mapped larger than max_scan, the gap between them widens as the priority approaches 1. That seems to go against my understanding of what the priority is supposed to mean - that as you get close to 1 you should get *more* likely to swap something out.
As an experiment I changed this statement:
if (--max_mapped >= 0) continue;
to this:
if (--max_mapped >= 0 && priority!=1) continue;
and now it boots, swaps, and survives.
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |