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/kern/host.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  * Mach Operating System
    3  * Copyright (c) 1993,1992,1991,1990,1989,1988 Carnegie Mellon University
    4  * All Rights Reserved.
    5  * 
    6  * Permission to use, copy, modify and distribute this software and its
    7  * documentation is hereby granted, provided that both the copyright
    8  * notice and this permission notice appear in all copies of the
    9  * software, derivative works or modified versions, and any portions
   10  * thereof, and that both notices appear in supporting documentation.
   11  * 
   12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   15  * 
   16  * Carnegie Mellon requests users of this software to return to
   17  * 
   18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   19  *  School of Computer Science
   20  *  Carnegie Mellon University
   21  *  Pittsburgh PA 15213-3890
   22  * 
   23  * any improvements or extensions that they make and grant Carnegie Mellon
   24  * the rights to redistribute these changes.
   25  */
   26 /*
   27  * HISTORY
   28  * $Log:        host.c,v $
   29  * Revision 2.11  93/11/17  17:10:04  dbg
   30  *      Get min_quantum from kern/quantum.h.
   31  *      [93/05/11            dbg]
   32  * 
   33  *      Fixed host_info to correctly return min_timeout and min_quantum
   34  *      in milliseconds.  Added ANSI function prototypes.
   35  *      [93/01/27            dbg]
   36  * 
   37  * Revision 2.10  93/01/14  17:34:15  danner
   38  *      64bit cleanup.
   39  *      [92/12/01            af]
   40  * 
   41  * Revision 2.9  92/08/03  17:37:08  jfriedl
   42  *      removed silly prototypes
   43  *      [92/08/02            jfriedl]
   44  * 
   45  * Revision 2.8  92/05/21  17:13:27  jfriedl
   46  *      Removed unused variable 'size_used' from host_processor_sets.
   47  *      Changes to quiet gcc warnings.
   48  *      [92/05/16            jfriedl]
   49  * 
   50  * Revision 2.7  91/05/14  16:41:16  mrt
   51  *      Correcting copyright
   52  * 
   53  * Revision 2.6  91/02/05  17:26:15  mrt
   54  *      Changed to new Mach copyright
   55  *      [91/02/01  16:12:16  mrt]
   56  * 
   57  * Revision 2.5  90/08/27  22:02:30  dbg
   58  *      Fix bug in host_processor_sets.  Import assert.h.
   59  *      [90/07/18            dbg]
   60  * 
   61  * Revision 2.4  90/08/07  17:58:28  rpd
   62  *      Changed host_processor_sets to use unprivileged ports.
   63  *      [90/08/07            rpd]
   64  * 
   65  * Revision 2.3  90/06/19  22:58:20  rpd
   66  *      Fixed bug in host_kernel_version.
   67  *      [90/06/16            rpd]
   68  * 
   69  *      Fixed bug in host_processors.
   70  *      [90/06/16            rpd]
   71  * 
   72  * Revision 2.2  90/06/02  14:53:48  rpd
   73  *      Added HOST_LOAD_INFO.
   74  *      [90/04/27            rpd]
   75  *      Created for new host/processor technology.
   76  *      [90/03/26  23:50:27  rpd]
   77  * 
   78  *      Move includes.
   79  *      [89/08/02            dlb]
   80  *      Remove interrupt protection from all_psets lock.
   81  *      [89/06/14            dlb]
   82  * 
   83  *      Add host_processor_sets and host_processor_set_priv.
   84  *      [89/06/09            dlb]
   85  * 
   86  *      Add scheduler information flavor to host_info.
   87  *      [89/06/08            dlb]
   88  *      Declare realhost here.
   89  *      [89/02/03            dlb]
   90  *      [89/01/30  16:54:25  dlb]
   91  * 
   92  * Revision 2.3  89/10/15  02:03:53  rpd
   93  *      Minor cleanups.
   94  * 
   95  * Revision 2.2  89/10/11  14:04:44  dlb
   96  *      Optimize host_processor_sets and add simplified !MACH_HOST case.
   97  *      Remove interrupt protection from all_psets lock.
   98  *      Add host_processor_sets and host_processor_set_priv.
   99  *      Add scheduler information flavor to host_info.
  100  * 
  101  *      Reformat includes.  mach_host.h moved to mach/ directory.
  102  *      [89/01/26            dlb]
  103  *      
  104  *      Move kernel version to a separate routine so it can be returned
  105  *      as a string of characters.
  106  *      [88/12/02            dlb]
  107  *      
  108  *      Bug fixes, add new flavors of host information.
  109  *      [88/12/01            dlb]
  110  *      
  111  *      Created.
  112  *      [88/10/31            dlb]
  113  */
  114 
  115 /*
  116  *      host.c
  117  *
  118  *      Non-ipc host functions.
  119  */
  120 
  121 #include <cpus.h>
  122 #include <mach_host.h>
  123 
  124 #include <kern/assert.h>
  125 #include <kern/kalloc.h>
  126 #include <kern/host.h>
  127 #include <mach/host_info.h>
  128 #include <mach/kern_return.h>
  129 #include <mach/machine.h>
  130 #include <mach/port.h>
  131 #include <kern/machine.h>
  132 #include <kern/memory.h>
  133 #include <kern/processor.h>
  134 #include <kern/quantum.h>
  135 #include <kern/strings.h>
  136 #include <kern/ipc_host.h>
  137 
  138 #include <mach/vm_param.h>
  139 
  140 
  141 
  142 host_data_t     realhost;
  143 
  144 kern_return_t host_processors(
  145         host_t                  host,
  146         processor_array_t       *processor_list,
  147         natural_t               *countp)
  148 {
  149         register int            i;
  150         register processor_t    *tp;
  151         vm_offset_t             addr;
  152         unsigned int            count;
  153 
  154         if (host == HOST_NULL)
  155                 return KERN_INVALID_ARGUMENT;
  156 
  157         /*
  158          *      Determine how many processors we have.
  159          *      (This number shouldn't change.)
  160          */
  161 
  162         count = 0;
  163         for (i = 0; i < NCPUS; i++)
  164                 if (machine_slot[i].is_cpu)
  165                         count++;
  166 
  167         if (count == 0)
  168                 panic("host_processors");
  169 
  170         addr = kalloc((vm_size_t) (count * sizeof(mach_port_t)));
  171         if (addr == 0)
  172                 return KERN_RESOURCE_SHORTAGE;
  173 
  174         tp = (processor_t *) addr;
  175         for (i = 0; i < NCPUS; i++)
  176                 if (machine_slot[i].is_cpu)
  177                         *tp++ = cpu_to_processor(i);
  178 
  179         *countp = count;
  180         *processor_list = (mach_port_t *) addr;
  181 
  182         /* do the conversion that Mig should handle */
  183 
  184         tp = (processor_t *) addr;
  185         for (i = 0; i < count; i++)
  186                 ((mach_port_t *) tp)[i] =
  187                       (mach_port_t)convert_processor_to_port(tp[i]);
  188 
  189         return KERN_SUCCESS;
  190 }
  191 
  192 kern_return_t   host_info(
  193         host_t          host,
  194         int             flavor,
  195         host_info_t     info,
  196         natural_t       *count)
  197 {
  198         register integer_t      i, *slot_ptr;
  199 
  200         if (host == HOST_NULL)
  201                 return KERN_INVALID_ARGUMENT;
  202         
  203         switch(flavor) {
  204 
  205         case HOST_BASIC_INFO:
  206             {
  207                 register host_basic_info_t      basic_info;
  208 
  209                 /*
  210                  *      Basic information about this host.
  211                  */
  212                 if (*count < HOST_BASIC_INFO_COUNT)
  213                         return KERN_FAILURE;
  214 
  215                 basic_info = (host_basic_info_t) info;
  216 
  217                 basic_info->max_cpus = machine_info.max_cpus;
  218                 basic_info->avail_cpus = machine_info.avail_cpus;
  219                 basic_info->memory_size = machine_info.memory_size;
  220                 basic_info->cpu_type =
  221                         machine_slot[master_processor->slot_num].cpu_type;
  222                 basic_info->cpu_subtype =
  223                         machine_slot[master_processor->slot_num].cpu_subtype;
  224 
  225                 *count = HOST_BASIC_INFO_COUNT;
  226                 return KERN_SUCCESS;
  227             }
  228 
  229         case HOST_PROCESSOR_SLOTS:
  230                 /*
  231                  *      Return numbers of slots with active processors
  232                  *      in them.
  233                  */
  234                 if (*count < NCPUS)
  235                         return KERN_INVALID_ARGUMENT;
  236 
  237                 slot_ptr = (integer_t *)info;
  238                 *count = 0;
  239                 for (i = 0; i < NCPUS; i++) {
  240                         if (machine_slot[i].is_cpu &&
  241                                 machine_slot[i].running) {
  242                                         *slot_ptr++ = i;
  243                                         (*count)++;
  244                                 }
  245                 }
  246                 return KERN_SUCCESS;
  247 
  248         case HOST_SCHED_INFO:
  249             {
  250                 register host_sched_info_t      sched_info;
  251 
  252                 /*
  253                  *      Return scheduler information.
  254                  */
  255                 if (*count < HOST_SCHED_INFO_COUNT)
  256                         return KERN_FAILURE;
  257 
  258                 sched_info = (host_sched_info_t) info;
  259 
  260                 sched_info->min_timeout = 10;           /* XXX */
  261                 sched_info->min_quantum = min_quantum / 1000;
  262                                 /* convert microseconds to milliseconds */
  263 
  264                 *count = HOST_SCHED_INFO_COUNT;
  265                 return KERN_SUCCESS;
  266             }
  267 
  268         case HOST_LOAD_INFO:
  269             {
  270                 register host_load_info_t load_info;
  271                 extern long avenrun[3], mach_factor[3];
  272 
  273                 if (*count < HOST_LOAD_INFO_COUNT)
  274                         return KERN_FAILURE;
  275 
  276                 load_info = (host_load_info_t) info;
  277 
  278                 bcopy(avenrun,
  279                       load_info->avenrun,
  280                       sizeof avenrun);
  281                 bcopy(mach_factor,
  282                       load_info->mach_factor,
  283                       sizeof mach_factor);
  284 
  285                 *count = HOST_LOAD_INFO_COUNT;
  286                 return KERN_SUCCESS;
  287             }
  288 
  289         default:
  290                 return KERN_INVALID_ARGUMENT;
  291         }
  292 }
  293 
  294 /*
  295  *      Return kernel version string (more than you ever
  296  *      wanted to know about what version of the kernel this is).
  297  */
  298 
  299 kern_return_t host_kernel_version(
  300         host_t                  host,
  301         kernel_version_t        out_version)
  302 {
  303         extern char     version[];
  304 
  305         if (host == HOST_NULL)
  306                 return KERN_INVALID_ARGUMENT;
  307 
  308         (void) strncpy(out_version, version, sizeof(kernel_version_t));
  309 
  310         return KERN_SUCCESS;
  311 }
  312 
  313 /*
  314  *      host_processor_sets:
  315  *
  316  *      List all processor sets on the host.
  317  */
  318 #if     MACH_HOST
  319 kern_return_t
  320 host_processor_sets(
  321         host_t                          host,
  322         processor_set_name_array_t      *pset_list,
  323         natural_t                       *count)
  324 {
  325         unsigned int actual;    /* this many psets */
  326         processor_set_t pset;
  327         processor_set_t *psets;
  328         int i;
  329 
  330         vm_size_t size;
  331         vm_size_t size_needed;
  332         vm_offset_t addr;
  333 
  334         if (host == HOST_NULL)
  335                 return KERN_INVALID_ARGUMENT;
  336 
  337         size = 0; addr = 0;
  338 
  339         for (;;) {
  340                 simple_lock(&all_psets_lock);
  341                 actual = all_psets_count;
  342 
  343                 /* do we have the memory we need? */
  344 
  345                 size_needed = actual * sizeof(mach_port_t);
  346                 if (size_needed <= size)
  347                         break;
  348 
  349                 /* unlock and allocate more memory */
  350                 simple_unlock(&all_psets_lock);
  351 
  352                 if (size != 0)
  353                         kfree(addr, size);
  354 
  355                 assert(size_needed > 0);
  356                 size = size_needed;
  357 
  358                 addr = kalloc(size);
  359                 if (addr == 0)
  360                         return KERN_RESOURCE_SHORTAGE;
  361         }
  362 
  363         /* OK, have memory and the all_psets_lock */
  364 
  365         psets = (processor_set_t *) addr;
  366 
  367         for (i = 0, pset = (processor_set_t) queue_first(&all_psets);
  368              i < actual;
  369              i++, pset = (processor_set_t) queue_next(&pset->all_psets)) {
  370                 /* take ref for convert_pset_name_to_port */
  371                 pset_reference(pset);
  372                 psets[i] = pset;
  373         }
  374         assert(queue_end(&all_psets, (queue_entry_t) pset));
  375 
  376         /* can unlock now that we've got the pset refs */
  377         simple_unlock(&all_psets_lock);
  378 
  379         /*
  380          *      Always have default port.
  381          */
  382 
  383         assert(actual > 0);
  384 
  385         /* if we allocated too much, must copy */
  386 
  387         if (size_needed < size) {
  388                 vm_offset_t newaddr;
  389 
  390                 newaddr = kalloc(size_needed);
  391                 if (newaddr == 0) {
  392                         for (i = 0; i < actual; i++)
  393                                 pset_deallocate(psets[i]);
  394                         kfree(addr, size);
  395                         return KERN_RESOURCE_SHORTAGE;
  396                 }
  397 
  398                 bcopy((void *) addr, (void *) newaddr, size_needed);
  399                 kfree(addr, size);
  400                 psets = (processor_set_t *) newaddr;
  401         }
  402 
  403         *pset_list = (mach_port_t *) psets;
  404         *count = actual;
  405 
  406         /* do the conversion that Mig should handle */
  407 
  408         for (i = 0; i < actual; i++)
  409                 ((mach_port_t *) psets)[i] =
  410                         (mach_port_t)convert_pset_name_to_port(psets[i]);
  411 
  412         return KERN_SUCCESS;
  413 }
  414 #else   /* MACH_HOST */
  415 /*
  416  *      Only one processor set, the default processor set, in this case.
  417  */
  418 kern_return_t
  419 host_processor_sets(
  420         host_t                          host,
  421         processor_set_name_array_t      *pset_list,
  422         natural_t                       *count)
  423 {
  424         vm_offset_t addr;
  425 
  426         if (host == HOST_NULL)
  427                 return KERN_INVALID_ARGUMENT;
  428 
  429         /*
  430          *      Allocate memory.  Can be pageable because it won't be
  431          *      touched while holding a lock.
  432          */
  433 
  434         addr = kalloc((vm_size_t) sizeof(mach_port_t));
  435         if (addr == 0)
  436                 return KERN_RESOURCE_SHORTAGE;
  437 
  438         /* take for for convert_pset_name_to_port */
  439         pset_reference(&default_pset);
  440         /* do the conversion that Mig should handle */
  441         *((mach_port_t *) addr) = 
  442                         (mach_port_t) convert_pset_name_to_port(&default_pset);
  443 
  444         *pset_list = (mach_port_t *) addr;
  445         *count = 1;
  446 
  447         return KERN_SUCCESS;
  448 }
  449 #endif  /* MACH_HOST */
  450 
  451 /*
  452  *      host_processor_set_priv:
  453  *
  454  *      Return control port for given processor set.
  455  */
  456 kern_return_t
  457 host_processor_set_priv(
  458         host_t          host,
  459         processor_set_t pset_name,
  460         processor_set_t *pset)
  461 {
  462     if ((host == HOST_NULL) || (pset_name == PROCESSOR_SET_NULL)) {
  463         *pset = PROCESSOR_SET_NULL;
  464         return KERN_INVALID_ARGUMENT;
  465     }
  466 
  467     *pset = pset_name;
  468     pset_reference(*pset);
  469     return KERN_SUCCESS;
  470 }

Cache object: cdf4bff12a64cdc3af0e29002cce4df3


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