From 7d1482bec149bf4b13f9d8955226c372ede68f61 Mon Sep 17 00:00:00 2001 From: Chunwei Chen Date: Tue, 19 May 2015 17:32:44 +0800 Subject: [PATCH] Allocate ABD buffer according to BUFC type in _cb functions In dsl_scan_scrub_cb and spa_load_verify_cb, we originally always allocated linear ABD. Now we try to allocate scatter ABD according to the BUFC type of the blkptr to reduce unnecessary spl slab allocation. Also in zio_ddt_read_start, we match the parent zio->io_data ABD type for the same reason. Signed-off-by: Chunwei Chen --- module/zfs/dsl_scan.c | 7 ++++++- module/zfs/spa.c | 5 ++++- module/zfs/zio.c | 8 ++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/module/zfs/dsl_scan.c b/module/zfs/dsl_scan.c index 0ea9c04f42ff..b0f83c7b5c58 100644 --- a/module/zfs/dsl_scan.c +++ b/module/zfs/dsl_scan.c @@ -1830,7 +1830,12 @@ dsl_scan_scrub_cb(dsl_pool_t *dp, if (needs_io && !zfs_no_scrub_io) { vdev_t *rvd = spa->spa_root_vdev; uint64_t maxinflight = rvd->vdev_children * zfs_top_maxinflight; - abd_t *data = abd_alloc_linear(size); + abd_t *data; + + if (ARC_BUFC_IS_SCATTER(BP_GET_BUFC_TYPE(bp))) + data = abd_alloc_scatter(size); + else + data = abd_alloc_linear(size); mutex_enter(&spa->spa_scrub_lock); while (spa->spa_scrub_inflight >= maxinflight) diff --git a/module/zfs/spa.c b/module/zfs/spa.c index 3365ccfd7da8..04be218372ad 100644 --- a/module/zfs/spa.c +++ b/module/zfs/spa.c @@ -1934,7 +1934,10 @@ spa_load_verify_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, rio = arg; size = BP_GET_PSIZE(bp); - data = abd_alloc_linear(size); + if (ARC_BUFC_IS_SCATTER(BP_GET_BUFC_TYPE(bp))) + data = abd_alloc_scatter(size); + else + data = abd_alloc_linear(size); mutex_enter(&spa->spa_scrub_lock); while (spa->spa_scrub_inflight >= spa_load_verify_maxinflight) diff --git a/module/zfs/zio.c b/module/zfs/zio.c index 360178a3aac9..0eb923a8eecb 100644 --- a/module/zfs/zio.c +++ b/module/zfs/zio.c @@ -2229,13 +2229,17 @@ zio_ddt_read_start(zio_t *zio) return (ZIO_PIPELINE_CONTINUE); for (p = 0; p < DDT_PHYS_TYPES; p++, ddp++) { + abd_t *tmp; if (ddp->ddp_phys_birth == 0 || ddp == ddp_self) continue; ddt_bp_create(ddt->ddt_checksum, &dde->dde_key, ddp, &blk); + if (ABD_IS_LINEAR(zio->io_data)) + tmp = abd_alloc_linear(zio->io_size); + else + tmp = abd_alloc_scatter(zio->io_size); zio_nowait(zio_read(zio, zio->io_spa, &blk, - abd_alloc_linear(zio->io_size), - zio->io_size, zio_ddt_child_read_done, dde, + tmp, zio->io_size, zio_ddt_child_read_done, dde, zio->io_priority, ZIO_DDT_CHILD_FLAGS(zio) | ZIO_FLAG_DONT_PROPAGATE, &zio->io_bookmark)); }