Back out scanning file descriptors with holding a process lock.
selrecord() requires allproc sx in pfind(), resulting in lock order reversal between allproc and a process lock.
This commit is contained in:
parent
cd189e1195
commit
1b36970495
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=76618
@ -768,13 +768,29 @@ select(p, uap)
|
||||
retry:
|
||||
ncoll = nselcoll;
|
||||
p->p_flag |= P_SELECT;
|
||||
PROC_UNLOCK(p);
|
||||
error = selscan(p, ibits, obits, uap->nd);
|
||||
PROC_LOCK(p);
|
||||
if (error || p->p_retval[0])
|
||||
goto done;
|
||||
if (atv.tv_sec || atv.tv_usec) {
|
||||
getmicrouptime(&rtv);
|
||||
if (timevalcmp(&rtv, &atv, >=))
|
||||
if (timevalcmp(&rtv, &atv, >=)) {
|
||||
/*
|
||||
* An event of our interest may occur during locking a process.
|
||||
* In order to avoid missing the event that occured during locking
|
||||
* the process, test P_SELECT and rescan file descriptors if
|
||||
* necessary.
|
||||
*/
|
||||
if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) {
|
||||
ncoll = nselcoll;
|
||||
p->p_flag |= P_SELECT;
|
||||
PROC_UNLOCK(p);
|
||||
error = selscan(p, ibits, obits, uap->nd);
|
||||
PROC_LOCK(p);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
ttv = atv;
|
||||
timevalsub(&ttv, &rtv);
|
||||
timo = ttv.tv_sec > 24 * 60 * 60 ?
|
||||
@ -958,13 +974,29 @@ poll(p, uap)
|
||||
retry:
|
||||
ncoll = nselcoll;
|
||||
p->p_flag |= P_SELECT;
|
||||
PROC_UNLOCK(p);
|
||||
error = pollscan(p, (struct pollfd *)bits, nfds);
|
||||
PROC_LOCK(p);
|
||||
if (error || p->p_retval[0])
|
||||
goto done;
|
||||
if (atv.tv_sec || atv.tv_usec) {
|
||||
getmicrouptime(&rtv);
|
||||
if (timevalcmp(&rtv, &atv, >=))
|
||||
if (timevalcmp(&rtv, &atv, >=)) {
|
||||
/*
|
||||
* An event of our interest may occur during locking a process.
|
||||
* In order to avoid missing the event that occured during locking
|
||||
* the process, test P_SELECT and rescan file descriptors if
|
||||
* necessary.
|
||||
*/
|
||||
if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) {
|
||||
ncoll = nselcoll;
|
||||
p->p_flag |= P_SELECT;
|
||||
PROC_UNLOCK(p);
|
||||
error = pollscan(p, (struct pollfd *)bits, nfds);
|
||||
PROC_LOCK(p);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
ttv = atv;
|
||||
timevalsub(&ttv, &rtv);
|
||||
timo = ttv.tv_sec > 24 * 60 * 60 ?
|
||||
|
@ -202,17 +202,31 @@ ncp_sock_rselect(struct socket *so,struct proc *p, struct timeval *tv, int event
|
||||
}
|
||||
timo = 0;
|
||||
PROC_LOCK(p);
|
||||
retry:
|
||||
p->p_flag |= P_SELECT;
|
||||
PROC_UNLOCK(p);
|
||||
error = ncp_poll(so, events);
|
||||
PROC_LOCK(p);
|
||||
if (error) {
|
||||
error = 0;
|
||||
goto done;
|
||||
}
|
||||
if (tv) {
|
||||
getmicrouptime(&rtv);
|
||||
if (timevalcmp(&rtv, &atv, >=))
|
||||
if (timevalcmp(&rtv, &atv, >=)) {
|
||||
/*
|
||||
* An event of our interest may occur during locking a process.
|
||||
* In order to avoid missing the event that occured during locking
|
||||
* the process, test P_SELECT and rescan file descriptors if
|
||||
* necessary.
|
||||
*/
|
||||
if ((p->p_flag & P_SELECT) == 0) {
|
||||
p->p_flag |= P_SELECT;
|
||||
PROC_UNLOCK(p);
|
||||
error = ncp_poll(so, events);
|
||||
PROC_LOCK(p);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
ttv=atv;
|
||||
timevalsub(&ttv, &rtv);
|
||||
timo = tvtohz(&ttv);
|
||||
|
@ -114,17 +114,31 @@ nbssn_rselect(struct nbpcb *nbp, struct timeval *tv, int events, struct proc *p)
|
||||
}
|
||||
timo = 0;
|
||||
PROC_LOCK(p);
|
||||
retry:
|
||||
p->p_flag |= P_SELECT;
|
||||
PROC_UNLOCK(p);
|
||||
error = nb_poll(nbp, events, p);
|
||||
PROC_LOCK(p);
|
||||
if (error) {
|
||||
error = 0;
|
||||
goto done;
|
||||
}
|
||||
if (tv) {
|
||||
getmicrouptime(&rtv);
|
||||
if (timevalcmp(&rtv, &atv, >=))
|
||||
if (timevalcmp(&rtv, &atv, >=)) {
|
||||
/*
|
||||
* An event of our interest may occur during locking a process.
|
||||
* In order to avoid missing the event that occured during locking
|
||||
* the process, test P_SELECT and rescan file descriptors if
|
||||
* necessary.
|
||||
*/
|
||||
if ((p->p_flag & P_SELECT) == 0) {
|
||||
p->p_flag |= P_SELECT;
|
||||
PROC_UNLOCK(p);
|
||||
error = nb_poll(nbp, events, p);
|
||||
PROC_LOCK(p);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
ttv = atv;
|
||||
timevalsub(&ttv, &rtv);
|
||||
timo = tvtohz(&ttv);
|
||||
|
Loading…
Reference in New Issue
Block a user