Print this page
5056 ZFS deadlock on db_mtx and dn_holds
Reviewed by: Will Andrews <willa@spectralogic.com>
Reviewed by: Matt Ahrens <mahrens@delphix.com>
Reviewed by: George Wilson <george.wilson@delphix.com>
Approved by: Dan McDonald <danmcd@omniti.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/spa.c
          +++ new/usr/src/uts/common/fs/zfs/spa.c
↓ 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 (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
  25   25   * Copyright (c) 2013, 2014, Nexenta Systems, Inc.  All rights reserved.
       26 + * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
  26   27   */
  27   28  
  28   29  /*
  29   30   * SPA: Storage Pool Allocator
  30   31   *
  31   32   * This file contains all the routines used when modifying on-disk SPA state.
  32   33   * This includes opening, importing, destroying, exporting a pool, and syncing a
  33   34   * pool.
  34   35   */
  35   36  
↓ open down ↓ 1045 lines elided ↑ open up ↑
1081 1082          }
1082 1083          mutex_exit(&spa->spa_proc_lock);
1083 1084  
1084 1085          /* If we didn't create a process, we need to create our taskqs. */
1085 1086          if (spa->spa_proc == &p0) {
1086 1087                  spa_create_zio_taskqs(spa);
1087 1088          }
1088 1089  
1089 1090          list_create(&spa->spa_config_dirty_list, sizeof (vdev_t),
1090 1091              offsetof(vdev_t, vdev_config_dirty_node));
     1092 +        list_create(&spa->spa_evicting_os_list, sizeof (objset_t),
     1093 +            offsetof(objset_t, os_evicting_node));
1091 1094          list_create(&spa->spa_state_dirty_list, sizeof (vdev_t),
1092 1095              offsetof(vdev_t, vdev_state_dirty_node));
1093 1096  
1094 1097          txg_list_create(&spa->spa_vdev_txg_list,
1095 1098              offsetof(struct vdev, vdev_txg_node));
1096 1099  
1097 1100          avl_create(&spa->spa_errlist_scrub,
1098 1101              spa_error_entry_compare, sizeof (spa_error_entry_t),
1099 1102              offsetof(spa_error_entry_t, se_avl));
1100 1103          avl_create(&spa->spa_errlist_last,
↓ open down ↓ 6 lines elided ↑ open up ↑
1107 1110   */
1108 1111  static void
1109 1112  spa_deactivate(spa_t *spa)
1110 1113  {
1111 1114          ASSERT(spa->spa_sync_on == B_FALSE);
1112 1115          ASSERT(spa->spa_dsl_pool == NULL);
1113 1116          ASSERT(spa->spa_root_vdev == NULL);
1114 1117          ASSERT(spa->spa_async_zio_root == NULL);
1115 1118          ASSERT(spa->spa_state != POOL_STATE_UNINITIALIZED);
1116 1119  
     1120 +        spa_evicting_os_wait(spa);
     1121 +
1117 1122          txg_list_destroy(&spa->spa_vdev_txg_list);
1118 1123  
1119 1124          list_destroy(&spa->spa_config_dirty_list);
     1125 +        list_destroy(&spa->spa_evicting_os_list);
1120 1126          list_destroy(&spa->spa_state_dirty_list);
1121 1127  
1122 1128          for (int t = 0; t < ZIO_TYPES; t++) {
1123 1129                  for (int q = 0; q < ZIO_TASKQ_TYPES; q++) {
1124 1130                          spa_taskqs_fini(spa, t, q);
1125 1131                  }
1126 1132          }
1127 1133  
1128 1134          metaslab_class_destroy(spa->spa_normal_class);
1129 1135          spa->spa_normal_class = NULL;
↓ open down ↓ 970 lines elided ↑ open up ↑
2100 2106                  }
2101 2107  
2102 2108                  nvlist_free(spa->spa_load_info);
2103 2109                  spa->spa_load_info = fnvlist_alloc();
2104 2110  
2105 2111                  gethrestime(&spa->spa_loaded_ts);
2106 2112                  error = spa_load_impl(spa, pool_guid, config, state, type,
2107 2113                      mosconfig, &ereport);
2108 2114          }
2109 2115  
     2116 +        /*
     2117 +         * Don't count references from objsets that are already closed
     2118 +         * and are making their way through the eviction process.
     2119 +         */
     2120 +        spa_evicting_os_wait(spa);
2110 2121          spa->spa_minref = refcount_count(&spa->spa_refcount);
2111 2122          if (error) {
2112 2123                  if (error != EEXIST) {
2113 2124                          spa->spa_loaded_ts.tv_sec = 0;
2114 2125                          spa->spa_loaded_ts.tv_nsec = 0;
2115 2126                  }
2116 2127                  if (error != EBADF) {
2117 2128                          zfs_ereport_post(ereport, spa, NULL, NULL, 0, 0);
2118 2129                  }
2119 2130          }
↓ open down ↓ 1548 lines elided ↑ open up ↑
3668 3679          /*
3669 3680           * We explicitly wait for the first transaction to complete so that our
3670 3681           * bean counters are appropriately updated.
3671 3682           */
3672 3683          txg_wait_synced(spa->spa_dsl_pool, txg);
3673 3684  
3674 3685          spa_config_sync(spa, B_FALSE, B_TRUE);
3675 3686  
3676 3687          spa_history_log_version(spa, "create");
3677 3688  
     3689 +        /*
     3690 +         * Don't count references from objsets that are already closed
     3691 +         * and are making their way through the eviction process.
     3692 +         */
     3693 +        spa_evicting_os_wait(spa);
3678 3694          spa->spa_minref = refcount_count(&spa->spa_refcount);
3679 3695  
3680 3696          mutex_exit(&spa_namespace_lock);
3681 3697  
3682 3698          return (0);
3683 3699  }
3684 3700  
3685 3701  #ifdef _KERNEL
3686 3702  /*
3687 3703   * Get the root pool information from the root disk, then import the root pool
↓ open down ↓ 512 lines elided ↑ open up ↑
4200 4216          /*
4201 4217           * The pool will be in core if it's openable,
4202 4218           * in which case we can modify its state.
4203 4219           */
4204 4220          if (spa->spa_state != POOL_STATE_UNINITIALIZED && spa->spa_sync_on) {
4205 4221                  /*
4206 4222                   * Objsets may be open only because they're dirty, so we
4207 4223                   * have to force it to sync before checking spa_refcnt.
4208 4224                   */
4209 4225                  txg_wait_synced(spa->spa_dsl_pool, 0);
     4226 +                spa_evicting_os_wait(spa);
4210 4227  
4211 4228                  /*
4212 4229                   * A pool cannot be exported or destroyed if there are active
4213 4230                   * references.  If we are resetting a pool, allow references by
4214 4231                   * fault injection handlers.
4215 4232                   */
4216 4233                  if (!spa_refcount_zero(spa) ||
4217 4234                      (spa->spa_inject_ref != 0 &&
4218 4235                      new_state != POOL_STATE_UNINITIALIZED)) {
4219 4236                          spa_async_resume(spa);
↓ open down ↓ 2426 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX