bdev: track IOs doing memory domain pull/push
Similarly to requests executed by accel, we need to track bdev_ios that have their data pushed/pulled. Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com> Change-Id: Ie6b0d2c058e9f13916a065acf8e05d1484eae535 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/16978 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Community-CI: Mellanox Build Bot Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
This commit is contained in:
parent
2326924683
commit
000b9697e7
@ -977,7 +977,8 @@ struct spdk_bdev_io {
|
|||||||
* 1. IOs awaiting retry due to NOMEM status,
|
* 1. IOs awaiting retry due to NOMEM status,
|
||||||
* 2. IOs awaiting submission due to QoS,
|
* 2. IOs awaiting submission due to QoS,
|
||||||
* 3. IOs with an accel sequence being executed,
|
* 3. IOs with an accel sequence being executed,
|
||||||
* 4. queued reset requests.
|
* 4. IOs awaiting memory domain pull/push,
|
||||||
|
* 5. queued reset requests.
|
||||||
*/
|
*/
|
||||||
TAILQ_ENTRY(spdk_bdev_io) link;
|
TAILQ_ENTRY(spdk_bdev_io) link;
|
||||||
|
|
||||||
|
@ -292,6 +292,9 @@ struct spdk_bdev_channel {
|
|||||||
/* List of I/Os with accel sequence being currently executed */
|
/* List of I/Os with accel sequence being currently executed */
|
||||||
bdev_io_tailq_t io_accel_exec;
|
bdev_io_tailq_t io_accel_exec;
|
||||||
|
|
||||||
|
/* List of I/Os doing memory domain pull/push */
|
||||||
|
bdev_io_tailq_t io_memory_domain;
|
||||||
|
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
|
||||||
struct spdk_histogram_data *histogram;
|
struct spdk_histogram_data *histogram;
|
||||||
@ -1396,9 +1399,20 @@ _bdev_io_complete_push_bounce_done(void *ctx, int rc)
|
|||||||
bdev_io_complete(bdev_io);
|
bdev_io_complete(bdev_io);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_bdev_io_push_bounce_md_buffer_done(void *ctx, int rc)
|
||||||
|
{
|
||||||
|
struct spdk_bdev_io *bdev_io = ctx;
|
||||||
|
struct spdk_bdev_channel *ch = bdev_io->internal.ch;
|
||||||
|
|
||||||
|
TAILQ_REMOVE(&ch->io_memory_domain, bdev_io, internal.link);
|
||||||
|
bdev_io->internal.data_transfer_cpl(bdev_io, rc);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
_bdev_io_push_bounce_md_buffer(struct spdk_bdev_io *bdev_io)
|
_bdev_io_push_bounce_md_buffer(struct spdk_bdev_io *bdev_io)
|
||||||
{
|
{
|
||||||
|
struct spdk_bdev_channel *ch = bdev_io->internal.ch;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
/* do the same for metadata buffer */
|
/* do the same for metadata buffer */
|
||||||
@ -1408,18 +1422,20 @@ _bdev_io_push_bounce_md_buffer(struct spdk_bdev_io *bdev_io)
|
|||||||
if (bdev_io->type == SPDK_BDEV_IO_TYPE_READ &&
|
if (bdev_io->type == SPDK_BDEV_IO_TYPE_READ &&
|
||||||
bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS) {
|
bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS) {
|
||||||
if (bdev_io_use_memory_domain(bdev_io)) {
|
if (bdev_io_use_memory_domain(bdev_io)) {
|
||||||
|
TAILQ_INSERT_TAIL(&ch->io_memory_domain, bdev_io, internal.link);
|
||||||
/* If memory domain is used then we need to call async push function */
|
/* If memory domain is used then we need to call async push function */
|
||||||
rc = spdk_memory_domain_push_data(bdev_io->internal.memory_domain,
|
rc = spdk_memory_domain_push_data(bdev_io->internal.memory_domain,
|
||||||
bdev_io->internal.memory_domain_ctx,
|
bdev_io->internal.memory_domain_ctx,
|
||||||
&bdev_io->internal.orig_md_iov,
|
&bdev_io->internal.orig_md_iov,
|
||||||
(uint32_t)bdev_io->internal.orig_iovcnt,
|
(uint32_t)bdev_io->internal.orig_iovcnt,
|
||||||
&bdev_io->internal.bounce_md_iov, 1,
|
&bdev_io->internal.bounce_md_iov, 1,
|
||||||
bdev_io->internal.data_transfer_cpl,
|
_bdev_io_push_bounce_md_buffer_done,
|
||||||
bdev_io);
|
bdev_io);
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
/* Continue IO completion in async callback */
|
/* Continue IO completion in async callback */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
TAILQ_REMOVE(&ch->io_memory_domain, bdev_io, internal.link);
|
||||||
SPDK_ERRLOG("Failed to push md to memory domain %s\n",
|
SPDK_ERRLOG("Failed to push md to memory domain %s\n",
|
||||||
spdk_memory_domain_get_dma_device_id(bdev_io->internal.memory_domain));
|
spdk_memory_domain_get_dma_device_id(bdev_io->internal.memory_domain));
|
||||||
} else {
|
} else {
|
||||||
@ -1437,8 +1453,10 @@ static void
|
|||||||
_bdev_io_push_bounce_data_buffer_done(void *ctx, int rc)
|
_bdev_io_push_bounce_data_buffer_done(void *ctx, int rc)
|
||||||
{
|
{
|
||||||
struct spdk_bdev_io *bdev_io = ctx;
|
struct spdk_bdev_io *bdev_io = ctx;
|
||||||
|
struct spdk_bdev_channel *ch = bdev_io->internal.ch;
|
||||||
|
|
||||||
assert(bdev_io->internal.data_transfer_cpl);
|
assert(bdev_io->internal.data_transfer_cpl);
|
||||||
|
TAILQ_REMOVE(&ch->io_memory_domain, bdev_io, internal.link);
|
||||||
|
|
||||||
if (rc) {
|
if (rc) {
|
||||||
bdev_io->internal.data_transfer_cpl(bdev_io, rc);
|
bdev_io->internal.data_transfer_cpl(bdev_io, rc);
|
||||||
@ -1458,8 +1476,10 @@ _bdev_io_push_bounce_data_buffer_done(void *ctx, int rc)
|
|||||||
static inline void
|
static inline void
|
||||||
_bdev_io_push_bounce_data_buffer(struct spdk_bdev_io *bdev_io, bdev_copy_bounce_buffer_cpl cpl_cb)
|
_bdev_io_push_bounce_data_buffer(struct spdk_bdev_io *bdev_io, bdev_copy_bounce_buffer_cpl cpl_cb)
|
||||||
{
|
{
|
||||||
|
struct spdk_bdev_channel *ch = bdev_io->internal.ch;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
|
TAILQ_INSERT_TAIL(&ch->io_memory_domain, bdev_io, internal.link);
|
||||||
bdev_io->internal.data_transfer_cpl = cpl_cb;
|
bdev_io->internal.data_transfer_cpl = cpl_cb;
|
||||||
|
|
||||||
/* if this is read path, copy data from bounce buffer to original buffer */
|
/* if this is read path, copy data from bounce buffer to original buffer */
|
||||||
@ -1550,6 +1570,10 @@ static void
|
|||||||
_bdev_memory_domain_get_io_cb(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io,
|
_bdev_memory_domain_get_io_cb(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io,
|
||||||
bool success)
|
bool success)
|
||||||
{
|
{
|
||||||
|
struct spdk_bdev_channel *bdev_ch = bdev_io->internal.ch;
|
||||||
|
|
||||||
|
TAILQ_REMOVE(&bdev_ch->io_memory_domain, bdev_io, internal.link);
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
SPDK_ERRLOG("Failed to get data buffer, completing IO\n");
|
SPDK_ERRLOG("Failed to get data buffer, completing IO\n");
|
||||||
bdev_io->internal.status = SPDK_BDEV_IO_STATUS_FAILED;
|
bdev_io->internal.status = SPDK_BDEV_IO_STATUS_FAILED;
|
||||||
@ -3266,6 +3290,8 @@ bdev_io_submit(struct spdk_bdev_io *bdev_io)
|
|||||||
static inline void
|
static inline void
|
||||||
_bdev_io_ext_use_bounce_buffer(struct spdk_bdev_io *bdev_io)
|
_bdev_io_ext_use_bounce_buffer(struct spdk_bdev_io *bdev_io)
|
||||||
{
|
{
|
||||||
|
struct spdk_bdev_channel *ch = bdev_io->internal.ch;
|
||||||
|
|
||||||
/* bdev doesn't support memory domains, thereby buffers in this IO request can't
|
/* bdev doesn't support memory domains, thereby buffers in this IO request can't
|
||||||
* be accessed directly. It is needed to allocate buffers before issuing IO operation.
|
* be accessed directly. It is needed to allocate buffers before issuing IO operation.
|
||||||
* For write operation we need to pull buffers from memory domain before submitting IO.
|
* For write operation we need to pull buffers from memory domain before submitting IO.
|
||||||
@ -3274,6 +3300,7 @@ _bdev_io_ext_use_bounce_buffer(struct spdk_bdev_io *bdev_io)
|
|||||||
* This IO request will go through a regular IO flow, so clear memory domains pointers */
|
* This IO request will go through a regular IO flow, so clear memory domains pointers */
|
||||||
bdev_io->u.bdev.memory_domain = NULL;
|
bdev_io->u.bdev.memory_domain = NULL;
|
||||||
bdev_io->u.bdev.memory_domain_ctx = NULL;
|
bdev_io->u.bdev.memory_domain_ctx = NULL;
|
||||||
|
TAILQ_INSERT_TAIL(&ch->io_memory_domain, bdev_io, internal.link);
|
||||||
_bdev_memory_domain_io_get_buf(bdev_io, _bdev_memory_domain_get_io_cb,
|
_bdev_memory_domain_io_get_buf(bdev_io, _bdev_memory_domain_get_io_cb,
|
||||||
bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen);
|
bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen);
|
||||||
}
|
}
|
||||||
@ -3478,6 +3505,7 @@ bdev_channel_destroy_resource(struct spdk_bdev_channel *ch)
|
|||||||
assert(TAILQ_EMPTY(&ch->io_locked));
|
assert(TAILQ_EMPTY(&ch->io_locked));
|
||||||
assert(TAILQ_EMPTY(&ch->io_submitted));
|
assert(TAILQ_EMPTY(&ch->io_submitted));
|
||||||
assert(TAILQ_EMPTY(&ch->io_accel_exec));
|
assert(TAILQ_EMPTY(&ch->io_accel_exec));
|
||||||
|
assert(TAILQ_EMPTY(&ch->io_memory_domain));
|
||||||
assert(ch->io_outstanding == 0);
|
assert(ch->io_outstanding == 0);
|
||||||
assert(shared_resource->ref > 0);
|
assert(shared_resource->ref > 0);
|
||||||
shared_resource->ref--;
|
shared_resource->ref--;
|
||||||
@ -3750,6 +3778,7 @@ bdev_channel_create(void *io_device, void *ctx_buf)
|
|||||||
TAILQ_INIT(&ch->io_submitted);
|
TAILQ_INIT(&ch->io_submitted);
|
||||||
TAILQ_INIT(&ch->io_locked);
|
TAILQ_INIT(&ch->io_locked);
|
||||||
TAILQ_INIT(&ch->io_accel_exec);
|
TAILQ_INIT(&ch->io_accel_exec);
|
||||||
|
TAILQ_INIT(&ch->io_memory_domain);
|
||||||
|
|
||||||
ch->stat = bdev_alloc_io_stat(false);
|
ch->stat = bdev_alloc_io_stat(false);
|
||||||
if (ch->stat == NULL) {
|
if (ch->stat == NULL) {
|
||||||
|
Loading…
Reference in New Issue
Block a user