__free_pages_ok on locked page

From: David Wragg (dpw@doc.ic.ac.uk)
Date: Sat Mar 11 2000 - 15:58:26 EST


Encountered in 2.3.47 (oops below), but the cause is still there in
2.3.51:

In swap_state.c, delete_from_swap_cache_nolock() is preceded by this
comment:

  /*
   * This will never put the page into the free list, the caller has
   * a reference on the page.
   */
  void delete_from_swap_cache_nolock(struct page *page)

But free_page_and_swap_cache() calls it in a situation where that
comment cannot hold:

        /*
         * If we are the only user, then try to free up the swap cache.
         */
        if (PageSwapCache(page) && !TryLockPage(page)) {
                if (!is_page_shared(page)) {
                        delete_from_swap_cache_nolock(page);
                }
                UnlockPage(page);
        }

If is_page_shared(page) == 0, then the page count must be 1, so the
page_cache_release(page) in delete_from_swap_cache_nolock() results in
a call to __free_pages_ok() on the locked page.

But while I can see that cause, I'm not so sure how to fix it. I think
delete_from_swap_cache_nolock needs a macro similar to
page_cache_release, but never does a __free_page. If an mm guru can
confirm this fix, I'd be happy to put together a patch for it.

David Wragg

kernel BUG at page_alloc.c:89!
invalid operand: 0000
CPU: 0
EIP: 0010:[<c012a79b>]
Using defaults from ksymoops -t elf32-i386 -a i386
EFLAGS: 00010296
eax: 0000001f ebx: c10008c0 ecx: 0000002a edx: 00000000
esi: 00000001 edi: c5cdc400 ebp: 00000000 esp: c5c81e48
ds: 0018 es: 0018 ss: 0018
Process tcpdump (pid: 8703, stackpage=c5c81000)
Stack: c01e4647 c01e4813 00000059 c10008c0 00000001 c5cdc400 00000001 0024e500
       00000001 c10008c0 00000001 c012af16 c012af2c c10008c0 c012afa0 c10008c0
       00000300 0006d000 c01212ca c10008c0 c0bf28e0 0806d000 c7fa90e0 07524000
Call Trace: [<c01e4647>] [<c01e4813>] [<c012af16>] [<c012af2c>] [<c012afa0>] [<c01212ca>] [<c0123748>]
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                these first three are bogus
       [<c011647d>] [<c011ba32>] [<c010ae77>] [<c01a9aa3>] [<c0114de2>] [<c010b030>]
Code: 0f 0b 83 c4 0c 8b 73 44 c7 44 24 1c ff ff ff ff 89 e9 d3 64

>>EIP; c012a79b <__free_pages_ok+7b/228> <=====
Trace; c012af2c <delete_from_swap_cache_nolock+44/48>
Trace; c012afa0 <free_page_and_swap_cache+44/7c>
Trace; c01212ca <zap_page_range+176/1f4>
Trace; c0123748 <exit_mmap+b8/11c>
Trace; c011647d <mmput+15/2c>
Trace; c011ba32 <do_exit+14a/340>
Trace; c010ae77 <do_signal+20b/2a0>
Trace; c01a9aa3 <net_rx_action+123/1e8>
Trace; c0114de2 <schedule+2ba/448>
Trace; c010b030 <signal_return+14/18>
Code; c012a79b <__free_pages_ok+7b/228>
00000000 <_EIP>:
Code; c012a79b <__free_pages_ok+7b/228> <=====
   0: 0f 0b ud2a <=====
Code; c012a79d <__free_pages_ok+7d/228>
   2: 83 c4 0c addl $0xc,%esp
Code; c012a7a0 <__free_pages_ok+80/228>
   5: 8b 73 44 movl 0x44(%ebx),%esi
Code; c012a7a3 <__free_pages_ok+83/228>
   8: c7 44 24 1c ff ff ff movl $0xffffffff,0x1c(%esp,1)
Code; c012a7aa <__free_pages_ok+8a/228>
   f: ff
Code; c012a7ab <__free_pages_ok+8b/228>
  10: 89 e9 movl %ebp,%ecx
Code; c012a7ad <__free_pages_ok+8d/228>
  12: d3 64 00 00 shll %cl,0x0(%eax,%eax,1)

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



This archive was generated by hypermail 2b29 : Wed Mar 15 2000 - 21:00:20 EST