Re: 2.4.18(19) swapcache oops

From: Andrew Morton (akpm@zip.com.au)
Date: Thu Aug 15 2002 - 15:05:41 EST


Hugh Dickins wrote:
>
> On Thu, 15 Aug 2002 j-nomura@ce.jp.nec.com wrote:
> >
> > I'm using 2.4.18 kernel and suspect there are swapcache race.
> > I looked into 2.4.19 patch but could not find the fix to it.
>
> I see a benign race but no oops.
>

But look at lru_cache_add():

void lru_cache_add(struct page * page)
{
        if (!TestSetPageLRU(page)) {
/* window here */
                spin_lock(&pagemap_lru_lock);
                add_page_to_inactive_list(page);
                spin_unlock(&pagemap_lru_lock);
        }
}

It sets PG_lru before adding the page to the LRU.

static inline void activate_page_nolock(struct page * page)
{
        if (PageLRU(page) && !PageActive(page)) {
                del_page_from_inactive_list(page);
                add_page_to_active_list(page);
        }
}

void activate_page(struct page * page)
{
        spin_lock(&pagemap_lru_lock);
        activate_page_nolock(page);
        spin_unlock(&pagemap_lru_lock);
}

So if activate_page gets the lock inside that window, it will
delete a page from the LRU which isn't on it (memory corruption).
Then activate_page will set PG_active and will drop the lock.

lru_cache_add gets the lock, runs add_page_to_inactive_list which
BUGs over PG_active.

--- 2.4.19/mm/swap.c~lru-race Thu Aug 15 13:03:48 2002
+++ 2.4.19-akpm/mm/swap.c Thu Aug 15 13:04:19 2002
@@ -57,9 +57,10 @@ void activate_page(struct page * page)
  */
 void lru_cache_add(struct page * page)
 {
- if (!TestSetPageLRU(page)) {
+ if (!PageLRU(page)) {
                 spin_lock(&pagemap_lru_lock);
- add_page_to_inactive_list(page);
+ if (!TestSetPageLRU(page))
+ add_page_to_inactive_list(page);
                 spin_unlock(&pagemap_lru_lock);
         }
 }

.
-
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 : Thu Aug 15 2002 - 22:00:40 EST