From 96befb971f9b7f73a0d3e90efe5b65d45319dae8 Mon Sep 17 00:00:00 2001 From: Domi Papoi Date: Mon, 11 Jan 2016 12:20:09 -0500 Subject: [PATCH] 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 --- drivers/video/msm/ba/msm_ba.c | 2 ++ drivers/video/msm/ba/msm_ba_common.c | 8 ++++---- 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)