[OpenAFS-devel] Re: 1.3.77 on Linux 2.6.10 (Fedora Core 3 test): patches for partial success

chas williams - CONTRACTOR chas@cmf.nrl.navy.mil
Tue, 11 Jan 2005 14:41:16 -0500


In message <20050107042308.GA24277@jadzia.bu.edu>,Matthew Miller writes:
>Unable to handle kernel paging request at virtual address 0008008e
> printing eip:
>c0131d35
>*pde = 12d54067
>Oops: 0000 [#1]
>DEBUG_PAGEALLOC
>Modules linked in: libafs(U) radeon parport_pc lp parport autofs4 sunrpc iptable_filter ip_tables video button battery ac md5 ipv6 usbled ohci1394 ieee1394 uhci_hcd ehci_hcd i2c_viapro i2c_core snd_via82xx snd_ac97_codec snd_pcm_oss snd_mixer_oss snd_pcm snd_timer snd_page_alloc gameport snd_mpu401_uart snd_rawmidi snd_seq_device snd soundcore sk98lin floppy dm_snapshot dm_zero dm_mirror ext3 jbd dm_mod sata_promise sata_via libata sd_mod scsi_mod
>CPU:    0
>EIP:    0060:[<c0131d35>]    Tainted: P      VLI
>EFLAGS: 00010216   (2.6.10-1.727_FC3) 
>EIP is at bit_waitqueue+0x2f/0x42
>eax: b9b92403   ebx: 0007ff56   ecx: 00000020   edx: 00000003
>esi: e118a120   edi: e11860e4   ebp: e0ce1680   esp: d35c9c7c
>ds: 007b   es: 007b   ss: 0068
>Process ls (pid: 5462, threadinfo=d35c9000 task=d1837aa0)
>Stack: 00000003 c0131cfb e1189f84 e0f413d0 c017a832 e1189f84 e134cbe8 c017aad6 
>       e1189f84 e0f1be5b e1189f84 e0f21969 00000202 00000000 00000000 c964e120 
>       00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
>Call Trace:
> [<c0131cfb>] wake_up_bit+0xb/0x16
> [<e0f413d0>] afs_delete_inode+0x0/0x10 [libafs]
> [<c017a832>] generic_delete_inode+0x20a/0x224
> [<c017aad6>] iput+0x5f/0x61
> [<e0f1be5b>] afs_PutVCache+0x4c/0x93 [libafs]
> [<e0f21969>] afs_DoBulkStat+0x5f8/0x144a [libafs]
> [<e08c4b3a>] __ext3_journal_stop+0x19/0x34 [ext3]
> [<e0f0f3bc>] afs_dir_GetBlob+0xb/0x1e [libafs]
> [<e0f0f45a>] FindItem+0x5c/0xde [libafs]
> [<e0f0f20d>] afs_dir_LookupOffset+0x4c/0x53 [libafs]
> [<e0f230c6>] afs_lookup+0x90b/0xf79 [libafs]

i took a little look at this problem this morning.  its back to 'where
does afs get its inodes'.  the wake_up_bit() mechanism has replaced
'per object' wait queues (atleast when testing for single bit changes).
the actual wait queue to use is determined using a hash on page->flags
(which encodes the zone table in the lower 8 bits).  afs inodes come from
a vmalloc() since afs gets all the inodes in one go.  vmalloc()'d memory
apparently doesnt get mapped to any particular zone.  so when an afs
inode uses wake_up_bit() they index off the end of the zone_page table.

i verified this by forcing afs_osi_Alloc() to always use kmalloc() and
starting afsd with suitably smallish parameters.  works fine.

a real fix?  two options i guess, dont get all the inodes in one go.
its a linked list in memory, so just get them one at a time to make sure
we use kmalloc().  or, and likely a better solution in the long term,
just get inodes the 'normal' way from the kernel (i had some code to
do this at one point and lost it, i have seen some code from a suse
developer as well to do the same thing).