This commit was generated by cvs2svn to track changes on a CVS vendor
[unix-history] / sys / kern / kern_malloc.c
index 59bbc0f..9b2c4e2 100644 (file)
  * SUCH DAMAGE.
  *
  *     from: @(#)kern_malloc.c 7.25 (Berkeley) 5/8/91
  * SUCH DAMAGE.
  *
  *     from: @(#)kern_malloc.c 7.25 (Berkeley) 5/8/91
- *     $Id: kern_malloc.c,v 1.3 1993/10/18 03:46:54 davidg Exp $
+ *     $Id: kern_malloc.c,v 1.8 1994/02/10 08:04:07 davidg Exp $
  */
 
 #include "param.h"
  */
 
 #include "param.h"
+#include "systm.h"
 #include "proc.h"
 #include "kernel.h"
 #include "malloc.h"
 #include "vm/vm.h"
 #include "vm/vm_kern.h"
 
 #include "proc.h"
 #include "kernel.h"
 #include "malloc.h"
 #include "vm/vm.h"
 #include "vm/vm_kern.h"
 
+extern int vm_page_count;
+
 struct kmembuckets bucket[MINBUCKET + 16];
 struct kmemstats kmemstats[M_LAST];
 struct kmemusage *kmemusage;
 struct kmembuckets bucket[MINBUCKET + 16];
 struct kmemstats kmemstats[M_LAST];
 struct kmemusage *kmemusage;
@@ -224,18 +227,19 @@ free(addr, type)
 /*
  * Initialize the kernel memory allocator
  */
 /*
  * Initialize the kernel memory allocator
  */
+void
 kmeminit()
 {
        register long indx;
        int npg;
 
 #if    (MAXALLOCSAVE > MINALLOCSIZE * 32768)
 kmeminit()
 {
        register long indx;
        int npg;
 
 #if    (MAXALLOCSAVE > MINALLOCSIZE * 32768)
-               ERROR!_kmeminit:_MAXALLOCSAVE_too_big
+#  error "kmeminit: MAXALLOCSAVE too big"
 #endif
 #if    (MAXALLOCSAVE < CLBYTES-1)
 #endif
 #if    (MAXALLOCSAVE < CLBYTES-1)
-               ERROR!_kmeminit:_MAXALLOCSAVE_too_small
+#  error "kmeminit: MAXALLOCSAVE too small"
 #endif
 #endif
-       npg = VM_KMEM_SIZE/ NBPG;
+       npg = (VM_KMEM_SIZE + VM_MBUF_SIZE) / NBPG;
        kmemusage = (struct kmemusage *) kmem_alloc(kernel_map,
                (vm_size_t)(npg * sizeof(struct kmemusage)));
        kmem_map = kmem_suballoc(kernel_map, (vm_offset_t *)&kmembase,
        kmemusage = (struct kmemusage *) kmem_alloc(kernel_map,
                (vm_size_t)(npg * sizeof(struct kmemusage)));
        kmem_map = kmem_suballoc(kernel_map, (vm_offset_t *)&kmembase,
@@ -250,5 +254,80 @@ kmeminit()
        }
        for (indx = 0; indx < M_LAST; indx++)
                kmemstats[indx].ks_limit = npg * NBPG * 6 / 10;
        }
        for (indx = 0; indx < M_LAST; indx++)
                kmemstats[indx].ks_limit = npg * NBPG * 6 / 10;
+
+       /* limit the amount of mbuf space to 1/16 of system memory */
+       kmemstats[M_MBUF].ks_limit = (vm_page_count * NBPG) / 16;
+#endif
+}
+
+void *
+contigmalloc(size, type, flags, maxpa, alignmask, boundarymask)
+       unsigned long size;
+       int type;
+       int flags;
+       unsigned long maxpa;            /* e.g. 16M - 1 for isa dma */
+       unsigned long alignmask;        /* e.g. 1M - 1 for M boundary */
+       unsigned long boundarymask;     /* e.g. 64K - 1 for 8-bit isa dma */
+{
+       unsigned long skipsize;
+       void *skipva;
+
+       size = round_page(size);
+       if (size == 0 || size > boundarymask + 1)
+               return (NULL);
+
+       /*
+        * Attempt to push the physical address to a suitable boundary by
+        * skipping some memory.  We could be cleverer here.  E.g., mallocate
+        * lots of single pages and then free the ones that we hope to use.
+        * flags == M_WAIT is likely to hang the system.
+        */
+       for (skipsize = 0, skipva = NULL; ; skipsize += NBPG) {
+               unsigned long off;
+               unsigned long pa;
+               unsigned long prevpa;
+               void *va;
+
+               if (skipsize != 0) {
+                       skipva = malloc(skipsize, type, flags);
+                       if (skipva == NULL) {
+#ifdef DEBUG
+                               printf("contigmalloc: skipva NULL on try %d\n",
+                                      1 + skipsize / NBPG);
+#endif
+                               return (NULL);
+                       }
+               }
+               va = malloc(size, type, flags);
+               if (skipsize != 0)
+                       free(skipva, type);
+               if (va == NULL) {
+#ifdef DEBUG
+                       printf("contigmalloc: va NULL on try %d\n",
+                              1 + skipsize / NBPG);
 #endif
 #endif
+                       return (NULL);
+               }
+               for (off = 0, prevpa = 0; off < size; off += NBPG, prevpa = pa)
+               {
+                       pa = pmap_extract(pmap_kernel(), (vm_offset_t)va + off);
+                       if (pa + NBPG - 1 > maxpa
+                           || off == 0 && pa & alignmask
+                           || off != 0
+                              && (pa != prevpa + NBPG
+                                  || (pa & boundarymask) == 0))
+                               goto fail;
+               }
+#ifdef DEBUG
+               printf("contigmalloc: success at va %lx pa %lx on try %d\n",
+                      (unsigned long)va,
+                      pmap_extract(pmap_kernel(), (unsigned long)va),
+                      1 + skipsize / NBPG);
+#endif
+               return (va);
+fail:
+               free(va, type);
+       }
 }
 }
+
+