--- linux-2.6.23/mm/hugetlb.c.orig 2008-01-16 12:05:41.496448000 -0500 +++ linux-2.6.23/mm/hugetlb.c 2008-01-16 12:09:57.184746000 -0500 @@ -377,18 +377,22 @@ int copy_hugetlb_page_range(struct mm_st dst_pte = huge_pte_alloc(dst, addr); if (!dst_pte) goto nomem; - spin_lock(&dst->page_table_lock); - spin_lock(&src->page_table_lock); - if (!pte_none(*src_pte)) { - if (cow) - ptep_set_wrprotect(src, addr, src_pte); - entry = *src_pte; - ptepage = pte_page(entry); - get_page(ptepage); - set_huge_pte_at(dst, addr, dst_pte, entry); + + /* if hugetlbpage pagetables are shared dont take additional references */ + if(!(is_vm_hugtlb_page(vma) && dst_pte == src_pte)) { + spin_lock(&dst->page_table_lock); + spin_lock(&src->page_table_lock); + if (!pte_none(*src_pte)) { + if (cow) + ptep_set_wrprotect(src, addr, src_pte); + entry = *src_pte; + ptepage = pte_page(entry); + get_page(ptepage); + set_huge_pte_at(dst, addr, dst_pte, entry); + } + spin_unlock(&src->page_table_lock); + spin_unlock(&dst->page_table_lock); } - spin_unlock(&src->page_table_lock); - spin_unlock(&dst->page_table_lock); } return 0;