#include "zdata.h"
 #include "compress.h"
 #include <linux/prefetch.h>
+#include <linux/psi.h>
 
 #include <trace/events/erofs.h>
 
        struct block_device *last_bdev;
        unsigned int nr_bios = 0;
        struct bio *bio = NULL;
+       /* initialize to 1 to make skip psi_memstall_leave unless needed */
+       unsigned long pflags = 1;
 
        bi_private = jobqueueset_init(sb, q, fgq, force_fg);
        qtail[JQ_BYPASS] = &q[JQ_BYPASS]->head;
                        if (bio && (cur != last_index + 1 ||
                                    last_bdev != mdev.m_bdev)) {
 submit_bio_retry:
+                               if (!pflags)
+                                       psi_memstall_leave(&pflags);
                                submit_bio(bio);
                                bio = NULL;
                        }
 
+                       if (unlikely(PageWorkingset(page)))
+                               psi_memstall_enter(&pflags);
+
                        if (!bio) {
                                bio = bio_alloc(mdev.m_bdev, BIO_MAX_VECS,
                                                REQ_OP_READ, GFP_NOIO);
                        move_to_bypass_jobqueue(pcl, qtail, owned_head);
        } while (owned_head != Z_EROFS_PCLUSTER_TAIL);
 
-       if (bio)
+       if (bio) {
+               if (!pflags)
+                       psi_memstall_leave(&pflags);
                submit_bio(bio);
+       }
 
        /*
         * although background is preferred, no one is pending for submission.