The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/kern_malloc.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: kern_malloc.c,v 1.158 2019/11/14 16:23:52 maxv Exp $   */
    2 
    3 /*
    4  * Copyright (c) 1987, 1991, 1993
    5  *      The Regents of the University of California.  All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. Neither the name of the University nor the names of its contributors
   16  *    may be used to endorse or promote products derived from this software
   17  *    without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  *
   31  *      @(#)kern_malloc.c       8.4 (Berkeley) 5/20/95
   32  */
   33 
   34 /*
   35  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
   36  *
   37  * Redistribution and use in source and binary forms, with or without
   38  * modification, are permitted provided that the following conditions
   39  * are met:
   40  * 1. Redistributions of source code must retain the above copyright
   41  *    notice, this list of conditions and the following disclaimer.
   42  * 2. Redistributions in binary form must reproduce the above copyright
   43  *    notice, this list of conditions and the following disclaimer in the
   44  *    documentation and/or other materials provided with the distribution.
   45  * 3. All advertising materials mentioning features or use of this software
   46  *    must display the following acknowledgement:
   47  *      This product includes software developed by the University of
   48  *      California, Berkeley and its contributors.
   49  * 4. Neither the name of the University nor the names of its contributors
   50  *    may be used to endorse or promote products derived from this software
   51  *    without specific prior written permission.
   52  *
   53  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   54  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   56  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   57  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   58  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   59  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   60  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   61  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   62  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   63  * SUCH DAMAGE.
   64  *
   65  *      @(#)kern_malloc.c       8.4 (Berkeley) 5/20/95
   66  */
   67 
   68 /*
   69  * Wrapper interface for obsolete malloc(9).
   70  */
   71 
   72 #include <sys/cdefs.h>
   73 __KERNEL_RCSID(0, "$NetBSD: kern_malloc.c,v 1.158 2019/11/14 16:23:52 maxv Exp $");
   74 
   75 #include <sys/param.h>
   76 #include <sys/malloc.h>
   77 #include <sys/kmem.h>
   78 #include <sys/asan.h>
   79 #include <sys/msan.h>
   80 
   81 /*
   82  * Built-in malloc types.  Note: ought to be removed.
   83  */
   84 MALLOC_DEFINE(M_DEVBUF, "devbuf", "device driver memory");
   85 MALLOC_DEFINE(M_DMAMAP, "DMA map", "bus_dma(9) structures");
   86 MALLOC_DEFINE(M_FREE, "free", "should be on free list");
   87 MALLOC_DEFINE(M_TEMP, "temp", "misc. temporary data buffers");
   88 MALLOC_DEFINE(M_RTABLE, "routetbl", "routing tables");
   89 MALLOC_DEFINE(M_FTABLE, "fragtbl", "fragment reassembly header");
   90 MALLOC_DEFINE(M_UFSMNT, "UFS mount", "UFS mount structure");
   91 MALLOC_DEFINE(M_NETADDR, "Export Host", "Export host address structure");
   92 MALLOC_DEFINE(M_MRTABLE, "mrt", "multicast routing tables");
   93 
   94 /*
   95  * Header contains total size, including the header itself.
   96  */
   97 struct malloc_header {
   98         size_t mh_size;
   99 #ifdef KASAN
  100         size_t mh_rqsz;
  101 #endif
  102 } __aligned(ALIGNBYTES + 1);
  103 
  104 void *
  105 kern_malloc(unsigned long reqsize, int flags)
  106 {
  107         const int kmflags = (flags & M_NOWAIT) ? KM_NOSLEEP : KM_SLEEP;
  108 #ifdef KASAN
  109         const size_t origsize = reqsize;
  110 #endif
  111         size_t size = reqsize;
  112         size_t allocsize, hdroffset;
  113         struct malloc_header *mh;
  114         void *p;
  115 
  116         kasan_add_redzone(&size);
  117 
  118         if (size >= PAGE_SIZE) {
  119                 if (size > (ULONG_MAX-PAGE_SIZE))
  120                         allocsize = ULONG_MAX;  /* this will fail later */
  121                 else
  122                         allocsize = PAGE_SIZE + size; /* for page alignment */
  123                 hdroffset = PAGE_SIZE - sizeof(struct malloc_header);
  124         } else {
  125                 allocsize = sizeof(struct malloc_header) + size;
  126                 hdroffset = 0;
  127         }
  128 
  129         p = kmem_intr_alloc(allocsize, kmflags);
  130         if (p == NULL)
  131                 return NULL;
  132 
  133         kmsan_mark(p, allocsize, KMSAN_STATE_UNINIT);
  134         kmsan_orig(p, allocsize, KMSAN_TYPE_MALLOC, __RET_ADDR);
  135 
  136         if ((flags & M_ZERO) != 0) {
  137                 memset(p, 0, allocsize);
  138         }
  139         mh = (void *)((char *)p + hdroffset);
  140         mh->mh_size = allocsize - hdroffset;
  141 #ifdef KASAN
  142         mh->mh_rqsz = origsize;
  143 #endif
  144         mh++;
  145 
  146         kasan_mark(mh, origsize, size, KASAN_MALLOC_REDZONE);
  147 
  148         return mh;
  149 }
  150 
  151 void
  152 kern_free(void *addr)
  153 {
  154         struct malloc_header *mh;
  155 
  156         mh = addr;
  157         mh--;
  158 
  159         kasan_mark(addr, mh->mh_size - sizeof(struct malloc_header),
  160             mh->mh_size - sizeof(struct malloc_header), KASAN_MALLOC_REDZONE);
  161 
  162         if (mh->mh_size >= PAGE_SIZE + sizeof(struct malloc_header)) {
  163                 kmsan_mark((char *)addr - PAGE_SIZE,
  164                     mh->mh_size + PAGE_SIZE - sizeof(struct malloc_header),
  165                     KMSAN_STATE_INITED);
  166                 kmem_intr_free((char *)addr - PAGE_SIZE,
  167                     mh->mh_size + PAGE_SIZE - sizeof(struct malloc_header));
  168         } else {
  169                 kmsan_mark(mh, mh->mh_size, KMSAN_STATE_INITED);
  170                 kmem_intr_free(mh, mh->mh_size);
  171         }
  172 }
  173 
  174 void *
  175 kern_realloc(void *curaddr, unsigned long newsize, int flags)
  176 {
  177         struct malloc_header *mh;
  178         unsigned long cursize;
  179         void *newaddr;
  180 
  181         /*
  182          * realloc() with a NULL pointer is the same as malloc().
  183          */
  184         if (curaddr == NULL)
  185                 return malloc(newsize, ksp, flags);
  186 
  187         /*
  188          * realloc() with zero size is the same as free().
  189          */
  190         if (newsize == 0) {
  191                 free(curaddr, ksp);
  192                 return NULL;
  193         }
  194 
  195         if ((flags & M_NOWAIT) == 0) {
  196                 ASSERT_SLEEPABLE();
  197         }
  198 
  199         mh = curaddr;
  200         mh--;
  201 
  202 #ifdef KASAN
  203         cursize = mh->mh_rqsz;
  204 #else
  205         cursize = mh->mh_size - sizeof(struct malloc_header);
  206 #endif
  207 
  208         /*
  209          * If we already actually have as much as they want, we're done.
  210          */
  211         if (newsize <= cursize)
  212                 return curaddr;
  213 
  214         /*
  215          * Can't satisfy the allocation with the existing block.
  216          * Allocate a new one and copy the data.
  217          */
  218         newaddr = malloc(newsize, ksp, flags);
  219         if (__predict_false(newaddr == NULL)) {
  220                 /*
  221                  * malloc() failed, because flags included M_NOWAIT.
  222                  * Return NULL to indicate that failure.  The old
  223                  * pointer is still valid.
  224                  */
  225                 return NULL;
  226         }
  227         memcpy(newaddr, curaddr, cursize);
  228 
  229         /*
  230          * We were successful: free the old allocation and return
  231          * the new one.
  232          */
  233         free(curaddr, ksp);
  234         return newaddr;
  235 }

Cache object: 349e77243db25272c0e6e8f249722d33


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.