Commit 64e80646 authored by Dariusz Stojaczyk's avatar Dariusz Stojaczyk Committed by Daniel Verkamp
Browse files

bdev_virtio: use scan_base as memory pool for all requests



Save us some allocations and fix
scan_target() error handling path

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


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarPawel Wodkowski <pawelx.wodkowski@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
parent 1e714cfe
Loading
Loading
Loading
Loading
+40 −41
Original line number Diff line number Diff line
@@ -55,13 +55,29 @@

#include "spdk/scsi_spec.h"

#define BDEV_VIRTIO_MAX_TARGET 64
#define BDEV_VIRTIO_SCAN_PAYLOAD_SIZE 256

static int bdev_virtio_initialize(void);
static void bdev_virtio_finish(void);

struct virtio_scsi_io_ctx {
	struct virtio_req 		vreq;
	struct virtio_scsi_cmd_req 	req;
	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;
	struct virtio_scsi_scan_buf	buf[BDEV_VIRTIO_MAX_TARGET];
};

struct virtio_scsi_disk {
@@ -71,12 +87,6 @@ struct virtio_scsi_disk {
	uint32_t		block_size;
};

struct virtio_scsi_io_ctx {
	struct virtio_req 		vreq;
	struct virtio_scsi_cmd_req 	req;
	struct virtio_scsi_cmd_resp 	resp;
};

struct bdev_virtio_io_channel {
	struct virtio_hw	*hw;
	struct spdk_bdev_poller	*poller;
@@ -272,17 +282,9 @@ bdev_virtio_destroy_cb(void *io_device, void *ctx_buf)
}

static void
scan_target_finish(struct virtio_scsi_scan_base *base, struct virtio_req *vreq)
scan_target_finish(struct virtio_scsi_scan_base *base)
{
	assert(base->refcount > 0);

	spdk_dma_free(vreq->iov[0].iov_base);
	spdk_dma_free(vreq->iov);
	spdk_dma_free(vreq->iov_resp.iov_base);
	spdk_dma_free(vreq->iov_req.iov_base);

	free(vreq);

	base->refcount--;
	if (base->refcount == 0) {
		spdk_bdev_poller_stop(&base->scan_poller);
@@ -358,7 +360,7 @@ process_read_cap(struct virtio_scsi_scan_base *base, struct virtio_req *vreq)
				sizeof(struct bdev_virtio_io_channel));
	spdk_bdev_register(bdev);

	scan_target_finish(base, vreq);
	scan_target_finish(base);
	return 0;
}

@@ -371,7 +373,7 @@ process_scan_resp(struct virtio_scsi_scan_base *base, struct virtio_req *vreq)
	if (vreq->iov_req.iov_len < sizeof(struct virtio_scsi_cmd_req) ||
	    vreq->iov_resp.iov_len < sizeof(struct virtio_scsi_cmd_resp)) {
		SPDK_ERRLOG("Received target scan message with invalid length.\n");
		scan_target_finish(base, vreq);
		scan_target_finish(base);
		return;
	}

@@ -389,7 +391,7 @@ process_scan_resp(struct virtio_scsi_scan_base *base, struct virtio_req *vreq)
	}

	if (rc < 0) {
		scan_target_finish(base, vreq);
		scan_target_finish(base);
	}
}

@@ -413,7 +415,7 @@ bdev_scan_poll(void *arg)
}

static void
scan_target(struct virtio_hw *hw, uint8_t target)
scan_target(struct virtio_scsi_scan_base *base, uint8_t target)
{
	struct iovec *iov;
	struct virtio_req *vreq;
@@ -421,28 +423,23 @@ scan_target(struct virtio_hw *hw, uint8_t target)
	struct virtio_scsi_cmd_resp *resp;
	struct spdk_scsi_cdb_inquiry *cdb;

	vreq = calloc(1, sizeof(*vreq));
	if (vreq == NULL) {
		SPDK_ERRLOG("Cannot allocate memory for target scan request.\n");
		return;
	}
	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;

	iov = spdk_dma_malloc(sizeof(*iov), 64, NULL);
	vreq->iov = iov;
	vreq->iovcnt = 1;
	vreq->is_write = 0;

	req = spdk_dma_zmalloc(sizeof(*req), 64, NULL);
	resp = spdk_dma_malloc(sizeof(*resp), 64, NULL);

	vreq->iov_req.iov_base = (void *)req;
	vreq->iov_req.iov_len = sizeof(*req);

	vreq->iov_resp.iov_base = (void *)resp;
	vreq->iov_resp.iov_len = sizeof(*resp);

	iov[0].iov_base = spdk_dma_malloc(4096, 64, NULL);
	iov[0].iov_len = 255;
	iov[0].iov_base = (void *)&base->buf[target].payload;
	iov[0].iov_len = BDEV_VIRTIO_SCAN_PAYLOAD_SIZE;

	req->lun[0] = 1;
	req->lun[1] = target;
@@ -451,7 +448,7 @@ scan_target(struct virtio_hw *hw, uint8_t target)
	cdb->opcode = SPDK_SPC_INQUIRY;
	cdb->alloc_len[1] = 255;

	virtio_xmit_pkts(hw->vqs[2], vreq);
	virtio_xmit_pkts(base->hw->vqs[2], vreq);
}

static int
@@ -500,19 +497,21 @@ bdev_virtio_initialize(void)
		goto out;
	}

	base->hw = hw;
	base->refcount = 64;
	spdk_bdev_poller_start(&base->scan_poller, bdev_scan_poll, base,
			       spdk_env_get_current_core(), 0);

	/* TODO check rc, add virtio_dev_deinit() */
	eth_virtio_dev_init(hw, 3);
	virtio_dev_start(hw);

	for (i = 0; i < 64; i++) {
		scan_target(hw, i);
	base->hw = hw;
	base->refcount = BDEV_VIRTIO_MAX_TARGET;

	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);
	}


	return 0;

out: