From: Lin Huang <linhu...@ruijie.com.cn>

add netdev-dpdk egress pkts policer.

Signed-off-by: Lin Huang <linhu...@ruijie.com.cn>
---
 lib/netdev-dpdk.c    | 118 +++++++++++++++++++++++++++++++++++++++++++
 vswitchd/vswitch.xml |  32 ++++++++++++
 2 files changed, 150 insertions(+)

diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index fb0dd43f7..6709c459c 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -19,6 +19,7 @@
 
 #include <errno.h>
 #include <signal.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -59,6 +60,7 @@
 #include "openvswitch/ofp-parse.h"
 #include "openvswitch/ofp-print.h"
 #include "openvswitch/shash.h"
+#include "openvswitch/token-bucket.h"
 #include "openvswitch/vlog.h"
 #include "ovs-numa.h"
 #include "ovs-rcu.h"
@@ -345,6 +347,7 @@ struct dpdk_qos_ops {
 
 /* dpdk_qos_ops for each type of user space QoS implementation. */
 static const struct dpdk_qos_ops egress_policer_ops;
+static const struct dpdk_qos_ops egress_pkts_policer_ops;
 static const struct dpdk_qos_ops trtcm_policer_ops;
 
 /*
@@ -353,6 +356,7 @@ static const struct dpdk_qos_ops trtcm_policer_ops;
  */
 static const struct dpdk_qos_ops *const qos_confs[] = {
     &egress_policer_ops,
+    &egress_pkts_policer_ops,
     &trtcm_policer_ops,
     NULL
 };
@@ -2335,6 +2339,29 @@ srtcm_policer_run_single_packet(struct rte_meter_srtcm 
*meter,
     return cnt;
 }
 
+static int
+pkts_policer_run_single_packet(struct token_bucket *tb, struct rte_mbuf **pkts,
+                               int pkt_cnt, bool should_steal)
+{
+    int cnt = 0;
+    struct rte_mbuf *pkt;
+
+    for (int i = 0; i < pkt_cnt; i++) {
+        pkt = pkts[i];
+        /* Handle current packet */
+        if (token_bucket_withdraw(tb, 1000)) {
+            if (cnt != i) {
+                pkts[cnt] = pkt;
+            }
+            cnt++;
+        } else if (should_steal) {
+            rte_pktmbuf_free(pkt);
+        }
+    }
+
+    return cnt;
+}
+
 static int
 ingress_policer_run(struct ingress_policer *policer, struct rte_mbuf **pkts,
                     int pkt_cnt, bool should_steal)
@@ -4858,6 +4885,97 @@ static const struct dpdk_qos_ops egress_policer_ops = {
     .qos_run = egress_policer_run
 };
 
+/* egress-pkts-policer details */
+
+struct egress_pkts_policer {
+    struct qos_conf qos_conf;
+    struct token_bucket tb;
+};
+
+static int
+egress_pkts_policer_qos_construct(const struct smap *details,
+                                  struct qos_conf **conf)
+{
+    uint32_t rate, burst;
+    struct egress_pkts_policer *policer;
+
+    policer = xmalloc(sizeof *policer);
+    rate  = smap_get_uint(details, "pkts_rate", 0);
+    burst = smap_get_uint(details, "pkts_burst", 0);
+
+    /*
+     * Force to 0 if no rate specified,
+     * default to rate if burst is 0,
+     * else stick with user-specified value.
+     */
+    burst = (!rate ? 0 : !burst ? rate : burst);
+
+    qos_conf_init(&policer->qos_conf, &egress_pkts_policer_ops);
+    token_bucket_init(&policer->tb, rate, burst * 1000);
+
+    *conf = &policer->qos_conf;
+
+    return 0;
+}
+
+static void
+egress_pkts_policer_qos_destruct(struct qos_conf *conf)
+{
+    struct egress_pkts_policer *policer =
+                CONTAINER_OF(conf, struct egress_pkts_policer, qos_conf);
+
+    free(policer);
+}
+
+static int
+egress_pkts_policer_qos_get(const struct qos_conf *conf, struct smap *details)
+{
+    struct egress_pkts_policer *policer =
+                CONTAINER_OF(conf, struct egress_pkts_policer, qos_conf);
+
+    smap_add_format(details, "pkts_rate", "%"PRIu32, policer->tb.rate);
+    smap_add_format(details, "pkts_burst", "%"PRIu32, policer->tb.burst);
+
+    return 0;
+}
+
+static bool
+egress_pkts_policer_qos_is_equal(const struct qos_conf *conf,
+                                 const struct smap *details)
+{
+    uint32_t rate, burst;
+    struct egress_pkts_policer *policer =
+        CONTAINER_OF(conf, struct egress_pkts_policer, qos_conf);
+
+    rate  = smap_get_uint(details, "pkts_rate", 0);
+    burst = smap_get_uint(details, "pkts_burst", 0);
+
+    return (policer->tb.rate == rate && policer->tb.burst == burst);
+}
+
+static int
+egress_pkts_policer_run(struct qos_conf *conf, struct rte_mbuf **pkts,
+                        int pkt_cnt, bool should_steal)
+{
+    int cnt = 0;
+    struct egress_pkts_policer *policer =
+                CONTAINER_OF(conf, struct egress_pkts_policer, qos_conf);
+
+    cnt = pkts_policer_run_single_packet(&policer->tb, pkts, pkt_cnt,
+                                         should_steal);
+
+    return cnt;
+}
+
+static const struct dpdk_qos_ops egress_pkts_policer_ops = {
+    .qos_name = "egress-pkts-policer",
+    .qos_construct = egress_pkts_policer_qos_construct,
+    .qos_destruct = egress_pkts_policer_qos_destruct,
+    .qos_get = egress_pkts_policer_qos_get,
+    .qos_is_equal = egress_pkts_policer_qos_is_equal,
+    .qos_run = egress_pkts_policer_run
+};
+
 /* trtcm-policer details */
 
 struct trtcm_policer {
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index edb5eafa0..94bfe54eb 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -4791,6 +4791,19 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch 
options:peer=p1 \
           in performance will be noticed in terms of overall aggregate traffic
           throughput.
         </dd>
+        <dt><code>egress-pkts-policer</code></dt>
+        <dd>
+          A DPDK egress packet per second policer algorithm using the ovs
+          token bucket library. The token bucket library provides an
+          implementation which allows the policing of packets traffic. The
+          implementation in OVS essentially creates a single token bucket used
+          to police traffic. It should be noted that when the token bucket is
+          configured as part of QoS there will be a performance overhead as the
+          token bucket itself will consume CPU cycles in order to police
+          traffic. These CPU cycles ordinarily are used for packet proccessing.
+          As such the drop in performance will be noticed in terms of overall
+          aggregate traffic throughput.
+        </dd>
         <dt><code>trtcm-policer</code></dt>
         <dd>
           A DPDK egress policer algorithm using RFC 4115's Two-Rate,
@@ -4896,6 +4909,25 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch 
options:peer=p1 \
       </column>
     </group>
 
+    <group title="Configuration for egress-pkts-policer QoS">
+      <p>
+        <ref table="QoS"/> <ref table="QoS" column="type"/>
+        <code>egress-pkts-policer</code> provides egress pkts policing for
+        userspace port types with DPDK.
+
+        It has the following key-value pairs defined.
+      </p>
+
+      <column name="other_config" key="pkts_rate" type='{"type": "integer"}'>
+        The Packets Per Second (pps) represents the packet per second rate at
+        which the token bucket will be updated.
+      </column>
+      <column name="other_config" key="pkts_burst" type='{"type": "integer"}'>
+        The Packets Per Second Burst Size is measured in count and represents a
+        token bucket.
+      </column>
+    </group>
+
     <group title="Configuration for linux-sfq">
       <p>
         The <code>linux-sfq</code> QoS supports the following key-value pairs:
-- 
2.37.1.windows.1

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to