diff --git a/include/spdk_internal/bdev.h b/include/spdk_internal/bdev.h index 24ef39d6c..b95c82949 100644 --- a/include/spdk_internal/bdev.h +++ b/include/spdk_internal/bdev.h @@ -251,6 +251,9 @@ struct spdk_bdev_io { /** bdev allocated memory associated with this request */ void *buf; + /** requested size of the buffer associated with this I/O */ + uint64_t buf_len; + /** Callback for when buf is allocated */ spdk_bdev_io_get_buf_cb get_buf_cb; @@ -367,7 +370,20 @@ void spdk_bdev_poller_start(struct spdk_bdev_poller **ppoller, void spdk_bdev_poller_stop(struct spdk_bdev_poller **ppoller); -void spdk_bdev_io_get_buf(struct spdk_bdev_io *bdev_io, spdk_bdev_io_get_buf_cb cb); +/** + * Allocate a buffer for given bdev_io. Allocation will happen + * only if the bdev_io has no assigned SGL yet. The buffer will be + * freed automatically on \c spdk_bdev_free_io() call. This call + * will never fail - in case of lack of memory given callback \c cb + * will be deferred until enough memory is freed. + * + * \param bdev_io I/O to allocate buffer for. + * \param cb callback to be called when the buffer is allocated + * or the bdev_io has an SGL assigned already. + * \param len size of the buffer to allocate. + */ +void spdk_bdev_io_get_buf(struct spdk_bdev_io *bdev_io, spdk_bdev_io_get_buf_cb cb, uint64_t len); + struct spdk_bdev_io *spdk_bdev_get_io(void); void spdk_bdev_io_complete(struct spdk_bdev_io *bdev_io, enum spdk_bdev_io_status status); diff --git a/lib/bdev/aio/bdev_aio.c b/lib/bdev/aio/bdev_aio.c index e9b8d93d0..96f53abad 100644 --- a/lib/bdev/aio/bdev_aio.c +++ b/lib/bdev/aio/bdev_aio.c @@ -244,7 +244,8 @@ static int _bdev_aio_submit_request(struct spdk_io_channel *ch, struct spdk_bdev { switch (bdev_io->type) { case SPDK_BDEV_IO_TYPE_READ: - spdk_bdev_io_get_buf(bdev_io, bdev_aio_get_buf_cb); + spdk_bdev_io_get_buf(bdev_io, bdev_aio_get_buf_cb, + bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen); return 0; case SPDK_BDEV_IO_TYPE_WRITE: diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index 303e2aaea..eec49c7e5 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -230,7 +230,7 @@ spdk_bdev_io_set_buf(struct spdk_bdev_io *bdev_io, void *buf) bdev_io->buf = buf; bdev_io->u.bdev.iovs[0].iov_base = (void *)((unsigned long)((char *)buf + 512) & ~511UL); - bdev_io->u.bdev.iovs[0].iov_len = bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen; + bdev_io->u.bdev.iovs[0].iov_len = bdev_io->buf_len; bdev_io->get_buf_cb(bdev_io->ch->channel, bdev_io); } @@ -241,17 +241,14 @@ spdk_bdev_io_put_buf(struct spdk_bdev_io *bdev_io) struct spdk_bdev_io *tmp; void *buf; bdev_io_tailq_t *tailq; - uint64_t length; struct spdk_bdev_mgmt_channel *ch; assert(bdev_io->u.bdev.iovcnt == 1); - length = bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen; buf = bdev_io->buf; - ch = spdk_io_channel_get_ctx(bdev_io->ch->mgmt_channel); - if (length <= SPDK_BDEV_SMALL_BUF_MAX_SIZE) { + if (bdev_io->buf_len <= SPDK_BDEV_SMALL_BUF_MAX_SIZE) { pool = g_bdev_mgr.buf_small_pool; tailq = &ch->need_buf_small; } else { @@ -269,9 +266,8 @@ spdk_bdev_io_put_buf(struct spdk_bdev_io *bdev_io) } void -spdk_bdev_io_get_buf(struct spdk_bdev_io *bdev_io, spdk_bdev_io_get_buf_cb cb) +spdk_bdev_io_get_buf(struct spdk_bdev_io *bdev_io, spdk_bdev_io_get_buf_cb cb, uint64_t len) { - uint64_t len = bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen; struct spdk_mempool *pool; bdev_io_tailq_t *tailq; void *buf = NULL; @@ -288,6 +284,7 @@ spdk_bdev_io_get_buf(struct spdk_bdev_io *bdev_io, spdk_bdev_io_get_buf_cb cb) ch = spdk_io_channel_get_ctx(bdev_io->ch->mgmt_channel); + bdev_io->buf_len = len; bdev_io->get_buf_cb = cb; if (len <= SPDK_BDEV_SMALL_BUF_MAX_SIZE) { pool = g_bdev_mgr.buf_small_pool; diff --git a/lib/bdev/lvol/vbdev_lvol.c b/lib/bdev/lvol/vbdev_lvol.c index c22f94bd3..911a9104d 100644 --- a/lib/bdev/lvol/vbdev_lvol.c +++ b/lib/bdev/lvol/vbdev_lvol.c @@ -386,7 +386,8 @@ vbdev_lvol_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_ switch (bdev_io->type) { case SPDK_BDEV_IO_TYPE_READ: - spdk_bdev_io_get_buf(bdev_io, lvol_read); + spdk_bdev_io_get_buf(bdev_io, lvol_read, + bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen); break; case SPDK_BDEV_IO_TYPE_WRITE: lvol_write(lvol, ch, bdev_io); diff --git a/lib/bdev/nvme/bdev_nvme.c b/lib/bdev/nvme/bdev_nvme.c index adb0bb1eb..7edde71a9 100644 --- a/lib/bdev/nvme/bdev_nvme.c +++ b/lib/bdev/nvme/bdev_nvme.c @@ -363,7 +363,8 @@ _bdev_nvme_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_ switch (bdev_io->type) { case SPDK_BDEV_IO_TYPE_READ: - spdk_bdev_io_get_buf(bdev_io, bdev_nvme_get_buf_cb); + spdk_bdev_io_get_buf(bdev_io, bdev_nvme_get_buf_cb, + bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen); return 0; case SPDK_BDEV_IO_TYPE_WRITE: diff --git a/lib/bdev/rbd/bdev_rbd.c b/lib/bdev/rbd/bdev_rbd.c index 0b56e8831..1583a094b 100644 --- a/lib/bdev/rbd/bdev_rbd.c +++ b/lib/bdev/rbd/bdev_rbd.c @@ -272,7 +272,8 @@ static int _bdev_rbd_submit_request(struct spdk_io_channel *ch, struct spdk_bdev { switch (bdev_io->type) { case SPDK_BDEV_IO_TYPE_READ: - spdk_bdev_io_get_buf(bdev_io, bdev_rbd_get_buf_cb); + spdk_bdev_io_get_buf(bdev_io, bdev_rbd_get_buf_cb, + bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen); return 0; case SPDK_BDEV_IO_TYPE_WRITE: diff --git a/lib/bdev/virtio/bdev_virtio.c b/lib/bdev/virtio/bdev_virtio.c index 480cafca7..06d8c89c0 100644 --- a/lib/bdev/virtio/bdev_virtio.c +++ b/lib/bdev/virtio/bdev_virtio.c @@ -155,7 +155,8 @@ static int _bdev_virtio_submit_request(struct spdk_io_channel *ch, struct spdk_b { switch (bdev_io->type) { case SPDK_BDEV_IO_TYPE_READ: - spdk_bdev_io_get_buf(bdev_io, bdev_virtio_rw); + spdk_bdev_io_get_buf(bdev_io, bdev_virtio_rw, + bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen); return 0; case SPDK_BDEV_IO_TYPE_WRITE: bdev_virtio_rw(ch, bdev_io); diff --git a/test/unit/lib/bdev/vbdev_lvol.c/vbdev_lvol_ut.c b/test/unit/lib/bdev/vbdev_lvol.c/vbdev_lvol_ut.c index 31caacd39..37e04bdc3 100644 --- a/test/unit/lib/bdev/vbdev_lvol.c/vbdev_lvol_ut.c +++ b/test/unit/lib/bdev/vbdev_lvol.c/vbdev_lvol_ut.c @@ -198,7 +198,7 @@ struct spdk_io_channel *spdk_lvol_get_io_channel(struct spdk_lvol *lvol) } void -spdk_bdev_io_get_buf(struct spdk_bdev_io *bdev_io, spdk_bdev_io_get_buf_cb cb) +spdk_bdev_io_get_buf(struct spdk_bdev_io *bdev_io, spdk_bdev_io_get_buf_cb cb, uint64_t len) { }