[PATCH RESEND 1/2] SD/MMC: add an interface to re-initialize bounce buffer

2012-08-08 Thread Qiang Liu
Add attribute bouncesz under sysfs.
Provide a helper of dynamic adjustment of bounce buffer for SDMA mmc card at
run-time (mounted or unmounted filesystem).

bouncesz should be integer multiple of 512, the value range is from 4K to 4M.

1. use variable instead of MMC_QUEUE_BOUNCESZ;
2. Re-initialize bounce buffer accorinding to new bounce size at run-time;

Cc: Chris Ball c...@laptop.org
Cc: Rob Landley r...@landley.net
Signed-off-by: Qiang Liu qiang@freescale.com
---

Hi all,

I resend the patch because bounce size is a key factor of performance for some
SDMA card, larger bounce size will improve throughput under condition of mass
data transfer. So I add this helper and export the value to user space.

 drivers/mmc/card/block.c |   48 +
 drivers/mmc/card/queue.c |  102 +-
 drivers/mmc/card/queue.h |6 +++
 3 files changed, 155 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index f1c84de..3ea4ac3 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -58,6 +58,9 @@ MODULE_ALIAS(mmc:block);
 #define INAND_CMD38_ARG_SECTRIM1 0x81
 #define INAND_CMD38_ARG_SECTRIM2 0x88

+#define MMC_MIN_QUEUE_BOUNCESZ 4096
+#define MMC_MAX_QUEUE_BOUNCESZ 4194304
+
 static DEFINE_MUTEX(block_mutex);

 /*
@@ -107,6 +110,7 @@ struct mmc_blk_data {
unsigned intpart_curr;
struct device_attribute force_ro;
struct device_attribute power_ro_lock;
+   struct device_attribute bouncesz;
int area_type;
 };

@@ -263,6 +267,33 @@ out:
return ret;
 }

+#ifdef CONFIG_MMC_BLOCK_BOUNCE
+static ssize_t mmc_bouncesz_show(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+return sprintf(buf, %u\n, mmc_queue_bouncesz);
+}
+
+static ssize_t mmc_bouncesz_store(struct device *dev,
+   struct device_attribute *attr,
+   const char *buf, size_t count)
+{
+   unsigned int bouncesz;
+   struct mmc_blk_data *md;
+
+   if ((sscanf(buf, %d, bouncesz) != 1) ||
+   (bouncesz  MMC_MIN_QUEUE_BOUNCESZ) ||
+   (bouncesz  MMC_MAX_QUEUE_BOUNCESZ) ||
+   (bouncesz % 512 != 0))
+   return -EINVAL;
+
+   md = mmc_blk_get(dev_to_disk(dev));
+   mmc_reinit_bounce_queue(md-queue, md-queue.card, bouncesz);
+   mmc_blk_put(md);
+   return mmc_queue_bouncesz;
+}
+#endif
+
 static int mmc_blk_open(struct block_device *bdev, fmode_t mode)
 {
struct mmc_blk_data *md = mmc_blk_get(bdev-bd_disk);
@@ -1648,6 +1679,8 @@ static void mmc_blk_remove_req(struct mmc_blk_data *md)
del_gendisk(md-disk);
}

+   device_remove_file(disk_to_dev(md-disk), md-bouncesz);
+
/* Then flush out any already in there */
mmc_cleanup_queue(md-queue);
mmc_blk_put(md);
@@ -1683,6 +1716,17 @@ static int mmc_add_disk(struct mmc_blk_data *md)
if (ret)
goto force_ro_fail;

+#ifdef CONFIG_MMC_BLOCK_BOUNCE
+   md-bouncesz.show = mmc_bouncesz_show;
+   md-bouncesz.store = mmc_bouncesz_store;
+   sysfs_attr_init(md-bouncesz.attr);
+   md-bouncesz.attr.name = bouncesz;
+   md-bouncesz.attr.mode = S_IRUGO | S_IWUSR;
+   ret = device_create_file(disk_to_dev(md-disk), md-bouncesz);
+   if (ret)
+   goto bouncesz_fail;
+#endif
+
if ((md-area_type  MMC_BLK_DATA_AREA_BOOT) 
 card-ext_csd.boot_ro_lockable) {
umode_t mode;
@@ -1707,6 +1751,10 @@ static int mmc_add_disk(struct mmc_blk_data *md)

 power_ro_lock_fail:
device_remove_file(disk_to_dev(md-disk), md-force_ro);
+#ifdef CONFIG_MMC_BLOCK_BOUNCE
+bouncesz_fail:
+   device_remove_file(disk_to_dev(md-disk), md-bouncesz);
+#endif
 force_ro_fail:
del_gendisk(md-disk);

diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index e360a97..b9777a5 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -22,6 +22,10 @@

 #define MMC_QUEUE_BOUNCESZ 65536

+#ifdef CONFIG_MMC_BLOCK_BOUNCE
+unsigned mmc_queue_bouncesz = MMC_QUEUE_BOUNCESZ;
+#endif
+
 #define MMC_QUEUE_SUSPENDED(1  0)

 /*
@@ -188,7 +192,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card 
*card,
if (host-max_segs == 1) {
unsigned int bouncesz;

-   bouncesz = MMC_QUEUE_BOUNCESZ;
+   bouncesz = mmc_queue_bouncesz;

if (bouncesz  host-max_req_size)
bouncesz = host-max_req_size;
@@ -332,6 +336,102 @@ void mmc_cleanup_queue(struct mmc_queue *mq)
 EXPORT_SYMBOL(mmc_cleanup_queue);

 /**
+ * mmc_reinit_bounce_queue - re-initialise a bounce buffer.
+ * @mq: mmc queue
+ * @card: mmc card to attach this queue
+ * @bouncesz: the bounce size that need re-initializing
+ *
+ * Initialise a MMC card request queue

[PATCH RESEND 2/2] mmc/doc: feature description of runtime bounce buffer size adjustment

2012-08-08 Thread Qiang Liu
Add feature description of attribute bounce buffer size.

Cc: Chris Ball c...@laptop.org
Cc: Rob Landley r...@landley.net
Signed-off-by: Qiang Liu qiang@freescale.com
---
 Documentation/mmc/mmc-dev-attrs.txt |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/Documentation/mmc/mmc-dev-attrs.txt 
b/Documentation/mmc/mmc-dev-attrs.txt
index 22ae844..8299433 100644
--- a/Documentation/mmc/mmc-dev-attrs.txt
+++ b/Documentation/mmc/mmc-dev-attrs.txt
@@ -7,6 +7,8 @@ SD or MMC device.
 The following attributes are read/write.

force_roEnforce read-only access even if write protect 
switch is off.
+   bounceszSupport dynamic adjustment of bounce buffer 
size at runtime,
+   from 4K to 4M, integer multiple of 512 bytes 
only.

 SD and MMC Device Attributes
 
--
1.7.5.1


--
To unsubscribe from this list: send the line unsubscribe linux-mmc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V2 1/2] SD/MMC: add an interface to re-initialize bounce buffer

2011-12-20 Thread Qiang Liu
Add bounce_size under /sys/block/mmcblk0/bouncesz.
Support dynamic adjustment of bounce buffer in run-time (include mounted or
unmounted filesystem).

/sys/block/mmcblk0/bouncesz should be integer multiple of 512, the
value should be range from 4096 to 4194304.

1. use variable instead of MMC_QUEUE_BOUNCESZ;
2. Re-initialize bounce buffer accorinding to new bounce size at run-time;

Signed-off-by: Qiang Liu qiang@freescale.com
---
changes for V2
merge former 2 patches to 1

Here is the test results with different mmc bounce size, IOzone is used to
test performance of mass data transmission.
Environment:
PowerPC P1022DS platform, Sandisk Class 10, 4G memory card, EXT4 filesystem
[root@p2020ds root]# cat /sys/fs/   block/mmcblk0/bouncesz
65536
[root@p2020ds root]# mount /dev/mmcblk0p1 /mnt/
EXT4-fs (mmcblk0p1): mounted filesystem without journal. Opts:
[root@p2020ds root]# iozone -Rab result -i0 -i1 -r64 =-  -n1g -g4g -f /mnt/ff

  KB  reclen   write rewritereadreread
 1048576  64   14229   13286   662028   663372
 2097152  64   13758   126054954947443
 4194304  64   13435   122152197422096

[root@p2020ds root]# echo 262144  /sys/block/mmcblk0/bouncesz
[root@p2020ds root]# cat /sys/block/mmcblk0/bouncesz
262144
[root@p2020ds root]# iozone -Rab result -i0 -i1 -r64 -n1g -g4g -f /mnt/ff

  KB  reclen   write rewritereadreread
 1048576  64   19228   19416   676659   677785
 2097152  64   18512   184992697827055
 4194304  64   17932   181852194521805

[root@p2020ds root]# echo 8192  /sys/block/mmcblk0/bouncesz
[root@p2020ds root]# cat /sys/block/mmcblk0/bouncesz
8192
[root@p2020ds root]# iozone -Rab result -i0 -i1 -r64 -n1g -g1g -f /mnt/ff
  KB  reclen   write rewritereadreread
 1048576  6450683324   640266   641609
---
 drivers/mmc/card/block.c |   43 +++
 drivers/mmc/card/queue.c |  102 +-
 drivers/mmc/card/queue.h |6 +++
 3 files changed, 149 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 0c959c9..790abe2 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -59,6 +59,9 @@ MODULE_ALIAS(mmc:block);
 #define INAND_CMD38_ARG_SECTRIM1 0x81
 #define INAND_CMD38_ARG_SECTRIM2 0x88

+#define MMC_MIN_QUEUE_BOUNCESZ 4096
+#define MMC_MAX_QUEUE_BOUNCESZ 4194304
+
 static DEFINE_MUTEX(block_mutex);

 /*
@@ -108,6 +111,7 @@ struct mmc_blk_data {
unsigned intpart_curr;
struct device_attribute force_ro;
struct device_attribute power_ro_lock;
+   struct device_attribute bouncesz;
int area_type;
 };

@@ -1633,6 +1637,7 @@ static void mmc_blk_remove_req(struct mmc_blk_data *md)
del_gendisk(md-disk);
}

+   device_remove_file(disk_to_dev(md-disk), md-bouncesz);
/* Then flush out any already in there */
mmc_cleanup_queue(md-queue);
mmc_blk_put(md);
@@ -1739,6 +1744,33 @@ static const struct mmc_fixup blk_fixups[] =
END_FIXUP
 };

+#ifdef CONFIG_MMC_BLOCK_BOUNCE
+static ssize_t mmc_bouncesz_show(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+return sprintf(buf, %u\n, mmc_queue_bouncesz);
+}
+
+static ssize_t mmc_bouncesz_store(struct device *dev,
+   struct device_attribute *attr,
+   const char *buf, size_t count)
+{
+   unsigned int bouncesz;
+   struct mmc_blk_data *md;
+
+   if ((sscanf(buf, %d, bouncesz) != 1) ||
+   (bouncesz  MMC_MIN_QUEUE_BOUNCESZ) ||
+   (bouncesz  MMC_MAX_QUEUE_BOUNCESZ) ||
+   (bouncesz % 512 != 0))
+   return -EINVAL;
+
+   md = mmc_blk_get(dev_to_disk(dev));
+   mmc_reinit_bounce_queue(md-queue, md-queue.card, bouncesz);
+   mmc_blk_put(md);
+   return mmc_queue_bouncesz;
+}
+#endif
+
 static int mmc_blk_probe(struct mmc_card *card)
 {
struct mmc_blk_data *md, *part_md;
@@ -1771,6 +1803,17 @@ static int mmc_blk_probe(struct mmc_card *card)
mmc_set_drvdata(card, md);
mmc_fixup_device(card, blk_fixups);

+#ifdef CONFIG_MMC_BLOCK_BOUNCE
+   md-bouncesz.show = mmc_bouncesz_show;
+   md-bouncesz.store = mmc_bouncesz_store;
+   sysfs_attr_init(md-bouncesz.attr);
+   md-bouncesz.attr.name = bouncesz;
+   md-bouncesz.attr.mode = S_IRUGO | S_IWUSR;
+   err = device_create_file(disk_to_dev(md-disk), md-bouncesz);
+   if (err)
+   goto out;
+#endif
+
if (mmc_add_disk(md))
goto out;

diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index dcad59c..c563e33 100644

[PATCH V2 2/2] mmc/doc: feature description of runtime bounce buffer size adjustment

2011-12-20 Thread Qiang Liu
Add feature description about runtime bounce buffer size adjustment.

CC: Chris Ball c...@laptop.org
Signed-off-by: Qiang Liu qiang@freescale.com
---
changes for V2
add suplementary description of bouncesz limitation

 Documentation/mmc/mmc-dev-attrs.txt |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/Documentation/mmc/mmc-dev-attrs.txt 
b/Documentation/mmc/mmc-dev-attrs.txt
index 22ae844..1314cab 100644
--- a/Documentation/mmc/mmc-dev-attrs.txt
+++ b/Documentation/mmc/mmc-dev-attrs.txt
@@ -7,6 +7,8 @@ SD or MMC device.
 The following attributes are read/write.

force_roEnforce read-only access even if write protect 
switch is off.
+   bounceszSupport dynamic adjustment of bounce buffer 
size at runtime,
+   from 4096 to 4194304, integer multiple of 512 
bytes only.

 SD and MMC Device Attributes
 
--
1.6.4


--
To unsubscribe from this list: send the line unsubscribe linux-mmc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] mmc/doc: feature description of runtime bounce buffer size adjustment

2011-12-01 Thread Qiang Liu
Add feature description about runtime bounce buffer size adjustment.

CC: Chris Ball c...@laptop.org
Signed-off-by: Qiang Liu qiang@freescale.com
---
Per Chris's request add description in mmc document.

 Documentation/mmc/mmc-dev-attrs.txt |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/Documentation/mmc/mmc-dev-attrs.txt 
b/Documentation/mmc/mmc-dev-attrs.txt
index 8898a95..5e1f47b 100644
--- a/Documentation/mmc/mmc-dev-attrs.txt
+++ b/Documentation/mmc/mmc-dev-attrs.txt
@@ -7,6 +7,8 @@ SD or MMC device.
 The following attributes are read/write.

force_roEnforce read-only access even if write protect 
switch is off.
+   bounceszSupport dynamic adjustment of bounce buffer 
size at runtime,
+   from 4096 to 4194304 only.

 SD and MMC Device Attributes
 
--
1.6.4


--
To unsubscribe from this list: send the line unsubscribe linux-mmc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] SD/MMC: add support of adjust bounce size at run-time

2011-11-23 Thread Qiang Liu
Add bounce_size under /sys/block/mmcblk0/bouncesz.
Support dynamic adjustment of bounce buffer in run-time (include mounted or
unmounted filesystem).

/sys/block/mmcblk0/bouncesz should be integer multiple of 512, the
value should be range from 4096 to 4194304.

Signed-off-by: Qiang Liu qiang@freescale.com
---
 drivers/mmc/card/block.c |   44 
 1 files changed, 44 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index a1cb21f..649bfed 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -59,6 +59,9 @@ MODULE_ALIAS(mmc:block);
 #define INAND_CMD38_ARG_SECTRIM1 0x81
 #define INAND_CMD38_ARG_SECTRIM2 0x88

+#define MMC_MIN_QUEUE_BOUNCESZ 4096
+#define MMC_MAX_QUEUE_BOUNCESZ 4194304
+
 static DEFINE_MUTEX(block_mutex);

 /*
@@ -107,6 +110,7 @@ struct mmc_blk_data {
 */
unsigned intpart_curr;
struct device_attribute force_ro;
+   struct device_attribute bouncesz;
 };

 static DEFINE_MUTEX(open_lock);
@@ -1547,6 +1551,7 @@ static void mmc_blk_remove_req(struct mmc_blk_data *md)
del_gendisk(md-disk);
}

+   device_remove_file(disk_to_dev(md-disk), md-bouncesz);
/* Then flush out any already in there */
mmc_cleanup_queue(md-queue);
mmc_blk_put(md);
@@ -1609,6 +1614,33 @@ static const struct mmc_fixup blk_fixups[] =
END_FIXUP
 };

+#ifdef CONFIG_MMC_BLOCK_BOUNCE
+static ssize_t mmc_bouncesz_show(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+return sprintf(buf, %u\n, mmc_queue_bouncesz);
+}
+
+static ssize_t mmc_bouncesz_store(struct device *dev,
+   struct device_attribute *attr,
+   const char *buf, size_t count)
+{
+   unsigned int bouncesz;
+   struct mmc_blk_data *md;
+
+   if ((sscanf(buf, %d, bouncesz) != 1) ||
+   (bouncesz  MMC_MIN_QUEUE_BOUNCESZ) ||
+   (bouncesz  MMC_MAX_QUEUE_BOUNCESZ) ||
+   (bouncesz % 512 != 0))
+   return -EINVAL;
+
+   md = mmc_blk_get(dev_to_disk(dev));
+   mmc_reinit_bounce_queue(md-queue, md-queue.card, bouncesz);
+   mmc_blk_put(md);
+   return mmc_queue_bouncesz;
+}
+#endif
+
 static int mmc_blk_probe(struct mmc_card *card)
 {
struct mmc_blk_data *md, *part_md;
@@ -1648,6 +1680,18 @@ static int mmc_blk_probe(struct mmc_card *card)
if (mmc_add_disk(part_md))
goto out;
}
+
+#ifdef CONFIG_MMC_BLOCK_BOUNCE
+   md-bouncesz.show = mmc_bouncesz_show;
+   md-bouncesz.store = mmc_bouncesz_store;
+   sysfs_attr_init(md-bouncesz.attr);
+   md-bouncesz.attr.name = bouncesz;
+   md-bouncesz.attr.mode = S_IRUGO | S_IWUSR;
+   err = device_create_file(disk_to_dev(md-disk), md-bouncesz);
+   if (err)
+   goto out;
+#endif
+
return 0;

  out:
--
1.6.4


--
To unsubscribe from this list: send the line unsubscribe linux-mmc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] SD/MMC: add an interface to re-initialize bounce buffer

2011-11-23 Thread Qiang Liu
1. use variable instead of MMC_QUEUE_BOUNCESZ;
2. Re-initialize bounce buffer accorinding to new bounce size at run-time;

Signed-off-by: Qiang Liu qiang@freescale.com
---
Here is the test results with different mmc bounce size, IOzone is used to
test performance of mass data transmission.
Environment:
PowerPC P1022DS platform, Sandisk Class 10, 4G memory card, EXT4 filesystem
[root@p2020ds root]# cat /sys/fs/   block/mmcblk0/bouncesz
65536
[root@p2020ds root]# mount /dev/mmcblk0p1 /mnt/
EXT4-fs (mmcblk0p1): mounted filesystem without journal. Opts: 
[root@p2020ds root]# iozone -Rab result -i0 -i1 -r64 =-  -n1g -g4g -f /mnt/ff

  KB  reclen   write rewritereadreread
 1048576  64   14229   13286   662028   663372
 2097152  64   13758   126054954947443
 4194304  64   13435   122152197422096

[root@p2020ds root]# echo 262144  /sys/block/mmcblk0/bouncesz
[root@p2020ds root]# cat /sys/block/mmcblk0/bouncesz
262144
[root@p2020ds root]# iozone -Rab result -i0 -i1 -r64 -n1g -g4g -f /mnt/ff

  KB  reclen   write rewritereadreread
 1048576  64   19228   19416   676659   677785
 2097152  64   18512   184992697827055
 4194304  64   17932   181852194521805

[root@p2020ds root]# echo 8192  /sys/block/mmcblk0/bouncesz
[root@p2020ds root]# cat /sys/block/mmcblk0/bouncesz
8192
[root@p2020ds root]# iozone -Rab result -i0 -i1 -r64 -n1g -g1g -f /mnt/ff
  KB  reclen   write rewritereadreread
 1048576  6450683324   640266   641609
---
 drivers/mmc/card/queue.c |  102 +-
 drivers/mmc/card/queue.h |6 +++
 2 files changed, 106 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index dcad59c..c563e33 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -21,7 +21,9 @@
 #include queue.h

 #define MMC_QUEUE_BOUNCESZ 65536
-
+#ifdef CONFIG_MMC_BLOCK_BOUNCE
+unsigned mmc_queue_bouncesz = MMC_QUEUE_BOUNCESZ;
+#endif
 #define MMC_QUEUE_SUSPENDED(1  0)

 /*
@@ -185,7 +187,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card 
*card,
if (host-max_segs == 1) {
unsigned int bouncesz;

-   bouncesz = MMC_QUEUE_BOUNCESZ;
+   bouncesz = mmc_queue_bouncesz;

if (bouncesz  host-max_req_size)
bouncesz = host-max_req_size;
@@ -329,6 +331,102 @@ void mmc_cleanup_queue(struct mmc_queue *mq)
 EXPORT_SYMBOL(mmc_cleanup_queue);

 /**
+ * mmc_reinit_bounce_queue - re-initialise a bounce buffer.
+ * @mq: mmc queue
+ * @card: mmc card to attach this queue
+ * @bouncesz: the bounce size that need re-initializing
+ *
+ * Initialise a MMC card request queue.
+ */
+#ifdef CONFIG_MMC_BLOCK_BOUNCE
+int mmc_reinit_bounce_queue(struct mmc_queue *mq, struct mmc_card *card,
+  unsigned int bouncesz)
+{
+   struct mmc_host *host = card-host;
+   struct mmc_queue_req *mqrq_cur = mq-mqrq[0];
+   struct mmc_queue_req *mqrq_prev = mq-mqrq[1];
+   int ret;
+   struct scatterlist *curr_bounce_sg, *prev_bounce_sg;
+   char *curr_bounce_buf, *prev_bounce_buf;
+
+   mmc_claim_host(card-host);
+
+   bouncesz = min(bouncesz, host-max_req_size);
+   bouncesz = min(bouncesz, host-max_seg_size);
+   bouncesz = min(bouncesz, host-max_blk_count * 512);
+
+   /* store current using addr of bounce_buf and bounce_sg */
+   curr_bounce_sg = mqrq_cur-bounce_sg;
+   prev_bounce_sg = mqrq_prev-bounce_sg;
+   curr_bounce_buf = mqrq_cur-bounce_buf;
+   prev_bounce_buf = mqrq_prev-bounce_buf;
+
+   if (host-max_segs != 1)
+   goto restore_queue;
+
+   /* realloc bounce queue use given bounce size */
+   mqrq_cur-bounce_buf = kmalloc(bouncesz, GFP_KERNEL);
+   if (!mqrq_cur-bounce_buf) {
+   printk(KERN_WARNING %s: unable to 
+   allocate bounce cur buffer\n,
+   mmc_card_name(card));
+   ret = -ENOMEM;
+   goto restore_queue;
+   }
+
+   mqrq_prev-bounce_buf = kmalloc(bouncesz, GFP_KERNEL);
+   if (!mqrq_prev-bounce_buf) {
+   printk(KERN_WARNING %s: unable to 
+   allocate bounce prev buffer\n,
+   mmc_card_name(card));
+   kfree(mqrq_cur-bounce_buf);
+   mqrq_cur-bounce_buf = NULL;
+   ret = -ENOMEM;
+   goto restore_queue;
+   }
+
+   mqrq_cur-bounce_sg =
+   mmc_alloc_sg(bouncesz / 512, ret);
+   if (ret)
+   goto cleanup_queue;
+
+   mqrq_prev-bounce_sg =
+   mmc_alloc_sg(bouncesz / 512, ret);
+   if (ret)
+   goto cleanup_queue

[PATCH] SD/MMC: fix the issue of SDHC performance regression

2011-11-07 Thread Qiang Liu
Low performance of SDHC (half of before) due to its frequency was set to 25MHz,
but not 50MHz (involved by commit id 013909c4ffd16ded4895528b856fd8782df04dc6,
add support for query function modes for uhs cards according to Physical Layer
SPEC V3.01).

Set high speed max frequency according to response status of CMD6, but
not for SPEC Version. Response of switch command is first consideration
factor when set SDHC max working frequency. TRAN_SPEED in CSD register
will be seemed as the second factor.

Signed-off-by: Qiang Liu qiang@freescale.com
---
 drivers/mmc/core/sd.c|6 +++---
 include/linux/mmc/card.h |3 +++
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index b33537f..5cdab7c 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -306,6 +306,9 @@ static int mmc_read_switch(struct mmc_card *card)
goto out;
}

+   if (status[13]  SD_MODE_HIGH_SPEED)
+   card-sw_caps.hs_max_dtr = HIGH_SPEED_MAX_DTR;
+
if (card-scr.sda_spec3) {
card-sw_caps.sd3_bus_mode = status[13];

@@ -348,9 +351,6 @@ static int mmc_read_switch(struct mmc_card *card)
}

card-sw_caps.sd3_curr_limit = status[7];
-   } else {
-   if (status[13]  0x02)
-   card-sw_caps.hs_max_dtr = 5000;
}

 out:
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 6ad4355..499a268 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -99,6 +99,7 @@ struct sd_ssr {
 struct sd_switch_caps {
unsigned inths_max_dtr;
unsigned intuhs_max_dtr;
+#define HIGH_SPEED_MAX_DTR 5000
 #define UHS_SDR104_MAX_DTR 20800
 #define UHS_SDR50_MAX_DTR  1
 #define UHS_DDR50_MAX_DTR  5000
@@ -106,11 +107,13 @@ struct sd_switch_caps {
 #define UHS_SDR12_MAX_DTR  2500
unsigned intsd3_bus_mode;
 #define UHS_SDR12_BUS_SPEED0
+#define HIGH_SPEED_BUS_SPEED   1
 #define UHS_SDR25_BUS_SPEED1
 #define UHS_SDR50_BUS_SPEED2
 #define UHS_SDR104_BUS_SPEED   3
 #define UHS_DDR50_BUS_SPEED4

+#define SD_MODE_HIGH_SPEED (1  HIGH_SPEED_BUS_SPEED)
 #define SD_MODE_UHS_SDR12  (1  UHS_SDR12_BUS_SPEED)
 #define SD_MODE_UHS_SDR25  (1  UHS_SDR25_BUS_SPEED)
 #define SD_MODE_UHS_SDR50  (1  UHS_SDR50_BUS_SPEED)
--
1.6.4


--
To unsubscribe from this list: send the line unsubscribe linux-mmc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [RFC/PATCH] SD/MMC: support adjust bounce buffer size dynamically in menuconfig

2011-11-04 Thread Qiang Liu
Improve IO throughput according to different controllers.
Make it configuable in menuconfig. Of course, there is another
implement of adjust bounce buffer size at run-time. Like:
echo 262144  /sys/block/mmcblk0/device/bouncesz
This will reinit mmc queue when bounce size is changed.
Which is better?

On powerpc platform, 256KiB will get better perfromance than 64KiB.
I used Sandisk Extreme III Class 6, 4G memory card, tested on P1022DS
with IOzone. P1022DS memory is 1GBytes. Filesystem is ext4.
By default, bounce buffer size is 64KiB,
[root@p1022ds root]# iozone -Rab result -i0 -i1 -r64 -n1g -g2g -f /mnt/ff
 KB  reclen   write rewritereadreread
1048576  64   12794   132603233031731
2097152  64   12301   123821821318239
use 256KiB as bounce buffer size,
[root@p1022ds root]# iozone -Rab result -i0 -i1 -r64 -n1g -g2g -f /mnt/ff
 KB  reclen   write rewritereadreread
1048576  64   18533   190762284123151
2097152  64   17744   179801833318342

Signed-off-by: Qiang Liu qiang@freescale.com
---
 drivers/mmc/card/Kconfig |9 +
 drivers/mmc/card/queue.c |2 +-
 2 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig
index 3b1f783..3390154 100644
--- a/drivers/mmc/card/Kconfig
+++ b/drivers/mmc/card/Kconfig
@@ -50,6 +50,15 @@ config MMC_BLOCK_BOUNCE

  If unsure, say Y here.

+config MMC_QUEUE_BOUNCESZ
+   int MMC memory card bounce buffer size
+   depends on MMC_BLOCK_BOUNCE
+   range 512 4194304
+   default 65536
+   help
+ Provide a flexible method to adjust bounce buffer size to
+ improve the throughput according to different controller.
+
 config SDIO_UART
tristate SDIO UART/GPS class support
help
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index dcad59c..590723f 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -20,7 +20,7 @@
 #include linux/mmc/host.h
 #include queue.h

-#define MMC_QUEUE_BOUNCESZ 65536
+#define MMC_QUEUE_BOUNCESZ CONFIG_MMC_QUEUE_BOUNCESZ

 #define MMC_QUEUE_SUSPENDED(1  0)

--
1.6.4


--
To unsubscribe from this list: send the line unsubscribe linux-mmc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html