From 292d5bd9bb344527e0da19433cf3e51f8a24058c Mon Sep 17 00:00:00 2001 From: Vlad Buslov Date: Mon, 4 Nov 2019 18:34:49 +0200 Subject: tc: Set 'no_percpu' flag for compatible actions 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 Reviewed-by: Roi Dayan Signed-off-by: Simon Horman --- 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 diff --git a/acinclude.m4 b/acinclude.m4 index bc5b1c667..fc6157ac8 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 ], [ + 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 ], [ - 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_CHECK_MEMBERS([struct tcf_t.firstuse], [], [], [#include ]) diff --git a/configure.ac b/configure.ac index 97d18685c..8abc1fdb5 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 4873a6ae6..c75918626 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 000000000..cd558fb4c --- /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 + +/* 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 + +#endif /* __UAPI_LINUX_NETLINK_WRAPPER_H */ diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h index 2f7e328c4..55f3ef17c 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 #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 d5487097d..ba3e9d09d 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); -- cgit v1.2.1