On 18/03/2016 17:18, Alex Bennée wrote:
> +
> + /* Protected by tb_lock. */
Only writes are protected by tb_lock. Read happen outside the lock.
Reads are not quite thread safe yet, because of tb_flush. In order to
fix that, there's either the async_safe_run() mechanism from Fred or
preferrably the code generation buffer could be moved under RCU.
Because tb_flush is really rare, my suggestion is simply to allocate two
code generation buffers and do something like
static int which_buffer_is_in_use_bit_mask = 1;
...
/* in tb_flush */
assert (which_buffer_is_in_use_bit_mask != 3);
if (which_buffer_is_in_use_bit_mask == 1) {
which_buffer_is_in_use_bit_mask |= 2;
call_rcu(function doing which_buffer_is_in_use_bit_mask &= ~1);
point TCG to second buffer
} else if (which_buffer_is_in_use_bit_mask == 2) {
which_buffer_is_in_use_bit_mask |= 1;
call_rcu(function doing which_buffer_is_in_use_bit_mask &= ~2);
point TCG to first buffer
}
Basically, we just assert that call_rcu makes at least one pass between
two tb_flushes.
All this is also a prerequisite for patch 1.
Paolo
> struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE];
> +