Add support to count upcall packets on every interface.
I always encounter high cpu use of ovs-vswictchd,
this help to check which interface send too many packets
without open vlog/set switch, and have no influence on datapath

Signed-off-by: wangchuanlei <[email protected]>
---
 include/linux/openvswitch.h  |  5 +++++
 include/openvswitch/netdev.h |  2 ++
 lib/dpctl.c                  |  1 +
 lib/dpif-netlink.c           | 11 +++++++++++
 lib/dpif-netlink.h           |  1 +
 lib/netdev-linux.c           | 10 ++++++++++
 6 files changed, 30 insertions(+)

diff --git a/include/linux/openvswitch.h b/include/linux/openvswitch.h
index 8bb5abdc8..ec4afc70c 100644
--- a/include/linux/openvswitch.h
+++ b/include/linux/openvswitch.h
@@ -141,6 +141,10 @@ struct ovs_vport_stats {
        __u64   tx_dropped;             /* no space available in linux  */
 };
 
+struct ovs_vport_upcall_stats {
+       __u64   upcall_packets;         /* total upcall packets         */
+};
+
 /* Allow last Netlink attribute to be unaligned */
 #define OVS_DP_F_UNALIGNED     (1 << 0)
 
@@ -301,6 +305,7 @@ enum ovs_vport_attr {
        OVS_VPORT_ATTR_PAD,
        OVS_VPORT_ATTR_IFINDEX,
        OVS_VPORT_ATTR_NETNSID,
+       OVS_VPORT_ATTR_UPCALL_STATS,  /* struct ovs_vport_upcall_stats */
        __OVS_VPORT_ATTR_MAX
 };
 
diff --git a/include/openvswitch/netdev.h b/include/openvswitch/netdev.h
index 0c10f7b48..91e87fc5a 100644
--- a/include/openvswitch/netdev.h
+++ b/include/openvswitch/netdev.h
@@ -87,6 +87,8 @@ struct netdev_stats {
     uint64_t rx_oversize_errors;
     uint64_t rx_fragmented_errors;
     uint64_t rx_jabber_errors;
+
+    uint64_t tx_upcall_packets;
 };
 
 /* Structure representation of custom statistics counter */
diff --git a/lib/dpctl.c b/lib/dpctl.c
index 29041fa3e..1cad453e9 100644
--- a/lib/dpctl.c
+++ b/lib/dpctl.c
@@ -742,6 +742,7 @@ show_dpif(struct dpif *dpif, struct dpctl_params *dpctl_p)
                 dpctl_print(dpctl_p, "\n");
 
                 print_stat(dpctl_p, "    collisions:", s.collisions);
+                print_stat(dpctl_p, " missed_wcl:", s.tx_upcall_packets);
                 dpctl_print(dpctl_p, "\n");
 
                 print_stat(dpctl_p, "    RX bytes:", s.rx_bytes);
diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
index a620a6ec5..d55939c39 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -4686,6 +4686,7 @@ dpif_netlink_vport_from_ofpbuf(struct dpif_netlink_vport 
*vport,
                                    .optional = true },
         [OVS_VPORT_ATTR_OPTIONS] = { .type = NL_A_NESTED, .optional = true },
         [OVS_VPORT_ATTR_NETNSID] = { .type = NL_A_U32, .optional = true },
+       [OVS_VPORT_ATTR_UPCALL_STATS] = { .type = NL_A_U64, .optional = true },
     };
 
     dpif_netlink_vport_init(vport);
@@ -4717,6 +4718,11 @@ dpif_netlink_vport_from_ofpbuf(struct dpif_netlink_vport 
*vport,
     if (a[OVS_VPORT_ATTR_STATS]) {
         vport->stats = nl_attr_get(a[OVS_VPORT_ATTR_STATS]);
     }
+
+    if (a[OVS_VPORT_ATTR_UPCALL_STATS]) {
+        vport->upcall_stats = nl_attr_get(a[OVS_VPORT_ATTR_UPCALL_STATS]);
+    }
+
     if (a[OVS_VPORT_ATTR_OPTIONS]) {
         vport->options = nl_attr_get(a[OVS_VPORT_ATTR_OPTIONS]);
         vport->options_len = nl_attr_get_size(a[OVS_VPORT_ATTR_OPTIONS]);
@@ -4767,6 +4773,11 @@ dpif_netlink_vport_to_ofpbuf(const struct 
dpif_netlink_vport *vport,
                           vport->stats, sizeof *vport->stats);
     }
 
+    if (vport->upcall_stats) {
+        nl_msg_put_unspec(buf, OVS_VPORT_ATTR_UPCALL_STATS,
+                          vport->upcall_stats, sizeof *vport->upcall_stats);
+    }
+
     if (vport->options) {
         nl_msg_put_nested(buf, OVS_VPORT_ATTR_OPTIONS,
                           vport->options, vport->options_len);
diff --git a/lib/dpif-netlink.h b/lib/dpif-netlink.h
index 24294bc42..4c406939a 100644
--- a/lib/dpif-netlink.h
+++ b/lib/dpif-netlink.h
@@ -44,6 +44,7 @@ struct dpif_netlink_vport {
     uint32_t n_upcall_pids;
     const uint32_t *upcall_pids;           /* OVS_VPORT_ATTR_UPCALL_PID. */
     const struct ovs_vport_stats *stats;   /* OVS_VPORT_ATTR_STATS. */
+    const struct ovs_vport_upcall_stats *upcall_stats; /* 
OVS_VPORT_ATTR_UPCALL_STATS */
     const struct nlattr *options;          /* OVS_VPORT_ATTR_OPTIONS. */
     size_t options_len;
 };
diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
index cdc66246c..a081b14f0 100644
--- a/lib/netdev-linux.c
+++ b/lib/netdev-linux.c
@@ -2181,6 +2181,13 @@ netdev_stats_from_ovs_vport_stats(struct netdev_stats 
*dst,
     dst->tx_window_errors = 0;
 }
 
+static void
+netdev_stats_from_ovs_vport_upcall_stats(struct netdev_stats *dst,
+                                         const struct ovs_vport_upcall_stats 
*src)
+{
+    dst->tx_upcall_packets = get_32aligned_u64(&src->upcall_packets);
+}
+
 static int
 get_stats_via_vport__(const struct netdev *netdev, struct netdev_stats *stats)
 {
@@ -2198,6 +2205,9 @@ get_stats_via_vport__(const struct netdev *netdev, struct 
netdev_stats *stats)
 
     netdev_stats_from_ovs_vport_stats(stats, reply.stats);
 
+    if (reply.upcall_stats)
+        netdev_stats_from_ovs_vport_upcall_stats(stats, reply.upcall_stats);
+
     ofpbuf_delete(buf);
 
     return 0;
-- 
2.27.0

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

Reply via email to