Panic: mutex Giant not owned cam_xpt.c :4799
Scott Long
scottl at samsco.org
Wed Oct 24 15:04:03 PDT 2007
Attached is a better patch. Once I was able to reproduce the problem
myself, I saw some other issues that needed fixing.
Scott
Steven Brown wrote:
> Just decided to try out the 0907 snapshot of -CURRENT (amd64) and it
> won't boot off the install CD
>
> Thought I would post as much info as I could for interested parties. I
> have to copy by hand, so I will try to include as much as I can.
>
> panic: mutex Giant not owned at /usr/src/sys/cam/cam_xpt.c :4799
>
> This error occurs right after "md0: Preloaded image </boot/mfsroot> ....
>
> The motherboard is an Asus P5M2-R, with dual bge ethernets (on mb), a
> Adaptec 3405 SATA/SAS RAID PCI-e card (aac driver), and has an Intel
> Q6600 quad core. 4GB of RAM. You will soon see why I included the
> information on the Adaptec card.
>
> This hardware works fine using 6.2-RELEASE p8 -- well, at least i386
> does. This system has a modified src/sys/dev/aac which includes the
> vendor ID info for the 3405/3805 cards and has no problems booting (and
> running), detecting Adaptec card, etc.
>
> I also have a CD with the same snapshot (CURRENT, 0907) in an i386
> version (not AMD64) which appears to produce the same error.
>
> Upon the panic, the system entered the debugger and I typed "trace" to
> get the following from AMD64 snapshot:
>
> Tracing pid 26 tid 100026 td 0xffffff0002245680
> kdb_enter() at kdb_enter+0x31
> panic() at panic+0x173
> _mtx_assert() at _mtx_assert+0xd6
> xpt_release_simq() at xpt_release_simq()+0x27
> aac_alloc_commands() at aac_alloc_commands()+0x156
> aac_command_thread() at aac_command_thread()+0xe5
> fork_exit() at fork_exit+0x12a
> fork_trampoline() at fork_trampoline()+0xe
> --- trap 0, rip = 0, rsp = 0xffffffffac6fdd30, rbp = 0 ---
>
>
> Hope this helps someone,
>
> Steve
> _______________________________________________
> freebsd-current at freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-current
> To unsubscribe, send any mail to "freebsd-current-unsubscribe at freebsd.org"
-------------- next part --------------
Index: aac.c
===================================================================
RCS file: /usr/ncvs/src/sys/dev/aac/aac.c,v
retrieving revision 1.122
diff -u -r1.122 aac.c
--- aac.c 20 Oct 2007 23:23:13 -0000 1.122
+++ aac.c 24 Oct 2007 21:58:00 -0000
@@ -1310,9 +1310,12 @@
aac_enqueue_free(cm);
+ /*
+ * Dequeue all events so that there's no risk of events getting
+ * stranded.
+ */
sc = cm->cm_sc;
- event = TAILQ_FIRST(&sc->aac_ev_cmfree);
- if (event != NULL) {
+ while ((event = TAILQ_FIRST(&sc->aac_ev_cmfree)) != NULL) {
TAILQ_REMOVE(&sc->aac_ev_cmfree, event, ev_links);
event->ev_callback(sc, event, event->ev_arg);
}
Index: aac_cam.c
===================================================================
RCS file: /usr/ncvs/src/sys/dev/aac/aac_cam.c,v
retrieving revision 1.28
diff -u -r1.28 aac_cam.c
--- aac_cam.c 17 Jun 2007 05:55:45 -0000 1.28
+++ aac_cam.c 24 Oct 2007 21:36:20 -0000
@@ -103,13 +103,17 @@
static void
aac_cam_event(struct aac_softc *sc, struct aac_event *event, void *arg)
{
+ union ccb *ccb;
struct aac_cam *camsc;
switch (event->ev_type) {
case AAC_EVENT_CMFREE:
- camsc = arg;
+ ccb = arg;
+ camsc = ccb->ccb_h.sim_priv.entries[0].ptr;
free(event, M_AACCAM);
xpt_release_simq(camsc->sim, 1);
+ ccb->ccb_h.status = CAM_REQUEUE_REQ;
+ xpt_done(ccb);
break;
default:
device_printf(sc->aac_dev, "unknown event %d in aac_cam\n",
@@ -131,19 +135,21 @@
static int
aac_cam_detach(device_t dev)
{
+ struct aac_softc *sc;
struct aac_cam *camsc;
debug_called(2);
camsc = (struct aac_cam *)device_get_softc(dev);
+ sc = camsc->inf->aac_sc;
- mtx_lock(&Giant);
+ mtx_lock(&sc->aac_io_lock);
xpt_async(AC_LOST_DEVICE, camsc->path, NULL);
xpt_free_path(camsc->path);
xpt_bus_deregister(cam_sim_path(camsc->sim));
cam_sim_free(camsc->sim, /*free_devq*/TRUE);
- mtx_unlock(&Giant);
+ mtx_unlock(&sc->aac_io_lock);
return (0);
}
@@ -171,15 +177,17 @@
return (EIO);
sim = cam_sim_alloc(aac_cam_action, aac_cam_poll, "aacp", camsc,
- device_get_unit(dev), &Giant, 1, 1, devq);
+ device_get_unit(dev), &inf->aac_sc->aac_io_lock, 1, 1, devq);
if (sim == NULL) {
cam_simq_free(devq);
return (EIO);
}
/* Since every bus has it's own sim, every bus 'appears' as bus 0 */
+ mtx_lock(&inf->aac_sc->aac_io_lock);
if (xpt_bus_register(sim, dev, 0) != CAM_SUCCESS) {
cam_sim_free(sim, TRUE);
+ mtx_unlock(&inf->aac_sc->aac_io_lock);
return (EIO);
}
@@ -187,8 +195,10 @@
CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
xpt_bus_deregister(cam_sim_path(sim));
cam_sim_free(sim, TRUE);
+ mtx_unlock(&inf->aac_sc->aac_io_lock);
return (EIO);
}
+ mtx_unlock(&inf->aac_sc->aac_io_lock);
camsc->sim = sim;
camsc->path = path;
@@ -321,27 +331,23 @@
/* Async ops that require communcation with the controller */
- mtx_lock(&sc->aac_io_lock);
if (aac_alloc_command(sc, &cm)) {
struct aac_event *event;
xpt_freeze_simq(sim, 1);
- ccb->ccb_h.status = CAM_REQUEUE_REQ;
- xpt_done(ccb);
+ ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
+ ccb->ccb_h.sim_priv.entries[0].ptr = camsc;
event = malloc(sizeof(struct aac_event), M_AACCAM,
M_NOWAIT | M_ZERO);
if (event == NULL) {
device_printf(sc->aac_dev,
"Warning, out of memory for event\n");
- /* XXX Yuck, what to do here? */
- mtx_unlock(&sc->aac_io_lock);
return;
}
event->ev_callback = aac_cam_event;
- event->ev_arg = camsc;
+ event->ev_arg = ccb;
event->ev_type = AAC_EVENT_CMFREE;
aac_add_event(sc, event);
- mtx_unlock(&sc->aac_io_lock);
return;
}
@@ -429,7 +435,6 @@
} else {
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
- mtx_unlock(&sc->aac_io_lock);
return;
}
default:
@@ -460,8 +465,6 @@
aac_enqueue_ready(cm);
aac_startio(cm->cm_sc);
- mtx_unlock(&sc->aac_io_lock);
-
return;
}
@@ -565,7 +568,6 @@
return (CAM_REQ_ABORTED);
}
- mtx_lock(&sc->aac_io_lock);
aac_alloc_sync_fib(sc, &fib);
vmi = (struct aac_vmioctl *)&fib->data[0];
@@ -586,12 +588,10 @@
device_printf(sc->aac_dev,"Error %d sending ResetBus command\n",
e);
aac_release_sync_fib(sc);
- mtx_unlock(&sc->aac_io_lock);
return (CAM_REQ_ABORTED);
}
aac_release_sync_fib(sc);
- mtx_unlock(&sc->aac_io_lock);
return (CAM_REQ_CMP);
}
More information about the freebsd-current
mailing list