Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp663148pxk; Sun, 30 Aug 2020 18:46:14 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyyE+cJctnksLs9ESo3WvognvAL4zx0I12GBboLT8Yx5wUOJNJgi0PvbfWIaqrEM4I/WEBj X-Received: by 2002:a17:906:aad4:: with SMTP id kt20mr9694479ejb.247.1598838374413; Sun, 30 Aug 2020 18:46:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1598838374; cv=none; d=google.com; s=arc-20160816; b=fKMmzr5Lw37i8QePrnB0zenhLB0dKtxbt258meRWrVsSIFkxrQihQuvmz6hP4xJir8 zQohEwW59ErOz33Bsl8t0LtTuQZSB20JXPhPdl1QC+fBUONGoRM2l4g2gvavkCfA/2WD lR70iz3EdlyWZJnVG3GZ0PZFXIfBQxuVABAa6ojRTC0jgG65kHoKFZVbbnijSqGFZLwV oED30e/6/3im2VDxAyEcabfxT3+ufUTaJBeiBl8Ynx7vMZAd7HgPs/CHHBKEYj/zko3P ZNd3jvLLSZlHLmSVZLN7hbsvslp5b7CjSNie8pVXJY3Jotj+/FOHnEI1B5yZexboecLx a/fg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:in-reply-to :mime-version:user-agent:date:message-id:from:references:cc:to :subject; bh=5Y+6RZScUDNV+ql/5VG4jVSlhIp/7UK+VnTvBBV2mC0=; b=OblAMnhpVDwOWxy1DrSyS6mdfi56RIsrk0SanV4s38CfYyCxROX8M0UPgbE4WGh/g/ NwAupcPKlUn2dt7iXPPcIL6E3W+zasKjsMtzTw54TX/WyQ4FZiU1TfF6W5MkYcR0L/Ef ImQzTclygP09vUZzMpL/t02pnFPYwlFADNJXg+IKb5HY/2MJ9ofg2uXUqwGS/Zk2nsjd RyisfGMzt/Y/CubGPmYqPJ3r/y/79QPZqXX8yh7+YYZdMAmPEWHe+//S2DN32Jm+PYHl ZSglODmj9Ey4NwY7Ig+DUZi82Sk3lxaDoaiIMXhi2UzcEEobkaFnHGzjT55QUApVk8At DlVw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id sb27si4597168ejb.24.2020.08.30.18.45.51; Sun, 30 Aug 2020 18:46:14 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726824AbgHaBnk (ORCPT + 99 others); Sun, 30 Aug 2020 21:43:40 -0400 Received: from szxga06-in.huawei.com ([45.249.212.32]:59108 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726454AbgHaBnk (ORCPT ); Sun, 30 Aug 2020 21:43:40 -0400 Received: from DGGEMS408-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id 3608E90A6B87991AE549; Mon, 31 Aug 2020 09:43:37 +0800 (CST) Received: from [127.0.0.1] (10.67.76.251) by DGGEMS408-HUB.china.huawei.com (10.3.19.208) with Microsoft SMTP Server id 14.3.487.0; Mon, 31 Aug 2020 09:43:31 +0800 Subject: Re: [NAK] Re: [PATCH] fs: Optimized fget to improve performance To: Al Viro CC: , , Yuqi Jin , kernel test robot , Will Deacon , Mark Rutland , Peter Zijlstra , Boqun Feng References: <1598523584-25601-1-git-send-email-zhangshaokun@hisilicon.com> <20200827142848.GZ1236603@ZenIV.linux.org.uk> From: Shaokun Zhang Message-ID: Date: Mon, 31 Aug 2020 09:43:31 +0800 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Thunderbird/68.8.1 MIME-Version: 1.0 In-Reply-To: <20200827142848.GZ1236603@ZenIV.linux.org.uk> Content-Type: text/plain; charset="gbk" Content-Transfer-Encoding: 8bit X-Originating-IP: [10.67.76.251] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Al, ?? 2020/8/27 22:28, Al Viro ะด??: > On Thu, Aug 27, 2020 at 06:19:44PM +0800, Shaokun Zhang wrote: >> From: Yuqi Jin >> >> It is well known that the performance of atomic_add is better than that of >> atomic_cmpxchg. >> The initial value of @f_count is 1. While @f_count is increased by 1 in >> __fget_files, it will go through three phases: > 0, < 0, and = 0. When the >> fixed value 0 is used as the condition for terminating the increase of 1, >> only atomic_cmpxchg can be used. When we use < 0 as the condition for >> stopping plus 1, we can use atomic_add to obtain better performance. > > Suppose another thread has just removed it from the descriptor table. > >> +static inline bool get_file_unless_negative(atomic_long_t *v, long a) >> +{ >> + long c = atomic_long_read(v); >> + >> + if (c <= 0) >> + return 0; > > Still 1. Now the other thread has gotten to dropping the last reference, > decremented counter to zero and committed to freeing the struct file. > Apologies that I missed it. >> + >> + return atomic_long_add_return(a, v) - 1; > > ... and you increment that sucker back to 1. Sure, you return 0, so the > caller does nothing to that struct file. Which includes undoing the > changes to its refecount. > > In the meanwhile, the third thread does fget on the same descriptor, > and there we end up bumping the refcount to 2 and succeeding. Which > leaves the caller with reference to already doomed struct file... > > IOW, NAK - this is completely broken. The whole point of > atomic_long_add_unless() is that the check and conditional increment > are atomic. Together. That's what your optimization takes out. > How about this? We try to replace atomic_cmpxchg with atomic_add to improve performance. The atomic_add does not check the current f_count value. Therefore, the number of online CPUs is reserved to prevent multi-core competition. + +static inline bool get_file_unless(atomic_long_t *v, long a) +{ + long cpus = num_online_cpus(); + long c = atomic_long_read(v); + long ret; + + if (c > cpus || c < -cpus) + ret = atomic_long_add_return(a, v) - a; + else + ret = atomic_long_add_unless(v, a, 0); + + return ret; +} + #define get_file_rcu_many(x, cnt) \ - atomic_long_add_unless(&(x)->f_count, (cnt), 0) + get_file_unless(&(x)->f_count, (cnt)) Thanks, Shaokun > . >