Message ID | 20241003004611.2323493-8-John.C.Harrison@Intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | None | expand |
I don't think there's an immediate use for this in drm-misc, so its easier to merge through xe. :-) Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Den 2024-10-03 kl. 02:46, skrev John.C.Harrison@Intel.com: > From: Michal Wajdeczko <michal.wajdeczko@intel.com> > > This drm printer wrapper can be used to increase the robustness of > the captured output generated by any other drm_printer to make sure > we didn't lost any intermediate lines of the output by adding line > numbers to each output line. Helpful for capturing some crash data. > > v2: Extended short int counters to full int (JohnH) > > Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> > Cc: Jani Nikula <jani.nikula@intel.com> > Cc: John Harrison <John.C.Harrison@Intel.com> > Cc: dri-devel@lists.freedesktop.org > Reviewed-by: Jani Nikula <jani.nikula@intel.com> > --- > drivers/gpu/drm/drm_print.c | 14 ++++++++ > include/drm/drm_print.h | 64 +++++++++++++++++++++++++++++++++++++ > 2 files changed, 78 insertions(+) > > diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c > index 0081190201a7..08cfea04e22b 100644 > --- a/drivers/gpu/drm/drm_print.c > +++ b/drivers/gpu/drm/drm_print.c > @@ -235,6 +235,20 @@ void __drm_printfn_err(struct drm_printer *p, struct va_format *vaf) > } > EXPORT_SYMBOL(__drm_printfn_err); > > +void __drm_printfn_line(struct drm_printer *p, struct va_format *vaf) > +{ > + unsigned int counter = ++p->line.counter; > + const char *prefix = p->prefix ?: ""; > + const char *pad = p->prefix ? " " : ""; > + > + if (p->line.series) > + drm_printf(p->arg, "%s%s%u.%u: %pV", > + prefix, pad, p->line.series, counter, vaf); > + else > + drm_printf(p->arg, "%s%s%u: %pV", prefix, pad, counter, vaf); > +} > +EXPORT_SYMBOL(__drm_printfn_line); > + > /** > * drm_puts - print a const string to a &drm_printer stream > * @p: the &drm printer > diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h > index d2676831d765..b3906dc04388 100644 > --- a/include/drm/drm_print.h > +++ b/include/drm/drm_print.h > @@ -177,6 +177,10 @@ struct drm_printer { > void *arg; > const void *origin; > const char *prefix; > + struct { > + unsigned int series; > + unsigned int counter; > + } line; > enum drm_debug_category category; > }; > > @@ -187,6 +191,7 @@ void __drm_puts_seq_file(struct drm_printer *p, const char *str); > void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf); > void __drm_printfn_dbg(struct drm_printer *p, struct va_format *vaf); > void __drm_printfn_err(struct drm_printer *p, struct va_format *vaf); > +void __drm_printfn_line(struct drm_printer *p, struct va_format *vaf); > > __printf(2, 3) > void drm_printf(struct drm_printer *p, const char *f, ...); > @@ -411,6 +416,65 @@ static inline struct drm_printer drm_err_printer(struct drm_device *drm, > return p; > } > > +/** > + * drm_line_printer - construct a &drm_printer that prefixes outputs with line numbers > + * @p: the &struct drm_printer which actually generates the output > + * @prefix: optional output prefix, or NULL for no prefix > + * @series: optional unique series identifier, or 0 to omit identifier in the output > + * > + * This printer can be used to increase the robustness of the captured output > + * to make sure we didn't lost any intermediate lines of the output. Helpful > + * while capturing some crash data. > + * > + * Example 1:: > + * > + * void crash_dump(struct drm_device *drm) > + * { > + * static unsigned int id; > + * struct drm_printer p = drm_err_printer(drm, "crash"); > + * struct drm_printer lp = drm_line_printer(&p, "dump", ++id); > + * > + * drm_printf(&lp, "foo"); > + * drm_printf(&lp, "bar"); > + * } > + * > + * Above code will print into the dmesg something like:: > + * > + * [ ] 0000:00:00.0: [drm] *ERROR* crash dump 1.1: foo > + * [ ] 0000:00:00.0: [drm] *ERROR* crash dump 1.2: bar > + * > + * Example 2:: > + * > + * void line_dump(struct device *dev) > + * { > + * struct drm_printer p = drm_info_printer(dev); > + * struct drm_printer lp = drm_line_printer(&p, NULL, 0); > + * > + * drm_printf(&lp, "foo"); > + * drm_printf(&lp, "bar"); > + * } > + * > + * Above code will print:: > + * > + * [ ] 0000:00:00.0: [drm] 1: foo > + * [ ] 0000:00:00.0: [drm] 2: bar > + * > + * RETURNS: > + * The &drm_printer object > + */ > +static inline struct drm_printer drm_line_printer(struct drm_printer *p, > + const char *prefix, > + unsigned int series) > +{ > + struct drm_printer lp = { > + .printfn = __drm_printfn_line, > + .arg = p, > + .prefix = prefix, > + .line = { .series = series, }, > + }; > + return lp; > +} > + > /* > * struct device based logging > *
diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c index 0081190201a7..08cfea04e22b 100644 --- a/drivers/gpu/drm/drm_print.c +++ b/drivers/gpu/drm/drm_print.c @@ -235,6 +235,20 @@ void __drm_printfn_err(struct drm_printer *p, struct va_format *vaf) } EXPORT_SYMBOL(__drm_printfn_err); +void __drm_printfn_line(struct drm_printer *p, struct va_format *vaf) +{ + unsigned int counter = ++p->line.counter; + const char *prefix = p->prefix ?: ""; + const char *pad = p->prefix ? " " : ""; + + if (p->line.series) + drm_printf(p->arg, "%s%s%u.%u: %pV", + prefix, pad, p->line.series, counter, vaf); + else + drm_printf(p->arg, "%s%s%u: %pV", prefix, pad, counter, vaf); +} +EXPORT_SYMBOL(__drm_printfn_line); + /** * drm_puts - print a const string to a &drm_printer stream * @p: the &drm printer diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h index d2676831d765..b3906dc04388 100644 --- a/include/drm/drm_print.h +++ b/include/drm/drm_print.h @@ -177,6 +177,10 @@ struct drm_printer { void *arg; const void *origin; const char *prefix; + struct { + unsigned int series; + unsigned int counter; + } line; enum drm_debug_category category; }; @@ -187,6 +191,7 @@ void __drm_puts_seq_file(struct drm_printer *p, const char *str); void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf); void __drm_printfn_dbg(struct drm_printer *p, struct va_format *vaf); void __drm_printfn_err(struct drm_printer *p, struct va_format *vaf); +void __drm_printfn_line(struct drm_printer *p, struct va_format *vaf); __printf(2, 3) void drm_printf(struct drm_printer *p, const char *f, ...); @@ -411,6 +416,65 @@ static inline struct drm_printer drm_err_printer(struct drm_device *drm, return p; } +/** + * drm_line_printer - construct a &drm_printer that prefixes outputs with line numbers + * @p: the &struct drm_printer which actually generates the output + * @prefix: optional output prefix, or NULL for no prefix + * @series: optional unique series identifier, or 0 to omit identifier in the output + * + * This printer can be used to increase the robustness of the captured output + * to make sure we didn't lost any intermediate lines of the output. Helpful + * while capturing some crash data. + * + * Example 1:: + * + * void crash_dump(struct drm_device *drm) + * { + * static unsigned int id; + * struct drm_printer p = drm_err_printer(drm, "crash"); + * struct drm_printer lp = drm_line_printer(&p, "dump", ++id); + * + * drm_printf(&lp, "foo"); + * drm_printf(&lp, "bar"); + * } + * + * Above code will print into the dmesg something like:: + * + * [ ] 0000:00:00.0: [drm] *ERROR* crash dump 1.1: foo + * [ ] 0000:00:00.0: [drm] *ERROR* crash dump 1.2: bar + * + * Example 2:: + * + * void line_dump(struct device *dev) + * { + * struct drm_printer p = drm_info_printer(dev); + * struct drm_printer lp = drm_line_printer(&p, NULL, 0); + * + * drm_printf(&lp, "foo"); + * drm_printf(&lp, "bar"); + * } + * + * Above code will print:: + * + * [ ] 0000:00:00.0: [drm] 1: foo + * [ ] 0000:00:00.0: [drm] 2: bar + * + * RETURNS: + * The &drm_printer object + */ +static inline struct drm_printer drm_line_printer(struct drm_printer *p, + const char *prefix, + unsigned int series) +{ + struct drm_printer lp = { + .printfn = __drm_printfn_line, + .arg = p, + .prefix = prefix, + .line = { .series = series, }, + }; + return lp; +} + /* * struct device based logging *