From: Roel Kluin <12o3l@tiscali.nl>
To: dwalker@mvista.com
Cc: lkml <linux-kernel@vger.kernel.org>
Subject: [PATCH v1] change likeliness accounting
Date: Fri, 14 Mar 2008 00:06:04 +0100 [thread overview]
Message-ID: <47D9B35C.9@tiscali.nl> (raw)
In the patch below I propose some changes to the likely/unlikely accounting.
---
In struct likeliness: store __builtin_return_address in 'caller', rather than
__FILE__ and __func__, and combine 'type' and 'line' into one 'label'.
The __check_likely macro performs some functionality originally in
do_check_likely(): The first check for LP_UNSEEN bit, the increment of the
experienced likely-count. do_check_likely() looses its parameter and return
value. I added a __builtin_expect() to make use of the expectation.
The likely diplay changes: now +/- denotes whether expectation fails in less
than 0.01% of the tests rather than whether more unexpected than expected were
encountered. __FILE__ is no longer displayed in output.
struct seq_operations becomes static and corrects a typo in comment.
Signed-off-by: Roel Kluin <12o3l@tiscali.nl>
---
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index d6d9efc..be055de 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -53,27 +53,31 @@ extern void __chk_io_ptr(const volatile void __iomem *);
#if defined(CONFIG_PROFILE_LIKELY) && !(defined(CONFIG_MODULE_UNLOAD) && defined(MODULE))
struct likeliness {
- const char *func;
- char *file;
- int line;
- int type;
+ unsigned long caller;
+ unsigned int label;
unsigned int count[2];
struct likeliness *next;
};
-extern int do_check_likely(struct likeliness *likeliness, int exp);
+extern void do_check_likely(struct likeliness *likeliness);
-#define LP_UNSEEN 4
+#define LP_IS_EXPECTED 1
+#define LP_UNSEEN 2
+#define LP_LINE_SHIFT 2
#define __check_likely(exp, is_likely) \
({ \
static struct likeliness likeliness = { \
- .func = __func__, \
- .file = __FILE__, \
- .line = __LINE__, \
- .type = is_likely | LP_UNSEEN, \
+ .label = __LINE__ << LP_LINE_SHIFT | \
+ LP_UNSEEN | is_likely, \
}; \
- do_check_likely(&likeliness, !!(exp)); \
+ \
+ if (likeliness.label & LP_UNSEEN) \
+ do_check_likely(&likeliness); \
+ \
+ __builtin_expect(!!(exp), is_likely) ? \
+ likeliness.count[1]++ || 1 : \
+ likeliness.count[0]++ && 0; \
})
/*
diff --git a/lib/likely_prof.c b/lib/likely_prof.c
index 5c6d91d..06f2edb 100644
--- a/lib/likely_prof.c
+++ b/lib/likely_prof.c
@@ -15,41 +15,34 @@
#include <linux/fs.h>
#include <linux/seq_file.h>
#include <linux/proc_fs.h>
+#include <linux/kallsyms.h>
#include <asm/bug.h>
#include <asm/atomic.h>
static struct likeliness *likeliness_head;
-int do_check_likely(struct likeliness *likeliness, int ret)
+void do_check_likely(struct likeliness *likeliness)
{
static unsigned long likely_lock;
- if (ret)
- likeliness->count[1]++;
- else
- likeliness->count[0]++;
-
- if (likeliness->type & LP_UNSEEN) {
- /*
- * We don't simple use a spinlock because internally to the
- * spinlock there is a call to unlikely which causes recursion.
- * We opted for this method because we didn't need a preempt/irq
- * disable and it was a bit cleaner then using internal __raw
- * spinlock calls.
- */
- if (!test_and_set_bit(0, &likely_lock)) {
- if (likeliness->type & LP_UNSEEN) {
- likeliness->type &= (~LP_UNSEEN);
- likeliness->next = likeliness_head;
- likeliness_head = likeliness;
- }
- smp_mb__before_clear_bit();
- clear_bit(0, &likely_lock);
+ /*
+ * We don't simply use a spinlock because internally to the spinlock
+ * there is a call to unlikely which causes recursion. We opted for this
+ * method because we didn't need a preempt/irq disable and it was a bit
+ * cleaner then using internal __raw spinlock calls.
+ */
+ if (!test_and_set_bit(0, &likely_lock)) {
+ if (likeliness->label & LP_UNSEEN) {
+ likeliness->label &= (~LP_UNSEEN);
+ likeliness->next = likeliness_head;
+ likeliness_head = likeliness;
+ likeliness->caller = (unsigned long)
+ __builtin_return_address(0);
}
+ smp_mb__before_clear_bit();
+ clear_bit(0, &likely_lock);
}
-
- return ret;
}
EXPORT_SYMBOL(do_check_likely);
@@ -86,18 +79,22 @@ static void *lp_seq_next(struct seq_file *out, void *p, loff_t *pos)
static int lp_seq_show(struct seq_file *out, void *p)
{
struct likeliness *entry = p;
- unsigned int true = entry->count[1];
- unsigned int false = entry->count[0];
-
- if (!entry->type) {
- if (true > false)
+ char function[KSYM_SYMBOL_LEN];
+ unsigned int pos = entry->count[1];
+ unsigned int neg = entry->count[0];
+
+ /*
+ * Balanced if the suggestion was false in less than 0.01% of the tests
+ */
+ if (!(entry->label & LP_IS_EXPECTED)) {
+ if (neg != 0 && (10000 * pos) / (pos + neg) > 1)
seq_printf(out, "+");
else
seq_printf(out, " ");
seq_printf(out, "unlikely ");
} else {
- if (true < false)
+ if (pos != 0 && (10000 * neg) / (pos + neg) > 1)
seq_printf(out, "-");
else
seq_printf(out, " ");
@@ -105,8 +102,9 @@ static int lp_seq_show(struct seq_file *out, void *p)
seq_printf(out, "likely ");
}
- seq_printf(out, "|%9u|%9u\t%s()@:%s@%d\n", true, false,
- entry->func, entry->file, entry->line);
+ sprint_symbol(function, entry->caller);
+ seq_printf(out, "|%9u|%9u\t%s()@:%u\n", pos, neg, function,
+ entry->label >> LP_LINE_SHIFT);
return 0;
}
@@ -115,7 +113,7 @@ static void lp_seq_stop(struct seq_file *m, void *p)
{
}
-struct seq_operations likely_profiling_ops = {
+static struct seq_operations likely_profiling_ops = {
.start = lp_seq_start,
.next = lp_seq_next,
.stop = lp_seq_stop,
next reply other threads:[~2008-03-13 23:06 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-03-13 23:06 Roel Kluin [this message]
2008-03-14 19:53 ` [PATCH v1] change likeliness accounting Daniel Walker
2008-03-14 20:26 ` Daniel Walker
2008-03-17 2:45 ` Nick Piggin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=47D9B35C.9@tiscali.nl \
--to=12o3l@tiscali.nl \
--cc=dwalker@mvista.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.