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

Commit aeb892b9 authored by Prabhanjan Kandula's avatar Prabhanjan Kandula
Browse files

msm: mdss: fix cwb output buffer memory leak



Currently, cwb buffers are allocated and mapped during
commit but not unmapped, leaving the kernel refcounts
intact which would eventually cause memory issues. Fix it
by adding the buffer to a cleanup queue after mapping and
unmap/free the buffer in the work queue after cwb intr done.

Change-Id: I2bb41a4fadc58ecedb1fafacf6821ce6376b1b4d
Signed-off-by: default avatarPrabhanjan Kandula <pkandula@codeaurora.org>
parent 3bf774ff
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -424,6 +424,7 @@ struct mdss_mdp_ctl_intfs_ops {
struct mdss_mdp_cwb {
	struct mutex queue_lock;
	struct list_head data_queue;
	struct list_head cleanup_queue;
	int valid;
	u32 wb_idx;
	struct mdp_output_layer layer;
+5 −0
Original line number Diff line number Diff line
@@ -3563,6 +3563,11 @@ int mdss_mdp_cwb_setup(struct mdss_mdp_ctl *ctl)
		goto cwb_setup_fail;
	}

	/* Add to cleanup list */
	mutex_lock(&cwb->queue_lock);
	list_add_tail(&cwb_data->next, &mdp5_data->cwb.cleanup_queue);
	mutex_unlock(&cwb->queue_lock);

	memset(&wb_args, 0, sizeof(wb_args));
	wb_args.data = &cwb_data->data;

+15 −0
Original line number Diff line number Diff line
@@ -5860,10 +5860,24 @@ __vsync_retire_get_fence(struct msm_sync_pt_data *sync_pt_data)
static void __cwb_wq_handler(struct work_struct *cwb_work)
{
	struct mdss_mdp_cwb *cwb = NULL;
	struct mdss_mdp_wb_data *cwb_data = NULL;

	cwb = container_of(cwb_work, struct mdss_mdp_cwb, cwb_work);
	blocking_notifier_call_chain(&cwb->notifier_head,
			MDP_NOTIFY_FRAME_DONE, NULL);

	/* free the buffer from cleanup queue */
	mutex_lock(&cwb->queue_lock);
	cwb_data = list_first_entry_or_null(&cwb->cleanup_queue,
			struct mdss_mdp_wb_data, next);
	 __list_del_entry(&cwb_data->next);
	mutex_unlock(&cwb->queue_lock);
	if (cwb_data == NULL) {
		pr_err("no output buffer for cwb cleanup\n");
		return;
	}
	mdss_mdp_data_free(&cwb_data->data, true, DMA_FROM_DEVICE);
	kfree(cwb_data);
}

static int __vsync_set_vsync_handler(struct msm_fb_data_type *mfd)
@@ -6094,6 +6108,7 @@ int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd)
	mutex_init(&mdp5_data->cwb.queue_lock);
	mutex_init(&mdp5_data->cwb.cwb_sync_pt_data.sync_mutex);
	INIT_LIST_HEAD(&mdp5_data->cwb.data_queue);
	INIT_LIST_HEAD(&mdp5_data->cwb.cleanup_queue);

	snprintf(timeline_name, sizeof(timeline_name), "cwb%d", mfd->index);
	mdp5_data->cwb.cwb_sync_pt_data.fence_name = "cwb-fence";