svn commit: r264114 - head/sys/kern
David Xu
davidxu at FreeBSD.org
Fri Apr 4 12:31:14 UTC 2014
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:
/*
More information about the svn-src-all
mailing list