From: Sasha Levin <sashal@kernel.org>
To: stable@vger.kernel.org
Cc: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>,
Tomasz Rusinowicz <tomasz.rusinowicz@intel.com>,
Sasha Levin <sashal@kernel.org>
Subject: [PATCH 6.6.y 4/5] accel/ivpu: Refactor functions in ivpu_fw_log.c
Date: Wed, 16 Sep 2026 14:55:40 -0400 [thread overview]
Message-ID: <20260916185541.1885084-4-sashal@kernel.org> (raw)
In-Reply-To: <20260916185541.1885084-1-sashal@kernel.org>
From: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
[ Upstream commit 1fc1251149a76d3b75d7f4c94d9c4e081b7df6b4 ]
Make function names more consistent and (arguably) readable in
fw log code. Add fw_log_print_all_in_bo() that remove duplicated code in
ivpu_fw_log_print().
Reviewed-by: Tomasz Rusinowicz <tomasz.rusinowicz@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-5-jacek.lawrynowicz@linux.intel.com
Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
Backport to 6.6: keep the VPU log labels and the existing module parameter.
Convert the existing ivpu_fw_log_print() into fw_log_print_all_in_bo()
and move its two BO calls into the existing debugfs and dump callers.
This preserves the number of functions; no helper or accessor functions
are added. Rename the existing parser, line printer and mark-read entry
point consistently with upstream.
Carry the log-printing prerequisites from 4bc988b470195 and the index
bounds checks from dd1311bcf0e62 so 0724afc55c77 can be cherry-picked
without conflicts. The tracing header already has read_wrap_count from
an earlier dependency, and the log-size/header-size check is already
present. Keep both checks and reset/update the reader wrap count.
Map the upstream BO accessor names to this branch's existing fields
with local macros, avoiding the unrelated GEM conversion and additional
functions. The target can then snapshot validated metadata and pass it
to every log consumer without re-reading the shared size fields.
Include ivpu_fw_log.h in ivpu_pm.c: the preceding cold-boot dependency
added an ivpu_fw_log_reset() call without its declaration in this tree.
Stable-dep-of: 0724afc55c77 ("accel/ivpu: Validate firmware log buffer metadata")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/accel/ivpu/ivpu_debugfs.c | 5 +-
drivers/accel/ivpu/ivpu_fw_log.c | 110 ++++++++++++++++++------------
drivers/accel/ivpu/ivpu_fw_log.h | 9 ++-
drivers/accel/ivpu/ivpu_pm.c | 1 +
4 files changed, 76 insertions(+), 49 deletions(-)
diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c
index 5e5996fd4f9f1..502a0a6468b5e 100644
--- a/drivers/accel/ivpu/ivpu_debugfs.c
+++ b/drivers/accel/ivpu/ivpu_debugfs.c
@@ -119,7 +119,8 @@ static int fw_log_show(struct seq_file *s, void *v)
struct ivpu_device *vdev = s->private;
struct drm_printer p = drm_seq_file_printer(s);
- ivpu_fw_log_print(vdev, true, &p);
+ fw_log_print_all_in_bo(vdev, "VPU critical", vdev->fw->mem_log_crit, true, &p);
+ fw_log_print_all_in_bo(vdev, "VPU verbose", vdev->fw->mem_log_verb, true, &p);
return 0;
}
@@ -137,7 +138,7 @@ fw_log_fops_write(struct file *file, const char __user *user_buf, size_t size, l
if (!size)
return -EINVAL;
- ivpu_fw_log_clear(vdev);
+ ivpu_fw_log_mark_read(vdev);
return size;
}
diff --git a/drivers/accel/ivpu/ivpu_fw_log.c b/drivers/accel/ivpu/ivpu_fw_log.c
index 0ed29e5ac8e52..365f2d782cdde 100644
--- a/drivers/accel/ivpu/ivpu_fw_log.c
+++ b/drivers/accel/ivpu/ivpu_fw_log.c
@@ -17,6 +17,10 @@
#define IVPU_FW_LOG_LINE_LENGTH 256
+/* Accessors for the BO layout used by this stable branch. */
+#define ivpu_bo_size(bo) ((bo)->base.size)
+#define ivpu_bo_vaddr(bo) ((bo)->kvaddr)
+
unsigned int ivpu_log_level = IVPU_FW_LOG_ERROR;
module_param(ivpu_log_level, uint, 0444);
MODULE_PARM_DESC(ivpu_log_level,
@@ -26,15 +30,15 @@ MODULE_PARM_DESC(ivpu_log_level,
" error=" __stringify(IVPU_FW_LOG_ERROR)
" fatal=" __stringify(IVPU_FW_LOG_FATAL));
-static int fw_log_ptr(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *offset,
- struct vpu_tracing_buffer_header **log_header)
+static int fw_log_from_bo(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *offset,
+ struct vpu_tracing_buffer_header **out_log)
{
struct vpu_tracing_buffer_header *log;
- if ((*offset + sizeof(*log)) > bo->base.size)
+ if ((*offset + sizeof(*log)) > ivpu_bo_size(bo))
return -EINVAL;
- log = bo->kvaddr + *offset;
+ log = ivpu_bo_vaddr(bo) + *offset;
if (log->vpu_canary_start != VPU_TRACING_BUFFER_CANARY)
return -EINVAL;
@@ -47,12 +51,12 @@ static int fw_log_ptr(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *offset,
ivpu_dbg(vdev, FW_BOOT, "Invalid log size 0x%x\n", log->size);
return -EINVAL;
}
- if ((char *)log + log->size > (char *)bo->kvaddr + bo->base.size) {
+ if ((char *)log + log->size > (char *)ivpu_bo_vaddr(bo) + ivpu_bo_size(bo)) {
ivpu_dbg(vdev, FW_BOOT, "Invalid log size 0x%x\n", log->size);
return -EINVAL;
}
- *log_header = log;
+ *out_log = log;
*offset += log->size;
ivpu_dbg(vdev, FW_BOOT,
@@ -63,7 +67,7 @@ static int fw_log_ptr(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *offset,
return 0;
}
-static void buffer_print(char *buffer, u32 size, struct drm_printer *p)
+static void fw_log_print_lines(char *buffer, u32 size, struct drm_printer *p)
{
char line[IVPU_FW_LOG_LINE_LENGTH];
u32 index = 0;
@@ -91,70 +95,88 @@ static void buffer_print(char *buffer, u32 size, struct drm_printer *p)
}
line[index] = 0;
if (index != 0)
- drm_printf(p, "%s\n", line);
+ drm_printf(p, "%s", line);
}
-static void fw_log_print_buffer(struct ivpu_device *vdev, struct vpu_tracing_buffer_header *log,
- const char *prefix, bool only_new_msgs, struct drm_printer *p)
+static void fw_log_print_buffer(struct vpu_tracing_buffer_header *log, const char *prefix,
+ bool only_new_msgs, struct drm_printer *p)
{
- char *log_buffer = (void *)log + log->header_size;
- u32 log_size = log->size - log->header_size;
- u32 log_start = log->read_index;
- u32 log_end = log->write_index;
-
- if (!(log->write_index || log->wrap_count) ||
- (log->write_index == log->read_index && only_new_msgs)) {
- drm_printf(p, "==== %s \"%s\" log empty ====\n", prefix, log->name);
- return;
+ char *log_data = (void *)log + log->header_size;
+ u32 data_size = log->size - log->header_size;
+ u32 log_start = only_new_msgs ? READ_ONCE(log->read_index) : 0;
+ u32 log_end = READ_ONCE(log->write_index);
+
+ if (log_start >= data_size)
+ log_start = 0;
+ if (log_end > data_size)
+ log_end = data_size;
+
+ if (log->wrap_count == log->read_wrap_count) {
+ if (log_end <= log_start) {
+ drm_printf(p, "==== %s \"%s\" log empty ====\n", prefix, log->name);
+ return;
+ }
+ } else if (log->wrap_count == log->read_wrap_count + 1) {
+ if (log_end > log_start)
+ log_start = log_end;
+ } else {
+ log_start = log_end;
}
drm_printf(p, "==== %s \"%s\" log start ====\n", prefix, log->name);
- if (log->write_index > log->read_index) {
- buffer_print(log_buffer + log_start, log_end - log_start, p);
+ if (log_end > log_start) {
+ fw_log_print_lines(log_data + log_start, log_end - log_start, p);
} else {
- buffer_print(log_buffer + log_end, log_size - log_end, p);
- buffer_print(log_buffer, log_end, p);
+ fw_log_print_lines(log_data + log_start, data_size - log_start, p);
+ fw_log_print_lines(log_data, log_end, p);
}
- drm_printf(p, "\x1b[0m");
+ drm_printf(p, "\n\x1b[0m"); /* add new line and clear formatting */
drm_printf(p, "==== %s \"%s\" log end ====\n", prefix, log->name);
}
-void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_printer *p)
+void
+fw_log_print_all_in_bo(struct ivpu_device *vdev, const char *name,
+ struct ivpu_bo *bo, bool only_new_msgs, struct drm_printer *p)
{
- struct vpu_tracing_buffer_header *log_header;
+ struct vpu_tracing_buffer_header *log;
u32 next = 0;
- while (fw_log_ptr(vdev, vdev->fw->mem_log_crit, &next, &log_header) == 0)
- fw_log_print_buffer(vdev, log_header, "VPU critical", only_new_msgs, p);
-
- next = 0;
- while (fw_log_ptr(vdev, vdev->fw->mem_log_verb, &next, &log_header) == 0)
- fw_log_print_buffer(vdev, log_header, "VPU verbose", only_new_msgs, p);
+ while (fw_log_from_bo(vdev, bo, &next, &log) == 0)
+ fw_log_print_buffer(log, name, only_new_msgs, p);
}
-void ivpu_fw_log_clear(struct ivpu_device *vdev)
+void ivpu_fw_log_mark_read(struct ivpu_device *vdev)
{
- struct vpu_tracing_buffer_header *log_header;
- u32 next = 0;
+ struct vpu_tracing_buffer_header *log;
+ u32 next;
- while (fw_log_ptr(vdev, vdev->fw->mem_log_crit, &next, &log_header) == 0)
- log_header->read_index = log_header->write_index;
+ next = 0;
+ while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) {
+ log->read_index = READ_ONCE(log->write_index);
+ log->read_wrap_count = READ_ONCE(log->wrap_count);
+ }
next = 0;
- while (fw_log_ptr(vdev, vdev->fw->mem_log_verb, &next, &log_header) == 0)
- log_header->read_index = log_header->write_index;
+ while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) {
+ log->read_index = READ_ONCE(log->write_index);
+ log->read_wrap_count = READ_ONCE(log->wrap_count);
+ }
}
void ivpu_fw_log_reset(struct ivpu_device *vdev)
{
- struct vpu_tracing_buffer_header *log_header;
+ struct vpu_tracing_buffer_header *log;
u32 next;
next = 0;
- while (fw_log_ptr(vdev, vdev->fw->mem_log_crit, &next, &log_header) == 0)
- log_header->read_index = 0;
+ while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) {
+ log->read_index = 0;
+ log->read_wrap_count = 0;
+ }
next = 0;
- while (fw_log_ptr(vdev, vdev->fw->mem_log_verb, &next, &log_header) == 0)
- log_header->read_index = 0;
+ while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) {
+ log->read_index = 0;
+ log->read_wrap_count = 0;
+ }
}
diff --git a/drivers/accel/ivpu/ivpu_fw_log.h b/drivers/accel/ivpu/ivpu_fw_log.h
index 692ee0f266a31..da17fab5ad3d8 100644
--- a/drivers/accel/ivpu/ivpu_fw_log.h
+++ b/drivers/accel/ivpu/ivpu_fw_log.h
@@ -11,6 +11,7 @@
#include <drm/drm_print.h>
#include "ivpu_drv.h"
+#include "ivpu_fw.h"
#define IVPU_FW_LOG_DEFAULT 0
#define IVPU_FW_LOG_DEBUG 1
@@ -25,15 +26,17 @@ extern unsigned int ivpu_log_level;
#define IVPU_FW_VERBOSE_BUFFER_LARGE_SIZE SZ_8M
#define IVPU_FW_CRITICAL_BUFFER_SIZE SZ_512K
-void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_printer *p);
-void ivpu_fw_log_clear(struct ivpu_device *vdev);
+void fw_log_print_all_in_bo(struct ivpu_device *vdev, const char *name,
+ struct ivpu_bo *bo, bool only_new_msgs, struct drm_printer *p);
+void ivpu_fw_log_mark_read(struct ivpu_device *vdev);
void ivpu_fw_log_reset(struct ivpu_device *vdev);
static inline void ivpu_fw_log_dump(struct ivpu_device *vdev)
{
struct drm_printer p = drm_info_printer(vdev->drm.dev);
- ivpu_fw_log_print(vdev, false, &p);
+ fw_log_print_all_in_bo(vdev, "VPU critical", vdev->fw->mem_log_crit, false, &p);
+ fw_log_print_all_in_bo(vdev, "VPU verbose", vdev->fw->mem_log_verb, false, &p);
}
#endif /* __IVPU_FW_LOG_H__ */
diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c
index e17e4e6b037ee..3a59242b6a423 100644
--- a/drivers/accel/ivpu/ivpu_pm.c
+++ b/drivers/accel/ivpu/ivpu_pm.c
@@ -13,6 +13,7 @@
#include "ivpu_drv.h"
#include "ivpu_hw.h"
#include "ivpu_fw.h"
+#include "ivpu_fw_log.h"
#include "ivpu_ipc.h"
#include "ivpu_job.h"
#include "ivpu_mmu.h"
--
2.53.0
next prev parent reply other threads:[~2026-09-16 18:55 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-16 15:13 FAILED: patch "[PATCH] accel/ivpu: Validate firmware log buffer metadata" failed to apply to 6.6-stable tree gregkh
2026-09-16 18:55 ` [PATCH 6.6.y 1/5] accel/ivpu: Fix a typo Sasha Levin
2026-09-16 18:55 ` [PATCH 6.6.y 2/5] accel/ivpu: Update VPU FW API headers Sasha Levin
2026-09-16 18:55 ` [PATCH 6.6.y 3/5] accel/ivpu: Reset fw log on cold boot Sasha Levin
2026-09-16 18:55 ` Sasha Levin [this message]
2026-09-16 18:55 ` [PATCH 6.6.y 5/5] accel/ivpu: Validate firmware log buffer metadata Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260916185541.1885084-4-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=jacek.lawrynowicz@linux.intel.com \
--cc=stable@vger.kernel.org \
--cc=tomasz.rusinowicz@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox