vhost: turn queue pair to vring
The queue pair is very virtio-net specific, other devices don't have such concept. To make it generic, we should log the number of vrings instead of the number of queue pairs. This patch just does a simple convert, a later patch would export the number of vrings to applications. Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com> Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
This commit is contained in:
parent
dba9bf127b
commit
ab4d7b9f1a
@ -84,10 +84,8 @@ cleanup_device(struct virtio_net *dev, int destroy)
|
||||
|
||||
vhost_backend_cleanup(dev);
|
||||
|
||||
for (i = 0; i < dev->virt_qp_nb; i++) {
|
||||
cleanup_vq(dev->virtqueue[i * VIRTIO_QNUM + VIRTIO_RXQ], destroy);
|
||||
cleanup_vq(dev->virtqueue[i * VIRTIO_QNUM + VIRTIO_TXQ], destroy);
|
||||
}
|
||||
for (i = 0; i < dev->nr_vring; i++)
|
||||
cleanup_vq(dev->virtqueue[i], destroy);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -97,24 +95,21 @@ static void
|
||||
free_device(struct virtio_net *dev)
|
||||
{
|
||||
uint32_t i;
|
||||
struct vhost_virtqueue *rxq, *txq;
|
||||
struct vhost_virtqueue *vq;
|
||||
|
||||
for (i = 0; i < dev->virt_qp_nb; i++) {
|
||||
rxq = dev->virtqueue[i * VIRTIO_QNUM + VIRTIO_RXQ];
|
||||
txq = dev->virtqueue[i * VIRTIO_QNUM + VIRTIO_TXQ];
|
||||
for (i = 0; i < dev->nr_vring; i++) {
|
||||
vq = dev->virtqueue[i];
|
||||
|
||||
rte_free(rxq->shadow_used_ring);
|
||||
rte_free(txq->shadow_used_ring);
|
||||
rte_free(vq->shadow_used_ring);
|
||||
|
||||
/* rxq and txq are allocated together as queue-pair */
|
||||
rte_free(rxq);
|
||||
rte_free(vq);
|
||||
}
|
||||
|
||||
rte_free(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
init_vring_queue(struct vhost_virtqueue *vq, int qp_idx)
|
||||
init_vring_queue(struct vhost_virtqueue *vq)
|
||||
{
|
||||
memset(vq, 0, sizeof(struct vhost_virtqueue));
|
||||
|
||||
@ -124,69 +119,48 @@ init_vring_queue(struct vhost_virtqueue *vq, int qp_idx)
|
||||
/* Backends are set to -1 indicating an inactive device. */
|
||||
vq->backend = -1;
|
||||
|
||||
/* always set the default vq pair to enabled */
|
||||
if (qp_idx == 0)
|
||||
vq->enabled = 1;
|
||||
/*
|
||||
* always set the vq to enabled; this is to keep compatibility
|
||||
* with the old QEMU, whereas there is no SET_VRING_ENABLE message.
|
||||
*/
|
||||
vq->enabled = 1;
|
||||
|
||||
TAILQ_INIT(&vq->zmbuf_list);
|
||||
}
|
||||
|
||||
static void
|
||||
init_vring_queue_pair(struct virtio_net *dev, uint32_t qp_idx)
|
||||
{
|
||||
uint32_t base_idx = qp_idx * VIRTIO_QNUM;
|
||||
|
||||
init_vring_queue(dev->virtqueue[base_idx + VIRTIO_RXQ], qp_idx);
|
||||
init_vring_queue(dev->virtqueue[base_idx + VIRTIO_TXQ], qp_idx);
|
||||
}
|
||||
|
||||
static void
|
||||
reset_vring_queue(struct vhost_virtqueue *vq, int qp_idx)
|
||||
reset_vring_queue(struct vhost_virtqueue *vq)
|
||||
{
|
||||
int callfd;
|
||||
|
||||
callfd = vq->callfd;
|
||||
init_vring_queue(vq, qp_idx);
|
||||
init_vring_queue(vq);
|
||||
vq->callfd = callfd;
|
||||
}
|
||||
|
||||
static void
|
||||
reset_vring_queue_pair(struct virtio_net *dev, uint32_t qp_idx)
|
||||
{
|
||||
uint32_t base_idx = qp_idx * VIRTIO_QNUM;
|
||||
|
||||
reset_vring_queue(dev->virtqueue[base_idx + VIRTIO_RXQ], qp_idx);
|
||||
reset_vring_queue(dev->virtqueue[base_idx + VIRTIO_TXQ], qp_idx);
|
||||
}
|
||||
|
||||
int
|
||||
alloc_vring_queue_pair(struct virtio_net *dev, uint32_t qp_idx)
|
||||
alloc_vring_queue(struct virtio_net *dev, uint32_t vring_idx)
|
||||
{
|
||||
struct vhost_virtqueue *virtqueue = NULL;
|
||||
uint32_t virt_rx_q_idx = qp_idx * VIRTIO_QNUM + VIRTIO_RXQ;
|
||||
uint32_t virt_tx_q_idx = qp_idx * VIRTIO_QNUM + VIRTIO_TXQ;
|
||||
struct vhost_virtqueue *vq;
|
||||
|
||||
virtqueue = rte_malloc(NULL,
|
||||
sizeof(struct vhost_virtqueue) * VIRTIO_QNUM, 0);
|
||||
if (virtqueue == NULL) {
|
||||
vq = rte_malloc(NULL, sizeof(struct vhost_virtqueue), 0);
|
||||
if (vq == NULL) {
|
||||
RTE_LOG(ERR, VHOST_CONFIG,
|
||||
"Failed to allocate memory for virt qp:%d.\n", qp_idx);
|
||||
"Failed to allocate memory for vring:%u.\n", vring_idx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dev->virtqueue[virt_rx_q_idx] = virtqueue;
|
||||
dev->virtqueue[virt_tx_q_idx] = virtqueue + VIRTIO_TXQ;
|
||||
dev->virtqueue[vring_idx] = vq;
|
||||
init_vring_queue(vq);
|
||||
|
||||
init_vring_queue_pair(dev, qp_idx);
|
||||
|
||||
dev->virt_qp_nb += 1;
|
||||
dev->nr_vring += 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset some variables in device structure, while keeping few
|
||||
* others untouched, such as vid, ifname, virt_qp_nb: they
|
||||
* others untouched, such as vid, ifname, nr_vring: they
|
||||
* should be same unless the device is removed.
|
||||
*/
|
||||
void
|
||||
@ -198,8 +172,8 @@ reset_device(struct virtio_net *dev)
|
||||
dev->protocol_features = 0;
|
||||
dev->flags = 0;
|
||||
|
||||
for (i = 0; i < dev->virt_qp_nb; i++)
|
||||
reset_vring_queue_pair(dev, i);
|
||||
for (i = 0; i < dev->nr_vring; i++)
|
||||
reset_vring_queue(dev->virtqueue[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -340,7 +314,7 @@ rte_vhost_get_queue_num(int vid)
|
||||
if (dev == NULL)
|
||||
return 0;
|
||||
|
||||
return dev->virt_qp_nb;
|
||||
return dev->nr_vring / 2;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -176,7 +176,7 @@ struct virtio_net {
|
||||
uint16_t vhost_hlen;
|
||||
/* to tell if we need broadcast rarp packet */
|
||||
rte_atomic16_t broadcast_rarp;
|
||||
uint32_t virt_qp_nb;
|
||||
uint32_t nr_vring;
|
||||
int dequeue_zero_copy;
|
||||
struct vhost_virtqueue *virtqueue[VHOST_MAX_QUEUE_PAIRS * 2];
|
||||
#define IF_NAME_SZ (PATH_MAX > IFNAMSIZ ? PATH_MAX : IFNAMSIZ)
|
||||
@ -256,7 +256,7 @@ void cleanup_device(struct virtio_net *dev, int destroy);
|
||||
void reset_device(struct virtio_net *dev);
|
||||
void vhost_destroy_device(int);
|
||||
|
||||
int alloc_vring_queue_pair(struct virtio_net *dev, uint32_t qp_idx);
|
||||
int alloc_vring_queue(struct virtio_net *dev, uint32_t vring_idx);
|
||||
|
||||
void vhost_set_ifname(int, const char *if_name, unsigned int if_len);
|
||||
void vhost_enable_dequeue_zero_copy(int vid);
|
||||
|
@ -233,13 +233,6 @@ numa_realloc(struct virtio_net *dev, int index)
|
||||
struct vhost_virtqueue *old_vq, *vq;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* vq is allocated on pairs, we should try to do realloc
|
||||
* on first queue of one queue pair only.
|
||||
*/
|
||||
if (index % VIRTIO_QNUM != 0)
|
||||
return dev;
|
||||
|
||||
old_dev = dev;
|
||||
vq = old_vq = dev->virtqueue[index];
|
||||
|
||||
@ -257,8 +250,7 @@ numa_realloc(struct virtio_net *dev, int index)
|
||||
if (oldnode != newnode) {
|
||||
RTE_LOG(INFO, VHOST_CONFIG,
|
||||
"reallocate vq from %d to %d node\n", oldnode, newnode);
|
||||
vq = rte_malloc_socket(NULL, sizeof(*vq) * VIRTIO_QNUM, 0,
|
||||
newnode);
|
||||
vq = rte_malloc_socket(NULL, sizeof(*vq), 0, newnode);
|
||||
if (!vq)
|
||||
return dev;
|
||||
|
||||
@ -290,7 +282,6 @@ numa_realloc(struct virtio_net *dev, int index)
|
||||
|
||||
out:
|
||||
dev->virtqueue[index] = vq;
|
||||
dev->virtqueue[index + 1] = vq + 1;
|
||||
vhost_devices[dev->vid] = dev;
|
||||
|
||||
return dev;
|
||||
@ -621,14 +612,13 @@ vq_is_ready(struct vhost_virtqueue *vq)
|
||||
static int
|
||||
virtio_is_ready(struct virtio_net *dev)
|
||||
{
|
||||
struct vhost_virtqueue *rvq, *tvq;
|
||||
struct vhost_virtqueue *vq;
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < dev->virt_qp_nb; i++) {
|
||||
rvq = dev->virtqueue[i * VIRTIO_QNUM + VIRTIO_RXQ];
|
||||
tvq = dev->virtqueue[i * VIRTIO_QNUM + VIRTIO_TXQ];
|
||||
for (i = 0; i < dev->nr_vring; i++) {
|
||||
vq = dev->virtqueue[i];
|
||||
|
||||
if (!vq_is_ready(rvq) || !vq_is_ready(tvq)) {
|
||||
if (!vq_is_ready(vq)) {
|
||||
RTE_LOG(INFO, VHOST_CONFIG,
|
||||
"virtio is not ready for processing.\n");
|
||||
return 0;
|
||||
@ -940,7 +930,6 @@ static int
|
||||
vhost_user_check_and_alloc_queue_pair(struct virtio_net *dev, VhostUserMsg *msg)
|
||||
{
|
||||
uint16_t vring_idx;
|
||||
uint16_t qp_idx;
|
||||
|
||||
switch (msg->request) {
|
||||
case VHOST_USER_SET_VRING_KICK:
|
||||
@ -960,17 +949,16 @@ vhost_user_check_and_alloc_queue_pair(struct virtio_net *dev, VhostUserMsg *msg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
qp_idx = vring_idx / VIRTIO_QNUM;
|
||||
if (qp_idx >= VHOST_MAX_QUEUE_PAIRS) {
|
||||
if (vring_idx >= VHOST_MAX_VRING) {
|
||||
RTE_LOG(ERR, VHOST_CONFIG,
|
||||
"invalid vring index: %u\n", vring_idx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dev->virtqueue[qp_idx * VIRTIO_QNUM])
|
||||
if (dev->virtqueue[vring_idx])
|
||||
return 0;
|
||||
|
||||
return alloc_vring_queue_pair(dev, qp_idx);
|
||||
return alloc_vring_queue(dev, vring_idx);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -86,9 +86,9 @@ vhost_log_used_vring(struct virtio_net *dev, struct vhost_virtqueue *vq,
|
||||
}
|
||||
|
||||
static bool
|
||||
is_valid_virt_queue_idx(uint32_t idx, int is_tx, uint32_t qp_nb)
|
||||
is_valid_virt_queue_idx(uint32_t idx, int is_tx, uint32_t nr_vring)
|
||||
{
|
||||
return (is_tx ^ (idx & 1)) == 0 && idx < qp_nb * VIRTIO_QNUM;
|
||||
return (is_tx ^ (idx & 1)) == 0 && idx < nr_vring;
|
||||
}
|
||||
|
||||
static inline void __attribute__((always_inline))
|
||||
@ -283,7 +283,7 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
|
||||
uint32_t i, sz;
|
||||
|
||||
LOG_DEBUG(VHOST_DATA, "(%d) %s\n", dev->vid, __func__);
|
||||
if (unlikely(!is_valid_virt_queue_idx(queue_id, 0, dev->virt_qp_nb))) {
|
||||
if (unlikely(!is_valid_virt_queue_idx(queue_id, 0, dev->nr_vring))) {
|
||||
RTE_LOG(ERR, VHOST_DATA, "(%d) %s: invalid virtqueue idx %d.\n",
|
||||
dev->vid, __func__, queue_id);
|
||||
return 0;
|
||||
@ -554,7 +554,7 @@ virtio_dev_merge_rx(struct virtio_net *dev, uint16_t queue_id,
|
||||
uint16_t avail_head;
|
||||
|
||||
LOG_DEBUG(VHOST_DATA, "(%d) %s\n", dev->vid, __func__);
|
||||
if (unlikely(!is_valid_virt_queue_idx(queue_id, 0, dev->virt_qp_nb))) {
|
||||
if (unlikely(!is_valid_virt_queue_idx(queue_id, 0, dev->nr_vring))) {
|
||||
RTE_LOG(ERR, VHOST_DATA, "(%d) %s: invalid virtqueue idx %d.\n",
|
||||
dev->vid, __func__, queue_id);
|
||||
return 0;
|
||||
@ -1019,7 +1019,7 @@ rte_vhost_dequeue_burst(int vid, uint16_t queue_id,
|
||||
if (!dev)
|
||||
return 0;
|
||||
|
||||
if (unlikely(!is_valid_virt_queue_idx(queue_id, 1, dev->virt_qp_nb))) {
|
||||
if (unlikely(!is_valid_virt_queue_idx(queue_id, 1, dev->nr_vring))) {
|
||||
RTE_LOG(ERR, VHOST_DATA, "(%d) %s: invalid virtqueue idx %d.\n",
|
||||
dev->vid, __func__, queue_id);
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user