FreeBSD Bugzilla – Attachment 162814 Details for
Bug 204298
xpt_release_device() panic: mutex CAM queue lock not owned
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Alternative patch
zzz2.patch (text/plain), 2.67 KB, created by
Alexander Motin
on 2015-11-05 14:24:20 UTC
(
hide
)
Description:
Alternative patch
Filename:
MIME Type:
Creator:
Alexander Motin
Created:
2015-11-05 14:24:20 UTC
Size:
2.67 KB
patch
obsolete
>Index: cam_xpt.c >=================================================================== >--- cam_xpt.c (revision 290391) >+++ cam_xpt.c (working copy) >@@ -2901,7 +2901,24 @@ call_sim: > */ > start_ccb->ccb_h.flags &= ~CAM_DEV_QFREEZE; > callout_stop(&dev->callout); >+ /* >+ * If CAM_DEV_REL_TIMEOUT_PENDING is still >+ * set, then the callout is still >+ * cancelable, since we hold the callout >+ * mutex and the callout function clears the >+ * flag before it ever unlocks/relocks the >+ * mutex. Since we already acquired a >+ * device ref for the callout we just >+ * stopped, we don't need another ref. >+ */ > } else { >+ /* >+ * Since the callout gets a pointer to the >+ * device, acquire a reference to make sure >+ * the device can't go away until the >+ * callout finishes or is stopped. >+ */ >+ xpt_acquire_device(dev); > > start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE; > } >@@ -4308,8 +4325,10 @@ xpt_release_devq_timeout(void *arg) > CAM_DEBUG_DEV(dev, CAM_DEBUG_TRACE, ("xpt_release_devq_timeout\n")); > devq = dev->sim->devq; > mtx_assert(&devq->send_mtx, MA_OWNED); >+ dev->flags &= ~CAM_DEV_REL_TIMEOUT_PENDING; > if (xpt_release_devq_device(dev, /*count*/1, /*run_queue*/TRUE)) > xpt_run_devq(devq); >+ xpt_release_device(dev); > } > > void >@@ -4345,20 +4364,11 @@ xpt_release_devq_device(struct cam_ed *dev, u_int > } > dev->ccbq.queue.qfrozen_cnt -= count; > if (dev->ccbq.queue.qfrozen_cnt == 0) { >+ KASSERT((dev->flags & CAM_DEV_REL_ON_COMPLETE) == 0, >+ ("released the queue while still waiting for completion")); >+ KASSERT((dev->flags & CAM_DEV_REL_TIMEOUT_PENDING) == 0, >+ ("released the queue while still having timeout pending")); > /* >- * No longer need to wait for a successful >- * command completion. >- */ >- dev->flags &= ~CAM_DEV_REL_ON_COMPLETE; >- /* >- * Remove any timeouts that might be scheduled >- * to release this queue. >- */ >- if ((dev->flags & CAM_DEV_REL_TIMEOUT_PENDING) != 0) { >- callout_stop(&dev->callout); >- dev->flags &= ~CAM_DEV_REL_TIMEOUT_PENDING; >- } >- /* > * Now that we are unfrozen schedule the > * device so any pending transactions are > * run. >@@ -4745,10 +4755,9 @@ xpt_release_device(struct cam_ed *device) > ("destroying device, but periphs list is not empty")); > KASSERT(device->devq_entry.index == CAM_UNQUEUED_INDEX, > ("destroying device while still queued for ccbs")); >+ KASSERT((device->flags & CAM_DEV_REL_TIMEOUT_PENDING) == 0, >+ ("destroying device while still having timeout pending")); > >- if ((device->flags & CAM_DEV_REL_TIMEOUT_PENDING) != 0) >- callout_stop(&device->callout); >- > xpt_release_target(device->target); > > cam_ccbq_fini(&device->ccbq);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 204298
:
162793
| 162814 |
162840