Skip to content

Commit

Permalink
jump_label: remove bug.h, atomic.h dependencies for HAVE_JUMP_LABEL
Browse files Browse the repository at this point in the history
Convert dynamic_debug to use jump labels.

In the course of adding jump label support to dynamic_debug (patch #4), I
found the inclusion of <linux/bug.h> by <linux/jump_label.h> to problematic b/c
it includes <linux/kernel.h> (thus, creating circular include dependencies).
Thus, I've removed the dependencies from jump_label.h on bug.h and atomic.h
so that it should be includable from mostly anywhere. There were a couple of
arch specific changes for powerpc (patch #2) and s390 (patch #3) that fell out
as well...hopefully this version compiles everywhere.

This patch (of 4):

The current jump_label.h includes bug.h for things such as WARN_ON().
This makes the header problematic for inclusion by kernel.h or any headers
that kernel.h includes, since bug.h includes kernel.h (circular
dependency).  The inclusion of atomic.h is similarly problematic.  Thus,
this should make jump_label.h 'includable' from most places.

Link: http://lkml.kernel.org/r/685502bf717a6d32ffcd7c3b5464c13d24c12811.1463778029.git.jbaron@akamai.com
Signed-off-by: Jason Baron <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Heiko Carstens <[email protected]>
Cc: Martin Schwidefsky <[email protected]>
Cc: Michael Ellerman <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Joe Perches <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
  • Loading branch information
almostivan authored and sfrothwell committed Jun 8, 2016
1 parent 6b99c3a commit 2660451
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 20 deletions.
50 changes: 30 additions & 20 deletions include/linux/jump_label.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@

#include <linux/types.h>
#include <linux/compiler.h>
#include <linux/bug.h>

extern bool static_key_initialized;

Expand Down Expand Up @@ -115,13 +114,6 @@ enum jump_label_type {

struct module;

#include <linux/atomic.h>

static inline int static_key_count(struct static_key *key)
{
return atomic_read(&key->enabled);
}

#ifdef HAVE_JUMP_LABEL

#define JUMP_TYPE_FALSE 0UL
Expand Down Expand Up @@ -152,16 +144,34 @@ extern int jump_label_text_reserved(void *start, void *end);
extern void static_key_slow_inc(struct static_key *key);
extern void static_key_slow_dec(struct static_key *key);
extern void jump_label_apply_nops(struct module *mod);
extern int static_key_count(struct static_key *key);
extern void static_key_enable(struct static_key *key);
extern void static_key_disable(struct static_key *key);

#define STATIC_KEY_INIT_TRUE \
{ .enabled = ATOMIC_INIT(1), \
/*
* We should be using ATOMIC_INIT() for initializing .enabled, but
* the inclusion of atomic.h is problematic for inclusion of jump_label.h
* in 'low-level' headers. Thus, we are initializing .enabled with a
* raw value, but have added a BUILD_BUG_ON() to catch any issues in
* jump_label_init() see: kernel/jump_label.c.
*/
#define STATIC_KEY_INIT_TRUE \
{ .enabled = { 1 }, \
.entries = (void *)JUMP_TYPE_TRUE }
#define STATIC_KEY_INIT_FALSE \
{ .enabled = ATOMIC_INIT(0), \
#define STATIC_KEY_INIT_FALSE \
{ .enabled = { 0 }, \
.entries = (void *)JUMP_TYPE_FALSE }

#else /* !HAVE_JUMP_LABEL */

#include <linux/atomic.h>
#include <linux/bug.h>

static inline int static_key_count(struct static_key *key)
{
return atomic_read(&key->enabled);
}

static __always_inline void jump_label_init(void)
{
static_key_initialized = true;
Expand Down Expand Up @@ -206,14 +216,6 @@ static inline int jump_label_apply_nops(struct module *mod)
return 0;
}

#define STATIC_KEY_INIT_TRUE { .enabled = ATOMIC_INIT(1) }
#define STATIC_KEY_INIT_FALSE { .enabled = ATOMIC_INIT(0) }

#endif /* HAVE_JUMP_LABEL */

#define STATIC_KEY_INIT STATIC_KEY_INIT_FALSE
#define jump_label_enabled static_key_enabled

static inline void static_key_enable(struct static_key *key)
{
int count = static_key_count(key);
Expand All @@ -234,6 +236,14 @@ static inline void static_key_disable(struct static_key *key)
static_key_slow_dec(key);
}

#define STATIC_KEY_INIT_TRUE { .enabled = ATOMIC_INIT(1) }
#define STATIC_KEY_INIT_FALSE { .enabled = ATOMIC_INIT(0) }

#endif /* HAVE_JUMP_LABEL */

#define STATIC_KEY_INIT STATIC_KEY_INIT_FALSE
#define jump_label_enabled static_key_enabled

/* -------------------------------------------------------------------------- */

/*
Expand Down
48 changes: 48 additions & 0 deletions kernel/jump_label.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <linux/err.h>
#include <linux/static_key.h>
#include <linux/jump_label_ratelimit.h>
#include <linux/bug.h>

#ifdef HAVE_JUMP_LABEL

Expand Down Expand Up @@ -56,6 +57,44 @@ jump_label_sort_entries(struct jump_entry *start, struct jump_entry *stop)

static void jump_label_update(struct static_key *key);

/*
* There is a similar definition for the !HAVE_JUMP_LABEL case in jump_label.h.
* The reason for the copying is that the use of 'atomic_read()' requires
* atomic.h and its problematic for some kernel headers such as kernel.h and
* others. Since static_key_count() is not used in the branch statements as it
* is for the !HAVE_JUMP_LABEL case its ok to have it be a function here.
* Similarly, for 'static_key_enable()' and 'static_key_disable()', which
* require bug.h. This should allow jump_label.h to be included from most/all
* places for HAVE_JUMP_LABEL.
*/
int static_key_count(struct static_key *key)
{
return atomic_read(&key->enabled);
}
EXPORT_SYMBOL_GPL(static_key_count);

void static_key_enable(struct static_key *key)
{
int count = static_key_count(key);

WARN_ON_ONCE(count < 0 || count > 1);

if (!count)
static_key_slow_inc(key);
}
EXPORT_SYMBOL_GPL(static_key_enable);

void static_key_disable(struct static_key *key)
{
int count = static_key_count(key);

WARN_ON_ONCE(count < 0 || count > 1);

if (count)
static_key_slow_dec(key);
}
EXPORT_SYMBOL_GPL(static_key_disable);

void static_key_slow_inc(struct static_key *key)
{
STATIC_KEY_CHECK_USE();
Expand Down Expand Up @@ -205,6 +244,15 @@ void __init jump_label_init(void)
struct static_key *key = NULL;
struct jump_entry *iter;

/*
* Since we are initializing the static_key.enabled field with
* with the 'raw' int values (to avoid pulling in atomic.h), let's make
* sure that is safe. There are only two cases to check since we
* initialize to 0 or 1.
*/
BUILD_BUG_ON((int)ATOMIC_INIT(0) != 0);
BUILD_BUG_ON((int)ATOMIC_INIT(1) != 1);

jump_label_lock();
jump_label_sort_entries(iter_start, iter_stop);

Expand Down

0 comments on commit 2660451

Please sign in to comment.