msm: camera: common: Append workq name in log

Append workq name in workq delay detect API to identify
which workq is scheduled late. Create workq name macros for
cci and cpas to pass to workq delay detect API.

CRs-Fixed: 2994927
Change-Id: Iebc14520b918272e92b59c900de5fe17f38a2406
Signed-off-by: Sokchetra Eung <eung@codeaurora.org>
This commit is contained in:
Sokchetra Eung
2021-07-14 23:15:03 -07:00
committed by Gerrit - the friendly Code Review server
parent 13670c580a
commit ba664cddff
11 changed files with 24 additions and 15 deletions

View File

@@ -1306,7 +1306,7 @@ static void cam_hw_cdm_work(struct work_struct *work)
return; return;
} }
cam_req_mgr_thread_switch_delay_detect( cam_req_mgr_thread_switch_delay_detect(cdm_hw->soc_info.dev_name,
payload->workq_scheduled_ts); payload->workq_scheduled_ts);
CAM_DBG(CAM_CDM, "IRQ status=0x%x", payload->irq_status); CAM_DBG(CAM_CDM, "IRQ status=0x%x", payload->irq_status);
@@ -2339,9 +2339,9 @@ static int cam_hw_cdm_component_bind(struct device *dev,
init_completion(&cdm_core->bl_fifo[i].bl_complete); init_completion(&cdm_core->bl_fifo[i].bl_complete);
len = strlcpy(work_q_name, cdm_core->name, len = strlcpy(work_q_name, cdm_hw->soc_info.label_name,
sizeof(cdm_core->name)); sizeof(work_q_name));
snprintf(work_q_name + len, sizeof(work_q_name) - len, "%d", i); snprintf(work_q_name + len, sizeof(work_q_name) - len, "%d_%d", cdm_hw->soc_info.index, i);
cdm_core->bl_fifo[i].work_queue = alloc_workqueue(work_q_name, cdm_core->bl_fifo[i].work_queue = alloc_workqueue(work_q_name,
WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_SYSFS, WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_SYSFS,
CAM_CDM_INFLIGHT_WORKS); CAM_CDM_INFLIGHT_WORKS);

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*/ */
#include <linux/delay.h> #include <linux/delay.h>
@@ -34,7 +34,7 @@ static void cam_virtual_cdm_work(struct work_struct *work)
cdm_hw = payload->hw; cdm_hw = payload->hw;
core = (struct cam_cdm *)cdm_hw->core_info; core = (struct cam_cdm *)cdm_hw->core_info;
cam_req_mgr_thread_switch_delay_detect( cam_req_mgr_thread_switch_delay_detect(core->name,
payload->workq_scheduled_ts); payload->workq_scheduled_ts);
if (payload->irq_status & 0x2) { if (payload->irq_status & 0x2) {

View File

@@ -3006,7 +3006,7 @@ int cam_cpas_hw_probe(struct platform_device *pdev,
cpas_hw_intf->hw_ops.write = NULL; cpas_hw_intf->hw_ops.write = NULL;
cpas_hw_intf->hw_ops.process_cmd = cam_cpas_hw_process_cmd; cpas_hw_intf->hw_ops.process_cmd = cam_cpas_hw_process_cmd;
cpas_core->work_queue = alloc_workqueue("cam-cpas", cpas_core->work_queue = alloc_workqueue(CAM_CPAS_WORKQUEUE_NAME,
WQ_UNBOUND | WQ_MEM_RECLAIM, CAM_CPAS_INFLIGHT_WORKS); WQ_UNBOUND | WQ_MEM_RECLAIM, CAM_CPAS_INFLIGHT_WORKS);
if (!cpas_core->work_queue) { if (!cpas_core->work_queue) {
rc = -ENOMEM; rc = -ENOMEM;

View File

@@ -31,6 +31,8 @@
#define CAM_CPAS_GET_CLIENT_IDX(handle) (handle) #define CAM_CPAS_GET_CLIENT_IDX(handle) (handle)
#define CAM_CPAS_GET_CLIENT_HANDLE(indx) (indx) #define CAM_CPAS_GET_CLIENT_HANDLE(indx) (indx)
#define CAM_CPAS_WORKQUEUE_NAME "cam-cpas"
#define CAM_CPAS_CLIENT_VALID(indx) \ #define CAM_CPAS_CLIENT_VALID(indx) \
((indx >= 0) && (indx < CAM_CPAS_MAX_CLIENTS)) ((indx >= 0) && (indx < CAM_CPAS_MAX_CLIENTS))
#define CAM_CPAS_CLIENT_REGISTERED(cpas_core, indx) \ #define CAM_CPAS_CLIENT_REGISTERED(cpas_core, indx) \

View File

@@ -602,7 +602,7 @@ static void cam_cpastop_work(struct work_struct *work)
return; return;
} }
cam_req_mgr_thread_switch_delay_detect( cam_req_mgr_thread_switch_delay_detect(CAM_CPAS_WORKQUEUE_NAME,
payload->workq_scheduled_ts); payload->workq_scheduled_ts);
cpas_hw = payload->hw; cpas_hw = payload->hw;

View File

@@ -114,7 +114,7 @@ void cam_req_mgr_process_workq(struct work_struct *w)
workq = (struct cam_req_mgr_core_workq *) workq = (struct cam_req_mgr_core_workq *)
container_of(w, struct cam_req_mgr_core_workq, work); container_of(w, struct cam_req_mgr_core_workq, work);
cam_req_mgr_thread_switch_delay_detect(workq->workq_scheduled_ts); cam_req_mgr_thread_switch_delay_detect(workq->workq_name, workq->workq_scheduled_ts);
while (i < CRM_TASK_PRIORITY_MAX) { while (i < CRM_TASK_PRIORITY_MAX) {
WORKQ_ACQUIRE_LOCK(workq, flags); WORKQ_ACQUIRE_LOCK(workq, flags);
while (!list_empty(&workq->task.process_head[i])) { while (!list_empty(&workq->task.process_head[i])) {
@@ -217,6 +217,7 @@ int cam_req_mgr_workq_create(char *name, int32_t num_tasks,
} }
/* Workq attributes initialization */ /* Workq attributes initialization */
strlcpy(crm_workq->workq_name, buf, sizeof(crm_workq->workq_name));
INIT_WORK(&crm_workq->work, func); INIT_WORK(&crm_workq->work, func);
spin_lock_init(&crm_workq->lock_bh); spin_lock_init(&crm_workq->lock_bh);
CAM_DBG(CAM_CRM, "LOCK_DBG workq %s lock %pK", CAM_DBG(CAM_CRM, "LOCK_DBG workq %s lock %pK",
@@ -282,7 +283,7 @@ void cam_req_mgr_workq_destroy(struct cam_req_mgr_core_workq **crm_workq)
} }
} }
void cam_req_mgr_thread_switch_delay_detect(ktime_t workq_scheduled) void cam_req_mgr_thread_switch_delay_detect(const char *name, ktime_t workq_scheduled)
{ {
uint64_t diff; uint64_t diff;
ktime_t cur_time; ktime_t cur_time;
@@ -296,7 +297,8 @@ void cam_req_mgr_thread_switch_delay_detect(ktime_t workq_scheduled)
if (diff > CAM_WORKQ_RESPONSE_TIME_THRESHOLD) { if (diff > CAM_WORKQ_RESPONSE_TIME_THRESHOLD) {
CAM_WARN_RATE_LIMIT(CAM_CRM, CAM_WARN_RATE_LIMIT(CAM_CRM,
"Workq delay detected %ld:%06ld %ld:%06ld %ld:", "Workq %s delay detected %ld:%06ld %ld:%06ld %ld:",
name,
workq_scheduled_ts.tv_sec, workq_scheduled_ts.tv_sec,
workq_scheduled_ts.tv_nsec/NSEC_PER_USEC, workq_scheduled_ts.tv_nsec/NSEC_PER_USEC,
cur_ts.tv_sec, cur_ts.tv_nsec/NSEC_PER_USEC, cur_ts.tv_sec, cur_ts.tv_nsec/NSEC_PER_USEC,

View File

@@ -77,6 +77,7 @@ struct crm_workq_task {
* @lock_bh : lock for task structs * @lock_bh : lock for task structs
* @in_irq : set true if workque can be used in irq context * @in_irq : set true if workque can be used in irq context
* @flush : used to track if flush has been called on workqueue * @flush : used to track if flush has been called on workqueue
* @work_q_name : name of the workq
* task - * task -
* @lock : Current task's lock handle * @lock : Current task's lock handle
* @pending_cnt : # of tasks left in queue * @pending_cnt : # of tasks left in queue
@@ -94,6 +95,7 @@ struct cam_req_mgr_core_workq {
uint32_t in_irq; uint32_t in_irq;
ktime_t workq_scheduled_ts; ktime_t workq_scheduled_ts;
atomic_t flush; atomic_t flush;
char workq_name[128];
/* tasks */ /* tasks */
struct { struct {
@@ -155,9 +157,10 @@ int cam_req_mgr_workq_enqueue_task(struct crm_workq_task *task,
/** /**
* cam_req_mgr_thread_switch_delay_detect() * cam_req_mgr_thread_switch_delay_detect()
* @brief: Detects if workq delay has occurred or not * @brief: Detects if workq delay has occurred or not
* @name : Name of the workq
* @timestamp: workq scheduled timestamp * @timestamp: workq scheduled timestamp
*/ */
void cam_req_mgr_thread_switch_delay_detect( void cam_req_mgr_thread_switch_delay_detect(const char *name,
ktime_t timestamp); ktime_t timestamp);
/** /**

View File

@@ -1506,7 +1506,7 @@ static void cam_cci_write_async_helper(struct work_struct *work)
enum cci_i2c_master_t master; enum cci_i2c_master_t master;
struct cam_cci_master_info *cci_master_info; struct cam_cci_master_info *cci_master_info;
cam_req_mgr_thread_switch_delay_detect( cam_req_mgr_thread_switch_delay_detect(CAM_CCI_WORKQUEUE_NAME,
write_async->workq_scheduled_ts); write_async->workq_scheduled_ts);
cci_dev = write_async->cci_dev; cci_dev = write_async->cci_dev;
i2c_msg = &write_async->c_ctrl.cfg.cci_i2c_write_cfg; i2c_msg = &write_async->c_ctrl.cfg.cci_i2c_write_cfg;

View File

@@ -57,6 +57,8 @@
#define CAMX_CCI_DEV_NAME "cam-cci-driver" #define CAMX_CCI_DEV_NAME "cam-cci-driver"
#define CAM_CCI_WORKQUEUE_NAME "cam_cci_wq"
#define MAX_CCI 2 #define MAX_CCI 2
#define PRIORITY_QUEUE (QUEUE_0) #define PRIORITY_QUEUE (QUEUE_0)

View File

@@ -399,7 +399,7 @@ int cam_cci_parse_dt_info(struct platform_device *pdev,
for (i = 0; i < MASTER_MAX; i++) { for (i = 0; i < MASTER_MAX; i++) {
new_cci_dev->write_wq[i] = create_singlethread_workqueue( new_cci_dev->write_wq[i] = create_singlethread_workqueue(
"cam_cci_wq"); CAM_CCI_WORKQUEUE_NAME);
if (!new_cci_dev->write_wq[i]) if (!new_cci_dev->write_wq[i])
CAM_ERR(CAM_CCI, "Failed to create write wq"); CAM_ERR(CAM_CCI, "Failed to create write wq");
} }

View File

@@ -294,7 +294,7 @@ void cam_sync_util_cb_dispatch(struct work_struct *cb_dispatch_work)
cb_dispatch_work); cb_dispatch_work);
sync_callback sync_data = cb_info->callback_func; sync_callback sync_data = cb_info->callback_func;
cam_req_mgr_thread_switch_delay_detect( cam_req_mgr_thread_switch_delay_detect(CAM_SYNC_WORKQUEUE_NAME,
cb_info->workq_scheduled_ts); cb_info->workq_scheduled_ts);
sync_data(cb_info->sync_obj, cb_info->status, cb_info->cb_data); sync_data(cb_info->sync_obj, cb_info->status, cb_info->cb_data);