mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-02 22:54:52 +00:00
cam: Make cam_debug macros atomic
The CAM_DEBUG* macros use multiple printfs to dump the data. This is suboptimal when tracing things that produce even a moderate amount since it gets intertwingled. I can't even turn on tracing with a 24-disk HBA on boot without it getting messed up. Add helper routines to work around clang's over-use of the stack: that way we only pay the stack penalty when a trace hits. Sponsored by: Netflix Reviewed by: ken, mav Differential Revision: https://reviews.freebsd.org/D42411
This commit is contained in:
parent
7bca09e2bb
commit
70f2356d36
|
@ -81,57 +81,46 @@ extern uint32_t cam_dflags;
|
|||
/* Printf delay value (to prevent scrolling) */
|
||||
extern uint32_t cam_debug_delay;
|
||||
|
||||
/* Helper routines -- helps conserve stack */
|
||||
struct cam_ed;
|
||||
void xpt_cam_path_debug(struct cam_path *path, const char *fmt, ...);
|
||||
void xpt_cam_dev_debug(struct cam_ed *dev, const char *fmt, ...);
|
||||
void xpt_cam_debug(const char *fmt, ...);
|
||||
|
||||
/* Stupid macro to remove a layer of parens */
|
||||
#define _CAM_X(...) __VA_ARGS__
|
||||
|
||||
/* Debugging macros. */
|
||||
#define CAM_DEBUGGED(path, flag) \
|
||||
(((flag) & (CAM_DEBUG_COMPILE) & cam_dflags) \
|
||||
&& (cam_dpath != NULL) \
|
||||
&& (xpt_path_comp(cam_dpath, path) >= 0) \
|
||||
&& (xpt_path_comp(cam_dpath, path) < 2))
|
||||
#define CAM_DEBUGGED(path, flag) \
|
||||
(((flag) & (CAM_DEBUG_COMPILE) & cam_dflags) \
|
||||
&& (cam_dpath != NULL) \
|
||||
&& (xpt_path_comp(cam_dpath, (path)) >= 0) \
|
||||
&& (xpt_path_comp(cam_dpath, (path)) < 2))
|
||||
|
||||
#define CAM_DEBUG(path, flag, printfargs) \
|
||||
if (((flag) & (CAM_DEBUG_COMPILE) & cam_dflags) \
|
||||
&& (cam_dpath != NULL) \
|
||||
&& (xpt_path_comp(cam_dpath, path) >= 0) \
|
||||
&& (xpt_path_comp(cam_dpath, path) < 2)) { \
|
||||
xpt_print_path(path); \
|
||||
printf printfargs; \
|
||||
if (cam_debug_delay != 0) \
|
||||
DELAY(cam_debug_delay); \
|
||||
#define CAM_DEBUG(path, flag, printfargs) \
|
||||
if (CAM_DEBUGGED(path, flag)) { \
|
||||
xpt_cam_path_debug(path, _CAM_X printfargs); \
|
||||
}
|
||||
|
||||
#define CAM_DEBUG_DEV(dev, flag, printfargs) \
|
||||
if (((flag) & (CAM_DEBUG_COMPILE) & cam_dflags) \
|
||||
&& (cam_dpath != NULL) \
|
||||
&& (xpt_path_comp_dev(cam_dpath, dev) >= 0) \
|
||||
&& (xpt_path_comp_dev(cam_dpath, dev) < 2)) { \
|
||||
xpt_print_device(dev); \
|
||||
printf printfargs; \
|
||||
if (cam_debug_delay != 0) \
|
||||
DELAY(cam_debug_delay); \
|
||||
#define CAM_DEBUG_DEV(dev, flag, printfargs) \
|
||||
if (((flag) & (CAM_DEBUG_COMPILE) & cam_dflags) \
|
||||
&& (cam_dpath != NULL) \
|
||||
&& (xpt_path_comp_dev(cam_dpath, (dev)) >= 0) \
|
||||
&& (xpt_path_comp_dev(cam_dpath, (dev)) < 2)) { \
|
||||
xpt_cam_dev_debug(dev, _CAM_X printfargs); \
|
||||
}
|
||||
|
||||
#define CAM_DEBUG_PRINT(flag, printfargs) \
|
||||
if (((flag) & (CAM_DEBUG_COMPILE) & cam_dflags)) { \
|
||||
printf("cam_debug: "); \
|
||||
printf printfargs; \
|
||||
if (cam_debug_delay != 0) \
|
||||
DELAY(cam_debug_delay); \
|
||||
}
|
||||
|
||||
#define CAM_DEBUG_PATH_PRINT(flag, path, printfargs) \
|
||||
if (((flag) & (CAM_DEBUG_COMPILE) & cam_dflags)) { \
|
||||
xpt_print(path, "cam_debug: "); \
|
||||
printf printfargs; \
|
||||
if (cam_debug_delay != 0) \
|
||||
DELAY(cam_debug_delay); \
|
||||
#define CAM_DEBUG_PRINT(flag, printfargs) \
|
||||
if (((flag) & (CAM_DEBUG_COMPILE) & cam_dflags)) { \
|
||||
xpt_cam_debug(_CAM_X printfargs); \
|
||||
}
|
||||
|
||||
#else /* !_KERNEL */
|
||||
|
||||
#define CAM_DEBUGGED(A, B) 0
|
||||
#define CAM_DEBUG(A, B, C)
|
||||
#define CAM_DEBUG_DEV(A, B, C)
|
||||
#define CAM_DEBUG_PRINT(A, B)
|
||||
#define CAM_DEBUG_PATH_PRINT(A, B, C)
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
|
|
|
@ -3712,18 +3712,18 @@ xpt_print_path(struct cam_path *path)
|
|||
sbuf_delete(&sb);
|
||||
}
|
||||
|
||||
void
|
||||
xpt_print_device(struct cam_ed *device)
|
||||
static void
|
||||
xpt_device_sbuf(struct cam_ed *device, struct sbuf *sb)
|
||||
{
|
||||
|
||||
if (device == NULL)
|
||||
printf("(nopath): ");
|
||||
sbuf_printf(sb, "(nopath): ");
|
||||
else {
|
||||
printf("(noperiph:%s%d:%d:%d:%jx): ", device->sim->sim_name,
|
||||
device->sim->unit_number,
|
||||
device->sim->bus_id,
|
||||
device->target->target_id,
|
||||
(uintmax_t)device->lun_id);
|
||||
sbuf_printf(sb, "(noperiph:%s%d:%d:%d:%jx): ",
|
||||
device->sim->sim_name,
|
||||
device->sim->unit_number,
|
||||
device->sim->bus_id,
|
||||
device->target->target_id,
|
||||
(uintmax_t)device->lun_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5543,3 +5543,60 @@ xpt_action_name(uint32_t action)
|
|||
snprintf(buffer, sizeof(buffer), "%#x", action);
|
||||
return (buffer);
|
||||
}
|
||||
|
||||
void
|
||||
xpt_cam_path_debug(struct cam_path *path, const char *fmt, ...)
|
||||
{
|
||||
struct sbuf sbuf;
|
||||
char buf[XPT_PRINT_LEN]; /* balance to not eat too much stack */
|
||||
struct sbuf *sb = sbuf_new(&sbuf, buf, sizeof(buf), SBUF_FIXEDLEN);
|
||||
va_list ap;
|
||||
|
||||
sbuf_set_drain(sb, sbuf_printf_drain, NULL);
|
||||
xpt_path_sbuf(path, sb);
|
||||
va_start(ap, fmt);
|
||||
sbuf_vprintf(sb, fmt, ap);
|
||||
va_end(ap);
|
||||
sbuf_finish(sb);
|
||||
sbuf_delete(sb);
|
||||
if (cam_debug_delay != 0)
|
||||
DELAY(cam_debug_delay);
|
||||
}
|
||||
|
||||
void
|
||||
xpt_cam_dev_debug(struct cam_ed *dev, const char *fmt, ...)
|
||||
{
|
||||
struct sbuf sbuf;
|
||||
char buf[XPT_PRINT_LEN]; /* balance to not eat too much stack */
|
||||
struct sbuf *sb = sbuf_new(&sbuf, buf, sizeof(buf), SBUF_FIXEDLEN);
|
||||
va_list ap;
|
||||
|
||||
sbuf_set_drain(sb, sbuf_printf_drain, NULL);
|
||||
xpt_device_sbuf(dev, sb);
|
||||
va_start(ap, fmt);
|
||||
sbuf_vprintf(sb, fmt, ap);
|
||||
va_end(ap);
|
||||
sbuf_finish(sb);
|
||||
sbuf_delete(sb);
|
||||
if (cam_debug_delay != 0)
|
||||
DELAY(cam_debug_delay);
|
||||
}
|
||||
|
||||
void
|
||||
xpt_cam_debug(const char *fmt, ...)
|
||||
{
|
||||
struct sbuf sbuf;
|
||||
char buf[XPT_PRINT_LEN]; /* balance to not eat too much stack */
|
||||
struct sbuf *sb = sbuf_new(&sbuf, buf, sizeof(buf), SBUF_FIXEDLEN);
|
||||
va_list ap;
|
||||
|
||||
sbuf_set_drain(sb, sbuf_printf_drain, NULL);
|
||||
sbuf_printf(sb, "cam_debug: ");
|
||||
va_start(ap, fmt);
|
||||
sbuf_vprintf(sb, fmt, ap);
|
||||
va_end(ap);
|
||||
sbuf_finish(sb);
|
||||
sbuf_delete(sb);
|
||||
if (cam_debug_delay != 0)
|
||||
DELAY(cam_debug_delay);
|
||||
}
|
||||
|
|
|
@ -33,16 +33,15 @@
|
|||
#define _CAM_CAM_XPT_H 1
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <sys/cdefs.h>
|
||||
#include <cam/cam_ccb.h>
|
||||
#endif
|
||||
#include <sys/sbuf.h>
|
||||
|
||||
/* Forward Declarations */
|
||||
union ccb;
|
||||
struct cam_periph;
|
||||
struct cam_ed;
|
||||
struct cam_sim;
|
||||
struct sbuf;
|
||||
|
||||
/*
|
||||
* Definition of a CAM path. Paths are created from bus, target, and lun ids
|
||||
|
@ -113,7 +112,6 @@ struct cam_sim *xpt_path_sim(struct cam_path *path);
|
|||
struct cam_periph *xpt_path_periph(struct cam_path *path);
|
||||
device_t xpt_path_sim_device(const struct cam_path *path);
|
||||
void xpt_print_path(struct cam_path *path);
|
||||
void xpt_print_device(struct cam_ed *device);
|
||||
void xpt_print(struct cam_path *path, const char *fmt, ...);
|
||||
void xpt_async(uint32_t async_code, struct cam_path *path,
|
||||
void *async_arg);
|
||||
|
|
Loading…
Reference in a new issue