bdev/virtio: defer ctrlr removal if scan I/O is in progress
A public API to remove a virtio controller is about to be published soon. Hence, we need to cover all possible corner-cases where calling it could cause a segfault. Change-Id: I804cc0bee4a60ab8fc159bb98b7712cc258117f3 Signed-off-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com> Reviewed-on: https://review.gerrithub.io/392271 Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com> Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
8b0f049e85
commit
31177e645c
@ -695,8 +695,12 @@ bdev_virtio_poll(void *arg)
|
|||||||
|
|
||||||
cnt = virtio_recv_pkts(ch->vq, (void **)io, io_len, SPDK_COUNTOF(io));
|
cnt = virtio_recv_pkts(ch->vq, (void **)io, io_len, SPDK_COUNTOF(io));
|
||||||
for (i = 0; i < cnt; ++i) {
|
for (i = 0; i < cnt; ++i) {
|
||||||
if (spdk_unlikely(svdev->scan_ctx &&
|
if (spdk_unlikely(svdev->scan_ctx && io[i] == &svdev->scan_ctx->io_ctx)) {
|
||||||
io[i] == &svdev->scan_ctx->io_ctx)) {
|
if (svdev->removed) {
|
||||||
|
_virtio_scsi_dev_scan_finish(svdev->scan_ctx, -EINTR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
process_scan_resp(svdev->scan_ctx);
|
process_scan_resp(svdev->scan_ctx);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -704,7 +708,14 @@ bdev_virtio_poll(void *arg)
|
|||||||
bdev_virtio_io_cpl(io[i]);
|
bdev_virtio_io_cpl(io[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spdk_unlikely(cnt > 0 && svdev->scan_ctx && svdev->scan_ctx->needs_resend)) {
|
if (spdk_unlikely(svdev->scan_ctx && svdev->scan_ctx->needs_resend)) {
|
||||||
|
if (svdev->removed) {
|
||||||
|
_virtio_scsi_dev_scan_finish(svdev->scan_ctx, -EINTR);
|
||||||
|
return;
|
||||||
|
} else if (cnt == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
rc = send_scan_io(svdev->scan_ctx);
|
rc = send_scan_io(svdev->scan_ctx);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
assert(svdev->scan_ctx->retries > 0);
|
assert(svdev->scan_ctx->retries > 0);
|
||||||
@ -1553,7 +1564,6 @@ virtio_scsi_dev_unregister_cb(void *io_device)
|
|||||||
static void
|
static void
|
||||||
virtio_scsi_dev_remove(struct virtio_scsi_dev *svdev)
|
virtio_scsi_dev_remove(struct virtio_scsi_dev *svdev)
|
||||||
{
|
{
|
||||||
struct virtio_scsi_scan_base *scan_ctx;
|
|
||||||
struct virtio_scsi_disk *disk, *disk_tmp;
|
struct virtio_scsi_disk *disk, *disk_tmp;
|
||||||
bool do_remove = true;
|
bool do_remove = true;
|
||||||
|
|
||||||
@ -1564,9 +1574,9 @@ virtio_scsi_dev_remove(struct virtio_scsi_dev *svdev)
|
|||||||
|
|
||||||
svdev->removed = true;
|
svdev->removed = true;
|
||||||
|
|
||||||
scan_ctx = svdev->scan_ctx;
|
if (svdev->scan_ctx) {
|
||||||
if (scan_ctx) {
|
/* The removal will continue after we receive a pending scan I/O. */
|
||||||
_virtio_scsi_dev_scan_finish(scan_ctx, -EINTR);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TAILQ_FOREACH_SAFE(disk, &svdev->luns, link, disk_tmp) {
|
TAILQ_FOREACH_SAFE(disk, &svdev->luns, link, disk_tmp) {
|
||||||
|
Loading…
Reference in New Issue
Block a user