Commit 4c312efd authored by Seth Rohit's avatar Seth Rohit Committed by Linus Torvalds

[PATCH] Broken Hugetlbpage support in 2.5.46

The hugetlb page support in 2.5.46 is broken (Don't know if this is the
first version of kernel or any prior revs also have that).  Basically the
free side of hugepages was really not freeing the physical resources (for
the cases when the pages allocated using system call interface).  Attached
is the patch that should resolve it. (doesn't break the hugetlbfs support
either).
parent ff01934e
...@@ -235,22 +235,55 @@ void huge_page_release(struct page *page) ...@@ -235,22 +235,55 @@ void huge_page_release(struct page *page)
free_huge_page(page); free_huge_page(page);
} }
static void
free_rsrc(struct inode * inode)
{
int i;
spin_lock(&htlbpage_lock);
for (i=0;i<MAX_ID;i++)
if (htlbpagek[i].key == inode->i_ino) {
htlbpagek[i].key = 0;
htlbpagek[i].in = NULL;
break;
}
spin_unlock(&htlbpage_lock);
kfree(inode);
}
void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
{ {
struct mm_struct *mm = vma->vm_mm; struct mm_struct *mm = vma->vm_mm;
unsigned long address; unsigned long address;
pte_t *pte; pte_t *pte;
struct page *page; struct page *page;
int free_more = 0;
struct inode *inode = NULL;
BUG_ON(start & (HPAGE_SIZE - 1)); BUG_ON(start & (HPAGE_SIZE - 1));
BUG_ON(end & (HPAGE_SIZE - 1)); BUG_ON(end & (HPAGE_SIZE - 1));
if (start < end) {
pte = huge_pte_offset(mm, start);
page = pte_page(*pte);
if ((page->mapping != NULL) && (page_count(page) == 2) &&
((inode=page->mapping->host)->i_mapping->a_ops == NULL))
free_more = 1;
}
for (address = start; address < end; address += HPAGE_SIZE) { for (address = start; address < end; address += HPAGE_SIZE) {
pte = huge_pte_offset(mm, address); pte = huge_pte_offset(mm, address);
page = pte_page(*pte); page = pte_page(*pte);
if (free_more) {
ClearPageDirty(page);
SetPageLocked(page);
remove_from_page_cache(page);
ClearPageLocked(page);
set_page_count(page, 1);
}
huge_page_release(page); huge_page_release(page);
pte_clear(pte); pte_clear(pte);
} }
if (free_more)
free_rsrc(inode);
mm->rss -= (end - start) >> PAGE_SHIFT; mm->rss -= (end - start) >> PAGE_SHIFT;
flush_tlb_range(vma, start, end); flush_tlb_range(vma, start, end);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment