0c8f059c29
My changes in 351599 (kindly committed by avg) made the cd(4) media check asynchronous to avoid a sleep while holding a mutex. There was a difficult to reproduce bug with those changes that caused a hang on boot on some single processor machines/VMs. Leandro Lupori managed to reproduce the bug, diagnose it, and supplied a patch! Here is his analysis, from the PR: ====== I was able to reproduce the problem described in comment#14. Actually, I wasn't trying to reproduce it, I just started seeing it a few weeks ago, in CURRENT. I can reproduce it consistently, by using QEMU to run a PowerPC64 VM with a single core/thread (-smp 1). It happens only when there is no media in the emulated CD-ROM, a device that QEMU adds by default, unless -nodefaults is specified in command line. I've debugged it and this is what I've found: 1- After the CD probe is successful, GEOM will try to open the device, which will end up calling cdcheckmedia(), that sets CD state to CD_STATE_MEDIA_PREVENT. 2- Next, scsi_prevent() is executed and succeeds, the CD_FLAG_DISC_LOCKED flag is set and CD state moves to CD_STATE_MEDIA_SIZE. 3- Next, scsi_read_capacity() is executed and fails, state is set to CD_STATE_MEDIA_ALLOW, cdmediaprobedone() is called and wakes up cdcheckmedia(). 4- Then, when cdstart() is invoked to process CD_STATE_MEDIA_ALLOW, it first checks if CD_FLAG_DISC_LOCKED is set, and if so skips directly to CD_STATE_MEDIA_SIZE state. This will repeat the steps of bullet 3, entering an infinite MEDIA_SIZE command loop. When there is a least another core/thread, the GEOM thread that performed the initial cdopen() will get scheduled again, closing the CD device, that will call cdprevent(PR_ALLOW) that clears the CD_FLAG_DISC_LOCKED flag and breaks the loop. So, apparently, the problem is CD_STATE_MEDIA_ALLOW being skipped when CD_FLAG_DISC_LOCKED is set. If I understand correctly, in this case, the state should be advanced to CD_STATE_MEDIA size only when the current state is CD_STATE_MEDIA_PREVENT. ===== PR: kern/219857 Submitted by: Leandro Lupori <leandro.lupori@gmail.com> MFC after: 1 week |
||
---|---|---|
.. | ||
scsi_all.c | ||
scsi_all.h | ||
scsi_cd.c | ||
scsi_cd.h | ||
scsi_ch.c | ||
scsi_ch.h | ||
scsi_da.c | ||
scsi_da.h | ||
scsi_enc_internal.h | ||
scsi_enc_safte.c | ||
scsi_enc_ses.c | ||
scsi_enc.c | ||
scsi_enc.h | ||
scsi_iu.h | ||
scsi_message.h | ||
scsi_pass.c | ||
scsi_pass.h | ||
scsi_pt.c | ||
scsi_pt.h | ||
scsi_sa.c | ||
scsi_sa.h | ||
scsi_ses.h | ||
scsi_sg.c | ||
scsi_sg.h | ||
scsi_targ_bh.c | ||
scsi_target.c | ||
scsi_targetio.h | ||
scsi_xpt.c | ||
smp_all.c | ||
smp_all.h |