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/dev/vinum/vinummemory.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 /*-
    2  * Copyright (c) 1997, 1998
    3  *      Nan Yang Computer Services Limited.  All rights reserved.
    4  *
    5  *  This software is distributed under the so-called ``Berkeley
    6  *  License'':
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. All advertising materials mentioning features or use of this software
   17  *    must display the following acknowledgement:
   18  *      This product includes software developed by Nan Yang Computer
   19  *      Services Limited.
   20  * 4. Neither the name of the Company nor the names of its contributors
   21  *    may be used to endorse or promote products derived from this software
   22  *    without specific prior written permission.
   23  *
   24  * This software is provided ``as is'', and any express or implied
   25  * warranties, including, but not limited to, the implied warranties of
   26  * merchantability and fitness for a particular purpose are disclaimed.
   27  * In no event shall the company or contributors be liable for any
   28  * direct, indirect, incidental, special, exemplary, or consequential
   29  * damages (including, but not limited to, procurement of substitute
   30  * goods or services; loss of use, data, or profits; or business
   31  * interruption) however caused and on any theory of liability, whether
   32  * in contract, strict liability, or tort (including negligence or
   33  * otherwise) arising in any way out of the use of this software, even if
   34  * advised of the possibility of such damage.
   35  *
   36  * $Id: vinummemory.c,v 1.31 2003/05/23 01:08:36 grog Exp $
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __FBSDID("$FreeBSD$");
   41 
   42 #include <dev/vinum/vinumhdr.h>
   43 
   44 #ifdef VINUMDEBUG
   45 #include <dev/vinum/request.h>
   46 extern struct rqinfo rqinfo[];
   47 extern struct rqinfo *rqip;
   48 int rqinfo_size = RQINFO_SIZE;                              /* for debugger */
   49 
   50 #undef longjmp                                              /* this was defined as LongJmp */
   51 #define strrchr rindex
   52 #ifdef __i386__                                             /* check for validity */
   53 void
   54 LongJmp(jmp_buf buf, int retval)
   55 {
   56 /*
   57    * longjmp is not documented, not even jmp_buf.
   58    * This is what's in i386/i386/support.s:
   59    * ENTRY(longjmp)
   60    *    movl    4(%esp),%eax
   61    *    movl    (%eax),%ebx                      restore ebx
   62    *    movl    4(%eax),%esp                     restore esp
   63    *    movl    8(%eax),%ebp                     restore ebp
   64    *    movl    12(%eax),%esi                    restore esi
   65    *    movl    16(%eax),%edi                    restore edi
   66    *    movl    20(%eax),%edx                    get rta
   67    *    movl    %edx,(%esp)                      put in return frame
   68    *    xorl    %eax,%eax                        return(1);
   69    *    incl    %eax
   70    *    ret
   71    *
   72    * from which we deduce the structure of jmp_buf:
   73  */
   74     struct JmpBuf {
   75         int jb_ebx;
   76         int jb_esp;
   77         int jb_ebp;
   78         int jb_esi;
   79         int jb_edi;
   80         int jb_eip;
   81     };
   82 
   83     struct JmpBuf *jb = (struct JmpBuf *) buf;
   84 
   85     if ((jb->jb_esp < 0xc0000000)
   86         || (jb->jb_ebp < 0xc0000000)
   87         || (jb->jb_eip < 0xc0000000))
   88         panic("Invalid longjmp");
   89     longjmp(buf, retval);
   90 }
   91 
   92 #else /* not i386 */
   93 #define LongJmp longjmp                                     /* just use the kernel function */
   94 #endif /* i386 */
   95 
   96 /* find the base name of a path name */
   97 char *
   98 basename(char *file)
   99 {
  100     char *f = strrchr(file, '/');                           /* chop off dirname if present */
  101 
  102     if (f == NULL)
  103         return file;
  104     else
  105         return ++f;                                         /* skip the / */
  106 }
  107 #endif /* VINUMDEBUG */
  108 
  109 #ifdef VINUMDEBUG
  110 void
  111 expand_table(void **table, int oldsize, int newsize, char *file, int line)
  112 #else
  113 void
  114 expand_table(void **table, int oldsize, int newsize)
  115 #endif
  116 {
  117     if (newsize > oldsize) {
  118         int *temp;
  119         int s;
  120 
  121         s = splhigh();
  122 #ifdef VINUMDEBUG
  123         temp = (int *) MMalloc(newsize, file, line);        /* allocate a new table */
  124 #else
  125         temp = (int *) Malloc(newsize);                     /* allocate a new table */
  126 #endif
  127         CHECKALLOC(temp, "vinum: Can't expand table\n");
  128         bzero((char *) temp, newsize);                      /* clean it all out */
  129         if (*table != NULL) {                               /* already something there, */
  130             bcopy((char *) *table, (char *) temp, oldsize); /* copy it to the old table */
  131 #ifdef VINUMDEBUG
  132             FFree(*table, file, line);
  133 #else
  134             Free(*table);
  135 #endif
  136         }
  137         *table = temp;
  138         splx(s);
  139     }
  140 }
  141 
  142 #ifdef VINUMDEBUG
  143 #define MALLOCENTRIES 16384
  144 int malloccount = 0;
  145 int highwater = 0;                                          /* highest index ever allocated */
  146 struct mc malloced[MALLOCENTRIES];
  147 
  148 #define FREECOUNT 64
  149 int freecount = FREECOUNT;                                  /* for debugger */
  150 int lastfree = 0;
  151 struct mc freeinfo[FREECOUNT];
  152 
  153 int total_malloced;
  154 static int mallocseq = 0;
  155 
  156 caddr_t
  157 MMalloc(int size, char *file, int line)
  158 {
  159     int s;
  160     caddr_t result;
  161     int i;
  162 
  163     if (malloccount >= MALLOCENTRIES) {                     /* too many */
  164         log(LOG_ERR, "vinum: can't allocate table space to trace memory allocation");
  165         return 0;                                           /* can't continue */
  166     }
  167     /* Wait for malloc if we can */
  168     result = malloc(size,
  169         M_DEVBUF,
  170         curthread->td_intr_nesting_level == 0 ? M_WAITOK : M_NOWAIT);
  171     if (result == NULL)
  172         log(LOG_ERR, "vinum: can't allocate %d bytes from %s:%d\n", size, file, line);
  173     else {
  174         s = splhigh();
  175         for (i = 0; i < malloccount; i++) {
  176             if (((result + size) > malloced[i].address)
  177                 && (result < malloced[i].address + malloced[i].size)) /* overlap */
  178                 kdb_enter("Malloc overlap");
  179         }
  180         if (result) {
  181             char *f = basename(file);
  182 
  183             i = malloccount++;
  184             total_malloced += size;
  185             microtime(&malloced[i].time);
  186             malloced[i].seq = mallocseq++;
  187             malloced[i].size = size;
  188             malloced[i].line = line;
  189             malloced[i].address = result;
  190             strlcpy(malloced[i].file, f, MCFILENAMELEN);
  191         }
  192         if (malloccount > highwater)
  193             highwater = malloccount;
  194         splx(s);
  195     }
  196     return result;
  197 }
  198 
  199 void
  200 FFree(void *mem, char *file, int line)
  201 {
  202     int s;
  203     int i;
  204 
  205     s = splhigh();
  206     for (i = 0; i < malloccount; i++) {
  207         if ((caddr_t) mem == malloced[i].address) {         /* found it */
  208             bzero(mem, malloced[i].size);                   /* XXX */
  209             free(mem, M_DEVBUF);
  210             malloccount--;
  211             total_malloced -= malloced[i].size;
  212             if (debug & DEBUG_MEMFREE) {                    /* keep track of recent frees */
  213                 char *f = strrchr(file, '/');               /* chop off dirname if present */
  214 
  215                 if (f == NULL)
  216                     f = file;
  217                 else
  218                     f++;                                    /* skip the / */
  219 
  220                 microtime(&freeinfo[lastfree].time);
  221                 freeinfo[lastfree].seq = malloced[i].seq;
  222                 freeinfo[lastfree].size = malloced[i].size;
  223                 freeinfo[lastfree].line = line;
  224                 freeinfo[lastfree].address = mem;
  225                 bcopy(f, freeinfo[lastfree].file, MCFILENAMELEN);
  226                 if (++lastfree == FREECOUNT)
  227                     lastfree = 0;
  228             }
  229             if (i < malloccount)                            /* more coming after */
  230                 bcopy(&malloced[i + 1], &malloced[i], (malloccount - i) * sizeof(struct mc));
  231             splx(s);
  232             return;
  233         }
  234     }
  235     splx(s);
  236     log(LOG_ERR,
  237         "Freeing unallocated data at 0x%p from %s, line %d\n",
  238         mem,
  239         file,
  240         line);
  241     kdb_enter("Free");
  242 }
  243 
  244 void
  245 vinum_meminfo(caddr_t data)
  246 {
  247     struct meminfo *m = (struct meminfo *) data;
  248 
  249     m->mallocs = malloccount;
  250     m->total_malloced = total_malloced;
  251     m->malloced = malloced;
  252     m->highwater = highwater;
  253 }
  254 
  255 int
  256 vinum_mallocinfo(caddr_t data)
  257 {
  258     struct mc *m = (struct mc *) data;
  259     unsigned int ent = m->seq;                              /* index of entry to return */
  260 
  261     if (ent >= malloccount)
  262         return ENOENT;
  263     m->address = malloced[ent].address;
  264     m->size = malloced[ent].size;
  265     m->line = malloced[ent].line;
  266     m->seq = malloced[ent].seq;
  267     strlcpy(m->file, malloced[ent].file, MCFILENAMELEN);
  268     return 0;
  269 }
  270 
  271 /*
  272  * return the nth request trace buffer entry.  This
  273  * is indexed back from the current entry (which
  274  * has index 0)
  275  */
  276 int
  277 vinum_rqinfo(caddr_t data)
  278 {
  279     struct rqinfo *rq = (struct rqinfo *) data;
  280     int ent = *(int *) data;                                /* 1st word is index */
  281     int lastent = rqip - rqinfo;                            /* entry number of current entry */
  282 
  283     if (ent >= RQINFO_SIZE)                                 /* out of the table */
  284         return ENOENT;
  285     if ((ent = lastent - ent - 1) < 0)
  286         ent += RQINFO_SIZE;                                 /* roll over backwards */
  287     bcopy(&rqinfo[ent], rq, sizeof(struct rqinfo));
  288     return 0;
  289 }
  290 #endif

Cache object: f384d248e82393d00af3c4b4e4707cf6


[ 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.