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/sys/pcpu.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  * Copyright (c) 2001 Wind River Systems, Inc.
    3  * All rights reserved.
    4  * Written by: John Baldwin <jhb@FreeBSD.org>
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 4. Neither the name of the author nor the names of any co-contributors
   15  *    may be used to endorse or promote products derived from this software
   16  *    without specific prior written permission.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   28  * SUCH DAMAGE.
   29  *
   30  * $FreeBSD: releng/9.0/sys/sys/pcpu.h 224221 2011-07-19 16:50:55Z attilio $
   31  */
   32 
   33 #ifndef _SYS_PCPU_H_
   34 #define _SYS_PCPU_H_
   35 
   36 #ifdef LOCORE
   37 #error "no assembler-serviceable parts inside"
   38 #endif
   39 
   40 #include <sys/_cpuset.h>
   41 #include <sys/queue.h>
   42 #include <sys/vmmeter.h>
   43 #include <sys/resource.h>
   44 #include <machine/pcpu.h>
   45 
   46 #define DPCPU_SETNAME           "set_pcpu"
   47 #define DPCPU_SYMPREFIX         "pcpu_entry_"
   48 
   49 #ifdef _KERNEL
   50 
   51 /*
   52  * Define a set for pcpu data.
   53  */
   54 extern uintptr_t *__start_set_pcpu;
   55 __GLOBL(__start_set_pcpu);
   56 extern uintptr_t *__stop_set_pcpu;
   57 __GLOBL(__stop_set_pcpu);
   58 
   59 /*
   60  * Array of dynamic pcpu base offsets.  Indexed by id.
   61  */
   62 extern uintptr_t dpcpu_off[];
   63 
   64 /*
   65  * Convenience defines.
   66  */
   67 #define DPCPU_START             ((uintptr_t)&__start_set_pcpu)
   68 #define DPCPU_STOP              ((uintptr_t)&__stop_set_pcpu)
   69 #define DPCPU_BYTES             (DPCPU_STOP - DPCPU_START)
   70 #define DPCPU_MODMIN            2048
   71 #define DPCPU_SIZE              roundup2(DPCPU_BYTES, PAGE_SIZE)
   72 #define DPCPU_MODSIZE           (DPCPU_SIZE - (DPCPU_BYTES - DPCPU_MODMIN))
   73 
   74 /*
   75  * Declaration and definition.
   76  */
   77 #define DPCPU_NAME(n)           pcpu_entry_##n
   78 #define DPCPU_DECLARE(t, n)     extern t DPCPU_NAME(n)
   79 #define DPCPU_DEFINE(t, n)      t DPCPU_NAME(n) __section(DPCPU_SETNAME) __used
   80 
   81 /*
   82  * Accessors with a given base.
   83  */
   84 #define _DPCPU_PTR(b, n)                                                \
   85     (__typeof(DPCPU_NAME(n))*)((b) + (uintptr_t)&DPCPU_NAME(n))
   86 #define _DPCPU_GET(b, n)        (*_DPCPU_PTR(b, n))
   87 #define _DPCPU_SET(b, n, v)     (*_DPCPU_PTR(b, n) = v)
   88 
   89 /*
   90  * Accessors for the current cpu.
   91  */
   92 #define DPCPU_PTR(n)            _DPCPU_PTR(PCPU_GET(dynamic), n)
   93 #define DPCPU_GET(n)            (*DPCPU_PTR(n))
   94 #define DPCPU_SET(n, v)         (*DPCPU_PTR(n) = v)
   95 
   96 /*
   97  * Accessors for remote cpus.
   98  */
   99 #define DPCPU_ID_PTR(i, n)      _DPCPU_PTR(dpcpu_off[(i)], n)
  100 #define DPCPU_ID_GET(i, n)      (*DPCPU_ID_PTR(i, n))
  101 #define DPCPU_ID_SET(i, n, v)   (*DPCPU_ID_PTR(i, n) = v)
  102 
  103 /*
  104  * Utility macros.
  105  */
  106 #define DPCPU_SUM(n) __extension__                                      \
  107 ({                                                                      \
  108         u_int _i;                                                       \
  109         __typeof(*DPCPU_PTR(n)) sum;                                    \
  110                                                                         \
  111         sum = 0;                                                        \
  112         CPU_FOREACH(_i) {                                               \
  113                 sum += *DPCPU_ID_PTR(_i, n);                            \
  114         }                                                               \
  115         sum;                                                            \
  116 })
  117 
  118 #define DPCPU_VARSUM(n, var) __extension__                              \
  119 ({                                                                      \
  120         u_int _i;                                                       \
  121         __typeof((DPCPU_PTR(n))->var) sum;                              \
  122                                                                         \
  123         sum = 0;                                                        \
  124         CPU_FOREACH(_i) {                                               \
  125                 sum += (DPCPU_ID_PTR(_i, n))->var;                      \
  126         }                                                               \
  127         sum;                                                            \
  128 })
  129 
  130 #define DPCPU_ZERO(n) do {                                              \
  131         u_int _i;                                                       \
  132                                                                         \
  133         CPU_FOREACH(_i) {                                               \
  134                 bzero(DPCPU_ID_PTR(_i, n), sizeof(*DPCPU_PTR(n)));      \
  135         }                                                               \
  136 } while(0)
  137 
  138 #endif /* _KERNEL */
  139 
  140 /* 
  141  * XXXUPS remove as soon as we have per cpu variable
  142  * linker sets and can define rm_queue in _rm_lock.h
  143  */
  144 struct rm_queue {
  145         struct rm_queue* volatile rmq_next;
  146         struct rm_queue* volatile rmq_prev;
  147 };
  148 
  149 /*
  150  * This structure maps out the global data that needs to be kept on a
  151  * per-cpu basis.  The members are accessed via the PCPU_GET/SET/PTR
  152  * macros defined in <machine/pcpu.h>.  Machine dependent fields are
  153  * defined in the PCPU_MD_FIELDS macro defined in <machine/pcpu.h>.
  154  */
  155 struct pcpu {
  156         struct thread   *pc_curthread;          /* Current thread */
  157         struct thread   *pc_idlethread;         /* Idle thread */
  158         struct thread   *pc_fpcurthread;        /* Fp state owner */
  159         struct thread   *pc_deadthread;         /* Zombie thread or NULL */
  160         struct pcb      *pc_curpcb;             /* Current pcb */
  161         uint64_t        pc_switchtime;          /* cpu_ticks() at last csw */
  162         int             pc_switchticks;         /* `ticks' at last csw */
  163         u_int           pc_cpuid;               /* This cpu number */
  164         STAILQ_ENTRY(pcpu) pc_allcpu;
  165         struct lock_list_entry *pc_spinlocks;
  166         struct vmmeter  pc_cnt;                 /* VM stats counters */
  167         long            pc_cp_time[CPUSTATES];  /* statclock ticks */
  168         struct device   *pc_device;
  169         void            *pc_netisr;             /* netisr SWI cookie */
  170         int             pc_dnweight;            /* vm_page_dontneed() */
  171         int             pc_domain;              /* Memory domain. */
  172 
  173         /*
  174          * Stuff for read mostly lock
  175          *
  176          * XXXUPS remove as soon as we have per cpu variable
  177          * linker sets.
  178          */
  179         struct rm_queue pc_rm_queue;
  180 
  181         uintptr_t       pc_dynamic;             /* Dynamic per-cpu data area */
  182 
  183         /*
  184          * Keep MD fields last, so that CPU-specific variations on a
  185          * single architecture don't result in offset variations of
  186          * the machine-independent fields of the pcpu.  Even though
  187          * the pcpu structure is private to the kernel, some ports
  188          * (e.g., lsof, part of gtop) define _KERNEL and include this
  189          * header.  While strictly speaking this is wrong, there's no
  190          * reason not to keep the offsets of the MI fields constant
  191          * if only to make kernel debugging easier.
  192          */
  193         PCPU_MD_FIELDS;
  194 } __aligned(CACHE_LINE_SIZE);
  195 
  196 #ifdef _KERNEL
  197 
  198 STAILQ_HEAD(cpuhead, pcpu);
  199 
  200 extern struct cpuhead cpuhead;
  201 extern struct pcpu *cpuid_to_pcpu[];
  202 
  203 #define curcpu          PCPU_GET(cpuid)
  204 #define curproc         (curthread->td_proc)
  205 #ifndef curthread
  206 #define curthread       PCPU_GET(curthread)
  207 #endif
  208 #define curvidata       PCPU_GET(vidata)
  209 
  210 /*
  211  * Machine dependent callouts.  cpu_pcpu_init() is responsible for
  212  * initializing machine dependent fields of struct pcpu, and
  213  * db_show_mdpcpu() is responsible for handling machine dependent
  214  * fields for the DDB 'show pcpu' command.
  215  */
  216 void    cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size);
  217 void    db_show_mdpcpu(struct pcpu *pcpu);
  218 
  219 void    *dpcpu_alloc(int size);
  220 void    dpcpu_copy(void *s, int size);
  221 void    dpcpu_free(void *s, int size);
  222 void    dpcpu_init(void *dpcpu, int cpuid);
  223 void    pcpu_destroy(struct pcpu *pcpu);
  224 struct  pcpu *pcpu_find(u_int cpuid);
  225 void    pcpu_init(struct pcpu *pcpu, int cpuid, size_t size);
  226 
  227 #endif /* _KERNEL */
  228 
  229 #endif /* !_SYS_PCPU_H_ */

Cache object: f7d2f264ff3be7800bf451a19e7e1d1c


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