diff mbox series

[ovs-dev,v4] netdev-dpdk:add set_queue datapath dpdk support

Message ID 1688632035-12346-1-git-send-email-ciel_wang@126.com
State Rejected
Headers show
Series [ovs-dev,v4] netdev-dpdk:add set_queue datapath dpdk support | expand

Checks

Context Check Description
ovsrobot/intel-ovs-compilation success test: success
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test success github build: passed

Commit Message

wangze July 6, 2023, 8:27 a.m. UTC
When doing set_queue action, skb_priority is marked in
userspace, but there is no further processing in datapath
dpdk. This patch add set_queue support in datapath dpdk,
sending skbs from specific queues according to the
skb_priority.

The enqueue action can be applied to the scenario of
double-sending arp packets in bond, usage:
ovs-ofctl add-flow br-ext "priority=10000,in_port=LOCAL,arp actions=push_vlan:
0x8100,set_field:4397->vlan_vid,set_queue:1,output:bond1,pop_queue,set_queue:2,
output:bond1,pop_queue" -Oopenflow13

Signed-off-by: wangze <ciel_wang@126.com>
Reviewed-by: wenxu <wenxu@chinatelecom.cn>
---
 lib/dpif-netdev.c | 43 +++++++++++++++++++++++++++++++++++++------
 1 file changed, 37 insertions(+), 6 deletions(-)

Comments

Ilya Maximets July 7, 2023, 2 p.m. UTC | #1
On 7/6/23 10:27, wangze wrote:
> When doing set_queue action, skb_priority is marked in
> userspace, but there is no further processing in datapath
> dpdk.

Hi.  There actually is further processing for dpdk ports.

The naming is confusing, I understand that, but set_queue OpenFlow
action actually has nothing in common with hardware Tx queues of
the device.  These are QoS queues configured in the database in
QoS table.  And netdev-dpdk makes use of them via Two Rate Three
Color Marker policing (trtcm-policer).  You can find documentation
for it here:
  https://docs.openvswitch.org/en/latest/topics/dpdk/qos/#multi-queue-policer
Or in the ovs-vswitchd.conf.db (5) man page.

The general QoS with set_queue examples can be found here:
  https://docs.openvswitch.org/en/latest/faq/qos/#quality-of-service-qos

In general, we shouldn't overload the meaning of the action.
And there are no high-level OpenFlow fileds or actions that
work with hardware Rx/Tx queues, AFAIK.  And there shouldn't be
as OpenFlow is a much higher abstraction.

> This patch add set_queue support in datapath dpdk,
> sending skbs from specific queues according to the
> skb_priority.
> 
> The enqueue action can be applied to the scenario of
> double-sending arp packets in bond, usage:
> ovs-ofctl add-flow br-ext "priority=10000,in_port=LOCAL,arp actions=push_vlan:
> 0x8100,set_field:4397->vlan_vid,set_queue:1,output:bond1,pop_queue,set_queue:2,
> output:bond1,pop_queue" -Oopenflow13

Why do you need to double-send ARP packets?
And why they need to go to different hardware queues?

Best regards, Ilya Maximets.
diff mbox series

Patch

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index ab493f9..4bf36fd 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -5259,6 +5259,31 @@  pmd_perf_metrics_enabled(const struct dp_netdev_pmd_thread *pmd OVS_UNUSED)
 }
 #endif
 
+
+#ifdef DPDK_NETDEV
+static int
+dp_netdev_pmd_flush_txqs_on_port(struct dp_netdev_pmd_thread *pmd,
+                                   struct tx_port *p)
+{
+    int i;
+    int output_cnt = 0;
+
+    int n_txq = netdev_n_txq(p->port->netdev);
+
+    for (i = 0; i < n_txq; i++) {
+        if (dp_packet_batch_is_empty(&p->txq_pkts[i])) {
+            continue;
+        }
+        output_cnt += dp_packet_batch_size(&p->txq_pkts[i]);
+        netdev_send(p->port->netdev, i, &p->txq_pkts[i], true);
+        dp_packet_batch_init(&p->txq_pkts[i]);
+    }
+
+    pmd_perf_update_counter(&pmd->perf_stats, PMD_STAT_SENT_PKTS, output_cnt);
+    return output_cnt;
+}
+#endif
+
 static int
 dp_netdev_pmd_flush_output_on_port(struct dp_netdev_pmd_thread *pmd,
                                    struct tx_port *p)
@@ -7799,13 +7824,11 @@  dp_netdev_add_port_tx_to_pmd(struct dp_netdev_pmd_thread *pmd,
     tx->flush_time = 0LL;
     dp_packet_batch_init(&tx->output_pkts);
 
-    if (tx->port->txq_mode == TXQ_MODE_XPS_HASH) {
-        int i, n_txq = netdev_n_txq(tx->port->netdev);
+    int i, n_txq = netdev_n_txq(tx->port->netdev);
 
-        tx->txq_pkts = xzalloc(n_txq * sizeof *tx->txq_pkts);
-        for (i = 0; i < n_txq; i++) {
-            dp_packet_batch_init(&tx->txq_pkts[i]);
-        }
+    tx->txq_pkts = xzalloc(n_txq * sizeof *tx->txq_pkts);
+    for (i = 0; i < n_txq; i++) {
+        dp_packet_batch_init(&tx->txq_pkts[i]);
     }
 
     hmap_insert(&pmd->tx_ports, &tx->node, hash_port_no(tx->port->port_no));
@@ -8832,6 +8855,7 @@  dp_execute_output_action(struct dp_netdev_pmd_thread *pmd,
     }
     dp_packet_batch_apply_cutlen(packets_);
 #ifdef DPDK_NETDEV
+    dp_netdev_pmd_flush_txqs_on_port(pmd, p);
     if (OVS_UNLIKELY(!dp_packet_batch_is_empty(&p->output_pkts)
                      && packets_->packets[0]->source
                         != p->output_pkts.packets[0]->source)) {
@@ -8851,9 +8875,16 @@  dp_execute_output_action(struct dp_netdev_pmd_thread *pmd,
     }
 
     struct dp_packet *packet;
+    int n_txq = netdev_n_txq(p->port->netdev);
     DP_PACKET_BATCH_FOR_EACH (i, packet, packets_) {
         p->output_pkts_rxqs[dp_packet_batch_size(&p->output_pkts)] =
             pmd->ctx.last_rxq;
+        if (packet->md.skb_priority) {
+            dp_packet_batch_add(
+                &p->txq_pkts[packet->md.skb_priority % n_txq - 1],
+                packet);
+            continue;
+        }
         dp_packet_batch_add(&p->output_pkts, packet);
     }
     return true;