|
@@ -573,17 +573,14 @@ EXPORT_SYMBOL(wait_on_page_bit);
|
|
|
* mechananism between PageLocked pages and PageWriteback pages is shared.
|
|
|
* But that's OK - sleepers in wait_on_page_writeback() just go back to sleep.
|
|
|
*
|
|
|
- * The first mb is necessary to safely close the critical section opened by the
|
|
|
- * test_and_set_bit() to lock the page; the second mb is necessary to enforce
|
|
|
- * ordering between the clear_bit and the read of the waitqueue (to avoid SMP
|
|
|
- * races with a parallel wait_on_page_locked()).
|
|
|
+ * The mb is necessary to enforce ordering between the clear_bit and the read
|
|
|
+ * of the waitqueue (to avoid SMP races with a parallel wait_on_page_locked()).
|
|
|
*/
|
|
|
void unlock_page(struct page *page)
|
|
|
{
|
|
|
- smp_mb__before_clear_bit();
|
|
|
- if (!test_and_clear_bit(PG_locked, &page->flags))
|
|
|
- BUG();
|
|
|
- smp_mb__after_clear_bit();
|
|
|
+ VM_BUG_ON(!PageLocked(page));
|
|
|
+ clear_bit_unlock(PG_locked, &page->flags);
|
|
|
+ smp_mb__after_clear_bit();
|
|
|
wake_up_page(page, PG_locked);
|
|
|
}
|
|
|
EXPORT_SYMBOL(unlock_page);
|