lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1a557cffd04632875f6d52d43a036ad9@codeaurora.org>
Date:   Tue, 03 Nov 2020 16:01:42 +0800
From:   Can Guo <cang@...eaurora.org>
To:     Stanley Chu <stanley.chu@...iatek.com>
Cc:     asutoshd@...eaurora.org, nguyenb@...eaurora.org,
        hongwus@...eaurora.org, rnayak@...eaurora.org,
        linux-scsi@...r.kernel.org, kernel-team@...roid.com,
        saravanak@...gle.com, salyzyn@...gle.com,
        Alim Akhtar <alim.akhtar@...sung.com>,
        Avri Altman <avri.altman@....com>,
        "James E.J. Bottomley" <jejb@...ux.ibm.com>,
        "Martin K. Petersen" <martin.petersen@...cle.com>,
        Bean Huo <beanhuo@...ron.com>,
        Bart Van Assche <bvanassche@....org>,
        Satya Tangirala <satyat@...gle.com>,
        open list <linux-kernel@...r.kernel.org>
Subject: Re: [PATCH v1 2/2] scsi: ufs: Try to save power mode change and UIC
 cmd completion timeout

Hi Stanley,

On 2020-11-03 15:20, Stanley Chu wrote:
> Hi Can,
> 
> Except for below nit, otherwise looks good to me.
> 
> Reviewed-by: Stanley Chu <stanley.chu@...iatek.com>
> 
> On Mon, 2020-11-02 at 22:24 -0800, Can Guo wrote:
>> Use the uic_cmd->cmd_active as a flag to track the lifecycle of an UIC 
>> cmd.
>> The flag is set before send the UIC cmd and cleared in IRQ handler. 
>> When a
>> PMC or UIC cmd completion timeout happens, if the flag is not set, 
>> instead
>> of returning timeout error, we still treat it as a successful 
>> operation.
>> This is to deal with the scenario in which completion has been raised 
>> but
>> the one waiting for the completion cannot be awaken in time due to 
>> kernel
>> scheduling problem.
>> 
>> Signed-off-by: Can Guo <cang@...eaurora.org>
>> ---
>>  drivers/scsi/ufs/ufshcd.c | 26 ++++++++++++++++++++++++--
>>  drivers/scsi/ufs/ufshcd.h |  2 ++
>>  2 files changed, 26 insertions(+), 2 deletions(-)
>> 
>> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
>> index efa7d86..7f33310 100644
>> --- a/drivers/scsi/ufs/ufshcd.c
>> +++ b/drivers/scsi/ufs/ufshcd.c
>> @@ -2122,10 +2122,20 @@ ufshcd_wait_for_uic_cmd(struct ufs_hba *hba, 
>> struct uic_command *uic_cmd)
>>  	unsigned long flags;
>> 
>>  	if (wait_for_completion_timeout(&uic_cmd->done,
>> -					msecs_to_jiffies(UIC_CMD_TIMEOUT)))
>> +					msecs_to_jiffies(UIC_CMD_TIMEOUT))) {
>>  		ret = uic_cmd->argument2 & MASK_UIC_COMMAND_RESULT;
>> -	else
>> +	} else {
>>  		ret = -ETIMEDOUT;
>> +		dev_err(hba->dev,
>> +			"uic cmd 0x%x with arg3 0x%x completion timeout\n",
>> +			uic_cmd->command, uic_cmd->argument3);
>> +
>> +		if (!uic_cmd->cmd_active) {
>> +			dev_err(hba->dev, "%s: UIC cmd has been completed, return the 
>> result\n",
>> +				__func__);
>> +			ret = uic_cmd->argument2 & MASK_UIC_COMMAND_RESULT;
>> +		}
>> +	}
>> 
>>  	spin_lock_irqsave(hba->host->host_lock, flags);
>>  	hba->active_uic_cmd = NULL;
>> @@ -2157,6 +2167,7 @@ __ufshcd_send_uic_cmd(struct ufs_hba *hba, 
>> struct uic_command *uic_cmd,
>>  	if (completion)
>>  		init_completion(&uic_cmd->done);
>> 
>> +	uic_cmd->cmd_active = 1;
>>  	ufshcd_dispatch_uic_cmd(hba, uic_cmd);
>> 
>>  	return 0;
>> @@ -3828,10 +3839,18 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba 
>> *hba, struct uic_command *cmd)
>>  		dev_err(hba->dev,
>>  			"pwr ctrl cmd 0x%x with mode 0x%x completion timeout\n",
>>  			cmd->command, cmd->argument3);
>> +
>> +		if (!cmd->cmd_active) {
>> +			dev_err(hba->dev, "%s: Power Mode Change operation has been 
>> completed, go check UPMCRS\n",
>> +				__func__);
>> +			goto check_upmcrs;
>> +		}
>> +
>>  		ret = -ETIMEDOUT;
>>  		goto out;
>>  	}
>> 
>> +check_upmcrs:
>>  	status = ufshcd_get_upmcrs(hba);
>>  	if (status != PWR_LOCAL) {
>>  		dev_err(hba->dev,
>> @@ -4923,11 +4942,14 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct 
>> ufs_hba *hba, u32 intr_status)
>>  			ufshcd_get_uic_cmd_result(hba);
>>  		hba->active_uic_cmd->argument3 =
>>  			ufshcd_get_dme_attr_val(hba);
>> +		if (!hba->uic_async_done)
> 
> Is this check necessary?
> 

Thanks for your quick response.

In the case of PMC, UIC cmd completion IRQ comes first, then power
status change IRQ comes next. In this case, an UIC cmd's lifecyle
ends only after the power status change IRQ comes [1].

I guess you may want to say that in current code since we have
masked UIC cmd completion IRQ in the case of a PMC operation, so
no need to check it here since we won't be here anyways before
power status change IRQ comes. So, removing the check here
definitely works, and then we won't even need below line as well.

	if ((intr_status & UFSHCD_UIC_PWR_MASK) && hba->uic_async_done) {
+		hba->active_uic_cmd->cmd_active = 0;
		complete(hba->uic_async_done);
		retval = IRQ_HANDLED;

If my guess is right, my opinion is that the current change may
be more readable and comprehensive as it strictly follows my
description in [1]. What do you think?

Thanks,

Can Guo.

>> +			hba->active_uic_cmd->cmd_active = 0;
>>  		complete(&hba->active_uic_cmd->done);
>>  		retval = IRQ_HANDLED;
>>  	}
>> 
>>  	if ((intr_status & UFSHCD_UIC_PWR_MASK) && hba->uic_async_done) {
>> +		hba->active_uic_cmd->cmd_active = 0;
>>  		complete(hba->uic_async_done);
>>  		retval = IRQ_HANDLED;
>>  	}
>> diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
>> index 66e5338..be982ed 100644
>> --- a/drivers/scsi/ufs/ufshcd.h
>> +++ b/drivers/scsi/ufs/ufshcd.h
>> @@ -64,6 +64,7 @@ enum dev_cmd_type {
>>   * @argument1: UIC command argument 1
>>   * @argument2: UIC command argument 2
>>   * @argument3: UIC command argument 3
>> + * @cmd_active: Indicate if UIC command is outstanding
>>   * @done: UIC command completion
>>   */
>>  struct uic_command {
>> @@ -71,6 +72,7 @@ struct uic_command {
>>  	u32 argument1;
>>  	u32 argument2;
>>  	u32 argument3;
>> +	int cmd_active;
>>  	struct completion done;
>>  };
>> 
> 
> 
> 
> Thanks,
> Stanley Chu

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ