[dpdk-dev] [PATCH 3/3] virtio-user: add mq in virtual pci driver
Jianfeng Tan
jianfeng.tan at intel.com
Thu May 5 10:59:41 CEST 2016
Partially implement ctrl-queue to handle control command with class
of VIRTIO_NET_CTRL_MQ and with cmd of VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET
to handle mq support. After filling the command into ctrl-queue, we
dequeue it when notify_queue(), and invoke method from device
emulation to enable/disable queues.
Signed-off-by: Jianfeng Tan <jianfeng.tan at intel.com>
---
drivers/net/virtio/virtio_user/virtio_user_pci.c | 89 +++++++++++++++++++++++-
1 file changed, 87 insertions(+), 2 deletions(-)
diff --git a/drivers/net/virtio/virtio_user/virtio_user_pci.c b/drivers/net/virtio/virtio_user/virtio_user_pci.c
index 873e619..aa02c60 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_pci.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_pci.c
@@ -38,6 +38,7 @@
#include "../virtio_logs.h"
#include "../virtio_pci.h"
#include "../virtqueue.h"
+#include "../virtio_ring.h"
#include "virtio_user_dev.h"
static void
@@ -157,8 +158,10 @@ vdev_setup_queue(struct virtio_hw *hw __rte_unused, struct virtqueue *vq)
if (vq->virtio_net_hdr_mz) {
vq->virtio_net_hdr_mem =
(phys_addr_t)vq->virtio_net_hdr_mz->addr;
- /* Do it one more time after we reset virtio_net_hdr_mem */
- vring_hdr_desc_init(vq);
+
+ /* Do it again after we reset virtio_net_hdr_mem for tx */
+ if ((vq->vq_queue_index % VTNET_CQ) == VTNET_TQ)
+ vring_hdr_desc_init(vq);
}
vq->offset = offsetof(struct rte_mbuf, buf_addr);
return 0;
@@ -182,11 +185,93 @@ vdev_del_queue(struct virtio_hw *hw, struct virtqueue *vq)
close(uhw->kickfds[vq->vq_queue_index]);
}
+static uint8_t
+handle_mq(struct virtqueue *vq, uint16_t queues)
+{
+ struct virtio_hw *hw = vq->hw;
+ struct virtio_user_hw *uhw = (struct virtio_user_hw *)hw->vdev_private;
+ uint32_t i;
+ uint8_t ret = 0;
+
+ if (queues > uhw->max_queue_pairs) {
+ PMD_INIT_LOG(ERR, "multi-q config %u, but only %u supported",
+ queues, uhw->max_queue_pairs);
+ return -1;
+ }
+
+ for (i = 0; i < queues; ++i)
+ ret |= virtio_user_enable_queue_pair(uhw, i, 1);
+ for (i = queues; i < uhw->max_queue_pairs; ++i)
+ ret |= virtio_user_enable_queue_pair(uhw, i, 0);
+
+ return ret;
+}
+
+static uint32_t
+handle_ctrl(struct virtqueue *vq, uint16_t desc_idx_hdr)
+{
+ struct virtio_net_ctrl_hdr *hdr;
+ virtio_net_ctrl_ack status = ~0;
+ uint16_t i, desc_idx_data, desc_idx_status;
+ uint32_t num_of_descs = 0;
+
+ /* locate desc for header, data, and status */
+ desc_idx_data = vq->vq_ring.desc[desc_idx_hdr].next;
+ num_of_descs++;
+
+
+ i = desc_idx_data;
+ while (vq->vq_ring.desc[i].flags == VRING_DESC_F_NEXT) {
+ i = vq->vq_ring.desc[i].next;
+ num_of_descs++;
+ }
+
+ /* locate desc for status */
+ desc_idx_status = i;
+ num_of_descs++;
+
+ hdr = (struct virtio_net_ctrl_hdr *)vq->vq_ring.desc[desc_idx_hdr].addr;
+ if (hdr->class == VIRTIO_NET_CTRL_MQ &&
+ hdr->cmd == VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET) {
+ uint16_t queues;
+
+ queues = *(uint16_t *)vq->vq_ring.desc[desc_idx_data].addr;
+ status = handle_mq(vq, queues);
+ }
+
+ /* Update status */
+ *(virtio_net_ctrl_ack *)vq->vq_ring.desc[desc_idx_status].addr = status;
+
+ return num_of_descs;
+}
+
static void
vdev_notify_queue(struct virtio_hw *hw, struct virtqueue *vq)
{
uint64_t buf = 1;
struct virtio_user_hw *uhw = (struct virtio_user_hw *)hw->vdev_private;
+ uint16_t avail_idx, desc_idx;
+ struct vring_used_elem *uep;
+ uint32_t num_of_descs;
+
+ if (vq == hw->cvq) {
+ /* Consume avail ring, using used ring idx as first one */
+ while (vq->vq_ring.used->idx != vq->vq_ring.avail->idx) {
+ avail_idx = (vq->vq_ring.used->idx) &
+ (vq->vq_nentries - 1);
+ desc_idx = vq->vq_ring.avail->ring[avail_idx];
+
+ num_of_descs = handle_ctrl(vq, desc_idx);
+
+ /* Update used ring */
+ uep = &vq->vq_ring.used->ring[avail_idx];
+ uep->id = avail_idx;
+ uep->len = num_of_descs;
+
+ vq->vq_ring.used->idx++;
+ }
+ return;
+ }
if (write(uhw->kickfds[vq->vq_queue_index], &buf, sizeof(buf)) < 0)
PMD_DRV_LOG(ERR, "failed to kick backend: %s\n", strerror(errno));
--
2.1.4
More information about the dev
mailing list