Wire the sysctl output buffer before grabbing any locks to prevent
SYSCTL_OUT() from blocking while locks are held. This should only be done when it would be inconvenient to make a temporary copy of the data and defer calling SYSCTL_OUT() until after the locks are released.
This commit is contained in:
parent
b44ba1a844
commit
5c38b6dbce
@ -2043,6 +2043,7 @@ sysctl_kern_file(SYSCTL_HANDLER_ARGS)
|
||||
int error;
|
||||
struct file *fp;
|
||||
|
||||
sysctl_wire_old_buffer(req, 0);
|
||||
sx_slock(&filelist_lock);
|
||||
if (!req->oldptr) {
|
||||
/*
|
||||
|
@ -193,6 +193,7 @@ sysctl_kern_randompid(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int error, pid;
|
||||
|
||||
sysctl_wire_old_buffer(req, sizeof(int));
|
||||
sx_xlock(&allproc_lock);
|
||||
pid = randompid;
|
||||
error = sysctl_handle_int(oidp, &pid, 0, req);
|
||||
|
@ -1023,6 +1023,7 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS)
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
sysctl_wire_old_buffer(req, 0);
|
||||
sx_slock(&allproc_lock);
|
||||
for (doingzomb=0 ; doingzomb < 2 ; doingzomb++) {
|
||||
if (!doingzomb)
|
||||
|
@ -2652,6 +2652,7 @@ sysctl_vnode(SYSCTL_HANDLER_ARGS)
|
||||
return (SYSCTL_OUT(req, 0,
|
||||
(numvnodes + KINFO_VNODESLOP) * (VPTRSZ + VNODESZ)));
|
||||
|
||||
sysctl_wire_old_buffer(req, 0);
|
||||
mtx_lock(&mountlist_mtx);
|
||||
for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
|
||||
if (vfs_busy(mp, LK_NOWAIT, &mountlist_mtx, td)) {
|
||||
|
@ -841,6 +841,9 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
|
||||
INP_INFO_RUNLOCK(&tcbinfo);
|
||||
splx(s);
|
||||
|
||||
sysctl_wire_old_buffer(req, 2 * (sizeof xig)
|
||||
+ n * sizeof(struct xtcpcb));
|
||||
|
||||
xig.xig_len = sizeof xig;
|
||||
xig.xig_count = n;
|
||||
xig.xig_gen = gencnt;
|
||||
|
@ -841,6 +841,9 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
|
||||
INP_INFO_RUNLOCK(&tcbinfo);
|
||||
splx(s);
|
||||
|
||||
sysctl_wire_old_buffer(req, 2 * (sizeof xig)
|
||||
+ n * sizeof(struct xtcpcb));
|
||||
|
||||
xig.xig_len = sizeof xig;
|
||||
xig.xig_count = n;
|
||||
xig.xig_gen = gencnt;
|
||||
|
@ -598,6 +598,9 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
|
||||
n = udbinfo.ipi_count;
|
||||
splx(s);
|
||||
|
||||
sysctl_wire_old_buffer(req, 2 * (sizeof xig)
|
||||
+ n * sizeof(struct xinpcb));
|
||||
|
||||
xig.xig_len = sizeof xig;
|
||||
xig.xig_count = n;
|
||||
xig.xig_gen = gencnt;
|
||||
|
@ -633,6 +633,7 @@ ncp_sysctl_connstat(SYSCTL_HANDLER_ARGS) {
|
||||
/* struct ucred *cred = req->p->p_ucred;*/
|
||||
|
||||
error = 0;
|
||||
sysctl_wire_old_buffer(req, 0);
|
||||
ncp_conn_locklist(LK_SHARED, req->p);
|
||||
error = SYSCTL_OUT(req, &ncp_conn_cnt, sizeof(ncp_conn_cnt));
|
||||
SLIST_FOREACH(ncp, &conn_list, nc_next) {
|
||||
|
@ -834,6 +834,7 @@ smb_sysctl_treedump(SYSCTL_HANDLER_ARGS)
|
||||
int error, itype;
|
||||
|
||||
smb_makescred(&scred, td, td->td_ucred);
|
||||
sysctl_wire_old_buffer(req, 0);
|
||||
error = smb_sm_lockvclist(LK_SHARED, td);
|
||||
if (error)
|
||||
return error;
|
||||
|
Loading…
Reference in New Issue
Block a user