dwarf_loader: Prepare and pass per-thread data to worker threads

Add interfaces to allow users of dwarf_loader to prepare and pass
per-thread data to steal-functions running on worker threads.

Signed-off-by: Kui-Feng Lee <kuifeng@fb.com>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: bpf@vger.kernel.org
Cc: dwarves@vger.kernel.org
Link: https://lore.kernel.org/r/20220126192039.2840752-3-kuifeng@fb.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Kui-Feng Lee 2022-01-26 11:20:37 -08:00 committed by Arnaldo Carvalho de Melo
parent 724c8fddd7
commit 96d2c5c323
2 changed files with 48 additions and 13 deletions

View File

@ -2682,18 +2682,18 @@ static int class_member__cache_byte_size(struct tag *tag, struct cu *cu,
return 0;
}
static int cu__finalize(struct cu *cu, struct conf_load *conf)
static int cu__finalize(struct cu *cu, struct conf_load *conf, void *thr_data)
{
cu__for_all_tags(cu, class_member__cache_byte_size, conf);
if (conf && conf->steal) {
return conf->steal(cu, conf, NULL);
return conf->steal(cu, conf, thr_data);
}
return LSK__KEEPIT;
}
static int cus__finalize(struct cus *cus, struct cu *cu, struct conf_load *conf)
static int cus__finalize(struct cus *cus, struct cu *cu, struct conf_load *conf, void *thr_data)
{
int lsk = cu__finalize(cu, conf);
int lsk = cu__finalize(cu, conf, thr_data);
switch (lsk) {
case LSK__DELETE:
cu__delete(cu);
@ -2862,7 +2862,13 @@ struct dwarf_cus {
struct dwarf_cu *type_dcu;
};
static int dwarf_cus__create_and_process_cu(struct dwarf_cus *dcus, Dwarf_Die *cu_die, uint8_t pointer_size)
struct dwarf_thread {
struct dwarf_cus *dcus;
void *data;
};
static int dwarf_cus__create_and_process_cu(struct dwarf_cus *dcus, Dwarf_Die *cu_die,
uint8_t pointer_size, void *thr_data)
{
/*
* DW_AT_name in DW_TAG_compile_unit can be NULL, first seen in:
@ -2884,7 +2890,7 @@ static int dwarf_cus__create_and_process_cu(struct dwarf_cus *dcus, Dwarf_Die *c
cu->dfops = &dwarf__ops;
if (die__process_and_recode(cu_die, cu, dcus->conf) != 0 ||
cus__finalize(dcus->cus, cu, dcus->conf) == LSK__STOP_LOADING)
cus__finalize(dcus->cus, cu, dcus->conf, thr_data) == LSK__STOP_LOADING)
return DWARF_CB_ABORT;
return DWARF_CB_OK;
@ -2918,7 +2924,8 @@ out_unlock:
static void *dwarf_cus__process_cu_thread(void *arg)
{
struct dwarf_cus *dcus = arg;
struct dwarf_thread *dthr = arg;
struct dwarf_cus *dcus = dthr->dcus;
uint8_t pointer_size, offset_size;
Dwarf_Die die_mem, *cu_die;
@ -2926,11 +2933,13 @@ static void *dwarf_cus__process_cu_thread(void *arg)
if (cu_die == NULL)
break;
if (dwarf_cus__create_and_process_cu(dcus, cu_die, pointer_size) == DWARF_CB_ABORT)
if (dwarf_cus__create_and_process_cu(dcus, cu_die,
pointer_size, dthr->data) == DWARF_CB_ABORT)
goto out_abort;
}
if (dcus->conf->thread_exit && dcus->conf->thread_exit(dcus->conf, NULL) != 0)
if (dcus->conf->thread_exit &&
dcus->conf->thread_exit(dcus->conf, dthr->data) != 0)
goto out_abort;
return (void *)DWARF_CB_OK;
@ -2941,10 +2950,26 @@ out_abort:
static int dwarf_cus__threaded_process_cus(struct dwarf_cus *dcus)
{
pthread_t threads[dcus->conf->nr_jobs];
struct dwarf_thread dthr[dcus->conf->nr_jobs];
void *thread_data[dcus->conf->nr_jobs];
int res;
int i;
if (dcus->conf->threads_prepare) {
res = dcus->conf->threads_prepare(dcus->conf, dcus->conf->nr_jobs, thread_data);
if (res != 0)
return res;
} else {
memset(thread_data, 0, sizeof(void *) * dcus->conf->nr_jobs);
}
for (i = 0; i < dcus->conf->nr_jobs; ++i) {
dcus->error = pthread_create(&threads[i], NULL, dwarf_cus__process_cu_thread, dcus);
dthr[i].dcus = dcus;
dthr[i].data = thread_data[i];
dcus->error = pthread_create(&threads[i], NULL,
dwarf_cus__process_cu_thread,
&dthr[i]);
if (dcus->error)
goto out_join;
}
@ -2960,6 +2985,13 @@ out_join:
dcus->error = (long)res;
}
if (dcus->conf->threads_collect) {
res = dcus->conf->threads_collect(dcus->conf, dcus->conf->nr_jobs,
thread_data, dcus->error);
if (dcus->error == 0)
dcus->error = res;
}
return dcus->error;
}
@ -2976,7 +3008,8 @@ static int __dwarf_cus__process_cus(struct dwarf_cus *dcus)
if (cu_die == NULL)
break;
if (dwarf_cus__create_and_process_cu(dcus, cu_die, pointer_size) == DWARF_CB_ABORT)
if (dwarf_cus__create_and_process_cu(dcus, cu_die,
pointer_size, NULL) == DWARF_CB_ABORT)
return DWARF_CB_ABORT;
dcus->off = noff;
@ -3070,7 +3103,7 @@ static int cus__merge_and_process_cu(struct cus *cus, struct conf_load *conf,
if (cu__resolve_func_ret_types(cu) != LSK__KEEPIT)
goto out_abort;
if (cus__finalize(cus, cu, conf) == LSK__STOP_LOADING)
if (cus__finalize(cus, cu, conf, NULL) == LSK__STOP_LOADING)
goto out_abort;
return 0;
@ -3102,7 +3135,7 @@ static int cus__load_module(struct cus *cus, struct conf_load *conf,
}
if (type_cu != NULL) {
type_lsk = cu__finalize(type_cu, conf);
type_lsk = cu__finalize(type_cu, conf, NULL);
if (type_lsk == LSK__KEEPIT) {
cus__add(cus, type_cu);
}

View File

@ -71,6 +71,8 @@ struct conf_load {
const char *kabi_prefix;
struct btf *base_btf;
struct conf_fprintf *conf_fprintf;
int (*threads_prepare)(struct conf_load *conf, int nr_threads, void **thr_data);
int (*threads_collect)(struct conf_load *conf, int nr_threads, void **thr_data, int error);
};
/** struct conf_fprintf - hints to the __fprintf routines