base: genlock: protect kref counting with spinlock

A race condition exists where the attach may not kref_get
before the kref_put finished. The genlock_file_lock was
originally added to protect against this case however it
was not protecting the kref.

CRs-fixed: 359649
Change-Id: Iab1fc847c2d3357ec1be79b7cc3e004643126dec
Signed-off-by: Jeff Boody <jboody@codeaurora.org>
diff --git a/drivers/base/genlock.c b/drivers/base/genlock.c
index 5e1d7af..0686d20 100644
--- a/drivers/base/genlock.c
+++ b/drivers/base/genlock.c
@@ -56,7 +56,7 @@
  * released while another process tries to attach it
  */
 
-static DEFINE_SPINLOCK(genlock_file_lock);
+static DEFINE_SPINLOCK(genlock_ref_lock);
 
 static void genlock_destroy(struct kref *kref)
 {
@@ -68,10 +68,8 @@
 	 * still active after the lock gets released
 	 */
 
-	spin_lock(&genlock_file_lock);
 	if (lock->file)
 		lock->file->private_data = NULL;
-	spin_unlock(&genlock_file_lock);
 
 	kfree(lock);
 }
@@ -203,19 +201,20 @@
 	 * released and then attached
 	 */
 
-	spin_lock(&genlock_file_lock);
+	spin_lock(&genlock_ref_lock);
 	lock = file->private_data;
-	spin_unlock(&genlock_file_lock);
 
 	fput(file);
 
 	if (lock == NULL) {
+		spin_unlock(&genlock_ref_lock);
 		GENLOCK_LOG_ERR("File descriptor is invalid\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	handle->lock = lock;
 	kref_get(&lock->refcount);
+	spin_unlock(&genlock_ref_lock);
 
 	return lock;
 }
@@ -595,7 +594,9 @@
 	}
 	spin_unlock_irqrestore(&handle->lock->lock, flags);
 
+	spin_lock(&genlock_ref_lock);
 	kref_put(&handle->lock->refcount, genlock_destroy);
+	spin_unlock(&genlock_ref_lock);
 	handle->lock = NULL;
 	handle->active = 0;
 }