git: 70f2356d364f - main - cam: Make cam_debug macros atomic
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 03 Nov 2023 16:18:01 UTC
The branch main has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=70f2356d364fdb7e2ff5487ae03125a338defd54 commit 70f2356d364fdb7e2ff5487ae03125a338defd54 Author: Warner Losh <imp@FreeBSD.org> AuthorDate: 2023-11-02 20:41:09 +0000 Commit: Warner Losh <imp@FreeBSD.org> CommitDate: 2023-11-03 16:15:38 +0000 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 --- sys/cam/cam_debug.h | 67 ++++++++++++++++++++--------------------------- sys/cam/cam_xpt.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++------- sys/cam/cam_xpt.h | 4 +-- 3 files changed, 95 insertions(+), 51 deletions(-) diff --git a/sys/cam/cam_debug.h b/sys/cam/cam_debug.h index 1526f11f4c0d..8c04b1fd7ce9 100644 --- a/sys/cam/cam_debug.h +++ b/sys/cam/cam_debug.h @@ -81,57 +81,46 @@ extern uint32_t cam_dflags; /* Printf delay value (to prevent scrolling) */ extern uint32_t cam_debug_delay; -/* 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_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); \ - } +/* 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, ...); -#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); \ +/* 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_DEBUG(path, flag, printfargs) \ + if (CAM_DEBUGGED(path, flag)) { \ + xpt_cam_path_debug(path, _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_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_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 */ diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index c32cad2433b1..a1dec7a8a674 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -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); +} diff --git a/sys/cam/cam_xpt.h b/sys/cam/cam_xpt.h index 1276dd7b9b2e..3c8d385fe33b 100644 --- a/sys/cam/cam_xpt.h +++ b/sys/cam/cam_xpt.h @@ -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);