]> Zhao Yanbai Git Server - minix.git/commitdiff
VM: full munmap
authorBen Gras <ben@minix3.org>
Tue, 18 Sep 2012 11:17:52 +0000 (13:17 +0200)
committerBen Gras <ben@minix3.org>
Tue, 18 Sep 2012 11:17:52 +0000 (13:17 +0200)
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)

15 files changed:
commands/ramdisk/ramdisk.c
drivers/memory/local.h
drivers/memory/memory.c
etc/rc
include/minix/com.h
include/sys/mman.h
lib/libc/include/namespace.h
lib/libc/sys-minix/mmap.c
servers/rs/memory.c
servers/vm/main.c
servers/vm/mmap.c
servers/vm/pb.c
servers/vm/proto.h
servers/vm/region.c
servers/vm/slaballoc.c

index cab1b38b979922810f1b0982c1bf6382a662b98f..d46bbca88004bb8e433d18c2a2824808255d677a 100644 (file)
@@ -28,8 +28,8 @@ main(int argc, char *argv[])
 #define KFACTOR 1024
        size = atol(argv[1])*KFACTOR;
 
-       if(size <= 0) {
-               fprintf(stderr, "size should be positive.\n");
+       if(size < 0) {
+               fprintf(stderr, "size should be non-negative.\n");
                return 1;
        }
 
index 498ef2757df6074f91a569ecbe58e01f2ffbfc09..eb9e706f7c1f7567d3b8896bd6336881ed4a1bf5 100644 (file)
@@ -2,8 +2,8 @@
 local defines and declarations 
 */
 
-extern unsigned char _binary_imgrd_mfs_start[], *_binary_imgrd_mfs_end;
+extern unsigned char _binary_imgrd_mfs_start_binary_imgrd_mfs_end;
 
-#define        imgrd   _binary_imgrd_mfs_start
+#define        imgrd   &_binary_imgrd_mfs_start
 #define        imgrd_size \
-       ((size_t)(_binary_imgrd_mfs_end - _binary_imgrd_mfs_start))
+       (((size_t) &_binary_imgrd_mfs_end - (size_t)&_binary_imgrd_mfs_start))
index e1bfec0c91c6cd5e57d65cb35d11c2206553cdd3..a5f3a6cea523e54328466bb4e1861e8872d132fc 100644 (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);
diff --git a/etc/rc b/etc/rc
index 3900c9abdc28bd70f5ca763d30261495935fc95c..597fa0948e90a05b5023255087d72979e562e4ef 100755 (executable)
--- a/etc/rc
+++ b/etc/rc
@@ -121,9 +121,6 @@ start)
     printroot >/etc/mtab               # /etc/mtab keeps track of mounts
     >/etc/utmp                         # /etc/utmp keeps track of logins
 
-    # Unmount now defunct ramdisk
-    umount /dev/imgrd > /dev/null || echo "Failed to unmount boot ramdisk"
-
     # Use MFS binary only from kernel image?
     if [ "`sysenv bin_img`" = 1 ]
     then
@@ -149,6 +146,10 @@ start)
                fi
     fi
 
+    # Unmount and free now defunct ramdisk
+    umount /dev/imgrd > /dev/null || echo "Failed to unmount boot ramdisk"
+    ramdisk 0 /dev/imgrd || echo "Failed to free boot ramdisk"
+
     # Edit settings for boot system services
     if [ "`sysenv skip_boot_config`" != 1 ]
     then
index 1383d0eb8eef8b8780134c83958b3379cc48d092..525e4bbc230eec8b2e6d748205661494a823ed5e 100644 (file)
 #      define VMUM_ADDR                m1_p1
 #      define VMUM_LEN                 m1_i1
 
-#define VM_MUNMAP_TEXT         (VM_RQ_BASE+19)
-
 /* To VM: forget all my yielded blocks. */
 #define VM_FORGETBLOCKS                (VM_RQ_BASE+22)
 
 
 /* Basic vm calls allowed to every process. */
 #define VM_BASIC_CALLS \
-    VM_MMAP, VM_MUNMAP, VM_MUNMAP_TEXT, VM_MAP_PHYS, VM_UNMAP_PHYS, \
+    VM_MMAP, VM_MUNMAP, VM_MAP_PHYS, VM_UNMAP_PHYS, \
     VM_FORGETBLOCKS, VM_FORGETBLOCK, VM_YIELDBLOCKGETBLOCK, VM_INFO
 
 /*===========================================================================*
index 7ef464bc056b75db24aea030ee8a71230b968fdd..dc8b1cb4d1e738287ef5d88acccd510ebd79c962 100644 (file)
@@ -76,7 +76,6 @@ int   munmap(void *, size_t);
 void * minix_mmap(void *, size_t, int, int, int, off_t);
 void * minix_mmap_for(endpoint_t, void *, size_t, int, int, int, off_t);
 int    minix_munmap(void *, size_t);
-int            minix_munmap_text(void *, size_t);
 void *         vm_remap(int d, int s, void *da, void *sa, size_t si);
 void *         vm_remap_ro(int d, int s, void *da, void *sa, size_t si);
 int            vm_unmap(int endpt, void *addr);
index 077b2a89d8285943e862f07dd7ceb28b81ee9410..6c876c3222d57455ee40342464b1988ea8489272 100644 (file)
 #define writev _writev
 #define minix_mmap _minix_mmap
 #define minix_munmap _minix_munmap
-#define minix_munmap_text _minix_munmap_text
 #define vfork __vfork14
 #endif /* __minix */
 
index 0fb444345288f31ff26e1be0384932f3939ae75a..a84034e924ee2ea7b86d3971ca97e0fe79cc6530 100644 (file)
@@ -12,7 +12,6 @@ __weak_alias(vm_getphys, _vm_getphys)
 __weak_alias(vm_getrefcount, _vm_getrefcount)
 __weak_alias(minix_mmap, _minix_mmap)
 __weak_alias(minix_munmap, _minix_munmap)
-__weak_alias(minix_munmap_text, _minix_munmap_text)
 #endif
 
 
@@ -65,16 +64,6 @@ int minix_munmap(void *addr, size_t len)
 }
 
 
-int minix_munmap_text(void *addr, size_t len)
-{
-       message m;
-
-       m.VMUM_ADDR = addr;
-       m.VMUM_LEN = len;
-
-       return _syscall(VM_PROC_NR, VM_MUNMAP_TEXT, &m);
-}
-
 void *vm_remap(endpoint_t d,
                        endpoint_t s,
                        void *da,
index 76bfc99dc5e74af4b5ce6380041be1301c9e17c9..b21d86199541790c277a69a69b60f3e527c1f88a 100644 (file)
@@ -7,10 +7,8 @@
 #include "inc.h"
 
 #define minix_munmap _minix_munmap
-#define minix_munmap_text _minix_munmap_text
 #include <sys/mman.h>
 #undef minix_munmap
-#undef minix_munmap_text
 
 int unmap_ok = 0;
 
@@ -24,14 +22,3 @@ int minix_munmap(void *addrstart, vir_bytes len)
 
   return _minix_munmap(addrstart, len);
 }
-
-/*===========================================================================*
- *                              minix_munmap_text                           *
- *===========================================================================*/
-int minix_munmap_text(void *addrstart, vir_bytes len)
-{
-  if(!unmap_ok)
-      return ENOSYS;
-
-  return _minix_munmap_text(addrstart, len);
-}
index a381089aa6e793f4dbfa3e8e2c3f53da8b6fcb6d..25a0b862dd2b08b06acac06a7a55d8fa222f0259 100644 (file)
@@ -381,7 +381,6 @@ void init_vm(void)
        /* Basic VM calls. */
        CALLMAP(VM_MMAP, do_mmap);
        CALLMAP(VM_MUNMAP, do_munmap);
-       CALLMAP(VM_MUNMAP_TEXT, do_munmap);
        CALLMAP(VM_MAP_PHYS, do_map_phys);
        CALLMAP(VM_UNMAP_PHYS, do_unmap_phys);
 
index a54f9b2b4ba6806cf05b82ba697f06e946d203fb..97fffb04084bca4d17c39154b2ccf91c09d9e681 100644 (file)
@@ -18,6 +18,7 @@
 #include <minix/debug.h>
 
 #include <sys/mman.h>
+#include <sys/param.h>
 
 #include <errno.h>
 #include <assert.h>
@@ -234,7 +235,7 @@ int do_unmap_phys(message *m)
                return EINVAL;
        }
 
-       if(map_unmap_region(vmp, region, region->length) != OK) {
+       if(map_unmap_region(vmp, region, 0, region->length) != OK) {
                return EINVAL;
        }
 
@@ -345,7 +346,7 @@ int do_shared_unmap(message *m)
                return EFAULT;
        }
 
-       if(map_unmap_region(vmp, vr, vr->length) != OK)
+       if(map_unmap_region(vmp, vr, 0, vr->length) != OK)
                panic("do_shared_unmap: map_unmap_region failed");
 
        return OK;
@@ -408,38 +409,38 @@ int do_munmap(message *m)
 {
         int r, n;
         struct vmproc *vmp;
-        vir_bytes addr, len;
+        vir_bytes addr, len, offset;
        struct vir_region *vr;
-        
+
         if((r=vm_isokendpt(m->m_source, &n)) != OK) {
                 panic("do_mmap: message from strange source: %d", m->m_source);
         }
  
         vmp = &vmproc[n];
 
-       if(m->m_type == VM_MUNMAP) {
-               addr = (vir_bytes) (vir_bytes) m->VMUM_ADDR;
-       } else if(m->m_type == VM_MUNMAP_TEXT) {
-               addr = (vir_bytes) (vir_bytes) m->VMUM_ADDR;
-       } else {
-               panic("do_munmap: strange type");
-       }
+       assert(m->m_type == VM_MUNMAP);
+        addr = (vir_bytes) (vir_bytes) m->VMUM_ADDR;
 
         if(!(vr = map_lookup(vmp, addr))) {
                 printf("VM: unmap: virtual address %p not found in %d\n",
                         m->VMUM_ADDR, vmp->vm_endpoint);
                 return EFAULT;
         }
+
+       if(addr % VM_PAGE_SIZE)
+               return EFAULT;
  
-       len = m->VMUM_LEN;
-       if (len % VM_PAGE_SIZE)
-               len += VM_PAGE_SIZE - (len % VM_PAGE_SIZE);
+       len = roundup(m->VMUM_LEN, VM_PAGE_SIZE);
 
-        if(addr != vr->vaddr || len > vr->length || len < VM_PAGE_SIZE) {
-                return EFAULT;
-        }       
+       offset = addr - vr->vaddr;
+
+       if(offset + len > vr->length) {
+               printf("munmap: addr 0x%lx len 0x%lx spills out of region\n",
+                       addr, len);
+               return EFAULT;
+       }
 
-       if(map_unmap_region(vmp, vr, len) != OK)
+       if(map_unmap_region(vmp, vr, offset, len) != OK)
                panic("do_munmap: map_unmap_region failed");
 
        return OK;
@@ -483,15 +484,3 @@ int minix_munmap(void *addr, size_t len)
        return munmap_lin(laddr, len);
 }
 
-/*===========================================================================*
- *                              munmap_text (override for VM)                *
- *===========================================================================*/
-int minix_munmap_text(void *addr, size_t len)
-{
-       vir_bytes laddr;
-       if(!unmap_ok)
-               return ENOSYS;
-       laddr = (vir_bytes) addr;
-       return munmap_lin(laddr, len);
-}
-
index d0ef49f96f4ef31822d95081e7d69c41b5688c26..b7434c2e0ced26b6ee85d7dd4cc300164cb19000 100644 (file)
@@ -78,7 +78,7 @@ USE(newphysr,
 /*===========================================================================*
  *                             pb_unreferenced                              *
  *===========================================================================*/
-void pb_unreferenced(struct vir_region *region, struct phys_region *pr)
+void pb_unreferenced(struct vir_region *region, struct phys_region *pr, int rm)
 {
        struct phys_block *pb;
 
@@ -116,5 +116,5 @@ void pb_unreferenced(struct vir_region *region, struct phys_region *pr)
                SLABFREE(pb);
        }
 
-       physr_remove(region->phys, pr->offset);
+       if(rm) physr_remove(region->phys, pr->offset);
 }
index 09ac90bf07e99b88c4989fdfdd1ea3f1f7bef3af..eb5be9f21623bc8ee9e4674211e77e9d515fe313 100644 (file)
@@ -132,7 +132,7 @@ int map_region_extend(struct vmproc *vmp, struct vir_region *vr,
 int map_region_extend_upto_v(struct vmproc *vmp, vir_bytes vir);
 int map_region_shrink(struct vir_region *vr, vir_bytes delta);
 int map_unmap_region(struct vmproc *vmp, struct vir_region *vr,
-       vir_bytes len);
+       vir_bytes offset, vir_bytes len);
 int map_free_proc(struct vmproc *vmp);
 int map_proc_copy(struct vmproc *dst, struct vmproc *src);
 int map_proc_copy_from(struct vmproc *dst, struct vmproc *src, struct
@@ -158,7 +158,6 @@ int map_remap(struct vmproc *dvmp, vir_bytes da, size_t size, struct
 int map_get_phys(struct vmproc *vmp, vir_bytes addr, phys_bytes *r);
 int map_get_ref(struct vmproc *vmp, vir_bytes addr, u8_t *cnt);
 
-void pb_unreferenced(struct vir_region *region, struct phys_region *pr);
 void get_stats_info(struct vm_stats_info *vsi);
 void get_usage_info(struct vmproc *vmp, struct vm_usage_info *vui);
 int get_region_info(struct vmproc *vmp, struct vm_region_info *vri, int
@@ -189,4 +188,4 @@ void init_query_exit(void);
 struct phys_block *pb_new(phys_bytes phys);
 struct phys_region *pb_reference(struct phys_block *newpb,
        vir_bytes offset, struct vir_region *region);
-void pb_unreferenced(struct vir_region *region, struct phys_region *pr);
+void pb_unreferenced(struct vir_region *region, struct phys_region *pr, int rm);
index 58aca9d37302643c8d380284e250591c92d2d072..c4379667a238a08d477b89c35a899e75bfb3b733 100644 (file)
@@ -429,8 +429,11 @@ static vir_bytes region_find_slot_range(struct vmproc *vmp,
                printf("VM: 1 minv: 0x%lx maxv: 0x%lx length: 0x%lx\n",
                        minv, maxv, length);
        }
+
        assert(minv < maxv);
-       assert(minv + length <= maxv);
+
+       if(minv + length > maxv)
+               return SLOT_FAIL;
 
 #define FREEVRANGE_TRY(rangestart, rangeend) {         \
        vir_bytes frstart = (rangestart), frend = (rangeend);   \
@@ -642,11 +645,14 @@ static struct phys_region *reset_physr_iter(struct vir_region *region,
 /*===========================================================================*
  *                             map_subfree                                  *
  *===========================================================================*/
-static int map_subfree(struct vir_region *region, vir_bytes len)
+static int map_subfree(struct vir_region *region, 
+       vir_bytes start, vir_bytes len)
 {
        struct phys_region *pr;
        physr_iter iter;
+       vir_bytes end = start+len;
 
+       int full = 0;
 
 #if SANITYCHECKS
        {
@@ -668,18 +674,25 @@ static int map_subfree(struct vir_region *region, vir_bytes len)
        }
 #endif
 
-       physr_start_iter_least(region->phys, &iter);
+       if(start == 0 && len == region->length)
+               full = 1;
+
+       physr_start_iter(region->phys, &iter, start, AVL_GREATER_EQUAL);
        while((pr = physr_get_iter(&iter))) {
                physr_incr_iter(&iter);
-               if(pr->offset >= len)
+               if(pr->offset >= end)
                        break;
-               if(pr->offset + VM_PAGE_SIZE <= len) {
-                       pb_unreferenced(region, pr);
-                       physr_start_iter_least(region->phys, &iter);
-                       SLABFREE(pr);
+               pb_unreferenced(region, pr, !full);
+               if(!full) {
+                       physr_start_iter(region->phys, &iter,
+                               pr->offset, AVL_GREATER_EQUAL);
                }
+               SLABFREE(pr);
        }
 
+       if(full)
+               physr_init(region->phys);
+
        return OK;
 }
 
@@ -690,7 +703,7 @@ static int map_free(struct vir_region *region)
 {
        int r;
 
-       if((r=map_subfree(region, region->length)) != OK) {
+       if((r=map_subfree(region, 0, region->length)) != OK) {
                printf("%d\n", __LINE__);
                return r;
        }
@@ -985,7 +998,7 @@ int written;
                        if((physr = physr_search(region->phys, offset,
                                AVL_EQUAL))) {
                                assert(physr->ph->refcount == 1);
-                               pb_unreferenced(region, physr);
+                               pb_unreferenced(region, physr, 1);
                                SLABFREE(physr);
                        }
                        offset += VM_PAGE_SIZE;
@@ -1052,7 +1065,7 @@ physr_iter *iter;
        SLABSANE(ph);
        SLABSANE(ph->ph);
        assert(ph->ph->refcount > 1);
-       pb_unreferenced(region, ph);
+       pb_unreferenced(region, ph, 1);
        assert(ph->ph->refcount >= 1);
        SLABFREE(ph);
 
@@ -1653,7 +1666,7 @@ u32_t map_region_get_tag(struct vir_region *vr)
  *                             map_unmap_region                        *
  *========================================================================*/
 int map_unmap_region(struct vmproc *vmp, struct vir_region *r,
-       vir_bytes len)
+       vir_bytes offset, vir_bytes len)
 {
 /* Shrink the region by 'len' bytes, from the start. Unreference
  * memory it used to reference if any.
@@ -1662,7 +1675,7 @@ int map_unmap_region(struct vmproc *vmp, struct vir_region *r,
 
        SANITYCHECK(SCL_FUNCTIONS);
 
-       if(len > r->length || (len % VM_PAGE_SIZE)) {
+       if(offset+len > r->length || (len % VM_PAGE_SIZE)) {
                printf("VM: bogus length 0x%lx\n", len);
                return EINVAL;
        }
@@ -1672,35 +1685,44 @@ int map_unmap_region(struct vmproc *vmp, struct vir_region *r,
                return EINVAL;
        }
 
-       regionstart = r->vaddr;
+       regionstart = r->vaddr + offset;
 
-       if(len == r->length) {
-               SANITYCHECK(SCL_DETAIL);
-               /* Whole region disappears. Unlink and free it. */
-               region_remove(&vmp->vm_regions_avl, r->vaddr);
-               map_free(r);
-       } else {
+       /* unreference its memory */
+       map_subfree(r, offset, len);
+
+       /* if unmap was at start/end of this region, it actually shrinks */
+       if(offset == 0) {
                struct phys_region *pr;
                physr_iter iter;
-               /* Region shrinks. First unreference its memory
-                * and then shrink the region.
-                */
-               SANITYCHECK(SCL_DETAIL);
-               map_subfree(r, len);
+
+               region_remove(&vmp->vm_regions_avl, r->vaddr);
+
                USE(r,
                r->vaddr += len;
                r->length -= len;);
-               physr_start_iter_least(r->phys, &iter);
+
+               region_insert(&vmp->vm_regions_avl, r);
 
                /* vaddr has increased; to make all the phys_regions
                 * point to the same addresses, make them shrink by the
                 * same amount.
                 */
+               physr_start_iter(r->phys, &iter, offset, AVL_GREATER_EQUAL);
+
                while((pr = physr_get_iter(&iter))) {
-                       assert(pr->offset >= len);
+                       assert(pr->offset >= offset);
                        USE(pr, pr->offset -= len;);
                        physr_incr_iter(&iter);
                }
+       } else if(offset + len == r->length) {
+               assert(len <= r->length);
+               r->length -= len;
+       }
+
+       if(r->length == 0) {
+               /* Whole region disappears. Unlink and free it. */
+               region_remove(&vmp->vm_regions_avl, r->vaddr);
+               map_free(r);
        }
 
        SANITYCHECK(SCL_DETAIL);
@@ -2104,7 +2126,7 @@ static void rm_phys_regions(struct vir_region *region,
 
         physr_start_iter(region->phys, &iter, begin, AVL_GREATER_EQUAL);
         while((pr = physr_get_iter(&iter)) && pr->offset < begin + length) {
-                pb_unreferenced(region, pr);
+                pb_unreferenced(region, pr, 1);
                 physr_start_iter(region->phys, &iter, begin,
                         AVL_GREATER_EQUAL);
                 SLABFREE(pr);
index e7c14931104a4db5440e61c4d7ab306d616ef074..e7f1d65863f19343b532dcc463eb0f478d4f8ff0 100644 (file)
@@ -205,12 +205,11 @@ static int checklist(char *file, int line,
                MYASSERT(n->sdh.magic1 == MAGIC1);
                MYASSERT(n->sdh.magic2 == MAGIC2);
 #endif
-               MYASSERT(n->sdh.list == l);
                MYASSERT(usedpages_add(n->sdh.phys, VM_PAGE_SIZE) == OK);
                if(n->sdh.prev)
                        MYASSERT(n->sdh.prev->sdh.next == n);
                else
-                       MYASSERT(s->list_head[l] == n);
+                       MYASSERT(s->list_head == n);
                if(n->sdh.next) MYASSERT(n->sdh.next->sdh.prev == n);
                for(i = 0; i < USEELEMENTS*8; i++)
                        if(i >= ITEMSPERPAGE(bytes))
@@ -233,7 +232,6 @@ void slab_sanitycheck(char *file, int line)
 {
        int s;
        for(s = 0; s < SLABSIZES; s++) {
-               int l;
                checklist(file, line, &slabs[s], s + MINSIZE);
        }
 }
@@ -247,6 +245,8 @@ int slabsane_f(char *file, int line, void *mem, int bytes)
        struct slabdata *f;
        int i;
 
+       bytes = roundup(bytes, OBJALIGN);
+
        return (objstats(mem, bytes, &s, &f, &i) == OK);
 }
 #endif
@@ -508,7 +508,6 @@ void slabstats(void)
        n++;
        if(n%1000) return;
        for(s = 0; s < SLABSIZES; s++) {
-               int l;
                int b, t;
                b = s + MINSIZE;
                t = checklist(__FILE__, __LINE__, &slabs[s], b);