svn commit: r358864 - head/sys/cam
Warner Losh
imp at FreeBSD.org
Tue Mar 10 23:59:59 UTC 2020
Author: imp
Date: Tue Mar 10 23:59:58 2020
New Revision: 358864
URL: https://svnweb.freebsd.org/changeset/base/358864
Log:
Eliminate xpt_copy_path.
It's used in exactly one place. In that place it's used so we can hold the lock
on the device associated with the path (since we do a xpt_path_lock and unlock
pair around the callback). Instead, inline taking and dropping the reference to
the device so we can ensure we can unlock the mutex after the callback finishes
if the path in the ccb that's queued to be processed by xpt_scanner_thread is
destroyed while being processed. We don't actually need the path itself for
anything other than dereferencing it to get the device to do the lock and
unlock.
This also makes the locking / use model for cam_path a little cleaner by
eliminating a case where we needlessly copy the object.
Reviewed by: chuck, chs, ken
Differential Revision: https://reviews.freebsd.org/D24008
Modified:
head/sys/cam/cam_xpt.c
head/sys/cam/cam_xpt.h
Modified: head/sys/cam/cam_xpt.c
==============================================================================
--- head/sys/cam/cam_xpt.c Tue Mar 10 23:58:41 2020 (r358863)
+++ head/sys/cam/cam_xpt.c Tue Mar 10 23:59:58 2020 (r358864)
@@ -803,7 +803,8 @@ static void
xpt_scanner_thread(void *dummy)
{
union ccb *ccb;
- struct cam_path path;
+ struct mtx *mtx;
+ struct cam_ed *device;
xpt_lock_buses();
for (;;) {
@@ -815,15 +816,22 @@ xpt_scanner_thread(void *dummy)
xpt_unlock_buses();
/*
- * Since lock can be dropped inside and path freed
- * by completion callback even before return here,
- * take our own path copy for reference.
+ * We need to lock the device's mutex which we use as
+ * the path mutex. We can't do it directly because the
+ * cam_path in the ccb may wind up going away because
+ * the path lock may be dropped and the path retired in
+ * the completion callback. We do this directly to keep
+ * the reference counts in cam_path sane. We also have
+ * to copy the device pointer because ccb_h.path may
+ * be freed in the callback.
*/
- xpt_copy_path(&path, ccb->ccb_h.path);
- xpt_path_lock(&path);
+ mtx = xpt_path_mtx(ccb->ccb_h.path);
+ device = ccb->ccb_h.path->device;
+ xpt_acquire_device(device);
+ mtx_lock(mtx);
xpt_action(ccb);
- xpt_path_unlock(&path);
- xpt_release_path(&path);
+ mtx_unlock(mtx);
+ xpt_release_device(device);
xpt_lock_buses();
}
@@ -3686,15 +3694,6 @@ xpt_clone_path(struct cam_path **new_path_ptr, struct
new_path = (struct cam_path *)malloc(sizeof(*path), M_CAMPATH, M_NOWAIT);
if (new_path == NULL)
return(CAM_RESRC_UNAVAIL);
- xpt_copy_path(new_path, path);
- *new_path_ptr = new_path;
- return (CAM_REQ_CMP);
-}
-
-void
-xpt_copy_path(struct cam_path *new_path, struct cam_path *path)
-{
-
*new_path = *path;
if (path->bus != NULL)
xpt_acquire_bus(path->bus);
@@ -3702,6 +3701,8 @@ xpt_copy_path(struct cam_path *new_path, struct cam_pa
xpt_acquire_target(path->target);
if (path->device != NULL)
xpt_acquire_device(path->device);
+ *new_path_ptr = new_path;
+ return (CAM_REQ_CMP);
}
void
Modified: head/sys/cam/cam_xpt.h
==============================================================================
--- head/sys/cam/cam_xpt.h Tue Mar 10 23:58:41 2020 (r358863)
+++ head/sys/cam/cam_xpt.h Tue Mar 10 23:59:58 2020 (r358864)
@@ -140,8 +140,6 @@ cam_status xpt_compile_path(struct cam_path *new_path
lun_id_t lun_id);
cam_status xpt_clone_path(struct cam_path **new_path,
struct cam_path *path);
-void xpt_copy_path(struct cam_path *new_path,
- struct cam_path *path);
void xpt_release_path(struct cam_path *path);
More information about the svn-src-head
mailing list