Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756272AbdDGOF7 (ORCPT ); Fri, 7 Apr 2017 10:05:59 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53924 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755430AbdDGOFt (ORCPT ); Fri, 7 Apr 2017 10:05:49 -0400 DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 80C4D3DBDF Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=rkrcmar@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 80C4D3DBDF Date: Fri, 7 Apr 2017 16:05:41 +0200 From: Radim =?utf-8?B?S3LEjW3DocWZ?= To: Christian Borntraeger Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, Christoffer Dall , Andrew Jones , Marc Zyngier , Paolo Bonzini , Cornelia Huck , James Hogan , Paul Mackerras Subject: Re: [PATCH 2/6] KVM: use kvm_{test,clear}_request instead of {test,clear}_bit Message-ID: <20170407140541.GF23559@potion> References: <20170406202056.18379-1-rkrcmar@redhat.com> <20170406202056.18379-3-rkrcmar@redhat.com> <20170407122413.GC23559@potion> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20170407122413.GC23559@potion> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Fri, 07 Apr 2017 14:05:48 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1517 Lines: 37 2017-04-07 14:24+0200, Radim Krčmář: > 2017-04-07 12:55+0200, Christian Borntraeger: >> On 04/06/2017 10:20 PM, Radim Krčmář wrote: >>> static inline bool kvm_check_request(int req, struct kvm_vcpu *vcpu) >>> { >>> - if (test_bit(req, &vcpu->requests)) { >>> - clear_bit(req, &vcpu->requests); >>> + if (kvm_test_request(req, vcpu)) { >>> + kvm_clear_request(req, vcpu); >> >> This looks fine. I am just asking myself why we do not use >> test_and_clear_bit? Do we expect gcc to merge all test bits as >> a fast path? This does not seem to work as far as I can tell and >> almost everybody does a fast path like in > > test_and_clear_bit() is a slower operation even if the test is false (at > least on x86), because it needs to be fully atomic. > >> arch/s390/kvm/kvm-s390.c: >> if (!vcpu->requests) >> return 0; >> >> arch/x86/kvm/x86.c: >> if (vcpu->requests) { > > We'll mostly have only one request set, so splitting the test_and_clear > improves the performance of many subsequent tests_and_clear()s even if > the compiler doesn't optimize. > > GCC couldn't even optimize if we used test_and_clear_bit(), because that > instruction adds barriers, but the forward check for vcpu->requests is > there because we do not trust the optimizer to do it for us and it would > make a big difference. Ugh, I started thinking that bitops are not atomic because I looked at wrong boot/bitops.h by mistake. The compiler cannot merge test_bit()s, but the speed difference holds.