Date: Fri, 4 Apr 2014 12:31:13 +0000 (UTC) From: David Xu <davidxu@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r264114 - head/sys/kern Message-ID: <201404041231.s34CVD2Y078019@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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: /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201404041231.s34CVD2Y078019>