diff options
Diffstat (limited to 'mm')
| -rw-r--r-- | mm/kasan/kasan.c | 5 | ||||
| -rw-r--r-- | mm/swapfile.c | 20 |
2 files changed, 22 insertions, 3 deletions
diff --git a/mm/kasan/kasan.c b/mm/kasan/kasan.c index eeaaac0fb24a..2bfdb3c23e72 100644 --- a/mm/kasan/kasan.c +++ b/mm/kasan/kasan.c @@ -678,12 +678,13 @@ void kasan_kfree_large(const void *ptr) int kasan_module_alloc(void *addr, size_t size) { void *ret; + size_t scaled_size; size_t shadow_size; unsigned long shadow_start; shadow_start = (unsigned long)kasan_mem_to_shadow(addr); - shadow_size = round_up(size >> KASAN_SHADOW_SCALE_SHIFT, - PAGE_SIZE); + scaled_size = (size + KASAN_SHADOW_MASK) >> KASAN_SHADOW_SCALE_SHIFT; + shadow_size = round_up(scaled_size, PAGE_SIZE); if (WARN_ON(!PAGE_ALIGNED(shadow_start))) return -EINVAL; diff --git a/mm/swapfile.c b/mm/swapfile.c index 63b65a893238..feb9abb8e8cc 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -974,11 +974,25 @@ int reuse_swap_page(struct page *page) count = page_mapcount(page); if (count <= 1 && PageSwapCache(page)) { count += page_swapcount(page); - if (count == 1 && !PageWriteback(page)) { + if (count != 1) + goto out; + if (!PageWriteback(page)) { delete_from_swap_cache(page); SetPageDirty(page); + } else { + swp_entry_t entry; + struct swap_info_struct *p; + + entry.val = page_private(page); + p = swap_info_get(entry); + if (p->flags & SWP_STABLE_WRITES) { + spin_unlock(&p->lock); + return false; + } + spin_unlock(&p->lock); } } +out: return count <= 1; } @@ -2524,6 +2538,10 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) error = -ENOMEM; goto bad_swap; } + + if (bdi_cap_stable_pages_required(inode_to_bdi(inode))) + p->flags |= SWP_STABLE_WRITES; + if (p->bdev && blk_queue_nonrot(bdev_get_queue(p->bdev))) { int cpu; |
