/* * remove user pages in a given range. */ void zap_page_range(struct mm_struct *mm, unsigned long address, unsigned long size) { pgd_t * dir; unsigned long end = address + size; int freed = 0; dir = pgd_offset(mm, address); /* * This is a long-lived spinlock. That's fine. * There's no contention, because the page table * lock only protects against kswapd anyway, and * even if kswapd happened to be looking at this * process we _want_ it to get stuck. */ if (address >= end) BUG(); spin_lock(&mm->page_table_lock); do { freed += zap_pmd_range(mm, dir, address, end - address); address = (address + PGDIR_SIZE) & PGDIR_MASK; dir++; } while (address && (address < end)); spin_unlock(&mm->page_table_lock); /* * Update rss for the mm_struct (not necessarily current->mm) * Notice that rss is an unsigned long. */ if (mm->rss > freed) mm->rss -= freed; else mm->rss = 0; }
/* * remove user pages in a given range. */ int zap_page_range(struct mm_struct *mm, unsigned long address, unsigned long size) { pgd_t * dir; unsigned long end = address + size; dir = pgd_offset(mm, address); flush_cache_range(mm, end - size, end); while (address < end) { zap_pmd_range(dir, address, end - address); address = (address + PGDIR_SIZE) & PGDIR_MASK; #ifdef CONFIG_BESTA if (!address) break; /* unsigned overflow */ #endif dir++; } flush_tlb_range(mm, end - size, end); return 0; }