1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-10-19 02:29:40 +00:00

Make CTL nicer to increased MAXPHYS.

Before this CTL always allocated MAXPHYS-sized buffers, even for 4KB I/O,
that is even more overkill for MAXPHYS of 1MB.  This change limits maximum
allocation to 512KB if MAXPHYS is bigger, plus if one is above 128KB, adds
new 128KB UMA zone for smaller I/Os.  The patch factors out alloc/free,
so later we could make it use more zones or malloc() if we'd like.

MFC after:	1 week
Sponsored by:	iXsystems, Inc.
This commit is contained in:
Alexander Motin 2020-11-11 21:59:39 +00:00
parent 755341df4f
commit 8054320e07
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=367600

View File

@ -102,7 +102,7 @@ __FBSDID("$FreeBSD$");
*/
#define CTLBLK_HALF_IO_SIZE (512 * 1024)
#define CTLBLK_MAX_IO_SIZE (CTLBLK_HALF_IO_SIZE * 2)
#define CTLBLK_MAX_SEG MAXPHYS
#define CTLBLK_MAX_SEG MIN(CTLBLK_HALF_IO_SIZE, MAXPHYS)
#define CTLBLK_HALF_SEGS MAX(CTLBLK_HALF_IO_SIZE / CTLBLK_MAX_SEG, 1)
#define CTLBLK_MAX_SEGS (CTLBLK_HALF_SEGS * 2)
@ -190,6 +190,9 @@ struct ctl_be_block_softc {
SLIST_HEAD(, ctl_be_block_lun) lun_list;
uma_zone_t beio_zone;
uma_zone_t buf_zone;
#if (CTLBLK_MAX_SEG > 131072)
uma_zone_t buf128_zone;
#endif
};
static struct ctl_be_block_softc backend_block_softc;
@ -299,6 +302,32 @@ static struct ctl_backend_driver ctl_be_block_driver =
MALLOC_DEFINE(M_CTLBLK, "ctlblock", "Memory used for CTL block backend");
CTL_BACKEND_DECLARE(cbb, ctl_be_block_driver);
static void
ctl_alloc_seg(struct ctl_be_block_softc *softc, struct ctl_sg_entry *sg,
size_t len)
{
#if (CTLBLK_MAX_SEG > 131072)
if (len <= 131072)
sg->addr = uma_zalloc(softc->buf128_zone, M_WAITOK);
else
#endif
sg->addr = uma_zalloc(softc->buf_zone, M_WAITOK);
sg->len = len;
}
static void
ctl_free_seg(struct ctl_be_block_softc *softc, struct ctl_sg_entry *sg)
{
#if (CTLBLK_MAX_SEG > 131072)
if (sg->len <= 131072)
uma_zfree(softc->buf128_zone, sg->addr);
else
#endif
uma_zfree(softc->buf_zone, sg->addr);
}
static struct ctl_be_block_io *
ctl_alloc_beio(struct ctl_be_block_softc *softc)
{
@ -317,12 +346,12 @@ ctl_real_free_beio(struct ctl_be_block_io *beio)
int i;
for (i = 0; i < beio->num_segs; i++) {
uma_zfree(softc->buf_zone, beio->sg_segs[i].addr);
ctl_free_seg(softc, &beio->sg_segs[i]);
/* For compare we had two equal S/G lists. */
if (beio->two_sglists) {
uma_zfree(softc->buf_zone,
beio->sg_segs[i + CTLBLK_HALF_SEGS].addr);
ctl_free_seg(softc,
&beio->sg_segs[i + CTLBLK_HALF_SEGS]);
}
}
@ -1140,8 +1169,7 @@ ctl_be_block_dispatch_dev(struct ctl_be_block_lun *be_lun,
/*
* We have to limit our I/O size to the maximum supported by the
* backend device. Hopefully it is MAXPHYS. If the driver doesn't
* set it properly, use DFLTPHYS.
* backend device.
*/
if (csw) {
max_iosize = dev->si_iosize_max;
@ -1330,8 +1358,7 @@ ctl_be_block_cw_dispatch_ws(struct ctl_be_block_lun *be_lun,
seglen -= seglen % cbe_lun->blocksize;
} else
seglen -= seglen % cbe_lun->blocksize;
beio->sg_segs[i].len = seglen;
beio->sg_segs[i].addr = uma_zalloc(softc->buf_zone, M_WAITOK);
ctl_alloc_seg(softc, &beio->sg_segs[i], seglen);
DPRINTF("segment %d addr %p len %zd\n", i,
beio->sg_segs[i].addr, beio->sg_segs[i].len);
@ -1603,18 +1630,17 @@ ctl_be_block_dispatch(struct ctl_be_block_lun *be_lun,
/*
* Setup the S/G entry for this chunk.
*/
beio->sg_segs[i].len = min(CTLBLK_MAX_SEG, len_left);
beio->sg_segs[i].addr = uma_zalloc(softc->buf_zone, M_WAITOK);
ctl_alloc_seg(softc, &beio->sg_segs[i],
min(CTLBLK_MAX_SEG, len_left));
DPRINTF("segment %d addr %p len %zd\n", i,
beio->sg_segs[i].addr, beio->sg_segs[i].len);
/* Set up second segment for compare operation. */
if (beio->two_sglists) {
beio->sg_segs[i + CTLBLK_HALF_SEGS].len =
beio->sg_segs[i].len;
beio->sg_segs[i + CTLBLK_HALF_SEGS].addr =
uma_zalloc(softc->buf_zone, M_WAITOK);
ctl_alloc_seg(softc,
&beio->sg_segs[i + CTLBLK_HALF_SEGS],
beio->sg_segs[i].len);
}
beio->num_segs++;
@ -1932,8 +1958,8 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
maxio = dev->si_iosize_max;
if (maxio <= 0)
maxio = DFLTPHYS;
if (maxio > CTLBLK_MAX_IO_SIZE)
maxio = CTLBLK_MAX_IO_SIZE;
if (maxio > CTLBLK_MAX_SEG)
maxio = CTLBLK_MAX_SEG;
}
be_lun->lun_flush = ctl_be_block_flush_dev;
be_lun->getattr = ctl_be_block_getattr_dev;
@ -2778,6 +2804,10 @@ ctl_be_block_init(void)
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
softc->buf_zone = uma_zcreate("ctlblock", CTLBLK_MAX_SEG,
NULL, NULL, NULL, NULL, /*align*/ 0, /*flags*/0);
#if (CTLBLK_MAX_SEG > 131072)
softc->buf128_zone = uma_zcreate("ctlblock128", 131072,
NULL, NULL, NULL, NULL, /*align*/ 0, /*flags*/0);
#endif
SLIST_INIT(&softc->lun_list);
return (0);
}
@ -2803,6 +2833,9 @@ ctl_be_block_shutdown(void)
}
mtx_unlock(&softc->lock);
uma_zdestroy(softc->buf_zone);
#if (CTLBLK_MAX_SEG > 131072)
uma_zdestroy(softc->buf128_zone);
#endif
uma_zdestroy(softc->beio_zone);
mtx_destroy(&softc->lock);
sx_destroy(&softc->modify_lock);