477 int nr = 0;
478
479
480
481
482
483
484 if (!sync && !force_flush) {
485 if (!spin_trylock(&purge_lock))
486 return;
487 } else
488 spin_lock(&purge_lock);
489
490 rcu_read_lock();
491 list_for_each_entry_rcu(va, &vmap_area_list, list) {
492 if (va->flags & VM_LAZY_FREE) {
493 if (va->va_start < *start)
494 *start = va->va_start;
495 if (va->va_end > *end)
496 *end = va->va_end;
497 nr += (va->va_end - va->va_start) >> PAGE_SHIFT;
498 unmap_vmap_area(va);
499 list_add_tail(&va->purge_list, &valist);
500 va->flags |= VM_LAZY_FREEING;
501 va->flags &= ~VM_LAZY_FREE;
502 }
503 }
504 rcu_read_unlock();
505
506 if (nr) {
507 BUG_ON(nr > atomic_read(&vmap_lazy_nr));
508 atomic_sub(nr, &vmap_lazy_nr);
509 }
510
511 if (nr || force_flush)
512 flush_tlb_kernel_range(*start, *end);
513
514 if (nr) {
515 spin_lock(&vmap_area_lock);
516 list_for_each_entry(va, &valist, purge_list)
517 __free_vmap_area(va);