Commit d436f90a authored by Ian Rogers's avatar Ian Rogers Committed by Namhyung Kim

perf machine: Move machine's threads into its own abstraction

Move thread_rb_node into the machine.c file. This hides the
implementation of threads from the rest of the code allowing for it to
be refactored.

Locking discipline is tightened up in this change. As the lock is now
encapsulated in threads, the findnew function requires holding it (as
it already did in machine). Rather than do conditionals with locks
based on whether the thread should be created (which could potentially
be error prone with a read lock match with a write unlock), have a
separate threads__find that won't create the thread and only holds the
read lock. This effectively duplicates the findnew logic, with the
existing findnew logic only operating under a write lock assuming
creation is necessary as a previous find failed. The creation may
still fail with the write lock due to another thread. The duplication
is removed in a later next patch that delegates the implementation to
hashtable.
Signed-off-by: default avatarIan Rogers <irogers@google.com>
Acked-by: default avatarNamhyung Kim <namhyung@kernel.org>
Cc: Yang Jihong <yangjihong1@huawei.com>
Cc: Oliver Upton <oliver.upton@linux.dev>
Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
Link: https://lore.kernel.org/r/20240301053646.1449657-5-irogers@google.com
parent 45ac4960
......@@ -328,7 +328,7 @@ static const char *lock_contention_get_name(struct lock_contention *con,
/* do not update idle comm which contains CPU number */
if (pid) {
struct thread *t = __machine__findnew_thread(machine, /*pid=*/-1, pid);
struct thread *t = machine__findnew_thread(machine, /*pid=*/-1, pid);
if (t == NULL)
return name;
......@@ -422,7 +422,7 @@ int lock_contention_read(struct lock_contention *con)
account_end_timestamp(con);
if (con->aggr_mode == LOCK_AGGR_TASK) {
struct thread *idle = __machine__findnew_thread(machine,
struct thread *idle = machine__findnew_thread(machine,
/*pid=*/0,
/*tid=*/0);
thread__set_comm(idle, "swapper", /*timestamp=*/0);
......
This diff is collapsed.
......@@ -31,13 +31,28 @@ struct vdso_info;
#define THREADS__TABLE_BITS 8
#define THREADS__TABLE_SIZE (1 << THREADS__TABLE_BITS)
struct threads {
struct threads_table_entry {
struct rb_root_cached entries;
struct rw_semaphore lock;
unsigned int nr;
struct thread *last_match;
};
struct threads {
struct threads_table_entry table[THREADS__TABLE_SIZE];
};
void threads__init(struct threads *threads);
void threads__exit(struct threads *threads);
size_t threads__nr(struct threads *threads);
struct thread *threads__find(struct threads *threads, pid_t tid);
struct thread *threads__findnew(struct threads *threads, pid_t pid, pid_t tid, bool *created);
void threads__remove_all_threads(struct threads *threads);
void threads__remove(struct threads *threads, struct thread *thread);
int threads__for_each_thread(struct threads *threads,
int (*fn)(struct thread *thread, void *data),
void *data);
struct machine {
struct rb_node rb_node;
pid_t pid;
......@@ -48,7 +63,7 @@ struct machine {
char *root_dir;
char *mmap_name;
char *kallsyms_filename;
struct threads threads[THREADS__TABLE_SIZE];
struct threads threads;
struct vdso_info *vdso_info;
struct perf_env *env;
struct dsos dsos;
......@@ -69,12 +84,6 @@ struct machine {
bool trampolines_mapped;
};
static inline struct threads *machine__threads(struct machine *machine, pid_t tid)
{
/* Cast it to handle tid == -1 */
return &machine->threads[(unsigned int)tid % THREADS__TABLE_SIZE];
}
/*
* The main kernel (vmlinux) map
*/
......@@ -220,7 +229,6 @@ bool machine__is(struct machine *machine, const char *arch);
bool machine__normalized_is(struct machine *machine, const char *arch);
int machine__nr_cpus_avail(struct machine *machine);
struct thread *__machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid);
struct thread *machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid);
struct dso *machine__findnew_dso_id(struct machine *machine, const char *filename, struct dso_id *id);
......
......@@ -26,7 +26,7 @@ int thread__init_maps(struct thread *thread, struct machine *machine)
if (pid == thread__tid(thread) || pid == -1) {
thread__set_maps(thread, maps__new(machine));
} else {
struct thread *leader = __machine__findnew_thread(machine, pid, pid);
struct thread *leader = machine__findnew_thread(machine, pid, pid);
if (leader) {
thread__set_maps(thread, maps__get(thread__maps(leader)));
......
......@@ -3,7 +3,6 @@
#define __PERF_THREAD_H
#include <linux/refcount.h>
#include <linux/rbtree.h>
#include <linux/list.h>
#include <stdio.h>
#include <unistd.h>
......@@ -29,11 +28,6 @@ struct lbr_stitch {
struct callchain_cursor_node *prev_lbr_cursor;
};
struct thread_rb_node {
struct rb_node rb_node;
struct thread *thread;
};
DECLARE_RC_STRUCT(thread) {
/** @maps: mmaps associated with this thread. */
struct maps *maps;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment