From owner-freebsd-bugs@FreeBSD.ORG Thu May 1 08:10:01 2008 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9BF941065671 for ; Thu, 1 May 2008 08:10:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 77C398FC13 for ; Thu, 1 May 2008 08:10:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.2/8.14.2) with ESMTP id m418A1nW090244 for ; Thu, 1 May 2008 08:10:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.2/8.14.1/Submit) id m418A1uE090243; Thu, 1 May 2008 08:10:01 GMT (envelope-from gnats) Resent-Date: Thu, 1 May 2008 08:10:01 GMT Resent-Message-Id: <200805010810.m418A1uE090243@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Arthur Hartwig Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 303871065674 for ; Thu, 1 May 2008 08:00:05 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21]) by mx1.freebsd.org (Postfix) with ESMTP id 08ABD8FC0A for ; Thu, 1 May 2008 08:00:05 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.14.2/8.14.2) with ESMTP id m417xOBm051026 for ; Thu, 1 May 2008 07:59:24 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.14.2/8.14.1/Submit) id m417xOCE051025; Thu, 1 May 2008 07:59:24 GMT (envelope-from nobody) Message-Id: <200805010759.m417xOCE051025@www.freebsd.org> Date: Thu, 1 May 2008 07:59:24 GMT From: Arthur Hartwig To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: kern/123288: Infinite loop in kernel on removal of USB serial adapter syslogd writes to X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 01 May 2008 08:10:01 -0000 >Number: 123288 >Category: kern >Synopsis: Infinite loop in kernel on removal of USB serial adapter syslogd writes to >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu May 01 08:10:01 UTC 2008 >Closed-Date: >Last-Modified: >Originator: Arthur Hartwig >Release: 6.3 >Organization: Nokia >Environment: >Description: In devfs_allocv() in fs/devfs/devfs_vnops.c if vget() returns ENOENT the code loops calling vget() the going to label loop the calling vget() then going to label loop etc etc. >How-To-Repeat: Insert USB serial adapter in system, run getty on the created ttyU device, login as root so syslogd uses /dev/ttyU for syslog output. After verifying syslogd is using /dev/ttyU as output device remove USB serial adapter. It may not be necessary to login on the ttyU device if there is another way to get syslogd to use it as an output device. A quick glance at the source code suggests the same problem exists in FreeBSD 7.0. >Fix: If vget() returns ENOENT give up rather than looping indefinitely hoping vget() will eventually return 0. Suggested code patch for FreeBSD 6.3: In devfs_allocv() change loop: DEVFS_DE_HOLD(de); DEVFS_DMP_HOLD(dmp); mtx_lock(&devfs_de_interlock); vp = de->de_vnode; if (vp != NULL) { VI_LOCK(vp); mtx_unlock(&devfs_de_interlock); sx_xunlock(&dmp->dm_lock); error = vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td); sx_xlock(&dmp->dm_lock); if (devfs_allocv_drop_refs(0, dmp, de)) { if (error == 0) vput(vp); return (ENOENT); } else if (error) goto loop; sx_xunlock(&dmp->dm_lock); to loop: DEVFS_DE_HOLD(de); DEVFS_DMP_HOLD(dmp); mtx_lock(&devfs_de_interlock); vp = de->de_vnode; if (vp != NULL) { VI_LOCK(vp); mtx_unlock(&devfs_de_interlock); sx_xunlock(&dmp->dm_lock); error = vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td); sx_xlock(&dmp->dm_lock); if (devfs_allocv_drop_refs(0, dmp, de)) { if (error == 0) vput(vp); return (ENOENT); } else if (error == ENOENT) { sx_xunlock(&dmp->dm_lock); return (ENOENT); } else if (error) goto loop; sx_xunlock(&dmp->dm_lock); I observed this problem on a SMP kernel running on a single CPU system. Its possible the problem might not occur on a MP system in that the locks and unlocks in the loop might give another thread an opportunity to do something (e.g. garbage collect) that causes vget() to return 0 in reasonable time. I have not explored this possibility. >Release-Note: >Audit-Trail: >Unformatted: