From: Ilan Aelion Date: Sun, 5 Aug 2012 12:56:40 +0000 (-0600) Subject: misc: tegra-throughput: prevent race on init X-Git-Tag: daily-2013.07.26.0_rel-roth-mp-3-partner~2595^2~9 X-Git-Url: http://nv-tegra.nvidia.com/gitweb/?p=linux-2.6.git;a=commitdiff_plain;h=e043dadf34ef4e7ea3eb04ad845860c0e55e52cb 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 --- diff --git a/drivers/misc/tegra-throughput.c b/drivers/misc/tegra-throughput.c index 2ab0e51..47dc682 100644 --- a/drivers/misc/tegra-throughput.c +++ b/drivers/misc/tegra-throughput.c @@ -99,19 +99,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; @@ -119,17 +124,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);