If implememented, this function returns the number of packets in an rx
queue of the netdev. If not implemented, it returns -1.

This function 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 <[email protected]>
---
 lib/netdev-bsd.c      |  1 +
 lib/netdev-dpdk.c     | 36 +++++++++++++++++++++++++++++++-----
 lib/netdev-dummy.c    |  1 +
 lib/netdev-linux.c    |  1 +
 lib/netdev-provider.h |  3 +++
 lib/netdev-vport.c    |  1 +
 lib/netdev.c          |  9 +++++++++
 lib/netdev.h          |  1 +
 8 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/lib/netdev-bsd.c b/lib/netdev-bsd.c
index 05974c1..8d1771e 100644
--- a/lib/netdev-bsd.c
+++ b/lib/netdev-bsd.c
@@ -1546,6 +1546,7 @@ netdev_bsd_update_flags(struct netdev *netdev_, enum 
netdev_flags off,
     netdev_bsd_rxq_recv,                             \
     netdev_bsd_rxq_wait,                             \
     netdev_bsd_rxq_drain,                            \
+    NULL, /* rxq_length */                           \
                                                      \
     NO_OFFLOAD_API                                   \
 }
diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index ccda3fc..4200556 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -1839,6 +1839,27 @@ netdev_dpdk_rxq_recv(struct netdev_rxq *rxq, struct 
dp_packet_batch *batch)
     return 0;
 }
 
+static int
+netdev_dpdk_vhost_rxq_length(struct netdev_rxq *rxq)
+{
+    struct netdev_dpdk *dev = netdev_dpdk_cast(rxq->netdev);
+    int qid = rxq->queue_id;
+
+    /* The DPDK API returns a uint32_t which often has invalid bits in the
+     * upper 16-bits. Need to restrict the value uint16_t. */
+    return rte_vhost_rx_queue_count(netdev_dpdk_get_vid(dev),
+                                    qid * VIRTIO_QNUM + VIRTIO_TXQ)
+                & UINT16_MAX;
+}
+
+static int
+netdev_dpdk_rxq_length(struct netdev_rxq *rxq)
+{
+    struct netdev_rxq_dpdk *rx = netdev_rxq_dpdk_cast(rxq);
+
+    return rte_eth_rx_queue_count(rx->port_id, rxq->queue_id);
+}
+
 static inline int
 netdev_dpdk_qos_run(struct netdev_dpdk *dev, struct rte_mbuf **pkts,
                     int cnt, bool may_steal)
@@ -3580,7 +3601,7 @@ unlock:
                           GET_CARRIER, GET_STATS,                        \
                           GET_CUSTOM_STATS,                                    
  \
                           GET_FEATURES, GET_STATUS,           \
-                          RECONFIGURE, RXQ_RECV)              \
+                          RECONFIGURE, RXQ_RECV, RXQ_LENGTH)  \
 {                                                             \
     NAME,                                                     \
     true,                       /* is_pmd */                  \
@@ -3649,6 +3670,7 @@ unlock:
     RXQ_RECV,                                                 \
     NULL,                       /* rx_wait */                 \
     NULL,                       /* rxq_drain */               \
+    RXQ_LENGTH,                                               \
     NO_OFFLOAD_API                                            \
 }
 
@@ -3667,7 +3689,8 @@ static const struct netdev_class dpdk_class =
         netdev_dpdk_get_features,
         netdev_dpdk_get_status,
         netdev_dpdk_reconfigure,
-        netdev_dpdk_rxq_recv);
+        netdev_dpdk_rxq_recv,
+        netdev_dpdk_rxq_length);
 
 static const struct netdev_class dpdk_ring_class =
     NETDEV_DPDK_CLASS(
@@ -3684,7 +3707,8 @@ static const struct netdev_class dpdk_ring_class =
         netdev_dpdk_get_features,
         netdev_dpdk_get_status,
         netdev_dpdk_reconfigure,
-        netdev_dpdk_rxq_recv);
+        netdev_dpdk_rxq_recv,
+        NULL);
 
 static const struct netdev_class dpdk_vhost_class =
     NETDEV_DPDK_CLASS(
@@ -3701,7 +3725,8 @@ static const struct netdev_class dpdk_vhost_class =
         NULL,
         NULL,
         netdev_dpdk_vhost_reconfigure,
-        netdev_dpdk_vhost_rxq_recv);
+        netdev_dpdk_vhost_rxq_recv,
+        netdev_dpdk_vhost_rxq_length);
 static const struct netdev_class dpdk_vhost_client_class =
     NETDEV_DPDK_CLASS(
         "dpdkvhostuserclient",
@@ -3717,7 +3742,8 @@ static const struct netdev_class dpdk_vhost_client_class =
         NULL,
         NULL,
         netdev_dpdk_vhost_client_reconfigure,
-        netdev_dpdk_vhost_rxq_recv);
+        netdev_dpdk_vhost_rxq_recv,
+        netdev_dpdk_vhost_rxq_length);
 
 void
 netdev_dpdk_register(void)
diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c
index 4246af3..7e2c0a2 100644
--- a/lib/netdev-dummy.c
+++ b/lib/netdev-dummy.c
@@ -1457,6 +1457,7 @@ netdev_dummy_update_flags(struct netdev *netdev_,
     netdev_dummy_rxq_recv,                                      \
     netdev_dummy_rxq_wait,                                      \
     netdev_dummy_rxq_drain,                                     \
+    NULL,                       /* rxq_length */                \
                                                                 \
     NO_OFFLOAD_API                                              \
 }
diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
index 37143b8..8b19890 100644
--- a/lib/netdev-linux.c
+++ b/lib/netdev-linux.c
@@ -2890,6 +2890,7 @@ netdev_linux_update_flags(struct netdev *netdev_, enum 
netdev_flags off,
     netdev_linux_rxq_recv,                                      \
     netdev_linux_rxq_wait,                                      \
     netdev_linux_rxq_drain,                                     \
+    NULL,                       /* rxq_length */                \
                                                                 \
     FLOW_OFFLOAD_API                                            \
 }
diff --git a/lib/netdev-provider.h b/lib/netdev-provider.h
index 25bd671..297644a 100644
--- a/lib/netdev-provider.h
+++ b/lib/netdev-provider.h
@@ -801,6 +801,9 @@ struct netdev_class {
     /* Discards all packets waiting to be received from 'rx'. */
     int (*rxq_drain)(struct netdev_rxq *rx);
 
+    /* Retrieve the number of packets present in an rx queue. */
+    int (*rxq_length)(struct netdev_rxq *rx);
+
     /* ## -------------------------------- ## */
     /* ## netdev flow offloading functions ## */
     /* ## -------------------------------- ## */
diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
index 478ed90..1e7bc96 100644
--- a/lib/netdev-vport.c
+++ b/lib/netdev-vport.c
@@ -944,6 +944,7 @@ netdev_vport_get_ifindex(const struct netdev *netdev_)
     NULL,                   /* rx_recv */                   \
     NULL,                   /* rx_wait */                   \
     NULL,                   /* rx_drain */                  \
+    NULL,                   /* rx_length */                 \
                                                             \
     NETDEV_FLOW_OFFLOAD_API
 
diff --git a/lib/netdev.c b/lib/netdev.c
index be05dc6..063c318 100644
--- a/lib/netdev.c
+++ b/lib/netdev.c
@@ -724,6 +724,15 @@ netdev_rxq_drain(struct netdev_rxq *rx)
             : 0);
 }
 
+/* Retrieve the number of packets present in an rx queue. */
+int
+netdev_rxq_length(struct netdev_rxq *rx)
+{
+    return (rx->netdev->netdev_class->rxq_length
+            ? rx->netdev->netdev_class->rxq_length(rx)
+            : -1);
+}
+
 /* Configures the number of tx queues of 'netdev'. Returns 0 if successful,
  * otherwise a positive errno value.
  *
diff --git a/lib/netdev.h b/lib/netdev.h
index ff1b604..edd41b1 100644
--- a/lib/netdev.h
+++ b/lib/netdev.h
@@ -178,6 +178,7 @@ int netdev_rxq_get_queue_id(const struct netdev_rxq *);
 int netdev_rxq_recv(struct netdev_rxq *rx, struct dp_packet_batch *);
 void netdev_rxq_wait(struct netdev_rxq *);
 int netdev_rxq_drain(struct netdev_rxq *);
+int netdev_rxq_length(struct netdev_rxq *rx);
 
 /* Packet transmission. */
 int netdev_send(struct netdev *, int qid, struct dp_packet_batch *,
-- 
1.9.1

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to