Print this page
6138 don't abuse atomic_cas_*

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/sun4/os/memnode.c
          +++ new/usr/src/uts/sun4/os/memnode.c
↓ open down ↓ 60 lines elided ↑ open up ↑
  61   61   *
  62   62   * It is rather tricky to do these updates since we can't
  63   63   * protect the memnode structures with locks, so we must
  64   64   * be mindful of the order in which updates and reads to
  65   65   * these values can occur.
  66   66   */
  67   67  void
  68   68  mem_node_add_slice(pfn_t start, pfn_t end)
  69   69  {
  70   70          int mnode;
  71      -        mnodeset_t newmask, oldmask;
  72   71  
  73   72          /*
  74   73           * DR will pass us the first pfn that is allocatable.
  75   74           * We need to round down to get the real start of
  76   75           * the slice.
  77   76           */
  78   77          if (mem_node_physalign) {
  79   78                  start &= ~(btop(mem_node_physalign) - 1);
  80   79                  end = roundup(end, btop(mem_node_physalign)) - 1;
  81   80          }
↓ open down ↓ 6 lines elided ↑ open up ↑
  88   87                   * Add slice to existing node.
  89   88                   */
  90   89                  if (start < mem_node_config[mnode].physbase)
  91   90                          mem_node_config[mnode].physbase = start;
  92   91                  if (end > mem_node_config[mnode].physmax)
  93   92                          mem_node_config[mnode].physmax = end;
  94   93          } else {
  95   94                  mem_node_config[mnode].physbase = start;
  96   95                  mem_node_config[mnode].physmax = end;
  97   96                  atomic_inc_16(&num_memnodes);
  98      -                do {
  99      -                        oldmask = memnodes_mask;
 100      -                        newmask = memnodes_mask | (1ull << mnode);
 101      -                } while (atomic_cas_64(&memnodes_mask, oldmask, newmask) !=
 102      -                         oldmask);
       97 +                atomic_or_64(&memnodes_mask, 1ull << mnode);
 103   98          }
 104   99          /*
 105  100           * Let the common lgrp framework know about the new memory
 106  101           */
 107  102          lgrp_config(LGRP_CONFIG_MEM_ADD, mnode, MEM_NODE_2_LGRPHAND(mnode));
 108  103  }
 109  104  
 110  105  /*
 111  106   * Remove a PFN range from a memnode.  On some platforms,
 112  107   * the memnode will be created with physbase at the first
 113  108   * allocatable PFN, but later deleted with the MC slice
 114  109   * base address converted to a PFN, in which case we need
 115  110   * to assume physbase and up.
 116  111   */
 117  112  void
 118  113  mem_node_del_slice(pfn_t start, pfn_t end)
 119  114  {
 120  115          int mnode;
 121  116          pgcnt_t delta_pgcnt, node_size;
 122      -        mnodeset_t omask, nmask;
 123  117  
 124  118          if (mem_node_physalign) {
 125  119                  start &= ~(btop(mem_node_physalign) - 1);
 126  120                  end = roundup(end, btop(mem_node_physalign)) - 1;
 127  121          }
 128  122          mnode = PFN_2_MEM_NODE(start);
 129  123  
 130  124          ASSERT(mnode < max_mem_nodes);
 131  125          ASSERT(mem_node_config[mnode].exists == 1);
 132  126  
↓ open down ↓ 16 lines elided ↑ open up ↑
 149  143                   * Let the common lgrp framework know the mnode is
 150  144                   * leaving
 151  145                   */
 152  146                  lgrp_config(LGRP_CONFIG_MEM_DEL, mnode,
 153  147                      MEM_NODE_2_LGRPHAND(mnode));
 154  148  
 155  149                  /*
 156  150                   * Delete the whole node.
 157  151                   */
 158  152                  ASSERT(MNODE_PGCNT(mnode) == 0);
 159      -                do {
 160      -                        omask = memnodes_mask;
 161      -                        nmask = omask & ~(1ull << mnode);
 162      -                } while (atomic_cas_64(&memnodes_mask, omask, nmask) != omask);
      153 +                atomic_and_64(&memnodes_mask, ~(1ull << mnode));
 163  154                  atomic_dec_16(&num_memnodes);
 164  155                  mem_node_config[mnode].exists = 0;
 165  156          }
 166  157  }
 167  158  
 168  159  void
 169  160  mem_node_add_range(pfn_t start, pfn_t end)
 170  161  {
 171  162          if (&plat_slice_add != NULL)
 172  163                  plat_slice_add(start, end);
↓ open down ↓ 34 lines elided ↑ open up ↑
 207  198          }
 208  199  }
 209  200  
 210  201  /*
 211  202   * Allocate an unassigned memnode.
 212  203   */
 213  204  int
 214  205  mem_node_alloc()
 215  206  {
 216  207          int mnode;
 217      -        mnodeset_t newmask, oldmask;
 218  208  
 219  209          /*
 220  210           * Find an unused memnode.  Update it atomically to prevent
 221  211           * a first time memnode creation race.
 222  212           */
 223  213          for (mnode = 0; mnode < max_mem_nodes; mnode++)
 224  214                  if (atomic_cas_32((uint32_t *)&mem_node_config[mnode].exists,
 225  215                      0, 1) == 0)
 226  216                          break;
 227  217  
 228  218          if (mnode >= max_mem_nodes)
 229  219                          panic("Out of free memnodes\n");
 230  220  
 231  221          mem_node_config[mnode].physbase = (uint64_t)-1;
 232  222          mem_node_config[mnode].physmax = 0;
 233  223          atomic_inc_16(&num_memnodes);
 234      -        do {
 235      -                oldmask = memnodes_mask;
 236      -                newmask = memnodes_mask | (1ull << mnode);
 237      -        } while (atomic_cas_64(&memnodes_mask, oldmask, newmask) != oldmask);
      224 +        atomic_or_64(&memnodes_mask, 1ull << mnode);
 238  225  
 239  226          return (mnode);
 240  227  }
 241  228  
 242  229  /*
 243  230   * Find the intersection between a memnode and a memlist
 244  231   * and returns the number of pages that overlap.
 245  232   *
 246  233   * Grab the memlist lock to protect the list from DR operations.
 247  234   */
↓ open down ↓ 71 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX