From 23e2949eae531c56c5111f6f6ce89ebdc97a2472 Mon Sep 17 00:00:00 2001 From: Ilan Aelion Date: Sun, 5 Aug 2012 06:56:40 -0600 Subject: misc: tegra-throughput: prevent race on init prevent a race condition on initialization which could result in multiple notifier registrations. Bug 1027664 Change-Id: I2e7dcad159f631a7e244d43019169fdaf195bc34 (cherry picked from commit 06ad60cd85a221eec673654c73d55fba34455a3a) Reviewed-on: http://git-master/r/121143 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Tested-by: Ilan Aelion Reviewed-by: Michael I Gold --- drivers/misc/tegra-throughput.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'drivers/misc') diff --git a/drivers/misc/tegra-throughput.c b/drivers/misc/tegra-throughput.c index 77eb7c31ed36..c90a6a00a1a0 100644 --- a/drivers/misc/tegra-throughput.c +++ b/drivers/misc/tegra-throughput.c @@ -98,19 +98,24 @@ static int notifier_initialized; static int throughput_open(struct inode *inode, struct file *file) { + int need_init = 0; + + spin_lock(&lock); + if (!notifier_initialized) { - tegra_dc_register_flip_notifier(&throughput_flip_nb); notifier_initialized = 1; + need_init = 1; } - spin_lock(&lock); - throughput_active_app_count++; if (throughput_active_app_count > 1) multiple_app_disable = 1; spin_unlock(&lock); + if (need_init) + tegra_dc_register_flip_notifier(&throughput_flip_nb); + pr_debug("throughput_open node %p file %p\n", inode, file); return 0; @@ -118,17 +123,22 @@ static int throughput_open(struct inode *inode, struct file *file) static int throughput_release(struct inode *inode, struct file *file) { + int need_deinit = 0; + spin_lock(&lock); - throughput_active_app_count--; - spin_unlock(&lock); + throughput_active_app_count--; if (throughput_active_app_count == 0) { reset_target_frame_time(); multiple_app_disable = 0; - tegra_dc_unregister_flip_notifier(&throughput_flip_nb); notifier_initialized = 0; + need_deinit = 1; } + spin_unlock(&lock); + + if (need_deinit) + tegra_dc_unregister_flip_notifier(&throughput_flip_nb); pr_debug("throughput_release node %p file %p\n", inode, file); -- cgit v1.2.3