* [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.