xref: /plan9/sys/src/cmd/venti/srv/disksched.c (revision 1f9fb5709ae2d5a408fa863c719cf9096933ed7f)
1368c31abSDavid du Colombier #include "stdinc.h"
2368c31abSDavid du Colombier #include "dat.h"
3368c31abSDavid du Colombier #include "fns.h"
4368c31abSDavid du Colombier 
5368c31abSDavid du Colombier ulong lasttime[2];
6368c31abSDavid du Colombier int manualscheduling;
7368c31abSDavid du Colombier int l0quantum = 120;
8368c31abSDavid du Colombier int l1quantum = 120;
9368c31abSDavid du Colombier ulong lasticachechange;
10368c31abSDavid du Colombier 
11368c31abSDavid du Colombier void
disksched(void)12368c31abSDavid du Colombier disksched(void)
13368c31abSDavid du Colombier {
14368c31abSDavid du Colombier 	int p, nwrite, nflush, ndirty, tdirty, toflush;
15368c31abSDavid du Colombier 	ulong t;
16368c31abSDavid du Colombier 	vlong cflush;
17368c31abSDavid du Colombier 	Stats *prev;
18368c31abSDavid du Colombier 
19368c31abSDavid du Colombier 	/*
20368c31abSDavid du Colombier 	 * no locks because all the data accesses are atomic.
21368c31abSDavid du Colombier 	 */
22368c31abSDavid du Colombier 	t = time(0);
23368c31abSDavid du Colombier 	if(manualscheduling){
24368c31abSDavid du Colombier 		lasticachechange = t;
25368c31abSDavid du Colombier 		return;
26368c31abSDavid du Colombier 	}
27368c31abSDavid du Colombier 
28368c31abSDavid du Colombier 	if(t-lasttime[0] < l0quantum){
29368c31abSDavid du Colombier 		/* level-0 disk access going on */
30368c31abSDavid du Colombier 		p = icachedirtyfrac();
31368c31abSDavid du Colombier 		if(p < IcacheFrac*5/10){	/* can wait */
32368c31abSDavid du Colombier 			icachesleeptime = SleepForever;
33368c31abSDavid du Colombier 			lasticachechange = t;
34368c31abSDavid du Colombier 		}else if(p > IcacheFrac*9/10){	/* can't wait */
35368c31abSDavid du Colombier 			icachesleeptime = 0;
36368c31abSDavid du Colombier 			lasticachechange = t;
37368c31abSDavid du Colombier 		}else if(t-lasticachechange > 60){
38368c31abSDavid du Colombier 			/* have minute worth of data for current rate */
39368c31abSDavid du Colombier 			prev = &stathist[(stattime-60+nstathist)%nstathist];
40368c31abSDavid du Colombier 
41368c31abSDavid du Colombier 			/* # entries written to index cache */
42368c31abSDavid du Colombier 			nwrite = stats.n[StatIcacheWrite] - prev->n[StatIcacheWrite];
43368c31abSDavid du Colombier 
44368c31abSDavid du Colombier 			/* # dirty entries in index cache */
45368c31abSDavid du Colombier 			ndirty = stats.n[StatIcacheDirty] - prev->n[StatIcacheDirty];
46368c31abSDavid du Colombier 
47368c31abSDavid du Colombier 			/* # entries flushed to disk */
48368c31abSDavid du Colombier 			nflush = nwrite - ndirty;
49368c31abSDavid du Colombier 
50368c31abSDavid du Colombier 			/* want to stay around 70% dirty */
51368c31abSDavid du Colombier 			tdirty = (vlong)stats.n[StatIcacheSize]*700/1000;
52368c31abSDavid du Colombier 
53368c31abSDavid du Colombier 			/* assume nflush*icachesleeptime is a constant */
54368c31abSDavid du Colombier 			cflush = (vlong)nflush*(icachesleeptime+1);
55368c31abSDavid du Colombier 
56368c31abSDavid du Colombier 			/* computer number entries to write in next minute */
57368c31abSDavid du Colombier 			toflush = nwrite + (stats.n[StatIcacheDirty] - tdirty);
58368c31abSDavid du Colombier 
59368c31abSDavid du Colombier 			/* schedule for  that many */
60368c31abSDavid du Colombier 			if(toflush <= 0 || cflush/toflush > 100000)
61368c31abSDavid du Colombier 				icachesleeptime = SleepForever;
62368c31abSDavid du Colombier 			else
63368c31abSDavid du Colombier 				icachesleeptime = cflush/toflush;
64368c31abSDavid du Colombier 		}
65368c31abSDavid du Colombier 		arenasumsleeptime = SleepForever;
66368c31abSDavid du Colombier 		return;
67368c31abSDavid du Colombier 	}
68368c31abSDavid du Colombier 	if(t-lasttime[1] < l1quantum){
69368c31abSDavid du Colombier 		/* level-1 disk access (icache flush) going on */
70368c31abSDavid du Colombier 		icachesleeptime = 0;
71368c31abSDavid du Colombier 		arenasumsleeptime = SleepForever;
72368c31abSDavid du Colombier 		return;
73368c31abSDavid du Colombier 	}
74368c31abSDavid du Colombier 	/* no disk access going on - no holds barred*/
75368c31abSDavid du Colombier 	icachesleeptime = 0;
76368c31abSDavid du Colombier 	arenasumsleeptime = 0;
77368c31abSDavid du Colombier }
78368c31abSDavid du Colombier 
79368c31abSDavid du Colombier void
diskaccess(int level)80368c31abSDavid du Colombier diskaccess(int level)
81368c31abSDavid du Colombier {
82368c31abSDavid du Colombier 	if(level < 0 || level >= nelem(lasttime)){
83*1f9fb570SDavid du Colombier 		fprint(2, "bad level in diskaccess; caller=%#p\n",
84*1f9fb570SDavid du Colombier 			getcallerpc(&level));
85368c31abSDavid du Colombier 		return;
86368c31abSDavid du Colombier 	}
87368c31abSDavid du Colombier 	lasttime[level] = time(0);
88368c31abSDavid du Colombier }
89368c31abSDavid du Colombier 
90