提交 f3acb3a8 编写于 作者: D Davidlohr Bueso 提交者: Arnaldo Carvalho de Melo

perf machine: Use cached rbtrees

At the cost of an extra pointer, we can avoid the O(logN) cost of
finding the first element in the tree (smallest node), which is
something required for nearly every operation dealing with
machine->guests and threads->entries.

The conversion is straightforward, however, it's worth noticing that the
rb_erase_init() calls have been replaced by rb_erase_cached() which has
no _init() flavor, however, the node is explicitly cleared next anyway,
which was redundant until now.
Signed-off-by: NDavidlohr Bueso <dbueso@suse.de>
Tested-by: NArnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/r/20181206191819.30182-3-dave@stgolabs.netSigned-off-by: NArnaldo Carvalho de Melo <acme@redhat.com>
上级 3aef2cad
...@@ -753,7 +753,8 @@ static int tasks_print(struct report *rep, FILE *fp) ...@@ -753,7 +753,8 @@ static int tasks_print(struct report *rep, FILE *fp)
for (i = 0; i < THREADS__TABLE_SIZE; i++) { for (i = 0; i < THREADS__TABLE_SIZE; i++) {
struct threads *threads = &machine->threads[i]; struct threads *threads = &machine->threads[i];
for (nd = rb_first(&threads->entries); nd; nd = rb_next(nd)) { for (nd = rb_first_cached(&threads->entries); nd;
nd = rb_next(nd)) {
task = tasks + itask++; task = tasks + itask++;
task->thread = rb_entry(nd, struct thread, rb_node); task->thread = rb_entry(nd, struct thread, rb_node);
......
...@@ -364,7 +364,8 @@ int perf_session__write_buildid_table(struct perf_session *session, ...@@ -364,7 +364,8 @@ int perf_session__write_buildid_table(struct perf_session *session,
if (err) if (err)
return err; return err;
for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) { for (nd = rb_first_cached(&session->machines.guests); nd;
nd = rb_next(nd)) {
struct machine *pos = rb_entry(nd, struct machine, rb_node); struct machine *pos = rb_entry(nd, struct machine, rb_node);
err = machine__write_buildid_table(pos, fd); err = machine__write_buildid_table(pos, fd);
if (err) if (err)
...@@ -397,7 +398,8 @@ int dsos__hit_all(struct perf_session *session) ...@@ -397,7 +398,8 @@ int dsos__hit_all(struct perf_session *session)
if (err) if (err)
return err; return err;
for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) { for (nd = rb_first_cached(&session->machines.guests); nd;
nd = rb_next(nd)) {
struct machine *pos = rb_entry(nd, struct machine, rb_node); struct machine *pos = rb_entry(nd, struct machine, rb_node);
err = machine__hit_all_dsos(pos); err = machine__hit_all_dsos(pos);
...@@ -850,7 +852,8 @@ int perf_session__cache_build_ids(struct perf_session *session) ...@@ -850,7 +852,8 @@ int perf_session__cache_build_ids(struct perf_session *session)
ret = machine__cache_build_ids(&session->machines.host); ret = machine__cache_build_ids(&session->machines.host);
for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) { for (nd = rb_first_cached(&session->machines.guests); nd;
nd = rb_next(nd)) {
struct machine *pos = rb_entry(nd, struct machine, rb_node); struct machine *pos = rb_entry(nd, struct machine, rb_node);
ret |= machine__cache_build_ids(pos); ret |= machine__cache_build_ids(pos);
} }
...@@ -867,7 +870,8 @@ bool perf_session__read_build_ids(struct perf_session *session, bool with_hits) ...@@ -867,7 +870,8 @@ bool perf_session__read_build_ids(struct perf_session *session, bool with_hits)
struct rb_node *nd; struct rb_node *nd;
bool ret = machine__read_build_ids(&session->machines.host, with_hits); bool ret = machine__read_build_ids(&session->machines.host, with_hits);
for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) { for (nd = rb_first_cached(&session->machines.guests); nd;
nd = rb_next(nd)) {
struct machine *pos = rb_entry(nd, struct machine, rb_node); struct machine *pos = rb_entry(nd, struct machine, rb_node);
ret |= machine__read_build_ids(pos, with_hits); ret |= machine__read_build_ids(pos, with_hits);
} }
......
...@@ -42,7 +42,7 @@ static void machine__threads_init(struct machine *machine) ...@@ -42,7 +42,7 @@ static void machine__threads_init(struct machine *machine)
for (i = 0; i < THREADS__TABLE_SIZE; i++) { for (i = 0; i < THREADS__TABLE_SIZE; i++) {
struct threads *threads = &machine->threads[i]; struct threads *threads = &machine->threads[i];
threads->entries = RB_ROOT; threads->entries = RB_ROOT_CACHED;
init_rwsem(&threads->lock); init_rwsem(&threads->lock);
threads->nr = 0; threads->nr = 0;
INIT_LIST_HEAD(&threads->dead); INIT_LIST_HEAD(&threads->dead);
...@@ -180,7 +180,7 @@ void machine__delete_threads(struct machine *machine) ...@@ -180,7 +180,7 @@ void machine__delete_threads(struct machine *machine)
for (i = 0; i < THREADS__TABLE_SIZE; i++) { for (i = 0; i < THREADS__TABLE_SIZE; i++) {
struct threads *threads = &machine->threads[i]; struct threads *threads = &machine->threads[i];
down_write(&threads->lock); down_write(&threads->lock);
nd = rb_first(&threads->entries); nd = rb_first_cached(&threads->entries);
while (nd) { while (nd) {
struct thread *t = rb_entry(nd, struct thread, rb_node); struct thread *t = rb_entry(nd, struct thread, rb_node);
...@@ -223,7 +223,7 @@ void machine__delete(struct machine *machine) ...@@ -223,7 +223,7 @@ void machine__delete(struct machine *machine)
void machines__init(struct machines *machines) void machines__init(struct machines *machines)
{ {
machine__init(&machines->host, "", HOST_KERNEL_ID); machine__init(&machines->host, "", HOST_KERNEL_ID);
machines->guests = RB_ROOT; machines->guests = RB_ROOT_CACHED;
} }
void machines__exit(struct machines *machines) void machines__exit(struct machines *machines)
...@@ -235,9 +235,10 @@ void machines__exit(struct machines *machines) ...@@ -235,9 +235,10 @@ void machines__exit(struct machines *machines)
struct machine *machines__add(struct machines *machines, pid_t pid, struct machine *machines__add(struct machines *machines, pid_t pid,
const char *root_dir) const char *root_dir)
{ {
struct rb_node **p = &machines->guests.rb_node; struct rb_node **p = &machines->guests.rb_root.rb_node;
struct rb_node *parent = NULL; struct rb_node *parent = NULL;
struct machine *pos, *machine = malloc(sizeof(*machine)); struct machine *pos, *machine = malloc(sizeof(*machine));
bool leftmost = true;
if (machine == NULL) if (machine == NULL)
return NULL; return NULL;
...@@ -252,12 +253,14 @@ struct machine *machines__add(struct machines *machines, pid_t pid, ...@@ -252,12 +253,14 @@ struct machine *machines__add(struct machines *machines, pid_t pid,
pos = rb_entry(parent, struct machine, rb_node); pos = rb_entry(parent, struct machine, rb_node);
if (pid < pos->pid) if (pid < pos->pid)
p = &(*p)->rb_left; p = &(*p)->rb_left;
else else {
p = &(*p)->rb_right; p = &(*p)->rb_right;
leftmost = false;
}
} }
rb_link_node(&machine->rb_node, parent, p); rb_link_node(&machine->rb_node, parent, p);
rb_insert_color(&machine->rb_node, &machines->guests); rb_insert_color_cached(&machine->rb_node, &machines->guests, leftmost);
return machine; return machine;
} }
...@@ -268,7 +271,7 @@ void machines__set_comm_exec(struct machines *machines, bool comm_exec) ...@@ -268,7 +271,7 @@ void machines__set_comm_exec(struct machines *machines, bool comm_exec)
machines->host.comm_exec = comm_exec; machines->host.comm_exec = comm_exec;
for (nd = rb_first(&machines->guests); nd; nd = rb_next(nd)) { for (nd = rb_first_cached(&machines->guests); nd; nd = rb_next(nd)) {
struct machine *machine = rb_entry(nd, struct machine, rb_node); struct machine *machine = rb_entry(nd, struct machine, rb_node);
machine->comm_exec = comm_exec; machine->comm_exec = comm_exec;
...@@ -277,7 +280,7 @@ void machines__set_comm_exec(struct machines *machines, bool comm_exec) ...@@ -277,7 +280,7 @@ void machines__set_comm_exec(struct machines *machines, bool comm_exec)
struct machine *machines__find(struct machines *machines, pid_t pid) struct machine *machines__find(struct machines *machines, pid_t pid)
{ {
struct rb_node **p = &machines->guests.rb_node; struct rb_node **p = &machines->guests.rb_root.rb_node;
struct rb_node *parent = NULL; struct rb_node *parent = NULL;
struct machine *machine; struct machine *machine;
struct machine *default_machine = NULL; struct machine *default_machine = NULL;
...@@ -340,7 +343,7 @@ void machines__process_guests(struct machines *machines, ...@@ -340,7 +343,7 @@ void machines__process_guests(struct machines *machines,
{ {
struct rb_node *nd; struct rb_node *nd;
for (nd = rb_first(&machines->guests); nd; nd = rb_next(nd)) { for (nd = rb_first_cached(&machines->guests); nd; nd = rb_next(nd)) {
struct machine *pos = rb_entry(nd, struct machine, rb_node); struct machine *pos = rb_entry(nd, struct machine, rb_node);
process(pos, data); process(pos, data);
} }
...@@ -353,7 +356,8 @@ void machines__set_id_hdr_size(struct machines *machines, u16 id_hdr_size) ...@@ -353,7 +356,8 @@ void machines__set_id_hdr_size(struct machines *machines, u16 id_hdr_size)
machines->host.id_hdr_size = id_hdr_size; machines->host.id_hdr_size = id_hdr_size;
for (node = rb_first(&machines->guests); node; node = rb_next(node)) { for (node = rb_first_cached(&machines->guests); node;
node = rb_next(node)) {
machine = rb_entry(node, struct machine, rb_node); machine = rb_entry(node, struct machine, rb_node);
machine->id_hdr_size = id_hdr_size; machine->id_hdr_size = id_hdr_size;
} }
...@@ -466,9 +470,10 @@ static struct thread *____machine__findnew_thread(struct machine *machine, ...@@ -466,9 +470,10 @@ static struct thread *____machine__findnew_thread(struct machine *machine,
pid_t pid, pid_t tid, pid_t pid, pid_t tid,
bool create) bool create)
{ {
struct rb_node **p = &threads->entries.rb_node; struct rb_node **p = &threads->entries.rb_root.rb_node;
struct rb_node *parent = NULL; struct rb_node *parent = NULL;
struct thread *th; struct thread *th;
bool leftmost = true;
th = threads__get_last_match(threads, machine, pid, tid); th = threads__get_last_match(threads, machine, pid, tid);
if (th) if (th)
...@@ -486,8 +491,10 @@ static struct thread *____machine__findnew_thread(struct machine *machine, ...@@ -486,8 +491,10 @@ static struct thread *____machine__findnew_thread(struct machine *machine,
if (tid < th->tid) if (tid < th->tid)
p = &(*p)->rb_left; p = &(*p)->rb_left;
else else {
p = &(*p)->rb_right; p = &(*p)->rb_right;
leftmost = false;
}
} }
if (!create) if (!create)
...@@ -496,7 +503,7 @@ static struct thread *____machine__findnew_thread(struct machine *machine, ...@@ -496,7 +503,7 @@ static struct thread *____machine__findnew_thread(struct machine *machine,
th = thread__new(pid, tid); th = thread__new(pid, tid);
if (th != NULL) { if (th != NULL) {
rb_link_node(&th->rb_node, parent, p); rb_link_node(&th->rb_node, parent, p);
rb_insert_color(&th->rb_node, &threads->entries); rb_insert_color_cached(&th->rb_node, &threads->entries, leftmost);
/* /*
* We have to initialize map_groups separately * We have to initialize map_groups separately
...@@ -507,7 +514,7 @@ static struct thread *____machine__findnew_thread(struct machine *machine, ...@@ -507,7 +514,7 @@ static struct thread *____machine__findnew_thread(struct machine *machine,
* leader and that would screwed the rb tree. * leader and that would screwed the rb tree.
*/ */
if (thread__init_map_groups(th, machine)) { if (thread__init_map_groups(th, machine)) {
rb_erase_init(&th->rb_node, &threads->entries); rb_erase_cached(&th->rb_node, &threads->entries);
RB_CLEAR_NODE(&th->rb_node); RB_CLEAR_NODE(&th->rb_node);
thread__put(th); thread__put(th);
return NULL; return NULL;
...@@ -798,7 +805,7 @@ size_t machines__fprintf_dsos(struct machines *machines, FILE *fp) ...@@ -798,7 +805,7 @@ size_t machines__fprintf_dsos(struct machines *machines, FILE *fp)
struct rb_node *nd; struct rb_node *nd;
size_t ret = __dsos__fprintf(&machines->host.dsos.head, fp); size_t ret = __dsos__fprintf(&machines->host.dsos.head, fp);
for (nd = rb_first(&machines->guests); nd; nd = rb_next(nd)) { for (nd = rb_first_cached(&machines->guests); nd; nd = rb_next(nd)) {
struct machine *pos = rb_entry(nd, struct machine, rb_node); struct machine *pos = rb_entry(nd, struct machine, rb_node);
ret += __dsos__fprintf(&pos->dsos.head, fp); ret += __dsos__fprintf(&pos->dsos.head, fp);
} }
...@@ -818,7 +825,7 @@ size_t machines__fprintf_dsos_buildid(struct machines *machines, FILE *fp, ...@@ -818,7 +825,7 @@ size_t machines__fprintf_dsos_buildid(struct machines *machines, FILE *fp,
struct rb_node *nd; struct rb_node *nd;
size_t ret = machine__fprintf_dsos_buildid(&machines->host, fp, skip, parm); size_t ret = machine__fprintf_dsos_buildid(&machines->host, fp, skip, parm);
for (nd = rb_first(&machines->guests); nd; nd = rb_next(nd)) { for (nd = rb_first_cached(&machines->guests); nd; nd = rb_next(nd)) {
struct machine *pos = rb_entry(nd, struct machine, rb_node); struct machine *pos = rb_entry(nd, struct machine, rb_node);
ret += machine__fprintf_dsos_buildid(pos, fp, skip, parm); ret += machine__fprintf_dsos_buildid(pos, fp, skip, parm);
} }
...@@ -858,7 +865,8 @@ size_t machine__fprintf(struct machine *machine, FILE *fp) ...@@ -858,7 +865,8 @@ size_t machine__fprintf(struct machine *machine, FILE *fp)
ret = fprintf(fp, "Threads: %u\n", threads->nr); ret = fprintf(fp, "Threads: %u\n", threads->nr);
for (nd = rb_first(&threads->entries); nd; nd = rb_next(nd)) { for (nd = rb_first_cached(&threads->entries); nd;
nd = rb_next(nd)) {
struct thread *pos = rb_entry(nd, struct thread, rb_node); struct thread *pos = rb_entry(nd, struct thread, rb_node);
ret += thread__fprintf(pos, fp); ret += thread__fprintf(pos, fp);
...@@ -1161,7 +1169,7 @@ int machines__create_guest_kernel_maps(struct machines *machines) ...@@ -1161,7 +1169,7 @@ int machines__create_guest_kernel_maps(struct machines *machines)
void machines__destroy_kernel_maps(struct machines *machines) void machines__destroy_kernel_maps(struct machines *machines)
{ {
struct rb_node *next = rb_first(&machines->guests); struct rb_node *next = rb_first_cached(&machines->guests);
machine__destroy_kernel_maps(&machines->host); machine__destroy_kernel_maps(&machines->host);
...@@ -1169,7 +1177,7 @@ void machines__destroy_kernel_maps(struct machines *machines) ...@@ -1169,7 +1177,7 @@ void machines__destroy_kernel_maps(struct machines *machines)
struct machine *pos = rb_entry(next, struct machine, rb_node); struct machine *pos = rb_entry(next, struct machine, rb_node);
next = rb_next(&pos->rb_node); next = rb_next(&pos->rb_node);
rb_erase(&pos->rb_node, &machines->guests); rb_erase_cached(&pos->rb_node, &machines->guests);
machine__delete(pos); machine__delete(pos);
} }
} }
...@@ -1734,7 +1742,7 @@ static void __machine__remove_thread(struct machine *machine, struct thread *th, ...@@ -1734,7 +1742,7 @@ static void __machine__remove_thread(struct machine *machine, struct thread *th,
BUG_ON(refcount_read(&th->refcnt) == 0); BUG_ON(refcount_read(&th->refcnt) == 0);
if (lock) if (lock)
down_write(&threads->lock); down_write(&threads->lock);
rb_erase_init(&th->rb_node, &threads->entries); rb_erase_cached(&th->rb_node, &threads->entries);
RB_CLEAR_NODE(&th->rb_node); RB_CLEAR_NODE(&th->rb_node);
--threads->nr; --threads->nr;
/* /*
...@@ -2511,7 +2519,8 @@ int machine__for_each_thread(struct machine *machine, ...@@ -2511,7 +2519,8 @@ int machine__for_each_thread(struct machine *machine,
for (i = 0; i < THREADS__TABLE_SIZE; i++) { for (i = 0; i < THREADS__TABLE_SIZE; i++) {
threads = &machine->threads[i]; threads = &machine->threads[i];
for (nd = rb_first(&threads->entries); nd; nd = rb_next(nd)) { for (nd = rb_first_cached(&threads->entries); nd;
nd = rb_next(nd)) {
thread = rb_entry(nd, struct thread, rb_node); thread = rb_entry(nd, struct thread, rb_node);
rc = fn(thread, priv); rc = fn(thread, priv);
if (rc != 0) if (rc != 0)
...@@ -2538,7 +2547,7 @@ int machines__for_each_thread(struct machines *machines, ...@@ -2538,7 +2547,7 @@ int machines__for_each_thread(struct machines *machines,
if (rc != 0) if (rc != 0)
return rc; return rc;
for (nd = rb_first(&machines->guests); nd; nd = rb_next(nd)) { for (nd = rb_first_cached(&machines->guests); nd; nd = rb_next(nd)) {
struct machine *machine = rb_entry(nd, struct machine, rb_node); struct machine *machine = rb_entry(nd, struct machine, rb_node);
rc = machine__for_each_thread(machine, fn, priv); rc = machine__for_each_thread(machine, fn, priv);
......
...@@ -29,11 +29,11 @@ struct vdso_info; ...@@ -29,11 +29,11 @@ struct vdso_info;
#define THREADS__TABLE_SIZE (1 << THREADS__TABLE_BITS) #define THREADS__TABLE_SIZE (1 << THREADS__TABLE_BITS)
struct threads { struct threads {
struct rb_root entries; struct rb_root_cached entries;
struct rw_semaphore lock; struct rw_semaphore lock;
unsigned int nr; unsigned int nr;
struct list_head dead; struct list_head dead;
struct thread *last_match; struct thread *last_match;
}; };
struct machine { struct machine {
...@@ -140,7 +140,7 @@ typedef void (*machine__process_t)(struct machine *machine, void *data); ...@@ -140,7 +140,7 @@ typedef void (*machine__process_t)(struct machine *machine, void *data);
struct machines { struct machines {
struct machine host; struct machine host;
struct rb_root guests; struct rb_root_cached guests;
}; };
void machines__init(struct machines *machines); void machines__init(struct machines *machines);
......
...@@ -144,8 +144,8 @@ struct __name##_sorted *__name = __name##_sorted__new ...@@ -144,8 +144,8 @@ struct __name##_sorted *__name = __name##_sorted__new
__ilist->rblist.nr_entries) __ilist->rblist.nr_entries)
/* For 'struct machine->threads' */ /* For 'struct machine->threads' */
#define DECLARE_RESORT_RB_MACHINE_THREADS(__name, __machine, hash_bucket) \ #define DECLARE_RESORT_RB_MACHINE_THREADS(__name, __machine, hash_bucket) \
DECLARE_RESORT_RB(__name)(&__machine->threads[hash_bucket].entries, \ DECLARE_RESORT_RB(__name)(&__machine->threads[hash_bucket].entries.rb_root, \
__machine->threads[hash_bucket].nr) __machine->threads[hash_bucket].nr)
#endif /* _PERF_RESORT_RB_H_ */ #endif /* _PERF_RESORT_RB_H_ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册