Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7f73deb5 authored by Sayali Lokhande's avatar Sayali Lokhande Committed by Gerrit - the friendly Code Review server
Browse files

scsi: ufs: Release rw_sem while sending device management requests



Consider the below scenario:
1. Clock scaling is running
   - releases rw_sem before sending hibern8
    - issues hibern8 enter
      - error in hibern8 [1]
      - triggers error-handler(eh) [3]
   - waits on acquiring rw_sem [5]
2. Exception is raised by device
   - acquires rw_sem (if eh not running)as part of
     sending device management reqs [2]
   - returns whithout releasing rw_sem
   (as eh starts running in between) [4]

Here, [5] waits on [2] which acquires rw_sem but does not release,
as eh[3] starts running in between [2] and [4]. Fix this by releasing
rw_sem in ufshcd_exec_dev_cmd() if it was indeed acquired.

Change-Id: Ic6bb9f25e25bff6b8798bb39ea150e920e5bc1a2
Signed-off-by: default avatarSayali Lokhande <sayalil@codeaurora.org>
parent ba1a7cac
Loading
Loading
Loading
Loading
+5 −2
Original line number Original line Diff line number Diff line
@@ -3445,6 +3445,7 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
	int tag;
	int tag;
	struct completion wait;
	struct completion wait;
	unsigned long flags;
	unsigned long flags;
	bool has_read_lock = false;


	/*
	/*
	 * May get invoked from shutdown and IOCTL contexts.
	 * May get invoked from shutdown and IOCTL contexts.
@@ -3452,8 +3453,10 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
	 * In error recovery context, it may come with lock acquired.
	 * In error recovery context, it may come with lock acquired.
	 */
	 */


	if (!ufshcd_is_shutdown_ongoing(hba) && !ufshcd_eh_in_progress(hba))
	if (!ufshcd_is_shutdown_ongoing(hba) && !ufshcd_eh_in_progress(hba)) {
		down_read(&hba->lock);
		down_read(&hba->lock);
		has_read_lock = true;
	}


	/*
	/*
	 * Get free slot, sleep if slots are unavailable.
	 * Get free slot, sleep if slots are unavailable.
@@ -3486,7 +3489,7 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
out_put_tag:
out_put_tag:
	ufshcd_put_dev_cmd_tag(hba, tag);
	ufshcd_put_dev_cmd_tag(hba, tag);
	wake_up(&hba->dev_cmd.tag_wq);
	wake_up(&hba->dev_cmd.tag_wq);
	if (!ufshcd_is_shutdown_ongoing(hba) && !ufshcd_eh_in_progress(hba))
	if (has_read_lock)
		up_read(&hba->lock);
		up_read(&hba->lock);
	return err;
	return err;
}
}