[ovs-dev] tc: Set 'no_percpu' flag for compatible actions
diff mbox series

Message ID 20191104163449.29899-1-roid@mellanox.com
State New
Headers show
Series
  • [ovs-dev] tc: Set 'no_percpu' flag for compatible actions
Related show

Commit Message

Roi Dayan Nov. 4, 2019, 4:34 p.m. UTC
From: Vlad Buslov <vladbu@mellanox.com>

Recent changes in Linux kernel TC action subsystem introduced new
TCA_ACT_FLAGS_NO_PERCPU_STATS flag. The purpose of the flag is to request
action implementation to skip allocating action stats with expensive percpu
allocator and use regular built-in action stats instead. Such approach
significantly improves rule insertion rate and reduce memory usage for
hardware-offloaded rules that don't need benefits provided by percpu
allocated stats (improved software TC fast-path performance). Set the flag
for all compatible actions.

Modify acinclude.m4 to use OVS-internal pkt_cls.h implementation when
TCA_ACT_FLAGS is not defined by kernel headers and to manually define
struct nla_bitfield32 in netlink.h (new file) when it is not defined by
kernel headers.

Signed-off-by: Vlad Buslov <vladbu@mellanox.com>
Reviewed-by: Roi Dayan <roid@mellanox.com>
---
 acinclude.m4              | 18 +++++++++++++++---
 configure.ac              |  1 +
 include/linux/automake.mk |  1 +
 include/linux/netlink.h   | 30 ++++++++++++++++++++++++++++++
 include/linux/pkt_cls.h   |  7 ++++++-
 lib/tc.c                  | 15 +++++++++++++++
 6 files changed, 68 insertions(+), 4 deletions(-)
 create mode 100644 include/linux/netlink.h

Comments

Simon Horman Nov. 11, 2019, 4:03 p.m. UTC | #1
On Mon, Nov 04, 2019 at 06:34:49PM +0200, Roi Dayan wrote:
> From: Vlad Buslov <vladbu@mellanox.com>
> 
> Recent changes in Linux kernel TC action subsystem introduced new
> TCA_ACT_FLAGS_NO_PERCPU_STATS flag. The purpose of the flag is to request
> action implementation to skip allocating action stats with expensive percpu
> allocator and use regular built-in action stats instead. Such approach
> significantly improves rule insertion rate and reduce memory usage for
> hardware-offloaded rules that don't need benefits provided by percpu
> allocated stats (improved software TC fast-path performance). Set the flag
> for all compatible actions.
> 
> Modify acinclude.m4 to use OVS-internal pkt_cls.h implementation when
> TCA_ACT_FLAGS is not defined by kernel headers and to manually define
> struct nla_bitfield32 in netlink.h (new file) when it is not defined by
> kernel headers.
> 
> Signed-off-by: Vlad Buslov <vladbu@mellanox.com>
> Reviewed-by: Roi Dayan <roid@mellanox.com>

Thanks, applied to master.

Patch
diff mbox series

diff --git a/acinclude.m4 b/acinclude.m4
index a0507cfe019e..4d56d9c4e152 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -174,16 +174,28 @@  AC_DEFUN([OVS_CHECK_LINUX], [
   AM_CONDITIONAL(LINUX_ENABLED, test -n "$KBUILD")
 ])
 
+dnl OVS_CHECK_LINUX_NETLINK
+dnl
+dnl Configure Linux netlink compat.
+AC_DEFUN([OVS_CHECK_LINUX_NETLINK], [
+  AC_COMPILE_IFELSE([
+    AC_LANG_PROGRAM([#include <linux/netlink.h>], [
+        struct nla_bitfield32 x =  { 0 };
+    ])],
+    [AC_DEFINE([HAVE_NLA_BITFIELD32], [1],
+    [Define to 1 if struct nla_bitfield32 is available.])])
+])
+
 dnl OVS_CHECK_LINUX_TC
 dnl
 dnl Configure Linux tc compat.
 AC_DEFUN([OVS_CHECK_LINUX_TC], [
   AC_COMPILE_IFELSE([
     AC_LANG_PROGRAM([#include <linux/pkt_cls.h>], [
-        int x = TCA_FLOWER_KEY_ENC_IP_TTL_MASK;
+        int x = TCA_ACT_FLAGS;
     ])],
-    [AC_DEFINE([HAVE_TCA_FLOWER_KEY_ENC_IP_TTL_MASK], [1],
-               [Define to 1 if TCA_FLOWER_KEY_ENC_IP_TTL_MASK is available.])])
+    [AC_DEFINE([HAVE_TCA_ACT_FLAGS], [1],
+               [Define to 1 if TCA_ACT_FLAGS is available.])])
 
   AC_COMPILE_IFELSE([
     AC_LANG_PROGRAM([#include <linux/tc_act/tc_vlan.h>], [
diff --git a/configure.ac b/configure.ac
index 97d18685cee1..8abc1fdb5ee5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -186,6 +186,7 @@  OVS_CTAGS_IDENTIFIERS
 AC_ARG_VAR(KARCH, [Kernel Architecture String])
 AC_SUBST(KARCH)
 OVS_CHECK_LINUX
+OVS_CHECK_LINUX_NETLINK
 OVS_CHECK_LINUX_TC
 OVS_CHECK_LINUX_SCTP_CT
 OVS_CHECK_DPDK
diff --git a/include/linux/automake.mk b/include/linux/automake.mk
index 4873a6ae6c6f..c75918626043 100644
--- a/include/linux/automake.mk
+++ b/include/linux/automake.mk
@@ -1,4 +1,5 @@ 
 noinst_HEADERS += \
+	include/linux/netlink.h \
 	include/linux/netfilter/nf_conntrack_sctp.h \
 	include/linux/pkt_cls.h \
 	include/linux/tc_act/tc_mpls.h \
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
new file mode 100644
index 000000000000..cd558fb4c1f1
--- /dev/null
+++ b/include/linux/netlink.h
@@ -0,0 +1,30 @@ 
+#ifndef __UAPI_LINUX_NETLINK_WRAPPER_H
+#define __UAPI_LINUX_NETLINK_WRAPPER_H 1
+
+#if !defined(__KERNEL__) && !defined(HAVE_NLA_BITFIELD32)
+
+#include <linux/types.h>
+
+/* Generic 32 bitflags attribute content sent to the kernel.
+ *
+ * The value is a bitmap that defines the values being set
+ * The selector is a bitmask that defines which value is legit
+ *
+ * Examples:
+ *  value = 0x0, and selector = 0x1
+ *  implies we are selecting bit 1 and we want to set its value to 0.
+ *
+ *  value = 0x2, and selector = 0x2
+ *  implies we are selecting bit 2 and we want to set its value to 1.
+ *
+ */
+struct nla_bitfield32 {
+    __u32 value;
+    __u32 selector;
+};
+
+#endif /* !__KERNEL__ && !HAVE_NLA_BITFIELD32 */
+
+#include_next <linux/netlink.h>
+
+#endif /* __UAPI_LINUX_NETLINK_WRAPPER_H */
diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h
index 4adea59e7c36..6d75356ecf57 100644
--- a/include/linux/pkt_cls.h
+++ b/include/linux/pkt_cls.h
@@ -1,7 +1,7 @@ 
 #ifndef __LINUX_PKT_CLS_WRAPPER_H
 #define __LINUX_PKT_CLS_WRAPPER_H 1
 
-#if defined(__KERNEL__) || defined(HAVE_TCA_FLOWER_KEY_ENC_IP_TTL_MASK)
+#if defined(__KERNEL__) || defined(HAVE_TCA_ACT_FLAGS)
 #include_next <linux/pkt_cls.h>
 #else
 
@@ -17,9 +17,14 @@  enum {
 	TCA_ACT_STATS,
 	TCA_ACT_PAD,
 	TCA_ACT_COOKIE,
+	TCA_ACT_FLAGS,
 	__TCA_ACT_MAX
 };
 
+#define TCA_ACT_FLAGS_NO_PERCPU_STATS 1 /* Don't use percpu allocator for
+                                         * actions stats.
+                                         */
+
 #define TCA_ACT_MAX __TCA_ACT_MAX
 #define TCA_OLD_COMPAT (TCA_ACT_MAX+1)
 #define TCA_ACT_MAX_PRIO 32
diff --git a/lib/tc.c b/lib/tc.c
index d5487097d8ec..ba3e9d09dabe 100644
--- a/lib/tc.c
+++ b/lib/tc.c
@@ -1957,6 +1957,14 @@  nl_msg_put_act_cookie(struct ofpbuf *request, struct tc_cookie *ck) {
     }
 }
 
+static inline void
+nl_msg_put_act_flags(struct ofpbuf *request) {
+    struct nla_bitfield32 act_flags = { TCA_ACT_FLAGS_NO_PERCPU_STATS,
+                                        TCA_ACT_FLAGS_NO_PERCPU_STATS };
+
+    nl_msg_put_unspec(request, TCA_ACT_FLAGS, &act_flags, sizeof act_flags);
+}
+
 /* Given flower, a key_to_pedit map entry, calculates the rest,
  * where:
  *
@@ -2129,6 +2137,7 @@  nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower)
         if (flower->tunnel) {
             act_offset = nl_msg_start_nested(request, act_index++);
             nl_msg_put_act_tunnel_key_release(request);
+            nl_msg_put_act_flags(request);
             nl_msg_end_nested(request, act_offset);
         }
 
@@ -2146,6 +2155,7 @@  nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower)
                 if (flower->csum_update_flags) {
                     act_offset = nl_msg_start_nested(request, act_index++);
                     nl_msg_put_act_csum(request, flower->csum_update_flags);
+                    nl_msg_put_act_flags(request);
                     nl_msg_end_nested(request, act_offset);
                 }
             }
@@ -2163,12 +2173,14 @@  nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower)
                                               action->encap.ttl,
                                               action->encap.data,
                                               action->encap.no_csum);
+                nl_msg_put_act_flags(request);
                 nl_msg_end_nested(request, act_offset);
             }
             break;
             case TC_ACT_VLAN_POP: {
                 act_offset = nl_msg_start_nested(request, act_index++);
                 nl_msg_put_act_pop_vlan(request);
+                nl_msg_put_act_flags(request);
                 nl_msg_end_nested(request, act_offset);
             }
             break;
@@ -2178,6 +2190,7 @@  nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower)
                                          action->vlan.vlan_push_tpid,
                                          action->vlan.vlan_push_id,
                                          action->vlan.vlan_push_prio);
+                nl_msg_put_act_flags(request);
                 nl_msg_end_nested(request, act_offset);
             }
             break;
@@ -2239,6 +2252,7 @@  nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower)
                     }
                 }
                 nl_msg_put_act_cookie(request, &flower->act_cookie);
+                nl_msg_put_act_flags(request);
                 nl_msg_end_nested(request, act_offset);
             }
             break;
@@ -2249,6 +2263,7 @@  nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower)
         act_offset = nl_msg_start_nested(request, act_index++);
         nl_msg_put_act_drop(request);
         nl_msg_put_act_cookie(request, &flower->act_cookie);
+        nl_msg_put_act_flags(request);
         nl_msg_end_nested(request, act_offset);
     }
     nl_msg_end_nested(request, offset);