[dpdk-dev,v2,2/7] virtio: add software rx ring, fake_buf into virtqueue
Commit Message
Add software RX ring in virtqueue.
Add fake_mbuf in virtqueue for wraparound processing.
Use global simple_rxtx to indicate whether simple rxtx is enabled
Signed-off-by: Huawei Xie <huawei.xie@intel.com>
---
drivers/net/virtio/virtio_ethdev.c | 12 ++++++++++++
drivers/net/virtio/virtio_rxtx.c | 7 +++++++
drivers/net/virtio/virtqueue.h | 4 ++++
3 files changed, 23 insertions(+)
Comments
On Sun, 18 Oct 2015 14:28:59 +0800
Huawei Xie <huawei.xie@intel.com> wrote:
> + if (vq->sw_ring)
> + rte_free(vq->sw_ring);
> +
Do not need to test for NULL before calling rte_free.
Better to just rely on the fact that rte_free(NULL) is documented
to be ok (no operation).
On 10/19/2015 12:20 PM, Stephen Hemminger wrote:
On Sun, 18 Oct 2015 14:28:59 +0800
Huawei Xie <huawei.xie@intel.com><mailto:huawei.xie@intel.com> wrote:
+ if (vq->sw_ring)
+ rte_free(vq->sw_ring);
+
Do not need to test for NULL before calling rte_free.
Better to just rely on the fact that rte_free(NULL) is documented
to be ok (no operation).
ok, btw, in previous commit, just in the same function,
void virtio_dev_queue_release(vq)
[...]
rte_free(vq);
vq = NULL;
I think there is no need to set NULL to vq. Will submit a patch to fix it if you agree.
On 10/19/2015 1:07 PM, Xie, Huawei wrote:
> On 10/19/2015 12:20 PM, Stephen Hemminger wrote:
>
> On Sun, 18 Oct 2015 14:28:59 +0800
> Huawei Xie <huawei.xie@intel.com><mailto:huawei.xie@intel.com> wrote:
>
>
>
> + if (vq->sw_ring)
> + rte_free(vq->sw_ring);
> +
>
>
>
> Do not need to test for NULL before calling rte_free.
> Better to just rely on the fact that rte_free(NULL) is documented
> to be ok (no operation).
>
>
>
> ok, btw, in previous commit, just in the same function,
> void virtio_dev_queue_release(vq)
> [...]
>
> rte_free(vq);
>
> vq = NULL;
> I think there is no need to set NULL to vq. Will submit a patch to fix it if you agree.
In v3 patch, i also remove the "vq = NULL".
>
>
@@ -247,6 +247,9 @@ virtio_dev_queue_release(struct virtqueue *vq) {
VIRTIO_WRITE_REG_2(hw, VIRTIO_PCI_QUEUE_SEL, vq->queue_id);
VIRTIO_WRITE_REG_4(hw, VIRTIO_PCI_QUEUE_PFN, 0);
+ if (vq->sw_ring)
+ rte_free(vq->sw_ring);
+
rte_free(vq);
vq = NULL;
}
@@ -292,6 +295,9 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
dev->data->port_id, queue_idx);
vq = rte_zmalloc(vq_name, sizeof(struct virtqueue) +
vq_size * sizeof(struct vq_desc_extra), RTE_CACHE_LINE_SIZE);
+ vq->sw_ring = rte_zmalloc_socket("rxq->sw_ring",
+ (RTE_PMD_VIRTIO_RX_MAX_BURST + vq_size) *
+ sizeof(vq->sw_ring[0]), RTE_CACHE_LINE_SIZE, socket_id);
} else if (queue_type == VTNET_TQ) {
snprintf(vq_name, sizeof(vq_name), "port%d_tvq%d",
dev->data->port_id, queue_idx);
@@ -308,6 +314,12 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
PMD_INIT_LOG(ERR, "%s: Can not allocate virtqueue", __func__);
return (-ENOMEM);
}
+ if (queue_type == VTNET_RQ && vq->sw_ring == NULL) {
+ PMD_INIT_LOG(ERR, "%s: Can not allocate RX soft ring",
+ __func__);
+ rte_free(vq);
+ return -ENOMEM;
+ }
vq->hw = hw;
vq->port_id = dev->data->port_id;
@@ -62,6 +62,8 @@
#define VIRTIO_DUMP_PACKET(m, len) do { } while (0)
#endif
+static int use_simple_rxtx;
+
static void
vq_ring_free_chain(struct virtqueue *vq, uint16_t desc_idx)
{
@@ -299,6 +301,11 @@ virtio_dev_vring_start(struct virtqueue *vq, int queue_type)
/* Allocate blank mbufs for the each rx descriptor */
nbufs = 0;
error = ENOSPC;
+
+ memset(&vq->fake_mbuf, 0, sizeof(vq->fake_mbuf));
+ for (i = 0; i < RTE_PMD_VIRTIO_RX_MAX_BURST; i++)
+ vq->sw_ring[vq->vq_nentries + i] = &vq->fake_mbuf;
+
while (!virtqueue_full(vq)) {
m = rte_rxmbuf_alloc(vq->mpool);
if (m == NULL)
@@ -190,6 +190,10 @@ struct virtqueue {
uint16_t vq_avail_idx;
phys_addr_t virtio_net_hdr_mem; /**< hdr for each xmit packet */
+ struct rte_mbuf **sw_ring; /**< RX software ring. */
+ /* dummy mbuf, for wraparound when processing RX ring. */
+ struct rte_mbuf fake_mbuf;
+
/* Statistics */
uint64_t packets;
uint64_t bytes;