aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/shmem.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/mm/shmem.c b/mm/shmem.c
index 8fa27e4e582a..262d71173447 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1039,6 +1039,7 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc)
1039 struct address_space *mapping; 1039 struct address_space *mapping;
1040 unsigned long index; 1040 unsigned long index;
1041 struct inode *inode; 1041 struct inode *inode;
1042 bool unlock_mutex = false;
1042 1043
1043 BUG_ON(!PageLocked(page)); 1044 BUG_ON(!PageLocked(page));
1044 mapping = page->mapping; 1045 mapping = page->mapping;
@@ -1064,7 +1065,26 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc)
1064 else 1065 else
1065 swap.val = 0; 1066 swap.val = 0;
1066 1067
1068 /*
1069 * Add inode to shmem_unuse()'s list of swapped-out inodes,
1070 * if it's not already there. Do it now because we cannot take
1071 * mutex while holding spinlock, and must do so before the page
1072 * is moved to swap cache, when its pagelock no longer protects
1073 * the inode from eviction. But don't unlock the mutex until
1074 * we've taken the spinlock, because shmem_unuse_inode() will
1075 * prune a !swapped inode from the swaplist under both locks.
1076 */
1077 if (swap.val && list_empty(&info->swaplist)) {
1078 mutex_lock(&shmem_swaplist_mutex);
1079 /* move instead of add in case we're racing */
1080 list_move_tail(&info->swaplist, &shmem_swaplist);
1081 unlock_mutex = true;
1082 }
1083
1067 spin_lock(&info->lock); 1084 spin_lock(&info->lock);
1085 if (unlock_mutex)
1086 mutex_unlock(&shmem_swaplist_mutex);
1087
1068 if (index >= info->next_index) { 1088 if (index >= info->next_index) {
1069 BUG_ON(!(info->flags & SHMEM_TRUNCATE)); 1089 BUG_ON(!(info->flags & SHMEM_TRUNCATE));
1070 goto unlock; 1090 goto unlock;
@@ -1084,21 +1104,10 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc)
1084 delete_from_page_cache(page); 1104 delete_from_page_cache(page);
1085 shmem_swp_set(info, entry, swap.val); 1105 shmem_swp_set(info, entry, swap.val);
1086 shmem_swp_unmap(entry); 1106 shmem_swp_unmap(entry);
1087 if (list_empty(&info->swaplist))
1088 inode = igrab(inode);
1089 else
1090 inode = NULL;
1091 spin_unlock(&info->lock); 1107 spin_unlock(&info->lock);
1092 swap_shmem_alloc(swap); 1108 swap_shmem_alloc(swap);
1093 BUG_ON(page_mapped(page)); 1109 BUG_ON(page_mapped(page));
1094 swap_writepage(page, wbc); 1110 swap_writepage(page, wbc);
1095 if (inode) {
1096 mutex_lock(&shmem_swaplist_mutex);
1097 /* move instead of add in case we're racing */
1098 list_move_tail(&info->swaplist, &shmem_swaplist);
1099 mutex_unlock(&shmem_swaplist_mutex);
1100 iput(inode);
1101 }
1102 return 0; 1111 return 0;
1103 } 1112 }
1104 1113