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/raid/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.25 2000/05/04 01:57:48 grog Exp grog $
   37  * $FreeBSD: src/sys/dev/vinum/vinummemory.c,v 1.22.2.1 2000/06/02 04:26:11 grog Exp $
   38  * $DragonFly: src/sys/dev/raid/vinum/vinummemory.c,v 1.9 2006/09/05 00:55:42 dillon Exp $
   39  */
   40 
   41 #include "vinumhdr.h"
   42 
   43 #ifdef VINUMDEBUG
   44 #undef longjmp                                              /* this was defined as LongJmp */
   45 void longjmp(jmp_buf, int);                                 /* the kernel doesn't define this */
   46 
   47 #include "request.h"
   48 extern struct rqinfo rqinfo[];
   49 extern struct rqinfo *rqip;
   50 int rqinfo_size = RQINFO_SIZE;                              /* for debugger */
   51 
   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
   93 #define LongJmp longjmp                                     /* just use the kernel function */
   94 #endif
   95 #endif
   96 
   97 /* find the base name of a path name */
   98 char *
   99 basename(char *file)
  100 {
  101     char *f = rindex(file, '/');                            /* chop off dirname if present */
  102 
  103     if (f == NULL)
  104         return file;
  105     else
  106         return ++f;                                         /* skip the / */
  107 }
  108 
  109 void
  110 expand_table(void **table, int oldsize, int newsize)
  111 {
  112     if (newsize > oldsize) {
  113         int *temp;
  114 
  115         crit_enter();
  116         temp = (int *) Malloc(newsize);                     /* allocate a new table */
  117         CHECKALLOC(temp, "vinum: Can't expand table\n");
  118         bzero((char *) temp, newsize);                      /* clean it all out */
  119         if (*table != NULL) {                               /* already something there, */
  120             bcopy((char *) *table, (char *) temp, oldsize); /* copy it to the old table */
  121             Free(*table);
  122         }
  123         *table = temp;
  124         crit_exit();
  125     }
  126 }
  127 
  128 #if VINUMDEBUG                                              /* XXX debug */
  129 #define MALLOCENTRIES 16384
  130 int malloccount = 0;
  131 int highwater = 0;                                          /* highest index ever allocated */
  132 struct mc malloced[MALLOCENTRIES];
  133 
  134 #define FREECOUNT 64
  135 int freecount = FREECOUNT;                                  /* for debugger */
  136 int lastfree = 0;
  137 struct mc freeinfo[FREECOUNT];
  138 
  139 int total_malloced;
  140 static int mallocseq = 0;
  141 
  142 caddr_t
  143 MMalloc(int size, char *file, int line)
  144 {
  145     caddr_t result;
  146     int i;
  147 
  148     if (malloccount >= MALLOCENTRIES) {                     /* too many */
  149         log(LOG_ERR, "vinum: can't allocate table space to trace memory allocation");
  150         return 0;                                           /* can't continue */
  151     }
  152     /* Wait for malloc if we can */
  153     result = kmalloc(size, M_DEVBUF, mycpu->gd_intr_nesting_level == 0 ? M_WAITOK : M_INTWAIT);
  154     if (result == NULL)
  155         log(LOG_ERR, "vinum: can't allocate %d bytes from %s:%d\n", size, file, line);
  156     else {
  157         crit_enter();
  158         for (i = 0; i < malloccount; i++) {
  159             if (((result + size) > malloced[i].address)
  160                 && (result < malloced[i].address + malloced[i].size)) /* overlap */
  161                 Debugger("Malloc overlap");
  162         }
  163         if (result) {
  164             char *f = basename(file);
  165 
  166             i = malloccount++;
  167             total_malloced += size;
  168             microtime(&malloced[i].time);
  169             malloced[i].seq = mallocseq++;
  170             malloced[i].size = size;
  171             malloced[i].line = line;
  172             malloced[i].address = result;
  173             bcopy(f, malloced[i].file, min(strlen(f), MCFILENAMELEN - 1));
  174             malloced[i].file[MCFILENAMELEN - 1] = '\0';
  175         }
  176         if (malloccount > highwater)
  177             highwater = malloccount;
  178         crit_exit();
  179     }
  180     return result;
  181 }
  182 
  183 void
  184 FFree(void *mem, char *file, int line)
  185 {
  186     int i;
  187 
  188     crit_enter();
  189     for (i = 0; i < malloccount; i++) {
  190         if ((caddr_t) mem == malloced[i].address) {         /* found it */
  191             bzero(mem, malloced[i].size);                   /* XXX */
  192             kfree(mem, M_DEVBUF);
  193             malloccount--;
  194             total_malloced -= malloced[i].size;
  195             if (debug & DEBUG_MEMFREE) {                    /* keep track of recent frees */
  196                 char *f = rindex(file, '/');                /* chop off dirname if present */
  197 
  198                 if (f == NULL)
  199                     f = file;
  200                 else
  201                     f++;                                    /* skip the / */
  202 
  203                 microtime(&freeinfo[lastfree].time);
  204                 freeinfo[lastfree].seq = malloced[i].seq;
  205                 freeinfo[lastfree].size = malloced[i].size;
  206                 freeinfo[lastfree].line = line;
  207                 freeinfo[lastfree].address = mem;
  208                 bcopy(f, freeinfo[lastfree].file, min(strlen(f), MCFILENAMELEN - 1));
  209                 freeinfo[lastfree].file[MCFILENAMELEN - 1] = '\0';
  210                 if (++lastfree == FREECOUNT)
  211                     lastfree = 0;
  212             }
  213             if (i < malloccount)                            /* more coming after */
  214                 bcopy(&malloced[i + 1], &malloced[i], (malloccount - i) * sizeof(struct mc));
  215             crit_exit();
  216             return;
  217         }
  218     }
  219     log(LOG_ERR,
  220         "Freeing unallocated data at 0x%p from %s, line %d\n",
  221         mem,
  222         file,
  223         line);
  224     Debugger("Free");
  225     crit_exit();
  226 }
  227 
  228 void
  229 vinum_meminfo(caddr_t data)
  230 {
  231     struct meminfo *m = (struct meminfo *) data;
  232 
  233     m->mallocs = malloccount;
  234     m->total_malloced = total_malloced;
  235     m->malloced = malloced;
  236     m->highwater = highwater;
  237 }
  238 
  239 int
  240 vinum_mallocinfo(caddr_t data)
  241 {
  242     struct mc *m = (struct mc *) data;
  243     unsigned int ent = m->seq;                              /* index of entry to return */
  244 
  245     if (ent >= malloccount)
  246         return ENOENT;
  247     m->address = malloced[ent].address;
  248     m->size = malloced[ent].size;
  249     m->line = malloced[ent].line;
  250     m->seq = malloced[ent].seq;
  251     bcopy(malloced[ent].file, m->file, MCFILENAMELEN);
  252     return 0;
  253 }
  254 
  255 /*
  256  * return the nth request trace buffer entry.  This
  257  * is indexed back from the current entry (which
  258  * has index 0)
  259  */
  260 int
  261 vinum_rqinfo(caddr_t data)
  262 {
  263     struct rqinfo *rq = (struct rqinfo *) data;
  264     int ent = *(int *) data;                                /* 1st word is index */
  265     int lastent = rqip - rqinfo;                            /* entry number of current entry */
  266 
  267     if (ent >= RQINFO_SIZE)                                 /* out of the table */
  268         return ENOENT;
  269     if ((ent = lastent - ent - 1) < 0)
  270         ent += RQINFO_SIZE;                                 /* roll over backwards */
  271     bcopy(&rqinfo[ent], rq, sizeof(struct rqinfo));
  272     return 0;
  273 }
  274 #endif

Cache object: 7f69b6a1ff50bad7737d4ff09ffe3fde


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