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

Commit 7f7b4791 authored by Ritesh Harjani's avatar Ritesh Harjani Committed by Gerrit - the friendly Code Review server
Browse files

mmc: cmdq: Add timeout in case of mmc_cmdq_halt_on_empty_queue()



We do see in fault injection framework below CMDQ getting stuck at
mmc_cmdq_halt_on_empty_queue() since error handler is not waking up
the thread which is waiting on empty queue condition.
Add a 10 sec timeout from the issue context to fix this.

Change-Id: Ia9edf908b849f1acbf233cbca13bdb139932b7cd
Signed-off-by: default avatarRitesh Harjani <riteshh@codeaurora.org>
Signed-off-by: default avatarSahitya Tummala <stummala@codeaurora.org>
parent 4ceaef34
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -1214,7 +1214,7 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
	mmc_get_card(card);

	if (mmc_card_cmdq(card)) {
		err = mmc_cmdq_halt_on_empty_queue(card->host);
		err = mmc_cmdq_halt_on_empty_queue(card->host, 0);
		if (err) {
			pr_err("%s: halt failed while doing %s err (%d)\n",
					mmc_hostname(card->host),
@@ -3236,9 +3236,10 @@ static int mmc_blk_cmdq_issue_rw_rq(struct mmc_queue *mq, struct request *req)
	struct mmc_cmdq_req *mc_rq;
	u8 active_small_sector_read = 0;
	int ret = 0;
	unsigned long timeout_ms = 10000; /* 10 sec safe timeout */

	mmc_cmdq_up_rwsem(host);
	mmc_deferred_scaling(host);
	mmc_deferred_scaling(host, timeout_ms);
	ret = mmc_cmdq_down_rwsem(host, req);
	if (ret)
		return ret;
+21 −9
Original line number Diff line number Diff line
@@ -373,12 +373,23 @@ static bool mmc_is_valid_state_for_clk_scaling(struct mmc_host *host)
	return R1_CURRENT_STATE(status) == R1_STATE_TRAN;
}

int mmc_cmdq_halt_on_empty_queue(struct mmc_host *host)
int mmc_cmdq_halt_on_empty_queue(struct mmc_host *host, unsigned long timeout)
{
	int err = 0;

	if (!timeout) {
		err = wait_event_interruptible(host->cmdq_ctx.queue_empty_wq,
					(!host->cmdq_ctx.active_reqs));
	} else {
		err = wait_event_interruptible_timeout(
				host->cmdq_ctx.queue_empty_wq,
				(!host->cmdq_ctx.active_reqs),
				msecs_to_jiffies(timeout));
		if (!err)
			pr_err("%s: halt_on_empty_queue timeout case: err(%d)\n",
					__func__, err);
	}

	if (host->cmdq_ctx.active_reqs) {
		pr_err("%s: %s: unexpected active requests (%lu)\n",
			mmc_hostname(host), __func__,
@@ -399,7 +410,8 @@ int mmc_cmdq_halt_on_empty_queue(struct mmc_host *host)
EXPORT_SYMBOL(mmc_cmdq_halt_on_empty_queue);

int mmc_clk_update_freq(struct mmc_host *host,
		unsigned long freq, enum mmc_load state)
		unsigned long freq, enum mmc_load state,
		unsigned long timeout)
{
	int err = 0;
	bool cmdq_mode;
@@ -441,7 +453,7 @@ int mmc_clk_update_freq(struct mmc_host *host,
	}

	if (cmdq_mode) {
		err = mmc_cmdq_halt_on_empty_queue(host);
		err = mmc_cmdq_halt_on_empty_queue(host, timeout);
		if (err) {
			pr_err("%s: %s: failed halting queue (%d)\n",
				mmc_hostname(host), __func__, err);
@@ -574,7 +586,7 @@ static int mmc_devfreq_set_target(struct device *dev,
	clk_scaling->need_freq_change = false;

	mmc_host_clk_hold(host);
	err = mmc_clk_update_freq(host, *freq, clk_scaling->state);
	err = mmc_clk_update_freq(host, *freq, clk_scaling->state, 0);
	if (err && err != -EAGAIN) {
		pr_err("%s: clock scale to %lu failed with error %d\n",
			mmc_hostname(host), *freq, err);
@@ -600,7 +612,7 @@ static int mmc_devfreq_set_target(struct device *dev,
 * This function does clock scaling in case "need_freq_change" flag was set
 * by the clock scaling logic.
 */
void mmc_deferred_scaling(struct mmc_host *host)
void mmc_deferred_scaling(struct mmc_host *host, unsigned long timeout)
{
	unsigned long target_freq;
	int err;
@@ -630,7 +642,7 @@ void mmc_deferred_scaling(struct mmc_host *host)
				target_freq, current->comm);

	err = mmc_clk_update_freq(host, target_freq,
		host->clk_scaling.state);
		host->clk_scaling.state, timeout);
	if (err && err != -EAGAIN) {
		pr_err("%s: failed on deferred scale clocks (%d)\n",
			mmc_hostname(host), err);
@@ -1236,7 +1248,7 @@ static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
	led_trigger_event(host->led, LED_FULL);

	if (mmc_is_data_request(mrq)) {
		mmc_deferred_scaling(host);
		mmc_deferred_scaling(host, 0);
		mmc_clk_scaling_start_busy(host, true);
	}

+2 −1
Original line number Diff line number Diff line
@@ -26,7 +26,8 @@ void mmc_init_erase(struct mmc_card *card);
void mmc_set_chip_select(struct mmc_host *host, int mode);
void mmc_set_clock(struct mmc_host *host, unsigned int hz);
int mmc_clk_update_freq(struct mmc_host *host,
		unsigned long freq, enum mmc_load state);
		unsigned long freq, enum mmc_load state,
		unsigned long timeout);
void mmc_gate_clock(struct mmc_host *host);
void mmc_ungate_clock(struct mmc_host *host);
void mmc_set_ungated(struct mmc_host *host);
+3 −3
Original line number Diff line number Diff line
@@ -275,7 +275,7 @@ static int mmc_scale_set(void *data, u64 val)
	mmc_host_clk_hold(host);

	/* change frequency from sysfs manually */
	err = mmc_clk_update_freq(host, val, host->clk_scaling.state);
	err = mmc_clk_update_freq(host, val, host->clk_scaling.state, 0);
	if (err == -EAGAIN)
		err = 0;
	else if (err)
@@ -547,7 +547,7 @@ static int mmc_dbg_card_status_get(void *data, u64 *val)

	mmc_get_card(card);
	if (mmc_card_cmdq(card)) {
		ret = mmc_cmdq_halt_on_empty_queue(card->host);
		ret = mmc_cmdq_halt_on_empty_queue(card->host, 0);
		if (ret) {
			pr_err("%s: halt failed while doing %s err (%d)\n",
					mmc_hostname(card->host), __func__,
@@ -589,7 +589,7 @@ static int mmc_ext_csd_open(struct inode *inode, struct file *filp)

	mmc_get_card(card);
	if (mmc_card_cmdq(card)) {
		err = mmc_cmdq_halt_on_empty_queue(card->host);
		err = mmc_cmdq_halt_on_empty_queue(card->host, 0);
		if (err) {
			pr_err("%s: halt failed while doing %s err (%d)\n",
					mmc_hostname(card->host), __func__,
+1 −1
Original line number Diff line number Diff line
@@ -767,7 +767,7 @@ static ssize_t store_enable(struct device *dev,
		host->clk_scaling.state = MMC_LOAD_HIGH;
		/* Set to max. frequency when disabling */
		mmc_clk_update_freq(host, host->card->clk_scaling_highest,
					host->clk_scaling.state);
					host->clk_scaling.state, 0);
	} else if (value) {
		/* Unmask host capability and resume scaling */
		host->caps2 |= MMC_CAP2_CLK_SCALE;
Loading