Print this page
NEX-19598 HAT panic
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-16970 assertion failed: ht->ht_valid_cnt >= 0, file: ../../i86pc/vm/htable.c, line: 1204
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-18463 Parallel dump produces corrupted dump file
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-5164 backport illumos 6514 AS_* lock macros simplification
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
6514 AS_* lock macros simplification
Reviewed by: Piotr Jasiukajtis <estibi@me.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Albert Lee <trisk@omniti.com>
Approved by: Dan McDonald <danmcd@omniti.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/i86pc/vm/hat_i86.c
          +++ new/usr/src/uts/i86pc/vm/hat_i86.c
↓ open down ↓ 18 lines elided ↑ open up ↑
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   */
  24   24  /*
  25   25   * Copyright (c) 2010, Intel Corporation.
  26   26   * All rights reserved.
  27   27   */
  28   28  /*
  29      - * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
       29 + * Copyright 2019 Nexenta Systems, Inc.  All rights reserved.
       30 + * Copyright 2018 Joyent, Inc.  All rights reserved.
  30   31   * Copyright (c) 2014, 2015 by Delphix. All rights reserved.
  31   32   */
  32   33  
  33   34  /*
  34   35   * VM - Hardware Address Translation management for i386 and amd64
  35   36   *
  36   37   * Implementation of the interfaces described in <common/vm/hat.h>
  37   38   *
  38   39   * Nearly all the details of how the hardware is managed should not be
  39   40   * visible outside this layer except for misc. machine specific functions
↓ open down ↓ 218 lines elided ↑ open up ↑
 258  259           * the htable_steal() code.
 259  260           */
 260  261          if (can_steal_post_boot == 0)
 261  262                  can_steal_post_boot = 1;
 262  263  
 263  264          ASSERT(AS_WRITE_HELD(as));
 264  265          hat = kmem_cache_alloc(hat_cache, KM_SLEEP);
 265  266          hat->hat_as = as;
 266  267          mutex_init(&hat->hat_mutex, NULL, MUTEX_DEFAULT, NULL);
 267  268          ASSERT(hat->hat_flags == 0);
      269 +        hat->hat_unmaps = 0;
 268  270  
 269  271  #if defined(__xpv)
 270  272          /*
 271  273           * No VLP stuff on the hypervisor due to the 64-bit split top level
 272  274           * page tables.  On 32-bit it's not needed as the hypervisor takes
 273  275           * care of copying the top level PTEs to a below 4Gig page.
 274  276           */
 275  277          use_vlp = 0;
 276  278  #else   /* __xpv */
 277  279          /* 32 bit processes uses a VLP style hat when running with PAE */
↓ open down ↓ 116 lines elided ↑ open up ↑
 394  396  hat_free_start(hat_t *hat)
 395  397  {
 396  398          ASSERT(AS_WRITE_HELD(hat->hat_as));
 397  399  
 398  400          /*
 399  401           * If the hat is currently a stealing victim, wait for the stealing
 400  402           * to finish.  Once we mark it as HAT_FREEING, htable_steal()
 401  403           * won't look at its pagetables anymore.
 402  404           */
 403  405          mutex_enter(&hat_list_lock);
 404      -        while (hat->hat_flags & HAT_VICTIM)
      406 +        while ((hat->hat_flags & HAT_VICTIM) || (hat->hat_unmaps > 0))
 405  407                  cv_wait(&hat_list_cv, &hat_list_lock);
 406  408          hat->hat_flags |= HAT_FREEING;
 407  409          mutex_exit(&hat_list_lock);
 408  410  }
 409  411  
 410  412  /*
 411  413   * An address space is being destroyed, so we destroy the associated hat.
 412  414   */
 413  415  void
 414  416  hat_free_end(hat_t *hat)
↓ open down ↓ 2040 lines elided ↑ open up ↑
2455 2457  
2456 2458          /*
2457 2459           * handle last range for callbacks
2458 2460           */
2459 2461          if (r_cnt > 0)
2460 2462                  handle_ranges(hat, cb, r_cnt, r);
2461 2463          XPV_ALLOW_MIGRATE();
2462 2464  }
2463 2465  
2464 2466  /*
2465      - * Invalidate a virtual address translation on a slave CPU during
2466      - * panic() dumps.
     2467 + * Flush the TLB for the local CPU
     2468 + * Invoked from a slave CPU during panic() dumps.
2467 2469   */
2468 2470  void
2469      -hat_flush_range(hat_t *hat, caddr_t va, size_t size)
     2471 +hat_flush(void)
2470 2472  {
2471      -        ssize_t sz;
2472      -        caddr_t endva = va + size;
2473      -
2474      -        while (va < endva) {
2475      -                sz = hat_getpagesize(hat, va);
2476      -                if (sz < 0) {
2477 2473  #ifdef __xpv
2478 2474                          xen_flush_tlb();
2479 2475  #else
2480 2476                          flush_all_tlb_entries();
2481 2477  #endif
2482      -                        break;
2483      -                }
2484      -#ifdef __xpv
2485      -                xen_flush_va(va);
2486      -#else
2487      -                mmu_tlbflush_entry(va);
2488      -#endif
2489      -                va += sz;
2490      -        }
2491 2478  }
2492 2479  
2493 2480  /*
2494 2481   * synchronize mapping with software data structures
2495 2482   *
2496 2483   * This interface is currently only used by the working set monitor
2497 2484   * driver.
2498 2485   */
2499 2486  /*ARGSUSED*/
2500 2487  void
↓ open down ↓ 813 lines elided ↑ open up ↑
3314 3301   *      and non zero if enabled.  If flag specifes multiple attributes
3315 3302   *      then returns 0 if ALL attributes are disabled.  This is an advisory
3316 3303   *      call.
3317 3304   */
3318 3305  uint_t
3319 3306  hat_page_getattr(struct page *pp, uint_t flag)
3320 3307  {
3321 3308          return (PP_GETRM(pp, flag));
3322 3309  }
3323 3310  
3324      -
3325 3311  /*
3326 3312   * common code used by hat_pageunload() and hment_steal()
3327 3313   */
3328 3314  hment_t *
3329 3315  hati_page_unmap(page_t *pp, htable_t *ht, uint_t entry)
3330 3316  {
3331 3317          x86pte_t old_pte;
3332 3318          pfn_t pfn = pp->p_pagenum;
3333 3319          hment_t *hm;
     3320 +        hat_t *hat = ht->ht_hat;
3334 3321  
3335 3322          /*
     3323 +         * There is a race between this function and the freeing of a HAT
     3324 +         * whose owning process is exiting; process exit code ignores htable
     3325 +         * reference counts.
     3326 +         * If the HAT is already freeing (HAT_FREEING) no-op this function.
     3327 +         * Otherwise increment hat_unmaps to block the hat from being free'd
     3328 +         * until this function completes.
     3329 +         */
     3330 +        mutex_enter(&hat_list_lock);
     3331 +        if (hat->hat_flags & HAT_FREEING) {
     3332 +                mutex_exit(&hat_list_lock);
     3333 +                x86_hm_exit(pp);
     3334 +                return (NULL);
     3335 +        }
     3336 +        ++(hat->hat_unmaps);
     3337 +        mutex_exit(&hat_list_lock);
     3338 +
     3339 +        /*
3336 3340           * We need to acquire a hold on the htable in order to
3337 3341           * do the invalidate. We know the htable must exist, since
3338 3342           * unmap's don't release the htable until after removing any
3339 3343           * hment. Having x86_hm_enter() keeps that from proceeding.
3340 3344           */
3341 3345          htable_acquire(ht);
3342 3346  
3343 3347          /*
3344 3348           * Invalidate the PTE and remove the hment.
3345 3349           */
↓ open down ↓ 16 lines elided ↑ open up ↑
3362 3366           */
3363 3367          if (PTE_GET(old_pte, PT_SOFTWARE) < PT_NOSYNC)
3364 3368                  hati_sync_pte_to_page(pp, old_pte, ht->ht_level);
3365 3369  
3366 3370          /*
3367 3371           * Remove the mapping list entry for this page.
3368 3372           */
3369 3373          hm = hment_remove(pp, ht, entry);
3370 3374  
3371 3375          /*
3372      -         * drop the mapping list lock so that we might free the
3373      -         * hment and htable.
     3376 +         * drop the mapping list lock so that we might free the hment and htable
3374 3377           */
3375 3378          x86_hm_exit(pp);
3376 3379          htable_release(ht);
     3380 +
     3381 +        mutex_enter(&hat_list_lock);
     3382 +        --(hat->hat_unmaps);
     3383 +        cv_broadcast(&hat_list_cv);
     3384 +        mutex_exit(&hat_list_lock);
3377 3385          return (hm);
3378 3386  }
3379 3387  
3380 3388  extern int      vpm_enable;
3381 3389  /*
3382 3390   * Unload all translations to a page. If the page is a subpage of a large
3383 3391   * page, the large page mappings are also removed.
3384 3392   *
3385 3393   * The forceflags are unused.
3386 3394   */
↓ open down ↓ 1106 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX