git: b06771aa667d - main - CTL: Allow I/Os up to 8MB, depending on maxphys value.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 30 Dec 2021 04:49:28 UTC
The branch main has been updated by mav: URL: https://cgit.FreeBSD.org/src/commit/?id=b06771aa667dadeffa0b0ec840af13b74d55e186 commit b06771aa667dadeffa0b0ec840af13b74d55e186 Author: Alexander Motin <mav@FreeBSD.org> AuthorDate: 2021-12-30 03:58:52 +0000 Commit: Alexander Motin <mav@FreeBSD.org> CommitDate: 2021-12-30 04:49:24 +0000 CTL: Allow I/Os up to 8MB, depending on maxphys value. For years CTL block backend limited I/O size to 1MB, splitting larger requests into sequentially processed chunks. It is sufficient for most of use cases, since typical initiators rarely use bigger I/Os. One of known exceptions is VMWare VAAI offload, by default sending up to 8 4MB EXTENDED COPY requests same time. CTL internally converted those into 32 1MB READ/WRITE requests, that could overwhelm the block backend, having finite number of processing threads and making more important interactive I/Os to wait in its queue. Previously it was partially covered by CTL core serializing sequential reads to help ZFS speculative prefetcher, but that serialization was significantly relaxed after recent ZFS improvements. With the new settings block backend receives 8 4MB requests, that should be easier for both CTL itself and the underlying storage. MFC after: 2 weeks Sponsored by: iXsystems, Inc. --- sys/cam/ctl/ctl_backend_block.c | 28 +++++++++++++--------------- sys/cam/ctl/ctl_tpc.c | 6 +++--- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/sys/cam/ctl/ctl_backend_block.c b/sys/cam/ctl/ctl_backend_block.c index ae558e496514..289da02398cc 100644 --- a/sys/cam/ctl/ctl_backend_block.c +++ b/sys/cam/ctl/ctl_backend_block.c @@ -4,7 +4,7 @@ * Copyright (c) 2003 Silicon Graphics International Corp. * Copyright (c) 2009-2011 Spectra Logic Corporation * Copyright (c) 2012,2021 The FreeBSD Foundation - * Copyright (c) 2014-2015 Alexander Motin <mav@FreeBSD.org> + * Copyright (c) 2014-2021 Alexander Motin <mav@FreeBSD.org> * All rights reserved. * * Portions of this software were developed by Edward Tomasz Napierala @@ -101,16 +101,15 @@ __FBSDID("$FreeBSD$"); #include <cam/ctl/ctl_error.h> /* - * The idea here is that we'll allocate enough S/G space to hold a 1MB - * I/O. If we get an I/O larger than that, we'll split it. + * The idea here is to allocate enough S/G space to handle at least 1MB I/Os. + * On systems with small maxphys it can be 8 128KB segments. On large systems + * it can be up to 8 1MB segments. I/Os larger than that we'll split. */ -#define CTLBLK_HALF_IO_SIZE (512 * 1024) -#define CTLBLK_MAX_IO_SIZE (CTLBLK_HALF_IO_SIZE * 2) +#define CTLBLK_MAX_SEGS 8 +#define CTLBLK_HALF_SEGS (CTLBLK_MAX_SEGS / 2) #define CTLBLK_MIN_SEG (128 * 1024) -#define CTLBLK_MAX_SEG MIN(CTLBLK_HALF_IO_SIZE, maxphys) -#define CTLBLK_HALF_SEGS MAX(CTLBLK_HALF_IO_SIZE / CTLBLK_MIN_SEG, 1) -#define CTLBLK_MAX_SEGS (CTLBLK_HALF_SEGS * 2) -#define CTLBLK_NUM_SEGS (CTLBLK_MAX_IO_SIZE / CTLBLK_MAX_SEG) +#define CTLBLK_MAX_SEG MIN(1024 * 1024, MAX(CTLBLK_MIN_SEG, maxphys)) +#define CTLBLK_MAX_IO_SIZE (CTLBLK_MAX_SEG * CTLBLK_MAX_SEGS) #ifdef CTLBLK_DEBUG #define DPRINTF(fmt, args...) \ @@ -1230,10 +1229,10 @@ ctl_be_block_dispatch_dev(struct ctl_be_block_lun *be_lun, */ if (csw) { max_iosize = dev->si_iosize_max; - if (max_iosize < PAGE_SIZE) + if (max_iosize <= 0) max_iosize = DFLTPHYS; } else - max_iosize = DFLTPHYS; + max_iosize = maxphys; cur_offset = beio->io_offset; for (i = 0; i < beio->num_segs; i++) { @@ -1401,7 +1400,7 @@ ctl_be_block_cw_dispatch_ws(struct ctl_be_block_lun *be_lun, else pbo = 0; len_left = (uint64_t)lbalen->len * cbe_lun->blocksize; - for (i = 0, lba = 0; i < CTLBLK_NUM_SEGS && len_left > 0; i++) { + for (i = 0, lba = 0; i < CTLBLK_MAX_SEGS && len_left > 0; i++) { /* * Setup the S/G entry for this chunk. */ @@ -1669,11 +1668,10 @@ ctl_be_block_dispatch(struct ctl_be_block_lun *be_lun, DPRINTF("%s at LBA %jx len %u @%ju\n", (beio->bio_cmd == BIO_READ) ? "READ" : "WRITE", (uintmax_t)lbalen->lba, lbalen->len, bptrlen->len); + lbas = CTLBLK_MAX_IO_SIZE; if (lbalen->flags & CTL_LLF_COMPARE) { beio->two_sglists = 1; - lbas = CTLBLK_HALF_IO_SIZE; - } else { - lbas = CTLBLK_MAX_IO_SIZE; + lbas /= 2; } lbas = MIN(lbalen->len - bptrlen->len, lbas / cbe_lun->blocksize); beio->io_offset = (lbalen->lba + bptrlen->len) * cbe_lun->blocksize; diff --git a/sys/cam/ctl/ctl_tpc.c b/sys/cam/ctl/ctl_tpc.c index de9e97b87a3e..60cd5611643d 100644 --- a/sys/cam/ctl/ctl_tpc.c +++ b/sys/cam/ctl/ctl_tpc.c @@ -1,7 +1,7 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * - * Copyright (c) 2014 Alexander Motin <mav@FreeBSD.org> + * Copyright (c) 2014-2021 Alexander Motin <mav@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -67,8 +67,8 @@ __FBSDID("$FreeBSD$"); #define TPC_MAX_LIST 8192 #define TPC_MAX_INLINE 0 #define TPC_MAX_LISTS 255 -#define TPC_MAX_IO_SIZE (1024 * 1024) -#define TPC_MAX_IOCHUNK_SIZE (TPC_MAX_IO_SIZE * 16) +#define TPC_MAX_IO_SIZE (8 * MIN(1024 * 1024, MAX(128 * 1024, maxphys))) +#define TPC_MAX_IOCHUNK_SIZE (TPC_MAX_IO_SIZE * 4) #define TPC_MIN_TOKEN_TIMEOUT 1 #define TPC_DFL_TOKEN_TIMEOUT 60 #define TPC_MAX_TOKEN_TIMEOUT 600