From: Alan Cox Date: Mon, 12 Oct 2015 21:58:27 +0000 (+0100) Subject: buffers: Allow for the buffer cache to be expandable. X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=95e8615b743c5db3cc54abf0a8a64f4fc2042d26;p=FUZIX.git buffers: Allow for the buffer cache to be expandable. Some of our platforms have no userspace mapped when in kernel space. That prevents them putting the discard code/data into the userspace area during boot and binning it when loading init over the top. Instead we allow the buffer cache to grow. The platform can then put the buffer cache just before the discard area, and once the root fs is mounted and we are ready to load init we can convert the entire discard area into cache pages. Even better we only need enough buffers to mount the root fs to be present at boot time (2 or 3). --- diff --git a/Kernel/devio.c b/Kernel/devio.c index f1bad74d..32302c70 100644 --- a/Kernel/devio.c +++ b/Kernel/devio.c @@ -80,7 +80,7 @@ int bfree(bufptr bp, uint8_t dirty) if(bp->bf_busy == BF_BUSY) /* do not free BF_SUPERBLOCK */ bp->bf_busy = BF_FREE; - if (dirty > 1) { // immediate writeback + if (dirty > 1) { /* immediate writeback */ if (bdwrite(bp) == -1) udata.u_error = EIO; bp->bf_dirty = false; @@ -130,7 +130,7 @@ void bufsync(void) /* FIXME: this can generate a lot of d_flush calls when you have plenty of buffers */ - for (bp = bufpool; bp < bufpool + NBUFS; ++bp) { + for (bp = bufpool; bp < bufpool_end; ++bp) { if ((bp->bf_dev != NO_DEVICE) && bp->bf_dirty) bdput(bp); } @@ -140,7 +140,7 @@ bufptr bfind(uint16_t dev, blkno_t blk) { bufptr bp; - for (bp = bufpool; bp < bufpool + NBUFS; ++bp) { + for (bp = bufpool; bp < bufpool_end; ++bp) { if (bp->bf_dev == dev && bp->bf_blk == blk) return bp; } @@ -151,7 +151,7 @@ void bdrop(uint16_t dev) { bufptr bp; - for (bp = bufpool; bp < bufpool + NBUFS; ++bp) { + for (bp = bufpool; bp < bufpool_end; ++bp) { if (bp->bf_dev == dev) { bdput(bp); bp->bf_dev = NO_DEVICE; @@ -168,7 +168,7 @@ bufptr freebuf(void) /* Try to find a non-busy buffer and write out the data if it is dirty */ oldest = NULL; oldtime = 0; - for (bp = bufpool; bp < bufpool + NBUFS; ++bp) { + for (bp = bufpool; bp < bufpool_end; ++bp) { if (bufclock - bp->bf_time >= oldtime && bp->bf_busy == BF_FREE) { oldest = bp; oldtime = bufclock - bp->bf_time; @@ -561,7 +561,7 @@ void bufdump(void) bufptr j; kprintf("\ndev\tblock\tdirty\tbusy\ttime clock %d\n", bufclock); - for (j = bufpool; j < bufpool + NBUFS; ++j) + for (j = bufpool; j < bufpool_end; ++j) kprintf("%d\t%u\t%d\t%d\t%u\n", j->bf_dev, j->bf_blk, j->bf_dirty, j->bf_busy, j->bf_time); } diff --git a/Kernel/include/kdata.h b/Kernel/include/kdata.h index b4643ea6..cb6d9464 100644 --- a/Kernel/include/kdata.h +++ b/Kernel/include/kdata.h @@ -23,6 +23,12 @@ extern uint16_t root_dev; /* Device number of root filesystem. */ extern uint16_t swap_dev; /* Device number used for swap */ extern struct blkbuf bufpool[NBUFS]; +#ifndef CONFIG_DYNAMIC_BUFPOOL +#define bufpool_end (bufpool + NBUFS) /* Define so its a compile time const */ +#else +extern struct blkbuf *bufpool_end; +#endif + extern struct p_tab ptab[PTABSIZE]; extern struct p_tab *ptab_end; extern struct oft of_tab[OFTSIZE]; /* Open File Table */ diff --git a/Kernel/kdata.c b/Kernel/kdata.c index 05b74ffb..8542ec8e 100644 --- a/Kernel/kdata.c +++ b/Kernel/kdata.c @@ -13,7 +13,7 @@ uint8_t ticks_this_dsecond; uint8_t ticks_per_dsecond; inoptr root; uint16_t waitno; -time_t tod; // time of day +time_t tod; /* Time of day */ ticks_t ticks; int16_t acct_fh = -1; /* Accounting file handle */ @@ -23,7 +23,9 @@ struct runload loadavg[3] = { { 254, 0 } /* 180 sets of 5 seconds per 15 minutes */ }; +#ifndef CONFIG_DYNAMIC_BUFPOOL struct blkbuf bufpool[NBUFS]; +#endif struct p_tab ptab[PTABSIZE]; struct p_tab *ptab_end; /* Points to first byte off end */ diff --git a/Kernel/start.c b/Kernel/start.c index 8e37bae9..9ee09b43 100644 --- a/Kernel/start.c +++ b/Kernel/start.c @@ -40,7 +40,7 @@ void bufinit(void) { bufptr bp; - for (bp = bufpool; bp < bufpool + NBUFS; ++bp) { + for (bp = bufpool; bp < bufpool_end; ++bp) { bp->bf_dev = NO_DEVICE; bp->bf_busy = BF_FREE; }