* Number of allocators to use, per spa instance
*/
static int spa_num_allocators = 4;
+static int spa_cpus_per_allocator = 4;
/*
* Spa active allocator.
if (altroot)
spa->spa_root = spa_strdup(altroot);
- /* Do not allow more allocators than CPUs. */
- spa->spa_alloc_count = MIN(MAX(spa_num_allocators, 1), boot_ncpus);
+ /* Do not allow more allocators than fraction of CPUs. */
+ spa->spa_alloc_count = MAX(MIN(spa_num_allocators,
+ boot_ncpus / MAX(spa_cpus_per_allocator, 1)), 1);
spa->spa_allocs = kmem_zalloc(spa->spa_alloc_count *
sizeof (spa_alloc_t), KM_SLEEP);
avl_create(&spa->spa_allocs[i].spaa_tree, zio_bookmark_compare,
sizeof (zio_t), offsetof(zio_t, io_queue_node.a));
}
+ if (spa->spa_alloc_count > 1) {
+ spa->spa_allocs_use = kmem_zalloc(offsetof(spa_allocs_use_t,
+ sau_inuse[spa->spa_alloc_count]), KM_SLEEP);
+ mutex_init(&spa->spa_allocs_use->sau_lock, NULL, MUTEX_DEFAULT,
+ NULL);
+ }
avl_create(&spa->spa_metaslabs_by_flushed, metaslab_sort_by_flushed,
sizeof (metaslab_t), offsetof(metaslab_t, ms_spa_txg_node));
}
kmem_free(spa->spa_allocs, spa->spa_alloc_count *
sizeof (spa_alloc_t));
+ if (spa->spa_alloc_count > 1) {
+ mutex_destroy(&spa->spa_allocs_use->sau_lock);
+ kmem_free(spa->spa_allocs_use, offsetof(spa_allocs_use_t,
+ sau_inuse[spa->spa_alloc_count]));
+ }
avl_destroy(&spa->spa_metaslabs_by_flushed);
avl_destroy(&spa->spa_sm_logs_by_txg);
param_get_uint, ZMOD_RW, "Reserved free space in pool");
ZFS_MODULE_PARAM(zfs, spa_, num_allocators, INT, ZMOD_RW,
- "Number of allocators per spa, capped by ncpus");
+ "Number of allocators per spa");
+
+ZFS_MODULE_PARAM(zfs, spa_, cpus_per_allocator, INT, ZMOD_RW,
+ "Minimum number of CPUs per allocators");