bio->bi_iter.bi_size += len;
        bio->bi_vcnt++;
+
+       if (!bio_flagged(bio, BIO_WORKINGSET) && unlikely(PageWorkingset(page)))
+               bio_set_flag(bio, BIO_WORKINGSET);
 }
 EXPORT_SYMBOL_GPL(__bio_add_page);
 
 
 #include <linux/blk-cgroup.h>
 #include <linux/debugfs.h>
 #include <linux/bpf.h>
+#include <linux/psi.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/block.h>
  */
 blk_qc_t submit_bio(struct bio *bio)
 {
+       bool workingset_read = false;
+       unsigned long pflags;
+       blk_qc_t ret;
+
        if (blkcg_punt_bio_submit(bio))
                return BLK_QC_T_NONE;
 
                if (op_is_write(bio_op(bio))) {
                        count_vm_events(PGPGOUT, count);
                } else {
+                       if (bio_flagged(bio, BIO_WORKINGSET))
+                               workingset_read = true;
                        task_io_account_read(bio->bi_iter.bi_size);
                        count_vm_events(PGPGIN, count);
                }
                }
        }
 
-       return generic_make_request(bio);
+       /*
+        * If we're reading data that is part of the userspace
+        * workingset, count submission time as memory stall. When the
+        * device is congested, or the submitting cgroup IO-throttled,
+        * submission can be a significant part of overall IO time.
+        */
+       if (workingset_read)
+               psi_memstall_enter(&pflags);
+
+       ret = generic_make_request(bio);
+
+       if (workingset_read)
+               psi_memstall_leave(&pflags);
+
+       return ret;
 }
 EXPORT_SYMBOL(submit_bio);
 
 
        BIO_BOUNCED,            /* bio is a bounce bio */
        BIO_USER_MAPPED,        /* contains user pages */
        BIO_NULL_MAPPED,        /* contains invalid user pages */
+       BIO_WORKINGSET,         /* contains userspace workingset pages */
        BIO_QUIET,              /* Make BIO Quiet */
        BIO_CHAIN,              /* chained bio, ->bi_remaining in effect */
        BIO_REFFED,             /* bio has elevated ->bi_cnt */