On 1/23/16, Jeff Merkey <linux.mdb@xxxxxxxxx> wrote: > If I leave the system in the debugger console overnight with all the > processors suspended for about 8 hours, then type go, the following > bug shows up during file I/O. This particular bug showed up while > using git to update some branches. > > I have only seen this bug once and I attempted to reproduce it to get > a trace dump but have not been able to trigger it again. The NULL > pointer is RDI set to NULL while trying to obtain a lock. > > (2)> .z grab_journal > ffffffffa00bb740 t jbd2_journal_grab_journal_head [jbd2] > (2)> u ffffffffa00bb740 > jbd2|jbd2_journal_grab_journal_head: > 0xffffffffa00bb740 0F1F440000 nop DWORD PTR [rax+rax]=0x0 > 0xffffffffa00bb745 55 push rbp > 0xffffffffa00bb746 4889E5 mov rbp,rsp > <<<<<<<<<<<< Crashes here with RDI set to NULL > 0xffffffffa00bb749 F00FBA2F18 lock bts DWORD PTR [rdi]=0x0,0x18 > <<<<<<<<<<<< > 0xffffffffa00bb74e 7219 jb > jbd2_journal_grab_journal_head+0x29 (0xffffffffa00bb769) (down) > 0xffffffffa00bb750 488B07 mov rax,QWORD PTR [rdi]=0x0 > 0xffffffffa00bb753 A900000200 test eax,0x20000 > 0xffffffffa00bb758 741D je > jbd2_journal_grab_journal_head+0x37 (0xffffffffa00bb777) (down) > 0xffffffffa00bb75a 488B4740 mov rax,QWORD PTR [rdi+64]=0x0 > 0xffffffffa00bb75e 83400801 add DWORD PTR [rax+8]=0x0,0x1 > 0xffffffffa00bb762 F0806703FE lock and BYTE PTR [rdi+3]=0x00,0xfe > 0xffffffffa00bb767 5D pop rbp > 0xffffffffa00bb768 C3 ret > 0xffffffffa00bb769 F390 pause > 0xffffffffa00bb76b 488B07 mov rax,QWORD PTR [rdi]=0x0 > 0xffffffffa00bb76e A900000001 test eax,0x1000000 > 0xffffffffa00bb773 75F4 jne > jbd2_journal_grab_journal_head+0x29 (0xffffffffa00bb769) (up) > 0xffffffffa00bb775 EBD2 jmp > jbd2_journal_grab_journal_head+0x9 (0xffffffffa00bb749) (up) > 0xffffffffa00bb777 31C0 xor eax,eax > > The backtrace showed this function being called from the swapper > thread when the crash occurred. It's damn hard to reproduce. If I > see it again, I'll get you a better trace. > > Jeff > Here is an objdump of the code in question. 0000000000005540 <jbd2_journal_grab_journal_head>: /* * Grab a ref against this buffer_head's journal_head. If it ended up not * having a journal_head, return NULL */ struct journal_head *jbd2_journal_grab_journal_head(struct buffer_head *bh) { 5540: e8 00 00 00 00 callq 5545 <jbd2_journal_grab_journal_head+0x5> 5545: 55 push %rbp 5546: 48 89 e5 mov %rsp,%rbp * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ static inline int test_and_set_bit(long nr, volatile unsigned long *addr) { GEN_BINARY_RMWcc(LOCK_PREFIX "bts", *addr, "Ir", nr, "%0", "c"); 5549: f0 0f ba 2f 18 lock btsl $0x18,(%rdi) << crashes here RDI=NULL 554e: 72 19 jb 5569 <jbd2_journal_grab_journal_head+0x29> } static __always_inline int constant_test_bit(long nr, const volatile unsigned long *addr) { return ((1UL << (nr & (BITS_PER_LONG-1))) & (addr[nr >> _BITOPS_LONG_SHIFT])) != 0; 5550: 48 8b 07 mov (%rdi),%rax struct journal_head *jh = NULL; jbd_lock_bh_journal_head(bh); if (buffer_jbd(bh)) { 5553: a9 00 00 02 00 test $0x20000,%eax 5558: 74 1d je 5577 <jbd2_journal_grab_journal_head+0x37> /* * Grab a ref against this buffer_head's journal_head. If it ended up not * having a journal_head, return NULL */ struct journal_head *jbd2_journal_grab_journal_head(struct buffer_head *bh) 555a: 48 8b 47 40 mov 0x40(%rdi),%rax struct journal_head *jh = NULL; jbd_lock_bh_journal_head(bh); if (buffer_jbd(bh)) { jh = bh2jh(bh); jh->b_jcount++; 555e: 83 40 08 01 addl $0x1,0x8(%rax) */ static __always_inline void clear_bit(long nr, volatile unsigned long *addr) { if (IS_IMMEDIATE(nr)) { asm volatile(LOCK_PREFIX "andb %1,%0" 5562: f0 80 67 03 fe lock andb $0xfe,0x3(%rdi) } jbd_unlock_bh_journal_head(bh); return jh; } 5567: 5d pop %rbp 5568: c3 retq 5569: f3 90 pause } static __always_inline int constant_test_bit(long nr, const volatile unsigned long *addr) { return ((1UL << (nr & (BITS_PER_LONG-1))) & (addr[nr >> _BITOPS_LONG_SHIFT])) != 0; 556b: 48 8b 07 mov (%rdi),%rax 556e: a9 00 00 00 01 test $0x1000000,%eax 5573: 75 f4 jne 5569 <jbd2_journal_grab_journal_head+0x29> preempt_disable(); 5575: eb d2 jmp 5549 <jbd2_journal_grab_journal_head+0x9> * Grab a ref against this buffer_head's journal_head. If it ended up not * having a journal_head, return NULL */ struct journal_head *jbd2_journal_grab_journal_head(struct buffer_head *bh) { struct journal_head *jh = NULL; 5577: 31 c0 xor %eax,%eax 5579: eb e7 jmp 5562 <jbd2_journal_grab_journal_head+0x22> 557b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) 0000000000005580 <jbd2_journal_put_journal_head>: /* * Drop a reference on the passed journal_head. If it fell to zero then * release the journal_head from the buffer_head. */ void jbd2_journal_put_journal_head(struct journal_head *jh) { 5580: e8 00 00 00 00 callq 5585 <jbd2_journal_put_journal_head+0x5> 5585: 55 push %rbp 5586: 48 89 e5 mov %rsp,%rbp 5589: 41 54 push %r12 558b: 53 push %rbx /* * Drop a reference on the passed journal_head. If it fell to zero then * release the journal_head from the buffer_head. */ void jbd2_journal_put_journal_head(struct journal_head *jh) 558c: 48 8b 1f mov (%rdi),%rbx * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ static inline int test_and_set_bit(long nr, volatile unsigned long *addr) { GEN_BINARY_RMWcc(LOCK_PREFIX "bts", *addr, "Ir", nr, "%0", "c"); 558f: f0 0f ba 2b 18 lock btsl $0x18,(%rbx) 5594: 72 1f jb 55b5 <jbd2_journal_put_journal_head+0x35> { struct buffer_head *bh = jh2bh(jh); jbd_lock_bh_journal_head(bh); J_ASSERT_JH(jh, jh->b_jcount > 0); 5596: 8b 47 08 mov 0x8(%rdi),%eax 5599: 85 c0 test %eax,%eax 559b: 0f 8e be 00 00 00 jle 565f <jbd2_journal_put_journal_head+0xdf> --jh->b_jcount; 55a1: 83 e8 01 sub $0x1,%eax if (!jh->b_jcount) { 55a4: 85 c0 test %eax,%eax { struct buffer_head *bh = jh2bh(jh); jbd_lock_bh_journal_head(bh); J_ASSERT_JH(jh, jh->b_jcount > 0); --jh->b_jcount; 55a6: 89 47 08 mov %eax,0x8(%rdi) if (!jh->b_jcount) { -- To unsubscribe from this list: send the line "unsubscribe linux-ext4" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html