Re: truncate_list_pages() BUG and confusion

From: Martin J. Bligh (Martin.Bligh@us.ibm.com)
Date: Fri Mar 08 2002 - 19:04:04 EST


>> void page_cache_release(struct page *page)
>> {
>> if (!PageReserved(page) && put_page_testzero(page)) {
>> if (PageLRU(page))
>> lru_cache_del(page);
>> __free_pages_ok(page, 0);
>> }
>> }
>>
>> We enter page_cache_release with the supposedly locked, and its count
>> non-zero (we incremented it). put_page_testzero does atomic_dec_and_test
>> on count which says it returns true if the result is 0, or false for all other cases.
>>
>> So if nobody else was holding a reference to the page, we've decremented
>> it's count to 0, and put_page_testzero returns 1. We then try to free the page.
>> It's still locked. BUG.
>
> If the page_cache_release() in truncate_complete_page() is calling
> __free_pages_ok() then something really horrid has happened.

That's exactly what's happening.
 
> Yes, it could be that the page has had its refcount incorrectly
> decremented somewhere.

I don't see you need that to make this bug happen.
Say count is 0 when we enter truncate_list_pages. We increment it.
It's now 1 when we call page_cache_release.
put_page_testzero dec's it back to 0, and returns true.
We do a __free_pages_ok. Page is still locked. BUG.

No other process, nothing funky happening, no races, no other
refcount decrements. Or that's the way I read it.

> Or the page wasn't in the pagecache at all.

The only thing I can think of was the pagecount shouldn't have been 0
to start with (or the code path we're reading is wrong ;-) )

M.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Fri Mar 15 2002 - 22:00:11 EST