Commit dec98224 authored by Dariusz Stojaczyk's avatar Dariusz Stojaczyk Committed by Jim Harris
Browse files

bdev_virtio: scan targets one by one



This ensures that we don't run out of free descriptors
and queue entries.

Change-Id: I3c6960564032ffce6e6b6bf887e8c5e12fdf3205
Signed-off-by: default avatarDariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/378153


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
parent 661feb15
Loading
Loading
Loading
Loading
+24 −35
Original line number Diff line number Diff line
@@ -67,21 +67,19 @@ struct virtio_scsi_io_ctx {
	struct virtio_scsi_cmd_resp 	resp;
};

struct virtio_scsi_scan_buf {
	struct virtio_scsi_io_ctx	io_ctx;
	struct iovec			iov;
	uint8_t				payload[BDEV_VIRTIO_SCAN_PAYLOAD_SIZE];
};

struct virtio_scsi_scan_base {
	struct virtio_hw		*hw;
	struct spdk_bdev_poller		*scan_poller;
	unsigned			refcount;

	/* Currently queried target */
	unsigned			target;

	/* Disks to be registered after the scan finishes */
	TAILQ_HEAD(, virtio_scsi_disk) found_disks;

	struct virtio_scsi_scan_buf	buf[BDEV_VIRTIO_MAX_TARGET];
	struct virtio_scsi_io_ctx	io_ctx;
	struct iovec			iov;
	uint8_t				payload[BDEV_VIRTIO_SCAN_PAYLOAD_SIZE];
};

struct virtio_scsi_disk {
@@ -97,6 +95,8 @@ struct bdev_virtio_io_channel {
	struct spdk_bdev_poller	*poller;
};

static void scan_target(struct virtio_scsi_scan_base *base);

static int
bdev_virtio_get_ctx_size(void)
{
@@ -291,9 +291,9 @@ scan_target_finish(struct virtio_scsi_scan_base *base)
{
	struct virtio_scsi_disk *disk;

	assert(base->refcount > 0);
	base->refcount--;
	if (base->refcount > 0) {
	base->target++;
	if (base->target < BDEV_VIRTIO_MAX_TARGET) {
		scan_target(base);
		return;
	}

@@ -413,23 +413,17 @@ static void
bdev_scan_poll(void *arg)
{
	struct virtio_scsi_scan_base *base = arg;
	struct virtio_req *req[32];
	uint16_t i, cnt;
	struct virtio_req *req;
	uint16_t cnt;

	cnt = virtio_recv_pkts(base->hw->vqs[2], req, SPDK_COUNTOF(req));
	if (cnt > base->refcount) {
		SPDK_ERRLOG("Received too many virtio messages. Got %"PRIu16", expected %u",
			    cnt, base->refcount);
		return;
	}

	for (i = 0; i < cnt; ++i) {
		process_scan_resp(base, req[i]);
	cnt = virtio_recv_pkts(base->hw->vqs[2], &req, 1);
	if (cnt > 0) {
		process_scan_resp(base, req);
	}
}

static void
scan_target(struct virtio_scsi_scan_base *base, uint8_t target)
scan_target(struct virtio_scsi_scan_base *base)
{
	struct iovec *iov;
	struct virtio_req *vreq;
@@ -437,10 +431,10 @@ scan_target(struct virtio_scsi_scan_base *base, uint8_t target)
	struct virtio_scsi_cmd_resp *resp;
	struct spdk_scsi_cdb_inquiry *cdb;

	vreq = &base->buf[target].io_ctx.vreq;
	req = &base->buf[target].io_ctx.req;
	resp = &base->buf[target].io_ctx.resp;
	iov = &base->buf[target].iov;
	vreq = &base->io_ctx.vreq;
	req = &base->io_ctx.req;
	resp = &base->io_ctx.resp;
	iov = &base->iov;

	vreq->iov = iov;
	vreq->iovcnt = 1;
@@ -452,11 +446,11 @@ scan_target(struct virtio_scsi_scan_base *base, uint8_t target)
	vreq->iov_resp.iov_base = (void *)resp;
	vreq->iov_resp.iov_len = sizeof(*resp);

	iov[0].iov_base = (void *)&base->buf[target].payload;
	iov[0].iov_base = (void *)&base->payload;
	iov[0].iov_len = BDEV_VIRTIO_SCAN_PAYLOAD_SIZE;

	req->lun[0] = 1;
	req->lun[1] = target;
	req->lun[1] = base->target;

	cdb = (struct spdk_scsi_cdb_inquiry *)req->cdb;
	cdb->opcode = SPDK_SPC_INQUIRY;
@@ -516,17 +510,12 @@ bdev_virtio_initialize(void)
	virtio_dev_start(hw);

	base->hw = hw;
	base->refcount = BDEV_VIRTIO_MAX_TARGET;
	TAILQ_INIT(&base->found_disks);

	spdk_bdev_poller_start(&base->scan_poller, bdev_scan_poll, base,
			       spdk_env_get_current_core(), 0);

	for (i = 0; i < BDEV_VIRTIO_MAX_TARGET; i++) {
		scan_target(base, i);
	}


	scan_target(base);
	return 0;

out: