Print this page
    
12694 race between write() and shutdown() for unix sockets
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/os/space.c
          +++ new/usr/src/uts/common/os/space.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  
    | 
      ↓ open down ↓ | 
    15 lines elided | 
    
      ↑ open up ↑ | 
  
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   * Copyright 2016 Nexenta Systems, Inc.
       26 + * Copyright 2020 Joyent, Inc.
  26   27   */
  27   28  
  28   29  /*
  29   30   * The intent of this file is to contain any data that must remain
  30   31   * resident in the kernel.
  31   32   *
  32   33   * space_store(), space_fetch(), and space_free() have been added to
  33   34   * easily store and retrieve kernel resident data.
  34   35   * These functions are recommended rather than adding new variables to
  35   36   * this file.
  36   37   *
  37   38   * Note that it's possible for name collisions to occur.  In order to
  38   39   * prevent collisions, it's recommended that the convention in
  39   40   * PSARC/1997/389 be used.  If a collision occurs, then space_store will
  40   41   * fail.
  41   42   */
  42   43  
  43   44  #include <sys/types.h>
  44   45  #include <sys/param.h>
  45   46  #include <sys/var.h>
  46   47  #include <sys/proc.h>
  47   48  #include <sys/signal.h>
  48   49  #include <sys/utsname.h>
  49   50  #include <sys/buf.h>
  50   51  #include <sys/cred.h>
  51   52  #include <sys/vfs.h>
  52   53  #include <sys/vnode.h>
  53   54  #include <sys/sysinfo.h>
  54   55  #include <sys/t_lock.h>
  55   56  #include <sys/vmem.h>
  56   57  #include <sys/modhash.h>
  57   58  #include <sys/cmn_err.h>
  58   59  
  59   60  #include <sys/strredir.h>
  60   61  #include <sys/kbio.h>
  61   62  #include <sys/consdev.h>
  62   63  #include <sys/wscons.h>
  63   64  #include <sys/bootprops.h>
  64   65  
  65   66  struct  buf     bfreelist;      /* Head of the free list of buffers */
  66   67  
  67   68  sysinfo_t       sysinfo;
  68   69  vminfo_t        vminfo;         /* VM stats protected by sysinfolock mutex */
  69   70  
  70   71  #ifdef  lint
  71   72  int     __lintzero;             /* Alway zero for shutting up lint */
  72   73  #endif
  73   74  
  74   75  /*
  75   76   * The following describe the physical memory configuration.
  76   77   *
  77   78   *      physmem  -  The amount of physical memory configured
  78   79   *                  in pages.  ptob(physmem) is the amount
  79   80   *                  of physical memory in bytes.  Defined in
  80   81   *                  .../os/startup.c.
  81   82   *
  82   83   *      physmax  -  The highest numbered physical page in memory.
  83   84   *
  84   85   *      maxmem   -  Maximum available memory, in pages.  Defined
  85   86   *                  in main.c.
  86   87   *
  87   88   *      physinstalled
  88   89   *               -  Pages of physical memory installed;
  89   90   *                  includes use by PROM/boot not counted in
  90   91   *                  physmem.
  91   92   */
  92   93  
  93   94  pfn_t   physmax;
  94   95  pgcnt_t physinstalled;
  95   96  
  96   97  struct var v;
  97   98  
  98   99  #include <sys/systm.h>
  99  100  #include <sys/conf.h>
 100  101  #include <sys/kmem.h>
 101  102  #include <sys/sysmacros.h>
 102  103  #include <sys/bootconf.h>
 103  104  
 104  105  /*
 105  106   * Data for segkmem pages that should be resident
 106  107   */
 107  108  struct vnode kvps[KV_MAX];
 108  109  
 109  110  /*
 110  111   * Data from swapgeneric.c that must be resident.
 111  112   */
 112  113  struct vnode *rootvp;           /* vnode of the root device */
 113  114  dev_t rootdev;                  /* dev_t of the root device */
 114  115  boolean_t root_is_ramdisk;      /* root is ramdisk */
 115  116  uint32_t ramdisk_size;          /* (KB) currently set only for sparc netboots */
 116  117  
 117  118  /*
 118  119   * dhcp
 119  120   */
 120  121  #include <sys/socket.h>
 121  122  #include <sys/errno.h>
 122  123  #include <sys/sockio.h>
 123  124  #include <sys/stream.h>
 124  125  #include <sys/stropts.h>
 125  126  #include <sys/dlpi.h>
 126  127  #include <net/if.h>
 127  128  
 128  129  int netboot;
 129  130  int obpdebug;
 130  131  char *dhcack;           /* dhcp response packet */
 131  132  int dhcacklen;
 132  133  char *netdev_path;      /* Used to cache the netdev_path handed up by boot */
 133  134  char dhcifname[IFNAMSIZ];
 134  135  
  
    | 
      ↓ open down ↓ | 
    99 lines elided | 
    
      ↑ open up ↑ | 
  
 135  136  /*
 136  137   * Data from arp.c that must be resident.
 137  138   */
 138  139  #include <net/if_arp.h>
 139  140  #include <netinet/in.h>
 140  141  #include <netinet/in_var.h>
 141  142  #include <netinet/if_ether.h>
 142  143  
 143  144  ether_addr_t etherbroadcastaddr = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 144  145  
 145      -
 146      -/*
 147      - * Data from timod that must be resident
 148      - */
 149      -
 150      -/*
 151      - * state transition table for TI interface
 152      - */
 153      -#include <sys/tihdr.h>
 154      -
 155      -#define nr      127             /* not reachable */
 156      -
 157      -char ti_statetbl[TE_NOEVENTS][TS_NOSTATES] = {
 158      -                                /* STATES */
 159      -        /* 0  1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16 */
 160      -
 161      -        { 1, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr},
 162      -        {nr, nr, nr,  2, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr},
 163      -        {nr, nr, nr,  4, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr},
 164      -        {nr,  3, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr},
 165      -        {nr, nr, nr, nr,  3, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr},
 166      -        {nr,  0,  3, nr,  3,  3, nr, nr,  7, nr, nr, nr,  6,  7,  9, 10, 11},
 167      -        {nr, nr,  0, nr, nr,  6, nr, nr, nr, nr, nr, nr,  3, nr,  3,  3,  3},
 168      -        {nr, nr, nr, nr, nr, nr, nr, nr,  9, nr, nr, nr, nr,  3, nr, nr, nr},
 169      -        {nr, nr, nr, nr, nr, nr, nr, nr,  3, nr, nr, nr, nr,  3, nr, nr, nr},
 170      -        {nr, nr, nr, nr, nr, nr, nr, nr,  7, nr, nr, nr, nr,  7, nr, nr, nr},
 171      -        {nr, nr, nr,  5, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr},
 172      -        {nr, nr, nr, nr, nr, nr, nr,  8, nr, nr, nr, nr, nr, nr, nr, nr, nr},
 173      -        {nr, nr, nr, nr, nr, nr, 12, 13, nr, 14, 15, 16, nr, nr, nr, nr, nr},
 174      -        {nr, nr, nr, nr, nr, nr, nr, nr, nr,  9, nr, 11, nr, nr, nr, nr, nr},
 175      -        {nr, nr, nr, nr, nr, nr, nr, nr, nr,  9, nr, 11, nr, nr, nr, nr, nr},
 176      -        {nr, nr, nr, nr, nr, nr, nr, nr, nr, 10, nr,  3, nr, nr, nr, nr, nr},
 177      -        {nr, nr, nr,  7, nr, nr, nr,  7, nr, nr, nr, nr, nr, nr, nr, nr, nr},
 178      -        {nr, nr, nr, nr, nr, nr,  9, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr},
 179      -        {nr, nr, nr, nr, nr, nr, nr, nr, nr,  9, 10, nr, nr, nr, nr, nr, nr},
 180      -        {nr, nr, nr, nr, nr, nr, nr, nr, nr,  9, 10, nr, nr, nr, nr, nr, nr},
 181      -        {nr, nr, nr, nr, nr, nr, nr, nr, nr, 11,  3, nr, nr, nr, nr, nr, nr},
 182      -        {nr, nr, nr, nr, nr, nr,  3, nr, nr,  3,  3,  3, nr, nr, nr, nr, nr},
 183      -        {nr, nr, nr, nr, nr, nr, nr,  3, nr, nr, nr, nr, nr, nr, nr, nr, nr},
 184      -        {nr, nr, nr, nr, nr, nr, nr,  7, nr, nr, nr, nr, nr, nr, nr, nr, nr},
 185      -        {nr, nr, nr,  9, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr},
 186      -        {nr, nr, nr,  3, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr},
 187      -        {nr, nr, nr,  3, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr},
 188      -        {nr, nr, nr,  3, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr},
 189      -};
 190      -
 191      -
 192  146  #include <sys/tty.h>
 193  147  #include <sys/ptyvar.h>
 194  148  
 195  149  static void store_fetch_initspace();
 196  150  
 197  151  /*
 198  152   * Allocate tunable structures at runtime.
 199  153   */
 200  154  void
 201  155  space_init(void)
 202  156  {
 203  157          pty_initspace();
 204  158          store_fetch_initspace();
 205  159  }
 206  160  
 207  161  int ts_dispatch_extended = -1; /* set in ts_getdptbl or set_platform_default */
 208  162  
 209  163  /*
 210  164   * Previously defined in consmsconf.c ...
 211  165   */
 212  166  dev_t kbddev = NODEV;
 213  167  dev_t mousedev = NODEV;
 214  168  dev_t stdindev = NODEV;
 215  169  dev_t diagdev = NODEV;
 216  170  struct vnode *wsconsvp;
 217  171  
 218  172  dev_t fbdev = NODEV;
 219  173  struct vnode *fbvp;
 220  174  dev_info_t *fbdip;
 221  175  
 222  176  /*
 223  177   * moved from cons.c because they must be resident in the kernel.
 224  178   */
 225  179  vnode_t *rconsvp;
 226  180  dev_t   rconsdev;
 227  181  dev_t   uconsdev = NODEV;
 228  182  
 229  183  /*
 230  184   * serial virtual console vnode pointer.
 231  185   */
 232  186  vnode_t         *vsconsvp = NULL;
 233  187  
 234  188  /*
 235  189   * Flag whether console fb output is using PROM/PROM emulation
 236  190   * terminal emulator, or is using the kernel terminal emulator.
 237  191   */
 238  192  int     consmode = CONS_FW;
 239  193  
 240  194  /*
 241  195   * The following allows systems to disable use of the kernel
 242  196   * terminal emulator (retreat to PROM terminal emulator if there
 243  197   * is PROM).
 244  198   */
 245  199  int     cons_tem_disable;
 246  200  
 247  201  /*
 248  202   * consconfig() in autoconf.c sets this; it's the vnode of the distinguished
 249  203   * keyboard/frame buffer combination, aka the workstation console.
 250  204   */
 251  205  vnode_t *rwsconsvp;
 252  206  dev_t   rwsconsdev;
 253  207  
 254  208  /*
 255  209   * Platform console abort policy.
 256  210   * Platforms may override the default software policy, if such hardware
 257  211   * (e.g. keyswitches with a secure position) exists.
 258  212   */
 259  213  int abort_enable = KIOCABORTENABLE;
 260  214  
 261  215  /* from cpc.c */
 262  216  uint_t kcpc_key;        /* TSD key for CPU performance counter context */
 263  217  
 264  218  /*
 265  219   * storing and retrieving data by string key
 266  220   *
 267  221   * this mechanism allows a consumer to store and retrieve by name a pointer
 268  222   * to some space maintained by the consumer.
 269  223   * For example, a driver or module may want to have persistent data
 270  224   * over unloading/loading cycles. The pointer is typically to some
 271  225   * kmem_alloced space and it should not be pointing to data that will
 272  226   * be destroyed when the module is unloaded.
 273  227   */
 274  228  static mod_hash_t *space_hash;
 275  229  static char *space_hash_name = "space_hash";
 276  230  static size_t   space_hash_nchains = 8;
 277  231  
 278  232  static void
 279  233  store_fetch_initspace()
 280  234  {
 281  235          space_hash = mod_hash_create_strhash(space_hash_name,
 282  236              space_hash_nchains, mod_hash_null_valdtor);
 283  237          ASSERT(space_hash);
 284  238  }
 285  239  
 286  240  int
 287  241  space_store(char *key, uintptr_t ptr)
 288  242  {
 289  243          char *s;
 290  244          int rval;
 291  245          size_t l;
 292  246  
 293  247          /* some sanity checks first */
 294  248          if (key == NULL) {
 295  249                  return (-1);
 296  250          }
 297  251          l = (size_t)strlen(key);
 298  252          if (l == 0) {
 299  253                  return (-1);
 300  254          }
 301  255  
 302  256          /* increment for null terminator */
 303  257          l++;
 304  258  
 305  259          /* alloc space for the string, mod_hash_insert will deallocate */
 306  260          s = kmem_alloc(l, KM_SLEEP);
 307  261          bcopy(key, s, l);
 308  262  
 309  263          rval = mod_hash_insert(space_hash,
 310  264              (mod_hash_key_t)s, (mod_hash_val_t)ptr);
 311  265  
 312  266          switch (rval) {
 313  267          case 0:
 314  268                  break;
 315  269  #ifdef DEBUG
 316  270          case MH_ERR_DUPLICATE:
 317  271                  cmn_err(CE_WARN, "space_store: duplicate key %s", key);
 318  272                  rval = -1;
 319  273                  break;
 320  274          case MH_ERR_NOMEM:
 321  275                  cmn_err(CE_WARN, "space_store: no mem for key %s", key);
 322  276                  rval = -1;
 323  277                  break;
 324  278          default:
 325  279                  cmn_err(CE_WARN, "space_store: unspecified error for key %s",
 326  280                      key);
 327  281                  rval = -1;
 328  282                  break;
 329  283  #else
 330  284          default:
 331  285                  rval = -1;
 332  286                  break;
 333  287  #endif
 334  288          }
 335  289  
 336  290          return (rval);
 337  291  }
 338  292  
 339  293  uintptr_t
 340  294  space_fetch(char *key)
 341  295  {
 342  296          uintptr_t ptr = 0;
 343  297          mod_hash_val_t val;
 344  298          int rval;
 345  299  
 346  300          if (key) {
 347  301                  rval = mod_hash_find(space_hash, (mod_hash_key_t)key, &val);
 348  302                  if (rval == 0) {
 349  303                          ptr = (uintptr_t)val;
 350  304                  }
 351  305          }
 352  306  
 353  307          return (ptr);
 354  308  }
 355  309  
 356  310  void
 357  311  space_free(char *key)
 358  312  {
 359  313          if (key) {
 360  314                  (void) mod_hash_destroy(space_hash, (mod_hash_key_t)key);
 361  315          }
 362  316  }
 363  317  
 364  318  /*
 365  319   * Support for CRC32.  At present all calculations are done in simple
 366  320   * macros, so all we need is somewhere to declare the global lookup table.
 367  321   */
 368  322  
 369  323  #include <sys/crc32.h>
 370  324  
 371  325  const uint32_t crc32_table[256] = { CRC32_TABLE };
 372  326  
 373  327  /*
 374  328   * We need to fanout load from NIC which can overwhelm a single CPU.
 375  329   * This becomes especially important on systems having slow CPUs
 376  330   * (sun4v architecture). mac_soft_ring_enable is false on all
 377  331   * systems except sun4v. On sun4v, they get enabled by default (see
 378  332   * sun4v/os/mach_startup.c).
 379  333   */
 380  334  boolean_t       mac_soft_ring_enable = B_FALSE;
 381  335  
 382  336  /*
 383  337   * Global iscsi boot prop
 384  338   */
 385  339  ib_boot_prop_t  *iscsiboot_prop = NULL;
  
    | 
      ↓ open down ↓ | 
    184 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX