[dpdk-dev] [PATCH v2 3/6] vhost: log used vring changes
Yuanhan Liu
yuanhan.liu at linux.intel.com
Thu Dec 17 04:11:58 CET 2015
Introducing a vhost_log_write() wrapper, vhost_log_used_vring, to
log used vring changes.
Signed-off-by: Yuanhan Liu <yuanhan.liu at linux.intel.com>
Signed-off-by: Victor Kaplansky <victork at redhat.com
---
lib/librte_vhost/rte_virtio_net.h | 3 +-
lib/librte_vhost/vhost_rxtx.c | 80 +++++++++++++++++++++++++++------------
lib/librte_vhost/virtio-net.c | 4 ++
3 files changed, 62 insertions(+), 25 deletions(-)
diff --git a/lib/librte_vhost/rte_virtio_net.h b/lib/librte_vhost/rte_virtio_net.h
index 5726683..0f83719 100644
--- a/lib/librte_vhost/rte_virtio_net.h
+++ b/lib/librte_vhost/rte_virtio_net.h
@@ -93,7 +93,8 @@ struct vhost_virtqueue {
int callfd; /**< Used to notify the guest (trigger interrupt). */
int kickfd; /**< Currently unused as polling mode is enabled. */
int enabled;
- uint64_t reserved[16]; /**< Reserve some spaces for future extension. */
+ uint64_t log_guest_addr; /**< Physical address of used ring, for logging */
+ uint64_t reserved[15]; /**< Reserve some spaces for future extension. */
struct buf_vector buf_vec[BUF_VECTOR_MAX]; /**< for scatter RX. */
} __rte_cache_aligned;
diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
index bbf3fac..f305acd 100644
--- a/lib/librte_vhost/vhost_rxtx.c
+++ b/lib/librte_vhost/vhost_rxtx.c
@@ -49,6 +49,16 @@ is_valid_virt_queue_idx(uint32_t idx, int is_tx, uint32_t qp_nb)
return (is_tx ^ (idx & 1)) == 0 && idx < qp_nb * VIRTIO_QNUM;
}
+static inline void __attribute__((always_inline))
+vhost_log_used_vring(struct virtio_net *dev, struct vhost_virtqueue *vq,
+ uint64_t offset, uint64_t len)
+{
+ uint64_t addr;
+
+ addr = vq->log_guest_addr + offset;
+ vhost_log_write(dev, addr, len);
+}
+
/**
* This function adds buffers to the virtio devices RX virtqueue. Buffers can
* be received from the physical port or from another virtio device. A packet
@@ -129,6 +139,7 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
uint32_t offset = 0, vb_offset = 0;
uint32_t pkt_len, len_to_cpy, data_len, total_copied = 0;
uint8_t hdr = 0, uncompleted_pkt = 0;
+ uint16_t idx;
/* Get descriptor from available ring */
desc = &vq->desc[head[packet_success]];
@@ -200,16 +211,18 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
}
/* Update used ring with desc information */
- vq->used->ring[res_cur_idx & (vq->size - 1)].id =
- head[packet_success];
+ idx = res_cur_idx & (vq->size - 1);
+ vq->used->ring[idx].id = head[packet_success];
/* Drop the packet if it is uncompleted */
if (unlikely(uncompleted_pkt == 1))
- vq->used->ring[res_cur_idx & (vq->size - 1)].len =
- vq->vhost_hlen;
+ vq->used->ring[idx].len = vq->vhost_hlen;
else
- vq->used->ring[res_cur_idx & (vq->size - 1)].len =
- pkt_len + vq->vhost_hlen;
+ vq->used->ring[idx].len = pkt_len + vq->vhost_hlen;
+
+ vhost_log_used_vring(dev, vq,
+ offsetof(struct vring_used, ring[idx]),
+ sizeof(vq->used->ring[idx]));
res_cur_idx++;
packet_success++;
@@ -236,6 +249,9 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
*(volatile uint16_t *)&vq->used->idx += count;
vq->last_used_idx = res_end_idx;
+ vhost_log_used_vring(dev, vq,
+ offsetof(struct vring_used, idx),
+ sizeof(vq->used->idx));
/* flush used->idx update before we read avail->flags. */
rte_mb();
@@ -265,6 +281,7 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
uint32_t seg_avail;
uint32_t vb_avail;
uint32_t cpy_len, entry_len;
+ uint16_t idx;
if (pkt == NULL)
return 0;
@@ -302,16 +319,18 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
entry_len = vq->vhost_hlen;
if (vb_avail == 0) {
- uint32_t desc_idx =
- vq->buf_vec[vec_idx].desc_idx;
+ uint32_t desc_idx = vq->buf_vec[vec_idx].desc_idx;
+
+ if ((vq->desc[desc_idx].flags & VRING_DESC_F_NEXT) == 0) {
+ idx = cur_idx & (vq->size - 1);
- if ((vq->desc[desc_idx].flags
- & VRING_DESC_F_NEXT) == 0) {
/* Update used ring with desc information */
- vq->used->ring[cur_idx & (vq->size - 1)].id
- = vq->buf_vec[vec_idx].desc_idx;
- vq->used->ring[cur_idx & (vq->size - 1)].len
- = entry_len;
+ vq->used->ring[idx].id = vq->buf_vec[vec_idx].desc_idx;
+ vq->used->ring[idx].len = entry_len;
+
+ vhost_log_used_vring(dev, vq,
+ offsetof(struct vring_used, ring[idx]),
+ sizeof(vq->used->ring[idx]));
entry_len = 0;
cur_idx++;
@@ -354,10 +373,13 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
if ((vq->desc[vq->buf_vec[vec_idx].desc_idx].flags &
VRING_DESC_F_NEXT) == 0) {
/* Update used ring with desc information */
- vq->used->ring[cur_idx & (vq->size - 1)].id
+ idx = cur_idx & (vq->size - 1);
+ vq->used->ring[idx].id
= vq->buf_vec[vec_idx].desc_idx;
- vq->used->ring[cur_idx & (vq->size - 1)].len
- = entry_len;
+ vq->used->ring[idx].len = entry_len;
+ vhost_log_used_vring(dev, vq,
+ offsetof(struct vring_used, ring[idx]),
+ sizeof(vq->used->ring[idx]));
entry_len = 0;
cur_idx++;
entry_success++;
@@ -390,16 +412,18 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
if ((vq->desc[desc_idx].flags &
VRING_DESC_F_NEXT) == 0) {
- uint16_t wrapped_idx =
- cur_idx & (vq->size - 1);
+ idx = cur_idx & (vq->size - 1);
/*
* Update used ring with the
* descriptor information
*/
- vq->used->ring[wrapped_idx].id
+ vq->used->ring[idx].id
= desc_idx;
- vq->used->ring[wrapped_idx].len
+ vq->used->ring[idx].len
= entry_len;
+ vhost_log_used_vring(dev, vq,
+ offsetof(struct vring_used, ring[idx]),
+ sizeof(vq->used->ring[idx]));
entry_success++;
entry_len = 0;
cur_idx++;
@@ -422,10 +446,13 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id,
* This whole packet completes.
*/
/* Update used ring with desc information */
- vq->used->ring[cur_idx & (vq->size - 1)].id
+ idx = cur_idx & (vq->size - 1);
+ vq->used->ring[idx].id
= vq->buf_vec[vec_idx].desc_idx;
- vq->used->ring[cur_idx & (vq->size - 1)].len
- = entry_len;
+ vq->used->ring[idx].len = entry_len;
+ vhost_log_used_vring(dev, vq,
+ offsetof(struct vring_used, ring[idx]),
+ sizeof(vq->used->ring[idx]));
entry_success++;
break;
}
@@ -653,6 +680,9 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id,
/* Update used index buffer information. */
vq->used->ring[used_idx].id = head[entry_success];
vq->used->ring[used_idx].len = 0;
+ vhost_log_used_vring(dev, vq,
+ offsetof(struct vring_used, ring[used_idx]),
+ sizeof(vq->used->ring[used_idx]));
/* Allocate an mbuf and populate the structure. */
m = rte_pktmbuf_alloc(mbuf_pool);
@@ -773,6 +803,8 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id,
rte_compiler_barrier();
vq->used->idx += entry_success;
+ vhost_log_used_vring(dev, vq, offsetof(struct vring_used, idx),
+ sizeof(vq->used->idx));
/* Kick guest if required. */
if (!(vq->avail->flags & VRING_AVAIL_F_NO_INTERRUPT))
eventfd_write(vq->callfd, (eventfd_t)1);
diff --git a/lib/librte_vhost/virtio-net.c b/lib/librte_vhost/virtio-net.c
index de78a0f..03044f6 100644
--- a/lib/librte_vhost/virtio-net.c
+++ b/lib/librte_vhost/virtio-net.c
@@ -666,12 +666,16 @@ set_vring_addr(struct vhost_device_ctx ctx, struct vhost_vring_addr *addr)
return -1;
}
+ vq->log_guest_addr = addr->log_guest_addr;
+
LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") mapped address desc: %p\n",
dev->device_fh, vq->desc);
LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") mapped address avail: %p\n",
dev->device_fh, vq->avail);
LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") mapped address used: %p\n",
dev->device_fh, vq->used);
+ LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") log_guest_addr: %"PRIx64"\n",
+ dev->device_fh, vq->log_guest_addr);
return 0;
}
--
1.9.0
More information about the dev
mailing list