<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/linux.git/fs/btrfs/compression.h, branch linux-7.1.y</title>
<subtitle>Linux kernel stable tree (mirror)</subtitle>
<id>https://git.radix-linux.su/kernel/linux.git/atom?h=linux-7.1.y</id>
<link rel='self' href='https://git.radix-linux.su/kernel/linux.git/atom?h=linux-7.1.y'/>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/'/>
<updated>2026-04-07T16:56:08+00:00</updated>
<entry>
<title>btrfs: prevent direct reclaim during compressed readahead</title>
<updated>2026-04-07T16:56:08+00:00</updated>
<author>
<name>JP Kobryn (Meta)</name>
<email>jp.kobryn@linux.dev</email>
</author>
<published>2026-03-28T21:46:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=7ae37b2c94ed30bfefece2b68c727a4474206718'/>
<id>urn:sha1:7ae37b2c94ed30bfefece2b68c727a4474206718</id>
<content type='text'>
Under memory pressure, direct reclaim can kick in during compressed
readahead. This puts the associated task into D-state. Then shrink_lruvec()
disables interrupts when acquiring the LRU lock. Under heavy pressure,
we've observed reclaim can run long enough that the CPU becomes prone to
CSD lock stalls since it cannot service incoming IPIs. Although the CSD
lock stalls are the worst case scenario, we have found many more subtle
occurrences of this latency on the order of seconds, over a minute in some
cases.

Prevent direct reclaim during compressed readahead. This is achieved by
using different GFP flags at key points when the bio is marked for
readahead.

There are two functions that allocate during compressed readahead:
btrfs_alloc_compr_folio() and add_ra_bio_pages(). Both currently use
GFP_NOFS which includes __GFP_DIRECT_RECLAIM.

For the internal API call btrfs_alloc_compr_folio(), the signature changes
to accept an additional gfp_t parameter. At the readahead call site, it
gets flags similar to GFP_NOFS but stripped of __GFP_DIRECT_RECLAIM.
__GFP_NOWARN is added since these allocations are allowed to fail. Demand
reads still use full GFP_NOFS and will enter reclaim if needed. All other
existing call sites of btrfs_alloc_compr_folio() now explicitly pass
GFP_NOFS to retain their current behavior.

add_ra_bio_pages() gains a bool parameter which allows callers to specify
if they want to allow direct reclaim or not. In either case, the
__GFP_NOWARN flag was added unconditionally since the allocations are
speculative.

There has been some previous work done on calling add_ra_bio_pages() [0].
This patch is complementary: where that patch reduces call frequency, this
patch reduces the latency associated with those calls.

[0] https://lore.kernel.org/linux-btrfs/656838ec1232314a2657716e59f4f15a8eadba64.1751492111.git.boris@bur.io/

Reviewed-by: Mark Harmstone &lt;mark@harmstone.com&gt;
Reviewed-by: Qu Wenruo &lt;wqu@suse.com&gt;
Signed-off-by: JP Kobryn (Meta) &lt;jp.kobryn@linux.dev&gt;
Reviewed-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
</content>
</entry>
<entry>
<title>btrfs: extract the max compression chunk size into a macro</title>
<updated>2026-04-07T16:56:00+00:00</updated>
<author>
<name>Qu Wenruo</name>
<email>wqu@suse.com</email>
</author>
<published>2026-02-27T02:45:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=cab4c8b594e23649591317c5f0606ea6a8a27236'/>
<id>urn:sha1:cab4c8b594e23649591317c5f0606ea6a8a27236</id>
<content type='text'>
We have two locations using open-coded 512K size, as the async chunk
size.

For compression we have not only the max size a compressed extent can
represent (128K), but also how large an async chunk can be (512K).

Although we have a macro for the maximum compressed extent size, we do
not have any macro for the async chunk size.

Add such a macro and replace the two open-coded SZ_512K.

Reviewed-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Signed-off-by: Qu Wenruo &lt;wqu@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
</content>
</entry>
<entry>
<title>btrfs: reduce the size of compressed_bio</title>
<updated>2026-04-07T16:55:59+00:00</updated>
<author>
<name>Qu Wenruo</name>
<email>wqu@suse.com</email>
</author>
<published>2026-02-20T03:41:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=b05342fe47b9828d004baf2b24cccd0479de54a5'/>
<id>urn:sha1:b05342fe47b9828d004baf2b24cccd0479de54a5</id>
<content type='text'>
The member compressed_bio::compressed_len can be replaced by the bio
size, as we always submit the full compressed data without any partial
read/write.

Furthermore we already have enough ASSERT()s making sure the bio size
matches the ordered extent or the extent map.

This saves 8 bytes from compressed_bio:

Before:

struct compressed_bio {
        u64                        start;                /*     0     8 */
        unsigned int               len;                  /*     8     4 */
        unsigned int               compressed_len;       /*    12     4 */
        u8                         compress_type;        /*    16     1 */
        bool                       writeback;            /*    17     1 */

        /* XXX 6 bytes hole, try to pack */

        struct btrfs_bio *         orig_bbio;            /*    24     8 */
        struct btrfs_bio           bbio __attribute__((__aligned__(8))); /*    32   304 */

        /* XXX last struct has 1 bit hole */

        /* size: 336, cachelines: 6, members: 7 */
        /* sum members: 330, holes: 1, sum holes: 6 */
        /* member types with bit holes: 1, total: 1 */
        /* forced alignments: 1 */
        /* last cacheline: 16 bytes */
} __attribute__((__aligned__(8)));

After:

 struct compressed_bio {
        u64                        start;                /*     0     8 */
        unsigned int               len;                  /*     8     4 */
        u8                         compress_type;        /*    12     1 */
        bool                       writeback;            /*    13     1 */

        /* XXX 2 bytes hole, try to pack */

        struct btrfs_bio *         orig_bbio;            /*    16     8 */
        struct btrfs_bio           bbio __attribute__((__aligned__(8))); /*    24   304 */

        /* XXX last struct has 1 bit hole */

        /* size: 328, cachelines: 6, members: 6 */
        /* sum members: 326, holes: 1, sum holes: 2 */
        /* member types with bit holes: 1, total: 1 */
        /* forced alignments: 1 */
        /* last cacheline: 8 bytes */
} __attribute__((__aligned__(8)));

Signed-off-by: Qu Wenruo &lt;wqu@suse.com&gt;
Reviewed-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
</content>
</entry>
<entry>
<title>btrfs: get rid of compressed_bio::compressed_folios[]</title>
<updated>2026-02-03T06:59:07+00:00</updated>
<author>
<name>Qu Wenruo</name>
<email>wqu@suse.com</email>
</author>
<published>2026-01-29T03:23:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=161ab30da6899f31f8128cec7c833e99fa4d06d2'/>
<id>urn:sha1:161ab30da6899f31f8128cec7c833e99fa4d06d2</id>
<content type='text'>
Now there is no one utilizing that member, we can safely remove it along
with compressed_bio::nr_folios member. The size is reduced from 352 to
336 bytes on x86_64.

Reviewed-by: Boris Burkov &lt;boris@bur.io&gt;
Signed-off-by: Qu Wenruo &lt;wqu@suse.com&gt;
Reviewed-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
</content>
</entry>
<entry>
<title>btrfs: get rid of compressed_folios[] usage for encoded writes</title>
<updated>2026-02-03T06:59:07+00:00</updated>
<author>
<name>Qu Wenruo</name>
<email>wqu@suse.com</email>
</author>
<published>2026-01-29T03:23:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=e1bc83f8b157689e5de4f651b6fbb9dcdccd33c1'/>
<id>urn:sha1:e1bc83f8b157689e5de4f651b6fbb9dcdccd33c1</id>
<content type='text'>
Currently only encoded writes utilized btrfs_submit_compressed_write(),
which utilized compressed_bio::compressed_folios[] array.

Change the only call site to call the new helper,
btrfs_alloc_compressed_write(), to allocate a compressed bio, then queue
needed folios into that bio, and finally call
btrfs_submit_compressed_write() to submit the compressed bio.

This change has one hidden benefit, previously we used
btrfs_alloc_folio_array() for the folios of
btrfs_submit_compressed_read(), which doesn't utilize the compression
page pool for bs == ps cases.

Now we call btrfs_alloc_compr_folio() which will benefit from the page pool.

The other obvious benefit is that we no longer need to allocate an array
to hold all those folios, thus one less error path.

Reviewed-by: Boris Burkov &lt;boris@bur.io&gt;
Signed-off-by: Qu Wenruo &lt;wqu@suse.com&gt;
Reviewed-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
</content>
</entry>
<entry>
<title>btrfs: remove the old btrfs_compress_folios() infrastructure</title>
<updated>2026-02-03T06:59:07+00:00</updated>
<author>
<name>Qu Wenruo</name>
<email>wqu@suse.com</email>
</author>
<published>2026-01-29T03:23:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=26902be0cd0997b34ef13593e35ef3501a3c70b5'/>
<id>urn:sha1:26902be0cd0997b34ef13593e35ef3501a3c70b5</id>
<content type='text'>
Since it's been replaced by btrfs_compress_bio(), remove all involved
functions.

Reviewed-by: Boris Burkov &lt;boris@bur.io&gt;
Signed-off-by: Qu Wenruo &lt;wqu@suse.com&gt;
Reviewed-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
</content>
</entry>
<entry>
<title>btrfs: introduce btrfs_compress_bio() helper</title>
<updated>2026-02-03T06:59:06+00:00</updated>
<author>
<name>Qu Wenruo</name>
<email>wqu@suse.com</email>
</author>
<published>2026-01-29T03:23:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=c51173271d528561706a2ce3bacd4f6232f4375b'/>
<id>urn:sha1:c51173271d528561706a2ce3bacd4f6232f4375b</id>
<content type='text'>
The helper will allocate a new compressed_bio, do the compression, and
return it to the caller.

This greatly simplifies the compression path, as we no longer need to
allocate a folio array thus no extra error path, furthermore the
compressed bio structure can be utilized for submission with very minor
modifications (like rounding up the bi_size and populate the bi_sector).

Reviewed-by: Boris Burkov &lt;boris@bur.io&gt;
Signed-off-by: Qu Wenruo &lt;wqu@suse.com&gt;
Reviewed-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
</content>
</entry>
<entry>
<title>btrfs: zlib: introduce zlib_compress_bio() helper</title>
<updated>2026-02-03T06:59:06+00:00</updated>
<author>
<name>Qu Wenruo</name>
<email>wqu@suse.com</email>
</author>
<published>2026-01-29T03:23:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=3d74a7556fbab89a3e78f514cf39d3413b9963d1'/>
<id>urn:sha1:3d74a7556fbab89a3e78f514cf39d3413b9963d1</id>
<content type='text'>
The new helper has the following enhancements against the existing
zlib_compress_folios()

- Much smaller parameter list

  No more shared IN/OUT members, no need to pre-allocate a
  compressed_folios[] array.

  Just a workspace and compressed_bio pointer, everything we need can be
  extracted from that @cb pointer.

- Ready-to-be-submitted compressed bio

  Although the caller still needs to do some common works like
  rounding up and zeroing the tailing part of the last fs block.

Reviewed-by: Boris Burkov &lt;boris@bur.io&gt;
Signed-off-by: Qu Wenruo &lt;wqu@suse.com&gt;
Reviewed-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
</content>
</entry>
<entry>
<title>btrfs: zstd: introduce zstd_compress_bio() helper</title>
<updated>2026-02-03T06:59:06+00:00</updated>
<author>
<name>Qu Wenruo</name>
<email>wqu@suse.com</email>
</author>
<published>2026-01-29T03:23:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=bba959655ac5665f3ad2fc244c98da48d2ae4c17'/>
<id>urn:sha1:bba959655ac5665f3ad2fc244c98da48d2ae4c17</id>
<content type='text'>
The new helper has the following enhancements against the existing
zstd_compress_folios()

- Much smaller parameter list

  No more shared IN/OUT members, no need to pre-allocate a
  compressed_folios[] array.

  Just a workspace and compressed_bio pointer, everything we need can be
  extracted from that @cb pointer.

- Ready-to-be-submitted compressed bio

  Although the caller still needs to do some common works like
  rounding up and zeroing the tailing part of the last fs block.

Overall the workflow is the same as zstd_compress_folios(), but with
some minor changes:

- @start/@len is now constant
  For the current input file offset, use @start + @tot_in instead.

  The original change of @start and @len makes it pretty hard to know
  what value we're really comparing to.

- No more @cur_len
  It's only utilized when switching input buffer.
  Directly use btrfs_calc_input_length() instead.

Reviewed-by: Boris Burkov &lt;boris@bur.io&gt;
Signed-off-by: Qu Wenruo &lt;wqu@suse.com&gt;
Reviewed-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
</content>
</entry>
<entry>
<title>btrfs: lzo: introduce lzo_compress_bio() helper</title>
<updated>2026-02-03T06:59:06+00:00</updated>
<author>
<name>Qu Wenruo</name>
<email>wqu@suse.com</email>
</author>
<published>2026-01-29T03:23:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=3be8a788eed3f7f30f32d69f50d648ba2c458f21'/>
<id>urn:sha1:3be8a788eed3f7f30f32d69f50d648ba2c458f21</id>
<content type='text'>
The new helper has the following enhancements against the existing
lzo_compress_folios()

- Much smaller parameter list

  No more shared IN/OUT members, no need to pre-allocate a
  compressed_folios[] array.

  Just a workspace list header and a compressed_bio pointer.

  Everything else can be fetched from that @cb pointer.

- Read-to-be-submitted compressed bio

  Although the caller still needs to do some common works like
  rounding up and zeroing the tailing part of the last fs block.

Some workloads are specific to lZO that is not needed with other
multi-run compression interfaces:

- Need to write a LZO header or segment header

  Use the new write_and_queue_folio() helper to do the bio_add_folio()
  call and folio switching.

- Need to update the LZO header after compression is done

  Use bio_first_folio_all() to grab the first folio and update the header.

- Extra corner case of error handling

  This can happen when we have queued part of a folio and hit an error.
  In that case those folios will be released by the bio.
  Thus we can only release the folio that has no queued part.

Reviewed-by: Boris Burkov &lt;boris@bur.io&gt;
Signed-off-by: Qu Wenruo &lt;wqu@suse.com&gt;
Reviewed-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
</content>
</entry>
</feed>
