diff options
Diffstat (limited to 'mm/vmalloc.c')
-rw-r--r-- | mm/vmalloc.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/mm/vmalloc.c b/mm/vmalloc.c index d3c1f5ee48b4..a5584384eabc 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c | |||
@@ -628,7 +628,7 @@ static bool __purge_vmap_area_lazy(unsigned long start, unsigned long end) | |||
628 | struct llist_node *valist; | 628 | struct llist_node *valist; |
629 | struct vmap_area *va; | 629 | struct vmap_area *va; |
630 | struct vmap_area *n_va; | 630 | struct vmap_area *n_va; |
631 | int nr = 0; | 631 | bool do_free = false; |
632 | 632 | ||
633 | lockdep_assert_held(&vmap_purge_lock); | 633 | lockdep_assert_held(&vmap_purge_lock); |
634 | 634 | ||
@@ -638,18 +638,22 @@ static bool __purge_vmap_area_lazy(unsigned long start, unsigned long end) | |||
638 | start = va->va_start; | 638 | start = va->va_start; |
639 | if (va->va_end > end) | 639 | if (va->va_end > end) |
640 | end = va->va_end; | 640 | end = va->va_end; |
641 | nr += (va->va_end - va->va_start) >> PAGE_SHIFT; | 641 | do_free = true; |
642 | } | 642 | } |
643 | 643 | ||
644 | if (!nr) | 644 | if (!do_free) |
645 | return false; | 645 | return false; |
646 | 646 | ||
647 | atomic_sub(nr, &vmap_lazy_nr); | ||
648 | flush_tlb_kernel_range(start, end); | 647 | flush_tlb_kernel_range(start, end); |
649 | 648 | ||
650 | spin_lock(&vmap_area_lock); | 649 | spin_lock(&vmap_area_lock); |
651 | llist_for_each_entry_safe(va, n_va, valist, purge_list) | 650 | llist_for_each_entry_safe(va, n_va, valist, purge_list) { |
651 | int nr = (va->va_end - va->va_start) >> PAGE_SHIFT; | ||
652 | |||
652 | __free_vmap_area(va); | 653 | __free_vmap_area(va); |
654 | atomic_sub(nr, &vmap_lazy_nr); | ||
655 | cond_resched_lock(&vmap_area_lock); | ||
656 | } | ||
653 | spin_unlock(&vmap_area_lock); | 657 | spin_unlock(&vmap_area_lock); |
654 | return true; | 658 | return true; |
655 | } | 659 | } |