summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDomi Papoi <dpapoi@codeaurora.org>2016-01-11 12:20:09 -0500
committerGerrit - the friendly Code Review server <code-review@localhost>2017-06-08 22:10:35 -0700
commit96befb971f9b7f73a0d3e90efe5b65d45319dae8 (patch)
tree2823b362b921b9331f42cc2e7a69b07098a88200
parent841681b80156df808c93a8c21301128a65197d04 (diff)
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: Domi Papoi <dpapoi@codeaurora.org>
-rw-r--r--drivers/video/msm/ba/msm_ba.c2
-rw-r--r--drivers/video/msm/ba/msm_ba_common.c8
2 files changed, 6 insertions, 4 deletions
diff --git a/drivers/video/msm/ba/msm_ba.c b/drivers/video/msm/ba/msm_ba.c
index 30464baa7934..1a03767be228 100644
--- a/drivers/video/msm/ba/msm_ba.c
+++ b/drivers/video/msm/ba/msm_ba.c
@@ -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);
}
diff --git a/drivers/video/msm/ba/msm_ba_common.c b/drivers/video/msm/ba/msm_ba_common.c
index 5249f16a4abf..f4ea966063d7 100644
--- a/drivers/video/msm/ba/msm_ba_common.c
+++ b/drivers/video/msm/ba/msm_ba_common.c
@@ -1,4 +1,4 @@
-/* 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)