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

Cache object: f23d5a04c71e09969e6d1738cd45e298


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