From: Jiri Olsa <olsajiri@gmail.com>
To: Ihor Solodrai <ihor.solodrai@pm.me>
Cc: dwarves@vger.kernel.org, acme@kernel.org,
alan.maguire@oracle.com, eddyz87@gmail.com, andrii@kernel.org,
mykolal@fb.com, bpf@vger.kernel.org
Subject: Re: [PATCH dwarves v3 7/8] dwarf_loader: multithreading with a job/worker model
Date: Wed, 1 Jan 2025 17:56:16 +0100 [thread overview]
Message-ID: <Z3VzsA8nv4kQj1bH@krava> (raw)
In-Reply-To: <20241221012245.243845-8-ihor.solodrai@pm.me>
On Sat, Dec 21, 2024 at 01:23:38AM +0000, Ihor Solodrai wrote:
SNIP
> diff --git a/btf_encoder.c b/btf_encoder.c
> index 90f1b9a..7e03ba4 100644
> --- a/btf_encoder.c
> +++ b/btf_encoder.c
> @@ -1326,7 +1326,7 @@ static void btf_encoder__delete_saved_funcs(struct btf_encoder *encoder)
> }
> }
>
> -int btf_encoder__add_saved_funcs(bool skip_encoding_inconsistent_proto)
> +static int btf_encoder__add_saved_funcs(bool skip_encoding_inconsistent_proto)
> {
> struct btf_encoder_func_state **saved_fns, *s;
> struct btf_encoder *e = NULL;
> @@ -2134,7 +2134,6 @@ int btf_encoder__encode(struct btf_encoder *encoder, struct conf_load *conf)
> int err;
> size_t shndx;
>
> - /* for single-threaded case, saved funcs are added here */
> btf_encoder__add_saved_funcs(conf->skip_encoding_btf_inconsistent_proto);
should we check the return value in here? now it's the only caller
SNIP
> -struct dwarf_thread {
> - struct dwarf_cus *dcus;
> - void *data;
> +/* Multithreading is implemented using a job/worker model.
> + * cus_processing_queue represents a collection of jobs to be
> + * completed by workers.
> + * dwarf_loader__worker_thread is the worker loop, taking jobs from
> + * the queue, executing them and re-enqueuing new jobs as necessary.
> + * Implementation of this queue ensures two constraints:
> + * * JOB_STEAL jobs for a CU are executed in the order of cu->id, as
> + * a consequence JOB_STEAL jobs always run one at a time.
> + * * Initial number of JOB_DECODE jobs in the queue is effectively a
> + * limit on how many decoded CUs can be held in memory.
> + * See dwarf_loader__decoded_cus_limit()
> + */
> +static struct {
> + pthread_mutex_t mutex;
> + pthread_cond_t job_added;
> + /* next_cu_id determines the next CU ready to be stealed
> + * This enforces the order of CU stealing.
> + */
> + uint32_t next_cu_id;
> + struct list_head jobs;
> +} cus_processing_queue;
> +
> +enum job_type {
> + JOB_NONE = 0,
nit, no need for JOB_NONE?
SNIP
> +static struct cu_processing_job *cus_queue__try_dequeue(void)
> +{
> + struct cu_processing_job *job, *dequeued_job = NULL;
> + struct list_head *pos, *tmp;
> +
> + list_for_each_safe(pos, tmp, &cus_processing_queue.jobs) {
> + job = list_entry(pos, struct cu_processing_job, node);
> + if (job->type == JOB_STEAL && job->cu->id == cus_processing_queue.next_cu_id) {
> + dequeued_job = job;
> + break;
> + }
> + if (job->type == JOB_DECODE) {
> + /* all JOB_STEALs are added to the head, so no viable JOB_STEAL available */
> + dequeued_job = job;
> + break;
> + }
> + }
> + /* No jobs or only steals out of order */
> + if (!dequeued_job)
> + return NULL;
> +
> + list_del(&dequeued_job->node);
> + return job;
IIUC job == dequeued_job at this point, but I think we should return
dequeued_job to be clear
SNIP
> -static void *dwarf_cus__process_cu_thread(void *arg)
> +static struct cu *dwarf_loader__decode_next_cu(struct dwarf_cus *dcus)
> {
> - struct dwarf_thread *dthr = arg;
> - struct dwarf_cus *dcus = dthr->dcus;
> uint8_t pointer_size, offset_size;
> + struct dwarf_cu *dcu = NULL;
> Dwarf_Die die_mem, *cu_die;
> - struct dwarf_cu *dcu;
> + int err;
>
> - while (dwarf_cus__nextcu(dcus, &dcu, &die_mem, &cu_die, &pointer_size, &offset_size) == 0) {
> - if (cu_die == NULL)
> + err = dwarf_cus__nextcu(dcus, &dcu, &die_mem, &cu_die, &pointer_size, &offset_size);
> +
> + if (err < 0)
> + goto out_error;
> + else if (err == 1) /* no more CUs */
> + return NULL;
> +
> + err = die__process_and_recode(cu_die, dcu->cu, dcus->conf);
> + if (err)
> + goto out_error;
> + if (cu_die == NULL)
> + return NULL;
should this check be placed before calling die__process_and_recode ?
SNIP
> -static int dwarf_cus__process_cus(struct dwarf_cus *dcus)
> -{
> - if (dcus->conf->nr_jobs > 1)
> - return dwarf_cus__threaded_process_cus(dcus);
> -
> - return __dwarf_cus__process_cus(dcus);
> -}
> -
> static int cus__merge_and_process_cu(struct cus *cus, struct conf_load *conf,
> Dwfl_Module *mod, Dwarf *dw, Elf *elf,
> const char *filename,
> @@ -3733,7 +3859,8 @@ static int cus__merge_and_process_cu(struct cus *cus, struct conf_load *conf,
> if (cu__resolve_func_ret_types_optimized(cu) != LSK__KEEPIT)
> goto out_abort;
>
> - if (cus__finalize(cus, cu, conf, NULL) == LSK__STOP_LOADING)
> + cu__finalize(cu, cus, conf);
> + if (cus__steal_now(cus, cu, conf) == LSK__STOP_LOADING)
> goto out_abort;
>
> return 0;
> @@ -3765,7 +3892,8 @@ static int cus__load_module(struct cus *cus, struct conf_load *conf,
> }
>
> if (type_cu != NULL) {
> - type_lsk = cu__finalize(type_cu, cus, conf, NULL);
> + cu__finalize(type_cu, cus, conf);
> + type_lsk = cus__steal_now(cus, type_cu, conf);
> if (type_lsk == LSK__DELETE) {
> cus__remove(cus, type_cu);
> }
> @@ -3787,6 +3915,7 @@ static int cus__load_module(struct cus *cus, struct conf_load *conf,
> .type_dcu = type_cu ? &type_dcu : NULL,
> .build_id = build_id,
> .build_id_len = build_id_len,
> + .nr_cus_created = 0,
should go to the previous patch? if needed at all..
thanks,
jirka
> };
> res = dwarf_cus__process_cus(&dcus);
> }
> diff --git a/dwarves.c b/dwarves.c
> index ae512b9..7c3e878 100644
> --- a/dwarves.c
> +++ b/dwarves.c
> @@ -530,48 +530,6 @@ void cus__unlock(struct cus *cus)
> pthread_mutex_unlock(&cus->mutex);
> }
>
SNIP
next prev parent reply other threads:[~2025-01-01 16:56 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-21 1:22 [PATCH dwarves v3 0/8] pahole: faster reproducible BTF encoding Ihor Solodrai
2024-12-21 1:22 ` [PATCH dwarves v3 1/8] btf_encoder: simplify function encoding Ihor Solodrai
2024-12-21 1:23 ` [PATCH dwarves v3 2/8] btf_encoder: separate elf function, saved function representations Ihor Solodrai
2025-01-01 16:56 ` Jiri Olsa
2025-01-02 19:54 ` Ihor Solodrai
2024-12-21 1:23 ` [PATCH dwarves v3 3/8] btf_encoder: introduce elf_functions struct type Ihor Solodrai
2025-01-01 16:56 ` Jiri Olsa
2025-01-02 20:06 ` Ihor Solodrai
2024-12-21 1:23 ` [PATCH dwarves v3 4/8] btf_encoder: introduce elf_functions_list Ihor Solodrai
2024-12-21 1:23 ` [PATCH dwarves v3 5/8] btf_encoder: remove skip_encoding_inconsistent_proto Ihor Solodrai
2024-12-21 1:23 ` [PATCH dwarves v3 6/8] dwarf_loader: introduce cu->id Ihor Solodrai
2024-12-21 1:23 ` [PATCH dwarves v3 7/8] dwarf_loader: multithreading with a job/worker model Ihor Solodrai
2024-12-30 16:07 ` Arnaldo Carvalho de Melo
2024-12-30 16:11 ` Arnaldo Carvalho de Melo
2024-12-30 18:37 ` Arnaldo Carvalho de Melo
2025-01-02 23:09 ` Ihor Solodrai
2025-01-01 16:56 ` Jiri Olsa [this message]
2025-01-03 0:24 ` Ihor Solodrai
2024-12-21 1:23 ` [PATCH dwarves v3 8/8] btf_encoder: clean up global encoders list Ihor Solodrai
2025-01-01 16:56 ` Jiri Olsa
2025-01-03 0:43 ` Ihor Solodrai
2025-01-03 9:27 ` Jiri Olsa
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=Z3VzsA8nv4kQj1bH@krava \
--to=olsajiri@gmail.com \
--cc=acme@kernel.org \
--cc=alan.maguire@oracle.com \
--cc=andrii@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=dwarves@vger.kernel.org \
--cc=eddyz87@gmail.com \
--cc=ihor.solodrai@pm.me \
--cc=mykolal@fb.com \
/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