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

2012-01-16 Thread Liu Qiang-B32616
Hi Chris,

Do you have any concerns about this patch? Or another advice?
Thanks.


-Original Message-
From: Liu Qiang-B32616
Sent: Wednesday, December 21, 2011 3:10 PM
To: c...@laptop.org; linux-mmc@vger.kernel.org
Cc: Li Yang-R58472; Liu Qiang-B32616; Liu Qiang-B32616
Subject: [PATCH V2 1/2] SD/MMC: add an interface to re-initialize bounce buffer

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

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

2012-01-16 Thread Liu Qiang-B32616
Hi Chris,

Is the description OK? Thanks.


From: Liu Qiang-B32616
Sent: Wednesday, December 21, 2011 1:10 AM
To: c...@laptop.org; linux-mmc@vger.kernel.org
Cc: Li Yang-R58472; Liu Qiang-B32616; Liu Qiang-B32616
Subject: [PATCH V2 2/2] mmc/doc: feature description of runtime bounce buffer 
size adjustment

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


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

2011-12-25 Thread Liu Qiang-B32616
Hi Chris,

Happy holidays!
How about this patch? And [PATCH V2 2/2] mmc/doc: feature description of
runtime bounce buffer size adjustment? I add the description in 
Documents/mmc/mmc-dev-attrs.txt
according to your suggestion.

Thanks for your reply.



-Original Message-
From: Liu Qiang-B32616 
Sent: Wednesday, December 21, 2011 3:10 PM
To: c...@laptop.org; linux-mmc@vger.kernel.org
Cc: Li Yang-R58472; Liu Qiang-B32616; Liu Qiang-B32616
Subject: [PATCH V2 1/2] SD/MMC: add an interface to re-initialize bounce buffer

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

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

2011-11-27 Thread Liu Qiang-B32616
Hi Chris,

What's your opinion about this patch?
I changed to adjust bounce size at run time through
echo /sys/block/mmcblk0/bouncesz.
Thanks.


-Original Message-
From: Liu Qiang-B32616 
Sent: Thursday, November 24, 2011 11:06 AM
To: c...@laptop.org; linux-mmc@vger.kernel.org
Cc: Li Yang-R58472; Liu Qiang-B32616
Subject: [PATCH 1/2] SD/MMC: add an interface to re-initialize bounce buffer

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

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

2011-11-07 Thread Liu Qiang-B32616


-Original Message-
From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc-ow...@vger.kernel.org] 
On Behalf Of Chris Ball
Sent: Monday, November 07, 2011 9:20 PM
To: Liu Qiang-B32616
Cc: linux-mmc@vger.kernel.org; Li Yang-R58472; Gala Kumar-B11780
Subject: Re: [PATCH] SD/MMC: fix the issue of SDHC performance regression

Hi,

On Mon, Nov 07 2011, Qiang Liu wrote:
 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

Have you seen:

http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commitdiff;h=f2815f68dabbb373fd1c9f0fd4a609d486697c2b
(mmc: sd: Handle SD3.0 cards not supporting UHS-I bus speed mode)

which is already in mainline?  I think your patch is identical.
[Liu Qiang] Yes, they are identical. Thanks a lot.

Thanks,

- Chris.
-- 
Chris Ball   c...@laptop.org   http://printf.net/
One Laptop Per Child
--
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


--
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


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

2011-11-07 Thread Liu Qiang-B32616
Hi all,

What about this feature? Provide a method of adjust mmc bounce size through 
menuconfig
or /sys/block/mmcblk0 at run-time. Which one is better?

Do you have any ideas? Thanks for your advice.


From: Liu Qiang-B32616
Sent: Friday, November 04, 2011 4:54 AM
To: linux-mmc@vger.kernel.org
Cc: c...@laptop.org; Li Yang-R58472; Gala Kumar-B11780; Liu Qiang-B32616; Liu 
Qiang-B32616
Subject: [PATCH] [RFC/PATCH] SD/MMC: support adjust bounce buffer size 
dynamically in menuconfig

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