While static batching successfully overlaps I/O and compute, different
compression algorithms exhibit vastly different scheduling thresholds.
Extremely fast algorithms like LZ4 require large batches (e.g., 32
pclusters) to effectively hide the synchronization overhead of the
thread pool.

Conversely, applying this large batch size to compute-heavy algorithms
like LZMA or ZSTD causes memory bloat and thread starvation, as the
main thread spends too much time reading and accumulating memory before
waking up the background workers.

This patch modifies the workqueue submission logic in
z_erofs_read_one_data to scale the batch size based on the algorithm
format. LZ4 is permitted to utilize the Z_EROFS_PCLUSTER_MAX_BATCH_SIZE,
while other heavier algorithms trigger workqueue submission at a much
lower threshold (8 pclusters) to ensure a steady pipeline of work and a
bounded memory footprint.

Signed-off-by: Nithurshen <[email protected]>
---
 include/erofs/internal.h | 2 +-
 lib/data.c               | 7 +++++--
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index b4db2e5..94f14da 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -64,7 +64,7 @@ struct erofs_buf {
 #define erofs_pos(sbi, nr)      ((erofs_off_t)(nr) << (sbi)->blkszbits)
 #define BLK_ROUND_UP(sbi, addr)        \
        (roundup(addr, erofs_blksiz(sbi)) >> (sbi)->blkszbits)
-#define Z_EROFS_PCLUSTER_BATCH_SIZE 32
+#define Z_EROFS_PCLUSTER_MAX_BATCH_SIZE 32
 
 struct erofs_buffer_head;
 struct erofs_bufmgr;
diff --git a/lib/data.c b/lib/data.c
index de05c6f..e9d2218 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -25,7 +25,7 @@ struct z_erofs_decompress_item {
 struct z_erofs_decompress_task {
        struct erofs_work work;
        struct z_erofs_read_ctx *ctx;
-       struct z_erofs_decompress_item items[Z_EROFS_PCLUSTER_BATCH_SIZE];
+       struct z_erofs_decompress_item items[Z_EROFS_PCLUSTER_MAX_BATCH_SIZE];
        unsigned int nr_reqs;
 };
 
@@ -409,7 +409,10 @@ int z_erofs_read_one_data(struct erofs_inode *inode,
        item->out_offset = out_offset;
        item->out_length = length;
 
-       if (task->nr_reqs == Z_EROFS_PCLUSTER_BATCH_SIZE) {
+       int batch_limit = (map->m_algorithmformat == Z_EROFS_COMPRESSION_LZ4) ? 
+                                               Z_EROFS_PCLUSTER_MAX_BATCH_SIZE 
: 8;
+
+       if (task->nr_reqs >= batch_limit) {
                z_erofs_read_ctx_enqueue(ctx);
        }
        return 0;
-- 
2.52.0


Reply via email to