From nobody@FreeBSD.org  Thu May  1 08:00:05 2008
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 303871065674
	for <freebsd-gnats-submit@FreeBSD.org>; 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 <freebsd-gnats-submit@FreeBSD.org>; 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 <freebsd-gnats-submit@FreeBSD.org>; 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 <arthur.hartwig@nokia.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Infinite loop in kernel on removal of USB serial adapter syslogd writes to
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         123288
>Category:       kern
>Synopsis:       [syslog] Infinite loop in kernel on removal of USB serial adapter syslogd writes to
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    gavin
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu May 01 08:10:01 UTC 2008
>Closed-Date:    Tue May 20 18:28:16 UTC 2008
>Last-Modified:  Tue May 20 18:28:16 UTC 2008
>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<x> device, login as root so syslogd uses /dev/ttyU<x> for syslog output. After verifying syslogd is using /dev/ttyU<x> as output device remove USB serial adapter.

It may not be necessary to login on the ttyU<x> 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:
State-Changed-From-To: open->feedback 
State-Changed-By: gavin 
State-Changed-When: Thu May 1 14:29:47 UTC 2008 
State-Changed-Why:  
To submitter:  Is this a duplicate of http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/122977 
or am I missing a subtle difference? 


Responsible-Changed-From-To: freebsd-bugs->gavin 
Responsible-Changed-By: gavin 
Responsible-Changed-When: Thu May 1 14:29:47 UTC 2008 
Responsible-Changed-Why:  
Track 

http://www.freebsd.org/cgi/query-pr.cgi?pr=123288 

From: Arthur Hartwig <Arthur.Hartwig@nokia.com>
To: bug-followup@FreeBSD.org, arthur.hartwig@nokia.com
Cc:  
Subject: Re: kern/123288: [syslog] Infinite loop in kernel on removal of USB
 serial adapter syslogd writes to
Date: Mon, 19 May 2008 18:19:11 +1000

 Hi Gavin,
     My apologies, it is a duplicate of 122977.
 
 Arthur
State-Changed-From-To: feedback->closed 
State-Changed-By: gavin 
State-Changed-When: Tue May 20 18:26:52 UTC 2008 
State-Changed-Why:  
Close, submitter confirms that this is a duplicate of kern/122977 

http://www.freebsd.org/cgi/query-pr.cgi?pr=123288 
>Unformatted:
