Date: Tue, 20 Feb 2007 11:59:02 +0100 From: Rink Springer <rink@FreeBSD.org> To: stable@FreeBSD.org Cc: roel@qsp.nl Subject: Deadlock in state 'sysctl lock' Message-ID: <20070220105902.GC39393@rink.nu>
next in thread | raw e-mail | index | archive | help
Hi people, At work, one of our SpamAssassin/ClamAV filtering machines just entered a deadlock state: FreeBSD/i386 (xxx.qsp.nl) (cuad0) login: root load: 0.00 cmd: login 683 [sysctl lock] 0.00u 0.00s 0% 148k load: 0.00 cmd: login 683 [sysctl lock] 0.00u 0.00s 0% 148k load: 0.00 cmd: login 683 [sysctl lock] 0.00u 0.00s 0% 148k load: 0.00 cmd: login 683 [sysctl lock] 0.00u 0.00s 0% 148k load: 0.00 cmd: login 683 [sysctl lock] 0.00u 0.00s 0% 148k After inspection, I believe the following code in kern/kern_sysctl.c:userland_sysctl() is the culprit: SYSCTL_LOCK(); do { req.oldidx =3D 0; req.newidx =3D 0; error =3D sysctl_root(0, name, namelen, &req); } while (error =3D=3D EAGAIN); if (req.lock =3D=3D REQ_WIRED && req.validlen > 0) vsunlock(req.oldptr, req.validlen); SYSCTL_UNLOCK(); Clearly, should sysctl_root() always return EAGAIN, this will cause a serious deadlock condition. It appears this is possible. The only plausible reference to sysctl's returning EGAIN seems to be in=20 kern/kern_proc.c:sysctl_out_proc(). However, this code returns ESRCH if the process couldn't have been found in the fast place, and since the complete handler function will be called by sysctl_root() every iteration, and thus will do a pfind() and return ESRCH if it failed and not EAGAIN as it will later on in the code path. The machine is a 6.0-STABLE SMP machine of 30-Mar-2006. No debugging options are in the kernel as the machine has quite some load. The only console messages were a lot of 'calcru' messages. Any help is very much appreciated. For now, I'd like to propose a change to kern/kern_sysctl.c:userland_sysctl(), to ensure this will never keep looping on EAGAIN states (preferably, it should trigger a panic or at least a KASSERT should such a condition occour). I know this is a bandaid for a problem we don't really quite understand yet, but this may ease debugging later on (especially as it will help us understand where exactly it is going bad) Any comments? It looks to me this deadlock is quite rare (in fact, I've never seen it before), but I believe it is serious enough to be addressed, even with such a bandaid until the real solution is presented by someone who knows the sysctl internals better than I do. Thanks, --=20 Rink P.W. Springer - http://rink.nu "It is such a quiet thing, to fall. But yet a far more terrible thing, to admit it." - Darth Traya
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070220105902.GC39393>