Messages in this thread Patch in this message | | | Date | Sat, 27 Jan 2001 20:37:22 -0800 (PST) | From | Linus Torvalds <> | Subject | Re: ps hang in 241-pre10 |
| |
On Sun, 28 Jan 2001, Marcelo Tosatti wrote: > > > > This is the smoking gun here, I bet, but I'd like to make sure I see the > > whole thing. I don't see _why_ we'd have deadlocked on __wait_on_page(), > > but I think this is the thread that hangs on to the mm semaphore. > > I was able to reproduce it here with dbench. > > Nothing is locked except this dbench thread (the only dbench thread): > > dbench D C1C9FE64 5200 1013 1 (L-TLB) 1370 785 > Call Trace: [___wait_on_page+130/160] [truncate_list_pages+100/404] [truncate_inode_pages+93/128] [iput+162/360] [dput+262/356] [fput+121/232] [exit_mmap+218/292] > [mmput+56/80] [do_exit+208/680] [do_signal+566/656] [dput+25/356] [path_release+13/60] [sys_newstat+100/112] [sys_read+188/196] [signal_return+20/24]
Ok, this definitely seems to be the pattern.
I don't see _what_ is going on, though.
I know of one "known bug" in pre10: if you run out of swap-space with shared memory segments, it will do the wrong thing (return 1 without unlocking the page). xmms might trigger this, but I didn't think that dbench used shared memory?
There's also an ugliness in the truncate ordering. I don't think it should matter, but I do believe it's conceptually wrong as-is.
Does this patch make any difference at all?
Linus
----- diff -u --recursive --new-file pre10/linux/mm/memory.c linux/mm/memory.c --- pre10/linux/mm/memory.c Sat Jan 27 10:53:39 2001 +++ linux/mm/memory.c Sat Jan 27 19:12:35 2001 @@ -945,7 +945,6 @@ if (inode->i_size < offset) goto do_expand; inode->i_size = offset; - truncate_inode_pages(mapping, offset); spin_lock(&mapping->i_shared_lock); if (!mapping->i_mmap && !mapping->i_mmap_shared) goto out_unlock; @@ -960,8 +959,7 @@ out_unlock: spin_unlock(&mapping->i_shared_lock); - /* this should go into ->truncate */ - inode->i_size = offset; + truncate_inode_pages(mapping, offset); if (inode->i_op && inode->i_op->truncate) inode->i_op->truncate(inode); return; diff -u --recursive --new-file pre10/linux/mm/shmem.c linux/mm/shmem.c --- pre10/linux/mm/shmem.c Sat Jan 27 10:53:39 2001 +++ linux/mm/shmem.c Sat Jan 27 19:50:08 2001 @@ -217,8 +217,11 @@ info = &page->mapping->host->u.shmem_i; swap = __get_swap_page(2); - if (!swap.val) - return 1; + if (!swap.val) { + set_page_dirty(page); + UnlockPage(page); + return -ENOMEM; + } spin_lock(&info->lock); shmem_recalc_inode(page->mapping->host); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/
| |