MFV r272585:

Split the godfather zio into CPU number's to reduce lock
contention.

Illumos issue:
    5176 lock contention on godfather zio

MFC after:	2 weeks
This commit is contained in:
Xin LI 2014-10-06 07:03:17 +00:00
commit 8fb26f5aef
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=272598
4 changed files with 26 additions and 11 deletions

View File

@ -2594,10 +2594,12 @@ dump_block_stats(spa_t *spa)
* all async I/Os to complete. * all async I/Os to complete.
*/ */
if (dump_opt['c']) { if (dump_opt['c']) {
(void) zio_wait(spa->spa_async_zio_root); for (int i = 0; i < max_ncpus; i++) {
spa->spa_async_zio_root = zio_root(spa, NULL, NULL, (void) zio_wait(spa->spa_async_zio_root[i]);
ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE | spa->spa_async_zio_root[i] = zio_root(spa, NULL, NULL,
ZIO_FLAG_GODFATHER); ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE |
ZIO_FLAG_GODFATHER);
}
} }
if (zcb.zcb_haderrors) { if (zcb.zcb_haderrors) {

View File

@ -1277,7 +1277,9 @@ spa_unload(spa_t *spa)
* Wait for any outstanding async I/O to complete. * Wait for any outstanding async I/O to complete.
*/ */
if (spa->spa_async_zio_root != NULL) { if (spa->spa_async_zio_root != NULL) {
(void) zio_wait(spa->spa_async_zio_root); for (int i = 0; i < max_ncpus; i++)
(void) zio_wait(spa->spa_async_zio_root[i]);
kmem_free(spa->spa_async_zio_root, max_ncpus * sizeof (void *));
spa->spa_async_zio_root = NULL; spa->spa_async_zio_root = NULL;
} }
@ -2213,8 +2215,13 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
/* /*
* Create "The Godfather" zio to hold all async IOs * Create "The Godfather" zio to hold all async IOs
*/ */
spa->spa_async_zio_root = zio_root(spa, NULL, NULL, spa->spa_async_zio_root = kmem_alloc(max_ncpus * sizeof (void *),
ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE | ZIO_FLAG_GODFATHER); KM_SLEEP);
for (int i = 0; i < max_ncpus; i++) {
spa->spa_async_zio_root[i] = zio_root(spa, NULL, NULL,
ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE |
ZIO_FLAG_GODFATHER);
}
/* /*
* Parse the configuration into a vdev tree. We explicitly set the * Parse the configuration into a vdev tree. We explicitly set the
@ -3567,8 +3574,13 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
/* /*
* Create "The Godfather" zio to hold all async IOs * Create "The Godfather" zio to hold all async IOs
*/ */
spa->spa_async_zio_root = zio_root(spa, NULL, NULL, spa->spa_async_zio_root = kmem_alloc(max_ncpus * sizeof (void *),
ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE | ZIO_FLAG_GODFATHER); KM_SLEEP);
for (int i = 0; i < max_ncpus; i++) {
spa->spa_async_zio_root[i] = zio_root(spa, NULL, NULL,
ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE |
ZIO_FLAG_GODFATHER);
}
/* /*
* Create the root vdev. * Create the root vdev.

View File

@ -206,7 +206,8 @@ struct spa {
uint64_t spa_failmode; /* failure mode for the pool */ uint64_t spa_failmode; /* failure mode for the pool */
uint64_t spa_delegation; /* delegation on/off */ uint64_t spa_delegation; /* delegation on/off */
list_t spa_config_list; /* previous cache file(s) */ list_t spa_config_list; /* previous cache file(s) */
zio_t *spa_async_zio_root; /* root of all async I/O */ /* per-CPU array of root of async I/O: */
zio_t **spa_async_zio_root;
zio_t *spa_suspend_zio_root; /* root of all suspended I/O */ zio_t *spa_suspend_zio_root; /* root of all suspended I/O */
kmutex_t spa_suspend_lock; /* protects suspend_zio_root */ kmutex_t spa_suspend_lock; /* protects suspend_zio_root */
kcondvar_t spa_suspend_cv; /* notification of resume */ kcondvar_t spa_suspend_cv; /* notification of resume */

View File

@ -1457,7 +1457,7 @@ zio_nowait(zio_t *zio)
*/ */
spa_t *spa = zio->io_spa; spa_t *spa = zio->io_spa;
zio_add_child(spa->spa_async_zio_root, zio); zio_add_child(spa->spa_async_zio_root[CPU_SEQID], zio);
} }
zio_execute(zio); zio_execute(zio);