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/net/vnet.h

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  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2006-2009 University of Zagreb
    5  * Copyright (c) 2006-2009 FreeBSD Foundation
    6  * All rights reserved.
    7  *
    8  * This software was developed by the University of Zagreb and the
    9  * FreeBSD Foundation under sponsorship by the Stichting NLnet and the
   10  * FreeBSD Foundation.
   11  *
   12  * Copyright (c) 2009 Jeffrey Roberson <jeff@freebsd.org>
   13  * Copyright (c) 2009 Robert N. M. Watson
   14  * All rights reserved.
   15  *
   16  * Redistribution and use in source and binary forms, with or without
   17  * modification, are permitted provided that the following conditions
   18  * are met:
   19  * 1. Redistributions of source code must retain the above copyright
   20  *    notice, this list of conditions and the following disclaimer.
   21  * 2. Redistributions in binary form must reproduce the above copyright
   22  *    notice, this list of conditions and the following disclaimer in the
   23  *    documentation and/or other materials provided with the distribution.
   24  *
   25  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   35  * SUCH DAMAGE.
   36  *
   37  * $FreeBSD$
   38  */
   39 
   40 /*-
   41  * This header file defines several sets of interfaces supporting virtualized
   42  * network stacks:
   43  *
   44  * - Definition of 'struct vnet' and functions and macros to allocate/free/
   45  *   manipulate it.
   46  *
   47  * - A virtual network stack memory allocator, which provides support for
   48  *   virtualized global variables via a special linker set, set_vnet.
   49  *
   50  * - Virtualized sysinits/sysuninits, which allow constructors and
   51  *   destructors to be run for each network stack subsystem as virtual
   52  *   instances are created and destroyed.
   53  *
   54  * If VIMAGE isn't compiled into the kernel, virtualized global variables
   55  * compile to normal global variables, and virtualized sysinits to regular
   56  * sysinits.
   57  */
   58 
   59 #ifndef _NET_VNET_H_
   60 #define _NET_VNET_H_
   61 
   62 /*
   63  * struct vnet describes a virtualized network stack, and is primarily a
   64  * pointer to storage for virtualized global variables.  Expose to userspace
   65  * as required for libkvm.
   66  */
   67 #if defined(_KERNEL) || defined(_WANT_VNET)
   68 #include <machine/param.h>      /* for CACHE_LINE_SIZE */
   69 #include <sys/queue.h>
   70 
   71 struct vnet {
   72         LIST_ENTRY(vnet)         vnet_le;       /* all vnets list */
   73         u_int                    vnet_magic_n;
   74         u_int                    vnet_ifcnt;
   75         u_int                    vnet_sockcnt;
   76         u_int                    vnet_state;    /* SI_SUB_* */
   77         void                    *vnet_data_mem;
   78         uintptr_t                vnet_data_base;
   79         bool                     vnet_shutdown; /* Shutdown in progress. */
   80 } __aligned(CACHE_LINE_SIZE);
   81 #define VNET_MAGIC_N    0x5e4a6f28
   82 
   83 /*
   84  * These two virtual network stack allocator definitions are also required
   85  * for libkvm so that it can evaluate virtualized global variables.
   86  */
   87 #define VNET_SETNAME            "set_vnet"
   88 #define VNET_SYMPREFIX          "vnet_entry_"
   89 #endif
   90 
   91 #ifdef _KERNEL
   92 
   93 #define VNET_PCPUSTAT_DECLARE(type, name)       \
   94     VNET_DECLARE(counter_u64_t, name[sizeof(type) / sizeof(uint64_t)])
   95 
   96 #define VNET_PCPUSTAT_DEFINE(type, name)        \
   97     VNET_DEFINE(counter_u64_t, name[sizeof(type) / sizeof(uint64_t)])
   98 #define VNET_PCPUSTAT_DEFINE_STATIC(type, name) \
   99     VNET_DEFINE_STATIC(counter_u64_t, name[sizeof(type) / sizeof(uint64_t)])
  100 
  101 #define VNET_PCPUSTAT_ALLOC(name, wait) \
  102     COUNTER_ARRAY_ALLOC(VNET(name), \
  103         sizeof(VNET(name)) / sizeof(counter_u64_t), (wait))
  104 
  105 #define VNET_PCPUSTAT_FREE(name)        \
  106     COUNTER_ARRAY_FREE(VNET(name), sizeof(VNET(name)) / sizeof(counter_u64_t))
  107 
  108 #define VNET_PCPUSTAT_ADD(type, name, f, v)     \
  109     counter_u64_add(VNET(name)[offsetof(type, f) / sizeof(uint64_t)], (v))
  110 
  111 #define VNET_PCPUSTAT_FETCH(type, name, f)      \
  112     counter_u64_fetch(VNET(name)[offsetof(type, f) / sizeof(uint64_t)])
  113 
  114 #define VNET_PCPUSTAT_SYSINIT(name)     \
  115 static void                             \
  116 vnet_##name##_init(const void *unused)  \
  117 {                                       \
  118         VNET_PCPUSTAT_ALLOC(name, M_WAITOK);    \
  119 }                                       \
  120 VNET_SYSINIT(vnet_ ## name ## _init, SI_SUB_INIT_IF,                    \
  121     SI_ORDER_FIRST, vnet_ ## name ## _init, NULL)
  122 
  123 #define VNET_PCPUSTAT_SYSUNINIT(name)                                   \
  124 static void                                                             \
  125 vnet_##name##_uninit(const void *unused)                                \
  126 {                                                                       \
  127         VNET_PCPUSTAT_FREE(name);                                       \
  128 }                                                                       \
  129 VNET_SYSUNINIT(vnet_ ## name ## _uninit, SI_SUB_INIT_IF,                \
  130     SI_ORDER_FIRST, vnet_ ## name ## _uninit, NULL)
  131 
  132 #ifdef SYSCTL_OID
  133 #define SYSCTL_VNET_PCPUSTAT(parent, nbr, name, type, array, desc)      \
  134 static int                                                              \
  135 array##_sysctl(SYSCTL_HANDLER_ARGS)                                     \
  136 {                                                                       \
  137         type s;                                                         \
  138         CTASSERT((sizeof(type) / sizeof(uint64_t)) ==                   \
  139             (sizeof(VNET(array)) / sizeof(counter_u64_t)));             \
  140         COUNTER_ARRAY_COPY(VNET(array), &s, sizeof(type) / sizeof(uint64_t));\
  141         if (req->newptr)                                                \
  142                 COUNTER_ARRAY_ZERO(VNET(array),                         \
  143                     sizeof(type) / sizeof(uint64_t));                   \
  144         return (SYSCTL_OUT(req, &s, sizeof(type)));                     \
  145 }                                                                       \
  146 SYSCTL_PROC(parent, nbr, name,                                          \
  147     CTLFLAG_VNET | CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_NEEDGIANT,     \
  148     NULL, 0, array ## _sysctl, "I", desc)
  149 #endif /* SYSCTL_OID */
  150 
  151 #ifdef VIMAGE
  152 #include <sys/lock.h>
  153 #include <sys/proc.h>                   /* for struct thread */
  154 #include <sys/rwlock.h>
  155 #include <sys/sx.h>
  156 
  157 /*
  158  * Location of the kernel's 'set_vnet' linker set.
  159  */
  160 extern uintptr_t        *__start_set_vnet;
  161 __GLOBL(__start_set_vnet);
  162 extern uintptr_t        *__stop_set_vnet;
  163 __GLOBL(__stop_set_vnet);
  164 
  165 #define VNET_START      (uintptr_t)&__start_set_vnet
  166 #define VNET_STOP       (uintptr_t)&__stop_set_vnet
  167 
  168 /*
  169  * Functions to allocate and destroy virtual network stacks.
  170  */
  171 struct vnet *vnet_alloc(void);
  172 void    vnet_destroy(struct vnet *vnet);
  173 
  174 /*
  175  * The current virtual network stack -- we may wish to move this to struct
  176  * pcpu in the future.
  177  */
  178 #define curvnet curthread->td_vnet
  179 
  180 /*
  181  * Various macros -- get and set the current network stack, but also
  182  * assertions.
  183  */
  184 #if defined(INVARIANTS) || defined(VNET_DEBUG)
  185 #define VNET_ASSERT(exp, msg)   do {                                    \
  186         if (!(exp))                                                     \
  187                 panic msg;                                              \
  188 } while (0)
  189 #else
  190 #define VNET_ASSERT(exp, msg)   do {                                    \
  191 } while (0)
  192 #endif
  193 
  194 #ifdef VNET_DEBUG
  195 void vnet_log_recursion(struct vnet *, const char *, int);
  196 
  197 #define CURVNET_SET_QUIET(arg)                                          \
  198         VNET_ASSERT((arg) != NULL && (arg)->vnet_magic_n == VNET_MAGIC_N, \
  199             ("CURVNET_SET at %s:%d %s() curvnet=%p vnet=%p",            \
  200             __FILE__, __LINE__, __func__, curvnet, (arg)));             \
  201         struct vnet *saved_vnet = curvnet;                              \
  202         const char *saved_vnet_lpush = curthread->td_vnet_lpush;        \
  203         curvnet = arg;                                                  \
  204         curthread->td_vnet_lpush = __func__;
  205 
  206 #define CURVNET_SET_VERBOSE(arg)                                        \
  207         CURVNET_SET_QUIET(arg)                                          \
  208         if (saved_vnet)                                                 \
  209                 vnet_log_recursion(saved_vnet, saved_vnet_lpush, __LINE__);
  210 
  211 #define CURVNET_SET(arg)        CURVNET_SET_VERBOSE(arg)
  212 
  213 #define CURVNET_RESTORE()                                               \
  214         VNET_ASSERT(curvnet != NULL && (saved_vnet == NULL ||           \
  215             saved_vnet->vnet_magic_n == VNET_MAGIC_N),                  \
  216             ("CURVNET_RESTORE at %s:%d %s() curvnet=%p saved_vnet=%p",  \
  217             __FILE__, __LINE__, __func__, curvnet, saved_vnet));        \
  218         curvnet = saved_vnet;                                           \
  219         curthread->td_vnet_lpush = saved_vnet_lpush;
  220 #else /* !VNET_DEBUG */
  221 
  222 #define CURVNET_SET_QUIET(arg)                                          \
  223         VNET_ASSERT((arg) != NULL && (arg)->vnet_magic_n == VNET_MAGIC_N, \
  224             ("CURVNET_SET at %s:%d %s() curvnet=%p vnet=%p",            \
  225             __FILE__, __LINE__, __func__, curvnet, (arg)));             \
  226         struct vnet *saved_vnet = curvnet;                              \
  227         curvnet = arg;  
  228 
  229 #define CURVNET_SET_VERBOSE(arg)                                        \
  230         CURVNET_SET_QUIET(arg)
  231 
  232 #define CURVNET_SET(arg)        CURVNET_SET_VERBOSE(arg)
  233 
  234 #define CURVNET_RESTORE()                                               \
  235         VNET_ASSERT(curvnet != NULL && (saved_vnet == NULL ||           \
  236             saved_vnet->vnet_magic_n == VNET_MAGIC_N),                  \
  237             ("CURVNET_RESTORE at %s:%d %s() curvnet=%p saved_vnet=%p",  \
  238             __FILE__, __LINE__, __func__, curvnet, saved_vnet));        \
  239         curvnet = saved_vnet;
  240 #endif /* VNET_DEBUG */
  241 
  242 #define CURVNET_ASSERT_SET()                                            \
  243         VNET_ASSERT(curvnet != NULL, ("vnet is not set at %s:%d %s()",  \
  244             __FILE__, __LINE__, __func__))
  245 
  246 extern struct vnet *vnet0;
  247 #define IS_DEFAULT_VNET(arg)    ((arg) == vnet0)
  248 
  249 #define CRED_TO_VNET(cr)        (cr)->cr_prison->pr_vnet
  250 #define TD_TO_VNET(td)          CRED_TO_VNET((td)->td_ucred)
  251 #define P_TO_VNET(p)            CRED_TO_VNET((p)->p_ucred)
  252 
  253 /*
  254  * Global linked list of all virtual network stacks, along with read locks to
  255  * access it.  If a caller may sleep while accessing the list, it must use
  256  * the sleepable lock macros.
  257  */
  258 LIST_HEAD(vnet_list_head, vnet);
  259 extern struct vnet_list_head vnet_head;
  260 extern struct rwlock vnet_rwlock;
  261 extern struct sx vnet_sxlock;
  262 
  263 #define VNET_LIST_RLOCK()               sx_slock(&vnet_sxlock)
  264 #define VNET_LIST_RLOCK_NOSLEEP()       rw_rlock(&vnet_rwlock)
  265 #define VNET_LIST_RUNLOCK()             sx_sunlock(&vnet_sxlock)
  266 #define VNET_LIST_RUNLOCK_NOSLEEP()     rw_runlock(&vnet_rwlock)
  267 
  268 /*
  269  * Iteration macros to walk the global list of virtual network stacks.
  270  */
  271 #define VNET_ITERATOR_DECL(arg) struct vnet *arg
  272 #define VNET_FOREACH(arg)       LIST_FOREACH((arg), &vnet_head, vnet_le)
  273 
  274 /*
  275  * Virtual network stack memory allocator, which allows global variables to
  276  * be automatically instantiated for each network stack instance.
  277  */
  278 #define VNET_NAME(n)            vnet_entry_##n
  279 #define VNET_DECLARE(t, n)      extern t VNET_NAME(n)
  280 /* struct _hack is to stop this from being used with static data */
  281 #define VNET_DEFINE(t, n)       \
  282     struct _hack; t VNET_NAME(n) __section(VNET_SETNAME) __used
  283 #if defined(KLD_MODULE) && (defined(__aarch64__) || defined(__riscv) \
  284                 || defined(__powerpc64__))
  285 /*
  286  * As with DPCPU_DEFINE_STATIC we are unable to mark this data as static
  287  * in modules on some architectures.
  288  */
  289 #define VNET_DEFINE_STATIC(t, n) \
  290     t VNET_NAME(n) __section(VNET_SETNAME) __used
  291 #else
  292 #define VNET_DEFINE_STATIC(t, n) \
  293     static t VNET_NAME(n) __section(VNET_SETNAME) __used
  294 #endif
  295 #define _VNET_PTR(b, n)         (__typeof(VNET_NAME(n))*)               \
  296                                     ((b) + (uintptr_t)&VNET_NAME(n))
  297 
  298 #define _VNET(b, n)             (*_VNET_PTR(b, n))
  299 
  300 /*
  301  * Virtualized global variable accessor macros.
  302  */
  303 #define VNET_VNET_PTR(vnet, n)          _VNET_PTR((vnet)->vnet_data_base, n)
  304 #define VNET_VNET(vnet, n)              (*VNET_VNET_PTR((vnet), n))
  305 
  306 #define VNET_PTR(n)             VNET_VNET_PTR(curvnet, n)
  307 #define VNET(n)                 VNET_VNET(curvnet, n)
  308 
  309 /*
  310  * Virtual network stack allocator interfaces from the kernel linker.
  311  */
  312 void    *vnet_data_alloc(int size);
  313 void     vnet_data_copy(void *start, int size);
  314 void     vnet_data_free(void *start_arg, int size);
  315 
  316 /*
  317  * Virtual sysinit mechanism, allowing network stack components to declare
  318  * startup and shutdown methods to be run when virtual network stack
  319  * instances are created and destroyed.
  320  */
  321 #include <sys/kernel.h>
  322 
  323 /*
  324  * SYSINIT/SYSUNINIT variants that provide per-vnet constructors and
  325  * destructors.
  326  */
  327 struct vnet_sysinit {
  328         enum sysinit_sub_id     subsystem;
  329         enum sysinit_elem_order order;
  330         sysinit_cfunc_t         func;
  331         const void              *arg;
  332         TAILQ_ENTRY(vnet_sysinit) link;
  333 };
  334 
  335 #define VNET_SYSINIT(ident, subsystem, order, func, arg)                \
  336         CTASSERT((subsystem) > SI_SUB_VNET &&                           \
  337             (subsystem) <= SI_SUB_VNET_DONE);                           \
  338         static struct vnet_sysinit ident ## _vnet_init = {              \
  339                 subsystem,                                              \
  340                 order,                                                  \
  341                 (sysinit_cfunc_t)(sysinit_nfunc_t)func,                 \
  342                 (arg)                                                   \
  343         };                                                              \
  344         SYSINIT(vnet_init_ ## ident, subsystem, order,                  \
  345             vnet_register_sysinit, &ident ## _vnet_init);               \
  346         SYSUNINIT(vnet_init_ ## ident, subsystem, order,                \
  347             vnet_deregister_sysinit, &ident ## _vnet_init)
  348 
  349 #define VNET_SYSUNINIT(ident, subsystem, order, func, arg)              \
  350         CTASSERT((subsystem) > SI_SUB_VNET &&                           \
  351             (subsystem) <= SI_SUB_VNET_DONE);                           \
  352         static struct vnet_sysinit ident ## _vnet_uninit = {            \
  353                 subsystem,                                              \
  354                 order,                                                  \
  355                 (sysinit_cfunc_t)(sysinit_nfunc_t)func,                 \
  356                 (arg)                                                   \
  357         };                                                              \
  358         SYSINIT(vnet_uninit_ ## ident, subsystem, order,                \
  359             vnet_register_sysuninit, &ident ## _vnet_uninit);           \
  360         SYSUNINIT(vnet_uninit_ ## ident, subsystem, order,              \
  361             vnet_deregister_sysuninit, &ident ## _vnet_uninit)
  362 
  363 /*
  364  * Run per-vnet sysinits or sysuninits during vnet creation/destruction.
  365  */
  366 void     vnet_sysinit(void);
  367 void     vnet_sysuninit(void);
  368 
  369 /*
  370  * Interfaces for managing per-vnet constructors and destructors.
  371  */
  372 void    vnet_register_sysinit(void *arg);
  373 void    vnet_register_sysuninit(void *arg);
  374 void    vnet_deregister_sysinit(void *arg);
  375 void    vnet_deregister_sysuninit(void *arg);
  376 
  377 /*
  378  * EVENTHANDLER(9) extensions.
  379  */
  380 #include <sys/eventhandler.h>
  381 
  382 void    vnet_global_eventhandler_iterator_func(void *, ...);
  383 #define VNET_GLOBAL_EVENTHANDLER_REGISTER_TAG(tag, name, func, arg, priority) \
  384 do {                                                                    \
  385         if (IS_DEFAULT_VNET(curvnet)) {                                 \
  386                 (tag) = vimage_eventhandler_register(NULL, #name, func, \
  387                     arg, priority,                                      \
  388                     vnet_global_eventhandler_iterator_func);            \
  389         }                                                               \
  390 } while(0)
  391 #define VNET_GLOBAL_EVENTHANDLER_REGISTER(name, func, arg, priority)    \
  392 do {                                                                    \
  393         if (IS_DEFAULT_VNET(curvnet)) {                                 \
  394                 vimage_eventhandler_register(NULL, #name, func,         \
  395                     arg, priority,                                      \
  396                     vnet_global_eventhandler_iterator_func);            \
  397         }                                                               \
  398 } while(0)
  399 
  400 #else /* !VIMAGE */
  401 
  402 /*
  403  * Various virtual network stack macros compile to no-ops without VIMAGE.
  404  */
  405 #define curvnet                 NULL
  406 
  407 #define VNET_ASSERT(exp, msg)
  408 #define CURVNET_SET(arg)
  409 #define CURVNET_SET_QUIET(arg)
  410 #define CURVNET_RESTORE()
  411 #define CURVNET_ASSERT_SET()                                            \
  412 
  413 #define VNET_LIST_RLOCK()
  414 #define VNET_LIST_RLOCK_NOSLEEP()
  415 #define VNET_LIST_RUNLOCK()
  416 #define VNET_LIST_RUNLOCK_NOSLEEP()
  417 #define VNET_ITERATOR_DECL(arg)
  418 #define VNET_FOREACH(arg)       for (int _vn = 0; _vn == 0; _vn++)
  419 
  420 #define IS_DEFAULT_VNET(arg)    1
  421 #define CRED_TO_VNET(cr)        NULL
  422 #define TD_TO_VNET(td)          NULL
  423 #define P_TO_VNET(p)            NULL
  424 
  425 /*
  426  * Versions of the VNET macros that compile to normal global variables and
  427  * standard sysctl definitions.
  428  */
  429 #define VNET_NAME(n)            n
  430 #define VNET_DECLARE(t, n)      extern t n
  431 #define VNET_DEFINE(t, n)       struct _hack; t n
  432 #define VNET_DEFINE_STATIC(t, n)        static t n
  433 #define _VNET_PTR(b, n)         &VNET_NAME(n)
  434 
  435 /*
  436  * Virtualized global variable accessor macros.
  437  */
  438 #define VNET_VNET_PTR(vnet, n)          (&(n))
  439 #define VNET_VNET(vnet, n)              (n)
  440 
  441 #define VNET_PTR(n)             (&(n))
  442 #define VNET(n)                 (n)
  443 
  444 /*
  445  * When VIMAGE isn't compiled into the kernel, VNET_SYSINIT/VNET_SYSUNINIT
  446  * map into normal sysinits, which have the same ordering properties.
  447  */
  448 #define VNET_SYSINIT(ident, subsystem, order, func, arg)                \
  449         SYSINIT(ident, subsystem, order, func, arg)
  450 #define VNET_SYSUNINIT(ident, subsystem, order, func, arg)              \
  451         SYSUNINIT(ident, subsystem, order, func, arg)
  452 
  453 /*
  454  * Without VIMAGE revert to the default implementation.
  455  */
  456 #define VNET_GLOBAL_EVENTHANDLER_REGISTER_TAG(tag, name, func, arg, priority) \
  457         (tag) = eventhandler_register(NULL, #name, func, arg, priority)
  458 #define VNET_GLOBAL_EVENTHANDLER_REGISTER(name, func, arg, priority)    \
  459         eventhandler_register(NULL, #name, func, arg, priority)
  460 #endif /* VIMAGE */
  461 #endif /* _KERNEL */
  462 
  463 #endif /* !_NET_VNET_H_ */

Cache object: c42a7b4da32fb7f6ae27d3e3011138c5


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