Re: [PATCH v2 2/2] media: qcom: iris: reduce impact of verbose firmware logging
From: Vishnu Reddy
Date: Thu Sep 24 2026 - 12:36:56 EST
On 9/11/2026 8:09 AM, Renjiang Han wrote:
> Verbose firmware logging can produce a large number of debug queue
> packets. The Iris interrupt thread used to drain the message queue once
> and then drain the debug queue. With heavy firmware logging, response
> packets that arrive while debug packets are being drained can remain
> pending until a later interrupt.
>
> Increase the HFI response timeout and runtime PM autosuspend delay when
> firmware logging is enabled beyond the default error and fatal levels.
> Restore the default values when the firmware log level is reduced again.
>
> Signed-off-by: Renjiang Han <renjiang.han@xxxxxxxxxxxxxxxx>
> ---
> drivers/media/platform/qcom/iris/iris_core.c | 2 +-
> drivers/media/platform/qcom/iris/iris_core.h | 2 ++
> drivers/media/platform/qcom/iris/iris_debugfs.c | 16 ++++++++++++++-
> drivers/media/platform/qcom/iris/iris_hfi_common.h | 1 +
> .../platform/qcom/iris/iris_hfi_gen1_response.c | 24 ++++++++++++++++------
> .../platform/qcom/iris/iris_hfi_gen2_response.c | 24 ++++++++++++++++------
> drivers/media/platform/qcom/iris/iris_probe.c | 3 ++-
> drivers/media/platform/qcom/iris/iris_utils.c | 4 +++-
> 8 files changed, 60 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/iris/iris_core.c b/drivers/media/platform/qcom/iris/iris_core.c
> index 8c335dbfce166848892c2b323cdcafe43af4a2d9..bbbb7191c4778d842d4fef32fa95a0a9aeeecf7a 100644
> --- a/drivers/media/platform/qcom/iris/iris_core.c
> +++ b/drivers/media/platform/qcom/iris/iris_core.c
> @@ -40,7 +40,7 @@ static int iris_wait_for_system_response(struct iris_core *core)
> return -EIO;
>
> ret = wait_for_completion_timeout(&core->core_init_done,
> - msecs_to_jiffies(HW_RESPONSE_TIMEOUT_VALUE));
> + msecs_to_jiffies(READ_ONCE(core->hw_response_timeout)));
> if (!ret) {
> core->state = IRIS_CORE_ERROR;
> return -ETIMEDOUT;
> diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h
> index a8e34c456ce3f3f178ca66a278d06d1ab50dafc4..5449e6b0e11c3122d1f57aedb6dd374ffa816497 100644
> --- a/drivers/media/platform/qcom/iris/iris_core.h
> +++ b/drivers/media/platform/qcom/iris/iris_core.h
> @@ -68,6 +68,7 @@ struct dentry;
> * @debug_queue: shared interface queue to receive debug info from firmware
> * @root: debugfs root directory
> * @fw_debug: firmware debug log mask
> + * @hw_response_timeout: hardware response timeout
> * @lock: a lock for this structure
> * @response_packet: a pointer to response packet from fw to driver
> * @header_id: id of packet header
> @@ -115,6 +116,7 @@ struct iris_core {
> struct iris_iface_q_info debug_queue;
> struct dentry *root;
> u32 fw_debug;
> + u32 hw_response_timeout;
> struct mutex lock; /* lock for core related operations */
> u8 *response_packet;
> u32 header_id;
> diff --git a/drivers/media/platform/qcom/iris/iris_debugfs.c b/drivers/media/platform/qcom/iris/iris_debugfs.c
> index 6122b994ad0aa70c0c4f26ea4ce076f1b025f810..77726270b11777acb5ea85203223c6943365a5ce 100644
> --- a/drivers/media/platform/qcom/iris/iris_debugfs.c
> +++ b/drivers/media/platform/qcom/iris/iris_debugfs.c
> @@ -4,6 +4,7 @@
> */
>
> #include <linux/debugfs.h>
> +#include <linux/pm_runtime.h>
>
> #include "iris_core.h"
> #include "iris_debugfs.h"
> @@ -20,8 +21,21 @@ static int iris_fw_level_get(void *data, u64 *val)
> static int iris_fw_level_set(void *data, u64 val)
> {
> struct iris_core *core = data;
> + bool debug_enabled;
> + u32 fw_debug;
>
> - WRITE_ONCE(core->fw_debug, (u32)val & IRIS_FW_DEBUG_LOGMASK);
> + fw_debug = (u32)val & IRIS_FW_DEBUG_LOGMASK;
> + debug_enabled = fw_debug & ~IRIS_FW_DEBUG_DEFAULT;
> +
> + WRITE_ONCE(core->fw_debug, fw_debug);
> +
> + if (debug_enabled) {
> + WRITE_ONCE(core->hw_response_timeout, 4 * HW_RESPONSE_TIMEOUT_VALUE);
> + pm_runtime_set_autosuspend_delay(core->dev, 4 * AUTOSUSPEND_DELAY_VALUE);
> + } else {
> + WRITE_ONCE(core->hw_response_timeout, HW_RESPONSE_TIMEOUT_VALUE);
> + pm_runtime_set_autosuspend_delay(core->dev, AUTOSUSPEND_DELAY_VALUE);
> + }
>
> return 0;
> }
> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/media/platform/qcom/iris/iris_hfi_common.h
> index d8bc0862c54bd229d575113752526d51e863e303..18c852d8b818f41bf5e1b0afd35082eeaf5240b4 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_common.h
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h
> @@ -112,6 +112,7 @@ struct iris_hfi_prop_type_handle {
> #define IRIS_FW_DEBUG_FATAL 0x00000010
> #define IRIS_FW_DEBUG_PERF 0x00000020
> #define IRIS_FW_DEBUG_LOGMASK 0x0fffffff
> +#define IRIS_FW_DEBUG_DEFAULT (IRIS_FW_DEBUG_ERROR | IRIS_FW_DEBUG_FATAL)
>
> struct iris_hfi_sys_ops {
> int (*sys_init)(struct iris_core *core);
> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
> index 903b60a7380559f4711b0907fb1de405fe1707f3..6b8f952d0d4b54f37596728f1823c9265c637bbe 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
> @@ -672,15 +672,17 @@ static void iris_hfi_gen1_handle_response(struct iris_core *core, void *response
> }
> }
>
> -static void iris_hfi_gen1_flush_debug_queue(struct iris_core *core, u8 *packet)
> +static int iris_hfi_gen1_flush_debug_queue(struct iris_core *core, u8 *packet)
> {
> struct hfi_msg_sys_debug_pkt *pkt;
> struct hfi_pkt_hdr *hdr;
> + int num_pkts = 0;
> u32 log_size;
> u8 *log;
>
> while (!iris_hfi_queue_dbg_read(core, packet)) {
> hdr = (struct hfi_pkt_hdr *)packet;
> + num_pkts++;
>
> if (hdr->size <= sizeof(*hdr))
> continue;
> @@ -705,15 +707,25 @@ static void iris_hfi_gen1_flush_debug_queue(struct iris_core *core, u8 *packet)
> dev_dbg(core->dev, "%.*s", (int)log_size, log);
> }
> }
> +
> + return num_pkts;
> }
>
> void iris_hfi_gen1_response_handler(struct iris_core *core)
> {
> - memset(core->response_packet, 0, sizeof(struct hfi_pkt_hdr));
> - while (!iris_hfi_queue_msg_read(core, core->response_packet)) {
> - iris_hfi_gen1_handle_response(core, core->response_packet);
> + int num_debug_pkts;
> + int num_msg_pkts;
> +
> + do {
> + num_msg_pkts = 0;
> memset(core->response_packet, 0, sizeof(struct hfi_pkt_hdr));
> - }
> + while (!iris_hfi_queue_msg_read(core, core->response_packet)) {
> + iris_hfi_gen1_handle_response(core, core->response_packet);
> + num_msg_pkts++;
> + memset(core->response_packet, 0, sizeof(struct hfi_pkt_hdr));
> + }
>
> - iris_hfi_gen1_flush_debug_queue(core, core->response_packet);
> + num_debug_pkts =
> + iris_hfi_gen1_flush_debug_queue(core, core->response_packet);
> + } while (num_msg_pkts || num_debug_pkts);
> }
> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
> index e8dc8751ea939bd544699f464a831736fcc10b7f..1bd4ec0c5ada1ef17de4f07fe19d1fac611db04f 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
> @@ -988,14 +988,16 @@ static int iris_hfi_gen2_handle_response(struct iris_core *core, void *response)
> return iris_hfi_gen2_handle_session_response(core, hdr);
> }
>
> -static void iris_hfi_gen2_flush_debug_queue(struct iris_core *core, u8 *packet)
> +static int iris_hfi_gen2_flush_debug_queue(struct iris_core *core, u8 *packet)
> {
> struct hfi_debug_header *pkt;
> + int num_pkts = 0;
> u32 log_size;
> u8 *log;
>
> while (!iris_hfi_queue_dbg_read(core, packet)) {
> pkt = (struct hfi_debug_header *)packet;
> + num_pkts++;
>
> if (pkt->size <= sizeof(*pkt) + 1)
> continue;
> @@ -1010,10 +1012,15 @@ static void iris_hfi_gen2_flush_debug_queue(struct iris_core *core, u8 *packet)
> else
> dev_dbg(core->dev, "%.*s", (int)log_size, log);
> }
> +
> + return num_pkts;
> }
>
> void iris_hfi_gen2_response_handler(struct iris_core *core)
> {
> + int num_debug_pkts;
> + int num_msg_pkts;
> +
> if (iris_vpu_watchdog(core, core->intr_status)) {
> struct iris_hfi_packet pkt = {.type = HFI_SYS_ERROR_WD_TIMEOUT};
>
> @@ -1024,11 +1031,16 @@ void iris_hfi_gen2_response_handler(struct iris_core *core)
> return;
> }
>
> - memset(core->response_packet, 0, sizeof(struct iris_hfi_header));
> - while (!iris_hfi_queue_msg_read(core, core->response_packet)) {
> - iris_hfi_gen2_handle_response(core, core->response_packet);
> + do {
> + num_msg_pkts = 0;
> memset(core->response_packet, 0, sizeof(struct iris_hfi_header));
> - }
> + while (!iris_hfi_queue_msg_read(core, core->response_packet)) {
> + iris_hfi_gen2_handle_response(core, core->response_packet);
> + num_msg_pkts++;
> + memset(core->response_packet, 0, sizeof(struct iris_hfi_header));
> + }
>
> - iris_hfi_gen2_flush_debug_queue(core, core->response_packet);
> + num_debug_pkts =
> + iris_hfi_gen2_flush_debug_queue(core, core->response_packet);
> + } while (num_msg_pkts || num_debug_pkts);
> }
> diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c
> index 8bc94acc4f58ce7792ddaeaad036475c476d5c36..318a548a7ac606594a41d9dae25e73205de1fd0d 100644
> --- a/drivers/media/platform/qcom/iris/iris_probe.c
> +++ b/drivers/media/platform/qcom/iris/iris_probe.c
> @@ -233,7 +233,8 @@ static int iris_probe(struct platform_device *pdev)
> if (!core)
> return -ENOMEM;
> core->dev = dev;
> - core->fw_debug = IRIS_FW_DEBUG_ERROR | IRIS_FW_DEBUG_FATAL;
> + core->fw_debug = IRIS_FW_DEBUG_DEFAULT;
> + core->hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE;
>
> core->state = IRIS_CORE_DEINIT;
> mutex_init(&core->lock);
> diff --git a/drivers/media/platform/qcom/iris/iris_utils.c b/drivers/media/platform/qcom/iris/iris_utils.c
> index ba5c8dc1280c2e147cd33498b69a815cf7c75683..dbddfd770edce22fba58eff15cb6d45eae5ed638 100644
> --- a/drivers/media/platform/qcom/iris/iris_utils.c
> +++ b/drivers/media/platform/qcom/iris/iris_utils.c
> @@ -70,12 +70,14 @@ void iris_helper_buffers_done(struct iris_inst *inst, unsigned int type,
> int iris_wait_for_session_response(struct iris_inst *inst, bool is_flush)
> {
> struct completion *done;
> + unsigned int timeout;
> int ret;
>
> done = is_flush ? &inst->flush_completion : &inst->completion;
> + timeout = READ_ONCE(inst->core->hw_response_timeout);
>
> mutex_unlock(&inst->lock);
> - ret = wait_for_completion_timeout(done, msecs_to_jiffies(HW_RESPONSE_TIMEOUT_VALUE));
> + ret = wait_for_completion_timeout(done, msecs_to_jiffies(timeout));
> mutex_lock(&inst->lock);
> if (!ret) {
> iris_inst_change_state(inst, IRIS_INST_ERROR);
Reviewed-by: Vishnu Reddy <busanna.reddy@xxxxxxxxxxxxxxxx>