From: Paolo Bonzini <pbonzini@redhat.com>
To: "Alex Bennée" <alex.bennee@linaro.org>,
"MTTCG Devel" <mttcg@greensocs.com>,
"QEMU Developers" <qemu-devel@nongnu.org>,
"Richard Henderson" <rth@twiddle.net>,
"Sergey Fedorov" <serge.fdrv@gmail.com>,
"Emilio G. Cota" <cota@braap.org>,
"Frederic Konrad" <fred.konrad@greensocs.com>,
a.rigo@virtualopensystems.com
Subject: Re: [Qemu-devel] Making cputlb.c operations safe for MTTCG
Date: Mon, 1 Aug 2016 16:54:22 +0200 [thread overview]
Message-ID: <f9d2b151-3a79-547b-b8d2-db6a4650936b@redhat.com> (raw)
In-Reply-To: <87wpk8k3dn.fsf@linaro.org>
On 26/07/2016 14:09, Alex Bennée wrote:
>
> As the eventual operation is the setting of a flag I'm wondering if we
> can simply use atomic primitives to ensure we don't corrupt the lookup
> address when setting the TLB_NOTDIRTY flag?
In theory tlb_reset_dirty and tlb_set_dirty1 can use atomic_* on
tlb_entry->addr_write, but careful because:
- you need to order reads and writes to tlb_entry->addr_write and
tlb_entry->addend properly
- addr_write cannot be written atomically for 32-bit host/64-bit target.
Probably you can use something like
union {
target_ulong addr_write;
#if TARGET_LONG_BITS == 32
struct { uint32_t lo_and_lfags; } addr_write_w;
#elif defined HOST_WORDS_BIGENDIAN
struct { uint32_t hi, lo_and_flags; } addr_write_w;
#else
struct { uint32_t lo_and_flags, hi; } addr_write_w;
#endif
};
IIRC "foreign" accesses only set TLB_NOTDIRTY, so they can use a cmpxchg
on lo_and_flags (worst case you end up with an unnecessary call to
notdirty_mem_write).
- When removing TLB_NOTDIRTY from a TLB entry
(notdirty_mem_write/tlb_unprotect_code), as well as filling in a TLB
entry without TLB_NOTDIRTY (tlb_set_page_with_attrs) you need to protect
from a concurrent tb_alloc_page and hence take the tb_lock.
In particular:
- in notdirty_mem_write, care must be put in the ordering of
tb_invalidate_phys_page_fast (which itself calls tlb_unprotect_code and
takes the tb_lock in tb_invalidate_phys_page_range) and tlb_set_dirty.
At least it seems to me that the call to tb_invalidate_phys_page_fast
should be after the write, but that's not all. Perhaps merge this part
of notdirty_mem_write:
/* Set both VGA and migration bits for simplicity and to remove
* the notdirty callback faster.
*/
cpu_physical_memory_set_dirty_range(ram_addr, size,
DIRTY_CLIENTS_NOCODE);
/* we remove the notdirty callback only if the code has been
flushed */
if (!cpu_physical_memory_is_clean(ram_addr)) {
tlb_set_dirty(current_cpu, current_cpu->mem_io_vaddr);
}
into tlb_unprotect_code?!? Or perhaps do tlb_set_dirty _first_, and
then add back the callback if cpu_physical_memory_is_clean(ram_addr) is
true. I haven't put much thought into it.
- tlb_set_page_with_attrs is also hard-ish to get right, but perhaps the
same idea of adding the callback last would work:
/* First set addr_write so that concurrent tlb_reset_dirty_range
* finds a match.
*/
te->addr_write = address;
if (memory_region_is_ram(section->mr)) {
if (cpu_physical_memory_is_clean(
memory_region_get_ram_addr(section->mr) + xlat)) {
te->addr_write = address | TLB_NOTDIRTY;
}
}
Paolo
> Of course the TLB structure itself covers a number of values but AFAICT
> erroneously setting TLB_NOTDIRTY on a entry that gets updated to a new
> address wouldn't cause a problem except triggering an additional
> slow-path write. If we are careful about the filling of the TLB entries
> can we be sure we are always safe?
next prev parent reply other threads:[~2016-08-01 14:54 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-07-26 12:09 [Qemu-devel] Making cputlb.c operations safe for MTTCG Alex Bennée
2016-07-26 14:03 ` [Qemu-devel] [PATCH] cputlb: make tlb_reset_dirty " Alex Bennée
2016-08-01 14:54 ` Paolo Bonzini [this message]
2016-08-02 6:37 ` [Qemu-devel] Making cputlb.c operations " Alex Bennée
2016-08-02 10:26 ` Paolo Bonzini
2016-08-03 17:25 ` Richard Henderson
2016-08-03 20:56 ` Paolo Bonzini
2016-09-27 16:16 ` Paolo Bonzini
2016-09-27 22:15 ` Alex Bennée
2016-09-27 22:29 ` Emilio G. Cota
2016-09-27 23:04 ` Alex Bennée
2016-09-27 23:05 ` Richard Henderson
2016-09-27 23:32 ` Alex Bennée
2016-09-28 0:34 ` Richard Henderson
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=f9d2b151-3a79-547b-b8d2-db6a4650936b@redhat.com \
--to=pbonzini@redhat.com \
--cc=a.rigo@virtualopensystems.com \
--cc=alex.bennee@linaro.org \
--cc=cota@braap.org \
--cc=fred.konrad@greensocs.com \
--cc=mttcg@greensocs.com \
--cc=qemu-devel@nongnu.org \
--cc=rth@twiddle.net \
--cc=serge.fdrv@gmail.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;
as well as URLs for NNTP newsgroup(s).