If the caller provides a non-NULL qfill pointer and the netdev
implemementation supports reading the rx queue fill level, the rxq_recv()
function returns the remaining number of packets in the rx queue after
reception of the packet burst to the caller. If the implementation does
not support this, it returns -ENOTSUP instead. Reading the remaining queue
fill level should not substantilly slow down the recv() operation.
A first implementation is provided for ethernet and vhostuser DPDK ports
in netdev-dpdk.c.
This output parameter will be used in the upcoming commit for PMD
performance metrics to supervise the rx queue fill level for DPDK
vhostuser ports.
Signed-off-by: Jan Scheurich
Acked-by: Billy O'Mahony
---
lib/dpif-netdev.c | 2 +-
lib/netdev-bsd.c | 8 +++-
lib/netdev-dpdk.c | 41 -
lib/netdev-dummy.c| 8 +++-
lib/netdev-linux.c| 7 ++-
lib/netdev-provider.h | 7 ++-
lib/netdev.c | 5 +++--
lib/netdev.h | 3 ++-
8 files changed, 68 insertions(+), 13 deletions(-)
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index be31fd0..7ce3943 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -3277,7 +3277,7 @@ dp_netdev_process_rxq_port(struct dp_netdev_pmd_thread
*pmd,
pmd->ctx.last_rxq = rxq;
dp_packet_batch_init(&batch);
-error = netdev_rxq_recv(rxq->rx, &batch);
+error = netdev_rxq_recv(rxq->rx, &batch, NULL);
if (!error) {
/* At least one packet received. */
*recirc_depth_get() = 0;
diff --git a/lib/netdev-bsd.c b/lib/netdev-bsd.c
index 05974c1..b70f327 100644
--- a/lib/netdev-bsd.c
+++ b/lib/netdev-bsd.c
@@ -618,7 +618,8 @@ netdev_rxq_bsd_recv_tap(struct netdev_rxq_bsd *rxq, struct
dp_packet *buffer)
}
static int
-netdev_bsd_rxq_recv(struct netdev_rxq *rxq_, struct dp_packet_batch *batch)
+netdev_bsd_rxq_recv(struct netdev_rxq *rxq_, struct dp_packet_batch *batch,
+int *qfill)
{
struct netdev_rxq_bsd *rxq = netdev_rxq_bsd_cast(rxq_);
struct netdev *netdev = rxq->up.netdev;
@@ -643,6 +644,11 @@ netdev_bsd_rxq_recv(struct netdev_rxq *rxq_, struct
dp_packet_batch *batch)
batch->packets[0] = packet;
batch->count = 1;
}
+
+if (qfill) {
+*qfill = -ENOTSUP;
+}
+
return retval;
}
diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index ee39cbe..a4fc382 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -1812,13 +1812,13 @@ netdev_dpdk_vhost_update_rx_counters(struct
netdev_stats *stats,
*/
static int
netdev_dpdk_vhost_rxq_recv(struct netdev_rxq *rxq,
- struct dp_packet_batch *batch)
+ struct dp_packet_batch *batch, int *qfill)
{
struct netdev_dpdk *dev = netdev_dpdk_cast(rxq->netdev);
struct ingress_policer *policer = netdev_dpdk_get_ingress_policer(dev);
uint16_t nb_rx = 0;
uint16_t dropped = 0;
-int qid = rxq->queue_id;
+int qid = rxq->queue_id * VIRTIO_QNUM + VIRTIO_TXQ;
int vid = netdev_dpdk_get_vid(dev);
if (OVS_UNLIKELY(vid < 0 || !dev->vhost_reconfigured
@@ -1826,14 +1826,23 @@ netdev_dpdk_vhost_rxq_recv(struct netdev_rxq *rxq,
return EAGAIN;
}
-nb_rx = rte_vhost_dequeue_burst(vid, qid * VIRTIO_QNUM + VIRTIO_TXQ,
-dev->mp,
+nb_rx = rte_vhost_dequeue_burst(vid, qid, dev->mp,
(struct rte_mbuf **) batch->packets,
NETDEV_MAX_BURST);
if (!nb_rx) {
return EAGAIN;
}
+if (qfill) {
+if (nb_rx == NETDEV_MAX_BURST) {
+/* The DPDK API returns a uint32_t which often has invalid bits in
+ * the upper 16-bits. Need to restrict the value to uint16_t. */
+*qfill = rte_vhost_rx_queue_count(vid, qid) & UINT16_MAX;
+} else {
+*qfill = 0;
+}
+}
+
if (policer) {
dropped = nb_rx;
nb_rx = ingress_policer_run(policer,
@@ -1854,7 +1863,8 @@ netdev_dpdk_vhost_rxq_recv(struct netdev_rxq *rxq,
}
static int
-netdev_dpdk_rxq_recv(struct netdev_rxq *rxq, struct dp_packet_batch *batch)
+netdev_dpdk_rxq_recv(struct netdev_rxq *rxq, struct dp_packet_batch *batch,
+ int *qfill)
{
struct netdev_rxq_dpdk *rx = netdev_rxq_dpdk_cast(rxq);
struct netdev_dpdk *dev = netdev_dpdk_cast(rxq->netdev);
@@ -1891,6 +1901,14 @@ netdev_dpdk_rxq_recv(struct netdev_rxq *rxq, struct
dp_packet_batch *batch)
batch->count = nb_rx;
dp_packet_batch_init_packet_fields(batch);
+if (qfill) {
+if (nb_rx == NETDEV_MAX_BURST) {
+*qfill = rte_eth_rx_queue_count(rx->port_id, rxq->queue_id);
+} else {
+*qfill = 0;
+}
+}
+
return 0;
}
@@ -3172,6 +3190,19 @@ vring_state_changed(int vid, uint16_t queue_id, int
enable)
return 0;
}
+/*
+ * Retrieve the DPDK virt