VM: full munmap

complete munmap implementation; single-page references made
a general munmap() implementation possible to write cleanly.

	. memory: let the MIOCRAMSIZE ioctl set the imgrd device
	  size (but only to 0)
	. let the ramdisk command set sizes to 0
	. use this command to set /dev/imgrd to 0 after mounting /usr
	  in /etc/rc, so the boot time ramdisk is freed (about 4MB
	  currently)
This commit is contained in:
Ben Gras
2012-09-18 13:17:52 +02:00
parent 16c3870b2e
commit ed1af3c86c
15 changed files with 116 additions and 134 deletions
+30 -29
View File
@@ -15,6 +15,7 @@
* Apr 20, 1992 device dependent/independent split (Kees J. Bot)
*/
#include <assert.h>
#include <minix/drivers.h>
#include <minix/chardriver.h>
#include <minix/blockdriver.h>
@@ -100,6 +101,7 @@ static char dev_zero[ZERO_BUF_SIZE];
static void sef_local_startup(void);
static int sef_cb_init_fresh(int type, sef_init_info_t *info);
/*===========================================================================*
* main *
*===========================================================================*/
@@ -528,30 +530,6 @@ static int m_block_close(dev_t minor)
}
openct[minor]--;
#if 0
/* Special case: free initial ramdisk after it's been unmounted once. */
if(minor == IMGRD_DEV && openct[minor] == 0 && m_vaddrs[IMGRD_DEV]) {
vir_bytes vaddr, vlen;
vaddr = m_vaddrs[IMGRD_DEV];
vlen = imgrd_size;
/* Align `inwards' so as to not unmap more than the initial
* ramdisk image.
*/
if(vaddr % PAGE_SIZE) {
vir_bytes o = PAGE_SIZE - (vaddr % PAGE_SIZE);
vlen -= o;
vaddr += o;
}
if(vlen % PAGE_SIZE) {
vlen -= vlen % PAGE_SIZE;
}
minix_munmap((void *) vaddr, vlen);
m_geom[IMGRD_DEV].dv_base= cvul64(0);
m_geom[IMGRD_DEV].dv_size= cvul64(0);
m_vaddrs[IMGRD_DEV] = 0;
}
#endif
return(OK);
}
@@ -569,15 +547,20 @@ static int m_block_ioctl(dev_t minor, unsigned int request, endpoint_t endpt,
u32_t ramdev_size;
int s;
void *mem;
int is_imgrd = 0;
if (request != MIOCRAMSIZE)
return EINVAL;
if(minor == IMGRD_DEV)
is_imgrd = 1;
/* Someone wants to create a new RAM disk with the given size.
* A ramdisk can be created only once, and only on RAM disk device.
*/
if ((dv = m_block_part(minor)) == NULL) return ENXIO;
if((minor < RAM_DEV_FIRST || minor > RAM_DEV_LAST) && minor != RAM_DEV_OLD) {
if((minor < RAM_DEV_FIRST || minor > RAM_DEV_LAST) &&
minor != RAM_DEV_OLD && !is_imgrd) {
printf("MEM: MIOCRAMSIZE: %d not a ramdisk\n", minor);
return EINVAL;
}
@@ -587,6 +570,8 @@ static int m_block_ioctl(dev_t minor, unsigned int request, endpoint_t endpt,
sizeof(ramdev_size));
if (s != OK)
return s;
if(is_imgrd)
ramdev_size = 0;
if(m_vaddrs[minor] && !cmp64(dv->dv_size, cvul64(ramdev_size))) {
return(OK);
}
@@ -597,21 +582,37 @@ static int m_block_ioctl(dev_t minor, unsigned int request, endpoint_t endpt,
return(EBUSY);
}
if(m_vaddrs[minor]) {
u32_t size;
u32_t a, o;
u64_t size;
int r;
if(ex64hi(dv->dv_size)) {
panic("huge old ramdisk");
}
size = ex64lo(dv->dv_size);
minix_munmap((void *) m_vaddrs[minor], size);
size = dv->dv_size;
a = m_vaddrs[minor];
if((o = a % PAGE_SIZE)) {
vir_bytes l = PAGE_SIZE - o;
a += l;
size -= l;
}
size = rounddown(size, PAGE_SIZE);
r = minix_munmap((void *) a, size);
if(r != OK) {
printf("memory: WARNING: munmap failed: %d\n", r);
}
m_vaddrs[minor] = (vir_bytes) NULL;
dv->dv_size = 0;
}
#if DEBUG
printf("MEM:%d: allocating ramdisk of size 0x%x\n", minor, ramdev_size);
#endif
mem = NULL;
/* Try to allocate a piece of memory for the RAM disk. */
if((mem = minix_mmap(NULL, ramdev_size, PROT_READ|PROT_WRITE,
if(ramdev_size > 0 &&
(mem = minix_mmap(NULL, ramdev_size, PROT_READ|PROT_WRITE,
MAP_PREALLOC|MAP_ANON, -1, 0)) == MAP_FAILED) {
printf("MEM: failed to get memory for ramdisk\n");
return(ENOMEM);