From: Adrian Hunter <adrian.hunter@intel.com>
To: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>,
linux-kernel@vger.kernel.org, David Ahern <dsahern@gmail.com>,
Frederic Weisbecker <fweisbec@gmail.com>,
Jiri Olsa <jolsa@redhat.com>, Namhyung Kim <namhyung@gmail.com>,
Paul Mackerras <paulus@samba.org>,
Stephane Eranian <eranian@google.com>
Subject: [PATCH V2 14/22] perf itrace: Add a hashtable for caching decoded instructions
Date: Thu, 20 Nov 2014 15:23:20 +0200 [thread overview]
Message-ID: <1416489808-4489-15-git-send-email-adrian.hunter@intel.com> (raw)
In-Reply-To: <1416489808-4489-1-git-send-email-adrian.hunter@intel.com>
Decoding Instruction Trace data may involve walking object
code. Rather than repetitively decoding the same instructions,
a cache can be used to cache the results.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
tools/perf/util/itrace.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++
tools/perf/util/itrace.h | 14 ++++++
2 files changed, 137 insertions(+)
diff --git a/tools/perf/util/itrace.c b/tools/perf/util/itrace.c
index eb43a7f..fd67a9a 100644
--- a/tools/perf/util/itrace.c
+++ b/tools/perf/util/itrace.c
@@ -37,6 +37,8 @@
#include "thread_map.h"
#include "itrace.h"
+#include <linux/hash.h>
+
#include "event.h"
#include "session.h"
#include "debug.h"
@@ -916,3 +918,124 @@ int itrace_mmap__read(struct itrace_mmap *mm, struct itrace_record *itr,
return 1;
}
+
+/**
+ * struct itrace_cache - hash table to cache decoded instruction blocks
+ * @hashtable: the hashtable
+ * @sz: hashtable size (number of hlists)
+ * @entry_size: size of an entry
+ * @limit: limit the number of entries to this maximum, when reached the cache
+ * is dropped and caching begins again with an empty cache
+ * @cnt: current number of entries
+ * @bits: hashtable size (@sz = 2^@bits)
+ */
+struct itrace_cache {
+ struct hlist_head *hashtable;
+ size_t sz;
+ size_t entry_size;
+ size_t limit;
+ size_t cnt;
+ unsigned int bits;
+};
+
+struct itrace_cache *itrace_cache__new(unsigned int bits, size_t entry_size,
+ unsigned int limit_percent)
+{
+ struct itrace_cache *c;
+ struct hlist_head *ht;
+ size_t sz, i;
+
+ c = zalloc(sizeof(struct itrace_cache));
+ if (!c)
+ return NULL;
+
+ sz = 1UL << bits;
+
+ ht = calloc(sz, sizeof(struct hlist_head));
+ if (!ht)
+ goto out_free;
+
+ for (i = 0; i < sz; i++)
+ INIT_HLIST_HEAD(&ht[i]);
+
+ c->hashtable = ht;
+ c->sz = sz;
+ c->entry_size = entry_size;
+ c->limit = (c->sz * limit_percent) / 100;
+ c->bits = bits;
+
+ return c;
+
+out_free:
+ free(c);
+ return NULL;
+}
+
+static void itrace_cache__drop(struct itrace_cache *c)
+{
+ struct itrace_cache_entry *entry;
+ struct hlist_node *tmp;
+ size_t i;
+
+ if (!c)
+ return;
+
+ for (i = 0; i < c->sz; i++) {
+ hlist_for_each_entry_safe(entry, tmp, &c->hashtable[i], hash) {
+ hlist_del(&entry->hash);
+ itrace_cache__free_entry(c, entry);
+ }
+ }
+
+ c->cnt = 0;
+}
+
+void itrace_cache__free(struct itrace_cache *c)
+{
+ if (!c)
+ return;
+
+ itrace_cache__drop(c);
+ free(c->hashtable);
+ free(c);
+}
+
+void *itrace_cache__alloc_entry(struct itrace_cache *c)
+{
+ return malloc(c->entry_size);
+}
+
+void itrace_cache__free_entry(struct itrace_cache *c __maybe_unused,
+ void *entry)
+{
+ free(entry);
+}
+
+int itrace_cache__add(struct itrace_cache *c, u32 key,
+ struct itrace_cache_entry *entry)
+{
+ if (c->limit && ++c->cnt > c->limit)
+ itrace_cache__drop(c);
+
+ entry->key = key;
+ hlist_add_head(&entry->hash, &c->hashtable[hash_32(key, c->bits)]);
+
+ return 0;
+}
+
+void *itrace_cache__lookup(struct itrace_cache *c, u32 key)
+{
+ struct itrace_cache_entry *entry;
+ struct hlist_head *hlist;
+
+ if (!c)
+ return NULL;
+
+ hlist = &c->hashtable[hash_32(key, c->bits)];
+ hlist_for_each_entry(entry, hlist, hash) {
+ if (entry->key == key)
+ return entry;
+ }
+
+ return NULL;
+}
diff --git a/tools/perf/util/itrace.h b/tools/perf/util/itrace.h
index 575037c..e67fa34 100644
--- a/tools/perf/util/itrace.h
+++ b/tools/perf/util/itrace.h
@@ -316,6 +316,20 @@ int itrace_heap__add(struct itrace_heap *heap, unsigned int queue_nr,
void itrace_heap__pop(struct itrace_heap *heap);
void itrace_heap__free(struct itrace_heap *heap);
+struct itrace_cache_entry {
+ struct hlist_node hash;
+ u32 key;
+};
+
+struct itrace_cache *itrace_cache__new(unsigned int bits, size_t entry_size,
+ unsigned int limit_percent);
+void itrace_cache__free(struct itrace_cache *itrace_cache);
+void *itrace_cache__alloc_entry(struct itrace_cache *c);
+void itrace_cache__free_entry(struct itrace_cache *c, void *entry);
+int itrace_cache__add(struct itrace_cache *c, u32 key,
+ struct itrace_cache_entry *entry);
+void *itrace_cache__lookup(struct itrace_cache *c, u32 key);
+
struct itrace_record *itrace_record__init(int *err);
int itrace_record__options(struct itrace_record *itr,
--
1.9.1
next prev parent reply other threads:[~2014-11-20 13:29 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-20 13:23 [PATCH V2 00/22] perf tools: Introduce an abstraction for Instruction Tracing Adrian Hunter
2014-11-20 13:23 ` [PATCH V2 01/22] perf header: Add Instruction Tracing feature Adrian Hunter
2014-11-20 13:23 ` [PATCH V2 02/22] perf evlist: Add initial support for mmapping an Instruction Trace buffer Adrian Hunter
2014-11-25 16:57 ` Jiri Olsa
2014-11-26 13:11 ` Adrian Hunter
2014-12-09 13:24 ` Arnaldo Carvalho de Melo
2014-12-10 12:28 ` Adrian Hunter
2014-11-20 13:23 ` [PATCH V2 03/22] perf tools: Add user events for Instruction Tracing Adrian Hunter
2014-11-20 13:23 ` [PATCH V2 04/22] perf tools: Add support for Instruction Trace recording Adrian Hunter
2014-11-20 13:23 ` [PATCH V2 05/22] perf record: Add basic Instruction Tracing support Adrian Hunter
2014-11-20 13:23 ` [PATCH V2 06/22] perf record: Extend -m option for Instruction Tracing mmap pages Adrian Hunter
2014-11-20 13:23 ` [PATCH V2 07/22] perf tools: Add a user event for Instruction Tracing errors Adrian Hunter
2014-11-20 13:23 ` [PATCH V2 08/22] perf session: Add hooks to allow transparent decoding of Instruction Tracing data Adrian Hunter
2014-11-20 13:23 ` [PATCH V2 09/22] perf session: Add Instruction Tracing options Adrian Hunter
2014-11-20 13:23 ` [PATCH V2 10/22] perf itrace: Add helpers for Instruction Tracing errors Adrian Hunter
2014-11-20 13:23 ` [PATCH V2 11/22] perf itrace: Add helpers for queuing Instruction Tracing data Adrian Hunter
2014-11-20 13:23 ` [PATCH V2 12/22] perf itrace: Add a heap for sorting Instruction Tracing queues Adrian Hunter
2014-11-20 13:23 ` [PATCH V2 13/22] perf itrace: Add processing for Instruction Tracing events Adrian Hunter
2014-11-20 13:23 ` Adrian Hunter [this message]
2014-11-20 13:23 ` [PATCH V2 15/22] perf tools: Add member to struct dso for an instruction cache Adrian Hunter
2014-11-20 13:23 ` [PATCH V2 16/22] perf script: Add Instruction Tracing support Adrian Hunter
2014-11-20 13:23 ` [PATCH V2 17/22] perf script: Always allow fields 'addr' and 'cpu' for itrace Adrian Hunter
2014-11-20 13:23 ` [PATCH V2 18/22] perf report: Add Instruction Tracing support Adrian Hunter
2014-11-20 13:23 ` [PATCH V2 19/22] perf inject: Re-pipe Instruction Tracing events Adrian Hunter
2014-11-20 13:23 ` [PATCH V2 20/22] perf inject: Add Instruction Tracing support Adrian Hunter
2014-11-20 13:23 ` [PATCH V2 21/22] perf tools: Add Instruction Tracing index Adrian Hunter
2014-11-20 13:23 ` [PATCH V2 22/22] perf tools: Hit all build ids when Instruction Tracing Adrian Hunter
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=1416489808-4489-15-git-send-email-adrian.hunter@intel.com \
--to=adrian.hunter@intel.com \
--cc=acme@kernel.org \
--cc=dsahern@gmail.com \
--cc=eranian@google.com \
--cc=fweisbec@gmail.com \
--cc=jolsa@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=namhyung@gmail.com \
--cc=paulus@samba.org \
--cc=peterz@infradead.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox