Date: Sat, 23 Jun 2018 21:03:02 +0000 From: Rick Macklem <rmacklem@uoguelph.ca> To: "freebsd-current@freebsd.org" <freebsd-current@freebsd.org> Cc: "kib@FreeBSD.org" <kib@FreeBSD.org>, Alexander Motin <mav@FreeBSD.org> Subject: nfsd kernel threads won't die via SIGKILL Message-ID: <YTXPR0101MB0959B4E960B85ACAC07B819DDD740@YTXPR0101MB0959.CANPRD01.PROD.OUTLOOK.COM>
next in thread | raw e-mail | index | archive | help
During testing of the pNFS server I have been frequently killing/restarting=
the nfsd.
Once in a while, the "slave" nfsd process doesn't terminate and a "ps axHl"=
shows:
0 48889 1 0 20 0 5884 812 svcexit D - 0:00.01 nfsd: ser=
ver=20
0 48889 1 0 40 0 5884 812 rpcsvc I - 0:00.00 nfsd: ser=
ver=20
... more of the same
0 48889 1 0 40 0 5884 812 rpcsvc I - 0:00.00 nfsd: ser=
ver=20
0 48889 1 0 -8 0 5884 812 rpcsvc I - 1:51.78 nfsd: ser=
ver=20
0 48889 1 0 -8 0 5884 812 rpcsvc I - 2:27.75 nfsd: ser=
ver=20
You can see that the top thread (the one that was created with the process)=
is
stuck in "D" on "svcexit".
The rest of the threads are still servicing NFS RPCs. If you still have an =
NFS mount on
the server, the mount continues to work and the CPU time for the last two t=
hreads
slowly climbs, due to NFS RPC activity. A SIGKILL was posted for the proces=
s and
these threads (created by kthread_add) are here, but the
cv_wait_sig/cv_timedwait_sig never seems to return EINTR for these other th=
reads.
if (ismaster || (!ismaster &&
1207 grp->sg_threadcount > grp->sg_minthreads)=
)
1208 error =3D cv_timedwait_sig(&st->st_co=
nd,
1209 &grp->sg_lock, 5 * hz);
1210 else
1211 error =3D cv_wait_sig(&st->st_cond,
1212 &grp->sg_lock);
The top thread (referred to in svc.c as "ismaster" did return from here wit=
h EINTR
and has now done an msleep() here, waiting for the other threads to termina=
te.
/* Waiting for threads to stop. */
1387 for (g =3D 0; g < pool->sp_groupcount; g++) {
1388 grp =3D &pool->sp_groups[g];
1389 mtx_lock(&grp->sg_lock);
1390 while (grp->sg_threadcount > 0)
1391 msleep(grp, &grp->sg_lock, 0, "svcexit", 0);
1392 mtx_unlock(&grp->sg_lock);
1393 }
Although I can't be sure if this patch has fixed the problem because it hap=
pens
intermittently, I have not seen the problem since applying this patch:
--- rpc/svc.c.sav 2018-06-21 22:52:11.623955000 -0400
+++ rpc/svc.c 2018-06-22 09:01:40.271803000 -0400
@@ -1388,7 +1388,7 @@ svc_run(SVCPOOL *pool)
grp =3D &pool->sp_groups[g];
mtx_lock(&grp->sg_lock);
while (grp->sg_threadcount > 0)
- msleep(grp, &grp->sg_lock, 0, "svcexit", 0);
+ msleep(grp, &grp->sg_lock, 0, "svcexit", 1);
mtx_unlock(&grp->sg_lock);
}
}
As you can see, all it does is add a timeout to the msleep().=20
I am not familiar with the signal delivery code in sleepqeue, so it probabl=
y
isn't correct, but my theory is alonge the lines of...
Since the msleep() doesn't have PCATCH, it does not set TDF_SINTR
and if that happens before the other threads return EINTR from cv_wait_sig(=
),
they no longer do so?
And I thought that waking up from the msleep() via timeouts would maybe all=
ow
the other threads to return EINTR from cv_wait_sig()?
Does this make sense? rick
ps: I'll post if I see the problem again with the patch applied.
pss: This is a single core i386 system, just in case that might affect this=
.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?YTXPR0101MB0959B4E960B85ACAC07B819DDD740>
