Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 52159d98 authored by Jason Baron's avatar Jason Baron Committed by Steven Rostedt
Browse files

jump label: Convert dynamic debug to use jump labels



Convert the 'dynamic debug' infrastructure to use jump labels.

Signed-off-by: default avatarJason Baron <jbaron@redhat.com>
LKML-Reference: <b77627358cea3e27d7be4386f45f66219afb8452.1284733808.git.jbaron@redhat.com>
Signed-off-by: default avatarSteven Rostedt <rostedt@goodmis.org>
parent 8f7b50c5
Loading
Loading
Loading
Loading
+21 −18
Original line number Diff line number Diff line
#ifndef _DYNAMIC_DEBUG_H
#define _DYNAMIC_DEBUG_H

#include <linux/jump_label.h>

/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which
 * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They
 * use independent hash functions, to reduce the chance of false positives.
@@ -22,8 +24,6 @@ struct _ddebug {
	const char *function;
	const char *filename;
	const char *format;
	char primary_hash;
	char secondary_hash;
	unsigned int lineno:24;
	/*
 	 * The flags field controls the behaviour at the callsite.
@@ -33,6 +33,7 @@ struct _ddebug {
#define _DPRINTK_FLAGS_PRINT   (1<<0)  /* printk() a message using the format */
#define _DPRINTK_FLAGS_DEFAULT 0
	unsigned int flags:8;
	char enabled;
} __attribute__((aligned(8)));


@@ -42,33 +43,35 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n,
#if defined(CONFIG_DYNAMIC_DEBUG)
extern int ddebug_remove_module(const char *mod_name);

#define __dynamic_dbg_enabled(dd)  ({	     \
	int __ret = 0;							     \
	if (unlikely((dynamic_debug_enabled & (1LL << DEBUG_HASH)) &&	     \
			(dynamic_debug_enabled2 & (1LL << DEBUG_HASH2))))   \
				if (unlikely(dd.flags))			     \
					__ret = 1;			     \
	__ret; })

#define dynamic_pr_debug(fmt, ...) do {					\
	__label__ do_printk;						\
	__label__ out;							\
	static struct _ddebug descriptor				\
	__used								\
	__attribute__((section("__verbose"), aligned(8))) =		\
	{ KBUILD_MODNAME, __func__, __FILE__, fmt, DEBUG_HASH,	\
		DEBUG_HASH2, __LINE__, _DPRINTK_FLAGS_DEFAULT };	\
	if (__dynamic_dbg_enabled(descriptor))				\
	{ KBUILD_MODNAME, __func__, __FILE__, fmt, __LINE__,		\
		_DPRINTK_FLAGS_DEFAULT };				\
	JUMP_LABEL(&descriptor.enabled, do_printk);			\
	goto out;							\
do_printk:								\
	printk(KERN_DEBUG pr_fmt(fmt),	##__VA_ARGS__);			\
out:	;								\
	} while (0)


#define dynamic_dev_dbg(dev, fmt, ...) do {				\
	__label__ do_printk;						\
	__label__ out;							\
	static struct _ddebug descriptor				\
	__used								\
	__attribute__((section("__verbose"), aligned(8))) =		\
	{ KBUILD_MODNAME, __func__, __FILE__, fmt, DEBUG_HASH,	\
		DEBUG_HASH2, __LINE__, _DPRINTK_FLAGS_DEFAULT };	\
	if (__dynamic_dbg_enabled(descriptor))				\
	{ KBUILD_MODNAME, __func__, __FILE__, fmt, __LINE__,		\
		_DPRINTK_FLAGS_DEFAULT };				\
	JUMP_LABEL(&descriptor.enabled, do_printk);			\
	goto out;							\
do_printk:								\
	dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__);		\
out:	;								\
	} while (0)

#else
+3 −39
Original line number Diff line number Diff line
@@ -26,19 +26,11 @@
#include <linux/dynamic_debug.h>
#include <linux/debugfs.h>
#include <linux/slab.h>
#include <linux/jump_label.h>

extern struct _ddebug __start___verbose[];
extern struct _ddebug __stop___verbose[];

/* dynamic_debug_enabled, and dynamic_debug_enabled2 are bitmasks in which
 * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They
 * use independent hash functions, to reduce the chance of false positives.
 */
long long dynamic_debug_enabled;
EXPORT_SYMBOL_GPL(dynamic_debug_enabled);
long long dynamic_debug_enabled2;
EXPORT_SYMBOL_GPL(dynamic_debug_enabled2);

struct ddebug_table {
	struct list_head link;
	char *mod_name;
@@ -87,26 +79,6 @@ static char *ddebug_describe_flags(struct _ddebug *dp, char *buf,
	return buf;
}

/*
 * must be called with ddebug_lock held
 */

static int disabled_hash(char hash, bool first_table)
{
	struct ddebug_table *dt;
	char table_hash_value;

	list_for_each_entry(dt, &ddebug_tables, link) {
		if (first_table)
			table_hash_value = dt->ddebugs->primary_hash;
		else
			table_hash_value = dt->ddebugs->secondary_hash;
		if (dt->num_enabled && (hash == table_hash_value))
			return 0;
	}
	return 1;
}

/*
 * Search the tables for _ddebug's which match the given
 * `query' and apply the `flags' and `mask' to them.  Tells
@@ -170,17 +142,9 @@ static void ddebug_change(const struct ddebug_query *query,
				dt->num_enabled++;
			dp->flags = newflags;
			if (newflags) {
				dynamic_debug_enabled |=
						(1LL << dp->primary_hash);
				dynamic_debug_enabled2 |=
						(1LL << dp->secondary_hash);
				enable_jump_label(&dp->enabled);
			} else {
				if (disabled_hash(dp->primary_hash, true))
					dynamic_debug_enabled &=
						~(1LL << dp->primary_hash);
				if (disabled_hash(dp->secondary_hash, false))
					dynamic_debug_enabled2 &=
						~(1LL << dp->secondary_hash);
				disable_jump_label(&dp->enabled);
			}
			if (verbose)
				printk(KERN_INFO
+1 −10
Original line number Diff line number Diff line
@@ -101,14 +101,6 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))"
modname_flags  = $(if $(filter 1,$(words $(modname))),\
                 -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))")

#hash values
ifdef CONFIG_DYNAMIC_DEBUG
debug_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname))"\
              -D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname))"
else
debug_flags =
endif

orig_c_flags   = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \
                 $(ccflags-y) $(CFLAGS_$(basetarget).o)
_c_flags       = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags))
@@ -152,8 +144,7 @@ endif

c_flags        = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
		 $(__c_flags) $(modkern_cflags)                           \
		 -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \
		  $(debug_flags)
		 -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags)

a_flags        = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
		 $(__a_flags) $(modkern_aflags)
+1 −1
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@
# fixdep: 	 Used to generate dependency information during build process
# docproc:	 Used in Documentation/DocBook

hostprogs-y	:= fixdep docproc hash
hostprogs-y	:= fixdep docproc
always		:= $(hostprogs-y)

# fixdep is needed to compile other host programs

scripts/basic/hash.c

deleted100644 → 0
+0 −64
Original line number Diff line number Diff line
/*
 * Copyright (C) 2008 Red Hat, Inc., Jason Baron <jbaron@redhat.com>
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define DYNAMIC_DEBUG_HASH_BITS 6

static const char *program;

static void usage(void)
{
	printf("Usage: %s <djb2|r5> <modname>\n", program);
	exit(1);
}

/* djb2 hashing algorithm by Dan Bernstein. From:
 * http://www.cse.yorku.ca/~oz/hash.html
 */

static unsigned int djb2_hash(char *str)
{
	unsigned long hash = 5381;
	int c;

	c = *str;
	while (c) {
		hash = ((hash << 5) + hash) + c;
		c = *++str;
	}
	return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1));
}

static unsigned int r5_hash(char *str)
{
	unsigned long hash = 0;
	int c;

	c = *str;
	while (c) {
		hash = (hash + (c << 4) + (c >> 4)) * 11;
		c = *++str;
	}
	return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1));
}

int main(int argc, char *argv[])
{
	program = argv[0];

	if (argc != 3)
		usage();
	if (!strcmp(argv[1], "djb2"))
		printf("%d\n", djb2_hash(argv[2]));
	else if (!strcmp(argv[1], "r5"))
		printf("%d\n", r5_hash(argv[2]));
	else
		usage();
	exit(0);
}