Improve write issue taskqs utilization

- Reduce number of allocators on small system down to one per 4
CPU cores, keeping maximum at 4 on 16+ core systems. Small systems
should not have the lock contention multiple allocators supposed
to solve, while having several metaslabs open and modified each
TXG is not free.
 - Reduce number of write issue taskqs down to one per 16 CPU
cores and an integer fraction of number of allocators.  On mid-
sized systems, where multiple allocators already make sense, too
many write issue taskqs may reduce write speed on single-file
workloads, since single file is handled by only one taskq to
reduce fragmentation. On large systems, that can actually benefit
from many taskq's better IOPS, the bottleneck is less important,
since in worst case there will be at least 16 cores to handle it.
 - Distribute dnodes between allocators (and taskqs) in a round-
robin fashion instead of relying on sync taskqs to be balanced.
The last is not guarantied and may depend on scheduling.
 - Remove io_wr_iss_tq from struct zio.  io_allocator is enough.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by:	Alexander Motin <mav@FreeBSD.org>
Sponsored by:	iXsystems, Inc.
Closes #16130
This commit is contained in:
Alexander Motin
2024-05-01 14:07:20 -04:00
committed by GitHub
parent 8fd3a5d02f
commit 645b833079
8 changed files with 98 additions and 47 deletions
+2
View File
@@ -829,6 +829,8 @@ extern uint_t zfs_sync_pass_deferred_free;
/* spa sync taskqueues */
taskq_t *spa_sync_tq_create(spa_t *spa, const char *name);
void spa_sync_tq_destroy(spa_t *spa);
uint_t spa_acq_allocator(spa_t *spa);
void spa_rel_allocator(spa_t *spa, uint_t allocator);
void spa_select_allocator(zio_t *zio);
/* spa namespace global mutex */
+8 -1
View File
@@ -63,6 +63,12 @@ typedef struct spa_alloc {
avl_tree_t spaa_tree;
} ____cacheline_aligned spa_alloc_t;
typedef struct spa_allocs_use {
kmutex_t sau_lock;
uint_t sau_rotor;
boolean_t sau_inuse[];
} spa_allocs_use_t;
typedef struct spa_error_entry {
zbookmark_phys_t se_bookmark;
char *se_name;
@@ -192,7 +198,7 @@ typedef struct spa_taskqs {
/* one for each thread in the spa sync taskq */
typedef struct spa_syncthread_info {
kthread_t *sti_thread;
taskq_t *sti_wr_iss_tq; /* assigned wr_iss taskq */
uint_t sti_allocator;
} spa_syncthread_info_t;
typedef enum spa_all_vdev_zap_action {
@@ -270,6 +276,7 @@ struct spa {
* allocation performance in write-heavy workloads.
*/
spa_alloc_t *spa_allocs;
spa_allocs_use_t *spa_allocs_use;
int spa_alloc_count;
int spa_active_allocator; /* selectable allocator */
-3
View File
@@ -528,9 +528,6 @@ struct zio {
/* Taskq dispatching state */
taskq_ent_t io_tqent;
/* write issue taskq selection, based upon sync thread */
taskq_t *io_wr_iss_tq;
};
enum blk_verify_flag {