diff --git a/mm/page_io.c b/mm/page_io.c index e91f008af794..2c6201e9f645 100644 --- a/mm/page_io.c +++ b/mm/page_io.c @@ -84,7 +84,7 @@ bool swap_slot_has_sync_io(swp_entry_t entry) SWP_SYNCHRONOUS_IO, swp_offset(entry)) == 1; } - return false; + return (sis->flags & SWP_SYNCHRONOUS_IO) == SWP_SYNCHRONOUS_IO; } static void swap_slot_free_notify(struct page *page) @@ -368,6 +368,7 @@ int swap_readpage(struct page *page, bool synchronous) blk_qc_t qc; struct gendisk *disk; unsigned long pflags; + swp_entry_t entry; VM_BUG_ON_PAGE(!PageSwapCache(page) && !synchronous, page); VM_BUG_ON_PAGE(!PageLocked(page), page); @@ -396,15 +397,24 @@ int swap_readpage(struct page *page, bool synchronous) goto out; } - ret = bdev_read_page(sis->bdev, swap_page_sector(page), page); - if (!ret) { - if (trylock_page(page)) { - swap_slot_free_notify(page); - unlock_page(page); - } + /* Moto huangzq2: Use rw_page for zram page but submit_bio for zram wb page. + * Since reading zram wb page is an async operation, we can not immediately + * free the slot here. So we need to read the page via submit_bio and free + * the slot in end_swap_bio_read. (bio chain will be used to handle bio here + * and bio in zram driver for wb page). + */ + entry.val = page_private(page); + if (swap_slot_has_sync_io(entry)) { + ret = bdev_read_page(sis->bdev, swap_page_sector(page), page); + if (!ret) { + if (trylock_page(page)) { + swap_slot_free_notify(page); + unlock_page(page); + } - count_vm_event(PSWPIN); - goto out; + count_vm_event(PSWPIN); + goto out; + } } ret = 0;