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

rte_virtio: move vtpci code to virtio_dev.c/.h



The vtpci layer is about to be removed.
This is only 1:1 code move, all functions
will be renamed/refactored in future patches.

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


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent a8c375ad
Loading
Loading
Loading
Loading
+91 −2
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@
#include "spdk/stdinc.h"

#include <linux/virtio_scsi.h>
#include <linux/virtio_pci.h>
#include <linux/virtio_config.h>

#include <rte_config.h>
#include <rte_memcpy.h>
@@ -51,9 +53,15 @@
#include <rte_dev.h>
#include <rte_prefetch.h>

#include "virtio_user/vhost.h"
#include "spdk/env.h"

#include "virtio_dev.h"
#include "virtio_pci.h"

struct virtio_driver g_virtio_driver = {
	.init_ctrlrs = TAILQ_HEAD_INITIALIZER(g_virtio_driver.init_ctrlrs),
	.attached_ctrlrs = TAILQ_HEAD_INITIALIZER(g_virtio_driver.attached_ctrlrs),
	.ctrlr_counter = 0,
};

static void
virtio_init_vring(struct virtqueue *vq)
@@ -259,6 +267,27 @@ virtio_negotiate_features(struct virtio_dev *dev, uint64_t req_features)
	return 0;
}

struct virtio_dev *
	virtio_dev_construct(const struct virtio_pci_ops *ops, void *ctx)
{
	struct virtio_dev *vdev;
	unsigned vdev_num;

	vdev = calloc(1, sizeof(*vdev));
	if (vdev == NULL) {
		SPDK_ERRLOG("virtio device calloc failed\n");
		return NULL;
	}

	vdev_num = __sync_add_and_fetch(&g_virtio_driver.ctrlr_counter, 1);
	vdev->id = vdev_num;
	pthread_mutex_init(&vdev->mutex, NULL);
	vdev->backend_ops = ops;
	vdev->ctx = ctx;

	return vdev;
}

/* reset device and renegotiate features if needed */
int
virtio_dev_init(struct virtio_dev *dev, uint64_t req_features)
@@ -629,4 +658,64 @@ virtio_dev_release_queue(struct virtio_dev *vdev, uint16_t index)
	pthread_mutex_unlock(&vdev->mutex);
}

void
vtpci_read_dev_config(struct virtio_dev *dev, size_t offset,
		      void *dst, int length)
{
	vtpci_ops(dev)->read_dev_cfg(dev, offset, dst, length);
}

void
vtpci_write_dev_config(struct virtio_dev *dev, size_t offset,
		       const void *src, int length)
{
	vtpci_ops(dev)->write_dev_cfg(dev, offset, src, length);
}

void
vtpci_reset(struct virtio_dev *dev)
{
	vtpci_ops(dev)->set_status(dev, VIRTIO_CONFIG_S_RESET);
	/* flush status write */
	vtpci_ops(dev)->get_status(dev);
}

void
vtpci_set_status(struct virtio_dev *dev, uint8_t status)
{
	if (status != VIRTIO_CONFIG_S_RESET)
		status |= vtpci_ops(dev)->get_status(dev);

	vtpci_ops(dev)->set_status(dev, status);
}

uint8_t
vtpci_get_status(struct virtio_dev *dev)
{
	return vtpci_ops(dev)->get_status(dev);
}

const struct virtio_pci_ops *
vtpci_ops(struct virtio_dev *dev)
{
	return dev->backend_ops;
}

void
vtpci_dump_json_config(struct virtio_dev *hw, struct spdk_json_write_ctx *w)
{
	spdk_json_write_name(w, "virtio");
	spdk_json_write_object_begin(w);

	spdk_json_write_name(w, "vq_count");
	spdk_json_write_uint32(w, hw->max_queues);

	spdk_json_write_name(w, "vq_size");
	spdk_json_write_uint32(w, vtpci_ops(hw)->get_queue_num(hw, 0));

	vtpci_ops(hw)->dump_json_config(hw, w);

	spdk_json_write_object_end(w);
}

SPDK_LOG_REGISTER_TRACE_FLAG("virtio_dev", SPDK_TRACE_VIRTIO_DEV)
+74 −0
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@
#include "spdk/stdinc.h"

#include <linux/virtio_ring.h>
#include <linux/virtio_pci.h>
#include <linux/virtio_config.h>

#include <rte_config.h>
#include <rte_memory.h>
@@ -45,6 +47,7 @@
#include "spdk_internal/log.h"
#include "spdk/likely.h"
#include "spdk/queue.h"
#include "spdk/json.h"

/*
 * Per virtio_config.h in Linux.
@@ -72,6 +75,12 @@
 */
#define SPDK_VIRTIO_QUEUE_LCORE_ID_UNUSED (UINT32_MAX - 1)

/* Number of non-request queues - eventq and controlq */
#define SPDK_VIRTIO_SCSI_QUEUE_NUM_FIXED 2

/* Extra status define for readability */
#define VIRTIO_CONFIG_S_RESET 0

struct virtio_pci_ops;

struct virtio_dev {
@@ -107,6 +116,38 @@ struct virtio_dev {
	TAILQ_ENTRY(virtio_dev) tailq;
};

struct virtio_pci_ops {
	void (*read_dev_cfg)(struct virtio_dev *hw, size_t offset,
			     void *dst, int len);
	void (*write_dev_cfg)(struct virtio_dev *hw, size_t offset,
			      const void *src, int len);
	uint8_t (*get_status)(struct virtio_dev *hw);
	void (*set_status)(struct virtio_dev *hw, uint8_t status);

	/**
	 * Get device features. The features might be already
	 * negotiated with driver (guest) features.
	 */
	uint64_t (*get_features)(struct virtio_dev *vdev);

	/**
	 * Negotiate and set device features.
	 * The negotiation can fail with return code -1.
	 * This function should also set vdev->negotiated_features field.
	 */
	int (*set_features)(struct virtio_dev *vdev, uint64_t features);

	/** Deinit and free virtio device */
	void (*free_vdev)(struct virtio_dev *vdev);

	uint16_t (*get_queue_num)(struct virtio_dev *hw, uint16_t queue_id);
	int (*setup_queue)(struct virtio_dev *hw, struct virtqueue *vq);
	void (*del_queue)(struct virtio_dev *hw, struct virtqueue *vq);
	void (*notify_queue)(struct virtio_dev *hw, struct virtqueue *vq);

	void (*dump_json_config)(struct virtio_dev *hw, struct spdk_json_write_ctx *w);
};

struct vq_desc_extra {
	void *cookie;
	uint16_t ndescs;
@@ -168,6 +209,16 @@ struct virtio_req {
	uint32_t	data_transferred;
};

struct virtio_driver {
	TAILQ_HEAD(, virtio_dev) init_ctrlrs;
	TAILQ_HEAD(, virtio_dev) attached_ctrlrs;

	/* Increment-only virtio_dev counter */
	unsigned ctrlr_counter;
};

extern struct virtio_driver g_virtio_driver;

/* Features desired/implemented by this driver. */
#define VIRTIO_SCSI_DEV_SUPPORTED_FEATURES		\
	(1ULL << VIRTIO_SCSI_F_INOUT		|	\
@@ -307,4 +358,27 @@ bool virtio_dev_queue_is_acquired(struct virtio_dev *vdev, uint16_t index);
 */
void virtio_dev_release_queue(struct virtio_dev *vdev, uint16_t index);

void vtpci_reset(struct virtio_dev *);

uint8_t vtpci_get_status(struct virtio_dev *);
void vtpci_set_status(struct virtio_dev *, uint8_t);

uint64_t vtpci_negotiate_features(struct virtio_dev *, uint64_t);

void vtpci_write_dev_config(struct virtio_dev *, size_t, const void *, int);

void vtpci_read_dev_config(struct virtio_dev *, size_t, void *, int);

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

static inline int
vtpci_with_feature(struct virtio_dev *dev, uint64_t bit)
{
	return (dev->negotiated_features & (1ULL << bit)) != 0;
}

void vtpci_dump_json_config(struct virtio_dev *hw, struct spdk_json_write_ctx *w);

extern const struct virtio_pci_ops virtio_user_ops;

#endif /* _VIRTIO_DEV_H_ */
+1 −88
Original line number Diff line number Diff line
@@ -37,15 +37,10 @@

#include "spdk/mmio.h"
#include "spdk/string.h"
#include "spdk/env.h"

#include "virtio_pci.h"

struct virtio_driver g_virtio_driver = {
	.init_ctrlrs = TAILQ_HEAD_INITIALIZER(g_virtio_driver.init_ctrlrs),
	.attached_ctrlrs = TAILQ_HEAD_INITIALIZER(g_virtio_driver.attached_ctrlrs),
	.ctrlr_counter = 0,
};

/*
 * Following macros are derived from linux/pci_regs.h, however,
 * we can't simply include that header here, as there is no such
@@ -297,44 +292,6 @@ const struct virtio_pci_ops modern_ops = {
	.dump_json_config = pci_dump_json_config,
};


void
vtpci_read_dev_config(struct virtio_dev *dev, size_t offset,
		      void *dst, int length)
{
	vtpci_ops(dev)->read_dev_cfg(dev, offset, dst, length);
}

void
vtpci_write_dev_config(struct virtio_dev *dev, size_t offset,
		       const void *src, int length)
{
	vtpci_ops(dev)->write_dev_cfg(dev, offset, src, length);
}

void
vtpci_reset(struct virtio_dev *dev)
{
	vtpci_ops(dev)->set_status(dev, VIRTIO_CONFIG_S_RESET);
	/* flush status write */
	vtpci_ops(dev)->get_status(dev);
}

void
vtpci_set_status(struct virtio_dev *dev, uint8_t status)
{
	if (status != VIRTIO_CONFIG_S_RESET)
		status |= vtpci_ops(dev)->get_status(dev);

	vtpci_ops(dev)->set_status(dev, status);
}

uint8_t
vtpci_get_status(struct virtio_dev *dev)
{
	return vtpci_ops(dev)->get_status(dev);
}

static void *
get_cfg_addr(struct virtio_hw *hw, struct virtio_pci_cap *cap)
{
@@ -514,27 +471,6 @@ err:
	return -1;
}

struct virtio_dev *
	virtio_dev_construct(const struct virtio_pci_ops *ops, void *ctx)
{
	struct virtio_dev *vdev;
	unsigned vdev_num;

	vdev = calloc(1, sizeof(*vdev));
	if (vdev == NULL) {
		SPDK_ERRLOG("virtio device calloc failed\n");
		return NULL;
	}

	vdev_num = __sync_add_and_fetch(&g_virtio_driver.ctrlr_counter, 1);
	vdev->id = vdev_num;
	pthread_mutex_init(&vdev->mutex, NULL);
	vdev->backend_ops = ops;
	vdev->ctx = ctx;

	return vdev;
}

int
vtpci_enumerate_pci(void)
{
@@ -546,27 +482,4 @@ vtpci_enumerate_pci(void)
	return spdk_pci_virtio_enumerate(pci_enum_virtio_probe_cb, NULL);
}

const struct virtio_pci_ops *
vtpci_ops(struct virtio_dev *dev)
{
	return dev->backend_ops;
}

void
vtpci_dump_json_config(struct virtio_dev *hw, struct spdk_json_write_ctx *w)
{
	spdk_json_write_name(w, "virtio");
	spdk_json_write_object_begin(w);

	spdk_json_write_name(w, "vq_count");
	spdk_json_write_uint32(w, hw->max_queues);

	spdk_json_write_name(w, "vq_size");
	spdk_json_write_uint32(w, vtpci_ops(hw)->get_queue_num(hw, 0));

	vtpci_ops(hw)->dump_json_config(hw, w);

	spdk_json_write_object_end(w);
}

SPDK_LOG_REGISTER_TRACE_FLAG("virtio_pci", SPDK_TRACE_VIRTIO_PCI)
+0 −76
Original line number Diff line number Diff line
@@ -36,53 +36,10 @@

#include "spdk/stdinc.h"

#include <linux/virtio_config.h>
#include <linux/virtio_pci.h>

#include "spdk/env.h"
#include "spdk/json.h"
#include "virtio_dev.h"

struct virtqueue;

/* Extra status define for readability */
#define VIRTIO_CONFIG_S_RESET 0

/* Number of non-request queues - eventq and controlq */
#define SPDK_VIRTIO_SCSI_QUEUE_NUM_FIXED 2

struct virtio_pci_ops {
	void (*read_dev_cfg)(struct virtio_dev *hw, size_t offset,
			     void *dst, int len);
	void (*write_dev_cfg)(struct virtio_dev *hw, size_t offset,
			      const void *src, int len);
	uint8_t (*get_status)(struct virtio_dev *hw);
	void (*set_status)(struct virtio_dev *hw, uint8_t status);

	/**
	 * Get device features. The features might be already
	 * negotiated with driver (guest) features.
	 */
	uint64_t (*get_features)(struct virtio_dev *vdev);

	/**
	 * Negotiate and set device features.
	 * The negotiation can fail with return code -1.
	 * This function should also set vdev->negotiated_features field.
	 */
	int (*set_features)(struct virtio_dev *vdev, uint64_t features);

	/** Deinit and free virtio device */
	void (*free_vdev)(struct virtio_dev *vdev);

	uint16_t (*get_queue_num)(struct virtio_dev *hw, uint16_t queue_id);
	int (*setup_queue)(struct virtio_dev *hw, struct virtqueue *vq);
	void (*del_queue)(struct virtio_dev *hw, struct virtqueue *vq);
	void (*notify_queue)(struct virtio_dev *hw, struct virtqueue *vq);

	void (*dump_json_config)(struct virtio_dev *hw, struct spdk_json_write_ctx *w);
};

struct virtio_hw {
	uint8_t	    use_msix;
	uint32_t    notify_off_multiplier;
@@ -102,42 +59,9 @@ struct virtio_hw {
	struct virtio_scsi_config *dev_cfg;
};

struct virtio_driver {
	TAILQ_HEAD(, virtio_dev) init_ctrlrs;
	TAILQ_HEAD(, virtio_dev) attached_ctrlrs;

	/* Increment-only virtio_dev counter */
	unsigned ctrlr_counter;
};

extern struct virtio_driver g_virtio_driver;

static inline int
vtpci_with_feature(struct virtio_dev *dev, uint64_t bit)
{
	return (dev->negotiated_features & (1ULL << bit)) != 0;
}

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

void vtpci_reset(struct virtio_dev *);

uint8_t vtpci_get_status(struct virtio_dev *);
void vtpci_set_status(struct virtio_dev *, uint8_t);

uint64_t vtpci_negotiate_features(struct virtio_dev *, uint64_t);

void vtpci_write_dev_config(struct virtio_dev *, size_t, const void *, int);

void vtpci_read_dev_config(struct virtio_dev *, size_t, void *, int);

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

void vtpci_dump_json_config(struct virtio_dev *hw, struct spdk_json_write_ctx *w);

extern const struct virtio_pci_ops virtio_user_ops;

#endif /* _VIRTIO_PCI_H_ */