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/vm/vm_kern.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) 1991, 1993
    3  *      The Regents of the University of California.  All rights reserved.
    4  *
    5  * This code is derived from software contributed to Berkeley by
    6  * The Mach Operating System project at Carnegie-Mellon University.
    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  * 4. Neither the name of the University nor the names of its contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  *
   32  *      from: @(#)vm_kern.c     8.3 (Berkeley) 1/12/94
   33  *
   34  *
   35  * Copyright (c) 1987, 1990 Carnegie-Mellon University.
   36  * All rights reserved.
   37  *
   38  * Authors: Avadis Tevanian, Jr., Michael Wayne Young
   39  *
   40  * Permission to use, copy, modify and distribute this software and
   41  * its documentation is hereby granted, provided that both the copyright
   42  * notice and this permission notice appear in all copies of the
   43  * software, derivative works or modified versions, and any portions
   44  * thereof, and that both notices appear in supporting documentation.
   45  *
   46  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   47  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
   48  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   49  *
   50  * Carnegie Mellon requests users of this software to return to
   51  *
   52  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   53  *  School of Computer Science
   54  *  Carnegie Mellon University
   55  *  Pittsburgh PA 15213-3890
   56  *
   57  * any improvements or extensions that they make and grant Carnegie the
   58  * rights to redistribute these changes.
   59  */
   60 
   61 /*
   62  *      Kernel memory management.
   63  */
   64 
   65 #include <sys/cdefs.h>
   66 __FBSDID("$FreeBSD: releng/10.0/sys/vm/vm_kern.c 255426 2013-09-09 18:11:59Z jhb $");
   67 
   68 #include <sys/param.h>
   69 #include <sys/systm.h>
   70 #include <sys/kernel.h>         /* for ticks and hz */
   71 #include <sys/eventhandler.h>
   72 #include <sys/lock.h>
   73 #include <sys/proc.h>
   74 #include <sys/malloc.h>
   75 #include <sys/rwlock.h>
   76 #include <sys/sysctl.h>
   77 #include <sys/vmem.h>
   78 
   79 #include <vm/vm.h>
   80 #include <vm/vm_param.h>
   81 #include <vm/vm_kern.h>
   82 #include <vm/pmap.h>
   83 #include <vm/vm_map.h>
   84 #include <vm/vm_object.h>
   85 #include <vm/vm_page.h>
   86 #include <vm/vm_pageout.h>
   87 #include <vm/vm_extern.h>
   88 #include <vm/uma.h>
   89 
   90 vm_map_t kernel_map;
   91 vm_map_t exec_map;
   92 vm_map_t pipe_map;
   93 
   94 const void *zero_region;
   95 CTASSERT((ZERO_REGION_SIZE & PAGE_MASK) == 0);
   96 
   97 SYSCTL_ULONG(_vm, OID_AUTO, min_kernel_address, CTLFLAG_RD,
   98     NULL, VM_MIN_KERNEL_ADDRESS, "Min kernel address");
   99 
  100 SYSCTL_ULONG(_vm, OID_AUTO, max_kernel_address, CTLFLAG_RD,
  101 #if defined(__arm__) || defined(__sparc64__)
  102     &vm_max_kernel_address, 0,
  103 #else
  104     NULL, VM_MAX_KERNEL_ADDRESS,
  105 #endif
  106     "Max kernel address");
  107 
  108 /*
  109  *      kva_alloc:
  110  *
  111  *      Allocate a virtual address range with no underlying object and
  112  *      no initial mapping to physical memory.  Any mapping from this
  113  *      range to physical memory must be explicitly created prior to
  114  *      its use, typically with pmap_qenter().  Any attempt to create
  115  *      a mapping on demand through vm_fault() will result in a panic. 
  116  */
  117 vm_offset_t
  118 kva_alloc(size)
  119         vm_size_t size;
  120 {
  121         vm_offset_t addr;
  122 
  123         size = round_page(size);
  124         if (vmem_alloc(kernel_arena, size, M_BESTFIT | M_NOWAIT, &addr))
  125                 return (0);
  126 
  127         return (addr);
  128 }
  129 
  130 /*
  131  *      kva_free:
  132  *
  133  *      Release a region of kernel virtual memory allocated
  134  *      with kva_alloc, and return the physical pages
  135  *      associated with that region.
  136  *
  137  *      This routine may not block on kernel maps.
  138  */
  139 void
  140 kva_free(addr, size)
  141         vm_offset_t addr;
  142         vm_size_t size;
  143 {
  144 
  145         size = round_page(size);
  146         vmem_free(kernel_arena, addr, size);
  147 }
  148 
  149 /*
  150  *      Allocates a region from the kernel address map and physical pages
  151  *      within the specified address range to the kernel object.  Creates a
  152  *      wired mapping from this region to these pages, and returns the
  153  *      region's starting virtual address.  The allocated pages are not
  154  *      necessarily physically contiguous.  If M_ZERO is specified through the
  155  *      given flags, then the pages are zeroed before they are mapped.
  156  */
  157 vm_offset_t
  158 kmem_alloc_attr(vmem_t *vmem, vm_size_t size, int flags, vm_paddr_t low,
  159     vm_paddr_t high, vm_memattr_t memattr)
  160 {
  161         vm_object_t object = vmem == kmem_arena ? kmem_object : kernel_object;
  162         vm_offset_t addr;
  163         vm_ooffset_t offset;
  164         vm_page_t m;
  165         int pflags, tries;
  166         int i;
  167 
  168         size = round_page(size);
  169         if (vmem_alloc(vmem, size, M_BESTFIT | flags, &addr))
  170                 return (0);
  171         offset = addr - VM_MIN_KERNEL_ADDRESS;
  172         pflags = malloc2vm_flags(flags) | VM_ALLOC_NOBUSY | VM_ALLOC_WIRED;
  173         VM_OBJECT_WLOCK(object);
  174         for (i = 0; i < size; i += PAGE_SIZE) {
  175                 tries = 0;
  176 retry:
  177                 m = vm_page_alloc_contig(object, OFF_TO_IDX(offset + i),
  178                     pflags, 1, low, high, PAGE_SIZE, 0, memattr);
  179                 if (m == NULL) {
  180                         VM_OBJECT_WUNLOCK(object);
  181                         if (tries < ((flags & M_NOWAIT) != 0 ? 1 : 3)) {
  182                                 vm_pageout_grow_cache(tries, low, high);
  183                                 VM_OBJECT_WLOCK(object);
  184                                 tries++;
  185                                 goto retry;
  186                         }
  187                         /* 
  188                          * Unmap and free the pages.
  189                          */
  190                         if (i != 0)
  191                                 pmap_remove(kernel_pmap, addr, addr + i);
  192                         while (i != 0) {
  193                                 i -= PAGE_SIZE;
  194                                 m = vm_page_lookup(object,
  195                                     OFF_TO_IDX(offset + i));
  196                                 vm_page_unwire(m, 0);
  197                                 vm_page_free(m);
  198                         }
  199                         vmem_free(vmem, addr, size);
  200                         return (0);
  201                 }
  202                 if ((flags & M_ZERO) && (m->flags & PG_ZERO) == 0)
  203                         pmap_zero_page(m);
  204                 m->valid = VM_PAGE_BITS_ALL;
  205                 pmap_enter(kernel_pmap, addr + i, VM_PROT_ALL, m, VM_PROT_ALL,
  206                     TRUE);
  207         }
  208         VM_OBJECT_WUNLOCK(object);
  209         return (addr);
  210 }
  211 
  212 /*
  213  *      Allocates a region from the kernel address map and physically
  214  *      contiguous pages within the specified address range to the kernel
  215  *      object.  Creates a wired mapping from this region to these pages, and
  216  *      returns the region's starting virtual address.  If M_ZERO is specified
  217  *      through the given flags, then the pages are zeroed before they are
  218  *      mapped.
  219  */
  220 vm_offset_t
  221 kmem_alloc_contig(struct vmem *vmem, vm_size_t size, int flags, vm_paddr_t low,
  222     vm_paddr_t high, u_long alignment, vm_paddr_t boundary,
  223     vm_memattr_t memattr)
  224 {
  225         vm_object_t object = vmem == kmem_arena ? kmem_object : kernel_object;
  226         vm_offset_t addr, tmp;
  227         vm_ooffset_t offset;
  228         vm_page_t end_m, m;
  229         int pflags, tries;
  230  
  231         size = round_page(size);
  232         if (vmem_alloc(vmem, size, flags | M_BESTFIT, &addr))
  233                 return (0);
  234         offset = addr - VM_MIN_KERNEL_ADDRESS;
  235         pflags = malloc2vm_flags(flags) | VM_ALLOC_NOBUSY | VM_ALLOC_WIRED;
  236         VM_OBJECT_WLOCK(object);
  237         tries = 0;
  238 retry:
  239         m = vm_page_alloc_contig(object, OFF_TO_IDX(offset), pflags,
  240             atop(size), low, high, alignment, boundary, memattr);
  241         if (m == NULL) {
  242                 VM_OBJECT_WUNLOCK(object);
  243                 if (tries < ((flags & M_NOWAIT) != 0 ? 1 : 3)) {
  244                         vm_pageout_grow_cache(tries, low, high);
  245                         VM_OBJECT_WLOCK(object);
  246                         tries++;
  247                         goto retry;
  248                 }
  249                 vmem_free(vmem, addr, size);
  250                 return (0);
  251         }
  252         end_m = m + atop(size);
  253         tmp = addr;
  254         for (; m < end_m; m++) {
  255                 if ((flags & M_ZERO) && (m->flags & PG_ZERO) == 0)
  256                         pmap_zero_page(m);
  257                 m->valid = VM_PAGE_BITS_ALL;
  258                 pmap_enter(kernel_pmap, tmp, VM_PROT_ALL, m, VM_PROT_ALL, true);
  259                 tmp += PAGE_SIZE;
  260         }
  261         VM_OBJECT_WUNLOCK(object);
  262         return (addr);
  263 }
  264 
  265 /*
  266  *      kmem_suballoc:
  267  *
  268  *      Allocates a map to manage a subrange
  269  *      of the kernel virtual address space.
  270  *
  271  *      Arguments are as follows:
  272  *
  273  *      parent          Map to take range from
  274  *      min, max        Returned endpoints of map
  275  *      size            Size of range to find
  276  *      superpage_align Request that min is superpage aligned
  277  */
  278 vm_map_t
  279 kmem_suballoc(vm_map_t parent, vm_offset_t *min, vm_offset_t *max,
  280     vm_size_t size, boolean_t superpage_align)
  281 {
  282         int ret;
  283         vm_map_t result;
  284 
  285         size = round_page(size);
  286 
  287         *min = vm_map_min(parent);
  288         ret = vm_map_find(parent, NULL, 0, min, size, 0, superpage_align ?
  289             VMFS_SUPER_SPACE : VMFS_ANY_SPACE, VM_PROT_ALL, VM_PROT_ALL,
  290             MAP_ACC_NO_CHARGE);
  291         if (ret != KERN_SUCCESS)
  292                 panic("kmem_suballoc: bad status return of %d", ret);
  293         *max = *min + size;
  294         result = vm_map_create(vm_map_pmap(parent), *min, *max);
  295         if (result == NULL)
  296                 panic("kmem_suballoc: cannot create submap");
  297         if (vm_map_submap(parent, *min, *max, result) != KERN_SUCCESS)
  298                 panic("kmem_suballoc: unable to change range to submap");
  299         return (result);
  300 }
  301 
  302 /*
  303  *      kmem_malloc:
  304  *
  305  *      Allocate wired-down pages in the kernel's address space.
  306  */
  307 vm_offset_t
  308 kmem_malloc(struct vmem *vmem, vm_size_t size, int flags)
  309 {
  310         vm_offset_t addr;
  311         int rv;
  312 
  313         size = round_page(size);
  314         if (vmem_alloc(vmem, size, flags | M_BESTFIT, &addr))
  315                 return (0);
  316 
  317         rv = kmem_back((vmem == kmem_arena) ? kmem_object : kernel_object,
  318             addr, size, flags);
  319         if (rv != KERN_SUCCESS) {
  320                 vmem_free(vmem, addr, size);
  321                 return (0);
  322         }
  323         return (addr);
  324 }
  325 
  326 /*
  327  *      kmem_back:
  328  *
  329  *      Allocate physical pages for the specified virtual address range.
  330  */
  331 int
  332 kmem_back(vm_object_t object, vm_offset_t addr, vm_size_t size, int flags)
  333 {
  334         vm_offset_t offset, i;
  335         vm_page_t m;
  336         int pflags;
  337 
  338         KASSERT(object == kmem_object || object == kernel_object,
  339             ("kmem_back: only supports kernel objects."));
  340 
  341         offset = addr - VM_MIN_KERNEL_ADDRESS;
  342         pflags = malloc2vm_flags(flags) | VM_ALLOC_NOBUSY | VM_ALLOC_WIRED;
  343 
  344         VM_OBJECT_WLOCK(object);
  345         for (i = 0; i < size; i += PAGE_SIZE) {
  346 retry:
  347                 m = vm_page_alloc(object, OFF_TO_IDX(offset + i), pflags);
  348 
  349                 /*
  350                  * Ran out of space, free everything up and return. Don't need
  351                  * to lock page queues here as we know that the pages we got
  352                  * aren't on any queues.
  353                  */
  354                 if (m == NULL) {
  355                         if ((flags & M_NOWAIT) == 0) {
  356                                 VM_OBJECT_WUNLOCK(object);
  357                                 VM_WAIT;
  358                                 VM_OBJECT_WLOCK(object);
  359                                 goto retry;
  360                         }
  361                         /* 
  362                          * Unmap and free the pages.
  363                          */
  364                         if (i != 0)
  365                                 pmap_remove(kernel_pmap, addr, addr + i);
  366                         while (i != 0) {
  367                                 i -= PAGE_SIZE;
  368                                 m = vm_page_lookup(object,
  369                                                    OFF_TO_IDX(offset + i));
  370                                 vm_page_unwire(m, 0);
  371                                 vm_page_free(m);
  372                         }
  373                         VM_OBJECT_WUNLOCK(object);
  374                         return (KERN_NO_SPACE);
  375                 }
  376                 if (flags & M_ZERO && (m->flags & PG_ZERO) == 0)
  377                         pmap_zero_page(m);
  378                 KASSERT((m->oflags & VPO_UNMANAGED) != 0,
  379                     ("kmem_malloc: page %p is managed", m));
  380                 m->valid = VM_PAGE_BITS_ALL;
  381                 pmap_enter(kernel_pmap, addr + i, VM_PROT_ALL, m, VM_PROT_ALL,
  382                     TRUE);
  383         }
  384         VM_OBJECT_WUNLOCK(object);
  385 
  386         return (KERN_SUCCESS);
  387 }
  388 
  389 void
  390 kmem_unback(vm_object_t object, vm_offset_t addr, vm_size_t size)
  391 {
  392         vm_page_t m;
  393         vm_offset_t offset;
  394         int i;
  395 
  396         KASSERT(object == kmem_object || object == kernel_object,
  397             ("kmem_unback: only supports kernel objects."));
  398 
  399         offset = addr - VM_MIN_KERNEL_ADDRESS;
  400         VM_OBJECT_WLOCK(object);
  401         pmap_remove(kernel_pmap, addr, addr + size);
  402         for (i = 0; i < size; i += PAGE_SIZE) {
  403                 m = vm_page_lookup(object, OFF_TO_IDX(offset + i));
  404                 vm_page_unwire(m, 0);
  405                 vm_page_free(m);
  406         }
  407         VM_OBJECT_WUNLOCK(object);
  408 }
  409 
  410 /*
  411  *      kmem_free:
  412  *
  413  *      Free memory allocated with kmem_malloc.  The size must match the
  414  *      original allocation.
  415  */
  416 void
  417 kmem_free(struct vmem *vmem, vm_offset_t addr, vm_size_t size)
  418 {
  419 
  420         size = round_page(size);
  421         kmem_unback((vmem == kmem_arena) ? kmem_object : kernel_object,
  422             addr, size);
  423         vmem_free(vmem, addr, size);
  424 }
  425 
  426 /*
  427  *      kmap_alloc_wait:
  428  *
  429  *      Allocates pageable memory from a sub-map of the kernel.  If the submap
  430  *      has no room, the caller sleeps waiting for more memory in the submap.
  431  *
  432  *      This routine may block.
  433  */
  434 vm_offset_t
  435 kmap_alloc_wait(map, size)
  436         vm_map_t map;
  437         vm_size_t size;
  438 {
  439         vm_offset_t addr;
  440 
  441         size = round_page(size);
  442         if (!swap_reserve(size))
  443                 return (0);
  444 
  445         for (;;) {
  446                 /*
  447                  * To make this work for more than one map, use the map's lock
  448                  * to lock out sleepers/wakers.
  449                  */
  450                 vm_map_lock(map);
  451                 if (vm_map_findspace(map, vm_map_min(map), size, &addr) == 0)
  452                         break;
  453                 /* no space now; see if we can ever get space */
  454                 if (vm_map_max(map) - vm_map_min(map) < size) {
  455                         vm_map_unlock(map);
  456                         swap_release(size);
  457                         return (0);
  458                 }
  459                 map->needs_wakeup = TRUE;
  460                 vm_map_unlock_and_wait(map, 0);
  461         }
  462         vm_map_insert(map, NULL, 0, addr, addr + size, VM_PROT_ALL,
  463             VM_PROT_ALL, MAP_ACC_CHARGED);
  464         vm_map_unlock(map);
  465         return (addr);
  466 }
  467 
  468 /*
  469  *      kmap_free_wakeup:
  470  *
  471  *      Returns memory to a submap of the kernel, and wakes up any processes
  472  *      waiting for memory in that map.
  473  */
  474 void
  475 kmap_free_wakeup(map, addr, size)
  476         vm_map_t map;
  477         vm_offset_t addr;
  478         vm_size_t size;
  479 {
  480 
  481         vm_map_lock(map);
  482         (void) vm_map_delete(map, trunc_page(addr), round_page(addr + size));
  483         if (map->needs_wakeup) {
  484                 map->needs_wakeup = FALSE;
  485                 vm_map_wakeup(map);
  486         }
  487         vm_map_unlock(map);
  488 }
  489 
  490 void
  491 kmem_init_zero_region(void)
  492 {
  493         vm_offset_t addr, i;
  494         vm_page_t m;
  495 
  496         /*
  497          * Map a single physical page of zeros to a larger virtual range.
  498          * This requires less looping in places that want large amounts of
  499          * zeros, while not using much more physical resources.
  500          */
  501         addr = kva_alloc(ZERO_REGION_SIZE);
  502         m = vm_page_alloc(NULL, 0, VM_ALLOC_NORMAL |
  503             VM_ALLOC_NOOBJ | VM_ALLOC_WIRED | VM_ALLOC_ZERO);
  504         if ((m->flags & PG_ZERO) == 0)
  505                 pmap_zero_page(m);
  506         for (i = 0; i < ZERO_REGION_SIZE; i += PAGE_SIZE)
  507                 pmap_qenter(addr + i, &m, 1);
  508         pmap_protect(kernel_pmap, addr, addr + ZERO_REGION_SIZE, VM_PROT_READ);
  509 
  510         zero_region = (const void *)addr;
  511 }
  512 
  513 /*
  514  *      kmem_init:
  515  *
  516  *      Create the kernel map; insert a mapping covering kernel text, 
  517  *      data, bss, and all space allocated thus far (`boostrap' data).  The 
  518  *      new map will thus map the range between VM_MIN_KERNEL_ADDRESS and 
  519  *      `start' as allocated, and the range between `start' and `end' as free.
  520  */
  521 void
  522 kmem_init(start, end)
  523         vm_offset_t start, end;
  524 {
  525         vm_map_t m;
  526 
  527         m = vm_map_create(kernel_pmap, VM_MIN_KERNEL_ADDRESS, end);
  528         m->system_map = 1;
  529         vm_map_lock(m);
  530         /* N.B.: cannot use kgdb to debug, starting with this assignment ... */
  531         kernel_map = m;
  532         (void) vm_map_insert(m, NULL, (vm_ooffset_t) 0,
  533 #ifdef __amd64__
  534             KERNBASE,
  535 #else                
  536             VM_MIN_KERNEL_ADDRESS,
  537 #endif
  538             start, VM_PROT_ALL, VM_PROT_ALL, MAP_NOFAULT);
  539         /* ... and ending with the completion of the above `insert' */
  540         vm_map_unlock(m);
  541 }
  542 
  543 #ifdef DIAGNOSTIC
  544 /*
  545  * Allow userspace to directly trigger the VM drain routine for testing
  546  * purposes.
  547  */
  548 static int
  549 debug_vm_lowmem(SYSCTL_HANDLER_ARGS)
  550 {
  551         int error, i;
  552 
  553         i = 0;
  554         error = sysctl_handle_int(oidp, &i, 0, req);
  555         if (error)
  556                 return (error);
  557         if (i)   
  558                 EVENTHANDLER_INVOKE(vm_lowmem, 0);
  559         return (0);
  560 }
  561 
  562 SYSCTL_PROC(_debug, OID_AUTO, vm_lowmem, CTLTYPE_INT | CTLFLAG_RW, 0, 0,
  563     debug_vm_lowmem, "I", "set to trigger vm_lowmem event");
  564 #endif

Cache object: f0e88a876bdc6a41a1098b41563343fa


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