summary refs log tree commit diff stats
path: root/results/scraper/fex/1731
diff options
context:
space:
mode:
authorChristian Krinitsin <mail@krinitsin.com>2025-07-17 09:10:43 +0200
committerChristian Krinitsin <mail@krinitsin.com>2025-07-17 09:10:43 +0200
commitf2ec263023649e596c5076df32c2d328bc9393d2 (patch)
tree5dd86caab46e552bd2e62bf9c4fb1a7504a44db4 /results/scraper/fex/1731
parent63d2e9d409831aa8582787234cae4741847504b7 (diff)
downloadqemu-analysis-main.tar.gz
qemu-analysis-main.zip
add downloaded fex bug-reports HEAD main
Diffstat (limited to 'results/scraper/fex/1731')
-rw-r--r--results/scraper/fex/173168
1 files changed, 68 insertions, 0 deletions
diff --git a/results/scraper/fex/1731 b/results/scraper/fex/1731
new file mode 100644
index 000000000..4325c7818
--- /dev/null
+++ b/results/scraper/fex/1731
@@ -0,0 +1,68 @@
+Idea for partial TSO cost mitigation/pgo with MTE extensions
+Following up from yesterday's discussion,

+

+#### Overview

+Using `MTE` (https://www.kernel.org/doc/html/latest/arm64/memory-tagging-extension.html) which tracks a 4-bit tag per 16 bytes of memory we can mark every 16 bytes of memory as either being `local` to a cpu core, thus `non-tso` accesses are fine, or as `shared`, thus accesses need to be `tso`. MTE gives us 4 bits, so we can track up to 15 cpu cores plus 1 id used for `shared` memory.

+

+The `rseq` (https://www.efficios.com/blog/2019/02/08/linux-restartable-sequences/) kernel feature can be used to detect when a task is switched between cpu cores.

+

+We can then detect `non-tso` accesses to `shared` and `tso` accesses to `local` memory with a synchronous tag mismatch exception, and backpatch the offending instruction to use slower, tso instructions.

+

+The optimisation depends on `local`/`shared` memory access being a characteristic of the specific memory operation. While this is overall likely to be true, functions like memcpy will have to deal with both `shared` and `local` memory.

+

+There are several limitations to this approach, however it should still be useful for instrumentation and pgo.

+

+#### Limitations

+-  Ping-ponging between `tso` and `non-tso` access modes. I'm not sure there's a good workaround for that, as I don't think we can allow TSO ops to work on both `local` and `shared` memory using MTE

+- Thunks could have issues

+- Object code caching would be possible, but backpatching has to be done per vm group increasing the memory load

+- Linux doesn't support PROT_MTE with non ram file-backed mappings `PROT_MTE is only supported on MAP_ANONYMOUS and RAM-based file mappings (tmpfs, memfd).`

+- Can only support up to 15 host cpu cores

+- While tso ops need only to be done in `shared` memory accesses, not all `shared` memory accesses need to be tso. It is impossible to detect `shared` accesses that don't need to be `tso` using this approach.

+

+#### Variations

+- The actual memops could be interpreted in the segfault handler, either to guarantee forward progress and/or limit backpatching

+

+#### Details

+

+##### Setup

+- Compute `HostCoreId` as such that they are either [0,14] with 15 reserved for `shared` memory, or as [1, 15] with 0 reserved for `shared` memory.

+- Extend the guest cpu frame to have a "current cpu core mte id" field, `frame->HostCoreId`

+- Dedicate a caller saved register in the jit to shadow this value, `rHostCoreId`

+- Reload `rHostCoreId`  from `frame->HostCoreId` on every re-enter to the jit abi

+- Using rseq, keep `frame->HostCoreId` in sync with the current `HostCoreId`. An alternative is to read from the rseq core id field.

+- Using rseq, update `rHostCoreId` on cpu core migration if the code is in the jit abi

+

+Assuming 0 is used to indicate `shared` memory

+

+##### `local` memops

+```

+[0] rAddr = x86AddressGen(...)

+[1] bfi rAddr[59:56], rHostCoreId

+[2] non-tso memop rAddr, data, ....

+```

+

+##### `shared` memops

+```

+[0] rAddr = x86AddressGen(...)

+[1] bfc rAddr[59:56]

+[2] tso memop rAddr, data, ....

+```

+

+##### `local` -> `shared` migration & backpatching

+- on `SIGSEGV` with `.si_code = SEGV_MTESERR` where the offending memop is a `non-tso` memop

+- take some lock

+- change `.si_addr` TAG to 0

+- backpatch memop[1] to bfc

+- backpatch memop[2] to `tso` memop 

+- release lock

+- re-execute the sequence

+

+##### `shared` -> `local` migration & backpatching

+- on `SIGSEGV` with `.si_code = SEGV_MTESERR` where the offending memop is a `tso` memop

+- take some lock

+- change `.si_addr` TAG to `CoreId`

+- backpatch memop[1] to bfi

+- backpatch memop[2] to `non-tso` memop

+- release lock

+- re-execute the sequence