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

Commit fcbe3439 authored by Linux Build Service Account's avatar Linux Build Service Account
Browse files

Merge 3c1766f3 on remote branch

Change-Id: Ied9564282a2cb1dbf489188b2c1efdfb2ce36bb7
parents 1972aa1c 3c1766f3
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include "camera_main.h"
#include "cam_trace.h"
#include "cam_req_mgr_workq.h"
#include "cam_common_util.h"

#define CAM_CDM_BL_FIFO_WAIT_TIMEOUT 2000
#define CAM_CDM_DBG_GEN_IRQ_USR_DATA 0xff
@@ -1215,8 +1216,10 @@ static void cam_hw_cdm_work(struct work_struct *work)
		return;
	}

	cam_req_mgr_thread_switch_delay_detect(
		payload->workq_scheduled_ts);
	cam_common_util_thread_switch_delay_detect(
		"CDM workq schedule",
		payload->workq_scheduled_ts,
		CAM_WORKQ_SCHEDULE_TIME_THRESHOLD);

	CAM_DBG(CAM_CDM, "IRQ status=0x%x", payload->irq_status);
	if (payload->irq_status &
+6 −3
Original line number Diff line number Diff line
// 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>
@@ -20,6 +20,7 @@
#include "cam_cdm_soc.h"
#include "cam_io_util.h"
#include "cam_req_mgr_workq.h"
#include "cam_common_util.h"

#define CAM_CDM_VIRTUAL_NAME "qcom,cam_virtual_cdm"

@@ -34,8 +35,10 @@ static void cam_virtual_cdm_work(struct work_struct *work)
		cdm_hw = payload->hw;
		core = (struct cam_cdm *)cdm_hw->core_info;

		cam_req_mgr_thread_switch_delay_detect(
			payload->workq_scheduled_ts);
		cam_common_util_thread_switch_delay_detect(
			"Virtual CDM workq schedule",
			payload->workq_scheduled_ts,
			CAM_WORKQ_SCHEDULE_TIME_THRESHOLD);

		if (payload->irq_status & 0x2) {
			struct cam_cdm_bl_cb_request_entry *node;
+5 −2
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#include "cpastop_v680_100.h"
#include "cpastop_v165_100.h"
#include "cam_req_mgr_workq.h"
#include "cam_common_util.h"

struct cam_camnoc_info *camnoc_info;
struct cam_cpas_camnoc_qchannel *qchannel_info;
@@ -598,8 +599,10 @@ static void cam_cpastop_work(struct work_struct *work)
		return;
	}

	cam_req_mgr_thread_switch_delay_detect(
			payload->workq_scheduled_ts);
	cam_common_util_thread_switch_delay_detect(
		"CPAS workq schedule",
		payload->workq_scheduled_ts,
		CAM_WORKQ_SCHEDULE_TIME_THRESHOLD);

	cpas_hw = payload->hw;
	cpas_core = (struct cam_cpas *) cpas_hw->core_info;
+25 −2
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2019, 2021 The Linux Foundation. All rights reserved.
 */

#include <linux/slab.h>
@@ -11,6 +11,14 @@
#include "cam_tasklet_util.h"
#include "cam_irq_controller.h"
#include "cam_debug_util.h"
#include "cam_common_util.h"


/* Threshold for scheduling delay in ms */
#define CAM_TASKLET_SCHED_TIME_THRESHOLD        5

/* Threshold for execution delay in ms */
#define CAM_TASKLET_EXE_TIME_THRESHOLD          10

#define CAM_TASKLETQ_SIZE                          256

@@ -27,6 +35,7 @@ static void cam_tasklet_action(unsigned long data);
 * @handler_priv:           Private data passed at event subscribe
 * @bottom_half_handler:    Function pointer for event handler in bottom
 *                          half context
 * @tasklet_enqueue_ts:     enqueue time of tasklet
 *
 */
struct cam_tasklet_queue_cmd {
@@ -34,6 +43,7 @@ struct cam_tasklet_queue_cmd {
	void                              *payload;
	void                              *handler_priv;
	CAM_IRQ_HANDLER_BOTTOM_HALF        bottom_half_handler;
	ktime_t                            tasklet_enqueue_ts;
};

/**
@@ -209,6 +219,7 @@ void cam_tasklet_enqueue_cmd(
	tasklet_cmd->bottom_half_handler = bottom_half_handler;
	tasklet_cmd->payload = evt_payload_priv;
	tasklet_cmd->handler_priv = handler_priv;
	tasklet_cmd->tasklet_enqueue_ts = ktime_get();
	spin_lock_irqsave(&tasklet->tasklet_lock, flags);
	list_add_tail(&tasklet_cmd->list,
		&tasklet->used_cmd_list);
@@ -322,12 +333,24 @@ static void cam_tasklet_action(unsigned long data)
{
	struct cam_tasklet_info          *tasklet_info = NULL;
	struct cam_tasklet_queue_cmd     *tasklet_cmd = NULL;
	ktime_t                           curr_time;

	tasklet_info = (struct cam_tasklet_info *)data;

	while (!cam_tasklet_dequeue_cmd(tasklet_info, &tasklet_cmd)) {
		cam_common_util_thread_switch_delay_detect(
			"Tasklet schedule",
			tasklet_cmd->tasklet_enqueue_ts,
			CAM_TASKLET_SCHED_TIME_THRESHOLD);
		curr_time = ktime_get();

		tasklet_cmd->bottom_half_handler(tasklet_cmd->handler_priv,
			tasklet_cmd->payload);

		cam_common_util_thread_switch_delay_detect(
			"Tasklet execution",
			curr_time,
			CAM_TASKLET_EXE_TIME_THRESHOLD);
		cam_tasklet_put_cmd(tasklet_info, (void **)(&tasklet_cmd));
	}
}
+13 −25
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
 */

#include "cam_req_mgr_workq.h"
#include "cam_debug_util.h"
#include "cam_common_util.h"

#define WORKQ_ACQUIRE_LOCK(workq, flags) {\
	if ((workq)->in_irq) \
@@ -94,6 +95,7 @@ void cam_req_mgr_process_workq(struct work_struct *w)
	struct crm_workq_task         *task;
	int32_t                        i = CRM_TASK_PRIORITY_0;
	unsigned long                  flags = 0;
	ktime_t                        curr_time;

	if (!w) {
		CAM_ERR(CAM_CRM, "NULL task pointer can not schedule");
@@ -102,7 +104,11 @@ void cam_req_mgr_process_workq(struct work_struct *w)
	workq = (struct cam_req_mgr_core_workq *)
		container_of(w, struct cam_req_mgr_core_workq, work);

	cam_req_mgr_thread_switch_delay_detect(workq->workq_scheduled_ts);
	cam_common_util_thread_switch_delay_detect(
		"CRM workq schedule",
		workq->workq_scheduled_ts,
		CAM_WORKQ_SCHEDULE_TIME_THRESHOLD);
	curr_time = ktime_get();
	while (i < CRM_TASK_PRIORITY_MAX) {
		WORKQ_ACQUIRE_LOCK(workq, flags);
		while (!list_empty(&workq->task.process_head[i])) {
@@ -119,6 +125,10 @@ void cam_req_mgr_process_workq(struct work_struct *w)
		WORKQ_RELEASE_LOCK(workq, flags);
		i++;
	}
	cam_common_util_thread_switch_delay_detect(
		"CRM workq execution",
		curr_time,
		CAM_WORKQ_EXE_TIME_THRESHOLD);
}

int cam_req_mgr_workq_enqueue_task(struct crm_workq_task *task,
@@ -165,8 +175,8 @@ int cam_req_mgr_workq_enqueue_task(struct crm_workq_task *task,
	CAM_DBG(CAM_CRM, "enq task %pK pending_cnt %d",
		task, atomic_read(&workq->task.pending_cnt));

	workq->workq_scheduled_ts = ktime_get();
	queue_work(workq->job, &workq->work);
	workq->workq_scheduled_ts = ktime_get();
	WORKQ_RELEASE_LOCK(workq, flags);
end:
	return rc;
@@ -267,25 +277,3 @@ void cam_req_mgr_workq_destroy(struct cam_req_mgr_core_workq **crm_workq)
		*crm_workq = NULL;
	}
}

void cam_req_mgr_thread_switch_delay_detect(ktime_t workq_scheduled)
{
	uint64_t                         diff;
	ktime_t                          cur_time;
	struct timespec64                cur_ts;
	struct timespec64                workq_scheduled_ts;

	cur_time = ktime_get();
	diff = ktime_ms_delta(cur_time, workq_scheduled);
	workq_scheduled_ts  = ktime_to_timespec64(workq_scheduled);
	cur_ts = ktime_to_timespec64(cur_time);

	if (diff > CAM_WORKQ_RESPONSE_TIME_THRESHOLD) {
		CAM_WARN_RATE_LIMIT(CAM_CRM,
			"Workq delay detected %ld:%06ld %ld:%06ld %ld:",
			workq_scheduled_ts.tv_sec,
			workq_scheduled_ts.tv_nsec/NSEC_PER_USEC,
			cur_ts.tv_sec, cur_ts.tv_nsec/NSEC_PER_USEC,
			diff);
	}
}
Loading