[ovs-dev,v2,03/11] datapath: compat: Introduce static key support

Message ID 1533170156-769-4-git-send-email-yihung.wei@gmail.com
State Changes Requested
Headers show
Series
  • conntrack zone limitation
Related show

Commit Message

Yi-Hung Wei Aug. 2, 2018, 12:35 a.m.
This is a feature that is needed for a follow up patch
in ovs kernel datapath.

Signed-off-by: Yi-Hung Wei <yihung.wei@gmail.com>
---
 acinclude.m4                                     |  3 +
 datapath/linux/Modules.mk                        |  1 +
 datapath/linux/compat/include/linux/static_key.h | 70 ++++++++++++++++++++++++
 3 files changed, 74 insertions(+)
 create mode 100644 datapath/linux/compat/include/linux/static_key.h

Comments

Darrell Ball Aug. 2, 2018, 5:08 a.m. | #1
Thanks for the patch Yi-hung

On 8/1/18, 5:42 PM, "ovs-dev-bounces@openvswitch.org on behalf of Yi-Hung Wei" <ovs-dev-bounces@openvswitch.org on behalf of yihung.wei@gmail.com> wrote:

    This is a feature that is needed for a follow up patch
    in ovs kernel datapath.

It is usually implied that patch in a series is needed by a subsequent patch in the same series.
Would you mind expanding the commit message on the general utility?

Also, the upstream commit id is embedded in the file, static_key.h

    + * This backport is based on upstream net-next commit 11276d5306b8
    + * ("locking/static_keys: Add a new static_key interface").

Would it be possible to bring it into the commit message also?


    
    Signed-off-by: Yi-Hung Wei <yihung.wei@gmail.com>
    ---
     acinclude.m4                                     |  3 +
     datapath/linux/Modules.mk                        |  1 +
     datapath/linux/compat/include/linux/static_key.h | 70 ++++++++++++++++++++++++
     3 files changed, 74 insertions(+)
     create mode 100644 datapath/linux/compat/include/linux/static_key.h
    
    diff --git a/acinclude.m4 b/acinclude.m4
    index 96fcad55a7cb..341edbbd70f1 100644
    --- a/acinclude.m4
    +++ b/acinclude.m4
    @@ -467,6 +467,9 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
       OVS_GREP_IFELSE([$KSRC/include/linux/err.h], [IS_ERR_OR_NULL])
       OVS_GREP_IFELSE([$KSRC/include/linux/err.h], [PTR_ERR_OR_ZERO])
     
    +  OVS_GREP_IFELSE([$KSRC/include/linux/jump_label.h], [DEFINE_STATIC_KEY_FALSE],
    +                  [OVS_DEFINE([HAVE_UPSTREAM_STATIC_KEY])])
    +
       OVS_GREP_IFELSE([$KSRC/include/linux/etherdevice.h], [eth_hw_addr_random])
       OVS_GREP_IFELSE([$KSRC/include/linux/etherdevice.h], [ether_addr_copy])
     
    diff --git a/datapath/linux/Modules.mk b/datapath/linux/Modules.mk
    index f5c3b6580ad7..2fec6500e7c8 100644
    --- a/datapath/linux/Modules.mk
    +++ b/datapath/linux/Modules.mk
    @@ -63,6 +63,7 @@ openvswitch_headers += \
     	linux/compat/include/linux/reciprocal_div.h \
     	linux/compat/include/linux/rtnetlink.h \
     	linux/compat/include/linux/skbuff.h \
    +	linux/compat/include/linux/static_key.h \
     	linux/compat/include/linux/stddef.h \
     	linux/compat/include/linux/types.h \
     	linux/compat/include/linux/u64_stats_sync.h \
    diff --git a/datapath/linux/compat/include/linux/static_key.h b/datapath/linux/compat/include/linux/static_key.h
    new file mode 100644
    index 000000000000..ea59e3e285a1
    --- /dev/null
    +++ b/datapath/linux/compat/include/linux/static_key.h
    @@ -0,0 +1,70 @@
    +#ifndef _STATIC_KEY_WRAPPER_H
    +#define _STATIC_KEY_WRAPPER_H
    +
    +#include_next <linux/static_key.h>
    +#ifndef HAVE_UPSTREAM_STATIC_KEY
    +/*
    + * This backport is based on upstream net-next commit 11276d5306b8
    + * ("locking/static_keys: Add a new static_key interface").
    + *
    + * For kernel that does not support the new static key interface,
    + * we do not backport the jump label support but the fall back version
    + * of static key that is simply a conditional branch.
    + */
    +
    +struct static_key_true {
    +	struct static_key key;
    +};
    +
    +struct static_key_false {
    +	struct static_key key;
    +};
    +
    +#define rpl_STATIC_KEY_INIT_TRUE	{ .enabled = ATOMIC_INIT(1) }
    +#define rpl_STATIC_KEY_INIT_FALSE	{ .enabled = ATOMIC_INIT(0) }
    +
    +#define STATIC_KEY_TRUE_INIT	\
    +	(struct static_key_true) { .key = rpl_STATIC_KEY_INIT_TRUE,  }
    +#define STATIC_KEY_FALSE_INIT	\
    +	(struct static_key_false){ .key = rpl_STATIC_KEY_INIT_FALSE, }
    +
    +#define DEFINE_STATIC_KEY_TRUE(name)	\
    +	struct static_key_true name = STATIC_KEY_TRUE_INIT
    +
    +#define DEFINE_STATIC_KEY_FALSE(name)	\
    +	struct static_key_false name = STATIC_KEY_FALSE_INIT
    +
    +static inline int rpl_static_key_count(struct static_key *key)
    +{
    +	return atomic_read(&key->enabled);
    +}
    +
    +static inline void rpl_static_key_enable(struct static_key *key)
    +{
    +	int count = rpl_static_key_count(key);
    +
    +	WARN_ON_ONCE(count < 0 || count > 1);
    +
    +	if (!count)
    +		static_key_slow_inc(key);
    +}
    +
    +static inline void rpl_static_key_disable(struct static_key *key)
    +{
    +	int count = rpl_static_key_count(key);
    +
    +	WARN_ON_ONCE(count < 0 || count > 1);
    +
    +	if (count)
    +		static_key_slow_dec(key);
    +}
    +
    +#define static_branch_likely(x)		likely(static_key_enabled(&(x)->key))
    +#define static_branch_unlikely(x)	unlikely(static_key_enabled(&(x)->key))
    +
    +#define static_branch_enable(x)		rpl_static_key_enable(&(x)->key)
    +#define static_branch_disable(x)	rpl_static_key_disable(&(x)->key)
    +
    +#endif /* HAVE_UPSTREAM_STATIC_KEY */
    +
    +#endif /* _STATIC_KEY_WRAPPER_H */
    -- 
    2.7.4
    
    _______________________________________________
    dev mailing list
    dev@openvswitch.org
    https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.openvswitch.org%2Fmailman%2Flistinfo%2Fovs-dev&amp;data=02%7C01%7Cdball%40vmware.com%7Cb4545747e6eb444d7b1008d5f810e1dc%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C1%7C0%7C636687673748107593&amp;sdata=xBYt7N%2FIbeasoJ8UIzC2EQuR2VsC1TRNLasGAMP1xHk%3D&amp;reserved=0
Yi-Hung Wei Aug. 2, 2018, 9:12 p.m. | #2
On Wed, Aug 1, 2018 at 10:08 PM, Darrell Ball <dball@vmware.com> wrote:
> Thanks for the patch Yi-hung
>
> On 8/1/18, 5:42 PM, "ovs-dev-bounces@openvswitch.org on behalf of Yi-Hung Wei" <ovs-dev-bounces@openvswitch.org on behalf of yihung.wei@gmail.com> wrote:
>
>     This is a feature that is needed for a follow up patch
>     in ovs kernel datapath.
>
> It is usually implied that patch in a series is needed by a subsequent patch in the same series.
> Would you mind expanding the commit message on the general utility?
> Also, the upstream commit id is embedded in the file, static_key.h
>
>     + * This backport is based on upstream net-next commit 11276d5306b8
>     + * ("locking/static_keys: Add a new static_key interface").
>
> Would it be possible to bring it into the commit message also?
Thanks for the feedback. I will update the commit message in v3 as following.

Static keys allow the inclusion of seldom used features in
performance-sensitive fast-path kernel code, via a GCC feature and a
code patching technique. For more information:
    * https://www.kernel.org/doc/Documentation/static-keys.txt

Since upstream ovs kernel module now uses some static key API that was
introduced in v4.3 kernel, we shall backport them to the compat module
for older kernel supprots.

This backport is based on upstream net-next commit 11276d5306b8
("locking/static_keys: Add a new static_key interface").


Thanks,

-Yi-Hung

Patch

diff --git a/acinclude.m4 b/acinclude.m4
index 96fcad55a7cb..341edbbd70f1 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -467,6 +467,9 @@  AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
   OVS_GREP_IFELSE([$KSRC/include/linux/err.h], [IS_ERR_OR_NULL])
   OVS_GREP_IFELSE([$KSRC/include/linux/err.h], [PTR_ERR_OR_ZERO])
 
+  OVS_GREP_IFELSE([$KSRC/include/linux/jump_label.h], [DEFINE_STATIC_KEY_FALSE],
+                  [OVS_DEFINE([HAVE_UPSTREAM_STATIC_KEY])])
+
   OVS_GREP_IFELSE([$KSRC/include/linux/etherdevice.h], [eth_hw_addr_random])
   OVS_GREP_IFELSE([$KSRC/include/linux/etherdevice.h], [ether_addr_copy])
 
diff --git a/datapath/linux/Modules.mk b/datapath/linux/Modules.mk
index f5c3b6580ad7..2fec6500e7c8 100644
--- a/datapath/linux/Modules.mk
+++ b/datapath/linux/Modules.mk
@@ -63,6 +63,7 @@  openvswitch_headers += \
 	linux/compat/include/linux/reciprocal_div.h \
 	linux/compat/include/linux/rtnetlink.h \
 	linux/compat/include/linux/skbuff.h \
+	linux/compat/include/linux/static_key.h \
 	linux/compat/include/linux/stddef.h \
 	linux/compat/include/linux/types.h \
 	linux/compat/include/linux/u64_stats_sync.h \
diff --git a/datapath/linux/compat/include/linux/static_key.h b/datapath/linux/compat/include/linux/static_key.h
new file mode 100644
index 000000000000..ea59e3e285a1
--- /dev/null
+++ b/datapath/linux/compat/include/linux/static_key.h
@@ -0,0 +1,70 @@ 
+#ifndef _STATIC_KEY_WRAPPER_H
+#define _STATIC_KEY_WRAPPER_H
+
+#include_next <linux/static_key.h>
+#ifndef HAVE_UPSTREAM_STATIC_KEY
+/*
+ * This backport is based on upstream net-next commit 11276d5306b8
+ * ("locking/static_keys: Add a new static_key interface").
+ *
+ * For kernel that does not support the new static key interface,
+ * we do not backport the jump label support but the fall back version
+ * of static key that is simply a conditional branch.
+ */
+
+struct static_key_true {
+	struct static_key key;
+};
+
+struct static_key_false {
+	struct static_key key;
+};
+
+#define rpl_STATIC_KEY_INIT_TRUE	{ .enabled = ATOMIC_INIT(1) }
+#define rpl_STATIC_KEY_INIT_FALSE	{ .enabled = ATOMIC_INIT(0) }
+
+#define STATIC_KEY_TRUE_INIT	\
+	(struct static_key_true) { .key = rpl_STATIC_KEY_INIT_TRUE,  }
+#define STATIC_KEY_FALSE_INIT	\
+	(struct static_key_false){ .key = rpl_STATIC_KEY_INIT_FALSE, }
+
+#define DEFINE_STATIC_KEY_TRUE(name)	\
+	struct static_key_true name = STATIC_KEY_TRUE_INIT
+
+#define DEFINE_STATIC_KEY_FALSE(name)	\
+	struct static_key_false name = STATIC_KEY_FALSE_INIT
+
+static inline int rpl_static_key_count(struct static_key *key)
+{
+	return atomic_read(&key->enabled);
+}
+
+static inline void rpl_static_key_enable(struct static_key *key)
+{
+	int count = rpl_static_key_count(key);
+
+	WARN_ON_ONCE(count < 0 || count > 1);
+
+	if (!count)
+		static_key_slow_inc(key);
+}
+
+static inline void rpl_static_key_disable(struct static_key *key)
+{
+	int count = rpl_static_key_count(key);
+
+	WARN_ON_ONCE(count < 0 || count > 1);
+
+	if (count)
+		static_key_slow_dec(key);
+}
+
+#define static_branch_likely(x)		likely(static_key_enabled(&(x)->key))
+#define static_branch_unlikely(x)	unlikely(static_key_enabled(&(x)->key))
+
+#define static_branch_enable(x)		rpl_static_key_enable(&(x)->key)
+#define static_branch_disable(x)	rpl_static_key_disable(&(x)->key)
+
+#endif /* HAVE_UPSTREAM_STATIC_KEY */
+
+#endif /* _STATIC_KEY_WRAPPER_H */