From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41161) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1agxkh-0004LW-Ol for qemu-devel@nongnu.org; Fri, 18 Mar 2016 12:59:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1agxke-0007e5-HX for qemu-devel@nongnu.org; Fri, 18 Mar 2016 12:59:55 -0400 Received: from mx1.redhat.com ([209.132.183.28]:36921) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1agxke-0007e0-C6 for qemu-devel@nongnu.org; Fri, 18 Mar 2016 12:59:52 -0400 References: <1458317932-1875-1-git-send-email-alex.bennee@linaro.org> <1458317932-1875-4-git-send-email-alex.bennee@linaro.org> From: Paolo Bonzini Message-ID: <56EC3402.1030007@redhat.com> Date: Fri, 18 Mar 2016 17:59:46 +0100 MIME-Version: 1.0 In-Reply-To: <1458317932-1875-4-git-send-email-alex.bennee@linaro.org> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [RFC v1 03/11] tcg: comment on which functions have to be called with tb_lock held List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: =?UTF-8?Q?Alex_Benn=c3=a9e?= , mttcg@greensocs.com, fred.konrad@greensocs.com, a.rigo@virtualopensystems.com, serge.fdrv@gmail.com, cota@braap.org Cc: Richard Henderson , mark.burton@greensocs.com, qemu-devel@nongnu.org, =?UTF-8?Q?Andreas_F=c3=a4rber?= , Peter Crosthwaite On 18/03/2016 17:18, Alex Benn=C3=A9e 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 =3D 1; ... /* in tb_flush */ assert (which_buffer_is_in_use_bit_mask !=3D 3); if (which_buffer_is_in_use_bit_mask =3D=3D 1) { which_buffer_is_in_use_bit_mask |=3D 2; call_rcu(function doing which_buffer_is_in_use_bit_mask &=3D ~1); point TCG to second buffer } else if (which_buffer_is_in_use_bit_mask =3D=3D 2) { which_buffer_is_in_use_bit_mask |=3D 1; call_rcu(function doing which_buffer_is_in_use_bit_mask &=3D ~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]; > +