Paul Mackerras <paulus@xxxxxxxxx> writes: > On Mon, Mar 04, 2013 at 04:28:42PM +0530, Aneesh Kumar K.V wrote: >> The last one that ends up doing atomic_xor_bits which cause the mapcount >> to go zero, will take the page off the list and free the page. > > No, look at the example again. page_table_free_rcu() won't take it > off the list because it uses the (mask & FRAG_MASK) == 0 test, which > fails (one fragment is still in use). page_table_free() won't take it > off the list because it uses the mask == 0 test, which also fails (one > fragment is still waiting for the RCU grace period). Finally, > __page_table_free_rcu() doesn't take it off the list, it just frees > the page. Oops. :) How about the below --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -425,7 +425,7 @@ void page_table_free(struct mm_struct *mm, unsigned long *table) bit = 1 << ((__pa(table) & ~PAGE_MASK) / PTE_FRAG_SIZE); spin_lock(&mm->page_table_lock); mask = atomic_xor_bits(&page->_mapcount, bit); - if (mask == 0) + if (!(mask & FRAG_MASK)) list_del(&page->lru); else if (mask & FRAG_MASK) { /* @@ -446,7 +446,7 @@ void page_table_free(struct mm_struct *mm, unsigned long *table) ie, we always remove the page from the list, when the lower half is zero or lower half is FRAG_MASK. We free the page when _mapcount is 0. -aneesh -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>