bdev/aio: Poller handles inline channel deletion
Change the poller to tolerate channel deletion within an I/O completion callback. This won't happen today because channel deletion is always deferred, but prepare for that case. It turns out this is simpler anyway. Change-Id: Ibff23d84fe14247849e95cebc3c80369812bdd6c Signed-off-by: Ben Walker <benjamin.walker@intel.com> Reviewed-on: https://review.gerrithub.io/370525 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
parent
f6e62d2ce1
commit
12b53038f6
@ -46,6 +46,8 @@
|
|||||||
static int bdev_aio_initialize(void);
|
static int bdev_aio_initialize(void);
|
||||||
static void aio_free_disk(struct file_disk *fdisk);
|
static void aio_free_disk(struct file_disk *fdisk);
|
||||||
|
|
||||||
|
#define SPDK_AIO_QUEUE_DEPTH 128
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bdev_aio_get_ctx_size(void)
|
bdev_aio_get_ctx_size(void)
|
||||||
{
|
{
|
||||||
@ -170,19 +172,11 @@ bdev_aio_destruct(void *ctx)
|
|||||||
static int
|
static int
|
||||||
bdev_aio_initialize_io_channel(struct bdev_aio_io_channel *ch)
|
bdev_aio_initialize_io_channel(struct bdev_aio_io_channel *ch)
|
||||||
{
|
{
|
||||||
ch->queue_depth = 128;
|
if (io_setup(SPDK_AIO_QUEUE_DEPTH, &ch->io_ctx) < 0) {
|
||||||
|
|
||||||
if (io_setup(ch->queue_depth, &ch->io_ctx) < 0) {
|
|
||||||
SPDK_ERRLOG("async I/O context setup failure\n");
|
SPDK_ERRLOG("async I/O context setup failure\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ch->events = calloc(sizeof(struct io_event), ch->queue_depth);
|
|
||||||
if (!ch->events) {
|
|
||||||
io_destroy(ch->io_ctx);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,12 +188,13 @@ bdev_aio_poll(void *arg)
|
|||||||
enum spdk_bdev_io_status status;
|
enum spdk_bdev_io_status status;
|
||||||
struct bdev_aio_task *aio_task;
|
struct bdev_aio_task *aio_task;
|
||||||
struct timespec timeout;
|
struct timespec timeout;
|
||||||
|
struct io_event events[SPDK_AIO_QUEUE_DEPTH];
|
||||||
|
|
||||||
timeout.tv_sec = 0;
|
timeout.tv_sec = 0;
|
||||||
timeout.tv_nsec = 0;
|
timeout.tv_nsec = 0;
|
||||||
|
|
||||||
nr = io_getevents(ch->io_ctx, 1, ch->queue_depth,
|
nr = io_getevents(ch->io_ctx, 1, SPDK_AIO_QUEUE_DEPTH,
|
||||||
ch->events, &timeout);
|
events, &timeout);
|
||||||
|
|
||||||
if (nr < 0) {
|
if (nr < 0) {
|
||||||
SPDK_ERRLOG("%s: io_getevents returned %d\n", __func__, nr);
|
SPDK_ERRLOG("%s: io_getevents returned %d\n", __func__, nr);
|
||||||
@ -207,8 +202,8 @@ bdev_aio_poll(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < nr; i++) {
|
for (i = 0; i < nr; i++) {
|
||||||
aio_task = ch->events[i].data;
|
aio_task = events[i].data;
|
||||||
if (ch->events[i].res != aio_task->len) {
|
if (events[i].res != aio_task->len) {
|
||||||
status = SPDK_BDEV_IO_STATUS_FAILED;
|
status = SPDK_BDEV_IO_STATUS_FAILED;
|
||||||
} else {
|
} else {
|
||||||
status = SPDK_BDEV_IO_STATUS_SUCCESS;
|
status = SPDK_BDEV_IO_STATUS_SUCCESS;
|
||||||
@ -309,7 +304,6 @@ bdev_aio_destroy_cb(void *io_device, void *ctx_buf)
|
|||||||
struct bdev_aio_io_channel *io_channel = ctx_buf;
|
struct bdev_aio_io_channel *io_channel = ctx_buf;
|
||||||
|
|
||||||
io_destroy(io_channel->io_ctx);
|
io_destroy(io_channel->io_ctx);
|
||||||
free(io_channel->events);
|
|
||||||
spdk_bdev_poller_stop(&io_channel->poller);
|
spdk_bdev_poller_stop(&io_channel->poller);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,8 +51,6 @@ struct bdev_aio_task {
|
|||||||
|
|
||||||
struct bdev_aio_io_channel {
|
struct bdev_aio_io_channel {
|
||||||
io_context_t io_ctx;
|
io_context_t io_ctx;
|
||||||
long queue_depth;
|
|
||||||
struct io_event *events;
|
|
||||||
struct spdk_bdev_poller *poller;
|
struct spdk_bdev_poller *poller;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user