git: 9front

Download patch

ref: 3e329e0c88e64ff5ed5773b5d627fafa1ac0cf6e
parent: 78f3b950ac5e3d249f23db35cdbe9ae20c05b9de
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Thu Oct 24 22:42:35 EDT 2013

kernel: disable freelist page caching for executables run from uncached mount

the image cache has the property of keeping a channel
for the executable binary arround which prevents the
mountpoint from going away.

this can easily be reproduced by running:

@{rfork n; ramfs; cp /bin/echo /tmp; /tmp/echo}

observe how ramfs stays arround until the image is
reclaimed. the echo binary is also cached but is
unreachable from any namespace.

we now restrict the caching to mounts that use the client
cache (-C flag) only. this should always be the case
for /bin. places where this isnt the case might observe
a performance regression.

--- a/sys/src/9/port/page.c
+++ b/sys/src/9/port/page.c
@@ -228,6 +228,9 @@
 		return;
 	}
 
+	if(p->image && p->image->nocache)
+		uncachepage(p);
+
 	if(p->image && p->image != &swapimage)
 		pagechaintail(p);
 	else 
@@ -291,8 +294,8 @@
 		return;
 	}
 
-	/* No freelist cache when memory is very low */
-	if(palloc.freecount < swapalloc.highwater) {
+	/* No freelist cache with uncached image or when memory is very low */
+	if(p->image->nocache || palloc.freecount < swapalloc.highwater) {
 		unlock(&palloc);
 		uncachepage(p);
 		return;
--- a/sys/src/9/port/portdat.h
+++ b/sys/src/9/port/portdat.h
@@ -352,7 +352,8 @@
 	Segment *s;			/* TEXT segment for image if running */
 	Image	*hash;			/* Qid hash chains */
 	Image	*next;			/* Free list */
-	int	notext;			/* no file associated */
+	char	notext;			/* no file associated */
+	char	nocache;		/* no freelist page caching */
 };
 
 struct Pte
--- a/sys/src/9/port/segment.c
+++ b/sys/src/9/port/segment.c
@@ -275,6 +275,7 @@
 
 	lock(i);
 	incref(c);
+	i->nocache = (c->flag & CCACHE) == 0;
 	c->flag &= ~CCACHE;
 	i->c = c;
 	i->type = c->type;
--