scsi_target witness lock error
Hidetoshi Shimokawa
simokawa at FreeBSD.ORG
Tue Dec 11 18:17:29 PST 2007
Hi Sean,
At Tue, 11 Dec 2007 16:53:15 -0800,
Sean Bruno wrote:
>
> While I was debugging some random stuff with the firewire target, I
> noted the following witness lock:
>
> http://www.consultcsg.com/scsitarget_witness.txt
>
> It looks like there is some kind of conflict between the locks in
> sys/cam/scsi/scsi_target.c and the kern environment locks? I'm fairly
> certain that this is an easy fix, but I just don't see how to work
> around it.
>
> Sean
This a patch I sent Scott several months ago.
It may help you. (this is for -current at that time)
/\ Hidetoshi Shimokawa
\/ simokawa at FreeBSD.ORG
Subject: scsi_target and WITNESS
From: Hidetoshi Shimokawa <simokawa at FreeBSD.ORG>
Date: Fri, 01 Jun 2007 11:57:50 +0900
Message-ID: <86vee8pej5.wl%simokawa at FreeBSD.ORG>
Hi Scott,
scsi_target seems to have several problems with WITNESS and MPSAFE sim.
I applied the following patch to workaround recurse/sleep/pagefault
problems. I think you should have a better fix.
=============================================
(cd /usr/src && patch -p6) < diff_to_current
=============================================
--- //depot/vendor/freebsd/src/sys/cam/scsi/scsi_target.c 2007/04/15 08:53:22
+++ //depot/user/simokawa/firewire_lock/sys/cam/scsi/scsi_target.c 2007/05/21 14:31:55
@@ -372,10 +372,14 @@
int retval;
softc = (struct targ_softc *)kn->kn_hook;
+#if 0
cam_periph_lock(softc->periph);
+#endif
retval = !TAILQ_EMPTY(&softc->user_ccb_queue) ||
!TAILQ_EMPTY(&softc->abort_queue);
+#if 0
cam_periph_unlock(softc->periph);
+#endif
return (retval);
}
@@ -585,12 +589,12 @@
cam_periph_unlock(softc->periph);
break;
default:
- cam_periph_lock(softc->periph);
if ((func_code & XPT_FC_QUEUED) != 0) {
CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH,
("Sending queued ccb %#x (%p)\n",
func_code, user_ccb));
descr = targgetdescr(softc);
+ cam_periph_lock(softc->periph);
descr->user_ccb = user_ccb;
descr->priority = priority;
descr->func_code = func_code;
@@ -601,6 +605,7 @@
CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH,
("Sending inline ccb %#x (%p)\n",
func_code, user_ccb));
+ cam_periph_lock(softc->periph);
ccb = targgetccb(softc, func_code, priority);
descr = (struct targ_cmd_descr *)
ccb->ccb_h.targ_descr;
@@ -762,7 +767,9 @@
&& ((ccb_h->flags & CAM_DIR_MASK) != CAM_DIR_NONE))
|| (ccb_h->func_code == XPT_DEV_MATCH))) {
+ cam_periph_unlock(softc->periph);
error = cam_periph_mapmem(ccb, mapinfo);
+ cam_periph_lock(softc->periph);
/*
* cam_periph_mapmem returned an error, we can't continue.
@@ -966,13 +973,16 @@
int ccb_len;
ccb_len = targccblen(type);
+ /* XXX */
+ cam_periph_unlock(softc->periph);
MALLOC(ccb, union ccb *, ccb_len, M_TARG, M_WAITOK);
+ ccb->ccb_h.targ_descr = targgetdescr(softc);
+ cam_periph_lock(softc->periph);
CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, ("getccb %p\n", ccb));
xpt_setup_ccb(&ccb->ccb_h, softc->path, priority);
ccb->ccb_h.func_code = type;
ccb->ccb_h.cbfcnp = targdone;
- ccb->ccb_h.targ_descr = targgetdescr(softc);
return (ccb);
}
@@ -1099,6 +1109,7 @@
static void
notify_user(struct targ_softc *softc)
{
+ mtx_assert(softc->periph->sim->mtx, MA_OWNED);
/*
* Notify users sleeping via poll(), kqueue(), and
* blocking read().
More information about the freebsd-scsi
mailing list