* Patch MTD: increase time out value for buffer program
[not found] <mailman.0.1338988276.11201.linux-mtd@lists.infradead.org>
@ 2012-06-13 4:29 ` Changming Chen (changmingche)
2012-06-26 15:58 ` Artem Bityutskiy
0 siblings, 1 reply; 5+ messages in thread
From: Changming Chen (changmingche) @ 2012-06-13 4:29 UTC (permalink / raw)
To: linux-mtd-owner@lists.infradead.org,
linux-mtd@lists.infradead.org
Cc: dwmw2@infradead.org, Youxin He (youxinhe), Frank Liu (frankliu)
The time out value(1ms:typical HZ defined smaller than 1000) defined for function "do_write_buffer" in "cfi_cmdset_0002.c" is not enough. Because the enlargement of buffer size, much time will cost for buffer program. It's has risk that time out will be triggered before buffer program finished and make misjudge for buffer program. we suggest that 4ms is more appropriate compare to 1ms. This change has no impact of program performance.
diff --git a/a/drivers/mtd/chips/cfi_cmdset_0002.c b/b/drivers/mtd/chips/cfi_cmd
index 9d93c45..7da8fca 100755
--- a/a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -1312,7 +1312,7 @@ static int __xipram do_write_buffer(struct map_info *map,
struct cfi_private *cfi = map->fldrv_priv;
unsigned long timeo = jiffies + HZ;
/* see comments in do_write_oneword() regarding uWriteTimeo. */
- unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
+ unsigned long uWriteTimeout = ( HZ / 1000 ) + 4;
int ret = -EIO;
unsigned long cmd_adr;
int z, words;
Best Regards!
chenchangming
Tel:+86-21-3899-7193
E-Mail:changmingche@micron.com
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: Patch MTD: increase time out value for buffer program
2012-06-13 4:29 ` Patch MTD: increase time out value for buffer program Changming Chen (changmingche)
@ 2012-06-26 15:58 ` Artem Bityutskiy
2012-06-27 3:27 ` Artem Bityutskiy
0 siblings, 1 reply; 5+ messages in thread
From: Artem Bityutskiy @ 2012-06-26 15:58 UTC (permalink / raw)
To: Changming Chen (changmingche)
Cc: dwmw2@infradead.org, linux-mtd@lists.infradead.org,
Youxin He (youxinhe), Frank Liu (frankliu)
[-- Attachment #1: Type: text/plain, Size: 1434 bytes --]
On Wed, 2012-06-13 at 04:29 +0000, Changming Chen (changmingche) wrote:
> The time out value(1ms:typical HZ defined smaller than 1000) defined for function "do_write_buffer" in "cfi_cmdset_0002.c" is not enough. Because the enlargement of buffer size, much time will cost for buffer program. It's has risk that time out will be triggered before buffer program finished and make misjudge for buffer program. we suggest that 4ms is more appropriate compare to 1ms. This change has no impact of program performance.
>
> diff --git a/a/drivers/mtd/chips/cfi_cmdset_0002.c b/b/drivers/mtd/chips/cfi_cmd
> index 9d93c45..7da8fca 100755
> --- a/a/drivers/mtd/chips/cfi_cmdset_0002.c
> +++ b/b/drivers/mtd/chips/cfi_cmdset_0002.c
> @@ -1312,7 +1312,7 @@ static int __xipram do_write_buffer(struct map_info *map,
> struct cfi_private *cfi = map->fldrv_priv;
> unsigned long timeo = jiffies + HZ;
> /* see comments in do_write_oneword() regarding uWriteTimeo. */
> - unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
> + unsigned long uWriteTimeout = ( HZ / 1000 ) + 4;
No, sorry, this is not a fix, this is a band-aid. The whole HZ/1000
thing is broken. You should not use HZ at all. For this driver it looks
like you should use ' schedule_timeout()' with the right timout instead
of 'schedule()' and get rid of all the HZ and jiffies stuff.
--
Best Regards,
Artem Bityutskiy
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Patch MTD: increase time out value for buffer program
2012-06-26 15:58 ` Artem Bityutskiy
@ 2012-06-27 3:27 ` Artem Bityutskiy
2012-06-27 5:23 ` Youxin He (youxinhe)
0 siblings, 1 reply; 5+ messages in thread
From: Artem Bityutskiy @ 2012-06-27 3:27 UTC (permalink / raw)
To: Changming Chen (changmingche)
Cc: linux-mtd@lists.infradead.org, dwmw2@infradead.org,
Youxin He (youxinhe), Frank Liu (frankliu)
[-- Attachment #1: Type: text/plain, Size: 4432 bytes --]
On Tue, 2012-06-26 at 18:58 +0300, Artem Bityutskiy wrote:
> On Wed, 2012-06-13 at 04:29 +0000, Changming Chen (changmingche) wrote:
> > The time out value(1ms:typical HZ defined smaller than 1000) defined for function "do_write_buffer" in "cfi_cmdset_0002.c" is not enough. Because the enlargement of buffer size, much time will cost for buffer program. It's has risk that time out will be triggered before buffer program finished and make misjudge for buffer program. we suggest that 4ms is more appropriate compare to 1ms. This change has no impact of program performance.
> >
> > diff --git a/a/drivers/mtd/chips/cfi_cmdset_0002.c b/b/drivers/mtd/chips/cfi_cmd
> > index 9d93c45..7da8fca 100755
> > --- a/a/drivers/mtd/chips/cfi_cmdset_0002.c
> > +++ b/b/drivers/mtd/chips/cfi_cmdset_0002.c
> > @@ -1312,7 +1312,7 @@ static int __xipram do_write_buffer(struct map_info *map,
> > struct cfi_private *cfi = map->fldrv_priv;
> > unsigned long timeo = jiffies + HZ;
> > /* see comments in do_write_oneword() regarding uWriteTimeo. */
> > - unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
> > + unsigned long uWriteTimeout = ( HZ / 1000 ) + 4;
>
> No, sorry, this is not a fix, this is a band-aid. The whole HZ/1000
> thing is broken. You should not use HZ at all. For this driver it looks
> like you should use ' schedule_timeout()' with the right timout instead
> of 'schedule()' and get rid of all the HZ and jiffies stuff.
What I meant is something like this (not tested, not even compiled),
which should also be done in many other places in this file:
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 22d0493..8ce3b44 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -48,6 +48,9 @@
#define SST49LF008A 0x005a
#define AT49BV6416 0x00d6
+/* Write operation timeout, ms */
+#define WRITE_TIEMEOUT 2
+
static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
@@ -1143,17 +1146,6 @@ static int cfi_amdstd_secsi_read (struct mtd_info *mtd, loff_t from, size_t len,
static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, map_word datum)
{
struct cfi_private *cfi = map->fldrv_priv;
- unsigned long timeo = jiffies + HZ;
- /*
- * We use a 1ms + 1 jiffies generic timeout for writes (most devices
- * have a max write time of a few hundreds usec). However, we should
- * use the maximum timeout value given by the chip at probe time
- * instead. Unfortunately, struct flchip does have a field for
- * maximum timeout, only for typical which can be far too short
- * depending of the conditions. The ' + 1' is to avoid having a
- * timeout of 0 jiffies if HZ is smaller than 1000.
- */
- unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
int ret = 0;
map_word oldd;
int retry_cnt = 0;
@@ -1197,8 +1189,6 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
adr, map_bankwidth(map),
chip->word_write_time);
- /* See comment above for timeout value. */
- timeo = jiffies + uWriteTimeout;
for (;;) {
if (chip->state != FL_WRITING) {
/* Someone's suspended the write. Sleep */
@@ -1207,20 +1197,18 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
mutex_unlock(&chip->mutex);
- schedule();
+ ret = schedule_timeout(msecs_to_jiffies(WRITE_TIEMEOUT));
remove_wait_queue(&chip->wq, &wait);
- timeo = jiffies + (HZ / 2); /* FIXME */
mutex_lock(&chip->mutex);
+ if (!ret) {
+ xip_enable(map, chip, adr);
+ printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
+ xip_disable(map, chip, adr);
+ break;
+ }
continue;
}
- if (time_after(jiffies, timeo) && !chip_ready(map, adr)){
- xip_enable(map, chip, adr);
- printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
- xip_disable(map, chip, adr);
- break;
- }
-
if (chip_ready(map, adr))
break;
--
Best Regards,
Artem Bityutskiy
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply related [flat|nested] 5+ messages in thread
* RE: Patch MTD: increase time out value for buffer program
2012-06-27 3:27 ` Artem Bityutskiy
@ 2012-06-27 5:23 ` Youxin He (youxinhe)
2012-06-27 10:33 ` Artem Bityutskiy
0 siblings, 1 reply; 5+ messages in thread
From: Youxin He (youxinhe) @ 2012-06-27 5:23 UTC (permalink / raw)
To: Artem Bityutskiy, Changming Chen (changmingche)
Cc: linux-mtd@lists.infradead.org, dwmw2@infradead.org,
Frank Liu (frankliu)
Hi Artem,
How about just change HZ/1000 stuff to msecs_to_jiffies()? Schedule_timeout() is a good idea but I don't see it is necessary to use schedule_timeout() to replace schedule(). The code you add below is just for suspend case, normal case will not go to schedule(), but normal case you should check for timeout otherwise infinite loop in case a program failure occur.
+ #define WRITE_TIEMEOUT 4
.......
- unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
+ unsigned long uWriteTimeout = msecs_to_jiffies(WRITE_TIEMEOUT);
.......
Thanks.
Best regards,
Youxin He
-----Original Message-----
From: Artem Bityutskiy [mailto:dedekind1@gmail.com]
Sent: Wednesday, June 27, 2012 11:27 AM
To: Changming Chen (changmingche)
Cc: dwmw2@infradead.org; linux-mtd@lists.infradead.org; Youxin He (youxinhe); Frank Liu (frankliu)
Subject: Re: Patch MTD: increase time out value for buffer program
On Tue, 2012-06-26 at 18:58 +0300, Artem Bityutskiy wrote:
> On Wed, 2012-06-13 at 04:29 +0000, Changming Chen (changmingche) wrote:
> > The time out value(1ms:typical HZ defined smaller than 1000) defined for function "do_write_buffer" in "cfi_cmdset_0002.c" is not enough. Because the enlargement of buffer size, much time will cost for buffer program. It's has risk that time out will be triggered before buffer program finished and make misjudge for buffer program. we suggest that 4ms is more appropriate compare to 1ms. This change has no impact of program performance.
> >
> > diff --git a/a/drivers/mtd/chips/cfi_cmdset_0002.c
> > b/b/drivers/mtd/chips/cfi_cmd index 9d93c45..7da8fca 100755
> > --- a/a/drivers/mtd/chips/cfi_cmdset_0002.c
> > +++ b/b/drivers/mtd/chips/cfi_cmdset_0002.c
> > @@ -1312,7 +1312,7 @@ static int __xipram do_write_buffer(struct map_info *map,
> > struct cfi_private *cfi = map->fldrv_priv;
> > unsigned long timeo = jiffies + HZ;
> > /* see comments in do_write_oneword() regarding uWriteTimeo. */
> > - unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
> > + unsigned long uWriteTimeout = ( HZ / 1000 ) + 4;
>
> No, sorry, this is not a fix, this is a band-aid. The whole HZ/1000
> thing is broken. You should not use HZ at all. For this driver it
> looks like you should use ' schedule_timeout()' with the right timout
> instead of 'schedule()' and get rid of all the HZ and jiffies stuff.
What I meant is something like this (not tested, not even compiled), which should also be done in many other places in this file:
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 22d0493..8ce3b44 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -48,6 +48,9 @@
#define SST49LF008A 0x005a
#define AT49BV6416 0x00d6
+/* Write operation timeout, ms */
+#define WRITE_TIEMEOUT 2
+
static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); @@ -1143,17 +1146,6 @@ static int cfi_amdstd_secsi_read (struct mtd_info *mtd, loff_t from, size_t len, static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, map_word datum) {
struct cfi_private *cfi = map->fldrv_priv;
- unsigned long timeo = jiffies + HZ;
- /*
- * We use a 1ms + 1 jiffies generic timeout for writes (most devices
- * have a max write time of a few hundreds usec). However, we should
- * use the maximum timeout value given by the chip at probe time
- * instead. Unfortunately, struct flchip does have a field for
- * maximum timeout, only for typical which can be far too short
- * depending of the conditions. The ' + 1' is to avoid having a
- * timeout of 0 jiffies if HZ is smaller than 1000.
- */
- unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
int ret = 0;
map_word oldd;
int retry_cnt = 0;
@@ -1197,8 +1189,6 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
adr, map_bankwidth(map),
chip->word_write_time);
- /* See comment above for timeout value. */
- timeo = jiffies + uWriteTimeout;
for (;;) {
if (chip->state != FL_WRITING) {
/* Someone's suspended the write. Sleep */ @@ -1207,20 +1197,18 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
mutex_unlock(&chip->mutex);
- schedule();
+ ret = schedule_timeout(msecs_to_jiffies(WRITE_TIEMEOUT));
remove_wait_queue(&chip->wq, &wait);
- timeo = jiffies + (HZ / 2); /* FIXME */
mutex_lock(&chip->mutex);
+ if (!ret) {
+ xip_enable(map, chip, adr);
+ printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
+ xip_disable(map, chip, adr);
+ break;
+ }
continue;
}
- if (time_after(jiffies, timeo) && !chip_ready(map, adr)){
- xip_enable(map, chip, adr);
- printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
- xip_disable(map, chip, adr);
- break;
- }
-
if (chip_ready(map, adr))
break;
--
Best Regards,
Artem Bityutskiy
^ permalink raw reply related [flat|nested] 5+ messages in thread
* RE: Patch MTD: increase time out value for buffer program
2012-06-27 5:23 ` Youxin He (youxinhe)
@ 2012-06-27 10:33 ` Artem Bityutskiy
0 siblings, 0 replies; 5+ messages in thread
From: Artem Bityutskiy @ 2012-06-27 10:33 UTC (permalink / raw)
To: Youxin He (youxinhe)
Cc: linux-mtd@lists.infradead.org, Changming Chen (changmingche),
dwmw2@infradead.org, Frank Liu (frankliu)
[-- Attachment #1: Type: text/plain, Size: 1169 bytes --]
On Wed, 2012-06-27 at 05:23 +0000, Youxin He (youxinhe) wrote:
> Hi Artem,
> How about just change HZ/1000 stuff to msecs_to_jiffies()? Schedule_timeout() is a good idea but I don't see it is necessary to use schedule_timeout() to replace schedule(). The code you add below is just for suspend case, normal case will not go to schedule(), but normal case you should check for timeout otherwise infinite loop in case a program failure occur.
>
> + #define WRITE_TIEMEOUT 4
> .......
> - unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
> + unsigned long uWriteTimeout = msecs_to_jiffies(WRITE_TIEMEOUT);
I think that the current code simply buggy and needs to be re-wised.
E.g., what is this:
timeo = jiffies + (HZ / 2); /* FIXME */
mutex_lock(&chip->mutex);
...
if (time_after(jiffies, timeo) && !chip_ready(map, adr)){
What if we are not able to grab the mutex for longer than "HZ/2".
So I suggest you to try to come-up with the general clean-up of the
timeouts in this driver. AFAICS, but not sure because did not think hard
enough, schedule_tiemout() could be use in most places in this driver.
--
Best Regards,
Artem Bityutskiy
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2012-06-27 10:29 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <mailman.0.1338988276.11201.linux-mtd@lists.infradead.org>
2012-06-13 4:29 ` Patch MTD: increase time out value for buffer program Changming Chen (changmingche)
2012-06-26 15:58 ` Artem Bityutskiy
2012-06-27 3:27 ` Artem Bityutskiy
2012-06-27 5:23 ` Youxin He (youxinhe)
2012-06-27 10:33 ` Artem Bityutskiy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox