public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
* OneNAND: read-while-load
@ 2007-01-04  8:55 Adrian Hunter
  2007-01-04 11:35 ` Josh Boyer
  0 siblings, 1 reply; 10+ messages in thread
From: Adrian Hunter @ 2007-01-04  8:55 UTC (permalink / raw)
  To: kyungmin.park; +Cc: linux-mtd

[-- Attachment #1: Type: text/plain, Size: 232 bytes --]

Hi

Here is a patch that implements read-while-load for OneNAND.  My
testing shows that it gives a measurable performance improvement for
large reads.

Sorry the patch is in an attachment, but I have email problems.

Regards
Adrian

[-- Attachment #2: 0001-MTD-OneNand-Implement-read-while-load.txt --]
[-- Type: text/plain, Size: 3306 bytes --]

From: Adrian Hunter <hunter.programmer@gmail.com>
Date: Thu, 4 Jan 2007 09:51:26 +0200
Subject: [MTD] OneNand: Implement read-while-load

Read-while-load enables higher performance read operations.

Signed-off-by: Adrian Hunter <hunter.programmer@gmail.com>
---
 drivers/mtd/onenand/onenand_base.c |   46 ++++++++++++++++++++++--------------
 include/linux/mtd/onenand.h        |    1 +
 2 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index e121bcc..11da796 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -727,38 +727,45 @@ static int onenand_read(struct mtd_info 
 	/* TODO handling oob */
 
 	stats = mtd->ecc_stats;
-	while (read < len) {
-		thislen = min_t(int, mtd->writesize, len - read);
 
-		column = from & (mtd->writesize - 1);
-		if (column + thislen > mtd->writesize)
-			thislen = mtd->writesize - column;
+	/* Read-while-load method */
 
+	/* Do first load to bufferRAM */
+	if (read < len) {
 		if (!onenand_check_bufferram(mtd, from)) {
 			this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize);
-
 			ret = this->wait(mtd, FL_READING);
-			/* First copy data and check return value for ECC handling */
 			onenand_update_bufferram(mtd, from, !ret);
 		}
-
-		this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);
-
-		if (ret) {
-			DEBUG(MTD_DEBUG_LEVEL0, "onenand_read: read failed = %d\n", ret);
-			goto out;
+	}
+	thislen = min_t(int, mtd->writesize, len - read);
+	column = from & (mtd->writesize - 1);
+	if (column + thislen > mtd->writesize)
+		thislen = mtd->writesize - column;
+	while (!ret) {
+		/* If there is more to load then start next load */
+		from += thislen;
+		if (read + thislen < len) {
+			this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize);
+			ONENAND_SET_PREV_BUFFERRAM(this);
 		}
-
+		/* While load is going, read from last bufferRAM */
+		this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);
+		/* See if we are done */
 		read += thislen;
-
 		if (read == len)
 			break;
-
-		from += thislen;
+		/* Set up for next read from bufferRAM */
+		ONENAND_SET_NEXT_BUFFERRAM(this);
 		buf += thislen;
+		thislen = min_t(int, mtd->writesize, len - read);
+		column = 0;
+		cond_resched();
+		/* Now wait for load */
+		ret = this->wait(mtd, FL_READING);
+		onenand_update_bufferram(mtd, from, !ret);
 	}
 
-out:
 	/* Deselect and wake up anyone waiting on the device */
 	onenand_release_device(mtd);
 
@@ -772,6 +779,9 @@ out:
 	if (mtd->ecc_stats.failed - stats.failed)
 		return -EBADMSG;
 
+	if (ret)
+		return ret;
+
 	return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
 }
 
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
index fe3500d..f775a7a 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -143,6 +143,7 @@ struct onenand_chip {
 #define ONENAND_CURRENT_BUFFERRAM(this)		(this->bufferram_index)
 #define ONENAND_NEXT_BUFFERRAM(this)		(this->bufferram_index ^ 1)
 #define ONENAND_SET_NEXT_BUFFERRAM(this)	(this->bufferram_index ^= 1)
+#define ONENAND_SET_PREV_BUFFERRAM(this)	(this->bufferram_index ^= 1)
 
 #define ONENAND_GET_SYS_CFG1(this)					\
 	(this->read_word(this->base + ONENAND_REG_SYS_CFG1))
-- 
1.4.3


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: OneNAND: read-while-load
  2007-01-04  8:55 Adrian Hunter
@ 2007-01-04 11:35 ` Josh Boyer
  2007-01-04 12:14   ` Adrian Hunter
  0 siblings, 1 reply; 10+ messages in thread
From: Josh Boyer @ 2007-01-04 11:35 UTC (permalink / raw)
  To: Adrian Hunter; +Cc: linux-mtd

On 1/4/07, Adrian Hunter <hunter.programmer@gmail.com> wrote:
> Hi
>
> Here is a patch that implements read-while-load for OneNAND.  My
> testing shows that it gives a measurable performance improvement for
> large reads.
>
> Sorry the patch is in an attachment, but I have email problems.

You're using a gmail account... what possible email problems could you have?

josh

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: OneNAND: read-while-load
  2007-01-04 11:35 ` Josh Boyer
@ 2007-01-04 12:14   ` Adrian Hunter
  2007-01-04 13:57     ` Josh Boyer
  0 siblings, 1 reply; 10+ messages in thread
From: Adrian Hunter @ 2007-01-04 12:14 UTC (permalink / raw)
  To: Josh Boyer; +Cc: linux-mtd

On 1/4/07, Josh Boyer <jwboyer@gmail.com> wrote:
> On 1/4/07, Adrian Hunter <hunter.programmer@gmail.com> wrote:
> > Hi
> >
> > Here is a patch that implements read-while-load for OneNAND.  My
> > testing shows that it gives a measurable performance improvement for
> > large reads.
> >
> > Sorry the patch is in an attachment, but I have email problems.
>
> You're using a gmail account... what possible email problems could you have?
>
> josh
>

It word-wraps.  Maybe it is the browser: firefox 2.0

I do use plain text and view original, but it goes like this:

From: Adrian Hunter <hunter.programmer@gmail.com>
Date: Thu, 4 Jan 2007 09:51:26 +0200
Subject: [MTD] OneNand: Implement read-while-load

Read-while-load enables higher performance read operations.

Signed-off-by: Adrian Hunter <hunter.programmer@gmail.com>
---
 drivers/mtd/onenand/onenand_base.c |   46 ++++++++++++++++++++++--------------
 include/linux/mtd/onenand.h        |    1 +
 2 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/drivers/mtd/onenand/onenand_base.c
b/drivers/mtd/onenand/onenand_base.c
index e121bcc..11da796 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -727,38 +727,45 @@ static int onenand_read(struct mtd_info
 	/* TODO handling oob */

 	stats = mtd->ecc_stats;
-	while (read < len) {
-		thislen = min_t(int, mtd->writesize, len - read);

-		column = from & (mtd->writesize - 1);
-		if (column + thislen > mtd->writesize)
-			thislen = mtd->writesize - column;
+	/* Read-while-load method */

+	/* Do first load to bufferRAM */
+	if (read < len) {
 		if (!onenand_check_bufferram(mtd, from)) {
 			this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize);
-
 			ret = this->wait(mtd, FL_READING);
-			/* First copy data and check return value for ECC handling */
 			onenand_update_bufferram(mtd, from, !ret);
 		}
-
-		this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);
-
-		if (ret) {
-			DEBUG(MTD_DEBUG_LEVEL0, "onenand_read: read failed = %d\n", ret);
-			goto out;
+	}
+	thislen = min_t(int, mtd->writesize, len - read);
+	column = from & (mtd->writesize - 1);
+	if (column + thislen > mtd->writesize)
+		thislen = mtd->writesize - column;
+	while (!ret) {
+		/* If there is more to load then start next load */
+		from += thislen;
+		if (read + thislen < len) {
+			this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize);
+			ONENAND_SET_PREV_BUFFERRAM(this);
 		}
-
+		/* While load is going, read from last bufferRAM */
+		this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);
+		/* See if we are done */
 		read += thislen;
-
 		if (read == len)
 			break;
-
-		from += thislen;
+		/* Set up for next read from bufferRAM */
+		ONENAND_SET_NEXT_BUFFERRAM(this);
 		buf += thislen;
+		thislen = min_t(int, mtd->writesize, len - read);
+		column = 0;
+		cond_resched();
+		/* Now wait for load */
+		ret = this->wait(mtd, FL_READING);
+		onenand_update_bufferram(mtd, from, !ret);
 	}

-out:
 	/* Deselect and wake up anyone waiting on the device */
 	onenand_release_device(mtd);

@@ -772,6 +779,9 @@ out:
 	if (mtd->ecc_stats.failed - stats.failed)
 		return -EBADMSG;

+	if (ret)
+		return ret;
+
 	return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
 }

diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
index fe3500d..f775a7a 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -143,6 +143,7 @@ struct onenand_chip {
 #define ONENAND_CURRENT_BUFFERRAM(this)		(this->bufferram_index)
 #define ONENAND_NEXT_BUFFERRAM(this)		(this->bufferram_index ^ 1)
 #define ONENAND_SET_NEXT_BUFFERRAM(this)	(this->bufferram_index ^= 1)
+#define ONENAND_SET_PREV_BUFFERRAM(this)	(this->bufferram_index ^= 1)

 #define ONENAND_GET_SYS_CFG1(this)					\
 	(this->read_word(this->base + ONENAND_REG_SYS_CFG1))
-- 
1.4.3

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: OneNAND: read-while-load
  2007-01-04 12:14   ` Adrian Hunter
@ 2007-01-04 13:57     ` Josh Boyer
  0 siblings, 0 replies; 10+ messages in thread
From: Josh Boyer @ 2007-01-04 13:57 UTC (permalink / raw)
  To: Adrian Hunter; +Cc: Josh Boyer, linux-mtd

On Thu, 2007-01-04 at 14:14 +0200, Adrian Hunter wrote:
> On 1/4/07, Josh Boyer <jwboyer@gmail.com> wrote:
> > On 1/4/07, Adrian Hunter <hunter.programmer@gmail.com> wrote:
> > > Hi
> > >
> > > Here is a patch that implements read-while-load for OneNAND.  My
> > > testing shows that it gives a measurable performance improvement for
> > > large reads.
> > >
> > > Sorry the patch is in an attachment, but I have email problems.
> >
> > You're using a gmail account... what possible email problems could you have?
> >
> > josh
> >
> 
> It word-wraps.  Maybe it is the browser: firefox 2.0
> 
> I do use plain text and view original, but it goes like this:

I see nothing corrupted about the patch.  Whitespace is preserved and I
don't see any word wraps.  Both in my gmail account, and this account
(evolution as the mailer).

At any rate, if you do have issues maybe David can give you an account
on infradead.

josh

^ permalink raw reply	[flat|nested] 10+ messages in thread

* OneNAND: read-while-load
@ 2007-01-05  7:15 Kyungmin Park
  2007-01-05  8:05 ` Adrian Hunter
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Kyungmin Park @ 2007-01-05  7:15 UTC (permalink / raw)
  To: Adrian Hunter; +Cc: Josh Boyer, linux-mtd@lists.infradead.org

Hi,

it looks good to me. except one

> +	/* Read-while-load method */
> 
> +	/* Do first load to bufferRAM */
> +	if (read < len) {

I think it is alway true. Is there any case that sends zero 'len' from upper layer?

I will run regression test with this one during this weekend.

And which program (JFFS2 or UBI) do you use.

I can't find any performance increase in JFFS2

Here's my test results

Target: Apollon (OMAP2) 330MHz, OneNAND 83MHz with Sync. Burst Read support mode

# iozone -U /jffs2 -f /jffs2/test -e -A -s 10m -q 256k

Before patch

              KB  reclen   write rewrite    read    reread
           10240       4    5961    5942    15667    15677
           10240       8    6053    6033    15849    15830
           10240      16    6068    6068    15983    15974
           10240      32    6091    6088    16098    16083
           10240      64    6115    6077    16128    16111
           10240     128    6142    6134    16249    16226
           10240     256    6138    6147    16184    16212

After patch

              KB  reclen   write rewrite    read    reread
           10240       4    5931    5914    15598    15577
           10240       8    6035    5941    15775    15743
           10240      16    6070    6037    16020    15986
           10240      32    6098    6081    16140    16115
           10240      64    6123    6100    16123    16108
           10240     128    6147    6102    16186    16188
           10240     256    6134    6114    16142    16152


Thank you,
Kyungmin Park

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: OneNAND: read-while-load
  2007-01-05  7:15 Kyungmin Park
@ 2007-01-05  8:05 ` Adrian Hunter
  2007-01-05  8:41 ` Adrian Hunter
  2007-01-05  9:01 ` Artem Bityutskiy
  2 siblings, 0 replies; 10+ messages in thread
From: Adrian Hunter @ 2007-01-05  8:05 UTC (permalink / raw)
  To: kyungmin.park; +Cc: Josh Boyer, linux-mtd@lists.infradead.org

On 1/5/07, Kyungmin Park <kyungmin.park@samsung.com> wrote:
> Hi,
>
> it looks good to me. except one
>
> > +     /* Read-while-load method */
> >
> > +     /* Do first load to bufferRAM */
> > +     if (read < len) {
>
> I think it is alway true. Is there any case that sends zero 'len' from upper layer?
>
> I will run regression test with this one during this weekend.
>
> And which program (JFFS2 or UBI) do you use.
>
> I can't find any performance increase in JFFS2
>
> Here's my test results
>
> Target: Apollon (OMAP2) 330MHz, OneNAND 83MHz with Sync. Burst Read support mode
>
> # iozone -U /jffs2 -f /jffs2/test -e -A -s 10m -q 256k
>
> Before patch
>
>               KB  reclen   write rewrite    read    reread
>            10240       4    5961    5942    15667    15677
>            10240       8    6053    6033    15849    15830
>            10240      16    6068    6068    15983    15974
>            10240      32    6091    6088    16098    16083
>            10240      64    6115    6077    16128    16111
>            10240     128    6142    6134    16249    16226
>            10240     256    6138    6147    16184    16212
>
> After patch
>
>               KB  reclen   write rewrite    read    reread
>            10240       4    5931    5914    15598    15577
>            10240       8    6035    5941    15775    15743
>            10240      16    6070    6037    16020    15986
>            10240      32    6098    6081    16140    16115
>            10240      64    6123    6100    16123    16108
>            10240     128    6147    6102    16186    16188
>            10240     256    6134    6114    16142    16152
>
>
> Thank you,
> Kyungmin Park

I will need to study your results more closely, however you won't see
results unless you can exclude the effects of buffering.  I tested
used jffs2 but I used a very simple program that un-mounted and
re-mounted before reading.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: OneNAND: read-while-load
  2007-01-05  7:15 Kyungmin Park
  2007-01-05  8:05 ` Adrian Hunter
@ 2007-01-05  8:41 ` Adrian Hunter
  2007-01-05  9:01 ` Artem Bityutskiy
  2 siblings, 0 replies; 10+ messages in thread
From: Adrian Hunter @ 2007-01-05  8:41 UTC (permalink / raw)
  To: kyungmin.park; +Cc: Josh Boyer, linux-mtd@lists.infradead.org

On 1/5/07, Kyungmin Park <kyungmin.park@samsung.com> wrote:
> Hi,
>
> it looks good to me. except one
>
> > +     /* Read-while-load method */
> >
> > +     /* Do first load to bufferRAM */
> > +     if (read < len) {
>
> I think it is alway true. Is there any case that sends zero 'len' from upper layer?
>

I don't know if the upper layer sends zero as 'len', but I would not
trust it not to.  I do not see any harm in the statement.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: OneNAND: read-while-load
  2007-01-05  7:15 Kyungmin Park
  2007-01-05  8:05 ` Adrian Hunter
  2007-01-05  8:41 ` Adrian Hunter
@ 2007-01-05  9:01 ` Artem Bityutskiy
  2 siblings, 0 replies; 10+ messages in thread
From: Artem Bityutskiy @ 2007-01-05  9:01 UTC (permalink / raw)
  To: kyungmin.park; +Cc: linux-mtd@lists.infradead.org, Adrian Hunter

Kyungmin, Adrian,

On Fri, 2007-01-05 at 07:15 +0000, Kyungmin Park wrote:
> I will run regression test with this one during this weekend.
> 
> And which program (JFFS2 or UBI) do you use.
> 
> I can't find any performance increase in JFFS2

It depends how you tested it. Surely you notice some performance gain
only if JFFS2 reads more then 2K bytes of data. And this only happens
when you read files's contents, especially if this file's pages were not
compressed to less then 2K.

So a test like:

dd if=/dev/udandom of=/mnt/jffs2/file bs=4K
time dd if=/mnt/jffs2/file of=/dev/null

would be roughly OK.

-- 
Best regards,
Artem Bityutskiy (Битюцкий Артём)

^ permalink raw reply	[flat|nested] 10+ messages in thread

* OneNAND: read-while-load
@ 2007-01-05  9:58 Kyungmin Park
  2007-01-05 10:54 ` Artem Bityutskiy
  0 siblings, 1 reply; 10+ messages in thread
From: Kyungmin Park @ 2007-01-05  9:58 UTC (permalink / raw)
  To: Artem Bityutskiy; +Cc: linux-mtd@lists.infradead.org, Adrian Hunter

Yes, We already knew read-while-loading has better performance than normal read.
Internally we called it 'MRead' (refer another OneNAND open source in samsung web site)

Currently it is best one if the JFFS2 requests read 4KB or more.
and if you are using the mtdblock. it also has benefits

Thank you,
Kyungmin Park

------- Original Message -------
Sender : Artem Bityutskiy<dedekind@infradead.org> 
Date   : Jan 05, 2007 18:01
Title  : Re: OneNAND: read-while-load

Kyungmin, Adrian,

On Fri, 2007-01-05 at 07:15 +0000, Kyungmin Park wrote:
> I will run regression test with this one during this weekend.
> 
> And which program (JFFS2 or UBI) do you use.
> 
> I can't find any performance increase in JFFS2

It depends how you tested it. Surely you notice some performance gain
only if JFFS2 reads more then 2K bytes of data. And this only happens
when you read files's contents, especially if this file's pages were not
compressed to less then 2K.

So a test like:

dd if=/dev/udandom of=/mnt/jffs2/file bs=4K
time dd if=/mnt/jffs2/file of=/dev/null

would be roughly OK.

-- 
Best regards,
Artem Bityutskiy (Битюцкий Артём)




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: OneNAND: read-while-load
  2007-01-05  9:58 OneNAND: read-while-load Kyungmin Park
@ 2007-01-05 10:54 ` Artem Bityutskiy
  0 siblings, 0 replies; 10+ messages in thread
From: Artem Bityutskiy @ 2007-01-05 10:54 UTC (permalink / raw)
  To: kyungmin.park; +Cc: linux-mtd@lists.infradead.org, Adrian Hunter

On Fri, 2007-01-05 at 09:58 +0000, Kyungmin Park wrote:
> Yes, We already knew read-while-loading has better performance than normal read.
> Internally we called it 'MRead' (refer another OneNAND open source in samsung web site)

It is true that JFFS2 is currently the main user. But it may be changed
in the future. Also one day one can teach JFFS2 to maintain larger nodes
with, say 16K or more bytes of data. And BTW, UBI reads whole
eraseblocks when making wear-leveling, so it would also benefit.

-- 
Best regards,
Artem Bityutskiy (Битюцкий Артём)

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2007-01-05 10:55 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-01-05  9:58 OneNAND: read-while-load Kyungmin Park
2007-01-05 10:54 ` Artem Bityutskiy
  -- strict thread matches above, loose matches on Subject: below --
2007-01-05  7:15 Kyungmin Park
2007-01-05  8:05 ` Adrian Hunter
2007-01-05  8:41 ` Adrian Hunter
2007-01-05  9:01 ` Artem Bityutskiy
2007-01-04  8:55 Adrian Hunter
2007-01-04 11:35 ` Josh Boyer
2007-01-04 12:14   ` Adrian Hunter
2007-01-04 13:57     ` Josh Boyer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox