diff options
| -rw-r--r-- | mm/ksm.c | 15 |
1 files changed, 10 insertions, 5 deletions
| @@ -783,6 +783,7 @@ static int unmerge_and_remove_all_rmap_items(void) | |||
| 783 | } | 783 | } |
| 784 | 784 | ||
| 785 | remove_trailing_rmap_items(mm_slot, &mm_slot->rmap_list); | 785 | remove_trailing_rmap_items(mm_slot, &mm_slot->rmap_list); |
| 786 | up_read(&mm->mmap_sem); | ||
| 786 | 787 | ||
| 787 | spin_lock(&ksm_mmlist_lock); | 788 | spin_lock(&ksm_mmlist_lock); |
| 788 | ksm_scan.mm_slot = list_entry(mm_slot->mm_list.next, | 789 | ksm_scan.mm_slot = list_entry(mm_slot->mm_list.next, |
| @@ -794,12 +795,9 @@ static int unmerge_and_remove_all_rmap_items(void) | |||
| 794 | 795 | ||
| 795 | free_mm_slot(mm_slot); | 796 | free_mm_slot(mm_slot); |
| 796 | clear_bit(MMF_VM_MERGEABLE, &mm->flags); | 797 | clear_bit(MMF_VM_MERGEABLE, &mm->flags); |
| 797 | up_read(&mm->mmap_sem); | ||
| 798 | mmdrop(mm); | 798 | mmdrop(mm); |
| 799 | } else { | 799 | } else |
| 800 | spin_unlock(&ksm_mmlist_lock); | 800 | spin_unlock(&ksm_mmlist_lock); |
| 801 | up_read(&mm->mmap_sem); | ||
| 802 | } | ||
| 803 | } | 801 | } |
| 804 | 802 | ||
| 805 | /* Clean up stable nodes, but don't worry if some are still busy */ | 803 | /* Clean up stable nodes, but don't worry if some are still busy */ |
| @@ -1663,8 +1661,15 @@ next_mm: | |||
| 1663 | up_read(&mm->mmap_sem); | 1661 | up_read(&mm->mmap_sem); |
| 1664 | mmdrop(mm); | 1662 | mmdrop(mm); |
| 1665 | } else { | 1663 | } else { |
| 1666 | spin_unlock(&ksm_mmlist_lock); | ||
| 1667 | up_read(&mm->mmap_sem); | 1664 | up_read(&mm->mmap_sem); |
| 1665 | /* | ||
| 1666 | * up_read(&mm->mmap_sem) first because after | ||
| 1667 | * spin_unlock(&ksm_mmlist_lock) run, the "mm" may | ||
| 1668 | * already have been freed under us by __ksm_exit() | ||
| 1669 | * because the "mm_slot" is still hashed and | ||
| 1670 | * ksm_scan.mm_slot doesn't point to it anymore. | ||
| 1671 | */ | ||
| 1672 | spin_unlock(&ksm_mmlist_lock); | ||
| 1668 | } | 1673 | } |
| 1669 | 1674 | ||
| 1670 | /* Repeat until we've completed scanning the whole list */ | 1675 | /* Repeat until we've completed scanning the whole list */ |
