summaryrefslogtreecommitdiffstats
path: root/sys/cam/scsi/scsi_enc.c
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2012-05-25 07:57:17 +0000
committermav <mav@FreeBSD.org>2012-05-25 07:57:17 +0000
commitc6d017514ef1fb2ef61823af78216702fbef2124 (patch)
treeeda68d68ed0fa19e05f7d4ca50e39c4772f7f1b2 /sys/cam/scsi/scsi_enc.c
parent08b1ccfacce95df401456f108afbeaab596dfe2b (diff)
downloadFreeBSD-src-c6d017514ef1fb2ef61823af78216702fbef2124.zip
FreeBSD-src-c6d017514ef1fb2ef61823af78216702fbef2124.tar.gz
Remove sleep() from invalidate call in ses driver, waiting for daemon
process exit. Instead use CAM's standard reference counting to prevent periph going away until process won't complete. I think that sleep in single CAM SWI thread is not a good idea and may lead to deadlocks if daemon process waits for some command completion. Combined with recent patch avoiding use of CAM SWI for ATA it just causes panics because of sleeps prohibited in interrupt thread context.
Diffstat (limited to 'sys/cam/scsi/scsi_enc.c')
-rw-r--r--sys/cam/scsi/scsi_enc.c18
1 files changed, 8 insertions, 10 deletions
diff --git a/sys/cam/scsi/scsi_enc.c b/sys/cam/scsi/scsi_enc.c
index 03e43bc..b1868a6 100644
--- a/sys/cam/scsi/scsi_enc.c
+++ b/sys/cam/scsi/scsi_enc.c
@@ -136,15 +136,8 @@ enc_oninvalidate(struct cam_periph *periph)
*/
enc->enc_flags |= ENC_FLAG_SHUTDOWN;
if (enc->enc_daemon != NULL) {
- /* Signal and wait for the ses daemon to terminate. */
+ /* Signal the ses daemon to terminate. */
wakeup(enc->enc_daemon);
- /*
- * We're called with the SIM mutex held, but we're dropping
- * the update mutex here on sleep. So we have to manually
- * drop the SIM mutex.
- */
- cam_periph_sleep(enc->periph, enc->enc_daemon,
- PUSER, "thtrm", 0);
}
callout_drain(&enc->status_updater);
@@ -839,6 +832,7 @@ enc_daemon(void *arg)
}
enc->enc_daemon = NULL;
cam_periph_unlock(enc->periph);
+ cam_periph_release(enc->periph);
kproc_exit(0);
}
@@ -849,6 +843,9 @@ enc_kproc_init(enc_softc_t *enc)
callout_init_mtx(&enc->status_updater, enc->periph->sim->mtx, 0);
+ if (cam_periph_acquire(enc->periph) != CAM_REQ_CMP)
+ return (ENXIO);
+
result = kproc_create(enc_daemon, enc, &enc->enc_daemon, /*flags*/0,
/*stackpgs*/0, "enc_daemon%d",
enc->periph->unit_number);
@@ -857,7 +854,8 @@ enc_kproc_init(enc_softc_t *enc)
cam_periph_lock(enc->periph);
enc->enc_vec.poll_status(enc);
cam_periph_unlock(enc->periph);
- }
+ } else
+ cam_periph_release(enc->periph);
return (result);
}
@@ -955,7 +953,7 @@ enc_ctor(struct cam_periph *periph, void *arg)
err = enc_kproc_init(enc);
if (err) {
xpt_print(periph->path,
- "error %d string enc_daemon\n", err);
+ "error %d starting enc_daemon\n", err);
goto out;
}
}
OpenPOWER on IntegriCloud