public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Profile likely/unlikely macros
@ 2006-04-25  2:57 Daniel Walker
  2006-04-25  3:06 ` Andrew Morton
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Daniel Walker @ 2006-04-25  2:57 UTC (permalink / raw)
  To: linux-kernel; +Cc: akpm, dwalker, hzhong

This patch adds a very lightweight profiling feature to the
likely/unlikely macros. It should work in all contexts including
NMI, and during boot. The patch is for 2.6.17-rc2 . 

It has a /proc/likely_prof interface which outputs something like 
the following,

Likely Profiling Results
 --------------------------------------------------------------------
[+- ] Type | # True | # False | Function:Filename@Line
 unlikely |        0|        3  tcp_sacktag_write_queue()@:net/ipv4/tcp_input.c@1215
 unlikely |        0|        3  tcp_sacktag_write_queue()@:net/ipv4/tcp_input.c@1214
 unlikely |        0|        3  tcp_sacktag_write_queue()@:net/ipv4/tcp_input.c@1213
+unlikely |     5050|        0  do_sys_vm86()@:arch/i386/kernel/vm86.c@314
 unlikely |        0|     5050  do_sys_vm86()@:arch/i386/kernel/vm86.c@305
+unlikely |    10100|        0  load_esp0()@:include/asm/processor.h@498
+unlikely |    10100|        0  load_esp0()@:include/asm/processor.h@498
-likely   |        0|     1945  audit_free()@:kernel/auditsc.c@715

You can identify which statments are miss labeled from the + or - in front .

Signed-Off-By: Daniel Walker <dwalker@mvista.com>

Index: linux-2.6.16/include/linux/compiler.h
===================================================================
--- linux-2.6.16.orig/include/linux/compiler.h
+++ linux-2.6.16/include/linux/compiler.h
@@ -53,14 +53,44 @@ extern void __chk_io_ptr(void __iomem *)
 # include <linux/compiler-intel.h>
 #endif
 
+#ifdef CONFIG_PROFILE_LIKELY
+struct likeliness {
+	const char *func;
+	char *file;
+	int line;
+	int type;
+	unsigned int count[2]; 
+	struct likeliness *next;
+};
+
+extern int do_check_likely(struct likeliness *likeliness, int exp);
+
+# define LIKELY_UNSEEN	4
+
+# define __check_likely(exp, is_likely)							\
+	({										\
+		static __attribute__((__section__(".likely.data")))			\
+			struct likeliness likeliness = {				\
+				.func = __func__,					\
+				.file = __FILE__,					\
+				.line = __LINE__,					\
+				.type = is_likely | LIKELY_UNSEEN,			\
+			};								\
+		do_check_likely(&likeliness, !!(exp));					\
+	})
+
+# define likely(x)	__check_likely(x, 1)
+# define unlikely(x)	__check_likely(x, 0)
+#else
 /*
  * Generic compiler-dependent macros required for kernel
  * build go below this comment. Actual compiler/compiler version
  * specific implementations come from the above header files
  */
 
-#define likely(x)	__builtin_expect(!!(x), 1)
-#define unlikely(x)	__builtin_expect(!!(x), 0)
+# define likely(x)	__builtin_expect(!!(x), 1)
+# define unlikely(x)	__builtin_expect(!!(x), 0)
+#endif
 
 /* Optimization barrier */
 #ifndef barrier
Index: linux-2.6.16/lib/Kconfig.debug
===================================================================
--- linux-2.6.16.orig/lib/Kconfig.debug
+++ linux-2.6.16/lib/Kconfig.debug
@@ -223,3 +223,10 @@ config RCU_TORTURE_TEST
 	  at boot time (you probably don't).
 	  Say M if you want the RCU torture tests to build as a module.
 	  Say N if you are unsure.
+config	PROFILE_LIKELY 
+	bool "Record return values from likely/unlikely macros"
+	default n
+	help
+	  Adds profiling on likely/unlikly macros . To see the
+	  results of the profiling you can view the following,
+		/proc/likely_prof
Index: linux-2.6.16/lib/Makefile
===================================================================
--- linux-2.6.16.orig/lib/Makefile
+++ linux-2.6.16/lib/Makefile
@@ -49,6 +49,8 @@ obj-$(CONFIG_TEXTSEARCH_FSM) += ts_fsm.o
 
 obj-$(CONFIG_SWIOTLB) += swiotlb.o
 
+obj-$(CONFIG_PROFILE_LIKELY) += likely_prof.o
+
 hostprogs-y	:= gen_crc32table
 clean-files	:= crc32table.h
 
Index: linux-2.6.16/lib/likely_prof.c
===================================================================
--- /dev/null
+++ linux-2.6.16/lib/likely_prof.c
@@ -0,0 +1,134 @@
+/*
+ * This code should enable profiling the likely and unlikely macros.
+ *
+ * Output goes in /prof/likely_prof
+ *
+ * Authors:
+ * Daniel Walker <dwalker@mvista.com> 
+ * Hua Zhong <hzhong@gmail.com>
+ * Andrew Morton <akpm@osdl.org>
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+#include <asm/bug.h>
+#include <asm/atomic.h>
+
+#define WAS_UNLIKELY	0	
+#define WAS_LIKELY	1
+
+static struct likeliness *likeliness_head = NULL; 
+
+static atomic_t likely_lock = ATOMIC_INIT(1);
+
+int do_check_likely(struct likeliness *likeliness, int ret)
+{
+	if (ret)
+		likeliness->count[1]++;
+	else
+		likeliness->count[0]++;
+
+	if (likeliness->type & LIKELY_UNSEEN) {
+		if (atomic_dec_and_test(&likely_lock)) {
+			if (likeliness->type & LIKELY_UNSEEN) {
+				likeliness->type &= (~LIKELY_UNSEEN);
+				likeliness->next = likeliness_head;
+				likeliness_head = likeliness;
+			}
+		}
+		atomic_inc(&likely_lock);
+	}
+
+	return ret;
+}
+
+static void * lp_seq_start(struct seq_file *out, loff_t *pos)
+{
+
+	if (!*pos) {
+
+		seq_printf(out, "Likely Profiling Results\n");
+		seq_printf(out, " --------------------------------------------------------------------\n");
+		seq_printf(out, "[+- ] Type | # True | # False | Function:Filename@Line\n");
+
+		out->private = (void *)likeliness_head;
+	}
+
+	return out->private;
+}
+
+static void * lp_seq_next(struct seq_file *out, void *p, loff_t *pos)
+{
+	struct likeliness * entry = (struct likeliness *) p;
+
+	if (entry->next) {
+		++(*pos);
+		out->private = (void *)entry->next;
+	} else 
+		out->private = NULL;
+
+	return (out->private);
+}
+
+static int lp_seq_show(struct seq_file *out, void *p)
+{
+	struct likeliness * entry = (struct likeliness *)p;
+	int true = entry->count[1], false = entry->count[0];
+	
+	if (entry->type == WAS_UNLIKELY) {
+		if (true > false)
+			seq_printf(out, "+");
+		else
+			seq_printf(out, " ");
+
+		seq_printf(out, "unlikely ");
+	}
+	else if (entry->type == WAS_LIKELY) {
+		if (true < false)
+			seq_printf(out, "-");
+		else
+			seq_printf(out, " ");
+
+		seq_printf(out, "likely   ");
+	} 
+
+	seq_printf(out, "|%9u|%9u\t%s()@:%s@%d\n", true, false,
+			entry->func, entry->file, entry->line); 
+
+	return 0;
+}
+
+static void lp_seq_stop(struct seq_file *m, void *p) { }
+
+struct seq_operations likely_profiling_ops = {
+	.start  = lp_seq_start,
+	.next   = lp_seq_next,
+	.stop   = lp_seq_stop,
+	.show   = lp_seq_show
+};
+
+static int lp_results_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &likely_profiling_ops);
+}
+
+static struct file_operations proc_likely_operations  = {
+	.open           = lp_results_open,
+	.read           = seq_read,
+	.llseek         = seq_lseek,
+	.release        = seq_release,
+};
+
+static int __init init_likely(void)
+{
+	struct proc_dir_entry *entry;
+	entry = create_proc_entry("likely_prof", 0, &proc_root);
+	if (entry) 
+		entry->proc_fops = &proc_likely_operations;
+
+	return 0;
+}
+__initcall(init_likely);

^ permalink raw reply	[flat|nested] 13+ messages in thread
* Re: [PATCH] Profile likely/unlikely macros
@ 2006-04-25  9:15 Mikael Pettersson
  0 siblings, 0 replies; 13+ messages in thread
From: Mikael Pettersson @ 2006-04-25  9:15 UTC (permalink / raw)
  To: dwalker, linux-kernel; +Cc: akpm, hzhong

On Mon, 24 Apr 2006 19:57:47 -0700, Daniel Walker wrote:
>+	if (likeliness->type & LIKELY_UNSEEN) {
>+		if (atomic_dec_and_test(&likely_lock)) {
>+			if (likeliness->type & LIKELY_UNSEEN) {
>+				likeliness->type &= (~LIKELY_UNSEEN);
>+				likeliness->next = likeliness_head;
>+				likeliness_head = likeliness;
>+			}
>+		}
>+		atomic_inc(&likely_lock);
>+	}

I'm pretty sure one can do this (prepending an element to a list)
w/o fiddling with locks by using CAS and looping until successful.

/Mikael

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2006-05-01 22:05 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-04-25  2:57 [PATCH] Profile likely/unlikely macros Daniel Walker
2006-04-25  3:06 ` Andrew Morton
2006-04-25  3:17   ` Daniel Walker
2006-04-25 10:11   ` Nick Piggin
2006-04-25 18:06     ` Hua Zhong
2006-04-25 18:23     ` Daniel Walker
2006-04-26  1:08       ` Nick Piggin
2006-04-26  9:56         ` Jörn Engel
2006-04-26 10:07           ` Nick Piggin
2006-04-25 23:14     ` Chen, Kenneth W
2006-04-25  9:19 ` Andreas Mohr
2006-05-01 22:05 ` Roland Dreier
  -- strict thread matches above, loose matches on Subject: below --
2006-04-25  9:15 Mikael Pettersson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox