[PATCH 01/12] drm/panic: Allocate QR-code buffers statically

Thomas Zimmermann <[email protected]>
Newsgroups org.kernel.vger.linux-doc,dev.linux.lists.imx,dev.linux.lists.sashiko-reviews,dev.linux.lists.virtualization,org.freedesktop.lists.amd-gfx,org.freedesktop.lists.dri-devel,org.freedesktop.lists.intel-gfx,org.freedesktop.lists.intel-xe,org.freedesktop.lists.nouveau,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-hyperv,org.kernel.vger.linux-renesas-soc,org.kernel.vger.rust-for-linux
Message-ID <[email protected]>
Declare qrbuf1 and qrbuf2 as static arrays so that the module loader
allocates them for us. Avoids the kmalloc later on. Also allows for
using sizeof() to get the number of bytes in each array. Access the
arrays once with memset, so that the physical pages are available on
a panic.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
 drivers/gpu/drm/drm_panic.c | 41 ++++++++++++++++++++-----------------
 1 file changed, 22 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index e576c4791861..0685f7d8dba2 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -628,24 +628,23 @@ MODULE_PARM_DESC(panic_qr_version, "maximum version (size) of the QR code");
 #define WINDOW_BITS 12
 #define MEM_LEVEL 4
 
-static char *qrbuf1;
-static char *qrbuf2;
+static u8 qrbuf1[QR_BUFFER1_SIZE];
+static u8 qrbuf2[QR_BUFFER2_SIZE];
 static struct z_stream_s stream;
 
 static void __init drm_panic_qr_init(void)
 {
-	qrbuf1 = kmalloc(QR_BUFFER1_SIZE, GFP_KERNEL);
-	qrbuf2 = kmalloc(QR_BUFFER2_SIZE, GFP_KERNEL);
+	/* best-effort allocation; can be NULL */
 	stream.workspace = kmalloc(zlib_deflate_workspacesize(WINDOW_BITS, MEM_LEVEL),
 				   GFP_KERNEL);
+
+	/* touch memory so that pages are there in the case of a panic */
+	memset(qrbuf1, 0, sizeof(qrbuf1));
+	memset(qrbuf2, 0, sizeof(qrbuf2));
 }
 
 static void drm_panic_qr_exit(void)
 {
-	kfree(qrbuf1);
-	qrbuf1 = NULL;
-	kfree(qrbuf2);
-	qrbuf2 = NULL;
 	kfree(stream.workspace);
 	stream.workspace = NULL;
 }
@@ -656,13 +655,17 @@ static int drm_panic_get_qr_code_url(u8 **qr_image)
 	char url[256];
 	size_t kmsg_len, max_kmsg_size;
 	char *kmsg;
-	int max_qr_data_size, url_len;
+	int ret;
+	size_t max_qr_data_size, url_len;
 
-	url_len = snprintf(url, sizeof(url), CONFIG_DRM_PANIC_SCREEN_QR_CODE_URL "?a=%s&v=%s&z=",
-			   utsname()->machine, utsname()->release);
+	ret = snprintf(url, sizeof(url), CONFIG_DRM_PANIC_SCREEN_QR_CODE_URL "?a=%s&v=%s&z=",
+		       utsname()->machine, utsname()->release);
+	if (ret >= sizeof(url))
+		return -EINVAL;
+	url_len = ret;
 
 	max_qr_data_size = drm_panic_qr_max_data_size(panic_qr_version, url_len);
-	max_kmsg_size = min(MAX_ZLIB_RATIO * max_qr_data_size, QR_BUFFER1_SIZE);
+	max_kmsg_size = min(MAX_ZLIB_RATIO * max_qr_data_size, sizeof(qrbuf1));
 
 	/* get kmsg to buffer 1 */
 	kmsg_dump_rewind(&iter);
@@ -681,7 +684,7 @@ static int drm_panic_get_qr_code_url(u8 **qr_image)
 	stream.avail_in = kmsg_len;
 	stream.total_in = 0;
 	stream.next_out = qrbuf2;
-	stream.avail_out = QR_BUFFER2_SIZE;
+	stream.avail_out = sizeof(qrbuf2);
 	stream.total_out = 0;
 
 	if (zlib_deflate(&stream, Z_FINISH) != Z_STREAM_END)
@@ -703,8 +706,8 @@ static int drm_panic_get_qr_code_url(u8 **qr_image)
 	*qr_image = qrbuf2;
 
 	/* generate qr code image in buffer2 */
-	return drm_panic_qr_generate(url, qrbuf2, stream.total_out, QR_BUFFER2_SIZE,
-				     qrbuf1, QR_BUFFER1_SIZE);
+	return drm_panic_qr_generate(url, qrbuf2, stream.total_out, sizeof(qrbuf2),
+				     qrbuf1, sizeof(qrbuf1));
 }
 
 static int drm_panic_get_qr_code_raw(u8 **qr_image)
@@ -712,7 +715,7 @@ static int drm_panic_get_qr_code_raw(u8 **qr_image)
 	struct kmsg_dump_iter iter;
 	size_t kmsg_len;
 	size_t max_kmsg_size = min(drm_panic_qr_max_data_size(panic_qr_version, 0),
-				   QR_BUFFER1_SIZE);
+				   sizeof(qrbuf1));
 
 	kmsg_dump_rewind(&iter);
 	kmsg_dump_get_buffer(&iter, false, qrbuf1, max_kmsg_size, &kmsg_len);
@@ -720,8 +723,8 @@ static int drm_panic_get_qr_code_raw(u8 **qr_image)
 		return -ENODATA;
 
 	*qr_image = qrbuf1;
-	return drm_panic_qr_generate(NULL, qrbuf1, kmsg_len, QR_BUFFER1_SIZE,
-				     qrbuf2, QR_BUFFER2_SIZE);
+	return drm_panic_qr_generate(NULL, qrbuf1, kmsg_len, sizeof(qrbuf1),
+				     qrbuf2, sizeof(qrbuf2));
 }
 
 static int drm_panic_get_qr_code(u8 **qr_image)
@@ -748,7 +751,7 @@ static int _draw_panic_screen_qr_code(struct drm_scanout_buffer *sb)
 	int qr_width, qr_canvas_width, qr_pitch, v_margin;
 	u8 *qr_image;
 
-	if (!font || !qrbuf1 || !qrbuf2 || !stream.workspace)
+	if (!font || !stream.workspace)
 		return -ENOMEM;
 
 	r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height);
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.