Another VM race? (was: page_launder() bug)
Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz)
Sun, 13 May 2001 23:02:27 +0200 (CEST)
> > > + if (!dead_swap_page &&
> > > + (PageTestandClearReferenced(page) || page->age > 0 ||
> > > + (!page->buffers && page_count(page) > 1) ||
> > > + page_ramdisk(page))) {
> > ^^^^^^^^^^^^^^^^^^^^^^
> > > del_page_from_inactive_dirty_list(page);
> > > add_page_to_active_list(page);
> > > continue;
> >
> > #define page_ramdisk(page) \
> > (page->buffers && (MAJOR(page->buffers->b_dev) == RAMDISK_MAJOR))
> >
> > Are you sure that no one will release buffers under your hands?
>
> Two things can happen:
>
> 1) the page gets ramdisk buffers _after_ we look at it first,
> in this case the page isn't freeable and will be moved to
> the active list on the next page_launder() loop
>
> 2) the page loses its ramdisk buffers after we look at it,
> now the page is freeable, but we won't see it again until
> it is moved from the active list to the inactive_dirty
> list again
>
> Any side effects harmful enough to warrant complicating this
> test ?
I mean this: Let's have a page with buffers. It does not care whether the
buffers are on ramdisk or not.
CPU 0 CPU 1
is executing the code marked is executing try_to_free_buffers on
above with ^^^^^^^: the same page (it can be, because CPU 0
did not lock the page)
(page->buffers &&
page->buffers = NULL
MAJOR(page->buffers->b_dev) ==
RAMDISK_MAJOR)) ===> Oops, NULL pointer dereference!
Maybe compiler CSE optimization will eliminate the double load of
page->buffers, but we must not rely on it. If the compiler doesn't
optimize it, it can produce random oopses.
Mikulas
-
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/