summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/uts/common/io/blkdev/blkdev.c1
-rw-r--r--usr/src/uts/common/io/vioblk/vioblk.c95
2 files changed, 46 insertions, 50 deletions
diff --git a/usr/src/uts/common/io/blkdev/blkdev.c b/usr/src/uts/common/io/blkdev/blkdev.c
index 0c4616c16d..b2aceb1c34 100644
--- a/usr/src/uts/common/io/blkdev/blkdev.c
+++ b/usr/src/uts/common/io/blkdev/blkdev.c
@@ -2016,6 +2016,7 @@ bd_free_space_cb(dkioc_free_list_t *dfl, void *arg)
return (0);
}
+ xi->i_flags |= BD_XFER_POLL;
bd_submit(bd, xi);
(void) biowait(bp);
diff --git a/usr/src/uts/common/io/vioblk/vioblk.c b/usr/src/uts/common/io/vioblk/vioblk.c
index 1271796c62..71a47a2886 100644
--- a/usr/src/uts/common/io/vioblk/vioblk.c
+++ b/usr/src/uts/common/io/vioblk/vioblk.c
@@ -375,6 +375,45 @@ out:
}
static int
+vioblk_map_discard(vioblk_t *vib, virtio_chain_t *vic, const bd_xfer_t *xfer)
+{
+ const dkioc_free_list_t *dfl = xfer->x_dfl;
+ const dkioc_free_list_ext_t *exts = dfl->dfl_exts;
+ virtio_dma_t *dma = NULL;
+ struct vioblk_discard_write_zeroes *wzp = NULL;
+
+ dma = virtio_dma_alloc(vib->vib_virtio,
+ dfl->dfl_num_exts * sizeof (*wzp), &vioblk_dma_attr,
+ DDI_DMA_CONSISTENT | DDI_DMA_WRITE, KM_SLEEP);
+ if (dma == NULL)
+ return (ENOMEM);
+
+ wzp = virtio_dma_va(dma, 0);
+
+ for (size_t i = 0; i < dfl->dfl_num_exts; i++, exts++, wzp++) {
+ uint64_t start = dfl->dfl_offset + exts->dfle_start;
+
+ struct vioblk_discard_write_zeroes vdwz = {
+ .vdwz_sector = start >> DEV_BSHIFT,
+ .vdwz_num_sectors = exts->dfle_length >> DEV_BSHIFT,
+ .vdwz_flags = 0
+ };
+
+ bcopy(&vdwz, wzp, sizeof (*wzp));
+ }
+
+ if (virtio_chain_append(vic,
+ virtio_dma_cookie_pa(dma, 0),
+ virtio_dma_cookie_size(dma, 0),
+ VIRTIO_DIR_DEVICE_READS) != DDI_SUCCESS) {
+ virtio_dma_free(dma);
+ return (ENOMEM);
+ }
+
+ return (0);
+}
+
+static int
vioblk_request(vioblk_t *vib, bd_xfer_t *xfer, int type)
{
virtio_chain_t *vic = NULL;
@@ -437,6 +476,11 @@ vioblk_request(vioblk_t *vib, bd_xfer_t *xfer, int type)
dev_err(vib->vib_dip, CE_PANIC,
"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);
+ if (r != 0) {
+ goto fail;
+ }
}
if (vib->vib_stats->vbs_rw_cookiesmax.value.ui32 < total_cookies) {
@@ -624,60 +668,11 @@ vioblk_bd_devid(void *arg, dev_info_t *dip, ddi_devid_t *devid)
static int
vioblk_bd_free_space(void *arg, bd_xfer_t *xfer)
{
- const dkioc_free_list_t *dfl = xfer->x_dfl;
- const dkioc_free_list_ext_t *exts = dfl->dfl_exts;
vioblk_t *vib = arg;
- virtio_dma_t *dma = NULL;
- virtio_chain_t *vic = NULL;
- vioblk_req_t *vbr = NULL;
- struct vioblk_discard_write_zeroes *wzp = NULL;
int r = 0;
- boolean_t polled = DFL_ISSYNC(dfl) ? B_TRUE : B_FALSE;
-
- /* XXX: This seems like it could be folded into vioblk_request() */
-
- dma = virtio_dma_alloc(vib->vib_virtio,
- dfl->dfl_num_exts * sizeof (*wzp), &vioblk_dma_attr,
- DDI_DMA_CONSISTENT | DDI_DMA_WRITE, KM_SLEEP);
- if (dma == NULL)
- return (ENOMEM);
-
- wzp = virtio_dma_va(dma, 0);
-
- for (size_t i = 0; i < dfl->dfl_num_exts; i++, exts++, wzp++) {
- uint64_t start = dfl->dfl_offset + exts->dfle_start;
-
- struct vioblk_discard_write_zeroes vdwz = {
- .vdwz_sector = start >> DEV_BSHIFT,
- .vdwz_num_sectors = exts->dfle_length >> DEV_BSHIFT,
- .vdwz_flags = 0
- };
-
- bcopy(&vdwz, wzp, sizeof (*wzp));
- }
mutex_enter(&vib->vib_mutex);
-
- vic = vioblk_common_start(vib, VIRTIO_BLK_T_DISCARD, 0, polled);
- if (vic == NULL) {
- mutex_exit(&vib->vib_mutex);
- virtio_dma_free(dma);
- return (ENOMEM);
- }
-
- vbr = virtio_chain_data(vic);
- if (virtio_chain_append(vic,
- virtio_dma_cookie_pa(dma, 0),
- virtio_dma_cookie_size(dma, 0),
- VIRTIO_DIR_DEVICE_READS) != DDI_SUCCESS) {
- vioblk_req_free(vib, vbr);
- virtio_chain_free(vic);
- mutex_exit(&vib->vib_mutex);
- return (ENOMEM);
- }
-
- vbr->vbr_xfer = xfer;
- r = vioblk_common_submit(vib, vic);
+ r = vioblk_request(vib, xfer, VIRTIO_BLK_T_DISCARD);
mutex_exit(&vib->vib_mutex);
return (r);