From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48058) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZP9z3-0007sY-Lf for qemu-devel@nongnu.org; Tue, 11 Aug 2015 09:52:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZP9yy-0002HJ-FY for qemu-devel@nongnu.org; Tue, 11 Aug 2015 09:52:53 -0400 Received: from mail-wi0-x22a.google.com ([2a00:1450:400c:c05::22a]:34576) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZP9yy-0002H1-96 for qemu-devel@nongnu.org; Tue, 11 Aug 2015 09:52:48 -0400 Received: by wicne3 with SMTP id ne3so177883797wic.1 for ; Tue, 11 Aug 2015 06:52:47 -0700 (PDT) Sender: Paolo Bonzini References: <1438966995-5913-1-git-send-email-a.rigo@virtualopensystems.com> <1438966995-5913-2-git-send-email-a.rigo@virtualopensystems.com> From: Paolo Bonzini Message-ID: <55C9FE29.2080204@redhat.com> Date: Tue, 11 Aug 2015 15:52:41 +0200 MIME-Version: 1.0 In-Reply-To: <1438966995-5913-2-git-send-email-a.rigo@virtualopensystems.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit Subject: Re: [Qemu-devel] [RFC v4 1/9] exec.c: Add new exclusive bitmap to ram_list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Alvise Rigo , qemu-devel@nongnu.org, mttcg@listserver.greensocs.com Cc: claudio.fontana@huawei.com, jani.kokkonen@huawei.com, tech@virtualopensystems.com, alex.bennee@linaro.org On 07/08/2015 19:03, Alvise Rigo wrote: > +static inline int cpu_physical_memory_excl_atleast_one_clean(ram_addr_t addr) > +{ > + unsigned long *bitmap = ram_list.dirty_memory[DIRTY_MEMORY_EXCLUSIVE]; > + unsigned long next, end; > + > + if (likely(smp_cpus <= BITS_PER_LONG)) { This only works if smp_cpus divides BITS_PER_LONG, i.e. BITS_PER_LONG % smp_cpus == 0. > + unsigned long mask = (1 << smp_cpus) - 1; > + > + return > + (mask & (bitmap[BIT_WORD(EXCL_BITMAP_GET_OFFSET(addr))] >> > + (EXCL_BITMAP_GET_OFFSET(addr) & (BITS_PER_LONG-1)))) != mask; > + } > + > + end = BIT_WORD(EXCL_BITMAP_GET_OFFSET(addr)) + smp_cpus; > + next = find_next_zero_bit(bitmap, end, > + BIT_WORD(EXCL_BITMAP_GET_OFFSET(addr))); > + > + return next < end; > +static inline int cpu_physical_memory_excl_is_dirty(ram_addr_t addr, > + unsigned long cpu) > +{ > + unsigned long *bitmap = ram_list.dirty_memory[DIRTY_MEMORY_EXCLUSIVE]; > + unsigned long end, next; > + uint32_t add; > + > + assert(cpu <= smp_cpus); > + > + if (likely(smp_cpus <= BITS_PER_LONG)) { > + cpu = (cpu == smp_cpus) ? (1 << cpu) - 1 : (1 << cpu); > + > + return cpu & (bitmap[BIT_WORD(EXCL_BITMAP_GET_OFFSET(addr))] >> > + (EXCL_BITMAP_GET_OFFSET(addr) & (BITS_PER_LONG-1))); > + } > + > + add = (cpu == smp_cpus) ? 0 : 1; Why not have a separate function for the cpu == smp_cpus case? I don't think real hardware has ll/sc per CPU. Can we have the bitmap as: - 0 if one or more CPUs have the address set to exclusive, _and_ no CPU has done a concurrent access - 1 if no CPUs have the address set to exclusive, _or_ one CPU has done a concurrent access. Then: - ll sets the bit to 0, and requests a flush if it was 1 - when setting a TLB entry, set it to TLB_EXCL if the bitmap has 0 - in the TLB_EXCL slow path, set the bit to 1 and, for conditional stores, succeed if the bit was 0 - when removing an exclusive entry, set the bit to 1 Paolo