All of lore.kernel.org
 help / color / mirror / Atom feed
From: majianpeng <majianpeng@gmail.com>
To: Hein Tibosch <hein_tibosch@yahoo.es>
Cc: balajitk <balajitk@ti.com>, cjb <cjb@laptop.org>,
	mayuzheng <mayuzheng@kedacom.com>,
	linux-mmc <linux-mmc@vger.kernel.org>,
	linux-omap <linux-omap@vger.kernel.org>,
	linux-kernel <linux-kernel@vger.kernel.org>,
	Felipe Balbi <balbi@ti.com>
Subject: Re: Re: [PATCH] mmc: omap_hsmmc: Fix sleep too long in ISR context.
Date: Thu, 1 Aug 2013 16:40:05 +0800	[thread overview]
Message-ID: <201308011640027321434@gmail.com> (raw)
In-Reply-To: 51FA1AB7.8030105@yahoo.es

>Hi Jianpeng Ma,
>
>On 8/1/2013 10:18 AM, majianpeng wrote:
>> We found a problem when we removed a working sd card that the irqaction
>> of omap_hsmmc can sleep to 3.6s. This cause our watchdog to work.
>> In func omap_hsmmc_reset_controller_fsm, it should watch a 0->1
>> transition.It used loops_per_jiffy as the timer.
>> The code is:
>>> while ((!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit))
>>>                && (i++ < limit))
>>>                        cpu_relax();
>> But the loops_per_jiffy is:
>>>  while(i++ < limit)
>>> 	cpu_relax();
>> It add some codes so the time became long.
>> Becasue those codes in ISR context, it can't use timer_before/after.
>> I divived the time into 1ms and used udelay(1) to instead.
>> It will cause do additional udelay(1).But from my test,it looks good.
>>
>> Reported-by: Yuzheng Ma <mayuzheng@kedacom.com>
>> Tested-by: Yuzheng Ma <mayuzheng@kedacom.com>
>> Signed-off-by: Jianpeng Ma <majianpeng@gmail.com>
>> ---
>>  drivers/mmc/host/omap_hsmmc.c | 20 +++++++++++++-------
>>  1 file changed, 13 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
>> index 1865321..96daca1 100644
>> --- a/drivers/mmc/host/omap_hsmmc.c
>> +++ b/drivers/mmc/host/omap_hsmmc.c
>> @@ -977,6 +977,8 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host,
>>  	unsigned long limit = (loops_per_jiffy *
>>  				msecs_to_jiffies(MMC_TIMEOUT_MS));
>>  
>> +	/*Divided time into us for unit 1,we can use udelay(1)*/
>> +	i = limit / (MMC_TIMEOUT_MS * 1000);
>
>'limit' is a number of loops, which you now divide by 20,000?
>
>To get uS, you could just change:
>
>-	unsigned long limit = (loops_per_jiffy *
>-				msecs_to_jiffies(MMC_TIMEOUT_MS));
>+	unsigned long limit = 1000 * MMC_TIMEOUT_MS;
>
Yes, you are right.
>and make this amount of loops using udelay().
>
>>  	OMAP_HSMMC_WRITE(host->base, SYSCTL,
>>  			 OMAP_HSMMC_READ(host->base, SYSCTL) | bit);
>>  
>> @@ -985,15 +987,19 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host,
>>  	 * Monitor a 0->1 transition first
>>  	 */
>>  	if (mmc_slot(host).features & HSMMC_HAS_UPDATED_RESET) {
>> -		while ((!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit))
>> -					&& (i++ < limit))
>> -			cpu_relax();
>
>I still don't see why any of these loops could last 3.6 seconds?
>Yes the __raw_readl() will add some time, but so much?
>I'd like to see which value you get for 'limit' on your machine
>Would PM play a role? Or cpu-freq, and 'loops_per_jiffy' isn't updated
>on time?
From my test, i found it don't monitor a 0->1 transtion.That is the last result is 'i = limit'.
The later while opertion stop also because 'i = limit'.
The basic reason is the hardware. 
It write bit and monitor 1-->0---1>---0.But we start monitor we only got 0 and the value don't change.
Maybe the transition is 1-->0.So the monitor can't work but still waste cpu.

>
>> +		while (i--) {
>> +			if ((OMAP_HSMMC_READ(host->base, SYSCTL) & bit))
>> +				break;
>> +			udelay(1);
>
>In earlier threads, the use of udelay was disliked because it's a waste
>of cpu cycles. The desired bit in SYSCTL will change, while udelay()
>is still making many useless loops.
Yes, but it at most wast 1us.

Jianpeng Ma
>
>> +		}
>>  	}
>> -	i = 0;
>>  
>> -	while ((OMAP_HSMMC_READ(host->base, SYSCTL) & bit) &&
>> -		(i++ < limit))
>> -		cpu_relax();
>> +	i = limit / (MMC_TIMEOUT_MS * 1000);
>> +	while (i--) {
>> +		if (!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit))
>> +			break;
>> +		udealy(1);
>> +	}
>>  
>>  	if (OMAP_HSMMC_READ(host->base, SYSCTL) & bit)
>>  		dev_err(mmc_dev(host->mmc),
>Hein
Thanks!
Jianpeng Ma
>Hi Jianpeng Ma,
>
>On 8/1/2013 10:18 AM, majianpeng wrote:
>> We found a problem when we removed a working sd card that the irqaction
>> of omap_hsmmc can sleep to 3.6s. This cause our watchdog to work.
>> In func omap_hsmmc_reset_controller_fsm, it should watch a 0->1
>> transition.It used loops_per_jiffy as the timer.
>> The code is:
>>> while ((!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit))
>>>                && (i++ < limit))
>>>                        cpu_relax();
>> But the loops_per_jiffy is:
>>>  while(i++ < limit)
>>> 	cpu_relax();
>> It add some codes so the time became long.
>> Becasue those codes in ISR context, it can't use timer_before/after.
>> I divived the time into 1ms and used udelay(1) to instead.
>> It will cause do additional udelay(1).But from my test,it looks good.
>>
>> Reported-by: Yuzheng Ma <mayuzheng@kedacom.com>
>> Tested-by: Yuzheng Ma <mayuzheng@kedacom.com>
>> Signed-off-by: Jianpeng Ma <majianpeng@gmail.com>
>> ---
>>  drivers/mmc/host/omap_hsmmc.c | 20 +++++++++++++-------
>>  1 file changed, 13 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
>> index 1865321..96daca1 100644
>> --- a/drivers/mmc/host/omap_hsmmc.c
>> +++ b/drivers/mmc/host/omap_hsmmc.c
>> @@ -977,6 +977,8 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host,
>>  	unsigned long limit = (loops_per_jiffy *
>>  				msecs_to_jiffies(MMC_TIMEOUT_MS));
>>  
>> +	/*Divided time into us for unit 1,we can use udelay(1)*/
>> +	i = limit / (MMC_TIMEOUT_MS * 1000);
>
>'limit' is a number of loops, which you now divide by 20,000?
>
>To get uS, you could just change:
>
>-	unsigned long limit = (loops_per_jiffy *
>-				msecs_to_jiffies(MMC_TIMEOUT_MS));
>+	unsigned long limit = 1000 * MMC_TIMEOUT_MS;
>
>and make this amount of loops using udelay().
>
>>  	OMAP_HSMMC_WRITE(host->base, SYSCTL,
>>  			 OMAP_HSMMC_READ(host->base, SYSCTL) | bit);
>>  
>> @@ -985,15 +987,19 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host,
>>  	 * Monitor a 0->1 transition first
>>  	 */
>>  	if (mmc_slot(host).features & HSMMC_HAS_UPDATED_RESET) {
>> -		while ((!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit))
>> -					&& (i++ < limit))
>> -			cpu_relax();
>
>I still don't see why any of these loops could last 3.6 seconds?
>Yes the __raw_readl() will add some time, but so much?
>I'd like to see which value you get for 'limit' on your machine
>Would PM play a role? Or cpu-freq, and 'loops_per_jiffy' isn't updated
>on time?
>
>> +		while (i--) {
>> +			if ((OMAP_HSMMC_READ(host->base, SYSCTL) & bit))
>> +				break;
>> +			udelay(1);
>
>In earlier threads, the use of udelay was disliked because it's a waste
>of cpu cycles. The desired bit in SYSCTL will change, while udelay()
>is still making many useless loops.
>
>> +		}
>>  	}
>> -	i = 0;
>>  
>> -	while ((OMAP_HSMMC_READ(host->base, SYSCTL) & bit) &&
>> -		(i++ < limit))
>> -		cpu_relax();
>> +	i = limit / (MMC_TIMEOUT_MS * 1000);
>> +	while (i--) {
>> +		if (!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit))
>> +			break;
>> +		udealy(1);
>> +	}
>>  
>>  	if (OMAP_HSMMC_READ(host->base, SYSCTL) & bit)
>>  		dev_err(mmc_dev(host->mmc),
>Hein

WARNING: multiple messages have this Message-ID (diff)
From: majianpeng <majianpeng@gmail.com>
To: "Hein Tibosch" <hein_tibosch@yahoo.es>
Cc: balajitk <balajitk@ti.com>, cjb <cjb@laptop.org>,
	mayuzheng <mayuzheng@kedacom.com>,
	linux-mmc <linux-mmc@vger.kernel.org>,
	linux-omap <linux-omap@vger.kernel.org>,
	linux-kernel <linux-kernel@vger.kernel.org>,
	"Felipe Balbi" <balbi@ti.com>
Subject: Re: Re: [PATCH] mmc: omap_hsmmc: Fix sleep too long in ISR context.
Date: Thu, 1 Aug 2013 16:40:05 +0800	[thread overview]
Message-ID: <201308011640027321434@gmail.com> (raw)
In-Reply-To: 51FA1AB7.8030105@yahoo.es

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="gb2312", Size: 7071 bytes --]

>Hi Jianpeng Ma,
>
>On 8/1/2013 10:18 AM, majianpeng wrote:
>> We found a problem when we removed a working sd card that the irqaction
>> of omap_hsmmc can sleep to 3.6s. This cause our watchdog to work.
>> In func omap_hsmmc_reset_controller_fsm, it should watch a 0->1
>> transition.It used loops_per_jiffy as the timer.
>> The code is:
>>> while ((!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit))
>>>                && (i++ < limit))
>>>                        cpu_relax();
>> But the loops_per_jiffy is:
>>>  while(i++ < limit)
>>> 	cpu_relax();
>> It add some codes so the time became long.
>> Becasue those codes in ISR context, it can't use timer_before/after.
>> I divived the time into 1ms and used udelay(1) to instead.
>> It will cause do additional udelay(1).But from my test,it looks good.
>>
>> Reported-by: Yuzheng Ma <mayuzheng@kedacom.com>
>> Tested-by: Yuzheng Ma <mayuzheng@kedacom.com>
>> Signed-off-by: Jianpeng Ma <majianpeng@gmail.com>
>> ---
>>  drivers/mmc/host/omap_hsmmc.c | 20 +++++++++++++-------
>>  1 file changed, 13 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
>> index 1865321..96daca1 100644
>> --- a/drivers/mmc/host/omap_hsmmc.c
>> +++ b/drivers/mmc/host/omap_hsmmc.c
>> @@ -977,6 +977,8 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host,
>>  	unsigned long limit = (loops_per_jiffy *
>>  				msecs_to_jiffies(MMC_TIMEOUT_MS));
>>  
>> +	/*Divided time into us for unit 1,we can use udelay(1)*/
>> +	i = limit / (MMC_TIMEOUT_MS * 1000);
>
>'limit' is a number of loops, which you now divide by 20,000?
>
>To get uS, you could just change:
>
>-	unsigned long limit = (loops_per_jiffy *
>-				msecs_to_jiffies(MMC_TIMEOUT_MS));
>+	unsigned long limit = 1000 * MMC_TIMEOUT_MS;
>
Yes, you are right.
>and make this amount of loops using udelay().
>
>>  	OMAP_HSMMC_WRITE(host->base, SYSCTL,
>>  			 OMAP_HSMMC_READ(host->base, SYSCTL) | bit);
>>  
>> @@ -985,15 +987,19 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host,
>>  	 * Monitor a 0->1 transition first
>>  	 */
>>  	if (mmc_slot(host).features & HSMMC_HAS_UPDATED_RESET) {
>> -		while ((!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit))
>> -					&& (i++ < limit))
>> -			cpu_relax();
>
>I still don't see why any of these loops could last 3.6 seconds?
>Yes the __raw_readl() will add some time, but so much?
>I'd like to see which value you get for 'limit' on your machine
>Would PM play a role? Or cpu-freq, and 'loops_per_jiffy' isn't updated
>on time?
>From my test, i found it don't monitor a 0->1 transtion.That is the last result is 'i = limit'.
The later while opertion stop also because 'i = limit'.
The basic reason is the hardware. 
It write bit and monitor 1-->0---1>---0.But we start monitor we only got 0 and the value don't change.
Maybe the transition is 1-->0.So the monitor can't work but still waste cpu.

>
>> +		while (i--) {
>> +			if ((OMAP_HSMMC_READ(host->base, SYSCTL) & bit))
>> +				break;
>> +			udelay(1);
>
>In earlier threads, the use of udelay was disliked because it's a waste
>of cpu cycles. The desired bit in SYSCTL will change, while udelay()
>is still making many useless loops.
Yes, but it at most wast 1us.

Jianpeng Ma
>
>> +		}
>>  	}
>> -	i = 0;
>>  
>> -	while ((OMAP_HSMMC_READ(host->base, SYSCTL) & bit) &&
>> -		(i++ < limit))
>> -		cpu_relax();
>> +	i = limit / (MMC_TIMEOUT_MS * 1000);
>> +	while (i--) {
>> +		if (!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit))
>> +			break;
>> +		udealy(1);
>> +	}
>>  
>>  	if (OMAP_HSMMC_READ(host->base, SYSCTL) & bit)
>>  		dev_err(mmc_dev(host->mmc),
>Hein
Thanks!
Jianpeng Ma
>Hi Jianpeng Ma,
>
>On 8/1/2013 10:18 AM, majianpeng wrote:
>> We found a problem when we removed a working sd card that the irqaction
>> of omap_hsmmc can sleep to 3.6s. This cause our watchdog to work.
>> In func omap_hsmmc_reset_controller_fsm, it should watch a 0->1
>> transition.It used loops_per_jiffy as the timer.
>> The code is:
>>> while ((!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit))
>>>                && (i++ < limit))
>>>                        cpu_relax();
>> But the loops_per_jiffy is:
>>>  while(i++ < limit)
>>> 	cpu_relax();
>> It add some codes so the time became long.
>> Becasue those codes in ISR context, it can't use timer_before/after.
>> I divived the time into 1ms and used udelay(1) to instead.
>> It will cause do additional udelay(1).But from my test,it looks good.
>>
>> Reported-by: Yuzheng Ma <mayuzheng@kedacom.com>
>> Tested-by: Yuzheng Ma <mayuzheng@kedacom.com>
>> Signed-off-by: Jianpeng Ma <majianpeng@gmail.com>
>> ---
>>  drivers/mmc/host/omap_hsmmc.c | 20 +++++++++++++-------
>>  1 file changed, 13 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
>> index 1865321..96daca1 100644
>> --- a/drivers/mmc/host/omap_hsmmc.c
>> +++ b/drivers/mmc/host/omap_hsmmc.c
>> @@ -977,6 +977,8 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host,
>>  	unsigned long limit = (loops_per_jiffy *
>>  				msecs_to_jiffies(MMC_TIMEOUT_MS));
>>  
>> +	/*Divided time into us for unit 1,we can use udelay(1)*/
>> +	i = limit / (MMC_TIMEOUT_MS * 1000);
>
>'limit' is a number of loops, which you now divide by 20,000?
>
>To get uS, you could just change:
>
>-	unsigned long limit = (loops_per_jiffy *
>-				msecs_to_jiffies(MMC_TIMEOUT_MS));
>+	unsigned long limit = 1000 * MMC_TIMEOUT_MS;
>
>and make this amount of loops using udelay().
>
>>  	OMAP_HSMMC_WRITE(host->base, SYSCTL,
>>  			 OMAP_HSMMC_READ(host->base, SYSCTL) | bit);
>>  
>> @@ -985,15 +987,19 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host,
>>  	 * Monitor a 0->1 transition first
>>  	 */
>>  	if (mmc_slot(host).features & HSMMC_HAS_UPDATED_RESET) {
>> -		while ((!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit))
>> -					&& (i++ < limit))
>> -			cpu_relax();
>
>I still don't see why any of these loops could last 3.6 seconds?
>Yes the __raw_readl() will add some time, but so much?
>I'd like to see which value you get for 'limit' on your machine
>Would PM play a role? Or cpu-freq, and 'loops_per_jiffy' isn't updated
>on time?
>
>> +		while (i--) {
>> +			if ((OMAP_HSMMC_READ(host->base, SYSCTL) & bit))
>> +				break;
>> +			udelay(1);
>
>In earlier threads, the use of udelay was disliked because it's a waste
>of cpu cycles. The desired bit in SYSCTL will change, while udelay()
>is still making many useless loops.
>
>> +		}
>>  	}
>> -	i = 0;
>>  
>> -	while ((OMAP_HSMMC_READ(host->base, SYSCTL) & bit) &&
>> -		(i++ < limit))
>> -		cpu_relax();
>> +	i = limit / (MMC_TIMEOUT_MS * 1000);
>> +	while (i--) {
>> +		if (!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit))
>> +			break;
>> +		udealy(1);
>> +	}
>>  
>>  	if (OMAP_HSMMC_READ(host->base, SYSCTL) & bit)
>>  		dev_err(mmc_dev(host->mmc),
>Heinÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

  reply	other threads:[~2013-08-01  8:40 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-01  2:18 [PATCH] mmc: omap_hsmmc: Fix sleep too long in ISR context majianpeng
2013-08-01  2:18 ` majianpeng
2013-08-01  8:22 ` Hein Tibosch
2013-08-01  8:40   ` majianpeng [this message]
2013-08-01  8:40     ` majianpeng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201308011640027321434@gmail.com \
    --to=majianpeng@gmail.com \
    --cc=balajitk@ti.com \
    --cc=balbi@ti.com \
    --cc=cjb@laptop.org \
    --cc=hein_tibosch@yahoo.es \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mmc@vger.kernel.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=mayuzheng@kedacom.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.