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