On 03/02/2015 17:17, Richard Henderson wrote: >> > @@ -759,7 +760,9 @@ static void page_flush_tb_1(int level, void **lp) >> > PageDesc *pd = *lp; >> > >> > for (i = 0; i < V_L2_SIZE; ++i) { >> > - pd[i].first_tb = NULL; >> > + for (j = 0; j < MAX_CPUS; j++) { >> > + pd[i].first_tb[j] = NULL; >> > + } >> > invalidate_page_bitmap(pd + i); >> > } >> > } else { > Surely you've got to do some locking somewhere in order to be able to modify > another thread's cpu tb list.
But that's probably not even necessary. page_flush_tb_1 is called from tb_flush, which in turn is only called in very special circumstances. It should be possible to have something like the kernel's "stop_machine" that does the following: 1) schedule a callback on all TCG CPU threads 2) wait for all CPUs to have reached that callback 3) do tb_flush on all CPUs, while it knows they are not holding any lock 4) release all TCG CPU threads With one TCG thread, just use qemu_bh_new (hidden behind a suitable API of course!). Once you have multiple TCG CPU threads, loop on all CPUs with the same run_on_cpu function that KVM uses. Paolo