From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: <329d8901cc6fd72ba935ebbb2c5e2d84@felloff.net> Date: Sat, 1 Mar 2014 22:46:00 +0100 From: cinap_lenrek@felloff.net To: 9fans@9fans.net MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Subject: [9fans] imagereclaim() Topicbox-Message-UUID: bfab48f2-ead8-11e9-9d60-3106f5b1d025 the imagereclaim algorithm is wrong. /* * All the pages with images backing them are at the * end of the list (see putpage) so start there and work * backward. */ for(p = palloc.tail; p && p->image && n<1000; p = p->prev) { if(p->ref == 0 && canlock(p)) { if(p->ref == 0) { n++; uncachepage(p); } unlock(p); } } 1) the uncachepage() call breaks the invariant that pages cached in a image are at the end of the page freelist. this can cause a gab of uncached pages in a run of cached pages from the end of the freelist. imagereclaim() will be unable to reclaim the images refered by the pages after the gab. in 9front, we unchain the page and put it back on the head of the freelist after uncachepage(). 2) there needs to a check to skip pages with p->imagge->notext != 0 in case you use the mount cache (port/cache.c). trying to uncache a page on a notext image will not reclaim any image structures. 3) bonus: when you run a program from ramfs, the ramfs will stay arround for quite a while even after the program has long exited and the ramfs has been unmounted. the reason is that we still cache the pages of the program keeping the image arround. the image has a Chan* reference to the original text file. until the image is reclaimed and the channel closed, the mount will stay arround preventing the fileserver (ramfs) from exiting. one can avoid keeping the chan reference by separately tracking the number of page references to an image. so when image->ref == image->pgref, we know that all references to a image are from the page freelist. in that case, one can close the channel in the image. when the image gets attached again (attachimage()), we take a new reference to the supplied channel and stick it on the image. use the channels mountid and quid to check for file equality as mountid's are not reused within the same kernel. no need to keep the channel arround. i suspect the bigboy hack (which increases the conf.nimage parameter to 2000 in pc/main.c confinit() for cpu servers) might be partially due to this imagereclaim() bug trying to cure the symptom. -- cinap