git: 1a7151f79664 - main - cam: Add probes for xpt actions
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 08 Jan 2026 06:24:35 UTC
The branch main has been updated by imp:
URL: https://cgit.FreeBSD.org/src/commit/?id=1a7151f79664644b2e7c8e69427be8b846e9c1a4
commit 1a7151f79664644b2e7c8e69427be8b846e9c1a4
Author: Warner Losh <imp@FreeBSD.org>
AuthorDate: 2026-01-08 06:19:10 +0000
Commit: Warner Losh <imp@FreeBSD.org>
CommitDate: 2026-01-08 06:19:10 +0000
cam: Add probes for xpt actions
cam::xpt:action(union ccb *)
cam::xpt:done((union ccb *)
cam::xpt:async-cb(void *cbarg, uint32_t async_code, struct cam_path
*path, void *async_arg);
Called when xpt_action(), xpt_done*() and the xpt async callbacks are
called.
Sponsored by: Netflix
Reviewed by: adrian
Differential Revision: https://reviews.freebsd.org/D54469
---
share/man/man4/Makefile | 1 +
share/man/man4/dtrace_cam.4 | 42 ++++++++++++++++++++++++++++++++++++++++++
sys/cam/cam_xpt.c | 22 +++++++++++++++++++++-
3 files changed, 64 insertions(+), 1 deletion(-)
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 5ee6eedd89ee..23bb8495975b 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -1009,6 +1009,7 @@ _ccd.4= ccd.4
.if ${MK_CDDL} != "no"
_dtrace_provs= dtrace_audit.4 \
dtrace_callout_execute.4 \
+ dtrace_cam.4 \
dtrace_dtrace.4 \
dtrace_fbt.4 \
dtrace_io.4 \
diff --git a/share/man/man4/dtrace_cam.4 b/share/man/man4/dtrace_cam.4
new file mode 100644
index 000000000000..e5b7ae34c391
--- /dev/null
+++ b/share/man/man4/dtrace_cam.4
@@ -0,0 +1,42 @@
+.\" Copyright (c) 2026 Netflix, Inc
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd December 26, 2025
+.Dt DTRACE_CAM 4
+.Os
+.Sh NAME
+.Nm dtrace_cam
+.Nd a DTrace provider for tracing events related to CAM
+.Sh SYNOPSIS
+.Fn cam::xpt:action "union ccb *ccn"
+.Fn cam::xpt:done "union ccb *ccb"
+.Fn cam::xpt:async-cb "void *cbarg" "uint32_t async_code" "struct cam_path *path" "void *async_Arg"
+.Sh DESCRIPTION
+The
+.Nm cam
+provider allows the tracing of CAM events.
+The
+.Fn cam::xpt_action
+probe fires when a CAM Control Block (ccb) is submitted to a CAM SIM driver.
+The
+.Fn cam::xpt:done
+probe fires when that request completes.
+The
+.Fn cam::xpt:async-cb
+probe fires just before an async callback is called.
+.Sh ARGUMENTS
+.Sh FILES
+.Sh EXAMPLES
+.Sh SEE ALSO
+.Xr dtrace 1 ,
+.Xr SDT 9
+.Sh HISTORY
+The
+.Nm cam
+provider first appeared in
+.Fx
+15.1 and 16.0.
+.Sh AUTHORS
+This manual page was written by
+.An Warner Losh Aq Mt imp@FreeBSD.org .
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index ecf06045ed90..8b42fb2ca6c5 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -70,6 +70,12 @@
#include <cam/scsi/scsi_pass.h>
+/* SDT Probes */
+SDT_PROBE_DEFINE1(cam, , xpt, action, "union ccb *");
+SDT_PROBE_DEFINE1(cam, , xpt, done, "union ccb *");
+SDT_PROBE_DEFINE4(cam, , xpt, async__cb, "void *", "uint32_t",
+ "struct cam_path *", "void *");
+
/* Wild guess based on not wanting to grow the stack too much */
#define XPT_PRINT_MAXLEN 512
#ifdef PRINTF_BUFR_SIZE
@@ -2479,6 +2485,8 @@ xptsetasyncfunc(struct cam_ed *device, void *arg)
device->target->target_id,
device->lun_id);
xpt_gdev_type(&cgd, &path);
+ CAM_PROBE4(xpt, async__cb, csa->callback_arg,
+ AC_FOUND_DEVICE, &path, &cgd);
csa->callback(csa->callback_arg,
AC_FOUND_DEVICE,
&path, &cgd);
@@ -2500,6 +2508,8 @@ xptsetasyncbusfunc(struct cam_eb *bus, void *arg)
CAM_LUN_WILDCARD);
xpt_path_lock(&path);
xpt_path_inq(&cpi, &path);
+ CAM_PROBE4(xpt, async__cb, csa->callback_arg,
+ AC_PATH_REGISTERED, &path, &cpi);
csa->callback(csa->callback_arg,
AC_PATH_REGISTERED,
&path, &cpi);
@@ -2526,6 +2536,7 @@ xpt_action(union ccb *start_ccb)
start_ccb->ccb_h.pinfo.priority != CAM_PRIORITY_NONE,
("%s: queued ccb and CAM_PRIORITY_NONE illegal.", __func__));
+ CAM_PROBE1(xpt, action, start_ccb);
start_ccb->ccb_h.status = CAM_REQ_INPROG;
(*(start_ccb->ccb_h.path->bus->xport->ops->action))(start_ccb);
}
@@ -4260,6 +4271,8 @@ xpt_async_bcast(struct async_list *async_head,
path->device->sim->mtx : NULL;
if (mtx)
mtx_lock(mtx);
+ CAM_PROBE4(xpt, async__cb, cur_entry->callback_arg,
+ async_code, path, async_arg);
cur_entry->callback(cur_entry->callback_arg,
async_code, path,
async_arg);
@@ -4499,8 +4512,10 @@ xpt_done(union ccb *done_ccb)
done_ccb->ccb_h.func_code,
xpt_action_name(done_ccb->ccb_h.func_code),
done_ccb->ccb_h.status));
- if ((done_ccb->ccb_h.func_code & XPT_FC_QUEUED) == 0)
+ if ((done_ccb->ccb_h.func_code & XPT_FC_QUEUED) == 0) {
+ CAM_PROBE1(xpt, done, done_ccb);
return;
+ }
/* Store the time the ccb was in the sim */
done_ccb->ccb_h.qos.periph_data = cam_iosched_delta_t(done_ccb->ccb_h.qos.periph_data);
@@ -5376,6 +5391,11 @@ xpt_done_process(struct ccb_hdr *ccb_h)
}
}
+ /*
+ * Call as late as possible. Do we want an early one too before the
+ * unfreeze / releases above?
+ */
+ CAM_PROBE1(xpt, done, (union ccb *)ccb_h); /* container_of? */
/* Call the peripheral driver's callback */
ccb_h->pinfo.index = CAM_UNQUEUED_INDEX;
(*ccb_h->cbfcnp)(ccb_h->path->periph, (union ccb *)ccb_h);