diff options
author | John Baldwin <jhb@FreeBSD.org> | 2021-04-12 20:56:16 +0000 |
---|---|---|
committer | John Baldwin <jhb@FreeBSD.org> | 2021-04-12 20:58:21 +0000 |
commit | 89df484739efe93b52da467f35255ae538bb946b (patch) | |
tree | 02bc506735c21fb23501fc4165a33f6e3d0922ec | |
parent | 568e69e4eb0ad1a5c69d8ea4592a4314bd6b6679 (diff) | |
download | src-89df484739efe93b52da467f35255ae538bb946b.tar.gz src-89df484739efe93b52da467f35255ae538bb946b.zip |
iscsi: Kick threads out of iscsi_ioctl() during unload.
iscsid can be sleeping in iscsi_ioctl() causing the destroy_dev() to
sleep forever if iscsi.ko is unloaded while iscsid is running.
Reported by: Jithesh Arakkan @ Chelsio
Reviewed by: mav
MFC after: 1 week
Sponsored by: Chelsio Communications
Differential Revision: https://reviews.freebsd.org/D29688
-rw-r--r-- | sys/dev/iscsi/iscsi.c | 11 | ||||
-rw-r--r-- | sys/dev/iscsi/iscsi.h | 1 |
2 files changed, 12 insertions, 0 deletions
diff --git a/sys/dev/iscsi/iscsi.c b/sys/dev/iscsi/iscsi.c index 4367f780d84b..13a35c371c40 100644 --- a/sys/dev/iscsi/iscsi.c +++ b/sys/dev/iscsi/iscsi.c @@ -1333,6 +1333,11 @@ iscsi_ioctl_daemon_wait(struct iscsi_softc *sc, } if (is == NULL) { + if (sc->sc_unloading) { + sx_sunlock(&sc->sc_lock); + return (ENXIO); + } + /* * No session requires attention from iscsid(8); wait. */ @@ -2560,6 +2565,12 @@ static int iscsi_unload(void) { + /* Awaken any threads asleep in iscsi_ioctl(). */ + sx_xlock(&sc->sc_lock); + sc->sc_unloading = true; + cv_signal(&sc->sc_cv); + sx_xunlock(&sc->sc_lock); + if (sc->sc_cdev != NULL) { ISCSI_DEBUG("removing device node"); destroy_dev(sc->sc_cdev); diff --git a/sys/dev/iscsi/iscsi.h b/sys/dev/iscsi/iscsi.h index 80ac9d877107..793b7529c7c0 100644 --- a/sys/dev/iscsi/iscsi.h +++ b/sys/dev/iscsi/iscsi.h @@ -132,6 +132,7 @@ struct iscsi_softc { TAILQ_HEAD(, iscsi_session) sc_sessions; struct cv sc_cv; unsigned int sc_last_session_id; + bool sc_unloading; eventhandler_tag sc_shutdown_pre_eh; eventhandler_tag sc_shutdown_post_eh; }; |