All of lore.kernel.org
 help / color / mirror / Atom feed
* [STABLE-PATCH] xfs: Correctly invert xfs_buftarg LRU isolation logic
@ 2019-10-31 15:32 Alex Lyakas
  2019-11-04 11:02 ` Greg KH
  0 siblings, 1 reply; 2+ messages in thread
From: Alex Lyakas @ 2019-10-31 15:32 UTC (permalink / raw)
  To: linux-xfs, stable; +Cc: vbendel, bfoster, hch, darrick.wong, Alex Lyakas

From: Vratislav Bendel <vbendel@redhat.com>

[upstream commit 19957a181608d25c8f4136652d0ea00b3738972d]

Due to an inverted logic mistake in xfs_buftarg_isolate()
the xfs_buffers with zero b_lru_ref will take another trip
around LRU, while isolating buffers with non-zero b_lru_ref.

Additionally those isolated buffers end up right back on the LRU
once they are released, because b_lru_ref remains elevated.

Fix that circuitous route by leaving them on the LRU
as originally intended.

[Additional description for the issue]

Due to this issue, buffers will spend one cycle less in
the LRU than intended. If we initialize b_lru_ref to X, we intend the
buffer to survive X shrinker calls, and on the X+1'th call to be taken
off the LRU (and maybe freed). But with this issue, the buffer will be
taken off the LRU and immediately re-added back. But this will happen
X-1 times, because on the X'th time the b_lru_ref will be 0, and the
buffer will not be re-added to the LRU. So the buffer will survive X-1
shrinker calls and not X as intended.

Furthermore, if somehow we end up with the buffer sitting on the LRU
and having b_lru_ref==0, this buffer will never be taken off the LRU,
due to the bug. Not sure that this can happen, because by default
b_lru_ref is set to 1.

This issue existed since the introduction of lru in XFS buffer cache
in commit
"430cbeb86fdcbbdabea7d4aa65307de8de425350 xfs: add a lru to the XFS buffer cache".

However, the integration with the "list_lru" insfrastructure was done in kernel 3.12,
in commit
"e80dfa19976b884db1ac2bc5d7d6ca0a4027bd1c xfs: convert buftarg LRU to generic code"

Therefore this patch is relevant for all kernels from 3.12 to 4.15
(upstream fix was made in 4.16).

Signed-off-by: Alex Lyakas <alex@zadara.com>
Signed-off-by: Vratislav Bendel <vbendel@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
(cherry picked from commit 19957a181608d25c8f4136652d0ea00b3738972d)
---
 fs/xfs/xfs_buf.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index 16f93d7..e4a6239 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -1702,7 +1702,7 @@ struct xfs_buf *
 	 * zero. If the value is already zero, we need to reclaim the
 	 * buffer, otherwise it gets another trip through the LRU.
 	 */
-	if (!atomic_add_unless(&bp->b_lru_ref, -1, 0)) {
+	if (atomic_add_unless(&bp->b_lru_ref, -1, 0)) {
 		spin_unlock(&bp->b_lock);
 		return LRU_ROTATE;
 	}
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [STABLE-PATCH] xfs: Correctly invert xfs_buftarg LRU isolation logic
  2019-10-31 15:32 [STABLE-PATCH] xfs: Correctly invert xfs_buftarg LRU isolation logic Alex Lyakas
@ 2019-11-04 11:02 ` Greg KH
  0 siblings, 0 replies; 2+ messages in thread
From: Greg KH @ 2019-11-04 11:02 UTC (permalink / raw)
  To: Alex Lyakas; +Cc: linux-xfs, stable, vbendel, bfoster, hch, darrick.wong

On Thu, Oct 31, 2019 at 05:32:55PM +0200, Alex Lyakas wrote:
> From: Vratislav Bendel <vbendel@redhat.com>
> 
> [upstream commit 19957a181608d25c8f4136652d0ea00b3738972d]
> 
> Due to an inverted logic mistake in xfs_buftarg_isolate()
> the xfs_buffers with zero b_lru_ref will take another trip
> around LRU, while isolating buffers with non-zero b_lru_ref.
> 
> Additionally those isolated buffers end up right back on the LRU
> once they are released, because b_lru_ref remains elevated.
> 
> Fix that circuitous route by leaving them on the LRU
> as originally intended.
> 
> [Additional description for the issue]
> 
> Due to this issue, buffers will spend one cycle less in
> the LRU than intended. If we initialize b_lru_ref to X, we intend the
> buffer to survive X shrinker calls, and on the X+1'th call to be taken
> off the LRU (and maybe freed). But with this issue, the buffer will be
> taken off the LRU and immediately re-added back. But this will happen
> X-1 times, because on the X'th time the b_lru_ref will be 0, and the
> buffer will not be re-added to the LRU. So the buffer will survive X-1
> shrinker calls and not X as intended.
> 
> Furthermore, if somehow we end up with the buffer sitting on the LRU
> and having b_lru_ref==0, this buffer will never be taken off the LRU,
> due to the bug. Not sure that this can happen, because by default
> b_lru_ref is set to 1.
> 
> This issue existed since the introduction of lru in XFS buffer cache
> in commit
> "430cbeb86fdcbbdabea7d4aa65307de8de425350 xfs: add a lru to the XFS buffer cache".
> 
> However, the integration with the "list_lru" insfrastructure was done in kernel 3.12,
> in commit
> "e80dfa19976b884db1ac2bc5d7d6ca0a4027bd1c xfs: convert buftarg LRU to generic code"
> 
> Therefore this patch is relevant for all kernels from 3.12 to 4.15
> (upstream fix was made in 4.16).
> 
> Signed-off-by: Alex Lyakas <alex@zadara.com>
> Signed-off-by: Vratislav Bendel <vbendel@redhat.com>
> Reviewed-by: Brian Foster <bfoster@redhat.com>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> (cherry picked from commit 19957a181608d25c8f4136652d0ea00b3738972d)
> ---
>  fs/xfs/xfs_buf.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Now queued up, thanks.

greg k-h

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-11-04 11:02 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-31 15:32 [STABLE-PATCH] xfs: Correctly invert xfs_buftarg LRU isolation logic Alex Lyakas
2019-11-04 11:02 ` Greg KH

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.