mirror of
https://github.com/torvalds/linux.git
synced 2026-11-10 17:11:02 +01:00
mm/madvise: swap in CoW'd MAP_PRIVATE-file mappings on MADV_WILLNEED
Currently MADV_WILLNEED treats file-backed and pure anonymous mappings entirely separately - using POSIX_FADV_WILLNEED (equivalent of a readahead) for the former and a tree walk and swap in to swap cache for the latter. MAP_PRIVATE-file backed mappings straddle the two and currently get treated as if they were purely file-backed, meaning any swapped out private pages remain swapped out. Resolve the issue by explicitly checking for CoW'd MAP_PRIVATE-file backed mappings and performing both walks in this case. Since the logic checks for vma->anon_vma this means un-CoW'd MAP_PRIVATE-file backed mappings retain only the single file walk. Link: https://lore.kernel.org/aprjOxDy3JCPb2oa@gremlin Reported-by: Mike Kaplinskiy <mike@recall.ai> Closes: https://lore.kernel.org/all/CABeknB_S2XJSHFgnHdgnN0rjzHhH4oQJs_APq9fvxHztQ_pgiA@mail.gmail.com/ Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org> Reviewed-by: Pedro Falcato <pfalcato@suse.de> Cc: David Hildenbrand <david@kernel.org> Cc: Jann Horn <jannh@google.com> Cc: Liam R. Howlett <liam@infradead.org>
This commit is contained in:
parent
ba99faaf67
commit
4cac0fd312
|
|
@ -297,11 +297,12 @@ static long madvise_willneed(struct madvise_behavior *madv_behavior)
|
|||
loff_t offset;
|
||||
|
||||
#ifdef CONFIG_SWAP
|
||||
if (!file) {
|
||||
if (vma_is_cow_mapping(vma) && vma->anon_vma) {
|
||||
walk_page_range_vma(vma, start, end, &swapin_walk_ops, vma);
|
||||
lru_add_drain(); /* Push any new pages onto the LRU now */
|
||||
return 0;
|
||||
}
|
||||
if (!file)
|
||||
return 0;
|
||||
|
||||
if (shmem_mapping(file->f_mapping)) {
|
||||
shmem_swapin_range(vma, start, end, file->f_mapping);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user