[ovs-dev,v2,2/4] netdev-dpdk.c: Support multi-queue QoS rate limitation function for dpdk datapath

Submitted by zhao zhaozhanxu on July 25, 2017, 2:53 a.m.

Details

Message ID 1500951228-18646-3-git-send-email-zhaozhanxu@163.com
State New
Headers show

Commit Message

zhao zhaozhanxu July 25, 2017, 2:53 a.m.
This patch modifies function `egress_policer_run`, so that it can find which queue
policy does the packet belongs to, then caculate whether the packet will be dropped,
if not be dropped, need to caculate whether the packet will be dropped by port policy.

Rate limitation logicality as below:
1. Find which queue policy does the packet belongs to by `skb_priority` of
   `struct dp_packet`, if found, goto 2 for queue policy QoS, else goto 3
   for port policy QoS.
2. Use srtcm algorithm to limit rate according to queue policy, if return
   color green, goto 3 for port policy QoS, else return false to drop packet.
3. Use srtcm algorithm to limit rate according to port policy, if return color
   gree, return true to let packet go, else return false to drop packet.

Finally, we can set `skb_priority` of `struct dp_packet` by openflow action set_queue.

$ ovs-ofctl add-flow br0 in_port=5,actions=set_queue:123,normal

Signed-off-by: zhaozhanxu <zhaozhanxu@163.com>
---
 lib/netdev-dpdk.c | 37 +++++++++++++++++++++++++++++++++++--
 1 file changed, 35 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index 089ad64..85f077e 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -3173,14 +3173,47 @@  egress_policer_qos_is_equal(const struct qos_conf *conf,
     return !memcmp(&params, &policer->app_srtcm_params, sizeof params);
 }
 
+static inline bool
+egress_policer_pkt_handle(struct egress_policer *policer,
+                          struct rte_mbuf *pkt, uint64_t time)
+{
+    struct egress_queue_policer *queue_policer;
+    uint32_t pkt_len = rte_pktmbuf_pkt_len(pkt) - sizeof(struct ether_hdr);
+
+    queue_policer = egress_policer_qos_find_queue(policer,
+                                ((struct dp_packet *)pkt)->md.skb_priority);
+    if (queue_policer) {
+        if (rte_meter_srtcm_color_blind_check(&queue_policer->egress_meter,
+                                        time, pkt_len) != e_RTE_METER_GREEN) {
+            return false;
+        }
+    }
+
+    return rte_meter_srtcm_color_blind_check(&policer->egress_meter,
+                                        time, pkt_len) == e_RTE_METER_GREEN;
+}
+
 static int
 egress_policer_run(struct qos_conf *conf, struct rte_mbuf **pkts, int pkt_cnt)
 {
-    int cnt = 0;
+    int i = 0, cnt = 0;
+    struct rte_mbuf *pkt = NULL;
+    uint64_t current_time = rte_rdtsc();
     struct egress_policer *policer =
         CONTAINER_OF(conf, struct egress_policer, qos_conf);
 
-    cnt = netdev_dpdk_policer_run(&policer->egress_meter, pkts, pkt_cnt);
+    for (i = 0; i < pkt_cnt; i++) {
+        pkt = pkts[i];
+        /* Handle current packet */
+        if (egress_policer_pkt_handle(policer, pkt, current_time)) {
+            if (cnt != i) {
+                pkts[cnt] = pkt;
+            }
+            cnt++;
+        } else {
+            rte_pktmbuf_free(pkt);
+        }
+    }
 
     return cnt;
 }