[PATCH 02/10] drm: drm_printer: Add printer for devcoredump
Add a drm printer suitable for use with the read callback for devcoredump or any other file operation read() function that isn't otherwise covered by seq_file. Signed-off-by: Jordan Crouse--- drivers/gpu/drm/drm_print.c | 54 + include/drm/drm_print.h | 27 +++ 2 files changed, 81 insertions(+) diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c index 781518fd88e3..f6efde48f8b3 100644 --- a/drivers/gpu/drm/drm_print.c +++ b/drivers/gpu/drm/drm_print.c @@ -30,6 +30,60 @@ #include #include +void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf) +{ + struct drm_print_iterator *iterator = p->arg; + + ssize_t len; + + if (!iterator->remain) + return; + + if (iterator->offset < iterator->start) { + char *buf; + ssize_t copy; + + /* Figure out how big the string will be */ + len = snprintf(NULL, 0, "%pV", vaf); + + if (iterator->offset + len <= iterator->start) { + iterator->offset += len; + return; + } + + /* Print the string into a temporary buffer */ + buf = kmalloc(len + 1, + GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY); + if (!buf) + return; + + snprintf(buf, len + 1, "%pV", vaf); + + copy = len - (iterator->start - iterator->offset); + + if (copy > iterator->remain) + copy = iterator->remain; + + /* Copy out the bit of the string that we need */ + memcpy(iterator->data, + buf + (iterator->start - iterator->offset), copy); + + iterator->offset = iterator->start + copy; + iterator->remain -= copy; + + kfree(buf); + } else { + ssize_t pos = iterator->offset - iterator->start; + + len = scnprintf(((char *) iterator->data) + pos, + iterator->remain, "%pV", vaf); + + iterator->offset += len; + iterator->remain -= len; + } +} +EXPORT_SYMBOL(__drm_printfn_coredump); + void __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf) { seq_printf(p->arg, "%pV", vaf); diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h index 2a4a42e59a47..29eee5175eac 100644 --- a/include/drm/drm_print.h +++ b/include/drm/drm_print.h @@ -73,6 +73,7 @@ struct drm_printer { const char *prefix; }; +void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf); void __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf); void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf); void __drm_printfn_debug(struct drm_printer *p, struct va_format *vaf); @@ -104,6 +105,32 @@ drm_vprintf(struct drm_printer *p, const char *fmt, va_list *va) #define drm_printf_indent(printer, indent, fmt, ...) \ drm_printf((printer), "%.*s" fmt, (indent), "\t\t\t\t\tX", ##__VA_ARGS__) +struct drm_print_iterator { + void *data; + + ssize_t start; + ssize_t offset; + ssize_t remain; +}; + +/** + * drm_coredump_printer - construct a _printer that can output to a buffer + * from the read function for devcoredump + * @iter: A pointer to a struct drm_print_iterator for the read instance + * + * RETURNS: + * The _printer object + */ +static inline struct drm_printer +drm_coredump_printer(struct drm_print_iterator *iter) +{ + struct drm_printer p = { + .printfn = __drm_printfn_coredump, + .arg = iter, + }; + return p; +} + /** * drm_seq_file_printer - construct a _printer that outputs to _file * @f: the seq_file to output to -- 2.17.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 02/10] drm: drm_printer: Add printer for devcoredump
Quoting Chris Wilson (2018-04-06 11:42:25) > Quoting Jordan Crouse (2018-04-05 23:00:48) > > +struct drm_print_iterator { > > + void *data; > > + > > + ssize_t start; > > + ssize_t offset; > > + ssize_t remain; > > +}; > > Neat, we should be able to use to replace struct > drm_i915_error_state_buf (or at least the seq_file side). Though comparing against which, we have loff_t for that interface. But that's immaterial for an in-memory file. (So nothing to see here, please move along.) -Chris ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 02/10] drm: drm_printer: Add printer for devcoredump
Quoting Jordan Crouse (2018-04-05 23:00:48) > +struct drm_print_iterator { > + void *data; > + > + ssize_t start; > + ssize_t offset; > + ssize_t remain; > +}; Neat, we should be able to use to replace struct drm_i915_error_state_buf (or at least the seq_file side). -Chris ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 02/10] drm: drm_printer: Add printer for devcoredump
Add a drm printer suitable for use with the read callback for devcoredump or any other file operation read() function that isn't otherwise covered by seq_file. Signed-off-by: Jordan Crouse--- drivers/gpu/drm/drm_print.c | 54 + include/drm/drm_print.h | 27 +++ 2 files changed, 81 insertions(+) diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c index 781518fd88e3..f6efde48f8b3 100644 --- a/drivers/gpu/drm/drm_print.c +++ b/drivers/gpu/drm/drm_print.c @@ -30,6 +30,60 @@ #include #include +void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf) +{ + struct drm_print_iterator *iterator = p->arg; + + ssize_t len; + + if (!iterator->remain) + return; + + if (iterator->offset < iterator->start) { + char *buf; + ssize_t copy; + + /* Figure out how big the string will be */ + len = snprintf(NULL, 0, "%pV", vaf); + + if (iterator->offset + len <= iterator->start) { + iterator->offset += len; + return; + } + + /* Print the string into a temporary buffer */ + buf = kmalloc(len + 1, + GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY); + if (!buf) + return; + + snprintf(buf, len + 1, "%pV", vaf); + + copy = len - (iterator->start - iterator->offset); + + if (copy > iterator->remain) + copy = iterator->remain; + + /* Copy out the bit of the string that we need */ + memcpy(iterator->data, + buf + (iterator->start - iterator->offset), copy); + + iterator->offset = iterator->start + copy; + iterator->remain -= copy; + + kfree(buf); + } else { + ssize_t pos = iterator->offset - iterator->start; + + len = scnprintf(((char *) iterator->data) + pos, + iterator->remain, "%pV", vaf); + + iterator->offset += len; + iterator->remain -= len; + } +} +EXPORT_SYMBOL(__drm_printfn_coredump); + void __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf) { seq_printf(p->arg, "%pV", vaf); diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h index 2a4a42e59a47..29eee5175eac 100644 --- a/include/drm/drm_print.h +++ b/include/drm/drm_print.h @@ -73,6 +73,7 @@ struct drm_printer { const char *prefix; }; +void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf); void __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf); void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf); void __drm_printfn_debug(struct drm_printer *p, struct va_format *vaf); @@ -104,6 +105,32 @@ drm_vprintf(struct drm_printer *p, const char *fmt, va_list *va) #define drm_printf_indent(printer, indent, fmt, ...) \ drm_printf((printer), "%.*s" fmt, (indent), "\t\t\t\t\tX", ##__VA_ARGS__) +struct drm_print_iterator { + void *data; + + ssize_t start; + ssize_t offset; + ssize_t remain; +}; + +/** + * drm_coredump_printer - construct a _printer that can output to a buffer + * from the read function for devcoredump + * @iter: A pointer to a struct drm_print_iterator for the read instance + * + * RETURNS: + * The _printer object + */ +static inline struct drm_printer +drm_coredump_printer(struct drm_print_iterator *iter) +{ + struct drm_printer p = { + .printfn = __drm_printfn_coredump, + .arg = iter, + }; + return p; +} + /** * drm_seq_file_printer - construct a _printer that outputs to _file * @f: the seq_file to output to -- 2.16.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel