diff options
Diffstat (limited to 'mm/shmem.c')
-rw-r--r-- | mm/shmem.c | 43 |
1 files changed, 12 insertions, 31 deletions
diff --git a/mm/shmem.c b/mm/shmem.c index 51b3d6ccddab..88c6685f16b7 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -1025,53 +1025,34 @@ out: | |||
1025 | return err; | 1025 | return err; |
1026 | } | 1026 | } |
1027 | 1027 | ||
1028 | static struct page *shmem_swapin_async(struct shared_policy *p, | 1028 | static struct page *shmem_swapin(struct shmem_inode_info *info, |
1029 | swp_entry_t entry, unsigned long idx) | 1029 | swp_entry_t entry, unsigned long idx) |
1030 | { | 1030 | { |
1031 | struct page *page; | ||
1032 | struct vm_area_struct pvma; | 1031 | struct vm_area_struct pvma; |
1032 | struct page *page; | ||
1033 | 1033 | ||
1034 | /* Create a pseudo vma that just contains the policy */ | 1034 | /* Create a pseudo vma that just contains the policy */ |
1035 | memset(&pvma, 0, sizeof(struct vm_area_struct)); | 1035 | pvma.vm_start = 0; |
1036 | pvma.vm_end = PAGE_SIZE; | ||
1037 | pvma.vm_pgoff = idx; | 1036 | pvma.vm_pgoff = idx; |
1038 | pvma.vm_policy = mpol_shared_policy_lookup(p, idx); | 1037 | pvma.vm_ops = NULL; |
1038 | pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, idx); | ||
1039 | swapin_readahead(entry, 0, &pvma); | ||
1039 | page = read_swap_cache_async(entry, &pvma, 0); | 1040 | page = read_swap_cache_async(entry, &pvma, 0); |
1040 | mpol_free(pvma.vm_policy); | 1041 | mpol_free(pvma.vm_policy); |
1041 | return page; | 1042 | return page; |
1042 | } | 1043 | } |
1043 | 1044 | ||
1044 | static struct page *shmem_swapin(struct shmem_inode_info *info, | 1045 | static struct page *shmem_alloc_page(gfp_t gfp, struct shmem_inode_info *info, |
1045 | swp_entry_t entry, unsigned long idx) | 1046 | unsigned long idx) |
1046 | { | ||
1047 | struct shared_policy *p = &info->policy; | ||
1048 | int i, num; | ||
1049 | struct page *page; | ||
1050 | unsigned long offset; | ||
1051 | |||
1052 | num = valid_swaphandles(entry, &offset); | ||
1053 | for (i = 0; i < num; offset++, i++) { | ||
1054 | page = shmem_swapin_async(p, | ||
1055 | swp_entry(swp_type(entry), offset), idx); | ||
1056 | if (!page) | ||
1057 | break; | ||
1058 | page_cache_release(page); | ||
1059 | } | ||
1060 | lru_add_drain(); /* Push any new pages onto the LRU now */ | ||
1061 | return shmem_swapin_async(p, entry, idx); | ||
1062 | } | ||
1063 | |||
1064 | static struct page * | ||
1065 | shmem_alloc_page(gfp_t gfp, struct shmem_inode_info *info, | ||
1066 | unsigned long idx) | ||
1067 | { | 1047 | { |
1068 | struct vm_area_struct pvma; | 1048 | struct vm_area_struct pvma; |
1069 | struct page *page; | 1049 | struct page *page; |
1070 | 1050 | ||
1071 | memset(&pvma, 0, sizeof(struct vm_area_struct)); | 1051 | /* Create a pseudo vma that just contains the policy */ |
1072 | pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, idx); | 1052 | pvma.vm_start = 0; |
1073 | pvma.vm_pgoff = idx; | 1053 | pvma.vm_pgoff = idx; |
1074 | pvma.vm_end = PAGE_SIZE; | 1054 | pvma.vm_ops = NULL; |
1055 | pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, idx); | ||
1075 | page = alloc_page_vma(gfp, &pvma, 0); | 1056 | page = alloc_page_vma(gfp, &pvma, 0); |
1076 | mpol_free(pvma.vm_policy); | 1057 | mpol_free(pvma.vm_policy); |
1077 | return page; | 1058 | return page; |