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>
This commit is contained in:
parent
841681b801
commit
96befb971f
2 changed files with 6 additions and 4 deletions
|
@ -736,7 +736,9 @@ void msm_ba_subdev_event_hndlr(struct v4l2_subdev *sd,
|
||||||
|
|
||||||
ba_sd_event->sd_event = *(struct v4l2_event *)arg;
|
ba_sd_event->sd_event = *(struct v4l2_event *)arg;
|
||||||
((int *)ba_sd_event->sd_event.u.data)[0] = ba_input->ba_ip_idx;
|
((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);
|
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);
|
schedule_delayed_work(&dev_ctxt->sd_events_work, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
* 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
|
* 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();
|
dev_ctxt = get_ba_dev();
|
||||||
ptr = (unsigned int *)sd_event->u.data;
|
ptr = (unsigned int *)sd_event->u.data;
|
||||||
|
|
||||||
mutex_lock(&dev_ctxt->dev_cs);
|
|
||||||
list_for_each_entry(inst, &(dev_ctxt->instances), list) {
|
list_for_each_entry(inst, &(dev_ctxt->instances), list) {
|
||||||
if (inst->ext_ops && inst->ext_ops->msm_ba_cb) {
|
if (inst->ext_ops && inst->ext_ops->msm_ba_cb) {
|
||||||
arg = ptr[1];
|
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);
|
msm_ba_queue_v4l2_event(inst, &event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutex_unlock(&dev_ctxt->dev_cs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void msm_ba_subdev_event_hndlr_delayed(struct work_struct *work)
|
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();
|
dev_ctxt = get_ba_dev();
|
||||||
|
|
||||||
|
mutex_lock(&dev_ctxt->dev_cs);
|
||||||
if (!list_empty(&dev_ctxt->sd_events)) {
|
if (!list_empty(&dev_ctxt->sd_events)) {
|
||||||
list_for_each_entry_safe(ba_sd_event, ba_sd_event_tmp,
|
list_for_each_entry_safe(ba_sd_event, ba_sd_event_tmp,
|
||||||
&(dev_ctxt->sd_events), list) {
|
&(dev_ctxt->sd_events), list) {
|
||||||
list_del(&ba_sd_event->list);
|
|
||||||
msm_ba_signal_sessions_event(&ba_sd_event->sd_event);
|
msm_ba_signal_sessions_event(&ba_sd_event->sd_event);
|
||||||
|
list_del(&ba_sd_event->list);
|
||||||
kfree(ba_sd_event);
|
kfree(ba_sd_event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dprintk(BA_ERR, "%s - queue empty!!!", __func__);
|
dprintk(BA_ERR, "%s - queue empty!!!", __func__);
|
||||||
}
|
}
|
||||||
|
mutex_unlock(&dev_ctxt->dev_cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct v4l2_subdev *msm_ba_sd_find(const char *name)
|
struct v4l2_subdev *msm_ba_sd_find(const char *name)
|
||||||
|
|
Loading…
Add table
Reference in a new issue