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

Commit 613b0e48 authored by Domi Papoi's avatar Domi Papoi Committed by Gerrit - the friendly Code Review server
Browse files

msm: BA: Fix a race condition in BA event handling



Add proper locking in event handling so that invocation
of multiple events will not corrupt the event list.

Change-Id: I4499b3c0a106cbada54bbc122bb03ad5c30ed2c3
Signed-off-by: default avatarDomi Papoi <dpapoi@codeaurora.org>
parent ee86fb3c
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -736,7 +736,9 @@ void msm_ba_subdev_event_hndlr(struct v4l2_subdev *sd,

	ba_sd_event->sd_event = *(struct v4l2_event *)arg;
	((int *)ba_sd_event->sd_event.u.data)[0] = ba_input->ba_ip_idx;
	mutex_lock(&dev_ctxt->dev_cs);
	list_add_tail(&ba_sd_event->list, &dev_ctxt->sd_events);
	mutex_unlock(&dev_ctxt->dev_cs);

	schedule_delayed_work(&dev_ctxt->sd_events_work, 0);
}
+4 −4
Original line number Diff line number Diff line
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -139,7 +139,6 @@ static void msm_ba_signal_sessions_event(struct v4l2_event *sd_event)
	dev_ctxt = get_ba_dev();
	ptr = (unsigned int *)sd_event->u.data;

	mutex_lock(&dev_ctxt->dev_cs);
	list_for_each_entry(inst, &(dev_ctxt->instances), list) {
		if (inst->ext_ops && inst->ext_ops->msm_ba_cb) {
			arg = ptr[1];
@@ -149,7 +148,6 @@ static void msm_ba_signal_sessions_event(struct v4l2_event *sd_event)
			msm_ba_queue_v4l2_event(inst, &event);
		}
	}
	mutex_unlock(&dev_ctxt->dev_cs);
}

void msm_ba_subdev_event_hndlr_delayed(struct work_struct *work)
@@ -160,17 +158,19 @@ void msm_ba_subdev_event_hndlr_delayed(struct work_struct *work)

	dev_ctxt = get_ba_dev();

	mutex_lock(&dev_ctxt->dev_cs);
	if (!list_empty(&dev_ctxt->sd_events)) {
		list_for_each_entry_safe(ba_sd_event, ba_sd_event_tmp,
				&(dev_ctxt->sd_events), list) {
			list_del(&ba_sd_event->list);
			msm_ba_signal_sessions_event(&ba_sd_event->sd_event);
			list_del(&ba_sd_event->list);
			kfree(ba_sd_event);
			break;
		}
	} else {
		dprintk(BA_ERR, "%s - queue empty!!!", __func__);
	}
	mutex_unlock(&dev_ctxt->dev_cs);
}

struct v4l2_subdev *msm_ba_sd_find(const char *name)