diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 4c724d5..745c3ba 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -1004,7 +1004,6 @@ static int cifs_oplock_thread(void *dummyarg)
 			netfid = oplock_item->netfid;
 			list_del(&oplock_item->qhead);
 			kmem_cache_free(cifs_oplock_cachep, oplock_item);
-			mutex_unlock(&cifs_oplock_mutex);
 
 			if (inode && S_ISREG(inode->i_mode)) {
 				cifsi = CIFS_I(inode);
@@ -1029,12 +1028,14 @@ static int cifs_oplock_thread(void *dummyarg)
 			}
 			iput(inode);
 
-				/* releasing stale oplock after recent reconnect
-				of smb session using a now incorrect file
-				handle is not a data integrity issue but do
-				not bother sending an oplock release if session
-				to server still is disconnected since oplock
-				already released by the server in that case */
+			/*
+			 * releasing stale oplock after recent reconnect
+			 * of smb session using a now incorrect file
+			 * handle is not a data integrity issue but do
+			 * not bother sending an oplock release if session
+			 * to server still is disconnected since oplock
+			 * already released by the server in that case
+			 */
 			if (!tcon->need_reconnect) {
 				rc = CIFSSMBLock(0, tcon, netfid,
 						0 /* len */ , 0 /* offset */, 0,
@@ -1042,6 +1043,12 @@ static int cifs_oplock_thread(void *dummyarg)
 						false /* wait flag */);
 				cFYI(1, ("Oplock release rc = %d", rc));
 			}
+
+			/*
+			 * release and reacquire the oplock mutex in order to
+			 * allow tasks waiting on it to have a chance.
+			 */
+			mutex_unlock(&cifs_oplock_mutex);
 			mutex_lock(&cifs_oplock_mutex);
 		}
 		mutex_unlock(&cifs_oplock_mutex);
