From owner-svn-src-all@FreeBSD.ORG Fri Apr 4 12:31:14 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 1F08BE3A; Fri, 4 Apr 2014 12:31:14 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id F375B8C9; Fri, 4 Apr 2014 12:31:13 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s34CVD0K078020; Fri, 4 Apr 2014 12:31:13 GMT (envelope-from davidxu@svn.freebsd.org) Received: (from davidxu@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s34CVD2Y078019; Fri, 4 Apr 2014 12:31:13 GMT (envelope-from davidxu@svn.freebsd.org) Message-Id: <201404041231.s34CVD2Y078019@svn.freebsd.org> From: David Xu Date: Fri, 4 Apr 2014 12:31:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r264114 - head/sys/kern X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 04 Apr 2014 12:31:14 -0000 Author: davidxu Date: Fri Apr 4 12:31:13 2014 New Revision: 264114 URL: http://svnweb.freebsd.org/changeset/base/264114 Log: Fix SIGIO delivery. Use fsetown() to handle file descriptor owner ioctl and use pgsigio() to send SIGIO. Submitted by: truckman Reviewed by: mjg Modified: head/sys/kern/subr_bus.c Modified: head/sys/kern/subr_bus.c ============================================================================== --- head/sys/kern/subr_bus.c Fri Apr 4 11:19:02 2014 (r264113) +++ head/sys/kern/subr_bus.c Fri Apr 4 12:31:13 2014 (r264114) @@ -391,11 +391,12 @@ static struct dev_softc int inuse; int nonblock; int queued; + int async; struct mtx mtx; struct cv cv; struct selinfo sel; struct devq devq; - struct proc *async_proc; + struct sigio *sigio; } devsoftc; static struct cdev *devctl_dev; @@ -422,7 +423,7 @@ devopen(struct cdev *dev, int oflags, in /* move to init */ devsoftc.inuse = 1; devsoftc.nonblock = 0; - devsoftc.async_proc = NULL; + devsoftc.async = 0; mtx_unlock(&devsoftc.mtx); return (0); } @@ -433,8 +434,8 @@ devclose(struct cdev *dev, int fflag, in mtx_lock(&devsoftc.mtx); devsoftc.inuse = 0; - devsoftc.async_proc = NULL; cv_broadcast(&devsoftc.cv); + funsetown(&devsoftc.sigio); mtx_unlock(&devsoftc.mtx); return (0); } @@ -490,33 +491,21 @@ devioctl(struct cdev *dev, u_long cmd, c devsoftc.nonblock = 0; return (0); case FIOASYNC: - /* - * FIXME: - * Since this is a simple assignment there is no guarantee that - * devsoftc.async_proc consumers will get a valid pointer. - * - * Example scenario where things break (processes A and B): - * 1. A opens devctl - * 2. A sends fd to B - * 3. B sets itself as async_proc - * 4. B exits - * - * However, normally this requires root privileges and the only - * in-tree consumer does not behave in a dangerous way so the - * issue is not critical. - */ if (*(int*)data) - devsoftc.async_proc = td->td_proc; + devsoftc.async = 1; else - devsoftc.async_proc = NULL; + devsoftc.async = 0; + return (0); + case FIOSETOWN: + return fsetown(*(int *)data, &devsoftc.sigio); + case FIOGETOWN: + *(int *)data = fgetown(&devsoftc.sigio); return (0); /* (un)Support for other fcntl() calls. */ case FIOCLEX: case FIONCLEX: case FIONREAD: - case FIOSETOWN: - case FIOGETOWN: default: break; } @@ -560,7 +549,6 @@ void devctl_queue_data_f(char *data, int flags) { struct dev_event_info *n1 = NULL, *n2 = NULL; - struct proc *p; if (strlen(data) == 0) goto out; @@ -590,13 +578,8 @@ devctl_queue_data_f(char *data, int flag cv_broadcast(&devsoftc.cv); mtx_unlock(&devsoftc.mtx); selwakeup(&devsoftc.sel); - /* XXX see a comment in devioctl */ - p = devsoftc.async_proc; - if (p != NULL) { - PROC_LOCK(p); - kern_psignal(p, SIGIO); - PROC_UNLOCK(p); - } + if (devsoftc.async && devsoftc.sigio != NULL) + pgsigio(&devsoftc.sigio, SIGIO, 0); return; out: /*