Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp6172862imu; Mon, 21 Jan 2019 04:30:55 -0800 (PST) X-Google-Smtp-Source: ALg8bN6VTXXaQXiq1u12bAmnfJAl22zPEMNKZ+qhnKynQHhtoYEIwYeIHpOXvP5+dYe2VChyRn2s X-Received: by 2002:a65:6094:: with SMTP id t20mr27761835pgu.285.1548073855784; Mon, 21 Jan 2019 04:30:55 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548073855; cv=none; d=google.com; s=arc-20160816; b=HwPxeu83L32iyA4gzgqUIhCQHhcuayLXaE4o24t2ToCGDh88FDFeiAokmpqq5/z55L ec8Nd2+pPmzyx5Zi02BOxDuafFdAmDmIvKtXdClVFVAQ5ZUsauOALhnlpTJgGOVEluzP uWZSRfO9jqWZIRdIpde6MruS2SqpJR+KbVY7zI7knzUPt7hkZr3tnchgOT0wIlaXrnnC WYFfKFIC2o4aDM9zczoS30Z8wX4q5VueoT0eDIqlinfgn9rjsP/p0Omihs+rx/Iny8jQ PaD9GwH5MOWVormoCdFUs0IsLzIY2dmcBA/HflFhCGXdHLfOty1P/mgQs8d8q1EHrxPU pl6w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=cVqSnm1+Gomh9R6fjm5+J2p/n3A44tXQxbOzw7X1r5Q=; b=GzDNtQEe7IdFfne07TuDkcmJWjISkhG3nSg85WAceWAqMD+/scwZO5UmAJy0Qzj/Q8 WvFHcXZYYlxQu7QJYWYme2Eqi4nQH4UZ84lWM2iAJJv+3uaN9ZjapXXctq98RfeUzwXA bSXXN6abWZcotv0CpqHSIgh1ms2sLdh1VRUBWkRYOL0rRCxUIVis85kNfQYw4fWuCxQO gIBCVihqevlDmQbT3O2Vnuz57KLa85mnVG/vK4NaO8YPEbNwHzCAL1L0SYmxbw+QXAKs x3KiFI/547D96LODGqVjHjEd0mpK811Pwf9OtZoVdd2aKe3yfxKVyou5cBFBILPCHTM7 KDXg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=sizwidYd; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x64si12349814pfb.120.2019.01.21.04.30.39; Mon, 21 Jan 2019 04:30:55 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=sizwidYd; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728549AbfAUM3Y (ORCPT + 99 others); Mon, 21 Jan 2019 07:29:24 -0500 Received: from mail-io1-f67.google.com ([209.85.166.67]:44764 "EHLO mail-io1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728299AbfAUM3Y (ORCPT ); Mon, 21 Jan 2019 07:29:24 -0500 Received: by mail-io1-f67.google.com with SMTP id r200so16192188iod.11 for ; Mon, 21 Jan 2019 04:29:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=cVqSnm1+Gomh9R6fjm5+J2p/n3A44tXQxbOzw7X1r5Q=; b=sizwidYd8GWX+Pfn/P39TN3P3JXvkhe/GzVgoEL1Tfk1ER3CMsaWG+mzvX7Ul1wu6s 3Nh6uN1wsQhXOjsac2gom26cNzLuB1HPaPEEW3Z8U5QTarEJxVSRKPDe6NmzokOieruf Ct8zFq7FU585So/E5moZH3juOrNMeYlrDCxbFiaiW/yqxO2yMRsT3FUinflw41sTcsnm MLFH7OFI12B9Rcp1s8iimVHGc5Wjxrd7wI+yG619NRXoqcpMmAWxq20H2mXV3TjgRukL 3CrpUhlnf/byPU3olWNeFAHKPZSEBiXQAq6VabRwEiAi2tjYoE6Kq/Sik6tobHyWkpSb r/JQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=cVqSnm1+Gomh9R6fjm5+J2p/n3A44tXQxbOzw7X1r5Q=; b=C7r72v+pwaPcdOMNqUbuCGvvUVq/Vkc7os8qEK2IAhJ5XLfWhidRZqvY6jUyL+C9G/ QEIQujoHkeXqxvonNsu+Jc09kDE1LD4TvU/pkvCzuVs27LZL0lmtKeeggGrMHkZ26Aoy H5KzrKNzZOBF/am/wTGwmjM/KhT/RZqPY35YRKHdgNlgbhZjwylBObt2YWKubJz+rOIR MTYYVpHYR77F4WmMBSw3nbCG0zavY8dTdhDQw+Hr0mhO+WBP7YuCDJAz4mkJdab76KJs oSg3RW49RZZoqjSpaXpqFr73amdHo97Dz4hhVNIeU7iNVzGDx+J2ty20mffofaJUHjJa LHXQ== X-Gm-Message-State: AJcUuke5ITy7VhpTJdeCK9vbJ361z2defmOnL+mttr0JI6gGMtYEwJrB uIX2zrVECflvi5vC5gIyU3O7lbf8q+4vn5GRvFL5/w== X-Received: by 2002:a6b:fa01:: with SMTP id p1mr15180792ioh.271.1548073762606; Mon, 21 Jan 2019 04:29:22 -0800 (PST) MIME-Version: 1.0 References: <1547634429-772-1-git-send-email-elena.reshetova@intel.com> <20190121114505.GA7307@andrea> In-Reply-To: <20190121114505.GA7307@andrea> From: Dmitry Vyukov Date: Mon, 21 Jan 2019 13:29:11 +0100 Message-ID: Subject: Re: [PATCH] kcov: convert kcov.refcount to refcount_t To: Andrea Parri Cc: Elena Reshetova , Kees Cook , Peter Zijlstra , Alan Stern , "Paul E. McKenney" , Will Deacon , Andrew Morton , Andrey Ryabinin , Anders Roxell , Mark Rutland , LKML Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, Jan 21, 2019 at 12:45 PM Andrea Parri wrote: > > On Mon, Jan 21, 2019 at 10:52:37AM +0100, Dmitry Vyukov wrote: > > [...] > > > > Am I missing something or refcount_dec_and_test does not in fact > > > provide ACQUIRE ordering? > > > > > > +case 5) - decrement-based RMW ops that return a value > > > +----------------------------------------------------- > > > + > > > +Function changes: > > > + atomic_dec_and_test() --> refcount_dec_and_test() > > > + atomic_sub_and_test() --> refcount_sub_and_test() > > > + no atomic counterpart --> refcount_dec_if_one() > > > + atomic_add_unless(&var, -1, 1) --> refcount_dec_not_one(&var) > > > + > > > +Memory ordering guarantees changes: > > > + fully ordered --> RELEASE ordering + control dependency > > > > > > I think that's against the expected refcount guarantees. When I > > > privatize an atomic_dec_and_test I would expect that not only stores, > > > but also loads act on a quiescent object. But loads can hoist outside > > > of the control dependency. > > > > > > Consider the following example, is it the case that the BUG_ON can still fire? > > Can't it fire in an SC world? (wrong example, or a Monday morning? ;D) I don't see how. Maybe there is a stupid off-by-one, but overall that's the example I wanted to show. refcount is 2, each thread sets own done flag, drops refcount, last thread checks done flag of the other thread. > > > struct X { > > > refcount_t rc; // == 2 > > > int done1, done2; // == 0 > > > }; > > > > > > // thread 1: > > > x->done1 = 1; > > > if (refcount_dec_and_test(&x->rc)) > > > BUG_ON(!x->done2); > > > > > > // thread 2: > > > x->done2 = 1; > > > if (refcount_dec_and_test(&x->rc)) > > > BUG_ON(!x->done1); > > > > +more people knowledgeable in memory ordering > > > > Unfortunately I can't find a way to reply to the > > Documentation/core-api/refcount-vs-atomic.rst patch review thread. > > > > The refcount_dec_and_test guarantees look too weak to me, see the > > example above. Shouldn't refcount_dec_and_test returning true give the > > object in fully quiescent state? Why only control dependency? Loads > > can hoist across control dependency, no? > > As you remarked, the doc. says CTRL+RELEASE (so yes, loads can hoist); > AFAICR, implementations do comply to this requirement. > > (FWIW, I sometimes think at this "weird" ordering as a weak "acq_rel", > the latter, acq_rel, being missing from the current APIs.) But doesn't it break like half of use cases? Iv'e skimmed through few uses. This read of db_info->views after refcount_dec_and_test looks like potential unordered read: https://elixir.bootlin.com/linux/v5.0-rc3/source/arch/s390/kernel/debug.c#L412 This read of vdata->maddr after refcount_dec_and_test looks like potential unordered read: https://elixir.bootlin.com/linux/v5.0-rc3/source/drivers/char/mspec.c#L171 This read of buf->sgt_base looks like potential unordered read: https://elixir.bootlin.com/linux/v5.0-rc3/source/drivers/media/common/videobuf2/videobuf2-dma-contig.c#L129 Also this: https://elixir.bootlin.com/linux/v5.0-rc3/source/fs/btrfs/scrub.c#L544 and this: https://elixir.bootlin.com/linux/v5.0-rc3/source/fs/nfs/inode.c#L992 For each case it's quite hard to prove if there is anything else that provides read ordering, or if the field was initialized before the object was first published and then never changed. But overall, why are we making it so error-prone and subtle? > > > > Suggested-by: Kees Cook > > > > Reviewed-by: David Windsor > > > > Reviewed-by: Hans Liljestrand > > > > Signed-off-by: Elena Reshetova > > > > --- > > > > kernel/kcov.c | 9 +++++---- > > > > 1 file changed, 5 insertions(+), 4 deletions(-) > > > > > > > > diff --git a/kernel/kcov.c b/kernel/kcov.c > > > > index c2277db..051e86e 100644 > > > > --- a/kernel/kcov.c > > > > +++ b/kernel/kcov.c > > > > @@ -20,6 +20,7 @@ > > > > #include > > > > #include > > > > #include > > > > +#include > > > > #include > > > > > > > > /* Number of 64-bit words written per one comparison: */ > > > > @@ -44,7 +45,7 @@ struct kcov { > > > > * - opened file descriptor > > > > * - task with enabled coverage (we can't unwire it from another task) > > > > */ > > > > - atomic_t refcount; > > > > + refcount_t refcount; > > > > /* The lock protects mode, size, area and t. */ > > > > spinlock_t lock; > > > > enum kcov_mode mode; > > > > @@ -228,12 +229,12 @@ EXPORT_SYMBOL(__sanitizer_cov_trace_switch); > > > > > > > > static void kcov_get(struct kcov *kcov) > > > > { > > > > - atomic_inc(&kcov->refcount); > > > > + refcount_inc(&kcov->refcount); > > > > } > > > > > > > > static void kcov_put(struct kcov *kcov) > > > > { > > > > - if (atomic_dec_and_test(&kcov->refcount)) { > > > > + if (refcount_dec_and_test(&kcov->refcount)) { > > > > vfree(kcov->area); > > > > kfree(kcov); > > > > } > > > > @@ -312,7 +313,7 @@ static int kcov_open(struct inode *inode, struct file *filep) > > > > if (!kcov) > > > > return -ENOMEM; > > > > kcov->mode = KCOV_MODE_DISABLED; > > > > - atomic_set(&kcov->refcount, 1); > > > > + refcount_set(&kcov->refcount, 1); > > > > spin_lock_init(&kcov->lock); > > > > filep->private_data = kcov; > > > > return nonseekable_open(inode, filep); > > > > -- > > > > 2.7.4 > > > >