Skip to content

Commit

Permalink
datapath: compat: Introduce static key support
Browse files Browse the repository at this point in the history
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").

Signed-off-by: Yi-Hung Wei <[email protected]>
Signed-off-by: Justin Pettit <[email protected]>
YiHungWei authored and justinpettit committed Aug 17, 2018
1 parent 7449643 commit 6660a95
Showing 3 changed files with 74 additions and 0 deletions.
3 changes: 3 additions & 0 deletions acinclude.m4
Original file line number Diff line number Diff line change
@@ -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])
1 change: 1 addition & 0 deletions datapath/linux/Modules.mk
Original file line number Diff line number Diff line change
@@ -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 \
70 changes: 70 additions & 0 deletions datapath/linux/compat/include/linux/static_key.h
Original file line number Diff line number Diff line change
@@ -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 */

0 comments on commit 6660a95

Please sign in to comment.