From: Pierrick Bouvier <pierrick.bouvier@linaro.org>
To: "Alex Bennée" <alex.bennee@linaro.org>
Cc: qemu-devel@nongnu.org, Mahmoud Mandour <ma.mandourr@gmail.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Richard Henderson <richard.henderson@linaro.org>,
Alexandre Iooss <erdnaxe@crans.org>
Subject: Re: [PATCH v2 01/14] plugins: implement inline operation relative to cpu_index
Date: Mon, 29 Jan 2024 14:10:57 +0400 [thread overview]
Message-ID: <12587b70-c0b8-40af-aa8d-168391d84568@linaro.org> (raw)
In-Reply-To: <87ttn0s3gq.fsf@draig.linaro.org>
On 1/26/24 16:07, Alex Bennée wrote:
> Pierrick Bouvier <pierrick.bouvier@linaro.org> writes:
>
>> Instead of working on a fixed memory location, allow to address it based
>> on cpu_index, an element size and a given offset.
>> Result address: ptr + offset + cpu_index * element_size.
>>
>> With this, we can target a member in a struct array from a base pointer.
>>
>> Current semantic is not modified, thus inline operation still targets
>> always the same memory location.
>>
>> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
>> ---
>> accel/tcg/plugin-gen.c | 67 +++++++++++++++++++++++++++++++++++-------
>> include/qemu/plugin.h | 3 ++
>> plugins/api.c | 7 +++--
>> plugins/core.c | 18 +++++++++---
>> plugins/plugin.h | 6 ++--
>> 5 files changed, 81 insertions(+), 20 deletions(-)
>>
>> diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
>> index b37ce7683e6..1a2375d7779 100644
>> --- a/accel/tcg/plugin-gen.c
>> +++ b/accel/tcg/plugin-gen.c
>> @@ -132,16 +132,28 @@ static void gen_empty_udata_cb_no_rwg(void)
>> */
>> static void gen_empty_inline_cb(void)
>> {
>> + TCGv_i32 cpu_index = tcg_temp_ebb_new_i32();
>> + TCGv_ptr cpu_index_as_ptr = tcg_temp_ebb_new_ptr();
>> TCGv_i64 val = tcg_temp_ebb_new_i64();
>> TCGv_ptr ptr = tcg_temp_ebb_new_ptr();
>>
>> + tcg_gen_ld_i32(cpu_index, tcg_env,
>> + -offsetof(ArchCPU, env) + offsetof(CPUState, cpu_index));
>> + /* pass an immediate != 0 so that it doesn't get optimized away */
>> + tcg_gen_muli_i32(cpu_index, cpu_index, 0xdeadbeef);
>> + tcg_gen_ext_i32_ptr(cpu_index_as_ptr, cpu_index);
>> +
>> tcg_gen_movi_ptr(ptr, 0);
>> + tcg_gen_add_ptr(ptr, ptr, cpu_index_as_ptr);
>> tcg_gen_ld_i64(val, ptr, 0);
>> /* pass an immediate != 0 so that it doesn't get optimized away */
>> tcg_gen_addi_i64(val, val, 0xdeadface);
>> +
>> tcg_gen_st_i64(val, ptr, 0);
>> tcg_temp_free_ptr(ptr);
>> tcg_temp_free_i64(val);
>> + tcg_temp_free_ptr(cpu_index_as_ptr);
>> + tcg_temp_free_i32(cpu_index);
>> }
>>
> <snip>
>> if (UINTPTR_MAX == UINT32_MAX) {
>> @@ -395,18 +439,19 @@ static TCGOp *append_inline_cb(const struct qemu_plugin_dyn_cb *cb,
>> TCGOp *begin_op, TCGOp *op,
>> int *unused)
>> {
>> - /* const_ptr */
>> - op = copy_const_ptr(&begin_op, op, cb->userp);
>> -
>> - /* ld_i64 */
>> + char *ptr = cb->userp;
>> + if (!cb->inline_direct_ptr) {
>> + /* dereference userp once to get access to memory location */
>> + ptr = *(char **)cb->userp;
>> + }
>
> I'm confused here, probably because inline_direct_ptr gets removed later
> on?
>
Yes, we temporarily need two code paths for this patch series. Else,
plugins should be updated at the same time than we make all changes to
not break anything.
>> + op = copy_ld_i32(&begin_op, op);
>> + op = copy_mul_i32(&begin_op, op, cb->inline_element_size);
>> + op = copy_ext_i32_ptr(&begin_op, op);
>> + op = copy_const_ptr(&begin_op, op, ptr + cb->inline_offset);
>> + op = copy_add_ptr(&begin_op, op);
>> op = copy_ld_i64(&begin_op, op);
>> -
>> - /* add_i64 */
>> op = copy_add_i64(&begin_op, op, cb->inline_insn.imm);
>> -
>> - /* st_i64 */
>> op = copy_st_i64(&begin_op, op);
>> -
>> return op;
>> }
>>
>> diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
>> index b0c5ac68293..9346249145d 100644
>> --- a/include/qemu/plugin.h
>> +++ b/include/qemu/plugin.h
>> @@ -86,6 +86,9 @@ enum plugin_dyn_cb_subtype {
>> struct qemu_plugin_dyn_cb {
>> union qemu_plugin_cb_sig f;
>> void *userp;
>> + size_t inline_offset;
>> + size_t inline_element_size;
>> + bool inline_direct_ptr;
>
> Ahh here it is.
>
> (I seem to recall there is a setting for git to order headers first that
> helps with this).
>
Indeed, found it (thanks):
https://gitlab.com/qemu-project/qemu/-/blob/master/scripts/git.orderfile
> We could do with some documentation here. I can guess the offset and
> element size values but what inline_direct_ptr means is not clear.
>
It represents if the userp is a pointer to data, or a pointer to pointer
to data. Any suggestion for name having this detail?
I have another patch that replace all this by a qemu_plugin_u64_t (from
scoreboard), that I'll integrate in a v3, which is much clearer. But
there will still be one commit needed with this.
>> enum plugin_dyn_cb_subtype type;
>> /* @rw applies to mem callbacks only (both regular and inline) */
>> enum qemu_plugin_mem_rw rw;
>> diff --git a/plugins/api.c b/plugins/api.c
>> index 8d5cca53295..e777eb4e9fc 100644
>> --- a/plugins/api.c
>> +++ b/plugins/api.c
>> @@ -106,7 +106,8 @@ void qemu_plugin_register_vcpu_tb_exec_inline(struct qemu_plugin_tb *tb,
>> void *ptr, uint64_t imm)
>> {
>> if (!tb->mem_only) {
>> - plugin_register_inline_op(&tb->cbs[PLUGIN_CB_INLINE], 0, op, ptr, imm);
>> + plugin_register_inline_op(&tb->cbs[PLUGIN_CB_INLINE],
>> + 0, op, ptr, 0, sizeof(uint64_t), true, imm);
>> }
>> }
>>
>> @@ -131,7 +132,7 @@ void qemu_plugin_register_vcpu_insn_exec_inline(struct qemu_plugin_insn *insn,
>> {
>> if (!insn->mem_only) {
>> plugin_register_inline_op(&insn->cbs[PLUGIN_CB_INSN][PLUGIN_CB_INLINE],
>> - 0, op, ptr, imm);
>> + 0, op, ptr, 0, sizeof(uint64_t), true, imm);
>> }
>> }
>>
>> @@ -156,7 +157,7 @@ void qemu_plugin_register_vcpu_mem_inline(struct qemu_plugin_insn *insn,
>> uint64_t imm)
>> {
>> plugin_register_inline_op(&insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_INLINE],
>> - rw, op, ptr, imm);
>> + rw, op, ptr, 0, sizeof(uint64_t), true, imm);
>> }
>>
>> void qemu_plugin_register_vcpu_tb_trans_cb(qemu_plugin_id_t id,
>> diff --git a/plugins/core.c b/plugins/core.c
>> index 49588285dd0..e07b9cdf229 100644
>> --- a/plugins/core.c
>> +++ b/plugins/core.c
>> @@ -280,13 +280,18 @@ static struct qemu_plugin_dyn_cb *plugin_get_dyn_cb(GArray **arr)
>>
>> void plugin_register_inline_op(GArray **arr,
>> enum qemu_plugin_mem_rw rw,
>> - enum qemu_plugin_op op, void *ptr,
>> + enum qemu_plugin_op op,
>> + void *ptr, size_t offset, size_t element_size,
>> + bool direct_ptr,
>> uint64_t imm)
>> {
>> struct qemu_plugin_dyn_cb *dyn_cb;
>>
>> dyn_cb = plugin_get_dyn_cb(arr);
>> dyn_cb->userp = ptr;
>> + dyn_cb->inline_element_size = element_size;
>> + dyn_cb->inline_offset = offset;
>> + dyn_cb->inline_direct_ptr = direct_ptr;
>> dyn_cb->type = PLUGIN_CB_INLINE;
>> dyn_cb->rw = rw;
>> dyn_cb->inline_insn.op = op;
>> @@ -431,9 +436,14 @@ void qemu_plugin_flush_cb(void)
>> plugin_cb__simple(QEMU_PLUGIN_EV_FLUSH);
>> }
>>
>> -void exec_inline_op(struct qemu_plugin_dyn_cb *cb)
>> +void exec_inline_op(struct qemu_plugin_dyn_cb *cb, int cpu_index)
>> {
>> - uint64_t *val = cb->userp;
>> + char *ptr = cb->userp;
>> + if (!cb->inline_direct_ptr) {
>> + ptr = *(char **) cb->userp;
>> + }
>> + ptr += cb->inline_offset;
>> + uint64_t *val = (uint64_t *)(ptr + cpu_index * cb->inline_element_size);
>>
>> switch (cb->inline_insn.op) {
>> case QEMU_PLUGIN_INLINE_ADD_U64:
>> @@ -466,7 +476,7 @@ void qemu_plugin_vcpu_mem_cb(CPUState *cpu, uint64_t vaddr,
>> vaddr, cb->userp);
>> break;
>> case PLUGIN_CB_INLINE:
>> - exec_inline_op(cb);
>> + exec_inline_op(cb, cpu->cpu_index);
>> break;
>> default:
>> g_assert_not_reached();
>> diff --git a/plugins/plugin.h b/plugins/plugin.h
>> index 5eb2fdbc85e..2c278379b70 100644
>> --- a/plugins/plugin.h
>> +++ b/plugins/plugin.h
>> @@ -66,7 +66,9 @@ struct qemu_plugin_ctx *plugin_id_to_ctx_locked(qemu_plugin_id_t id);
>>
>> void plugin_register_inline_op(GArray **arr,
>> enum qemu_plugin_mem_rw rw,
>> - enum qemu_plugin_op op, void *ptr,
>> + enum qemu_plugin_op op,
>> + void *ptr, size_t offset, size_t element_size,
>> + bool direct_ptr,
>> uint64_t imm);
>>
>> void plugin_reset_uninstall(qemu_plugin_id_t id,
>> @@ -95,6 +97,6 @@ void plugin_register_vcpu_mem_cb(GArray **arr,
>> enum qemu_plugin_mem_rw rw,
>> void *udata);
>>
>> -void exec_inline_op(struct qemu_plugin_dyn_cb *cb);
>> +void exec_inline_op(struct qemu_plugin_dyn_cb *cb, int cpu_index);
>>
>> #endif /* PLUGIN_H */
>
next prev parent reply other threads:[~2024-01-29 10:11 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-18 3:23 [PATCH v2 00/14] TCG Plugin inline operation enhancement Pierrick Bouvier
2024-01-18 3:23 ` [PATCH v2 01/14] plugins: implement inline operation relative to cpu_index Pierrick Bouvier
2024-01-26 12:07 ` Alex Bennée
2024-01-29 10:10 ` Pierrick Bouvier [this message]
2024-01-18 3:23 ` [PATCH v2 02/14] plugins: scoreboard API Pierrick Bouvier
2024-01-26 15:14 ` Alex Bennée
2024-01-30 7:37 ` Pierrick Bouvier
2024-01-30 10:23 ` Alex Bennée
2024-01-30 11:10 ` Pierrick Bouvier
2024-01-31 7:44 ` Pierrick Bouvier
2024-02-01 5:28 ` Pierrick Bouvier
2024-01-18 3:23 ` [PATCH v2 03/14] docs/devel: plugins can trigger a tb flush Pierrick Bouvier
2024-01-18 3:23 ` [PATCH v2 04/14] plugins: add inline operation per vcpu Pierrick Bouvier
2024-01-26 15:17 ` Alex Bennée
2024-01-18 3:23 ` [PATCH v2 05/14] tests/plugin: add test plugin for inline operations Pierrick Bouvier
2024-01-26 16:05 ` Alex Bennée
2024-01-30 7:49 ` Pierrick Bouvier
2024-01-30 14:52 ` Alex Bennée
2024-01-30 16:40 ` Pierrick Bouvier
2024-01-18 3:23 ` [PATCH v2 06/14] tests/plugin/mem: migrate to new per_vcpu API Pierrick Bouvier
2024-01-18 3:23 ` [PATCH v2 07/14] tests/plugin/insn: " Pierrick Bouvier
2024-01-18 3:23 ` [PATCH v2 08/14] tests/plugin/bb: " Pierrick Bouvier
2024-01-18 3:23 ` [PATCH v2 09/14] contrib/plugins/hotblocks: " Pierrick Bouvier
2024-01-18 3:23 ` [PATCH v2 10/14] contrib/plugins/howvec: " Pierrick Bouvier
2024-01-18 3:23 ` [PATCH v2 11/14] plugins: remove non per_vcpu inline operation from API Pierrick Bouvier
2024-01-26 16:26 ` Alex Bennée
2024-01-30 7:53 ` Pierrick Bouvier
2024-01-18 3:23 ` [PATCH v2 12/14] plugins: register inline op with a qemu_plugin_u64_t Pierrick Bouvier
2024-01-18 3:23 ` [PATCH v2 13/14] MAINTAINERS: Add myself as reviewer for TCG Plugins Pierrick Bouvier
2024-01-26 16:27 ` Alex Bennée
2024-01-18 3:23 ` [PATCH v2 14/14] contrib/plugins/execlog: fix new warnings Pierrick Bouvier
2024-01-26 16:31 ` Alex Bennée
2024-01-30 7:51 ` Pierrick Bouvier
2024-01-26 9:21 ` [PATCH v2 00/14] TCG Plugin inline operation enhancement Pierrick Bouvier
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=12587b70-c0b8-40af-aa8d-168391d84568@linaro.org \
--to=pierrick.bouvier@linaro.org \
--cc=alex.bennee@linaro.org \
--cc=erdnaxe@crans.org \
--cc=ma.mandourr@gmail.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.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;
as well as URLs for NNTP newsgroup(s).