Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5dc634bd authored by Jordan Crouse's avatar Jordan Crouse Committed by Rob Clark
Browse files

drm: Add puts callback for the coredump printer



Add a puts function for the coredump printer to bypass printf()
for constant strings for a speed boost. Reorganize the
coredump printf callback to share as much code as possible.

v2: Try to reuse code between print and puts as suggested by
    Chris Wilson

Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
Signed-off-by: default avatarRob Clark <robdclark@gmail.com>
parent 4538d732
Loading
Loading
Loading
Loading
+49 −35
Original line number Original line Diff line number Diff line
@@ -30,7 +30,7 @@
#include <drm/drmP.h>
#include <drm/drmP.h>
#include <drm/drm_print.h>
#include <drm/drm_print.h>


void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf)
void __drm_puts_coredump(struct drm_printer *p, const char *str)
{
{
	struct drm_print_iterator *iterator = p->arg;
	struct drm_print_iterator *iterator = p->arg;
	ssize_t len;
	ssize_t len;
@@ -38,26 +38,16 @@ void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf)
	if (!iterator->remain)
	if (!iterator->remain)
		return;
		return;


	/* Figure out how big the string will be */
	len = snprintf(NULL, 0, "%pV", vaf);

	if (iterator->offset < iterator->start) {
	if (iterator->offset < iterator->start) {
		char *buf;
		ssize_t copy;
		ssize_t copy;


		len = strlen(str);

		if (iterator->offset + len <= iterator->start) {
		if (iterator->offset + len <= iterator->start) {
			iterator->offset += len;
			iterator->offset += len;
			return;
			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);
		copy = len - (iterator->start - iterator->offset);


		if (copy > iterator->remain)
		if (copy > iterator->remain)
@@ -65,17 +55,45 @@ void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf)


		/* Copy out the bit of the string that we need */
		/* Copy out the bit of the string that we need */
		memcpy(iterator->data,
		memcpy(iterator->data,
			buf + (iterator->start - iterator->offset), copy);
			str + (iterator->start - iterator->offset), copy);


		iterator->offset = iterator->start + copy;
		iterator->offset = iterator->start + copy;
		iterator->remain -= copy;
		iterator->remain -= copy;

		kfree(buf);
	} else {
	} else {
		ssize_t pos = iterator->offset - iterator->start;

		len = min_t(ssize_t, strlen(str), iterator->remain);

		memcpy(iterator->data + pos, str, len);

		iterator->offset += len;
		iterator->remain -= len;
	}
}
EXPORT_SYMBOL(__drm_puts_coredump);

void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf)
{
	struct drm_print_iterator *iterator = p->arg;
	size_t len;
	char *buf;
	char *buf;

	if (!iterator->remain)
		return;

	/* Figure out how big the string will be */
	len = snprintf(NULL, 0, "%pV", vaf);

	/* This is the easiest path, we've already advanced beyond the offset */
	if (iterator->offset + len <= iterator->start) {
		iterator->offset += len;
		return;
	}

	/* Then check if we can directly copy into the target buffer */
	if ((iterator->offset >= iterator->start) && (len < iterator->remain)) {
		ssize_t pos = iterator->offset - iterator->start;
		ssize_t pos = iterator->offset - iterator->start;


		if (len < iterator->remain) {
		snprintf(((char *) iterator->data) + pos,
		snprintf(((char *) iterator->data) + pos,
			iterator->remain, "%pV", vaf);
			iterator->remain, "%pV", vaf);


@@ -85,23 +103,19 @@ void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf)
		return;
		return;
	}
	}


		/* Print the string into a temporary buffer */
	/*
		buf = kmalloc(len + 1,
	 * Finally, hit the slow path and make a temporary string to copy over
			GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
	 * using _drm_puts_coredump
	 */
	buf = kmalloc(len + 1, GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
	if (!buf)
	if (!buf)
		return;
		return;


	snprintf(buf, len + 1, "%pV", vaf);
	snprintf(buf, len + 1, "%pV", vaf);

	__drm_puts_coredump(p, (const char *) buf);
		/* Copy out the remaining bits */
		memcpy(iterator->data + pos, buf, iterator->remain);

		iterator->offset += iterator->remain;
		iterator->remain = 0;


	kfree(buf);
	kfree(buf);
}
}
}
EXPORT_SYMBOL(__drm_printfn_coredump);
EXPORT_SYMBOL(__drm_printfn_coredump);


void __drm_puts_seq_file(struct drm_printer *p, const char *str)
void __drm_puts_seq_file(struct drm_printer *p, const char *str)
+2 −0
Original line number Original line Diff line number Diff line
@@ -75,6 +75,7 @@ struct drm_printer {
};
};


void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf);
void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf);
void __drm_puts_coredump(struct drm_printer *p, const char *str);
void __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf);
void __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf);
void __drm_puts_seq_file(struct drm_printer *p, const char *str);
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_info(struct drm_printer *p, struct va_format *vaf);
@@ -163,6 +164,7 @@ drm_coredump_printer(struct drm_print_iterator *iter)
{
{
	struct drm_printer p = {
	struct drm_printer p = {
		.printfn = __drm_printfn_coredump,
		.printfn = __drm_printfn_coredump,
		.puts = __drm_puts_coredump,
		.arg = iter,
		.arg = iter,
	};
	};