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

Commit 5fa13e17 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 b29f3404
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -4044,6 +4044,7 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
	int tag;
	struct completion wait;
	unsigned long flags;
	bool has_read_lock = false;

	/*
	 * May get invoked from shutdown and IOCTL contexts.
@@ -4051,8 +4052,10 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
	 * 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);
		has_read_lock = true;
	}

	/*
	 * Get free slot, sleep if slots are unavailable.
@@ -4090,7 +4093,7 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
out_put_tag:
	ufshcd_put_dev_cmd_tag(hba, tag);
	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);
	return err;
}