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

rte_virtio: rework vtpci ops



Added vtpci_init/deinit() that set up
vtpci_internal for given virtio device.

This patch allows having multiple
devices with different vtpci_ops.

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


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
parent 5faa8559
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -621,7 +621,7 @@ bdev_virtio_initialize(void)
	}

	if (scan_pci) {
		vtpci_init();
		vtpci_enumerate_pci();
	}

	TAILQ_FOREACH(vdev, &g_virtio_driver.init_ctrlrs, tailq) {
+5 −3
Original line number Diff line number Diff line
@@ -120,8 +120,8 @@ virtio_init_queue(struct virtio_dev *dev, uint16_t vtpci_queue_idx)
		return -EINVAL;
	}

	snprintf(vq_name, sizeof(vq_name), "port%d_vq%d",
		 dev->port_id, vtpci_queue_idx);
	snprintf(vq_name, sizeof(vq_name), "dev%d_vq%d",
		 dev->id, vtpci_queue_idx);

	size = RTE_ALIGN_CEIL(sizeof(*vq) +
				vq_size * sizeof(struct vq_desc_extra),
@@ -318,9 +318,11 @@ virtio_dev_init(struct virtio_dev *dev, uint64_t req_features)
void
virtio_dev_free(struct virtio_dev *dev)
{
	uint32_t vdev_id = dev->id;

	virtio_free_queues(dev);
	vtpci_ops(dev)->free_vdev(dev);
	/* FIXME clear VTPCI_OPS(dev) */
	vtpci_deinit(vdev_id);
}

int
+2 −1
Original line number Diff line number Diff line
@@ -45,7 +45,8 @@ struct virtio_dev {
	/** Max number of queues the host supports. */
	uint16_t	max_queues;

	uint8_t		port_id;
	/* Device index. */
	uint32_t	id;
	uint64_t	req_guest_features;
	uint64_t	guest_features;
	int		is_hw;
+50 −4
Original line number Diff line number Diff line
@@ -83,6 +83,12 @@ check_vq_phys_addr_ok(struct virtqueue *vq)
	return 1;
}

static struct rte_pci_ioport *
vtpci_io(struct virtio_dev *vdev)
{
	return &g_virtio_driver.internal[vdev->id].io;
}

static void
free_virtio_hw(struct virtio_dev *dev)
{
@@ -724,7 +730,10 @@ pci_enum_virtio_probe_cb(void *ctx, struct spdk_pci_device *pci_dev)
	 */
	if (virtio_read_caps(hw) == 0) {
		PMD_INIT_LOG(INFO, "modern virtio pci detected.");
		vtpci_ops(vdev) = &modern_ops;
		rc = vtpci_init(vdev, &modern_ops);
		if (rc != 0) {
			goto err;
		}
		vdev->modern = 1;
		TAILQ_INSERT_TAIL(&g_virtio_driver.init_ctrlrs, vdev, tailq);
		return 0;
@@ -745,7 +754,10 @@ pci_enum_virtio_probe_cb(void *ctx, struct spdk_pci_device *pci_dev)
	}
#endif

	vtpci_ops(vdev) = &legacy_ops;
	rc = vtpci_init(vdev, &legacy_ops);
	if (rc != 0) {
		goto err;
	}
	vdev->modern = 0;

	vtpci_read_dev_config(vdev, offsetof(struct virtio_scsi_config, num_queues),
@@ -760,7 +772,29 @@ err:
}

int
vtpci_init(void)
vtpci_init(struct virtio_dev *vdev, const struct virtio_pci_ops *ops)
{
	unsigned vdev_num;

	for (vdev_num = 0; vdev_num < VIRTIO_MAX_DEVICES; vdev_num++) {
		if (g_virtio_driver.internal[vdev_num].vtpci_ops == NULL) {
			break;
		}
	}

	if (vdev_num == VIRTIO_MAX_DEVICES) {
		PMD_INIT_LOG(ERR, "Max vhost device limit reached (%d).", VIRTIO_MAX_DEVICES);
		return -ENOSPC;
	}

	vdev->id = vdev_num;
	g_virtio_driver.internal[vdev_num].vtpci_ops = ops;

	return 0;
}

int
vtpci_enumerate_pci(void)
{
	if (!spdk_process_is_primary()) {
		PMD_INIT_LOG(INFO, "virtio_pci secondary process support is not implemented yet.");
@@ -769,3 +803,15 @@ vtpci_init(void)

	return spdk_pci_virtio_enumerate(pci_enum_virtio_probe_cb, NULL);
}

const struct virtio_pci_ops *
vtpci_ops(struct virtio_dev *dev)
{
	return g_virtio_driver.internal[dev->id].vtpci_ops;
}

void
vtpci_deinit(uint32_t id)
{
	g_virtio_driver.internal[id].vtpci_ops = NULL;
}
+18 −5
Original line number Diff line number Diff line
@@ -43,6 +43,8 @@

struct virtqueue;

#define VIRTIO_MAX_DEVICES 128

/* VirtIO PCI vendor/device ID. */
#define VIRTIO_PCI_VENDORID     0x1AF4
#define VIRTIO_PCI_DEVICEID_SCSI_MODERN 0x1004
@@ -242,11 +244,8 @@ struct vtpci_internal {
	struct rte_pci_ioport io;
};

#define vtpci_ops(dev)	(g_virtio_driver.internal[(dev)->port_id].vtpci_ops)
#define vtpci_io(dev)	(&g_virtio_driver.internal[(dev)->port_id].io)

struct virtio_driver {
	struct vtpci_internal internal[128];
	struct vtpci_internal internal[VIRTIO_MAX_DEVICES];
	TAILQ_HEAD(, virtio_dev) init_ctrlrs;
	TAILQ_HEAD(, virtio_dev) attached_ctrlrs;
};
@@ -268,7 +267,17 @@ vtpci_with_feature(struct virtio_dev *dev, uint64_t bit)
	return (dev->guest_features & (1ULL << bit)) != 0;
}

int vtpci_init(void);
/**
 * Init all compatible Virtio PCI devices.
 */
int vtpci_enumerate_pci(void);

/**
 * Init virtual PCI layer for given device.  This
 * will set vdev->id field.
 */
int vtpci_init(struct virtio_dev *vdev, const struct virtio_pci_ops *ops);

void vtpci_reset(struct virtio_dev *);

void vtpci_reinit_complete(struct virtio_dev *);
@@ -284,6 +293,10 @@ void vtpci_read_dev_config(struct virtio_dev *, size_t, void *, int);

uint8_t vtpci_isr(struct virtio_dev *);

const struct virtio_pci_ops *vtpci_ops(struct virtio_dev *dev);

void vtpci_deinit(uint32_t id);

extern const struct virtio_pci_ops virtio_user_ops;

#endif /* _VIRTIO_PCI_H_ */
Loading