From patchwork Tue Mar 19 00:15:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13596046 Received: from mail-pl1-f171.google.com (mail-pl1-f171.google.com [209.85.214.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F36A12F5B for ; Tue, 19 Mar 2024 00:17:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710807435; cv=none; b=gEVMGtiyvn2nQPKx5RQ61Oi2ZyGXMfaSxpSM8HbTSa3PMvWITCblbMfT8wZ0mSy3ySysNHvd7BG8xoj+ZWynxoYhDAm+huggiVfOzZrXRiNcPysuYHtNjDjRIbEbcu4FRKGMBKsv+Tn7Yb0ZuOKVX3cDL1QYkVn56I0niPJJpzw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710807435; c=relaxed/simple; bh=PSvqTpkS4fozP/IBctLIB4nZm9FVIu6ICdCwOUPt784=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nNyYdxOqJHgy14e8cyVWC1Y3Qp79j4Zr3AGi6AO1EHYlnPTVnNNY5qAX2zf4jvCfPoVK0Q4+gwomGsV5nDO0P8oymHE09Lf0zEuOlqfGoVUJZqQy/Vnf4jOHlJdJXXSitJxxozSbCk+unWFa8SjpvjsrDyUapl/KqTF4eq0SWs4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fromorbit.com; spf=pass smtp.mailfrom=fromorbit.com; dkim=pass (2048-bit key) header.d=fromorbit-com.20230601.gappssmtp.com header.i=@fromorbit-com.20230601.gappssmtp.com header.b=ZtNsj+0l; arc=none smtp.client-ip=209.85.214.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fromorbit.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fromorbit.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=fromorbit-com.20230601.gappssmtp.com header.i=@fromorbit-com.20230601.gappssmtp.com header.b="ZtNsj+0l" Received: by mail-pl1-f171.google.com with SMTP id d9443c01a7336-1dde26f7e1dso35134335ad.1 for ; Mon, 18 Mar 2024 17:17:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20230601.gappssmtp.com; s=20230601; t=1710807433; x=1711412233; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=jNiN0Kr8TGljxcsoI4JBbWsa1vOCRxTDW+ISsIi2EQs=; b=ZtNsj+0ldwbvfpukaVh1oMj2In9NiAkSKL1oCBQ5SNSzB9yX1qaQfYeAvPyFDMLYj2 HtKJbb/zF5OdZlEM/6VkzLiytQNPhcjCB2prIJ2UkkKXQvjvCjFM0xTOBpnRfxgAICmh e3q6i+dNqbZfTWKiJ/IHX60acZ7KaSJFHCOZaCpFdUCSfasjXRmoLw+bXmmzfJCTk6I7 gUcfo3rnsRiGZzjQXlu3L/q+gXOA409tOikhVXQR80I6nS9p3SpNfK7Aqd4dfR9wd3Xw uWVG/u36ZNwMz/PRJ556mR2IXuxxh5dKOk2jYJiIe4MUjCzf+frqB9r3uBUihMUn/JO5 AuaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1710807433; x=1711412233; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jNiN0Kr8TGljxcsoI4JBbWsa1vOCRxTDW+ISsIi2EQs=; b=hwGEMMgO/j4+DZBMIqUKkxxchNLzqi4x/uVPrX30aSf3cEKmS7ObWgsMDsVPXzP5Sp vlh8J2mRFfYWfTvE8EJySgWzQD8vJFUY8AEGoqG03eKuZ2FU0U0t6j/PIBhHr+VrO5pS HNGmPm2Gsvb8KoJoeHkrR7iD/B+gbqCkhOj8Wg42AKPuS80dN+m0Zc6tNlb8xz04rHaz 4YHkI/6rhUFLtRT9ZLgUzL73Geliseb7baO69SnYlvkm3HmrII8Dp6AbOKwmWVHpS4/3 8I7uLTr/T8zgFaeNZ2AS6gP8X08FLZ4W53cT+x3142QjE2QBORqmDAMO8xrurgUpS4UM PB/Q== X-Gm-Message-State: AOJu0YxJve2pVTMaS0eZIJJxMaP8QEpv/tD2s1BrDRe56bv3nizphipK PFCiMYUKB3940nbinwRWeA3WGm3NPzapU29Y71QpEj1NC05U0XFAJYoygJUQJ56iKDE3vJepM6l I X-Google-Smtp-Source: AGHT+IFa/GDzICRw7RfNEjQOaAryiOwHcU7Brcbk2pvfBT3AtD5ab/qltp7I+9SN+IHA1GX5QGKrYw== X-Received: by 2002:a17:902:c952:b0:1dd:6765:103 with SMTP id i18-20020a170902c95200b001dd67650103mr13199835pla.48.1710807433072; Mon, 18 Mar 2024 17:17:13 -0700 (PDT) Received: from dread.disaster.area (pa49-180-185-123.pa.nsw.optusnet.com.au. [49.180.185.123]) by smtp.gmail.com with ESMTPSA id km12-20020a17090327cc00b001dd5ba34f3esm9900935plb.278.2024.03.18.17.17.11 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Mar 2024 17:17:11 -0700 (PDT) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.96) (envelope-from ) id 1rmNAD-003pkj-2k for linux-xfs@vger.kernel.org; Tue, 19 Mar 2024 11:17:09 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.97) (envelope-from ) id 1rmNAD-0000000EONN-1MyD for linux-xfs@vger.kernel.org; Tue, 19 Mar 2024 11:17:09 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 1/4] xfs: make inode inactivation state changes atomic Date: Tue, 19 Mar 2024 11:15:57 +1100 Message-ID: <20240319001707.3430251-2-david@fromorbit.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240319001707.3430251-1-david@fromorbit.com> References: <20240319001707.3430251-1-david@fromorbit.com> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Dave Chinner We need the XFS_NEED_INACTIVE flag to correspond to whether the inode is on the inodegc queues so that we can then use this state for lazy removal. To do this, move the addition of the inode to the inodegc queue under the ip->i_flags_lock so that it is atomic w.r.t. setting the XFS_NEED_INACTIVE flag. Then, when we remove the inode from the inodegc list to actually run inactivation, clear the XFS_NEED_INACTIVE at the same time we are setting XFS_INACTIVATING to indicate that inactivation is in progress. These changes result in all the state changes and inodegc queuing being atomic w.r.t. each other and inode lookups via the use of the ip->i_flags lock. Signed-off-by: Dave Chinner Reviewed-by: Darrick J. Wong --- fs/xfs/xfs_icache.c | 16 ++++++++++++++-- fs/xfs/xfs_inode.h | 11 +++++++---- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 6c87b90754c4..9a362964f656 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -1880,7 +1880,12 @@ xfs_inodegc_worker( llist_for_each_entry_safe(ip, n, node, i_gclist) { int error; - xfs_iflags_set(ip, XFS_INACTIVATING); + /* Switch state to inactivating. */ + spin_lock(&ip->i_flags_lock); + ip->i_flags |= XFS_INACTIVATING; + ip->i_flags &= ~XFS_NEED_INACTIVE; + spin_unlock(&ip->i_flags_lock); + error = xfs_inodegc_inactivate(ip); if (error && !gc->error) gc->error = error; @@ -2075,9 +2080,14 @@ xfs_inodegc_queue( unsigned long queue_delay = 1; trace_xfs_inode_set_need_inactive(ip); + + /* + * Put the addition of the inode to the gc list under the + * ip->i_flags_lock so that the state change and list addition are + * atomic w.r.t. lookup operations under the ip->i_flags_lock. + */ spin_lock(&ip->i_flags_lock); ip->i_flags |= XFS_NEED_INACTIVE; - spin_unlock(&ip->i_flags_lock); cpu_nr = get_cpu(); gc = this_cpu_ptr(mp->m_inodegc); @@ -2086,6 +2096,8 @@ xfs_inodegc_queue( WRITE_ONCE(gc->items, items + 1); shrinker_hits = READ_ONCE(gc->shrinker_hits); + spin_unlock(&ip->i_flags_lock); + /* * Ensure the list add is always seen by anyone who finds the cpumask * bit set. This effectively gives the cpumask bit set operation diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 94fa79ae1591..b0943d888f5c 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -349,10 +349,13 @@ static inline bool xfs_inode_has_forcealign(struct xfs_inode *ip) /* * If we need to update on-disk metadata before this IRECLAIMABLE inode can be - * freed, then NEED_INACTIVE will be set. Once we start the updates, the - * INACTIVATING bit will be set to keep iget away from this inode. After the - * inactivation completes, both flags will be cleared and the inode is a - * plain old IRECLAIMABLE inode. + * freed, then NEED_INACTIVE will be set. If the inode is accessed via iget + * whilst NEED_INACTIVE is set, the inode will be reactivated and become a + * normal inode again. Once we start the inactivation, the INACTIVATING bit will + * be set and the NEED_INACTIVE bit will be cleared. The INACTIVATING bit will + * keep iget away from this inode whilst inactivation is in progress. After the + * inactivation completes, INACTIVATING will be cleared and the inode + * transitions to a plain old IRECLAIMABLE inode. */ #define XFS_INACTIVATING (1 << 13) From patchwork Tue Mar 19 00:15:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13596047 Received: from mail-pf1-f179.google.com (mail-pf1-f179.google.com [209.85.210.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6E0842FB6 for ; Tue, 19 Mar 2024 00:17:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710807435; cv=none; b=sngoARFseEFzox7Lb3Ua/XO8MzL/vk+V0MkOngj5E5y8A22XL2/2mo5lCy7BmuWVdFpN9Zg5NPf+U3goE3UJZQ/r0iaBq9Aubcdwf7DxBfC+EZblMN3FGMb2xPKjkcN1H64wrwaqXJrTGN28cniZs5BRttwIdfE/GiSN5nHRvbs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710807435; c=relaxed/simple; bh=3JQ1gvt+lcgaeKtFjjCkc8E54eKaNQv2fDaIaYCFPxU=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YzO/tFtUr0vQdZgqMtI70eJWITs4MPI6ajXXaUfxLNcB8SZyS08P8yIlCMJqzeSsR5UoTDdbacvJ5In0sNbVrubJdPAZ/ZLY2WkW0oaFJktlFXh5NiA8jU+d7+ktqcz3DM6RKXOurE9SRr5qQMfKl6+f4IyzOMruw0Y92GvB12E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fromorbit.com; spf=pass smtp.mailfrom=fromorbit.com; dkim=pass (2048-bit key) header.d=fromorbit-com.20230601.gappssmtp.com header.i=@fromorbit-com.20230601.gappssmtp.com header.b=d2UOKT/d; arc=none smtp.client-ip=209.85.210.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fromorbit.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fromorbit.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=fromorbit-com.20230601.gappssmtp.com header.i=@fromorbit-com.20230601.gappssmtp.com header.b="d2UOKT/d" Received: by mail-pf1-f179.google.com with SMTP id d2e1a72fcca58-6e6adc557b6so4631319b3a.2 for ; Mon, 18 Mar 2024 17:17:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20230601.gappssmtp.com; s=20230601; t=1710807434; x=1711412234; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=38Mm0g44j6DzSxjcPXjDVW5ORPCUj/mMvG9NE8VE3sU=; b=d2UOKT/dlMZm0gV73SiuZl+vwym3ybpG8NLyvnTGdpcdzzm34fnNgTaN5h1n/xI3Nc gWv4q/Q0ZqHsMht1a3ZyzU52HCb6Ildu54q6+/6oSzousfOE4K34XDEK87Qu4lyW43tO rKZkji8oWw1xFIhiQ8pUsQMBeF0oK6XnYasiVzbxBNA/4XlMHy5hBVtPE9GOb+7YLVAV VsEhbdyrEM59o3QrGz4rBtG0vwppdOQJ/Pb46Wai4tzP7iUBk0ftmOIW4e8VL/yQLNsq 6A+XQDDYhSbaTRyMFaDyy1l9nt1c5M9O4hiRGPktGuUVy82Sc7yblQ2riOkFA9rK+YcR LaZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1710807434; x=1711412234; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=38Mm0g44j6DzSxjcPXjDVW5ORPCUj/mMvG9NE8VE3sU=; b=jh33ZUWOSY5pg5g7rpUZYwzdME7Z/w7w6xASouNIdsxnNHNmW1F+PTz1xs8hlDw7DH LXCnAoIj9ho8DhrkK/hxr8BU9IEd9ey7d1O8pRcw+CH9gSsxAsTLR5tnRcbchYVw9dg8 /S411+4N8Otj3rD5fOKxjLsDhF5XGGcfDpkBSMaZuD8u4AO8AMyQF7O3YF9NuyfD0QdH We6jCygB7CPB6yU60z/m3lwd7LVo3WMlm8tZ4QhjrI9gVxc+MYKi4EV8dra8N8b5Wb0t KBd/Ge9WSC58arVFBFKLZwzCoOB/+Wa6Xv6hPWcqod7enWzoVqlEl1JbNU+hTihgzg2r 3vdQ== X-Gm-Message-State: AOJu0YwTBbsIbLbv1+WvCQGyD4pFBqQsyRcjxVdGhwW55iZqom9MSrxV ngi5/1Np6T/PWAWjdERdpnHxDQbPyrbbEQ/He1wBue/W9/wBYhc9S9mHFhpedFN4aKmaHNuSLKe q X-Google-Smtp-Source: AGHT+IESfqRNAzXEfBNJCs+gOdaiFmuHsI182WyKMSVW/4pGE0q1MKAqMlbPeURaEl1qM+bxNs+hWQ== X-Received: by 2002:a05:6a20:7f8e:b0:1a1:4b57:4e9b with SMTP id d14-20020a056a207f8e00b001a14b574e9bmr16875157pzj.60.1710807433564; Mon, 18 Mar 2024 17:17:13 -0700 (PDT) Received: from dread.disaster.area (pa49-180-185-123.pa.nsw.optusnet.com.au. [49.180.185.123]) by smtp.gmail.com with ESMTPSA id r21-20020a635155000000b005dc98d9114bsm7730052pgl.43.2024.03.18.17.17.11 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Mar 2024 17:17:13 -0700 (PDT) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.96) (envelope-from ) id 1rmNAD-003pkl-2r for linux-xfs@vger.kernel.org; Tue, 19 Mar 2024 11:17:09 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.97) (envelope-from ) id 1rmNAD-0000000EONR-1VPx for linux-xfs@vger.kernel.org; Tue, 19 Mar 2024 11:17:09 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 2/4] xfs: prepare inode for i_gclist detection Date: Tue, 19 Mar 2024 11:15:58 +1100 Message-ID: <20240319001707.3430251-3-david@fromorbit.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240319001707.3430251-1-david@fromorbit.com> References: <20240319001707.3430251-1-david@fromorbit.com> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Dave Chinner We currently don't initialise the inode->i_gclist member because it it not necessary for a pure llist_add/llist_del_all producer- consumer usage pattern. However, for lazy removal from the inodegc list, we need to be able to determine if the inode is already on an inodegc list before we queue it. We can do this detection by using llist_on_list(), but this requires that we initialise the llist_node before we use it, and we re-initialise it when we remove it from the llist. Because we already serialise the inodegc list add with inode state changes under the ip->i_flags_lock, we can do the initialisation on list removal atomically with the state change. We can also do the check of whether the inode is already on a inodegc list inside the state change region on insert. This gives us the ability to use llist_on_list(ip->i_gclist) to determine if the inode needs to be queued for inactivation without having to depend on inode state flags. Signed-off-by: Dave Chinner Reviewed-by: Darrick J. Wong --- fs/xfs/xfs_icache.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 9a362964f656..559b8f71dc91 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -113,6 +113,7 @@ xfs_inode_alloc( spin_lock_init(&ip->i_ioend_lock); ip->i_next_unlinked = NULLAGINO; ip->i_prev_unlinked = 0; + init_llist_node(&ip->i_gclist); return ip; } @@ -1880,8 +1881,14 @@ xfs_inodegc_worker( llist_for_each_entry_safe(ip, n, node, i_gclist) { int error; - /* Switch state to inactivating. */ + /* + * Switch state to inactivating and remove the inode from the + * gclist. This allows the use of llist_on_list() in the queuing + * code to determine if the inode is already on an inodegc + * queue. + */ spin_lock(&ip->i_flags_lock); + init_llist_node(&ip->i_gclist); ip->i_flags |= XFS_INACTIVATING; ip->i_flags &= ~XFS_NEED_INACTIVE; spin_unlock(&ip->i_flags_lock); @@ -2082,13 +2089,21 @@ xfs_inodegc_queue( trace_xfs_inode_set_need_inactive(ip); /* - * Put the addition of the inode to the gc list under the + * The addition of the inode to the gc list is done under the * ip->i_flags_lock so that the state change and list addition are * atomic w.r.t. lookup operations under the ip->i_flags_lock. + * The removal is also done under the ip->i_flags_lock and so this + * allows us to safely use llist_on_list() here to determine if the + * inode is already queued on an inactivation queue. */ spin_lock(&ip->i_flags_lock); ip->i_flags |= XFS_NEED_INACTIVE; + if (llist_on_list(&ip->i_gclist)) { + spin_unlock(&ip->i_flags_lock); + return; + } + cpu_nr = get_cpu(); gc = this_cpu_ptr(mp->m_inodegc); llist_add(&ip->i_gclist, &gc->list); From patchwork Tue Mar 19 00:15:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13596045 Received: from mail-oi1-f176.google.com (mail-oi1-f176.google.com [209.85.167.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5FFD92F26 for ; Tue, 19 Mar 2024 00:17:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710807435; cv=none; b=n+IBnRa7rjsp2Ab3gL73lrxzTJHUQuLqsJIKey678c+Oqvp/KmGprhdhyezfcCPKkI0JjKxAaKEUCeFeOF6iU68z4dLUDv5Msy3cBtHhwn88dRDNzA3CZt7P+yx7QPumaS+VsaEKNaQ3gT9KfOX1vwISawiLjPsloqB51QBuDIQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710807435; c=relaxed/simple; bh=wHqVaMI4xy3U1hWGEDchFJ1oRdRvPb042b0MHihlk7E=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=O/B+EsZsBV/6fZ3Zv2ayKstQCrfjosIGiduqkcq0mtlX3xg7+HO1zWH29orO+FvIm7sWHLQ53Pftx6nJXtv8k6bqWHwuvB6yaNi4d+OyUYAckzvL2wV/Evet9R0NS3Dhn642UdbvLCnqe+TOSjKRp8nzizy+etCPJxkjXkl4OSw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fromorbit.com; spf=pass smtp.mailfrom=fromorbit.com; dkim=pass (2048-bit key) header.d=fromorbit-com.20230601.gappssmtp.com header.i=@fromorbit-com.20230601.gappssmtp.com header.b=bld66Bbf; arc=none smtp.client-ip=209.85.167.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fromorbit.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fromorbit.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=fromorbit-com.20230601.gappssmtp.com header.i=@fromorbit-com.20230601.gappssmtp.com header.b="bld66Bbf" Received: by mail-oi1-f176.google.com with SMTP id 5614622812f47-3bbbc6b4ed1so3821011b6e.2 for ; Mon, 18 Mar 2024 17:17:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20230601.gappssmtp.com; s=20230601; t=1710807432; x=1711412232; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=vYVju6Qwf9lti2OS9PrCiq/kBri8X1HE/SQhRJwCOeE=; b=bld66BbfSwNW3v5jC2zNREZw/FNUJIn88mPqWtDfMSbGKrp6bE+GvB5E1hqiV9zuV+ WHJRTdrQ0nBXIKuGJ6vZPaggKrPdTIYTFHWnxOS4P7hGksICTHxrzQFxLx7PhYPWtm6B F0zBSKIbodTMyT1+KbMr+0MKrhka6aCwMxsWLV6r2RZ4rZozHSVBY2HSfn5sTWOF7DrK 8+RWyjKju7ltAyY4S/eAM7T79hmnXOneYC1Zd7HJf4QEM5XGvwROmN0pMJ9U0pTxzXB5 TQUwVccp56uqDltiQzQ/Z3AuxBhVCBlnUNZaXUHxQC0PhIjbT/ooxhdmdxEVLdE+urR7 nUnw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1710807432; x=1711412232; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vYVju6Qwf9lti2OS9PrCiq/kBri8X1HE/SQhRJwCOeE=; b=tEJVjvT31O7P3KFNE3XmPm7me/VW1qgVeZzxdimqydBufMS8HzFHpGBORVcG+Ra6vJ Z6cUqrMvYVI6dHrGNKmI8UQ8kn2+9EbSLp2TfodtY7dVesVR2F/GRAqWsD/1beg53Bdy QlivDV5YwBKfFhTFrVSwdDHt2a5twhhw438+dGE9xzkUkqF8ACxjJ4Ox/D2f4fczKVSv rIYMgB5yIuwTWfyrm0fCWZJrJE3qjGdj/Yq+F2ysMxkzpmoun9ftiRJxKrOWwtBG6kRa mUMt3nDYXyZRkuPkEVlvumpNTvVglWOruX9Dg555w/+ZPFbePIQlfVawgrVRB+rmhinJ Hxig== X-Gm-Message-State: AOJu0Yzhp57RSCSf4V1tzO/NDlzHCnOp1w1xzrIJVrIbptC/ufHBSnhG Dk4pt4PObtnqTc9pyE/PwPjo+5Pbt6+0OIt8ETSqpahZ0w/lATdIl1xtsxKiVoLDGbiviGrdb8m C X-Google-Smtp-Source: AGHT+IH4Daa4k669sfTI/Mi/dmDnC8nkhWr4Gi0GFBIOJUmbfkfMmH99LZnT9T6BYUVcmrttv7LZ3g== X-Received: by 2002:a05:6808:3011:b0:3c2:400f:5302 with SMTP id ay17-20020a056808301100b003c2400f5302mr16974514oib.33.1710807432252; Mon, 18 Mar 2024 17:17:12 -0700 (PDT) Received: from dread.disaster.area (pa49-180-185-123.pa.nsw.optusnet.com.au. [49.180.185.123]) by smtp.gmail.com with ESMTPSA id b18-20020a630c12000000b005dca5caed40sm7700427pgl.81.2024.03.18.17.17.11 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Mar 2024 17:17:11 -0700 (PDT) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.96) (envelope-from ) id 1rmNAD-003pkq-2y for linux-xfs@vger.kernel.org; Tue, 19 Mar 2024 11:17:09 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.97) (envelope-from ) id 1rmNAD-0000000EONV-1eiL for linux-xfs@vger.kernel.org; Tue, 19 Mar 2024 11:17:09 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 3/4] xfs: allow lazy removal of inodes from the inodegc queues Date: Tue, 19 Mar 2024 11:15:59 +1100 Message-ID: <20240319001707.3430251-4-david@fromorbit.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240319001707.3430251-1-david@fromorbit.com> References: <20240319001707.3430251-1-david@fromorbit.com> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Dave Chinner To allow us to recycle inodes that are awaiting inactivation, we need to enable lazy removal of inodes from the list. Th elist is a lockless single linked variant, so we can't just remove inodes from the list at will. Instead, we can remove them lazily whenever inodegc runs by enabling the inodegc processing to determine whether inactivation needs to be done at processing time rather than queuing time. We've already modified the queuing code to only queue the inode if it isn't already queued, so here all we need to do is modify the queue processing to determine if inactivation needs to be done. Hence we introduce the behaviour that we can cancel inactivation processing simply by clearing the XFS_NEED_INACTIVE flag on the inode. Processing will check this flag and skip inactivation processing if it is not set. The flag is always set at queuing time, regardless of whether the inode is already one the queues or not. Hence if it is not set at processing time, it means that something has cancelled the inactivation and we should just remove it from the list and then leave it alone. Signed-off-by: Dave Chinner Reviewed-by: Darrick J. Wong --- fs/xfs/xfs_icache.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 559b8f71dc91..7359753b892b 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -1882,13 +1882,21 @@ xfs_inodegc_worker( int error; /* - * Switch state to inactivating and remove the inode from the - * gclist. This allows the use of llist_on_list() in the queuing - * code to determine if the inode is already on an inodegc - * queue. + * Remove the inode from the gclist and determine if it needs to + * be processed. The XFS_NEED_INACTIVE flag gets cleared if the + * inode is reactivated after queuing, but the list removal is + * lazy and left up to us. + * + * We always remove the inode from the list to allow the use of + * llist_on_list() in the queuing code to determine if the inode + * is already on an inodegc queue. */ spin_lock(&ip->i_flags_lock); init_llist_node(&ip->i_gclist); + if (!(ip->i_flags & XFS_NEED_INACTIVE)) { + spin_unlock(&ip->i_flags_lock); + continue; + } ip->i_flags |= XFS_INACTIVATING; ip->i_flags &= ~XFS_NEED_INACTIVE; spin_unlock(&ip->i_flags_lock); @@ -2160,7 +2168,6 @@ xfs_inode_mark_reclaimable( struct xfs_inode *ip) { struct xfs_mount *mp = ip->i_mount; - bool need_inactive; XFS_STATS_INC(mp, vn_reclaim); @@ -2169,8 +2176,23 @@ xfs_inode_mark_reclaimable( */ ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_ALL_IRECLAIM_FLAGS)); - need_inactive = xfs_inode_needs_inactive(ip); - if (need_inactive) { + /* + * If the inode is already queued for inactivation because it was + * re-activated and is now being reclaimed again (e.g. fs has been + * frozen for a while) we must ensure that the inode waits for inodegc + * to be run and removes it from the inodegc queue before it moves to + * the reclaimable state and gets freed. + * + * We don't care about races here. We can't race with a list addition + * because only one thread can be evicting the inode from the VFS cache, + * hence false negatives can't occur and we only need to worry about + * list removal races. If we get a false positive from a list removal + * race, then the inode goes through the inactive list whether it needs + * to or not. This will slow down reclaim of this inode slightly but + * should have no other side effects. + */ + if (llist_on_list(&ip->i_gclist) || + xfs_inode_needs_inactive(ip)) { xfs_inodegc_queue(ip); return; } From patchwork Tue Mar 19 00:16:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 13596049 Received: from mail-oo1-f41.google.com (mail-oo1-f41.google.com [209.85.161.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B98DC2F2C for ; Tue, 19 Mar 2024 00:17:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710807437; cv=none; b=fJZRUJ6hnXriVnkJmt8fqCbj3I4yIefNzzxAhLp3T01tkJMN3lLVzv1SWGPe+oW1nRxqfNuhOFDJNVySA/rlHDYouo01aMB0EdUkDEDNA500pPCN+nznH5kG5I0wGc99u1yuIFLaE9CA0kAM2x41uOnttC7u/dYdc2i5wym+NSU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710807437; c=relaxed/simple; bh=lxuYIAuL1kM9hp2A0Y+zXc4bmexOZVuPGoTV6tYyaL0=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=App5+1JLt+x4OvoYrQctpHeRPNoucrPB8KoixbY7pZuCRdfR9el3p3GekNpOai2w1DomI+df5Gil6reiJiqknwEvpWLQYablfHKYE/syWmVlHw/5Y7bOP3lTYS5HclSC82c6NKSQybbztKtP1t30aFg++yNtHt7MuG8fxe1idBE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fromorbit.com; spf=pass smtp.mailfrom=fromorbit.com; dkim=pass (2048-bit key) header.d=fromorbit-com.20230601.gappssmtp.com header.i=@fromorbit-com.20230601.gappssmtp.com header.b=De4pTrCT; arc=none smtp.client-ip=209.85.161.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fromorbit.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fromorbit.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=fromorbit-com.20230601.gappssmtp.com header.i=@fromorbit-com.20230601.gappssmtp.com header.b="De4pTrCT" Received: by mail-oo1-f41.google.com with SMTP id 006d021491bc7-5a0932aa9ecso1913903eaf.3 for ; Mon, 18 Mar 2024 17:17:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20230601.gappssmtp.com; s=20230601; t=1710807433; x=1711412233; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=DpRkxRNrSAm/FKzDVegPZPmXRFDr56kqZzAnl/Q5SLs=; b=De4pTrCTOZMGajY4Jg4sQeXiLrvSiOJIpIj1cwoYJ68KhGmwc0IkABjVh2Nd0tyrDe Mabsr4ulEm/S/k6+dn7gQJ0OI6a1BFb5fWj2CZMP1TgrFqxqgyC7JlqtriwGGL+lqzqE KVijVmqM2ozz4s2gCtLK/pZJEVGafkfA4HSlEmYs2DAKVLq3c1PjBTGAH1KfufLZfSsN Ky+wNz0wMssGNuAt63mikyi/a4EcEPaRFGKzQTMZUUjUWSz/V2EJ9X5YjTXZ7n1AFCRE ZytqUDla9qkAN4673H2yoASFTJXk+AwVIZnz0Ap4u0H+9CIM5XCP5ivnz8QsKDbvePTP 5QMA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1710807433; x=1711412233; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=DpRkxRNrSAm/FKzDVegPZPmXRFDr56kqZzAnl/Q5SLs=; b=RNQJ7Fg1RZm0WbZGPMTO7Po3L/TW7RIAnO9p/vXJ6V9R+d7i76zLQfjuyOnHB9Js+1 5YXev0mjlaGm2txP/Q5PNnWYYcuJLZft4Rli/UDmm0V8tWFEQdfdjMaCHkcscRStE3pm OWvoJ+SlD+0S2CN71bFL+GMzZh72VJx3kEpNHz/lQyXnV/C23srF/1/ZXq886TQUzNr3 cEW3g4B8lfKaVqyjHc5Vjd07WkZPMq8LleXn4Ns03+pjujFDJPmxGN/kCyu51DkGBCyh NsYD0g75xF7t3P284dme71uTmQoEJjoVBnQqbEaK/jpqyprtYO2OEGKSB4/q+CU7cj2L lX5w== X-Gm-Message-State: AOJu0YzLsxVqHqWPgOPhvav/+YEE0Hr+C0HEdYq0URBQh6f9oyO1zgoS Equ8Vm+KUAj/aeSC1hbhyhg+xGC37bSwJdnQBe/KpZYdVfUTxVGWvPmR31G2ioFUI7k2i+f1kY+ 1 X-Google-Smtp-Source: AGHT+IHOP4a3BifE6dr1TwkUOGQ2KhjQxlzP8TPA/X9gY+shKv47GYtyi2f4zCoufvC3PHUWQ2qF8Q== X-Received: by 2002:a05:6870:2046:b0:21e:7156:a69f with SMTP id l6-20020a056870204600b0021e7156a69fmr14900371oad.42.1710807432665; Mon, 18 Mar 2024 17:17:12 -0700 (PDT) Received: from dread.disaster.area (pa49-180-185-123.pa.nsw.optusnet.com.au. [49.180.185.123]) by smtp.gmail.com with ESMTPSA id a26-20020a62e21a000000b006e6ae26625asm8443304pfi.68.2024.03.18.17.17.11 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Mar 2024 17:17:11 -0700 (PDT) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.96) (envelope-from ) id 1rmNAD-003pkt-34 for linux-xfs@vger.kernel.org; Tue, 19 Mar 2024 11:17:09 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.97) (envelope-from ) id 1rmNAD-0000000EONZ-1njG for linux-xfs@vger.kernel.org; Tue, 19 Mar 2024 11:17:09 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 4/4] xfs: reactivate XFS_NEED_INACTIVE inodes from xfs_iget Date: Tue, 19 Mar 2024 11:16:00 +1100 Message-ID: <20240319001707.3430251-5-david@fromorbit.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240319001707.3430251-1-david@fromorbit.com> References: <20240319001707.3430251-1-david@fromorbit.com> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Dave Chinner When xfs_iget() finds an inode that is queued for inactivation, it issues an inodegc flush to trigger the inactivation work and then retries the lookup. However, when the filesystem is frozen, inodegc is turned off and the flush does nothing and does not block. This results in lookup spinning on NEED_INACTIVE inodes and being unable to make progress until the filesystem is thawed. This is less than ideal. The only reason we can't immediately recycle the inode is that it queued on a lockless list we can't remove it from. However, those lists now support lazy removal, and so we can now modify the lookup code to reactivate inode queued for inactivation. The process is identical to how we recycle reclaimable inodes from xfs_iget(), so this ends up being a relatively simple change to make. Signed-off-by: Dave Chinner Reviewed-by: Darrick J. Wong --- fs/xfs/xfs_icache.c | 110 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 87 insertions(+), 23 deletions(-) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 7359753b892b..56de3e843df2 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -63,6 +63,8 @@ static int xfs_icwalk_ag(struct xfs_perag *pag, XFS_ICWALK_FLAG_RECLAIM_SICK | \ XFS_ICWALK_FLAG_UNION) +static void xfs_inodegc_queue(struct xfs_inode *ip); + /* * Allocate and initialise an xfs_inode. */ @@ -325,6 +327,7 @@ xfs_reinit_inode( return error; } + /* * Carefully nudge an inode whose VFS state has been torn down back into a * usable state. Drops the i_flags_lock and the rcu read lock. @@ -388,7 +391,82 @@ xfs_iget_recycle( inode->i_state = I_NEW; spin_unlock(&ip->i_flags_lock); spin_unlock(&pag->pag_ici_lock); + XFS_STATS_INC(mp, xs_ig_frecycle); + return 0; +} +static int +xfs_iget_reactivate( + struct xfs_perag *pag, + struct xfs_inode *ip) __releases(&ip->i_flags_lock) +{ + struct xfs_mount *mp = ip->i_mount; + struct inode *inode = VFS_I(ip); + int error; + + trace_xfs_iget_recycle(ip); + + /* + * If the inode has been unlinked, then the lookup must not find it + * until inactivation has actually freed the inode. + */ + if (VFS_I(ip)->i_nlink == 0) { + spin_unlock(&ip->i_flags_lock); + rcu_read_unlock(); + return -ENOENT; + } + + /* + * Take the ILOCK here to serialise against lookup races with putting + * the inode back on the inodegc queue during error handling. + */ + if (!xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) + return -EAGAIN; + + /* + * Move the state to inactivating so both inactivation and racing + * lookups will skip over this inode until we've finished reactivating + * it and can return it to the XFS_INEW state. + */ + ip->i_flags &= ~XFS_NEED_INACTIVE; + ip->i_flags |= XFS_INACTIVATING; + spin_unlock(&ip->i_flags_lock); + rcu_read_unlock(); + + ASSERT(!rwsem_is_locked(&inode->i_rwsem)); + error = xfs_reinit_inode(mp, inode); + if (error) { + /* + * Well, that sucks. Put the inode back on the inactive queue. + * Do this while still under the ILOCK so that we can set the + * NEED_INACTIVE flag and clear the INACTIVATING flag an not + * have another lookup race with us before we've finished + * putting the inode back on the inodegc queue. + */ + spin_unlock(&ip->i_flags_lock); + ip->i_flags |= XFS_NEED_INACTIVE; + ip->i_flags &= ~XFS_INACTIVATING; + spin_unlock(&ip->i_flags_lock); + + xfs_inodegc_queue(ip); + xfs_iunlock(ip, XFS_ILOCK_EXCL); + + trace_xfs_iget_recycle_fail(ip); + return error; + } + xfs_iunlock(ip, XFS_ILOCK_EXCL); + + /* + * Reset the inode state to new so that xfs_iget() will complete + * the required remaining inode initialisation before it returns the + * inode to the caller. + */ + spin_lock(&ip->i_flags_lock); + ip->i_flags &= ~XFS_IRECLAIM_RESET_FLAGS; + ip->i_flags |= XFS_INEW; + inode->i_state = I_NEW; + spin_unlock(&ip->i_flags_lock); + XFS_STATS_INC(mp, xs_ig_frecycle); return 0; } @@ -526,15 +604,6 @@ xfs_iget_cache_hit( if (ip->i_flags & (XFS_INEW | XFS_IRECLAIM | XFS_INACTIVATING)) goto out_skip; - if (ip->i_flags & XFS_NEED_INACTIVE) { - /* Unlinked inodes cannot be re-grabbed. */ - if (VFS_I(ip)->i_nlink == 0) { - error = -ENOENT; - goto out_error; - } - goto out_inodegc_flush; - } - /* * Check the inode free state is valid. This also detects lookup * racing with unlinks. @@ -545,11 +614,18 @@ xfs_iget_cache_hit( /* Skip inodes that have no vfs state. */ if ((flags & XFS_IGET_INCORE) && - (ip->i_flags & XFS_IRECLAIMABLE)) + (ip->i_flags & (XFS_IRECLAIMABLE | XFS_NEED_INACTIVE))) goto out_skip; /* The inode fits the selection criteria; process it. */ - if (ip->i_flags & XFS_IRECLAIMABLE) { + if (ip->i_flags & XFS_NEED_INACTIVE) { + /* Drops i_flags_lock and RCU read lock. */ + error = xfs_iget_reactivate(pag, ip); + if (error == -EAGAIN) + goto out_skip; + if (error) + return error; + } else if (ip->i_flags & XFS_IRECLAIMABLE) { /* Drops i_flags_lock and RCU read lock. */ error = xfs_iget_recycle(pag, ip); if (error == -EAGAIN) @@ -578,23 +654,11 @@ xfs_iget_cache_hit( out_skip: trace_xfs_iget_skip(ip); - XFS_STATS_INC(mp, xs_ig_frecycle); error = -EAGAIN; out_error: spin_unlock(&ip->i_flags_lock); rcu_read_unlock(); return error; - -out_inodegc_flush: - spin_unlock(&ip->i_flags_lock); - rcu_read_unlock(); - /* - * Do not wait for the workers, because the caller could hold an AGI - * buffer lock. We're just going to sleep in a loop anyway. - */ - if (xfs_is_inodegc_enabled(mp)) - xfs_inodegc_queue_all(mp); - return -EAGAIN; } static int