This commit was generated by cvs2svn to track changes on a CVS vendor
[unix-history] / sys / kern / kern_malloc.c
index 63a3bb0..9b2c4e2 100644 (file)
@@ -31,7 +31,7 @@
  * 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.5 1993/11/25 01:33:02 wollman Exp $
+ *     $Id: kern_malloc.c,v 1.8 1994/02/10 08:04:07 davidg Exp $
  */
 
 #include "param.h"
  */
 
 #include "param.h"
@@ -42,6 +42,8 @@
 #include "vm/vm.h"
 #include "vm/vm_kern.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;
@@ -252,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
 }
 #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
+                       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);
+       }
+}
+
+