diff options
Diffstat (limited to 'mm/shmem.c')
-rw-r--r-- | mm/shmem.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/mm/shmem.c b/mm/shmem.c index abd7403aba41..54287d443806 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -661,8 +661,8 @@ unsigned long shmem_partial_swap_usage(struct address_space *mapping, | |||
661 | swapped++; | 661 | swapped++; |
662 | 662 | ||
663 | if (need_resched()) { | 663 | if (need_resched()) { |
664 | slot = radix_tree_iter_resume(slot, &iter); | ||
664 | cond_resched_rcu(); | 665 | cond_resched_rcu(); |
665 | slot = radix_tree_iter_next(&iter); | ||
666 | } | 666 | } |
667 | } | 667 | } |
668 | 668 | ||
@@ -1049,6 +1049,30 @@ static void shmem_evict_inode(struct inode *inode) | |||
1049 | clear_inode(inode); | 1049 | clear_inode(inode); |
1050 | } | 1050 | } |
1051 | 1051 | ||
1052 | static unsigned long find_swap_entry(struct radix_tree_root *root, void *item) | ||
1053 | { | ||
1054 | struct radix_tree_iter iter; | ||
1055 | void **slot; | ||
1056 | unsigned long found = -1; | ||
1057 | unsigned int checked = 0; | ||
1058 | |||
1059 | rcu_read_lock(); | ||
1060 | radix_tree_for_each_slot(slot, root, &iter, 0) { | ||
1061 | if (*slot == item) { | ||
1062 | found = iter.index; | ||
1063 | break; | ||
1064 | } | ||
1065 | checked++; | ||
1066 | if ((checked % 4096) != 0) | ||
1067 | continue; | ||
1068 | slot = radix_tree_iter_resume(slot, &iter); | ||
1069 | cond_resched_rcu(); | ||
1070 | } | ||
1071 | |||
1072 | rcu_read_unlock(); | ||
1073 | return found; | ||
1074 | } | ||
1075 | |||
1052 | /* | 1076 | /* |
1053 | * If swap found in inode, free it and move page from swapcache to filecache. | 1077 | * If swap found in inode, free it and move page from swapcache to filecache. |
1054 | */ | 1078 | */ |
@@ -1062,7 +1086,7 @@ static int shmem_unuse_inode(struct shmem_inode_info *info, | |||
1062 | int error = 0; | 1086 | int error = 0; |
1063 | 1087 | ||
1064 | radswap = swp_to_radix_entry(swap); | 1088 | radswap = swp_to_radix_entry(swap); |
1065 | index = radix_tree_locate_item(&mapping->page_tree, radswap); | 1089 | index = find_swap_entry(&mapping->page_tree, radswap); |
1066 | if (index == -1) | 1090 | if (index == -1) |
1067 | return -EAGAIN; /* tell shmem_unuse we found nothing */ | 1091 | return -EAGAIN; /* tell shmem_unuse we found nothing */ |
1068 | 1092 | ||
@@ -2447,8 +2471,8 @@ static void shmem_tag_pins(struct address_space *mapping) | |||
2447 | } | 2471 | } |
2448 | 2472 | ||
2449 | if (need_resched()) { | 2473 | if (need_resched()) { |
2474 | slot = radix_tree_iter_resume(slot, &iter); | ||
2450 | cond_resched_rcu(); | 2475 | cond_resched_rcu(); |
2451 | slot = radix_tree_iter_next(&iter); | ||
2452 | } | 2476 | } |
2453 | } | 2477 | } |
2454 | rcu_read_unlock(); | 2478 | rcu_read_unlock(); |
@@ -2517,8 +2541,8 @@ static int shmem_wait_for_pins(struct address_space *mapping) | |||
2517 | spin_unlock_irq(&mapping->tree_lock); | 2541 | spin_unlock_irq(&mapping->tree_lock); |
2518 | continue_resched: | 2542 | continue_resched: |
2519 | if (need_resched()) { | 2543 | if (need_resched()) { |
2544 | slot = radix_tree_iter_resume(slot, &iter); | ||
2520 | cond_resched_rcu(); | 2545 | cond_resched_rcu(); |
2521 | slot = radix_tree_iter_next(&iter); | ||
2522 | } | 2546 | } |
2523 | } | 2547 | } |
2524 | rcu_read_unlock(); | 2548 | rcu_read_unlock(); |