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

Commit 3f0b4eeb authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: sde: Convert workq to kernel thread in SDE rotator"

parents 11ce4393 f8d9a466
Loading
Loading
Loading
Loading
+59 −26
Original line number Diff line number Diff line
@@ -1021,6 +1021,7 @@ static int sde_rotator_init_queue(struct sde_rot_mgr *mgr)
{
	int i, size, ret = 0;
	char name[32];
	struct sched_param param = { .sched_priority = 5 };

	size = sizeof(struct sde_rot_queue) * mgr->queue_count;
	mgr->commitq = devm_kzalloc(mgr->device, size, GFP_KERNEL);
@@ -1031,11 +1032,21 @@ static int sde_rotator_init_queue(struct sde_rot_mgr *mgr)
		snprintf(name, sizeof(name), "rot_commitq_%d_%d",
				mgr->device->id, i);
		SDEROT_DBG("work queue name=%s\n", name);
		mgr->commitq[i].rot_work_queue =
			alloc_ordered_workqueue("%s",
				WQ_MEM_RECLAIM | WQ_HIGHPRI, name);
		if (!mgr->commitq[i].rot_work_queue) {
		kthread_init_worker(&mgr->commitq[i].rot_kw);
		mgr->commitq[i].rot_thread = kthread_run(kthread_worker_fn,
				&mgr->commitq[i].rot_kw, name);
		if (IS_ERR(mgr->commitq[i].rot_thread)) {
			ret = -EPERM;
			mgr->commitq[i].rot_thread = NULL;
			break;
		}

		ret = sched_setscheduler(mgr->commitq[i].rot_thread,
			SCHED_FIFO, &param);
		if (ret) {
			SDEROT_ERR(
				"failed to set kthread priority for commitq %d\n",
				ret);
			break;
		}

@@ -1052,10 +1063,21 @@ static int sde_rotator_init_queue(struct sde_rot_mgr *mgr)
		snprintf(name, sizeof(name), "rot_doneq_%d_%d",
				mgr->device->id, i);
		SDEROT_DBG("work queue name=%s\n", name);
		mgr->doneq[i].rot_work_queue = alloc_ordered_workqueue("%s",
				WQ_MEM_RECLAIM | WQ_HIGHPRI, name);
		if (!mgr->doneq[i].rot_work_queue) {
		kthread_init_worker(&mgr->doneq[i].rot_kw);
		mgr->doneq[i].rot_thread = kthread_run(kthread_worker_fn,
				&mgr->doneq[i].rot_kw, name);
		if (IS_ERR(mgr->doneq[i].rot_thread)) {
			ret = -EPERM;
			mgr->doneq[i].rot_thread = NULL;
			break;
		}

		ret = sched_setscheduler(mgr->doneq[i].rot_thread,
			SCHED_FIFO, &param);
		if (ret) {
			SDEROT_ERR(
				"failed to set kthread priority for doneq %d\n",
				ret);
			break;
		}

@@ -1071,18 +1093,20 @@ static void sde_rotator_deinit_queue(struct sde_rot_mgr *mgr)

	if (mgr->commitq) {
		for (i = 0; i < mgr->queue_count; i++) {
			if (mgr->commitq[i].rot_work_queue)
				destroy_workqueue(
					mgr->commitq[i].rot_work_queue);
			if (mgr->commitq[i].rot_thread) {
				kthread_flush_worker(&mgr->commitq[i].rot_kw);
				kthread_stop(mgr->commitq[i].rot_thread);
			}
		}
		devm_kfree(mgr->device, mgr->commitq);
		mgr->commitq = NULL;
	}
	if (mgr->doneq) {
		for (i = 0; i < mgr->queue_count; i++) {
			if (mgr->doneq[i].rot_work_queue)
				destroy_workqueue(
					mgr->doneq[i].rot_work_queue);
			if (mgr->doneq[i].rot_thread) {
				kthread_flush_worker(&mgr->doneq[i].rot_kw);
				kthread_stop(mgr->doneq[i].rot_thread);
			}
		}
		devm_kfree(mgr->device, mgr->doneq);
		mgr->doneq = NULL;
@@ -1203,7 +1227,7 @@ void sde_rotator_queue_request(struct sde_rot_mgr *mgr,

		if (entry->item.ts)
			entry->item.ts[SDE_ROTATOR_TS_QUEUE] = ktime_get();
		queue_work(queue->rot_work_queue, &entry->commit_work);
		kthread_queue_work(&queue->rot_kw, &entry->commit_work);
	}
}

@@ -1423,12 +1447,13 @@ static void sde_rotator_release_entry(struct sde_rot_mgr *mgr,
 *
 * Note this asynchronous handler is protected by hal lock.
 */
static void sde_rotator_commit_handler(struct work_struct *work)
static void sde_rotator_commit_handler(struct kthread_work *work)
{
	struct sde_rot_entry *entry;
	struct sde_rot_entry_container *request;
	struct sde_rot_hw_resource *hw;
	struct sde_rot_mgr *mgr;
	struct sched_param param = { .sched_priority = 5 };
	int ret;

	entry = container_of(work, struct sde_rot_entry, commit_work);
@@ -1439,6 +1464,12 @@ static void sde_rotator_commit_handler(struct work_struct *work)
		return;
	}

	ret = sched_setscheduler(entry->fenceq->rot_thread, SCHED_FIFO, &param);
	if (ret) {
		SDEROT_WARN("Fail to set kthread priority for fenceq: %d\n",
				ret);
	}

	mgr = entry->private->mgr;

	SDEROT_EVTLOG(
@@ -1514,7 +1545,7 @@ static void sde_rotator_commit_handler(struct work_struct *work)

	SDEROT_EVTLOG(entry->item.session_id, 1);

	queue_work(entry->doneq->rot_work_queue, &entry->done_work);
	kthread_queue_work(&entry->doneq->rot_kw, &entry->done_work);
	sde_rot_mgr_unlock(mgr);
	return;
error:
@@ -1526,8 +1557,8 @@ static void sde_rotator_commit_handler(struct work_struct *work)
	sde_rotator_release_entry(mgr, entry);
	atomic_dec(&request->pending_count);
	atomic_inc(&request->failed_count);
	if (request->retireq && request->retire_work)
		queue_work(request->retireq, request->retire_work);
	if (request->retire_kw && request->retire_work)
		kthread_queue_work(request->retire_kw, request->retire_work);
	sde_rot_mgr_unlock(mgr);
}

@@ -1541,7 +1572,7 @@ static void sde_rotator_commit_handler(struct work_struct *work)
 *
 * Note this asynchronous handler is protected by hal lock.
 */
static void sde_rotator_done_handler(struct work_struct *work)
static void sde_rotator_done_handler(struct kthread_work *work)
{
	struct sde_rot_entry *entry;
	struct sde_rot_entry_container *request;
@@ -1606,8 +1637,8 @@ static void sde_rotator_done_handler(struct work_struct *work)
	ATRACE_INT("sde_rot_done", 1);
	sde_rotator_release_entry(mgr, entry);
	atomic_dec(&request->pending_count);
	if (request->retireq && request->retire_work)
		queue_work(request->retireq, request->retire_work);
	if (request->retire_kw && request->retire_work)
		kthread_queue_work(request->retire_kw, request->retire_work);
	if (entry->item.ts)
		entry->item.ts[SDE_ROTATOR_TS_RETIRE] = ktime_get();
	sde_rot_mgr_unlock(mgr);
@@ -1966,8 +1997,10 @@ static int sde_rotator_add_request(struct sde_rot_mgr *mgr,

		entry->request = req;

		INIT_WORK(&entry->commit_work, sde_rotator_commit_handler);
		INIT_WORK(&entry->done_work, sde_rotator_done_handler);
		kthread_init_work(&entry->commit_work,
				sde_rotator_commit_handler);
		kthread_init_work(&entry->done_work,
				sde_rotator_done_handler);
		SDEROT_DBG(
			"Entry added. wbidx=%u, src{%u,%u,%u,%u}f=%x dst{%u,%u,%u,%u}f=%x session_id=%u\n",
			item->wb_idx,
@@ -2016,8 +2049,8 @@ static void sde_rotator_cancel_request(struct sde_rot_mgr *mgr,
		sde_rot_mgr_unlock(mgr);
		for (i = req->count - 1; i >= 0; i--) {
			entry = req->entries + i;
			cancel_work_sync(&entry->commit_work);
			cancel_work_sync(&entry->done_work);
			kthread_cancel_work_sync(&entry->commit_work);
			kthread_cancel_work_sync(&entry->done_work);
		}
		sde_rot_mgr_lock(mgr);
		SDEROT_DBG("cancel work done\n");
@@ -2134,7 +2167,7 @@ void sde_rotator_commit_request(struct sde_rot_mgr *mgr,

	sde_rot_mgr_unlock(mgr);
	for (i = 0; i < req->count; i++)
		flush_work(&req->entries[i].commit_work);
		kthread_flush_work(&req->entries[i].commit_work);
	sde_rot_mgr_lock(mgr);
}

+7 −6
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@
#include <linux/types.h>
#include <linux/cdev.h>
#include <linux/pm_runtime.h>
#include <linux/completion.h>
#include <linux/kthread.h>

#include "sde_rotator_base.h"
#include "sde_rotator_util.h"
@@ -230,7 +230,8 @@ struct sde_rot_hw_resource {
};

struct sde_rot_queue {
	struct workqueue_struct *rot_work_queue;
	struct kthread_worker rot_kw;
	struct task_struct *rot_thread;
	struct sde_rot_timeline *timeline;
	struct sde_rot_hw_resource *hw;
};
@@ -253,8 +254,8 @@ struct sde_rot_entry_container {
	u32 count;
	atomic_t pending_count;
	atomic_t failed_count;
	struct workqueue_struct *retireq;
	struct work_struct *retire_work;
	struct kthread_worker *retire_kw;
	struct kthread_work *retire_work;
	bool finished;
	struct sde_rot_entry *entries;
};
@@ -284,8 +285,8 @@ struct sde_rot_file_private;
 */
struct sde_rot_entry {
	struct sde_rotation_item item;
	struct work_struct commit_work;
	struct work_struct done_work;
	struct kthread_work commit_work;
	struct kthread_work done_work;
	struct sde_rot_queue *commitq;
	struct sde_rot_queue *fenceq;
	struct sde_rot_queue *doneq;
+24 −20
Original line number Diff line number Diff line
@@ -54,8 +54,8 @@
#define SDE_ROTATOR_DEGREE_180		180
#define SDE_ROTATOR_DEGREE_90		90

static void sde_rotator_submit_handler(struct work_struct *work);
static void sde_rotator_retire_handler(struct work_struct *work);
static void sde_rotator_submit_handler(struct kthread_work *work);
static void sde_rotator_retire_handler(struct kthread_work *work);
#ifdef CONFIG_COMPAT
static long sde_rotator_compat_ioctl32(struct file *file,
	unsigned int cmd, unsigned long arg);
@@ -467,8 +467,8 @@ static void sde_rotator_stop_streaming(struct vb2_queue *q)
			SDEDEV_DBG(rot_dev->dev, "cancel request s:%d\n",
					ctx->session_id);
			mutex_unlock(q->lock);
			cancel_work_sync(&request->submit_work);
			cancel_work_sync(&request->retire_work);
			kthread_cancel_work_sync(&request->submit_work);
			kthread_cancel_work_sync(&request->retire_work);
			mutex_lock(q->lock);
			spin_lock(&ctx->list_lock);
			list_del_init(&request->list);
@@ -926,9 +926,9 @@ struct sde_rotator_ctx *sde_rotator_ctx_open(
	for (i = 0 ; i < ARRAY_SIZE(ctx->requests); i++) {
		struct sde_rotator_request *request = &ctx->requests[i];

		INIT_WORK(&request->submit_work,
		kthread_init_work(&request->submit_work,
				sde_rotator_submit_handler);
		INIT_WORK(&request->retire_work,
		kthread_init_work(&request->retire_work,
				sde_rotator_retire_handler);
		request->ctx = ctx;
		INIT_LIST_HEAD(&request->list);
@@ -965,14 +965,16 @@ struct sde_rotator_ctx *sde_rotator_ctx_open(

	snprintf(name, sizeof(name), "rot_fenceq_%d_%d", rot_dev->dev->id,
			ctx->session_id);
	ctx->work_queue.rot_work_queue = alloc_ordered_workqueue("%s",
			WQ_MEM_RECLAIM | WQ_HIGHPRI, name);
	if (!ctx->work_queue.rot_work_queue) {
		SDEDEV_ERR(ctx->rot_dev->dev, "fail allocate workqueue\n");
	kthread_init_worker(&ctx->work_queue.rot_kw);
	ctx->work_queue.rot_thread = kthread_run(kthread_worker_fn,
			&ctx->work_queue.rot_kw, name);
	if (IS_ERR(ctx->work_queue.rot_thread)) {
		SDEDEV_ERR(ctx->rot_dev->dev, "fail allocate kthread\n");
		ret = -EPERM;
		ctx->work_queue.rot_thread = NULL;
		goto error_alloc_workqueue;
	}
	SDEDEV_DBG(ctx->rot_dev->dev, "work queue name=%s\n", name);
	SDEDEV_DBG(ctx->rot_dev->dev, "kthread name=%s\n", name);

	snprintf(name, sizeof(name), "%d_%d", rot_dev->dev->id,
			ctx->session_id);
@@ -1022,7 +1024,8 @@ struct sde_rotator_ctx *sde_rotator_ctx_open(
error_open_session:
	sde_rot_mgr_unlock(rot_dev->mgr);
	sde_rotator_destroy_timeline(ctx->work_queue.timeline);
	destroy_workqueue(ctx->work_queue.rot_work_queue);
	kthread_flush_worker(&ctx->work_queue.rot_kw);
	kthread_stop(ctx->work_queue.rot_thread);
error_alloc_workqueue:
	sysfs_remove_group(&ctx->kobj, &sde_rotator_fs_attr_group);
error_create_sysfs:
@@ -1072,7 +1075,7 @@ static int sde_rotator_ctx_release(struct sde_rotator_ctx *ctx,

		SDEDEV_DBG(rot_dev->dev, "release submit work s:%d\n",
				session_id);
		cancel_work_sync(&request->submit_work);
		kthread_cancel_work_sync(&request->submit_work);
	}
	SDEDEV_DBG(rot_dev->dev, "release session s:%d\n", session_id);
	sde_rot_mgr_lock(rot_dev->mgr);
@@ -1085,12 +1088,13 @@ static int sde_rotator_ctx_release(struct sde_rotator_ctx *ctx,

		SDEDEV_DBG(rot_dev->dev, "release retire work s:%d\n",
				session_id);
		cancel_work_sync(&request->retire_work);
		kthread_cancel_work_sync(&request->retire_work);
	}
	mutex_lock(&rot_dev->lock);
	SDEDEV_DBG(rot_dev->dev, "release context s:%d\n", session_id);
	sde_rotator_destroy_timeline(ctx->work_queue.timeline);
	destroy_workqueue(ctx->work_queue.rot_work_queue);
	kthread_flush_worker(&ctx->work_queue.rot_kw);
	kthread_stop(ctx->work_queue.rot_thread);
	sysfs_remove_group(&ctx->kobj, &sde_rotator_fs_attr_group);
	kobject_put(&ctx->kobj);
	if (ctx->file) {
@@ -1609,7 +1613,7 @@ int sde_rotator_inline_commit(void *handle, struct sde_rotator_inline_cmd *cmd,
		} else {
			SDEROT_ERR("invalid stats timestamp\n");
		}
		req->retireq = ctx->work_queue.rot_work_queue;
		req->retire_kw = &ctx->work_queue.rot_kw;
		req->retire_work = &request->retire_work;

		trace_rot_entry_fence(
@@ -2719,7 +2723,7 @@ static const struct v4l2_ioctl_ops sde_rotator_ioctl_ops = {
 *
 * This function is scheduled in work queue context.
 */
static void sde_rotator_retire_handler(struct work_struct *work)
static void sde_rotator_retire_handler(struct kthread_work *work)
{
	struct vb2_v4l2_buffer *src_buf;
	struct vb2_v4l2_buffer *dst_buf;
@@ -2909,7 +2913,7 @@ static int sde_rotator_process_buffers(struct sde_rotator_ctx *ctx,
		goto error_init_request;
	}

	req->retireq = ctx->work_queue.rot_work_queue;
	req->retire_kw = &ctx->work_queue.rot_kw;
	req->retire_work = &request->retire_work;

	ret = sde_rotator_handle_request_common(
@@ -2938,7 +2942,7 @@ static int sde_rotator_process_buffers(struct sde_rotator_ctx *ctx,
 *
 * This function is scheduled in work queue context.
 */
static void sde_rotator_submit_handler(struct work_struct *work)
static void sde_rotator_submit_handler(struct kthread_work *work)
{
	struct sde_rotator_ctx *ctx;
	struct sde_rotator_device *rot_dev;
@@ -3203,7 +3207,7 @@ static int sde_rotator_job_ready(void *priv)
			list_del_init(&request->list);
			list_add_tail(&request->list, &ctx->pending_list);
			spin_unlock(&ctx->list_lock);
			queue_work(ctx->work_queue.rot_work_queue,
			kthread_queue_work(&ctx->work_queue.rot_kw,
					&request->submit_work);
		}
	} else if (request && !atomic_read(&request->req->pending_count)) {
+3 −2
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <linux/msm-bus.h>
#include <linux/platform_device.h>
#include <linux/soc/qcom/llcc-qcom.h>
#include <linux/kthread.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fh.h>
#include <media/v4l2-ctrls.h>
@@ -95,8 +96,8 @@ struct sde_rotator_vbinfo {
 */
struct sde_rotator_request {
	struct list_head list;
	struct work_struct submit_work;
	struct work_struct retire_work;
	struct kthread_work submit_work;
	struct kthread_work retire_work;
	struct sde_rot_entry_container *req;
	struct sde_rotator_ctx *ctx;
	bool committed;