Mercurial > illumos > git > illumos-joyent
changeset 25199:296594ec0d43
12511 vioblk should preallocate virtio chains
Reviewed by: Jason King <jason.king@joyent.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Andy Fiddaman <andy@omniosce.org>
Approved by: Joshua M. Clulow <josh@sysmgr.org>
author | Patrick Mooney <pmooney@pfmooney.com> |
---|---|
date | Thu, 09 Jul 2020 20:43:07 +0000 |
parents | 8e4d3d596404 |
children | 6963fbd5fdc7 |
files | usr/src/uts/common/io/vioblk/vioblk.c usr/src/uts/common/io/vioblk/vioblk.h |
diffstat | 2 files changed, 37 insertions(+), 55 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/io/vioblk/vioblk.c Wed Jul 01 20:39:55 2020 +0000 +++ b/usr/src/uts/common/io/vioblk/vioblk.c Thu Jul 09 20:43:07 2020 +0000 @@ -24,6 +24,7 @@ * Copyright (c) 2012, Alexey Zaytsev <alexey.zaytsev@gmail.com> * Copyright 2020 Joyent Inc. * Copyright 2019 Western Digital Corporation. + * Copyright 2020 Oxide Computer Company */ /* @@ -163,6 +164,7 @@ VERIFY0(vbr->vbr_status); vbr->vbr_status |= VIOBLK_REQSTAT_ALLOCATED; + VERIFY3P(vbr->vbr_chain, !=, NULL); VERIFY3P(vbr->vbr_xfer, ==, NULL); VERIFY3S(vbr->vbr_error, ==, 0); @@ -184,6 +186,7 @@ vbr->vbr_xfer = NULL; vbr->vbr_error = 0; vbr->vbr_type = 0; + virtio_chain_clear(vbr->vbr_chain); list_insert_head(&vib->vib_reqs, vbr); @@ -214,12 +217,11 @@ } } -static virtio_chain_t * +static vioblk_req_t * vioblk_common_start(vioblk_t *vib, int type, uint64_t sector, boolean_t polled) { vioblk_req_t *vbr = NULL; - virtio_chain_t *vic = NULL; if ((vbr = vioblk_req_alloc(vib)) == NULL) { vib->vib_stats->vbs_rw_outofmemory.value.ui64++; @@ -235,45 +237,32 @@ vbr->vbr_status |= VIOBLK_REQSTAT_POLLED; } - if ((vic = virtio_chain_alloc(vib->vib_vq, KM_NOSLEEP)) == NULL) { - vib->vib_stats->vbs_rw_outofmemory.value.ui64++; - goto fail; - } - struct vioblk_req_hdr vbh; vbh.vbh_type = type; vbh.vbh_ioprio = 0; vbh.vbh_sector = (sector * vib->vib_blk_size) / DEV_BSIZE; bcopy(&vbh, virtio_dma_va(vbr->vbr_dma, 0), sizeof (vbh)); - virtio_chain_data_set(vic, vbr); - /* * Put the header in the first descriptor. See the block comment at * the top of the file for more details on the chain layout. */ - if (virtio_chain_append(vic, virtio_dma_cookie_pa(vbr->vbr_dma, 0), + if (virtio_chain_append(vbr->vbr_chain, + virtio_dma_cookie_pa(vbr->vbr_dma, 0), sizeof (struct vioblk_req_hdr), VIRTIO_DIR_DEVICE_READS) != DDI_SUCCESS) { - goto fail; + vioblk_req_free(vib, vbr); + return (NULL); } - return (vic); - -fail: - vbr->vbr_xfer = NULL; - vioblk_req_free(vib, vbr); - if (vic != NULL) { - virtio_chain_free(vic); - } - return (NULL); + return (vbr); } static int -vioblk_common_submit(vioblk_t *vib, virtio_chain_t *vic) +vioblk_common_submit(vioblk_t *vib, vioblk_req_t *vbr) { + virtio_chain_t *vic = vbr->vbr_chain; int r; - vioblk_req_t *vbr = virtio_chain_data(vic); VERIFY(MUTEX_HELD(&vib->vib_mutex)); @@ -285,8 +274,8 @@ if (virtio_chain_append(vic, virtio_dma_cookie_pa(vbr->vbr_dma, 0) + sizeof (struct vioblk_req_hdr), sizeof (uint8_t), VIRTIO_DIR_DEVICE_WRITES) != DDI_SUCCESS) { - r = ENOMEM; - goto out; + vioblk_req_free(vib, vbr); + return (ENOMEM); } virtio_dma_sync(vbr->vbr_dma, DDI_DMA_SYNC_FORDEV); @@ -324,10 +313,7 @@ vioblk_complete(vib, vbr); r = vbr->vbr_error; - -out: vioblk_req_free(vib, vbr); - virtio_chain_free(vic); return (r); } @@ -335,19 +321,16 @@ vioblk_internal(vioblk_t *vib, int type, virtio_dma_t *dma, uint64_t sector, virtio_direction_t dir) { - virtio_chain_t *vic; vioblk_req_t *vbr; - int r; VERIFY(MUTEX_HELD(&vib->vib_mutex)); /* * Allocate a polled request. */ - if ((vic = vioblk_common_start(vib, type, sector, B_TRUE)) == NULL) { + if ((vbr = vioblk_common_start(vib, type, sector, B_TRUE)) == NULL) { return (ENOMEM); } - vbr = virtio_chain_data(vic); /* * If there is a request payload, it goes between the header and the @@ -355,23 +338,19 @@ * detail on the chain layout. */ if (dma != NULL) { + virtio_chain_t *vic = vbr->vbr_chain; for (uint_t n = 0; n < virtio_dma_ncookies(dma); n++) { if (virtio_chain_append(vic, virtio_dma_cookie_pa(dma, n), virtio_dma_cookie_size(dma, n), dir) != DDI_SUCCESS) { - r = ENOMEM; - goto out; + vioblk_req_free(vib, vbr); + return (ENOMEM); } } } - return (vioblk_common_submit(vib, vic)); - -out: - vioblk_req_free(vib, vbr); - virtio_chain_free(vic); - return (r); + return (vioblk_common_submit(vib, vbr)); } static int @@ -416,11 +395,9 @@ static int vioblk_request(vioblk_t *vib, bd_xfer_t *xfer, int type) { - virtio_chain_t *vic = NULL; vioblk_req_t *vbr = NULL; uint_t total_cookies = 2; boolean_t polled = (xfer->x_flags & BD_XFER_POLL) != 0; - int r; VERIFY(MUTEX_HELD(&vib->vib_mutex)); @@ -434,11 +411,10 @@ return (EINVAL); } - if ((vic = vioblk_common_start(vib, type, xfer->x_blkno, polled)) == + if ((vbr = vioblk_common_start(vib, type, xfer->x_blkno, polled)) == NULL) { return (ENOMEM); } - vbr = virtio_chain_data(vic); vbr->vbr_xfer = xfer; /* @@ -450,6 +426,7 @@ xfer->x_nblks > 0) { virtio_direction_t dir = (type == VIRTIO_BLK_T_OUT) ? VIRTIO_DIR_DEVICE_READS : VIRTIO_DIR_DEVICE_WRITES; + virtio_chain_t *vic = vbr->vbr_chain; for (uint_t n = 0; n < xfer->x_ndmac; n++) { ddi_dma_cookie_t dmac; @@ -465,8 +442,8 @@ if (virtio_chain_append(vic, dmac.dmac_laddress, dmac.dmac_size, dir) != DDI_SUCCESS) { - r = ENOMEM; - goto fail; + vioblk_req_free(vib, vbr); + return (ENOMEM); } } @@ -477,9 +454,10 @@ "request of type %d had payload length of %lu blocks", type, xfer->x_nblks); } else if (type == VIRTIO_BLK_T_DISCARD) { - r = vioblk_map_discard(vib, vic, xfer); + int r = vioblk_map_discard(vib, vbr->vbr_chain, xfer); if (r != 0) { - goto fail; + vioblk_req_free(vib, vbr); + return (r); } } @@ -487,13 +465,7 @@ vib->vib_stats->vbs_rw_cookiesmax.value.ui32 = total_cookies; } - return (vioblk_common_submit(vib, vic)); - -fail: - vbr->vbr_xfer = NULL; - vioblk_req_free(vib, vbr); - virtio_chain_free(vic); - return (r); + return (vioblk_common_submit(vib, vbr)); } static int @@ -753,7 +725,6 @@ vioblk_complete(vib, vbr); vioblk_req_free(vib, vbr); - virtio_chain_free(vic); } if (wakeup) { @@ -797,6 +768,10 @@ VERIFY0(vbr->vbr_status); + if (vbr->vbr_chain != NULL) { + virtio_chain_free(vbr->vbr_chain); + vbr->vbr_chain = NULL; + } if (vbr->vbr_dma != NULL) { virtio_dma_free(vbr->vbr_dma); vbr->vbr_dma = NULL; @@ -833,6 +808,11 @@ KM_SLEEP)) == NULL) { goto fail; } + vbr->vbr_chain = virtio_chain_alloc(vib->vib_vq, KM_SLEEP); + if (vbr->vbr_chain == NULL) { + goto fail; + } + virtio_chain_data_set(vbr->vbr_chain, vbr); } return (0);
--- a/usr/src/uts/common/io/vioblk/vioblk.h Wed Jul 01 20:39:55 2020 +0000 +++ b/usr/src/uts/common/io/vioblk/vioblk.h Thu Jul 09 20:43:07 2020 +0000 @@ -11,6 +11,7 @@ /* * Copyright 2019 Joyent, Inc. + * Copyright 2020 Oxide Computer Company */ /* @@ -193,6 +194,7 @@ int vbr_type; int vbr_error; virtio_dma_t *vbr_dma; + virtio_chain_t *vbr_chain; bd_xfer_t *vbr_xfer; list_node_t vbr_link; } vioblk_req_t;