Hello,
I was working on some memory related cleaning requirements and as part
of this I tried to force all SLAB allocated memory (this is the
allocator I use in my kernel) to be zeroized before being handed back to
the requester.
So basically in mm/slab.c (__cache_alloc_node() and __cache_alloc()) I
made the optional zeroization (based on __GFP_ZERO) non optional
(forcing __GFP_ZERO in the flags, so always done). Therefore all
allocated memory through these 2 functions is set to 0 before being used
by the kernel.
When doing so, the kernel will fail booting with the following backtrace
(I am testing this on Qemu emulating a versatilepb board with stock
kernel 3.4.4 but I have the same problem on real hardware [i.MX25 based]
with kernel 3.0.3).
...
[0.659312] Trying to unpack rootfs image as initramfs...
[0.666474] Unable to handle kernel NULL pointer dereference at
virtual address 0004
[0.666916] pgd = c0004000
[0.667091] [0004] *pgd=
[0.667601] Internal error: Oops: 805 [#1] PREEMPT ARM
[0.668024] CPU: 0Not tainted (3.4.4 #77)
[0.668691] PC is at inode_lru_list_del+0x2c/0x98
[0.668942] LR is at inode_lru_list_del+0x18/0x98
[0.669180] pc : []lr : [] psr: a013
[0.669197] sp : c789dde8 ip : 0002 fp : c789ddfc
[0.669660] r10: c7a96c30 r9 : c7a96c43 r8 : 0030
[0.670164] r7 : 0001 r6 : c017a550 r5 : c789c000 r4 : c741eed8
[0.670490] r3 : c741ef4c r2 : r1 : r0 : 0001
[0.670933] Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM
Segment kernel
[0.671294] Control: 00093177 Table: 4000 DAC: 0017
[0.671611] Process swapper (pid: 1, stack limit = 0xc789c270)
[0.671957] Stack: (0xc789dde8 to 0xc789e000)
[0.672278] dde0: 0007 c741eed8 c789de1c
c789de00 c00a2588 c00a0b68
[0.672730] de00: 0007 c741eed8 c789c000 c741eed8 c789de34
c789de20 c00a2714 c00a24b8
[0.673137] de20: c741df70 c789de54 c789de38 c009f874
c00a26e4 c741df70
[0.673538] de40: c7402ed8 c789de74 c789de58 c00971f8
c009f76c 0001 c7403f70
[0.674099] de60: c741df70 c01ec998 c789def4 c789de78 c00972fc
c00970d0 c785bf78
[0.674645] de80: c7403f70 01c0d8cc 0004 c7a94000
c789dea0 c7402ed8
[0.675360] dea0: 0002 c78941c0 0002
[0.675967] dec0: 502f13fa 502f13fa
c7a94000
[0.676579] dee0: c7a96c00 c789df04 c789def8 c0097328
c0097218 c789df7c c789df08
[0.677007] df00: c01b6d28 c009731c c789df24 c019e8a8 0001
0009 000241c0
[0.677488] df20: 1000 502f13fa
502f13fa
[0.678020] df40: 173eed84
c789df80 0005 c01c6188
[0.678559] df60: c01b6bf8 c01b41a8 c01d0cf8 c789dfb4
c789df80 c01b48d0 c01b6c04
[0.679050] df80: c031f4dc c789dfb4 c01c61a4 0005
c01c61a8 0005 c01c6188
[0.679544] dfa0: c01eca40 002e c789dff4 c789dfb8 c01b4a9c
c01b483c 0005 0005
[0.680024] dfc0: c01b41a8 c01b49a8 c0019eb0 c01b49a8
c0019eb0 0013
[0.680540] dfe0: c789dff8 c0019eb0
c01b49b4
[0.681055] Backtrace:
[0.681459] [] (inode_lru_list_del+0x0/0x98) from
[] (iput_final+0xdc/0x22c)
[0.682041] r4:c741eed8 r3:0007
[0.682379] [] (iput_final+0x0/0x22c) from []
(iput+0x3c/0x44)
[0.682843] r6:c741eed8 r5:c789c000 r4:c741eed8 r3:0007
[0.683254] [] (iput+0x0/0x44) from []
(d_delete+0x114/0x128)
[0.683632] r4:c741df70 r3:
[0.683887] [] (d_delete+0x0/0x128) from []
(vfs_rmdir+0x134/0x148)
[0.684301] r6: r5:c7402ed8 r4:c741df70 r3:
[0.684707] [] (vfs_rmdir+0x0/0x148) from []
(do_rmdir+0xf0/0x104)
[0.685101] r6:c01ec998 r5:c741df70 r4:c7403f70 r3:0001
[0.685487] [] (do_rmdir+0x0/0x104) from []
(sys_rmdir+0x18/0x1c)
[0.685878] r5: r4:c7a96c00
[0.686200] [] (sys_rmdir+0x0/0x1c) from []
(populate_rootfs+0x130/0x228)
[0.686677] [] (populate_rootfs+0x0/0x228) from
[] (do_one_initcall+0xa0/0x178)
[0.687176] [] (do_one_initcall+0x0/0x178) from
[] (kernel_init+0xf4/0x1bc)
[0.687617] r8:002e r7:c01eca40 r6:c01c6188 r5:0005 r4:c01c61a8
[0.688076] [] (kernel_init+0x0/0x1bc) from []
(do_exit+0x0/0x77c)
[0.688601] Code: e2843074 e1530002 0a10 e5941078 (e5821004)
[0.690985] ---[ end trace 1b75b31a2719ed1c ]---
[0.691426] note: swapper[1] exited with preempt_count 2
[0.692799] Kernel panic - not syncing: Attempted to kill init!
exitcode=0x000b
The fact is, that when inspecting the inode structure passed to
inode_lru_list_del(), some list members seem to be badly set. In my case
the i_lru (and i_wb_list ?) member is