Received: by 2002:a05:6358:3188:b0:123:57c1:9b43 with SMTP id q8csp19205623rwd; Wed, 28 Jun 2023 06:31:13 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ4nnzGfkAtqU5lq2NGhf/ozabFPQOSnLX9sZ4cgZmQaBURYmJzZi9Q18SNRKzl9+N4Mkj4S X-Received: by 2002:a05:6a20:938b:b0:e9:5b0a:deff with SMTP id x11-20020a056a20938b00b000e95b0adeffmr33596138pzh.22.1687959072493; Wed, 28 Jun 2023 06:31:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1687959072; cv=none; d=google.com; s=arc-20160816; b=o0eX/bYiKnK4qncvX9vGteH5DHkx3SOuPuIm4+Ha+kHH6BI6dO8uihwPM8wPSL4mB/ VwZ8i/PyUSgULxAdlZNuTvB27mPjOeGTMUShAlt9DPvZmf58Ss8ApTxvpzPA9IUtpmF4 HU6QZjvzoWxTxBIJCOAq0XOAYg49+Wk1AymwBPl51wDs7rwHq7Nih7Q2//VQVNW+5QWM x6GHbIVSRGUUA/Ew/bucmE6Shn1e00Pn+sVa7A1BFVWAQEhXUzZtiTKOTOME2+la26wx 4kCIufmTAPh3fkfhcDj6AsV/9QjV6oVo9MZG42upRfH3ytuQSSv0fozBCCUs8pRpnedL 0Vtw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=S3z6PQMBbqHCrDxx2xZUe/zIGd4+bhvDi4ij+gJc1bg=; fh=fHzCyx2lgDg5rzxkd+fn4L1zIOfYfCj3lN8BN24cVWY=; b=Fhq4Cb3Rq9cTYV+tCOGLQxomb5aWJlTnbcRuFB0Vbm1PCvyzw706m+l0FpPGFURVTT sP/Cl2vY7ZVyM+2QjyHv86gJhyR2JWI4op/kn5Xdd9gkkXl5/ENFj5QrJ/ptda1LPolI 3AY9CAenDGF53JUGHcJ0Ku1r6IhU59iDRJ4FnMXSg24ypBp4FvOK8b/+C+sCFYBJKOzr WwXZzg27+Sx+bw7t+Vi4UKkpHIPPvpptKyrV6Vbg10l59fnG7A+SAEYwEdU3OJ2SlkRk QpaiPD1lUB1hCENI+zU0P2XLWyt64ti819Y+sYmUQznLHYkigjTlJEk4fA4hME0B/TU4 ud+A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id d26-20020aa7869a000000b00673c91e710csi6717814pfo.154.2023.06.28.06.30.57; Wed, 28 Jun 2023 06:31:12 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231971AbjF1NYe (ORCPT + 99 others); Wed, 28 Jun 2023 09:24:34 -0400 Received: from szxga08-in.huawei.com ([45.249.212.255]:19165 "EHLO szxga08-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231835AbjF1NYX (ORCPT ); Wed, 28 Jun 2023 09:24:23 -0400 Received: from dggpeml500021.china.huawei.com (unknown [172.30.72.54]) by szxga08-in.huawei.com (SkyGuard) with ESMTP id 4Qrj3529Chz1HC8N; Wed, 28 Jun 2023 21:24:01 +0800 (CST) Received: from huawei.com (10.175.127.227) by dggpeml500021.china.huawei.com (7.185.36.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Wed, 28 Jun 2023 21:24:17 +0800 From: Baokun Li To: CC: , , , , , , , Subject: [PATCH v2 2/7] quota: add new global dquot list releasing_dquots Date: Wed, 28 Jun 2023 21:21:50 +0800 Message-ID: <20230628132155.1560425-3-libaokun1@huawei.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20230628132155.1560425-1-libaokun1@huawei.com> References: <20230628132155.1560425-1-libaokun1@huawei.com> MIME-Version: 1.0 Content-Transfer-Encoding: 7BIT Content-Type: text/plain; charset=US-ASCII X-Originating-IP: [10.175.127.227] X-ClientProxiedBy: dggems706-chm.china.huawei.com (10.3.19.183) To dggpeml500021.china.huawei.com (7.185.36.21) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org Add a new global dquot list that obeys the following rules: 1). A dquot is added to this list when its last reference count is about to be dropped. 2). The reference count of the dquot in the list is greater than or equal to 1 ( due to possible race with dqget()). 3). When a dquot is removed from this list, a reference count is always subtracted, and if the reference count is then 0, the dquot is added to the free_dquots list. This list is used to safely perform the final cleanup before releasing the last reference count, to avoid various contention issues caused by performing cleanup directly in dqput(), and to avoid the performance impact caused by calling synchronize_srcu(&dquot_srcu) directly in dqput(). Here it is just defining the list and implementing the corresponding operation function, which we will use later. Suggested-by: Jan Kara Signed-off-by: Baokun Li --- fs/quota/dquot.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 108ba9f1e420..a8b43b5b5623 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -226,12 +226,21 @@ static void put_quota_format(struct quota_format_type *fmt) /* * Dquot List Management: * The quota code uses four lists for dquot management: the inuse_list, - * free_dquots, dqi_dirty_list, and dquot_hash[] array. A single dquot - * structure may be on some of those lists, depending on its current state. + * releasing_dquots, free_dquots, dqi_dirty_list, and dquot_hash[] array. + * A single dquot structure may be on some of those lists, depending on + * its current state. * * All dquots are placed to the end of inuse_list when first created, and this * list is used for invalidate operation, which must look at every dquot. * + * When the last reference of a dquot will be dropped, the dquot will be + * added to releasing_dquots. We'd then queue work item which would call + * synchronize_srcu() and after that perform the final cleanup of all the + * dquots on the list. Both releasing_dquots and free_dquots use the + * dq_free list_head in the dquot struct. when a dquot is removed from + * releasing_dquots, a reference count is always subtracted, and if + * dq_count == 0 at that point, the dquot will be added to the free_dquots. + * * Unused dquots (dq_count == 0) are added to the free_dquots list when freed, * and this list is searched whenever we need an available dquot. Dquots are * removed from the list as soon as they are used again, and @@ -250,6 +259,7 @@ static void put_quota_format(struct quota_format_type *fmt) static LIST_HEAD(inuse_list); static LIST_HEAD(free_dquots); +static LIST_HEAD(releasing_dquots); static unsigned int dq_hash_bits, dq_hash_mask; static struct hlist_head *dquot_hash; @@ -305,6 +315,13 @@ static inline void put_dquot_last(struct dquot *dquot) dqstats_inc(DQST_FREE_DQUOTS); } +static inline void put_releasing_dquots(struct dquot *dquot) +{ + list_add_tail(&dquot->dq_free, &releasing_dquots); + /* dquot will be moved to free_dquots during shrink. */ + dqstats_inc(DQST_FREE_DQUOTS); +} + static inline void remove_free_dquot(struct dquot *dquot) { if (list_empty(&dquot->dq_free)) -- 2.31.1