Re: [PATCH] mmc: sdhci: fix possible scheduling while atomic

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I have no way to test this problem but I was thinking along the lines of

--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1862,6 +1862,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 
 
        sdhci_runtime_pm_get(host);
        disable_irq(host->irq);
+       sdhci_disable_card_detection(host);
        spin_lock(&host->lock);
 
        ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
@@ -1883,6 +1884,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 
                ctrl |= SDHCI_CTRL_EXEC_TUNING;
        else {
                spin_unlock(&host->lock);
+               sdhci_enable_card_detection(host);
                enable_irq(host->irq);
                sdhci_runtime_pm_put(host);
                return 0;
@@ -1890,6 +1892,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 
 
        if (host->ops->platform_execute_tuning) {
                spin_unlock(&host->lock);
+               sdhci_enable_card_detection(host);
                enable_irq(host->irq);
                err = host->ops->platform_execute_tuning(host, opcode);
                sdhci_runtime_pm_put(host);
@@ -2047,6 +2050,7 @@ out:
 
        sdhci_clear_set_irqs(host, SDHCI_INT_DATA_AVAIL, ier);
        spin_unlock(&host->lock);
+       sdhci_enable_card_detection(host);
        enable_irq(host->irq);
        sdhci_runtime_pm_put(host);
 

regards,

Philip

On Jan 20, 2014, at 9:51 AM, Philip Rakity <prakity@xxxxxxxxxx> wrote:

> 
> Chris,
> 
> The suggested fix can lock out interrupts for up to 150ms.  There needs to be another way.
> So, I would strongly recommend we find another solution.
> 
> Philip
> 
> On Jan 17, 2014, at 7:57 PM, Andrew Bresticker <abrestic@xxxxxxxxxxxx> wrote:
> 
>> sdhci_execute_tuning() takes host->lock without disabling interrupts.
>> Use spin_lock_irq{save,restore} instead so that we avoid taking an
>> interrupt and scheduling while holding host->lock.
>> 
>> Signed-off-by: Andrew Bresticker <abrestic@xxxxxxxxxxxx>
>> ---
>> drivers/mmc/host/sdhci.c | 13 +++++++------
>> 1 file changed, 7 insertions(+), 6 deletions(-)
>> 
>> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
>> index ec3eb30..84c80e7 100644
>> --- a/drivers/mmc/host/sdhci.c
>> +++ b/drivers/mmc/host/sdhci.c
>> @@ -1857,12 +1857,13 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
>> 	unsigned long timeout;
>> 	int err = 0;
>> 	bool requires_tuning_nonuhs = false;
>> +	unsigned long flags;
>> 
>> 	host = mmc_priv(mmc);
>> 
>> 	sdhci_runtime_pm_get(host);
>> 	disable_irq(host->irq);
>> -	spin_lock(&host->lock);
>> +	spin_lock_irqsave(&host->lock, flags);
> 
> 
> The disable_irq() call stops the controller from doing interrupts.  
> Please explain what problem you are seeing
> 
>> 
>> 	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
>> 
>> @@ -1882,14 +1883,14 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
>> 	    requires_tuning_nonuhs)
>> 		ctrl |= SDHCI_CTRL_EXEC_TUNING;
>> 	else {
>> -		spin_unlock(&host->lock);
>> +		spin_unlock_irqrestore(&host->lock, flags);
>> 		enable_irq(host->irq);
>> 		sdhci_runtime_pm_put(host);
>> 		return 0;
>> 	}
>> 
>> 	if (host->ops->platform_execute_tuning) {
>> -		spin_unlock(&host->lock);
>> +		spin_unlock_irqrestore(&host->lock, flags);
>> 		enable_irq(host->irq);
>> 		err = host->ops->platform_execute_tuning(host, opcode);
>> 		sdhci_runtime_pm_put(host);
>> @@ -1963,7 +1964,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
>> 		host->cmd = NULL;
>> 		host->mrq = NULL;
>> 
>> -		spin_unlock(&host->lock);
>> +		spin_unlock_irqrestore(&host->lock, flags);
>> 		enable_irq(host->irq);
>> 
>> 		/* Wait for Buffer Read Ready interrupt */
>> @@ -1971,7 +1972,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
>> 					(host->tuning_done == 1),
>> 					msecs_to_jiffies(50));
>> 		disable_irq(host->irq);
>> -		spin_lock(&host->lock);
>> +		spin_lock_irqsave(&host->lock, flags);
>> 
>> 		if (!host->tuning_done) {
>> 			pr_info(DRIVER_NAME ": Timeout waiting for "
>> @@ -2046,7 +2047,7 @@ out:
>> 		err = 0;
>> 
>> 	sdhci_clear_set_irqs(host, SDHCI_INT_DATA_AVAIL, ier);
>> -	spin_unlock(&host->lock);
>> +	spin_unlock_irqrestore(&host->lock, flags);
>> 	enable_irq(host->irq);
>> 	sdhci_runtime_pm_put(host);
>> 
>> -- 
>> 1.8.5.2
>> 
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>> the body of a message to majordomo@xxxxxxxxxxxxxxx
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux