Alexander Bluhm <alexander.bl...@gmx.net> wrote:

> On Thu, Nov 26, 2020 at 04:51:23PM +0100, Marcus MERIGHI wrote:
> > Starting stack trace...
> > panic(ffffffff81de557b) at panic+0x11d
> > kerntrap(ffff8000229c1630) at kerntrap+0x114
> > alltraps_kern_meltdown() at alltraps_kern_meltdown+0x7b
> > fill_file(ffff800000ca8000,fffffd811c6a23d0,fffffd81012516f8,3,0,ffff800022735658)
> >  at fil6
> > sysctl_file(ffff8000229c1c58,4,b4769963000,ffff8000229c1c88,ffff8000227d8c98)
> >  at sysctl_f2
> > kern_sysctl(ffff8000229c1c54,5,b4769963000,ffff8000229c1c88,0,0) at 
> > kern_sysctl+0x1d1
> > sys_sysctl(ffff8000227d8c98,ffff8000229c1cf0,ffff8000229c1d50) at 
> > sys_sysctl+0x184
> > syscall(ffff8000229c1dc0) at syscall+0x389
> > Xsyscall() at Xsyscall+0x128
> > end of kernel
> 
> This trace looks like a bug in the fstat sysctl.  I guess that
> NET_LOCK() sleeps and the allprocess ps_list is not protected.

sysctl_file should grab all the locks it needs at the top, and not
grab/release locks along the way.

sysctl_file is a O(n) fancy bcopy, copying elements from a list, into a
different list.

If n is 1000, and each file structured contains 25 fields to copy, this
remains cheap enough and network is slow enough that a single lock at the
top will be better than dancing around lock/unlock for each n.

This dance is buggy because of sleeps.  But even if it wasn't sleeping, each
O is now *more expensive*.

Finally, this sysctl is not supposed to return an arbitrary error (EBUSY),
which fstat will report to the user.   That is not in the contract for
either sysctl(2) (EBUSY is not a listed error), of fstat(8).  Everything
suggests this must succeed, as it did in the previous decades.  It also
matches expectations... because sysctl_file() is just a fancy bcopy.

Reply via email to