[PATCH v3] mtd: spinand: read return badly if the last page has bitflips

2019-06-27 Thread liaoweixiong
In case of the last page containing bitflips (ret > 0),
spinand_mtd_read() will return that number of bitflips for the last
page. But to me it looks like it should instead return max_bitflips like
it does when the last page read returns with 0.

Signed-off-by: Weixiong Liao 
Reviewed-by: Boris Brezillon 
Reviewed-by: Frieder Schrempf 
Cc: sta...@vger.kernel.org
Fixes: 7529df465248 ("mtd: nand: Add core infrastructure to support SPI NANDs")
---
Changes since v2:
- Resend this patch with Cc and Fixes tags.

Changes since v1:
- More accurate description for this patch
---

 drivers/mtd/nand/spi/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 556bfdb..6b9388d 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -511,12 +511,12 @@ static int spinand_mtd_read(struct mtd_info *mtd, loff_t 
from,
if (ret == -EBADMSG) {
ecc_failed = true;
mtd->ecc_stats.failed++;
-   ret = 0;
} else {
mtd->ecc_stats.corrected += ret;
max_bitflips = max_t(unsigned int, max_bitflips, ret);
}
 
+   ret = 0;
ops->retlen += iter.req.datalen;
ops->oobretlen += iter.req.ooblen;
}
-- 
1.9.1



Re: [RESEND PATCH v2] mtd: spinand: read return badly if the last page has bitflips

2019-06-27 Thread liaoweixiong
Hi Miquel,

On 2019/6/28 AM2:17, Miquel Raynal wrote:
> Hi Miquel,
> 
> Miquel Raynal  wrote on Thu, 27 Jun 2019
> 19:06:44 +0200:
> 
>> Hello,
>>
>> Schrempf Frieder  wrote on Tue, 25 Jun
>> 2019 07:04:06 +:
>>
>>> Hi liaoweixiong,
>>>
>>> On 25.06.19 05:08, Greg KH wrote:  
>>>> On Tue, Jun 25, 2019 at 09:02:29AM +0800, liaoweixiong wrote:
>>>>> In case of the last page containing bitflips (ret > 0),
>>>>> spinand_mtd_read() will return that number of bitflips for the last
>>>>> page. But to me it looks like it should instead return max_bitflips like
>>>>> it does when the last page read returns with 0.
>>>>>
>>>>> Signed-off-by: liaoweixiong   
>>
>> Please write your entire official first/last name(s)
>>

OK.

>>>>> Reviewed-by: Boris Brezillon 
>>>>> Reviewed-by: Frieder Schrempf   
>>
>> I am waiting your next version with Acked-by instead of Rewieved-by
>> tags and Greg's comment addressed.
> 
> Sorry for the mistake, R-b tags are fine here, don't touch that.
> The rest needs to be fixed though.
> 

OK.

>>>>> Fixes: 7529df465248 ("mtd: nand: Add core infrastructure to support SPI 
>>>>> NANDs")  
>>
>> Finally, when we ask you to resend a patch, it means sending a new
>> version of the patch. So in the subject, you should not use the
>> [RESEND] keyword (which means you are sending something again exactly
>> as it was before, you just got ignored, for example) but instead you
>> should increment the version number (v3) and also write a nice
>> changelog after the three dashes '---' (will be ignored by Git when
>> applying).
>>
>> I would like to queue this for the next release so if you can do it
>> ASAP, that would be great.
>>

I will do it right now.

>> Thank you,
>> Miquèl
> 
> 
> 
> 
> Thanks,
> Miquèl
> 

-- 
liaoweixiong


[RESEND PATCH v2] mtd: spinand: read return badly if the last page has bitflips

2019-06-25 Thread liaoweixiong
In case of the last page containing bitflips (ret > 0),
spinand_mtd_read() will return that number of bitflips for the last
page. But to me it looks like it should instead return max_bitflips like
it does when the last page read returns with 0.

Signed-off-by: liaoweixiong 
Reviewed-by: Boris Brezillon 
Reviewed-by: Frieder Schrempf 
Cc: sta...@vger.kernel.org
Fixes: 7529df465248 ("mtd: nand: Add core infrastructure to support SPI NANDs")
---
 drivers/mtd/nand/spi/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 556bfdb..6b9388d 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -511,12 +511,12 @@ static int spinand_mtd_read(struct mtd_info *mtd, loff_t 
from,
if (ret == -EBADMSG) {
ecc_failed = true;
mtd->ecc_stats.failed++;
-   ret = 0;
} else {
mtd->ecc_stats.corrected += ret;
max_bitflips = max_t(unsigned int, max_bitflips, ret);
}
 
+   ret = 0;
ops->retlen += iter.req.datalen;
ops->oobretlen += iter.req.ooblen;
}
-- 
1.9.1



Re: [RESEND PATCH v2] mtd: spinand: read return badly if the last page has bitflips

2019-06-25 Thread liaoweixiong
Oh, i am sorry that i had misunderstanded your letter.
Thank you for your document and guidance.

On 2019/6/25 PM 3:04, Schrempf Frieder wrote:
> Hi liaoweixiong,
> 
> On 25.06.19 05:08, Greg KH wrote:
>> On Tue, Jun 25, 2019 at 09:02:29AM +0800, liaoweixiong wrote:
>>> In case of the last page containing bitflips (ret > 0),
>>> spinand_mtd_read() will return that number of bitflips for the last
>>> page. But to me it looks like it should instead return max_bitflips like
>>> it does when the last page read returns with 0.
>>>
>>> Signed-off-by: liaoweixiong 
>>> Reviewed-by: Boris Brezillon 
>>> Reviewed-by: Frieder Schrempf 
>>> Fixes: 7529df465248 ("mtd: nand: Add core infrastructure to support SPI 
>>> NANDs")
>>> ---
>>>   drivers/mtd/nand/spi/core.c | 2 +-
>>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> 
>>
>> This is not the correct way to submit patches for inclusion in the
>> stable kernel tree.  Please read:
>>  https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html
>> for how to do this properly.
>>
>> 
> 
> FYI, you should not send the patch to sta...@vger.kernel.org, but 
> instead, as I said in my other reply, add the tag "Cc: 
> sta...@vger.kernel.org". See "Option 1" in the document Greg referred to.
> 
> Thanks,
> Frieder
> 

-- 
liaoweixiong


[RESEND PATCH v2] mtd: spinand: read return badly if the last page has bitflips

2019-06-24 Thread liaoweixiong
In case of the last page containing bitflips (ret > 0),
spinand_mtd_read() will return that number of bitflips for the last
page. But to me it looks like it should instead return max_bitflips like
it does when the last page read returns with 0.

Signed-off-by: liaoweixiong 
Reviewed-by: Boris Brezillon 
Reviewed-by: Frieder Schrempf 
Fixes: 7529df465248 ("mtd: nand: Add core infrastructure to support SPI NANDs")
---
 drivers/mtd/nand/spi/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 556bfdb..6b9388d 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -511,12 +511,12 @@ static int spinand_mtd_read(struct mtd_info *mtd, loff_t 
from,
if (ret == -EBADMSG) {
ecc_failed = true;
mtd->ecc_stats.failed++;
-   ret = 0;
} else {
mtd->ecc_stats.corrected += ret;
max_bitflips = max_t(unsigned int, max_bitflips, ret);
}
 
+   ret = 0;
ops->retlen += iter.req.datalen;
ops->oobretlen += iter.req.ooblen;
}
-- 
1.9.1



Re: [RESEND PATCH v2] mtd: spinand: read return badly if the last page has bitflips

2019-06-24 Thread liaoweixiong
Um.. I am sorry. It is the first time for me to resend patch.
I will send this patch again with correct tags.

On 2019/6/24 PM10:47, Schrempf Frieder wrote:
> On 24.06.19 14:15, liaoweixiong wrote:
>> In case of the last page containing bitflips (ret > 0),
>> spinand_mtd_read() will return that number of bitflips for the last
>> page. But to me it looks like it should instead return max_bitflips like
>> it does when the last page read returns with 0.
>>
>> Signed-off-by: liaoweixiong 
>> Acked-by: Boris Brezillon 
>> Acked-by: Frieder Schrempf 
> 
> Why did you change our Reviewed-by tags to Acked-by tags?
> 
>> Fixes: 7529df465248 ("mtd: nand: Add core infrastructure to support SPI 
>> NANDs")
>> ---
>>   drivers/mtd/nand/spi/core.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
>> index 556bfdb..6b9388d 100644
>> --- a/drivers/mtd/nand/spi/core.c
>> +++ b/drivers/mtd/nand/spi/core.c
>> @@ -511,12 +511,12 @@ static int spinand_mtd_read(struct mtd_info *mtd, 
>> loff_t from,
>>  if (ret == -EBADMSG) {
>>  ecc_failed = true;
>>  mtd->ecc_stats.failed++;
>> -ret = 0;
>>  } else {
>>  mtd->ecc_stats.corrected += ret;
>>  max_bitflips = max_t(unsigned int, max_bitflips, ret);
>>  }
>>   
>> +ret = 0;
>>  ops->retlen += iter.req.datalen;
>>  ops->oobretlen += iter.req.ooblen;
>>  }

-- 
liaoweixiong


[RESEND PATCH v2] mtd: spinand: read return badly if the last page has bitflips

2019-06-24 Thread liaoweixiong
In case of the last page containing bitflips (ret > 0),
spinand_mtd_read() will return that number of bitflips for the last
page. But to me it looks like it should instead return max_bitflips like
it does when the last page read returns with 0.

Signed-off-by: liaoweixiong 
Acked-by: Boris Brezillon 
Acked-by: Frieder Schrempf 
Fixes: 7529df465248 ("mtd: nand: Add core infrastructure to support SPI NANDs")
---
 drivers/mtd/nand/spi/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 556bfdb..6b9388d 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -511,12 +511,12 @@ static int spinand_mtd_read(struct mtd_info *mtd, loff_t 
from,
if (ret == -EBADMSG) {
ecc_failed = true;
mtd->ecc_stats.failed++;
-   ret = 0;
} else {
mtd->ecc_stats.corrected += ret;
max_bitflips = max_t(unsigned int, max_bitflips, ret);
}
 
+   ret = 0;
ops->retlen += iter.req.datalen;
ops->oobretlen += iter.req.ooblen;
}
-- 
1.9.1



Re: [PATCH v2] mtd: spinand: read return badly if the last page has bitflips

2019-06-24 Thread liaoweixiong
OK, thanks for your reviewing. I will resend right now.

On 2019/6/24 PM3:37, Schrempf Frieder wrote:
> On 20.06.19 03:00, liaoweixiong wrote:
>> In case of the last page containing bitflips (ret > 0),
>> spinand_mtd_read() will return that number of bitflips for the last
>> page. But to me it looks like it should instead return max_bitflips like
>> it does when the last page read returns with 0.
>>
>> Signed-off-by: liaoweixiong 
> 
> Reviewed-by: Frieder Schrempf 
> 
> This should probably be resent with the following tags:
> 
> Cc: sta...@vger.kernel.org
> Fixes: 7529df465248 ("mtd: nand: Add core infrastructure to support SPI 
> NANDs")
> 
>> ---
>>   drivers/mtd/nand/spi/core.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
>> index 556bfdb..6b9388d 100644
>> --- a/drivers/mtd/nand/spi/core.c
>> +++ b/drivers/mtd/nand/spi/core.c
>> @@ -511,12 +511,12 @@ static int spinand_mtd_read(struct mtd_info *mtd, 
>> loff_t from,
>>  if (ret == -EBADMSG) {
>>  ecc_failed = true;
>>  mtd->ecc_stats.failed++;
>> -ret = 0;
>>  } else {
>>  mtd->ecc_stats.corrected += ret;
>>  max_bitflips = max_t(unsigned int, max_bitflips, ret);
>>  }
>>   
>> +ret = 0;
>>  ops->retlen += iter.req.datalen;
>>  ops->oobretlen += iter.req.ooblen;
>>  }

-- 
liaoweixiong


[PATCH v2] mtd: spinand: read return badly if the last page has bitflips

2019-06-19 Thread liaoweixiong
In case of the last page containing bitflips (ret > 0),
spinand_mtd_read() will return that number of bitflips for the last
page. But to me it looks like it should instead return max_bitflips like
it does when the last page read returns with 0.

Signed-off-by: liaoweixiong 
---
 drivers/mtd/nand/spi/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 556bfdb..6b9388d 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -511,12 +511,12 @@ static int spinand_mtd_read(struct mtd_info *mtd, loff_t 
from,
if (ret == -EBADMSG) {
ecc_failed = true;
mtd->ecc_stats.failed++;
-   ret = 0;
} else {
mtd->ecc_stats.corrected += ret;
max_bitflips = max_t(unsigned int, max_bitflips, ret);
}
 
+   ret = 0;
ops->retlen += iter.req.datalen;
ops->oobretlen += iter.req.ooblen;
}
-- 
1.9.1



Re: [PATCH] mtd: spinand: fix error read return value

2019-06-19 Thread liaoweixiong
hi Boris Brezillon,

Sure, i will adjust the commit message and send again right now.

On 2019/6/20 AM12:18, Boris Brezillon wrote:
> On Wed, 19 Jun 2019 14:02:14 +
> Schrempf Frieder  wrote:
> 
>> On 19.06.19 15:46, Boris Brezillon wrote:
>>> Hi liaoweixiong,
>>>
>>> On Wed, 19 Jun 2019 21:13:24 +0800
>>> liaoweixiong  wrote:
>>>   
>>>> In function spinand_mtd_read, if the last page to read occurs bitflip,
>>>> this function will return error value because veriable ret not equal to 0. 
>>>>  
>>>
>>> Actually, that's exactly what the MTD core expects (see [1]), so you're
>>> the one introducing a regression here.  
>>
>> To me it looks like the patch description is somewhat incorrect, but the 
>> fix itself looks okay, unless I'm getting it wrong.
>>
>> In case of the last page containing bitflips (ret > 0), 
>> spinand_mtd_read() will return that number of bitflips for the last 
>> page. But to me it looks like it should instead return max_bitflips like 
>> it does when the last page read returns with 0.
> 
> Oh, you're right. liaoweixiong, can you adjust the commit message
> accordingly?
> 
>>
>>>>
>>>> Signed-off-by: liaoweixiong 
>>>> ---
>>>>   drivers/mtd/nand/spi/core.c | 2 +-
>>>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
>>>> index 556bfdb..6b9388d 100644
>>>> --- a/drivers/mtd/nand/spi/core.c
>>>> +++ b/drivers/mtd/nand/spi/core.c
>>>> @@ -511,12 +511,12 @@ static int spinand_mtd_read(struct mtd_info *mtd, 
>>>> loff_t from,
>>>>if (ret == -EBADMSG) {
>>>>ecc_failed = true;
>>>>mtd->ecc_stats.failed++;
>>>> -  ret = 0;
>>>>} else {
>>>>mtd->ecc_stats.corrected += ret;
>>>>max_bitflips = max_t(unsigned int, max_bitflips, ret);
>>>>}
>>>>   
>>>> +  ret = 0;
>>>>ops->retlen += iter.req.datalen;
>>>>ops->oobretlen += iter.req.ooblen;
>>>>}  
>>>
>>> [1]https://elixir.bootlin.com/linux/latest/source/drivers/mtd/mtdcore.c#L1209
>>>
>>> __
>>> Linux MTD discussion mailing list
>>> http://lists.infradead.org/mailman/listinfo/linux-mtd/
>>>  

-- 
liaoweixiong


[PATCH] mtd: spinand: fix error read return value

2019-06-19 Thread liaoweixiong
In function spinand_mtd_read, if the last page to read occurs bitflip,
this function will return error value because veriable ret not equal to 0.

Signed-off-by: liaoweixiong 
---
 drivers/mtd/nand/spi/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 556bfdb..6b9388d 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -511,12 +511,12 @@ static int spinand_mtd_read(struct mtd_info *mtd, loff_t 
from,
if (ret == -EBADMSG) {
ecc_failed = true;
mtd->ecc_stats.failed++;
-   ret = 0;
} else {
mtd->ecc_stats.corrected += ret;
max_bitflips = max_t(unsigned int, max_bitflips, ret);
}
 
+   ret = 0;
ops->retlen += iter.req.datalen;
ops->oobretlen += iter.req.ooblen;
}
-- 
1.9.1



[PATCH v13 1/4] pstore/blk: new support logger for block devices

2019-03-06 Thread liaoweixiong
pstore_blk is similar to pstore_ram, but dump log to block devices
rather than persistent ram.

Why should we need pstore_blk?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fact, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

pstore_blk can only dump Oops/Panic log to block devices. It only
supports dmesg now. To make pstore_blk work, the block driver should
provide the block device and the read/write apis when on panic.

pstore_blk begins at 'blkz_register', by witch block device can register
a block device to pstore_blk. Then pstore_blk divide and manage the
block device as zones, which is similar to pstore_ram.

Recommend that, block driver register pstore_blk after block device is
ready.

pstore_blk works well on allwinner(sunxi) platform.

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig  |8 +
 fs/pstore/Makefile |3 +
 fs/pstore/blkzone.c| 1037 
 include/linux/pstore_blk.h |   80 
 4 files changed, 1128 insertions(+)
 create mode 100644 fs/pstore/blkzone.c
 create mode 100644 include/linux/pstore_blk.h

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index 8b3ba27..defcb75 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -152,3 +152,11 @@ config PSTORE_RAM
  "ramoops.ko".
 
  For more information, see Documentation/admin-guide/ramoops.rst.
+
+config PSTORE_BLK
+   tristate "Log panic/oops to a block device"
+   depends on PSTORE
+   depends on BLOCK
+   help
+ This enables panic and oops message to be logged to a block dev
+ where it can be read back at some later point.
diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
index 967b589..0ee2fc8 100644
--- a/fs/pstore/Makefile
+++ b/fs/pstore/Makefile
@@ -12,3 +12,6 @@ pstore-$(CONFIG_PSTORE_PMSG)  += pmsg.o
 
 ramoops-objs += ram.o ram_core.o
 obj-$(CONFIG_PSTORE_RAM)   += ramoops.o
+
+obj-$(CONFIG_PSTORE_BLK) += pstore_blk.o
+pstore_blk-y += blkzone.o
diff --git a/fs/pstore/blkzone.c b/fs/pstore/blkzone.c
new file mode 100644
index 000..5e28ac4
--- /dev/null
+++ b/fs/pstore/blkzone.c
@@ -0,0 +1,1037 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *
+ * blkzone.c: Block device Oops/Panic logger
+ *
+ * Copyright (C) 2019 liaoweixiong 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define MODNAME "pstore-blk"
+#define pr_fmt(fmt) MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define PSTORE_BLKDEV "/dev/pstore-blk"
+
+/**
+ * struct blkz_head - head of zone to flush to storage
+ *
+ * @sig: signature to indicate header (BLK_SIG xor BLKZONE-type value)
+ * @datalen: length of data in @data
+ * @data: zone data.
+ */
+struct blkz_buffer {
+#define BLK_SIG (0x43474244) /* DBGC */
+   uint32_t sig;
+   atomic_t datalen;
+   uint8_t data[];
+};
+
+/**
+ * struct blkz_dmesg_header: dmesg information
+ *
+ * @magic: magic num for dmesg header
+ * @time: trigger time
+ * @compressed: whether conpressed
+ * @count: oops/panic counter
+ * @reason: identify oops or panic
+ */
+struct blkz_dmesg_header {
+#define DMESG_HEADER_MAGIC 0x4dfc3ae5
+   uint32_t magic;
+   struct timespec64 time;
+   bool compressed;
+   uint32_t counter;
+   enum kmsg_dump_reason reason;
+   uint8_t data[0];
+};
+
+/**
+ * struct blkz_zone - zone information
+ * @off:
+ * zone offset of block device
+ * @type:
+ * frontent type for this zone
+ * @name:
+ * frontent name for this zone
+ * @buffer:
+ * pointer to data buffer managed by this zone
+ * @buffer_size:
+ * bytes in @buffer->data
+ * @should_recover:
+ * should recover from storage
+ * @dirty:
+ * mark whether the data in @buffer are dirty (not flush to storage yet)
+ */
+struct blkz_zone {
+   unsigned long off;
+   const char *name;
+   enum pstore_type_id type;
+
+   struct blkz_buffer *buffer;
+   size_t buffer_size;
+   bool should_recover;
+   atomic_t dirty;
+};
+
+struct blkz_context {
+   struct blkz_zone **dbzs;/* dmesg block zones */
+   unsigned int dmesg_max_cnt;
+   unsigned int

[PATCH v13 4/4] Documentation: pstore/blk: create document for pstore_blk

2019-03-06 Thread liaoweixiong
The document, at Documentation/admin-guide/pstore-block.rst,
tells user how to use pstore_blk and the attentions about panic
read/write

Signed-off-by: liaoweixiong 
---
 Documentation/admin-guide/pstore-block.rst | 233 +
 MAINTAINERS|   1 +
 fs/pstore/Kconfig  |   4 +
 3 files changed, 238 insertions(+)
 create mode 100644 Documentation/admin-guide/pstore-block.rst

diff --git a/Documentation/admin-guide/pstore-block.rst 
b/Documentation/admin-guide/pstore-block.rst
new file mode 100644
index 000..c22245d
--- /dev/null
+++ b/Documentation/admin-guide/pstore-block.rst
@@ -0,0 +1,233 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Pstore block oops/panic logger
+==
+
+Introduction
+
+
+Pstore block (pstore_blk) is an oops/panic logger that write its logs to a 
block
+device before the system crashes. Pstore_blk needs the block device driver
+to register a partition of the block device, like /dev/mmcblk0p7 for MMC
+driver, and read/write APIs for this partition when on panic.
+
+Pstore block concepts
+-
+
+Pstore block begins at function ``blkz_register``, by which a block driver
+registers to pstore_blk. Note that the block driver should register to
+pstore_blk after block device has registered. The Block driver transfers a
+structure ``blkz_info`` which is defined in *linux/pstore_blk.h*.
+
+The following key members of ``struct blkz_info`` may be of interest to you.
+
+blkdev
+~~
+
+The block device to use. Most of the time, it is a partition of block device.
+It's ok to keep it as NULL if you are passing ``read`` and ``write`` in
+blkz_info as ``blkdev`` is used by blkz_default_general_read/write. If both of
+``blkdev``, ``read`` and ``write`` are NULL, no block device is effective and
+the data will only be saved in RAM.
+
+It accept the following variants:
+
+1.  device number in hexadecimal represents itself; no
+   leading 0x, for example b302.
+#. /dev/ represents the device number of disk
+#. /dev/ represents the device number of partition - device
+   number of disk plus the partition number
+#. /dev/p - same as the above; this form is used when disk
+   name of partitioned disk ends with a digit.
+#. PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF representing the unique id of
+   a partition if the partition table provides it. The UUID may be either an
+   EFI/GPT UUID, or refer to an MSDOS partition using the format -PP,
+   where  is a zero-filled hex representation of the 32-bit
+   "NT disk signature", and PP is a zero-filled hex representation of the
+   1-based partition number.
+#. PARTUUID=/PARTNROFF= to select a partition in relation to a
+   partition with a known unique id.
+#. : major and minor number of the device separated by a colon.
+
+See more in section **read/write**.
+
+total_size
+~~
+
+The total size in bytes of block device used for pstore_blk. It **MUST** be 
less
+than or equal to size of block device if ``blkdev`` valid. It **MUST** be a
+multiple of 4096. If ``total_size`` is zero with ``blkdev``, ``total_size`` 
will be
+set to equal to size of ``blkdev``.
+
+The block device area is divided into many chunks, and each event writes a 
chunk
+of information.
+
+dmesg_size
+~~
+
+The chunk size in bytes for dmesg(oops/panic). It **MUST** be a multiple of
+SECTOR_SIZE (Most of the time, the SECTOR_SIZE is 512). If you don't need 
dmesg,
+you can safely to set it to 0.
+
+NOTE that, the remaining space, except ``pmsg_size`` and others, belongs to
+dmesg. It means that there are multiple chunks for dmesg.
+
+Pstore_blk will log to dmesg chunks one by one, and always overwrite the oldest
+chunk if no free chunk.
+
+pmsg_size
+~
+
+The chunk size in bytes for pmsg. It **MUST** be a multiple of SECTOR_SIZE 
(Most
+of the time, the SECTOR_SIZE is 512). If you don't need pmsg, you can safely 
set
+it to 0.
+
+There is only one chunk for pmsg.
+
+Pmsg is a user space accessible pstore object. Writes to */dev/pmsg0* are
+appended to the chunk. On reboot the contents are available in
+/sys/fs/pstore/pmsg-pstore-blk-0.
+
+dump_oops
+~
+
+Dumping both oopses and panics can be done by setting 1 in the ``dump_oops``
+member while setting 0 in that variable dumps only the panics.
+
+read/write
+~~
+
+They are general ``read/write`` APIs. It is safe and recommended to ignore it,
+but set ``blkdev``.
+
+These general APIs are used all the time expect panic. The ``read`` API is
+usually used to recover data from block device, and the ``write`` API is 
usually
+to flush new data and erase to block device.
+
+Pstore_blk will temporarily hold all new data before block device is ready. If
+you ignore both of ``read/write`` and ``blkdev``, the old data will be lost.
+
+NOTE that the general APIs must check whether the block device is ready if
+self-defined.
+
+panic_read/p

[PATCH v13 0/4] pstore/block: new support logger for block devices

2019-03-06 Thread liaoweixiong
Why should we need pstore_block?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fast, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

[PATCH v13]
On patch 1:
1. no need to check zone->buffer in blkz_zone_write() since it never be null
2. blkz_free_zones should return directly if zones is null
3. In blkz_init_zones(), it will causes memory leak if
blkz_init_zone() return failure because it forget to free zone->buffer.
4. In blkz_zone_write(), we copy new data to ram buffer only when buf and
wlen are valid.
On pathc 2:
1. Fix spelling error on Kconfig
On patch 3:
1. In blkz_pstore_erase(), if there are new but dirty data in pmsg
zone buffer, we should try to flush them to block device.
2. Fix spelling error on Kconfig

[PATCH v12]
On patch 4:
1. Modify the document according to Randy Dunlap's suggestion.

[PATCH v11]
Change patchset label from RFC to PATCH

[PATCH v10]
Cancel DT support for blkoops temporarily.
On patch 1:
1. pstore/blk should unlink PSTORE_BLKDEV when unregister.
On patch 2:
1. cancel DT support temporarily. I will submit other patches to support DT
   when DT maintainers acked.
2. add spin lock to protect blkz_info when modify panic operations.
3. change default value of total size on Kconfig from 1024 to 0.

[PATCH v9]
On patch 1:
1. rename part_path/part_size, members of blkz_info, to blkdev/total_size
2. if total_size is zero, get size from @blkdev
3. support multiple variants for @blkdev, such as partuuid, major with
   minor, and /dev/. See details on Documentation.
4. get size from block device
5. add depends on CONFIG_BLOCK
On patch 2:
1. update document
On patch 3:
1. update codes for new blkzone. Blkoops support insmod without total_size.
   for example: "insmod ./blkoops.ko blkdev=93:6" (major:minor).
2. use late_initcalls rather than module_init, to avoid block device not
ready.
3. support for block driver to add panic apis to blkoops. By this, block
   driver can do the least work that just provides panic operations.
On patch 5:
1. update document

[PATCH v8]
On patch 2:
1. move DT to /bindings/pstore
2. Delete details for kernel.

[PATCH v7]
On patch 1:
1. Fix line over 80 characters.
On patch 2:
1. Insert a separate patch for DT bindings.

[PATCH v6]
On patch 1:
1. Fix according to email from Kees Cook, including spelling mistakes,
   explicit overflow test, none of the zeroing etc.
2. Do not recover data but metadata of dmesg when panic.
3. No need to take recovery when do erase.
4. Do not use "blkoops" for blkzone any more because "blkoops" is used for
   other module now. (rename blkbuf to blkoops)
On patch 2:
1. Rename blkbuf to blkoops.
2. Add Kconfig/device tree/module parameters settings for blkoops.
3. Add document for device tree.
On patch 3:
1. Blkoops support pmsg.
2. Fix description for new version patch.
On patch 4:
1. Fix description for new version patch.

[PATCH v5]
On patch 1:
1. rename pstore/rom to pstore/blk
2. Do not allocate any memory in the write path of panic. So, use local
array instead in function romz_recover_dmesg_meta.
3. Add C header file "linux/fs.h" to fix implicit declaration of function
   'filp_open','kernel_read'...
On patch 3:
1. If panic, do not recover pmsg but flush if it is dirty.
2. Fix erase pmsg failed.
On patch 4:
1. Create a document for pstore/blk

[PATCH v4]
On patch 1:
1. Fix always true condition '(--i >= 0) => (0-u32max >= 0)' in function
   romz_init_zones by defining variable i to 'int' rahter than
   'unsigned int'.
2. To make codes more easily to read, we use macro READ_NEXT_ZONE for
   return value of romz_dmesg_read if it need to read next zone.
   Moveover, we assign READ_NEXT_ZONE -1024 rather than 0.
3. Add 'FLUSH_META' to 'enum romz_flush_mode' and rename 'NOT_FLUSH' to
   'FLUSH_NONE'
4. Function romz_zone_write work badly with FLUSH_PART mode as badly
   address and offset to write.
On patch 3:
NEW SUPPORT psmg for pstore_rom.

[PATCH v3]
On patch 1:
Fix build as module error for undefined 'vfs_read' and 'vfs_write'
Both of 'vfs_read' and 'vfs_write' haven't be exproted yet, so we use
'kernel_read' and 'kernel_write' instead.

[PATCH v2]
On patch 1:
Fix build as module error for redefinition of 'romz_unregister' and
'romz_register'

[PATCH v1]
On patch 1:
Core codes of pstore_rom, which works well on allwinner(sunxi) platform.
On patch 2:
A sample for pstore_rom, using general ram rather than block device.

liaoweixiong (4):
  pstore/blk: new support logger for block devices
  pstore/blk: add blkoops for pstore_blk
  pstore/blk: support pmsg for pstore block
  Documentation: pstore/blk: create document for pstore_blk

 Documentation/admin-guide/pstore-block.rst |  233 ++

[PATCH v13 2/4] pstore/blk: add blkoops for pstore_blk

2019-03-06 Thread liaoweixiong
blkoops is a sample for pstore/blk. It can only record oops, excluding
panics as no read/write apis for panic registered. It support settings
on Kconfg/module parameters. It can record oops log even power failure
if "PSTORE_BLKOOPS_BLKDEV" on Kconfig or "blkdev" on module parameter
is valid. Otherwise, it can only record data to ram buffer, which will
be dropped when reboot.

Signed-off-by: liaoweixiong 
---
 MAINTAINERS|   2 +-
 fs/pstore/Kconfig  | 102 +++
 fs/pstore/Makefile |   2 +
 fs/pstore/blkoops.c| 198 +
 include/linux/pstore_blk.h |  14 +++-
 5 files changed, 313 insertions(+), 5 deletions(-)
 create mode 100644 fs/pstore/blkoops.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 51029a4..4e9242a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12318,7 +12318,7 @@ F:  drivers/firmware/efi/efi-pstore.c
 F: drivers/acpi/apei/erst.c
 F: Documentation/admin-guide/ramoops.rst
 F: Documentation/devicetree/bindings/reserved-memory/ramoops.txt
-K: \b(pstore|ramoops)
+K: \b(pstore|ramoops|blkoops)
 
 PTP HARDWARE CLOCK SUPPORT
 M: Richard Cochran 
diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index defcb75..2fba1c5 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -160,3 +160,105 @@ config PSTORE_BLK
help
  This enables panic and oops message to be logged to a block dev
  where it can be read back at some later point.
+
+config PSTORE_BLKOOPS
+   tristate "pstore block with oops logger"
+   depends on PSTORE_BLK
+   help
+ This is a sample for pstore block with oops logger.
+
+ It CANNOT record panic log as no read/write APIs for panic registered.
+
+ It CAN record oops log even power failure if
+ "PSTORE_BLKOOPS_BLKDEV" on Kconfig or "block-device" on dts or
+ "blkdev" on module parameter is valid.
+
+ Otherwise, it can only record data to ram buffer, which will be
+ dropped on reboot.
+
+ NOTE that, there are two ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
+config PSTORE_BLKOOPS_DMESG_SIZE
+   int "dmesg size in kbytes for blkoops"
+   depends on PSTORE_BLKOOPS
+   default 64
+   help
+ This just sets size of dmesg (dmesg_size) for pstore/blk. The value
+ must be a multiple of 4096.
+
+ NOTE that, there are two ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
+config PSTORE_BLKOOPS_TOTAL_SIZE
+   int "total size in kbytes for blkoops"
+   depends on PSTORE_BLKOOPS
+   default 0
+   help
+ The total size in kbytes pstore/blk can use. It must be less than or
+ equal to size of block device if @blkdev valid. If @total_size is zero
+ with @blkdev, @total_size will be set equal to size of @blkdev.
+ The value must be a multiple of 4096.
+
+ NOTE that, there are two ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
+config PSTORE_BLKOOPS_BLKDEV
+   string "block device for blkoops"
+   depends on PSTORE_BLKOOPS
+   default ""
+   help
+ This just sets block device (blkdev) for pstore/blk. Pstore/blk
+ will record data to this block device to avoid losing data due to
+ power failure. So, if it is not set, pstore/blk will drop all data
+ when on reboot.
+
+ It accept the following variants:
+ 1)  device number in hexadecimal represents
+itself no leading 0x, for example b302.
+ 2) /dev/ represents the device number of disk
+ 3) /

[PATCH v13 3/4] pstore/blk: support pmsg for pstore block

2019-03-06 Thread liaoweixiong
To enable pmsg, just set pmsg_size when block device register blkzone.

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig  |  18 
 fs/pstore/blkoops.c|  10 ++
 fs/pstore/blkzone.c| 256 +
 include/linux/pstore_blk.h |   1 +
 4 files changed, 264 insertions(+), 21 deletions(-)

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index 2fba1c5..2788ae8 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -204,6 +204,24 @@ config PSTORE_BLKOOPS_DMESG_SIZE
 It is the first priority. Take care of that blkoops will take lower
 priority settings if higher priority one do not set.
 
+config PSTORE_BLKOOPS_PMSG_SIZE
+   int "pmsg size in kbytes for blkoops"
+   depends on PSTORE_BLKOOPS
+   default 64
+   help
+ This just sets size of pmsg (pmsg_size) for pstore/blk. The value must
+ be a multiple of 4096. Pmsg works only if "blkdev" is set.
+
+ NOTE that, there are two ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
 config PSTORE_BLKOOPS_TOTAL_SIZE
int "total size in kbytes for blkoops"
depends on PSTORE_BLKOOPS
diff --git a/fs/pstore/blkoops.c b/fs/pstore/blkoops.c
index 22c0c84..05140fd 100644
--- a/fs/pstore/blkoops.c
+++ b/fs/pstore/blkoops.c
@@ -30,6 +30,10 @@
 module_param(dmesg_size, long, 0400);
 MODULE_PARM_DESC(dmesg_size, "demsg size in kbytes");
 
+static long pmsg_size = -1;
+module_param(pmsg_size, long, 0400);
+MODULE_PARM_DESC(pmsg_size, "pmsg size in kbytes");
+
 static long total_size = -1;
 module_param(total_size, long, 0400);
 MODULE_PARM_DESC(total_size, "total size in kbytes");
@@ -47,11 +51,13 @@ struct blkz_info blkz_info = {
 
 struct blkoops_info {
unsigned long dmesg_size;
+   unsigned long pmsg_size;
unsigned long total_size;
const char *blkdev;
 };
 struct blkoops_info blkoops_info = {
.dmesg_size = CONFIG_PSTORE_BLKOOPS_DMESG_SIZE * 1024,
+   .pmsg_size = CONFIG_PSTORE_BLKOOPS_PMSG_SIZE * 1024,
.total_size = CONFIG_PSTORE_BLKOOPS_TOTAL_SIZE * 1024,
.blkdev = CONFIG_PSTORE_BLKOOPS_BLKDEV,
 };
@@ -104,6 +110,7 @@ static int blkoops_probe(struct platform_device *pdev)
 
check_size(total_size, 4096);
check_size(dmesg_size, 4096);
+   check_size(pmsg_size, 4096);
 
 #undef check_size
 
@@ -112,6 +119,7 @@ static int blkoops_probe(struct platform_device *pdev)
 * through /sys/module/blkoops/parameters/
 */
dmesg_size = blkz_info.dmesg_size;
+   pmsg_size = blkz_info.pmsg_size;
total_size = blkz_info.total_size;
if (blkz_info.blkdev)
strncpy(blkdev, blkz_info.blkdev, 80 - 1);
@@ -156,6 +164,8 @@ void blkoops_register_dummy(void)
info->blkdev = (const char *)blkdev;
if (dmesg_size >= 0)
info->dmesg_size = (unsigned long)dmesg_size * 1024;
+   if (pmsg_size >= 0)
+   info->pmsg_size = (unsigned long)pmsg_size * 1024;
} else if (info->total_size > 0 || strlen(info->blkdev)) {
pr_info("using kconfig value\n");
} else {
diff --git a/fs/pstore/blkzone.c b/fs/pstore/blkzone.c
index 5e28ac4..8c3c735 100644
--- a/fs/pstore/blkzone.c
+++ b/fs/pstore/blkzone.c
@@ -40,12 +40,14 @@
  *
  * @sig: signature to indicate header (BLK_SIG xor BLKZONE-type value)
  * @datalen: length of data in @data
+ * @start: offset into @data where the beginning of the stored bytes begin
  * @data: zone data.
  */
 struct blkz_buffer {
 #define BLK_SIG (0x43474244) /* DBGC */
uint32_t sig;
atomic_t datalen;
+   atomic_t start;
uint8_t data[];
 };
 
@@ -78,6 +80,9 @@ struct blkz_dmesg_header {
  * frontent name for this zone
  * @buffer:
  * pointer to data buffer managed by this zone
+ * @oldbuf:
+ * pointer to old data buffer. It is used for single zone such as pmsg,
+ * saving the old buffer.
  * @buffer_size:
  * bytes in @buffer->data
  * @should_recover:
@@ -91,6 +96,7 @@ struct blkz_zone {
enum pstore_type_id type;
 
struct blkz_buffer *buffer;
+   struct blkz_buffer *oldbuf;
size_t buffer_size;
bool should_recover;
atomic_t dirty;
@@ -98,8 +104,10 @@ struct blkz_zone {
 
 struct blkz_context {
struct blkz_zone **dbzs;/* dmesg block zones */
+   struct blkz_zone *pbz;   

Re: [PATCH v12 3/4] pstore/blk: support pmsg for pstore block

2019-03-06 Thread liaoweixiong
Hi,

On 2019-03-06 09:16, Randy Dunlap wrote:
> Hi,
> 
> On 2/27/19 11:12 PM, liaoweixiong wrote:
>> diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
>> index 7dfe00b..b417bf5 100644
>> --- a/fs/pstore/Kconfig
>> +++ b/fs/pstore/Kconfig
>> @@ -210,6 +210,27 @@ config PSTORE_BLKOOPS_DMESG_SIZE
>>   It is the first priority. Take care of that blkoops will take lower
>>   priority settings if higher priority one do not set.
>>  
>> +config PSTORE_BLKOOPS_PMSG_SIZE
>> +int "pmsg size in kbytes for blkoops"
>> +depends on PSTORE_BLKOOPS
>> +default 64
>> +help
>> +  This just sets size of pmsg (pmsg_size) for pstore/blk. The value must
>> +  be a multiple of 4096. Pmsg work only if "blkdev" is set.
> 
> works
> 

Fixed.

>> +
>> +  NOTE that, there are three ways to set parameters of blkoops and
>> +  prioritize according to configuration flexibility. That is
>> +  Kconfig < device tree < module parameters. It means that the value can
>> +  be overwritten by higher priority settings.
>> +  1. Kconfig
>> + It just sets a default value.
>> +  2. device tree
>> + It is set on device tree, which will overwrites value from Kconfig,
> 
> overwrite the value from 
> Kconfig,
> 

Fixed.

>> + but can also be overwritten by module parameters.
>> +  3. module parameters
>> + It is the first priority. Take care of that blkoops will take lower
>> +     priority settings if higher priority one do not set.
>> +
>>  config PSTORE_BLKOOPS_TOTAL_SIZE
>>  int "total size in kbytes for blkoops"
>>  depends on PSTORE_BLKOOPS
> 
> cheers.
> 

Thank you. Cheers.

-- 
liaoweixiong


Re: [PATCH v12 2/4] pstore/blk: add blkoops for pstore_blk

2019-03-06 Thread liaoweixiong
Hi,

I will fix all on next version. Thank you very much.

On 2019-03-06 09:14, Randy Dunlap wrote:
> Hi,
> 
> On 2/27/19 11:12 PM, liaoweixiong wrote:
>> diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
>> index defcb75..7dfe00b 100644
>> --- a/fs/pstore/Kconfig
>> +++ b/fs/pstore/Kconfig
>> @@ -160,3 +160,117 @@ config PSTORE_BLK
>>  help
>>This enables panic and oops message to be logged to a block dev
>>where it can be read back at some later point.
>> +
>> +config PSTORE_BLKOOPS
>> +tristate "pstore block with oops logger"
>> +depends on PSTORE_BLK
>> +help
>> +  This is a sample for pstore block with oops logger.
>> +
>> +  It CANNOT record panic log as no read/write apis for panic registered.
> 
> APIs
> 

Fixed.

>> +
>> +  It CAN record oops log even power failure if
>> +  "PSTORE_BLKOOPS_BLKDEV" on Kconfig or "block-device" on dts or
>> +  "blkdev" on module parameter is valid.
>> +
>> +  Otherwise, it can only record data to ram buffer, which will be
>> +  dropped when reboot.
> 
> dropped on reboot.
> or
> dropped when rebooting.
> 

Fixed.

>> +
>> +  NOTE that, there are three ways to set parameters of blkoops and
>> +  prioritize according to configuration flexibility. That is
>> +  Kconfig < device tree < module parameters. It means that the value can
>> +  be overwritten by higher priority settings.
>> +  1. Kconfig
>> + It just sets a default value.
>> +  2. device tree
>> + It is set on device tree, which will overwrites value from Kconfig,
> 
> overwrite the value from 
> Kconfig,
> 

Fixed.

>> + but can also be overwritten by module parameters.
>> +  3. module parameters
>> + It is the first priority. Take care of that blkoops will take lower
>> + priority settings if higher priority one do not set.
>> +
>> +config PSTORE_BLKOOPS_DMESG_SIZE
>> +int "dmesg size in kbytes for blkoops"
>> +depends on PSTORE_BLKOOPS
>> +default 64
>> +help
>> +  This just sets size of dmesg (dmesg_size) for pstore/blk. The value
>> +  must be a multiple of 4096.
>> +
>> +  NOTE that, there are three ways to set parameters of blkoops and
>> +  prioritize according to configuration flexibility. That is
>> +  Kconfig < device tree < module parameters. It means that the value can
>> +  be overwritten by higher priority settings.
>> +  1. Kconfig
>> + It just sets a default value.
>> +  2. device tree
>> + It is set on device tree, which will overwrites value from Kconfig,
> 
> overwrite the value from 
> Kconfig,
> 

It cancels device tree support. I forget to delete it.

>> + but can also be overwritten by module parameters.
>> +  3. module parameters
>> + It is the first priority. Take care of that blkoops will take lower
>> + priority settings if higher priority one do not set.
>> +
>> +config PSTORE_BLKOOPS_TOTAL_SIZE
>> +int "total size in kbytes for blkoops"
>> +depends on PSTORE_BLKOOPS
>> +default 0
>> +help
>> +  The total size in kbytes pstore/blk can use. It must be less than or
>> +  equal to size of block device if @blkdev valid. If @total_size is zero
>> +  with @blkdev, @total_size will be set to equal to size of @blkdev.
> 
>   set equal to size of @blkdev.
> 

Fixed.

>> +  The value must be a multiple of 4096.
>> +
>> +  NOTE that, there are three ways to set parameters of blkoops and
>> +  prioritize according to configuration flexibility. That is
>> +  Kconfig < device tree < module parameters. It means that the value can
>> +  be overwritten by higher priority settings.
>> +  1. Kconfig
>> + It just sets a default value.
>> +  2. device tree
>> + It is set on device tree, which will overwrites value from Kconfig,
> 
> overwrite the value from 
> Kconfig,
> 

Fixed.

>> + but can also be overwritten by module parameters.
>> +  3. module parameters
>> + It is the first priority. Take care of that blkoops wil

Re: [PATCH v12 1/4] pstore/blk: new support logger for block devices

2019-03-05 Thread liaoweixiong
hi Dan Carpenter,

On 2019/03/05 15:12, Dan Carpenter wrote:
> Hi liaoweixiong,
> 
> url:
> https://github.com/0day-ci/linux/commits/liaoweixiong/pstore-block-new-support-logger-for-block-devices/20190303-142003
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git 
> for-next/pstore
> 
> smatch warnings:
> fs/pstore/blkzone.c:180 blkz_zone_write() error: we previously assumed 
> 'zone->buffer' could be null (see line 167)
> 
> # 
> https://github.com/0day-ci/linux/commit/113727d0f1946ad094dbc6531d653a88c7a221bf
> git remote add linux-review https://github.com/0day-ci/linux
> git remote update linux-review
> git checkout 113727d0f1946ad094dbc6531d653a88c7a221bf
> vim +180 fs/pstore/blkzone.c
> 
> 113727d0 liaoweixiong 2019-02-28  153  
> 113727d0 liaoweixiong 2019-02-28  154  static int blkz_zone_write(struct 
> blkz_zone *zone,
> 113727d0 liaoweixiong 2019-02-28  155 enum blkz_flush_mode 
> flush_mode, const char *buf,
> 113727d0 liaoweixiong 2019-02-28  156 size_t len, unsigned 
> long off)
> 113727d0 liaoweixiong 2019-02-28  157  {
> 113727d0 liaoweixiong 2019-02-28  158 struct blkz_info *info = 
> blkz_cxt.bzinfo;
> 113727d0 liaoweixiong 2019-02-28  159 ssize_t wcnt;
> 113727d0 liaoweixiong 2019-02-28  160 ssize_t (*writeop)(const char 
> *buf, size_t bytes, loff_t pos);
> 113727d0 liaoweixiong 2019-02-28  161 size_t wlen;
> 113727d0 liaoweixiong 2019-02-28  162  
> 113727d0 liaoweixiong 2019-02-28  163 if (off > zone->buffer_size)
> 113727d0 liaoweixiong 2019-02-28  164 return -EINVAL;
> 113727d0 liaoweixiong 2019-02-28  165 wlen = min_t(size_t, len, 
> zone->buffer_size - off);
> 113727d0 liaoweixiong 2019-02-28  166 if (flush_mode != FLUSH_META && 
> flush_mode != FLUSH_NONE) {
> 113727d0 liaoweixiong 2019-02-28 @167 if (buf && zone->buffer)
>
> Check.
> 

zone->buffer should not be checked whether null as it will never be null
here. I will fix it on next version.
zone->buffer was allocated when the zone was initialized (see line 995).
Pstore/blk will not go on if allocates buffer for zone->buffer failed.

> 113727d0 liaoweixiong 2019-02-28  168 
> memcpy(zone->buffer->data + off, buf, wlen);
> 113727d0 liaoweixiong 2019-02-28  169 
> atomic_set(>buffer->datalen, wlen + off);
> 113727d0 liaoweixiong 2019-02-28  170 }
> 113727d0 liaoweixiong 2019-02-28  171  
> 113727d0 liaoweixiong 2019-02-28  172 writeop = is_on_panic() ? 
> info->panic_write : info->write;
> 113727d0 liaoweixiong 2019-02-28  173 if (!writeop)
> 113727d0 liaoweixiong 2019-02-28  174 return -EINVAL;
> 113727d0 liaoweixiong 2019-02-28  175  
> 113727d0 liaoweixiong 2019-02-28  176 switch (flush_mode) {
> 113727d0 liaoweixiong 2019-02-28  177 case FLUSH_NONE:
> 113727d0 liaoweixiong 2019-02-28  178 return 0;
> 113727d0 liaoweixiong 2019-02-28  179 case FLUSH_PART:
> 113727d0 liaoweixiong 2019-02-28 @180 wcnt = writeop((const 
> char *)zone->buffer->data + off, wlen,
>
> 
> Unchecked.
> 
> 113727d0 liaoweixiong 2019-02-28  181 
> zone->off + sizeof(*zone->buffer) + off);
>   
>   
> This is weird.  I can't fetch for-next/pstore so I don't know what
> type "buffer" is.  It's vague.  We also have ->buffer_size which seems
> like a more expected way to describe the size.
> 

The type of buffer is struct blkz_buffer (see line 98). struct
blkz_buffer is a header of data, who's member data[0] point to real
data. The codes "sizeof(*zone->buffer)" just to get size of header.
There is a size recorder for blkz_buffer->data on struct blkz_zone. It
is no need to write to block device, that's why it do not live in struct
blkz_buffer.

> 113727d0 liaoweixiong 2019-02-28  182 if (wcnt != wlen)
> 113727d0 liaoweixiong 2019-02-28  183     goto set_dirty;
> 113727d0 liaoweixiong 2019-02-28  184 case FLUSH_META:
> 113727d0 liaoweixiong 2019-02-28  185 wlen = sizeof(struct 
> blkz_buffer);
> 113727d0 liaoweixiong 2019-02-28  186 wcnt = writeop((const 
> char *)zone->buffer, wlen, zone->off);
> 113727d0 liaoweixiong 2019-02-28  187 if (wcnt != wlen)
> 113727d0

[PATCH v12 3/4] pstore/blk: support pmsg for pstore block

2019-02-27 Thread liaoweixiong
To enable pmsg, just set pmsg_size when block device register blkzone.

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig  |  21 
 fs/pstore/blkoops.c|  10 ++
 fs/pstore/blkzone.c| 253 +
 include/linux/pstore_blk.h |   1 +
 4 files changed, 264 insertions(+), 21 deletions(-)

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index 7dfe00b..b417bf5 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -210,6 +210,27 @@ config PSTORE_BLKOOPS_DMESG_SIZE
 It is the first priority. Take care of that blkoops will take lower
 priority settings if higher priority one do not set.
 
+config PSTORE_BLKOOPS_PMSG_SIZE
+   int "pmsg size in kbytes for blkoops"
+   depends on PSTORE_BLKOOPS
+   default 64
+   help
+ This just sets size of pmsg (pmsg_size) for pstore/blk. The value must
+ be a multiple of 4096. Pmsg work only if "blkdev" is set.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. device tree
+It is set on device tree, which will overwrites value from Kconfig,
+but can also be overwritten by module parameters.
+ 3. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
 config PSTORE_BLKOOPS_TOTAL_SIZE
int "total size in kbytes for blkoops"
depends on PSTORE_BLKOOPS
diff --git a/fs/pstore/blkoops.c b/fs/pstore/blkoops.c
index 22c0c84..05140fd 100644
--- a/fs/pstore/blkoops.c
+++ b/fs/pstore/blkoops.c
@@ -30,6 +30,10 @@
 module_param(dmesg_size, long, 0400);
 MODULE_PARM_DESC(dmesg_size, "demsg size in kbytes");
 
+static long pmsg_size = -1;
+module_param(pmsg_size, long, 0400);
+MODULE_PARM_DESC(pmsg_size, "pmsg size in kbytes");
+
 static long total_size = -1;
 module_param(total_size, long, 0400);
 MODULE_PARM_DESC(total_size, "total size in kbytes");
@@ -47,11 +51,13 @@ struct blkz_info blkz_info = {
 
 struct blkoops_info {
unsigned long dmesg_size;
+   unsigned long pmsg_size;
unsigned long total_size;
const char *blkdev;
 };
 struct blkoops_info blkoops_info = {
.dmesg_size = CONFIG_PSTORE_BLKOOPS_DMESG_SIZE * 1024,
+   .pmsg_size = CONFIG_PSTORE_BLKOOPS_PMSG_SIZE * 1024,
.total_size = CONFIG_PSTORE_BLKOOPS_TOTAL_SIZE * 1024,
.blkdev = CONFIG_PSTORE_BLKOOPS_BLKDEV,
 };
@@ -104,6 +110,7 @@ static int blkoops_probe(struct platform_device *pdev)
 
check_size(total_size, 4096);
check_size(dmesg_size, 4096);
+   check_size(pmsg_size, 4096);
 
 #undef check_size
 
@@ -112,6 +119,7 @@ static int blkoops_probe(struct platform_device *pdev)
 * through /sys/module/blkoops/parameters/
 */
dmesg_size = blkz_info.dmesg_size;
+   pmsg_size = blkz_info.pmsg_size;
total_size = blkz_info.total_size;
if (blkz_info.blkdev)
strncpy(blkdev, blkz_info.blkdev, 80 - 1);
@@ -156,6 +164,8 @@ void blkoops_register_dummy(void)
info->blkdev = (const char *)blkdev;
if (dmesg_size >= 0)
info->dmesg_size = (unsigned long)dmesg_size * 1024;
+   if (pmsg_size >= 0)
+   info->pmsg_size = (unsigned long)pmsg_size * 1024;
} else if (info->total_size > 0 || strlen(info->blkdev)) {
pr_info("using kconfig value\n");
} else {
diff --git a/fs/pstore/blkzone.c b/fs/pstore/blkzone.c
index cba55b3..cd3d4ed 100644
--- a/fs/pstore/blkzone.c
+++ b/fs/pstore/blkzone.c
@@ -40,12 +40,14 @@
  *
  * @sig: signature to indicate header (BLK_SIG xor BLKZONE-type value)
  * @datalen: length of data in @data
+ * @start: offset into @data where the beginning of the stored bytes begin
  * @data: zone data.
  */
 struct blkz_buffer {
 #define BLK_SIG (0x43474244) /* DBGC */
uint32_t sig;
atomic_t datalen;
+   atomic_t start;
uint8_t data[];
 };
 
@@ -78,6 +80,9 @@ struct blkz_dmesg_header {
  * frontent name for this zone
  * @buffer:
  * pointer to data buffer managed by this zone
+ * @oldbuf:
+ * pointer to old data buffer. It is used for single zone such as pmsg,
+ * saving the old buffer.
  * @buffer_size:
  * bytes in @buffer->data
  * @should_recover:
@@ -91,6 +96,7 @@ struct blkz_zone {
enum pstore_type_id type;
 
struct blkz_buffer *buffer;
+   struct blkz_buffer *oldbuf;
size_t buffer_size;
bool should_recover;

[PATCH v12 4/4] Documentation: pstore/blk: create document for pstore_blk

2019-02-27 Thread liaoweixiong
The document, at Documentation/admin-guide/pstore-block.rst,
tells user how to use pstore_blk and the attentions about panic
read/write

Signed-off-by: liaoweixiong 
---
 Documentation/admin-guide/pstore-block.rst | 233 +
 MAINTAINERS|   1 +
 fs/pstore/Kconfig  |   4 +
 3 files changed, 238 insertions(+)
 create mode 100644 Documentation/admin-guide/pstore-block.rst

diff --git a/Documentation/admin-guide/pstore-block.rst 
b/Documentation/admin-guide/pstore-block.rst
new file mode 100644
index 000..c22245d
--- /dev/null
+++ b/Documentation/admin-guide/pstore-block.rst
@@ -0,0 +1,233 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Pstore block oops/panic logger
+==
+
+Introduction
+
+
+Pstore block (pstore_blk) is an oops/panic logger that write its logs to a 
block
+device before the system crashes. Pstore_blk needs the block device driver
+to register a partition of the block device, like /dev/mmcblk0p7 for MMC
+driver, and read/write APIs for this partition when on panic.
+
+Pstore block concepts
+-
+
+Pstore block begins at function ``blkz_register``, by which a block driver
+registers to pstore_blk. Note that the block driver should register to
+pstore_blk after block device has registered. The Block driver transfers a
+structure ``blkz_info`` which is defined in *linux/pstore_blk.h*.
+
+The following key members of ``struct blkz_info`` may be of interest to you.
+
+blkdev
+~~
+
+The block device to use. Most of the time, it is a partition of block device.
+It's ok to keep it as NULL if you are passing ``read`` and ``write`` in
+blkz_info as ``blkdev`` is used by blkz_default_general_read/write. If both of
+``blkdev``, ``read`` and ``write`` are NULL, no block device is effective and
+the data will only be saved in RAM.
+
+It accept the following variants:
+
+1.  device number in hexadecimal represents itself; no
+   leading 0x, for example b302.
+#. /dev/ represents the device number of disk
+#. /dev/ represents the device number of partition - device
+   number of disk plus the partition number
+#. /dev/p - same as the above; this form is used when disk
+   name of partitioned disk ends with a digit.
+#. PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF representing the unique id of
+   a partition if the partition table provides it. The UUID may be either an
+   EFI/GPT UUID, or refer to an MSDOS partition using the format -PP,
+   where  is a zero-filled hex representation of the 32-bit
+   "NT disk signature", and PP is a zero-filled hex representation of the
+   1-based partition number.
+#. PARTUUID=/PARTNROFF= to select a partition in relation to a
+   partition with a known unique id.
+#. : major and minor number of the device separated by a colon.
+
+See more in section **read/write**.
+
+total_size
+~~
+
+The total size in bytes of block device used for pstore_blk. It **MUST** be 
less
+than or equal to size of block device if ``blkdev`` valid. It **MUST** be a
+multiple of 4096. If ``total_size`` is zero with ``blkdev``, ``total_size`` 
will be
+set to equal to size of ``blkdev``.
+
+The block device area is divided into many chunks, and each event writes a 
chunk
+of information.
+
+dmesg_size
+~~
+
+The chunk size in bytes for dmesg(oops/panic). It **MUST** be a multiple of
+SECTOR_SIZE (Most of the time, the SECTOR_SIZE is 512). If you don't need 
dmesg,
+you can safely to set it to 0.
+
+NOTE that, the remaining space, except ``pmsg_size`` and others, belongs to
+dmesg. It means that there are multiple chunks for dmesg.
+
+Pstore_blk will log to dmesg chunks one by one, and always overwrite the oldest
+chunk if no free chunk.
+
+pmsg_size
+~
+
+The chunk size in bytes for pmsg. It **MUST** be a multiple of SECTOR_SIZE 
(Most
+of the time, the SECTOR_SIZE is 512). If you don't need pmsg, you can safely 
set
+it to 0.
+
+There is only one chunk for pmsg.
+
+Pmsg is a user space accessible pstore object. Writes to */dev/pmsg0* are
+appended to the chunk. On reboot the contents are available in
+/sys/fs/pstore/pmsg-pstore-blk-0.
+
+dump_oops
+~
+
+Dumping both oopses and panics can be done by setting 1 in the ``dump_oops``
+member while setting 0 in that variable dumps only the panics.
+
+read/write
+~~
+
+They are general ``read/write`` APIs. It is safe and recommended to ignore it,
+but set ``blkdev``.
+
+These general APIs are used all the time expect panic. The ``read`` API is
+usually used to recover data from block device, and the ``write`` API is 
usually
+to flush new data and erase to block device.
+
+Pstore_blk will temporarily hold all new data before block device is ready. If
+you ignore both of ``read/write`` and ``blkdev``, the old data will be lost.
+
+NOTE that the general APIs must check whether the block device is ready if
+self-defined.
+
+panic_read/p

[PATCH v12 2/4] pstore/blk: add blkoops for pstore_blk

2019-02-27 Thread liaoweixiong
blkoops is a sample for pstore/blk. It can only record oops, excluding
panics as no read/write apis for panic registered. It support settings
on Kconfg/module parameters. It can record oops log even power failure
if "PSTORE_BLKOOPS_BLKDEV" on Kconfig or "blkdev" on module parameter
is valid. Otherwise, it can only record data to ram buffer, which will
be dropped when reboot.

Signed-off-by: liaoweixiong 
---
 MAINTAINERS|   2 +-
 fs/pstore/Kconfig  | 114 ++
 fs/pstore/Makefile |   2 +
 fs/pstore/blkoops.c| 198 +
 include/linux/pstore_blk.h |  14 +++-
 5 files changed, 325 insertions(+), 5 deletions(-)
 create mode 100644 fs/pstore/blkoops.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 51029a4..4e9242a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12318,7 +12318,7 @@ F:  drivers/firmware/efi/efi-pstore.c
 F: drivers/acpi/apei/erst.c
 F: Documentation/admin-guide/ramoops.rst
 F: Documentation/devicetree/bindings/reserved-memory/ramoops.txt
-K: \b(pstore|ramoops)
+K: \b(pstore|ramoops|blkoops)
 
 PTP HARDWARE CLOCK SUPPORT
 M: Richard Cochran 
diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index defcb75..7dfe00b 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -160,3 +160,117 @@ config PSTORE_BLK
help
  This enables panic and oops message to be logged to a block dev
  where it can be read back at some later point.
+
+config PSTORE_BLKOOPS
+   tristate "pstore block with oops logger"
+   depends on PSTORE_BLK
+   help
+ This is a sample for pstore block with oops logger.
+
+ It CANNOT record panic log as no read/write apis for panic registered.
+
+ It CAN record oops log even power failure if
+ "PSTORE_BLKOOPS_BLKDEV" on Kconfig or "block-device" on dts or
+ "blkdev" on module parameter is valid.
+
+ Otherwise, it can only record data to ram buffer, which will be
+ dropped when reboot.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. device tree
+It is set on device tree, which will overwrites value from Kconfig,
+but can also be overwritten by module parameters.
+ 3. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
+config PSTORE_BLKOOPS_DMESG_SIZE
+   int "dmesg size in kbytes for blkoops"
+   depends on PSTORE_BLKOOPS
+   default 64
+   help
+ This just sets size of dmesg (dmesg_size) for pstore/blk. The value
+ must be a multiple of 4096.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. device tree
+It is set on device tree, which will overwrites value from Kconfig,
+but can also be overwritten by module parameters.
+ 3. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
+config PSTORE_BLKOOPS_TOTAL_SIZE
+   int "total size in kbytes for blkoops"
+   depends on PSTORE_BLKOOPS
+   default 0
+   help
+ The total size in kbytes pstore/blk can use. It must be less than or
+ equal to size of block device if @blkdev valid. If @total_size is zero
+ with @blkdev, @total_size will be set to equal to size of @blkdev.
+ The value must be a multiple of 4096.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. device tree
+It is set on device tree, which will overwrites value from Kconfig,
+but can also be overwritten by module parameters.
+ 3. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
+config PSTORE_BLKOOPS_BLKDEV
+   string "block device 

[PATCH v12 1/4] pstore/blk: new support logger for block devices

2019-02-27 Thread liaoweixiong
pstore_blk is similar to pstore_ram, but dump log to block devices
rather than persistent ram.

Why should we need pstore_blk?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fact, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

pstore_blk can only dump Oops/Panic log to block devices. It only
supports dmesg now. To make pstore_blk work, the block driver should
provide the block device and the read/write apis when on panic.

pstore_blk begins at 'blkz_register', by witch block device can register
a block device to pstore_blk. Then pstore_blk divide and manage the
block device as zones, which is similar to pstore_ram.

Recommend that, block driver register pstore_blk after block device is
ready.

pstore_blk works well on allwinner(sunxi) platform.

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig  |8 +
 fs/pstore/Makefile |3 +
 fs/pstore/blkzone.c| 1031 
 include/linux/pstore_blk.h |   80 
 4 files changed, 1122 insertions(+)
 create mode 100644 fs/pstore/blkzone.c
 create mode 100644 include/linux/pstore_blk.h

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index 8b3ba27..defcb75 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -152,3 +152,11 @@ config PSTORE_RAM
  "ramoops.ko".
 
  For more information, see Documentation/admin-guide/ramoops.rst.
+
+config PSTORE_BLK
+   tristate "Log panic/oops to a block device"
+   depends on PSTORE
+   depends on BLOCK
+   help
+ This enables panic and oops message to be logged to a block dev
+ where it can be read back at some later point.
diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
index 967b589..0ee2fc8 100644
--- a/fs/pstore/Makefile
+++ b/fs/pstore/Makefile
@@ -12,3 +12,6 @@ pstore-$(CONFIG_PSTORE_PMSG)  += pmsg.o
 
 ramoops-objs += ram.o ram_core.o
 obj-$(CONFIG_PSTORE_RAM)   += ramoops.o
+
+obj-$(CONFIG_PSTORE_BLK) += pstore_blk.o
+pstore_blk-y += blkzone.o
diff --git a/fs/pstore/blkzone.c b/fs/pstore/blkzone.c
new file mode 100644
index 000..cba55b3
--- /dev/null
+++ b/fs/pstore/blkzone.c
@@ -0,0 +1,1031 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *
+ * blkzone.c: Block device Oops/Panic logger
+ *
+ * Copyright (C) 2019 liaoweixiong 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define MODNAME "pstore-blk"
+#define pr_fmt(fmt) MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define PSTORE_BLKDEV "/dev/pstore-blk"
+
+/**
+ * struct blkz_head - head of zone to flush to storage
+ *
+ * @sig: signature to indicate header (BLK_SIG xor BLKZONE-type value)
+ * @datalen: length of data in @data
+ * @data: zone data.
+ */
+struct blkz_buffer {
+#define BLK_SIG (0x43474244) /* DBGC */
+   uint32_t sig;
+   atomic_t datalen;
+   uint8_t data[];
+};
+
+/**
+ * struct blkz_dmesg_header: dmesg information
+ *
+ * @magic: magic num for dmesg header
+ * @time: trigger time
+ * @compressed: whether conpressed
+ * @count: oops/panic counter
+ * @reason: identify oops or panic
+ */
+struct blkz_dmesg_header {
+#define DMESG_HEADER_MAGIC 0x4dfc3ae5
+   uint32_t magic;
+   struct timespec64 time;
+   bool compressed;
+   uint32_t counter;
+   enum kmsg_dump_reason reason;
+   uint8_t data[0];
+};
+
+/**
+ * struct blkz_zone - zone information
+ * @off:
+ * zone offset of block device
+ * @type:
+ * frontent type for this zone
+ * @name:
+ * frontent name for this zone
+ * @buffer:
+ * pointer to data buffer managed by this zone
+ * @buffer_size:
+ * bytes in @buffer->data
+ * @should_recover:
+ * should recover from storage
+ * @dirty:
+ * mark whether the data in @buffer are dirty (not flush to storage yet)
+ */
+struct blkz_zone {
+   unsigned long off;
+   const char *name;
+   enum pstore_type_id type;
+
+   struct blkz_buffer *buffer;
+   size_t buffer_size;
+   bool should_recover;
+   atomic_t dirty;
+};
+
+struct blkz_context {
+   struct blkz_zone **dbzs;/* dmesg block zones */
+   unsigned int dmesg_max_cnt;
+   unsigned int

[PATCH v12 0/4] pstore/block: new support logger for block devices

2019-02-27 Thread liaoweixiong
Why should we need pstore_block?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fast, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

[PATCH v12]
On patch 4:
1. Modify the document according to Randy Dunlap's suggestion.

[PATCH v11]
Change patchset label from RFC to PATCH

[PATCH v10]
Cancel DT support for blkoops temporarily.
On patch 1:
1. pstore/blk should unlink PSTORE_BLKDEV when unregister.
On patch 2:
1. cancel DT support temporarily. I will submit other patches to support DT
   when DT maintainers acked.
2. add spin lock to protect blkz_info when modify panic operations.
3. change default value of total size on Kconfig from 1024 to 0.

[PATCH v9]
On patch 1:
1. rename part_path/part_size, members of blkz_info, to blkdev/total_size
2. if total_size is zero, get size from @blkdev
3. support multiple variants for @blkdev, such as partuuid, major with minor,
   and /dev/. See details on Documentation.
4. get size from block device
5. add depends on CONFIG_BLOCK
On patch 2:
1. update document
On patch 3:
1. update codes for new blkzone. Blkoops support insmod without total_size.
   for example: "insmod ./blkoops.ko blkdev=93:6" (major:minor).
2. use late_initcalls rather than module_init, to avoid block device not ready.
3. support for block driver to add panic apis to blkoops. By this, block
   driver can do the least work that just provides panic operations.
On patch 5:
1. update document

[PATCH v8]
On patch 2:
1. move DT to /bindings/pstore
2. Delete details for kernel.

[PATCH v7]
On patch 1:
1. Fix line over 80 characters.
On patch 2:
1. Insert a separate patch for DT bindings.

[PATCH v6]
On patch 1:
1. Fix according to email from Kees Cook, including spelling mistakes,
   explicit overflow test, none of the zeroing etc.
2. Do not recover data but metadata of dmesg when panic.
3. No need to take recovery when do erase.
4. Do not use "blkoops" for blkzone any more because "blkoops" is used for
   other module now. (rename blkbuf to blkoops)
On patch 2:
1. Rename blkbuf to blkoops.
2. Add Kconfig/device tree/module parameters settings for blkoops.
3. Add document for device tree.
On patch 3:
1. Blkoops support pmsg.
2. Fix description for new version patch.
On patch 4:
1. Fix description for new version patch.

[PATCH v5]
On patch 1:
1. rename pstore/rom to pstore/blk
2. Do not allocate any memory in the write path of panic. So, use local
array instead in function romz_recover_dmesg_meta.
3. Add C header file "linux/fs.h" to fix implicit declaration of function
   'filp_open','kernel_read'...
On patch 3:
1. If panic, do not recover pmsg but flush if it is dirty.
2. Fix erase pmsg failed.
On patch 4:
1. Create a document for pstore/blk

[PATCH v4]
On patch 1:
1. Fix always true condition '(--i >= 0) => (0-u32max >= 0)' in function
   romz_init_zones by defining variable i to 'int' rahter than
   'unsigned int'.
2. To make codes more easily to read, we use macro READ_NEXT_ZONE for
   return value of romz_dmesg_read if it need to read next zone.
   Moveover, we assign READ_NEXT_ZONE -1024 rather than 0.
3. Add 'FLUSH_META' to 'enum romz_flush_mode' and rename 'NOT_FLUSH' to
   'FLUSH_NONE'
4. Function romz_zone_write work badly with FLUSH_PART mode as badly
   address and offset to write.
On patch 3:
NEW SUPPORT psmg for pstore_rom.

[PATCH v3]
On patch 1:
Fix build as module error for undefined 'vfs_read' and 'vfs_write'
Both of 'vfs_read' and 'vfs_write' haven't be exproted yet, so we use
'kernel_read' and 'kernel_write' instead.

[PATCH v2]
On patch 1:
Fix build as module error for redefinition of 'romz_unregister' and
'romz_register'

[PATCH v1]
On patch 1:
Core codes of pstore_rom, which works well on allwinner(sunxi) platform.
On patch 2:
A sample for pstore_rom, using general ram rather than block device.

liaoweixiong (4):
  pstore/blk: new support logger for block devices
  pstore/blk: add blkoops for pstore_blk
  pstore/blk: support pmsg for pstore block
  Documentation: pstore/blk: create document for pstore_blk

 Documentation/admin-guide/pstore-block.rst |  233 ++
 MAINTAINERS|3 +-
 fs/pstore/Kconfig  |  147 
 fs/pstore/Makefile |5 +
 fs/pstore/blkoops.c|  208 +
 fs/pstore/blkzone.c| 1242 
 include/linux/pstore_blk.h |   87 ++
 7 files changed, 1924 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/admin-guide/pstore-block.rst
 create mode 100644 fs/pstore/blkoops.c
 create mode 100644 fs/pstore/blkzone.c
 create mode 100644 include/linux/pstore_blk.h

-- 
1.9.1



Re: [RFC v9 5/5] Documentation: pstore/blk: create document for pstore_blk

2019-02-27 Thread liaoweixiong
Thank you for your correction. I will update the patch in the 12th version.

On 2019/02/28 13:15, Randy Dunlap wrote:
> On 2/19/19 3:52 AM, liaoweixiong wrote:
>> The document, at Documentation/admin-guide/pstore-block.rst,
>> tells user how to use pstore_blk and the attentions about panic
>> read/write
>>
>> Signed-off-by: liaoweixiong 
>> ---
>>  Documentation/admin-guide/pstore-block.rst | 233 
>> +
>>  MAINTAINERS|   1 +
>>  fs/pstore/Kconfig  |   4 +
>>  3 files changed, 238 insertions(+)
>>  create mode 100644 Documentation/admin-guide/pstore-block.rst
>>
>> diff --git a/Documentation/admin-guide/pstore-block.rst 
>> b/Documentation/admin-guide/pstore-block.rst
>> new file mode 100644
>> index 000..a828274
>> --- /dev/null
>> +++ b/Documentation/admin-guide/pstore-block.rst
>> @@ -0,0 +1,233 @@
>> +.. SPDX-License-Identifier: GPL-2.0
>> +
>> +Pstore block oops/panic logger
>> +==
>> +
>> +Introduction
>> +
>> +
>> +Pstore block (pstore_blk) is an oops/panic logger that write its logs to 
>> block
> 
>  to a 
> block
> 
>> +device before the system crashes. Pstore_blk needs block device driver
> 
> needs the block
> 
>> +registering a partition path of the block device, like /dev/mmcblk0p7 for 
>> mmc
> 
>to register   for 
> MMC
> 
>> +driver, and read/write APIs for this partition when on panic.
>> +
>> +Pstore block concepts
>> +-
>> +
>> +Pstore block begins at function ``blkz_register``, by which block driver
> 
>   by which a block driver
> 
>> +registers to pstore_blk. Note that, block driver should register to 
>> pstore_blk
> 
> Note that the block driver should
> 
>> +after block device has registered. Block driver transfers a structure
> 
>   The block driver
> 
>> +``blkz_info`` which is defined in *linux/pstore_blk.h*.
>> +
>> +The following key members of ``struct blkz_info`` may be of interest to you.
>> +
>> +blkdev
>> +~~
>> +
>> +The block device to use. Most of the time, it is a partition of block 
>> device.
>> +It's ok to keep it as NULL if you passing ``read`` and ``write`` in 
>> blkz_info as
> 
>   if you are passing
> 
>> +``blkdev`` is used by blkz_default_general_read/write. If both of 
>> ``blkdev``,
>> +``read`` and ``write`` are NULL, no block device is effective and the data 
>> will
>> +be saved in ddr buffer.
> 
> what is ddr buffer?
> 

It is a buffer allocated from RAM. I modify it as follow:
If both of ``blkdev``, ``read`` and ``write`` are NULL, no block device
is effective and the data will only be saved in RAM.

>> +
>> +It accept the following variants:
>> +
>> +1.  device number in hexadecimal represents itself no
> 
>  itself; 
> no
> 
>> +   leading 0x, for example b302.
>> +#. /dev/ represents the device number of disk
>> +#. /dev/ represents the device number of partition - 
>> device
>> +   number of disk plus the partition number
>> +#. /dev/p - same as the above, that form is used when 
>> disk
> 
>above; this form
> 
>> +   name of partitioned disk ends on a digit.
> 
>ends with a digit.
> 
>> +#. PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF representing the unique id 
>> of
>> +   a partition if the partition table provides it. The UUID may be either an
>> +   EFI/GPT UUID, or refer to an MSDOS partition using the format 
>> -PP,
>> +   where  is a zero-filled hex representation of the 32-bit
>> +   "NT disk signature", and PP is a zero-filled hex representation of the
>> +   1-based partition number.
>> +#. PARTUUID=/PARTNROFF= to select a partition in relation to a
>> +   partition with a known unique id.
>> +#. : major and minor number of the device separated by a 
>> colon.
>> +
>> +See more on section **read/write**.
> 
> in section
> 
>> +
>> +total_size
>> +~~

[PATCH v11 2/4] pstore/blk: add blkoops for pstore_blk

2019-02-26 Thread liaoweixiong
blkoops is a sample for pstore/blk. It can only record oops, excluding
panics as no read/write apis for panic registered. It support settings
on Kconfg/module parameters. It can record oops log even power failure
if "PSTORE_BLKOOPS_BLKDEV" on Kconfig or "blkdev" on module parameter
is valid. Otherwise, it can only record data to ram buffer, which will
be dropped when reboot.

Signed-off-by: liaoweixiong 
---
 MAINTAINERS|   2 +-
 fs/pstore/Kconfig  | 114 ++
 fs/pstore/Makefile |   2 +
 fs/pstore/blkoops.c| 198 +
 include/linux/pstore_blk.h |  14 +++-
 5 files changed, 325 insertions(+), 5 deletions(-)
 create mode 100644 fs/pstore/blkoops.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 51029a4..4e9242a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12318,7 +12318,7 @@ F:  drivers/firmware/efi/efi-pstore.c
 F: drivers/acpi/apei/erst.c
 F: Documentation/admin-guide/ramoops.rst
 F: Documentation/devicetree/bindings/reserved-memory/ramoops.txt
-K: \b(pstore|ramoops)
+K: \b(pstore|ramoops|blkoops)
 
 PTP HARDWARE CLOCK SUPPORT
 M: Richard Cochran 
diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index defcb75..7dfe00b 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -160,3 +160,117 @@ config PSTORE_BLK
help
  This enables panic and oops message to be logged to a block dev
  where it can be read back at some later point.
+
+config PSTORE_BLKOOPS
+   tristate "pstore block with oops logger"
+   depends on PSTORE_BLK
+   help
+ This is a sample for pstore block with oops logger.
+
+ It CANNOT record panic log as no read/write apis for panic registered.
+
+ It CAN record oops log even power failure if
+ "PSTORE_BLKOOPS_BLKDEV" on Kconfig or "block-device" on dts or
+ "blkdev" on module parameter is valid.
+
+ Otherwise, it can only record data to ram buffer, which will be
+ dropped when reboot.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. device tree
+It is set on device tree, which will overwrites value from Kconfig,
+but can also be overwritten by module parameters.
+ 3. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
+config PSTORE_BLKOOPS_DMESG_SIZE
+   int "dmesg size in kbytes for blkoops"
+   depends on PSTORE_BLKOOPS
+   default 64
+   help
+ This just sets size of dmesg (dmesg_size) for pstore/blk. The value
+ must be a multiple of 4096.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. device tree
+It is set on device tree, which will overwrites value from Kconfig,
+but can also be overwritten by module parameters.
+ 3. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
+config PSTORE_BLKOOPS_TOTAL_SIZE
+   int "total size in kbytes for blkoops"
+   depends on PSTORE_BLKOOPS
+   default 0
+   help
+ The total size in kbytes pstore/blk can use. It must be less than or
+ equal to size of block device if @blkdev valid. If @total_size is zero
+ with @blkdev, @total_size will be set to equal to size of @blkdev.
+ The value must be a multiple of 4096.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. device tree
+It is set on device tree, which will overwrites value from Kconfig,
+but can also be overwritten by module parameters.
+ 3. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
+config PSTORE_BLKOOPS_BLKDEV
+   string "block device 

[PATCH v11 1/4] pstore/blk: new support logger for block devices

2019-02-26 Thread liaoweixiong
pstore_blk is similar to pstore_ram, but dump log to block devices
rather than persistent ram.

Why should we need pstore_blk?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fact, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

pstore_blk can only dump Oops/Panic log to block devices. It only
supports dmesg now. To make pstore_blk work, the block driver should
provide the block device and the read/write apis when on panic.

pstore_blk begins at 'blkz_register', by witch block device can register
a block device to pstore_blk. Then pstore_blk divide and manage the
block device as zones, which is similar to pstore_ram.

Recommend that, block driver register pstore_blk after block device is
ready.

pstore_blk works well on allwinner(sunxi) platform.

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig  |8 +
 fs/pstore/Makefile |3 +
 fs/pstore/blkzone.c| 1031 
 include/linux/pstore_blk.h |   80 
 4 files changed, 1122 insertions(+)
 create mode 100644 fs/pstore/blkzone.c
 create mode 100644 include/linux/pstore_blk.h

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index 8b3ba27..defcb75 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -152,3 +152,11 @@ config PSTORE_RAM
  "ramoops.ko".
 
  For more information, see Documentation/admin-guide/ramoops.rst.
+
+config PSTORE_BLK
+   tristate "Log panic/oops to a block device"
+   depends on PSTORE
+   depends on BLOCK
+   help
+ This enables panic and oops message to be logged to a block dev
+ where it can be read back at some later point.
diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
index 967b589..0ee2fc8 100644
--- a/fs/pstore/Makefile
+++ b/fs/pstore/Makefile
@@ -12,3 +12,6 @@ pstore-$(CONFIG_PSTORE_PMSG)  += pmsg.o
 
 ramoops-objs += ram.o ram_core.o
 obj-$(CONFIG_PSTORE_RAM)   += ramoops.o
+
+obj-$(CONFIG_PSTORE_BLK) += pstore_blk.o
+pstore_blk-y += blkzone.o
diff --git a/fs/pstore/blkzone.c b/fs/pstore/blkzone.c
new file mode 100644
index 000..cba55b3
--- /dev/null
+++ b/fs/pstore/blkzone.c
@@ -0,0 +1,1031 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *
+ * blkzone.c: Block device Oops/Panic logger
+ *
+ * Copyright (C) 2019 liaoweixiong 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define MODNAME "pstore-blk"
+#define pr_fmt(fmt) MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define PSTORE_BLKDEV "/dev/pstore-blk"
+
+/**
+ * struct blkz_head - head of zone to flush to storage
+ *
+ * @sig: signature to indicate header (BLK_SIG xor BLKZONE-type value)
+ * @datalen: length of data in @data
+ * @data: zone data.
+ */
+struct blkz_buffer {
+#define BLK_SIG (0x43474244) /* DBGC */
+   uint32_t sig;
+   atomic_t datalen;
+   uint8_t data[];
+};
+
+/**
+ * struct blkz_dmesg_header: dmesg information
+ *
+ * @magic: magic num for dmesg header
+ * @time: trigger time
+ * @compressed: whether conpressed
+ * @count: oops/panic counter
+ * @reason: identify oops or panic
+ */
+struct blkz_dmesg_header {
+#define DMESG_HEADER_MAGIC 0x4dfc3ae5
+   uint32_t magic;
+   struct timespec64 time;
+   bool compressed;
+   uint32_t counter;
+   enum kmsg_dump_reason reason;
+   uint8_t data[0];
+};
+
+/**
+ * struct blkz_zone - zone information
+ * @off:
+ * zone offset of block device
+ * @type:
+ * frontent type for this zone
+ * @name:
+ * frontent name for this zone
+ * @buffer:
+ * pointer to data buffer managed by this zone
+ * @buffer_size:
+ * bytes in @buffer->data
+ * @should_recover:
+ * should recover from storage
+ * @dirty:
+ * mark whether the data in @buffer are dirty (not flush to storage yet)
+ */
+struct blkz_zone {
+   unsigned long off;
+   const char *name;
+   enum pstore_type_id type;
+
+   struct blkz_buffer *buffer;
+   size_t buffer_size;
+   bool should_recover;
+   atomic_t dirty;
+};
+
+struct blkz_context {
+   struct blkz_zone **dbzs;/* dmesg block zones */
+   unsigned int dmesg_max_cnt;
+   unsigned int

[PATCH v11 3/4] pstore/blk: support pmsg for pstore block

2019-02-26 Thread liaoweixiong
To enable pmsg, just set pmsg_size when block device register blkzone.

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig  |  21 
 fs/pstore/blkoops.c|  10 ++
 fs/pstore/blkzone.c| 253 +
 include/linux/pstore_blk.h |   1 +
 4 files changed, 264 insertions(+), 21 deletions(-)

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index 7dfe00b..b417bf5 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -210,6 +210,27 @@ config PSTORE_BLKOOPS_DMESG_SIZE
 It is the first priority. Take care of that blkoops will take lower
 priority settings if higher priority one do not set.
 
+config PSTORE_BLKOOPS_PMSG_SIZE
+   int "pmsg size in kbytes for blkoops"
+   depends on PSTORE_BLKOOPS
+   default 64
+   help
+ This just sets size of pmsg (pmsg_size) for pstore/blk. The value must
+ be a multiple of 4096. Pmsg work only if "blkdev" is set.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. device tree
+It is set on device tree, which will overwrites value from Kconfig,
+but can also be overwritten by module parameters.
+ 3. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
 config PSTORE_BLKOOPS_TOTAL_SIZE
int "total size in kbytes for blkoops"
depends on PSTORE_BLKOOPS
diff --git a/fs/pstore/blkoops.c b/fs/pstore/blkoops.c
index 22c0c84..05140fd 100644
--- a/fs/pstore/blkoops.c
+++ b/fs/pstore/blkoops.c
@@ -30,6 +30,10 @@
 module_param(dmesg_size, long, 0400);
 MODULE_PARM_DESC(dmesg_size, "demsg size in kbytes");
 
+static long pmsg_size = -1;
+module_param(pmsg_size, long, 0400);
+MODULE_PARM_DESC(pmsg_size, "pmsg size in kbytes");
+
 static long total_size = -1;
 module_param(total_size, long, 0400);
 MODULE_PARM_DESC(total_size, "total size in kbytes");
@@ -47,11 +51,13 @@ struct blkz_info blkz_info = {
 
 struct blkoops_info {
unsigned long dmesg_size;
+   unsigned long pmsg_size;
unsigned long total_size;
const char *blkdev;
 };
 struct blkoops_info blkoops_info = {
.dmesg_size = CONFIG_PSTORE_BLKOOPS_DMESG_SIZE * 1024,
+   .pmsg_size = CONFIG_PSTORE_BLKOOPS_PMSG_SIZE * 1024,
.total_size = CONFIG_PSTORE_BLKOOPS_TOTAL_SIZE * 1024,
.blkdev = CONFIG_PSTORE_BLKOOPS_BLKDEV,
 };
@@ -104,6 +110,7 @@ static int blkoops_probe(struct platform_device *pdev)
 
check_size(total_size, 4096);
check_size(dmesg_size, 4096);
+   check_size(pmsg_size, 4096);
 
 #undef check_size
 
@@ -112,6 +119,7 @@ static int blkoops_probe(struct platform_device *pdev)
 * through /sys/module/blkoops/parameters/
 */
dmesg_size = blkz_info.dmesg_size;
+   pmsg_size = blkz_info.pmsg_size;
total_size = blkz_info.total_size;
if (blkz_info.blkdev)
strncpy(blkdev, blkz_info.blkdev, 80 - 1);
@@ -156,6 +164,8 @@ void blkoops_register_dummy(void)
info->blkdev = (const char *)blkdev;
if (dmesg_size >= 0)
info->dmesg_size = (unsigned long)dmesg_size * 1024;
+   if (pmsg_size >= 0)
+   info->pmsg_size = (unsigned long)pmsg_size * 1024;
} else if (info->total_size > 0 || strlen(info->blkdev)) {
pr_info("using kconfig value\n");
} else {
diff --git a/fs/pstore/blkzone.c b/fs/pstore/blkzone.c
index cba55b3..cd3d4ed 100644
--- a/fs/pstore/blkzone.c
+++ b/fs/pstore/blkzone.c
@@ -40,12 +40,14 @@
  *
  * @sig: signature to indicate header (BLK_SIG xor BLKZONE-type value)
  * @datalen: length of data in @data
+ * @start: offset into @data where the beginning of the stored bytes begin
  * @data: zone data.
  */
 struct blkz_buffer {
 #define BLK_SIG (0x43474244) /* DBGC */
uint32_t sig;
atomic_t datalen;
+   atomic_t start;
uint8_t data[];
 };
 
@@ -78,6 +80,9 @@ struct blkz_dmesg_header {
  * frontent name for this zone
  * @buffer:
  * pointer to data buffer managed by this zone
+ * @oldbuf:
+ * pointer to old data buffer. It is used for single zone such as pmsg,
+ * saving the old buffer.
  * @buffer_size:
  * bytes in @buffer->data
  * @should_recover:
@@ -91,6 +96,7 @@ struct blkz_zone {
enum pstore_type_id type;
 
struct blkz_buffer *buffer;
+   struct blkz_buffer *oldbuf;
size_t buffer_size;
bool should_recover;

[PATCH v11 0/4] pstore/block: new support logger for block devices

2019-02-26 Thread liaoweixiong
Why should we need pstore_block?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fast, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

[PATCH v11]
Change patchset label from RFC to PATCH

[PATCH v10]
Cancel DT support for blkoops temporarily.
On patch 1:
1. pstore/blk should unlink PSTORE_BLKDEV when unregister.
On patch 2:
1. cancel DT support temporarily. I will submit other patches to support DT
   when DT maintainers acked.
2. add spin lock to protect blkz_info when modify panic operations.
3. change default value of total size on Kconfig from 1024 to 0.

[PATCH v9]
On patch 1:
1. rename part_path/part_size, members of blkz_info, to blkdev/total_size
2. if total_size is zero, get size from @blkdev
3. support multiple variants for @blkdev, such as partuuid, major with minor,
   and /dev/. See details on Documentation.
4. get size from block device
5. add depends on CONFIG_BLOCK
On patch 2:
1. update document
On patch 3:
1. update codes for new blkzone. Blkoops support insmod without total_size.
   for example: "insmod ./blkoops.ko blkdev=93:6" (major:minor).
2. use late_initcalls rather than module_init, to avoid block device not ready.
3. support for block driver to add panic apis to blkoops. By this, block
   driver can do the least work that just provides panic operations.
On patch 5:
1. update document

[PATCH v8]
On patch 2:
1. move DT to /bindings/pstore
2. Delete details for kernel.

[PATCH v7]
On patch 1:
1. Fix line over 80 characters.
On patch 2:
1. Insert a separate patch for DT bindings.

[PATCH v6]
On patch 1:
1. Fix according to email from Kees Cook, including spelling mistakes,
   explicit overflow test, none of the zeroing etc.
2. Do not recover data but metadata of dmesg when panic.
3. No need to take recovery when do erase.
4. Do not use "blkoops" for blkzone any more because "blkoops" is used for
   other module now. (rename blkbuf to blkoops)
On patch 2:
1. Rename blkbuf to blkoops.
2. Add Kconfig/device tree/module parameters settings for blkoops.
3. Add document for device tree.
On patch 3:
1. Blkoops support pmsg.
2. Fix description for new version patch.
On patch 4:
1. Fix description for new version patch.

[PATCH v5]
On patch 1:
1. rename pstore/rom to pstore/blk
2. Do not allocate any memory in the write path of panic. So, use local
array instead in function romz_recover_dmesg_meta.
3. Add C header file "linux/fs.h" to fix implicit declaration of function
   'filp_open','kernel_read'...
On patch 3:
1. If panic, do not recover pmsg but flush if it is dirty.
2. Fix erase pmsg failed.
On patch 4:
1. Create a document for pstore/blk

[PATCH v4]
On patch 1:
1. Fix always true condition '(--i >= 0) => (0-u32max >= 0)' in function
   romz_init_zones by defining variable i to 'int' rahter than
   'unsigned int'.
2. To make codes more easily to read, we use macro READ_NEXT_ZONE for
   return value of romz_dmesg_read if it need to read next zone.
   Moveover, we assign READ_NEXT_ZONE -1024 rather than 0.
3. Add 'FLUSH_META' to 'enum romz_flush_mode' and rename 'NOT_FLUSH' to
   'FLUSH_NONE'
4. Function romz_zone_write work badly with FLUSH_PART mode as badly
   address and offset to write.
On patch 3:
NEW SUPPORT psmg for pstore_rom.

[PATCH v3]
On patch 1:
Fix build as module error for undefined 'vfs_read' and 'vfs_write'
Both of 'vfs_read' and 'vfs_write' haven't be exproted yet, so we use
'kernel_read' and 'kernel_write' instead.

[PATCH v2]
On patch 1:
Fix build as module error for redefinition of 'romz_unregister' and
'romz_register'

[PATCH v1]
On patch 1:
Core codes of pstore_rom, which works well on allwinner(sunxi) platform.
On patch 2:
A sample for pstore_rom, using general ram rather than block device.

liaoweixiong (4):
  pstore/blk: new support logger for block devices
  pstore/blk: add blkoops for pstore_blk
  pstore/blk: support pmsg for pstore block
  Documentation: pstore/blk: create document for pstore_blk

 Documentation/admin-guide/pstore-block.rst |  233 ++
 MAINTAINERS|3 +-
 fs/pstore/Kconfig  |  147 
 fs/pstore/Makefile |5 +
 fs/pstore/blkoops.c|  208 +
 fs/pstore/blkzone.c| 1242 
 include/linux/pstore_blk.h |   87 ++
 7 files changed, 1924 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/admin-guide/pstore-block.rst
 create mode 100644 fs/pstore/blkoops.c
 create mode 100644 fs/pstore/blkzone.c
 create mode 100644 include/linux/pstore_blk.h

-- 
1.9.1



[PATCH v11 4/4] Documentation: pstore/blk: create document for pstore_blk

2019-02-26 Thread liaoweixiong
The document, at Documentation/admin-guide/pstore-block.rst,
tells user how to use pstore_blk and the attentions about panic
read/write

Signed-off-by: liaoweixiong 
---
 Documentation/admin-guide/pstore-block.rst | 233 +
 MAINTAINERS|   1 +
 fs/pstore/Kconfig  |   4 +
 3 files changed, 238 insertions(+)
 create mode 100644 Documentation/admin-guide/pstore-block.rst

diff --git a/Documentation/admin-guide/pstore-block.rst 
b/Documentation/admin-guide/pstore-block.rst
new file mode 100644
index 000..a828274
--- /dev/null
+++ b/Documentation/admin-guide/pstore-block.rst
@@ -0,0 +1,233 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Pstore block oops/panic logger
+==
+
+Introduction
+
+
+Pstore block (pstore_blk) is an oops/panic logger that write its logs to block
+device before the system crashes. Pstore_blk needs block device driver
+registering a partition path of the block device, like /dev/mmcblk0p7 for mmc
+driver, and read/write APIs for this partition when on panic.
+
+Pstore block concepts
+-
+
+Pstore block begins at function ``blkz_register``, by which block driver
+registers to pstore_blk. Note that, block driver should register to pstore_blk
+after block device has registered. Block driver transfers a structure
+``blkz_info`` which is defined in *linux/pstore_blk.h*.
+
+The following key members of ``struct blkz_info`` may be of interest to you.
+
+blkdev
+~~
+
+The block device to use. Most of the time, it is a partition of block device.
+It's ok to keep it as NULL if you passing ``read`` and ``write`` in blkz_info 
as
+``blkdev`` is used by blkz_default_general_read/write. If both of ``blkdev``,
+``read`` and ``write`` are NULL, no block device is effective and the data will
+be saved in ddr buffer.
+
+It accept the following variants:
+
+1.  device number in hexadecimal represents itself no
+   leading 0x, for example b302.
+#. /dev/ represents the device number of disk
+#. /dev/ represents the device number of partition - device
+   number of disk plus the partition number
+#. /dev/p - same as the above, that form is used when disk
+   name of partitioned disk ends on a digit.
+#. PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF representing the unique id of
+   a partition if the partition table provides it. The UUID may be either an
+   EFI/GPT UUID, or refer to an MSDOS partition using the format -PP,
+   where  is a zero-filled hex representation of the 32-bit
+   "NT disk signature", and PP is a zero-filled hex representation of the
+   1-based partition number.
+#. PARTUUID=/PARTNROFF= to select a partition in relation to a
+   partition with a known unique id.
+#. : major and minor number of the device separated by a colon.
+
+See more on section **read/write**.
+
+total_size
+~~
+
+The total size in bytes of block device used for pstore_blk. It **MUST** be 
less
+than or equal to size of block device if ``blkdev`` valid. It **MUST** be a
+multiple of 4096. If ``total_size`` is zero with ``blkdev``, ``total_size`` 
will be
+set to equal to size of ``blkdev``.
+
+The block device area is divided into many chunks, and each event writes a 
chunk
+of information.
+
+dmesg_size
+~~
+
+The chunk size in bytes for dmesg(oops/panic). It **MUST** be a multiple of
+SECTOR_SIZE (Most of the time, the SECTOR_SIZE is 512). If you don't need 
dmesg,
+you are safely to set it to 0.
+
+NOTE that, the remaining space, except ``pmsg_size`` and others, belongs to
+dmesg. It means that there are multiple chunks for dmesg.
+
+Psotre_blk will log to dmesg chunks one by one, and always overwrite the oldest
+chunk if no free chunk.
+
+pmsg_size
+~
+
+The chunk size in bytes for pmsg. It **MUST** be a multiple of SECTOR_SIZE 
(Most
+of the time, the SECTOR_SIZE is 512). If you don't need pmsg, you are safely to
+set it to 0.
+
+There is only one chunk for pmsg.
+
+Pmsg is a user space accessible pstore object. Writes to */dev/pmsg0* are
+appended to the chunk. On reboot the contents are available in
+/sys/fs/pstore/pmsg-pstore-blk-0.
+
+dump_oops
+~
+
+Dumping both oopses and panics can be done by setting 1 in the ``dump_oops``
+member while setting 0 in that variable dumps only the panics.
+
+read/write
+~~
+
+They are general ``read/write`` APIs. It is safely and recommended to ignore 
it,
+but set ``blkdev``.
+
+These general APIs are used all the time expect panic. The ``read`` API is
+usually used to recover data from block device, and the ``write`` API is 
usually
+to flush new data and erase to block device.
+
+Pstore_blk will temporarily hold all new data before block device is ready. If
+you ignore both of ``read/write`` and ``blkdev``, the old data will be lost.
+
+NOTE that, the general APIs must check whether the block device is ready if
+self-defined.
+
+panic_read/p

Re: [RFC v10 0/4] pstore/block: new support logger for block devices

2019-02-26 Thread liaoweixiong


On 2019-02-26 19:20, Greg Kroah-Hartman wrote:
> On Tue, Feb 26, 2019 at 02:33:41PM +0800, liaoweixiong wrote:
>> Why should we need pstore_block?
>> 1. Most embedded intelligent equipment have no persistent ram, which
>> increases costs. We perfer to cheaper solutions, like block devices.
>> In fast, there is already a sample for block device logger in driver
>> MTD (drivers/mtd/mtdoops.c).
>> 2. Do not any equipment have battery, which means that it lost all data
>> on general ram if power failure. Pstore has little to do for these
>> equipments.
>>
>> [PATCH v10]
> 
> Why are you still labeling these as "RFC"?  No one should actually be
> applying a Request For Comments patchset, as you obviously are not
> thinking it is ready to be merged :(
> 
> After 10 revisions, I hope you are confident in this patchset :)
> 

I'm confident in this patchset :) . It is first time for me to submit
RFC patches, i just don't know i should change the label to PATCH. Thank
you for reminding me.

> thanks,
> 
> greg k-h
> 

-- 
liaoweixiong


[RFC v10 2/4] pstore/blk: add blkoops for pstore_blk

2019-02-25 Thread liaoweixiong
blkoops is a sample for pstore/blk. It can only record oops, excluding
panics as no read/write apis for panic registered. It support settings
on Kconfg/module parameters. It can record oops log even power failure
if "PSTORE_BLKOOPS_BLKDEV" on Kconfig or "blkdev" on module parameter
is valid. Otherwise, it can only record data to ram buffer, which will
be dropped when reboot.

Signed-off-by: liaoweixiong 
---
 MAINTAINERS|   2 +-
 fs/pstore/Kconfig  | 114 ++
 fs/pstore/Makefile |   2 +
 fs/pstore/blkoops.c| 198 +
 include/linux/pstore_blk.h |  14 +++-
 5 files changed, 325 insertions(+), 5 deletions(-)
 create mode 100644 fs/pstore/blkoops.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 51029a4..4e9242a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12318,7 +12318,7 @@ F:  drivers/firmware/efi/efi-pstore.c
 F: drivers/acpi/apei/erst.c
 F: Documentation/admin-guide/ramoops.rst
 F: Documentation/devicetree/bindings/reserved-memory/ramoops.txt
-K: \b(pstore|ramoops)
+K: \b(pstore|ramoops|blkoops)
 
 PTP HARDWARE CLOCK SUPPORT
 M: Richard Cochran 
diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index defcb75..7dfe00b 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -160,3 +160,117 @@ config PSTORE_BLK
help
  This enables panic and oops message to be logged to a block dev
  where it can be read back at some later point.
+
+config PSTORE_BLKOOPS
+   tristate "pstore block with oops logger"
+   depends on PSTORE_BLK
+   help
+ This is a sample for pstore block with oops logger.
+
+ It CANNOT record panic log as no read/write apis for panic registered.
+
+ It CAN record oops log even power failure if
+ "PSTORE_BLKOOPS_BLKDEV" on Kconfig or "block-device" on dts or
+ "blkdev" on module parameter is valid.
+
+ Otherwise, it can only record data to ram buffer, which will be
+ dropped when reboot.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. device tree
+It is set on device tree, which will overwrites value from Kconfig,
+but can also be overwritten by module parameters.
+ 3. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
+config PSTORE_BLKOOPS_DMESG_SIZE
+   int "dmesg size in kbytes for blkoops"
+   depends on PSTORE_BLKOOPS
+   default 64
+   help
+ This just sets size of dmesg (dmesg_size) for pstore/blk. The value
+ must be a multiple of 4096.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. device tree
+It is set on device tree, which will overwrites value from Kconfig,
+but can also be overwritten by module parameters.
+ 3. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
+config PSTORE_BLKOOPS_TOTAL_SIZE
+   int "total size in kbytes for blkoops"
+   depends on PSTORE_BLKOOPS
+   default 0
+   help
+ The total size in kbytes pstore/blk can use. It must be less than or
+ equal to size of block device if @blkdev valid. If @total_size is zero
+ with @blkdev, @total_size will be set to equal to size of @blkdev.
+ The value must be a multiple of 4096.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. device tree
+It is set on device tree, which will overwrites value from Kconfig,
+but can also be overwritten by module parameters.
+ 3. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
+config PSTORE_BLKOOPS_BLKDEV
+   string "block device 

[RFC v10 0/4] pstore/block: new support logger for block devices

2019-02-25 Thread liaoweixiong
Why should we need pstore_block?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fast, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

[PATCH v10]
Cancel DT support for blkoops temporarily.
On patch 1:
1. pstore/blk should unlink PSTORE_BLKDEV when unregister.
On patch 2:
1. cancel DT support temporarily. I will submit other patches to support DT
   when DT maintainers acked.
2. add spin lock to protect blkz_info when modify panic operations.
3. change default value of total size on Kconfig from 1024 to 0.

[PATCH v9]
On patch 1:
1. rename part_path/part_size, members of blkz_info, to blkdev/total_size
2. if total_size is zero, get size from @blkdev
3. support multiple variants for @blkdev, such as partuuid, major with minor,
   and /dev/. See details on Documentation.
4. get size from block device
5. add depends on CONFIG_BLOCK
On patch 2:
1. update document
On patch 3:
1. update codes for new blkzone. Blkoops support insmod without total_size.
   for example: "insmod ./blkoops.ko blkdev=93:6" (major:minor).
2. use late_initcalls rather than module_init, to avoid block device not ready.
3. support for block driver to add panic apis to blkoops. By this, block
   driver can do the least work that just provides panic operations.
On patch 5:
1. update document

[PATCH v8]
On patch 2:
1. move DT to /bindings/pstore
2. Delete details for kernel.

[PATCH v7]
On patch 1:
1. Fix line over 80 characters.
On patch 2:
1. Insert a separate patch for DT bindings.

[PATCH v6]
On patch 1:
1. Fix according to email from Kees Cook, including spelling mistakes,
   explicit overflow test, none of the zeroing etc.
2. Do not recover data but metadata of dmesg when panic.
3. No need to take recovery when do erase.
4. Do not use "blkoops" for blkzone any more because "blkoops" is used for
   other module now. (rename blkbuf to blkoops)
On patch 2:
1. Rename blkbuf to blkoops.
2. Add Kconfig/device tree/module parameters settings for blkoops.
3. Add document for device tree.
On patch 3:
1. Blkoops support pmsg.
2. Fix description for new version patch.
On patch 4:
1. Fix description for new version patch.

[PATCH v5]
On patch 1:
1. rename pstore/rom to pstore/blk
2. Do not allocate any memory in the write path of panic. So, use local
array instead in function romz_recover_dmesg_meta.
3. Add C header file "linux/fs.h" to fix implicit declaration of function
   'filp_open','kernel_read'...
On patch 3:
1. If panic, do not recover pmsg but flush if it is dirty.
2. Fix erase pmsg failed.
On patch 4:
1. Create a document for pstore/blk

[PATCH v4]
On patch 1:
1. Fix always true condition '(--i >= 0) => (0-u32max >= 0)' in function
   romz_init_zones by defining variable i to 'int' rahter than
   'unsigned int'.
2. To make codes more easily to read, we use macro READ_NEXT_ZONE for
   return value of romz_dmesg_read if it need to read next zone.
   Moveover, we assign READ_NEXT_ZONE -1024 rather than 0.
3. Add 'FLUSH_META' to 'enum romz_flush_mode' and rename 'NOT_FLUSH' to
   'FLUSH_NONE'
4. Function romz_zone_write work badly with FLUSH_PART mode as badly
   address and offset to write.
On patch 3:
NEW SUPPORT psmg for pstore_rom.

[PATCH v3]
On patch 1:
Fix build as module error for undefined 'vfs_read' and 'vfs_write'
Both of 'vfs_read' and 'vfs_write' haven't be exproted yet, so we use
'kernel_read' and 'kernel_write' instead.

[PATCH v2]
On patch 1:
Fix build as module error for redefinition of 'romz_unregister' and
'romz_register'

[PATCH v1]
On patch 1:
Core codes of pstore_rom, which works well on allwinner(sunxi) platform.
On patch 2:
A sample for pstore_rom, using general ram rather than block device.

liaoweixiong (4):
  pstore/blk: new support logger for block devices
  pstore/blk: add blkoops for pstore_blk
  pstore/blk: support pmsg for pstore block
  Documentation: pstore/blk: create document for pstore_blk

 Documentation/admin-guide/pstore-block.rst |  233 ++
 MAINTAINERS|3 +-
 fs/pstore/Kconfig  |  147 
 fs/pstore/Makefile |5 +
 fs/pstore/blkoops.c|  206 +
 fs/pstore/blkzone.c| 1244 
 include/linux/pstore_blk.h |   87 ++
 7 files changed, 1924 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/admin-guide/pstore-block.rst
 create mode 100644 fs/pstore/blkoops.c
 create mode 100644 fs/pstore/blkzone.c
 create mode 100644 include/linux/pstore_blk.h

-- 
1.9.1



[RFC v10 4/4] Documentation: pstore/blk: create document for pstore_blk

2019-02-25 Thread liaoweixiong
The document, at Documentation/admin-guide/pstore-block.rst,
tells user how to use pstore_blk and the attentions about panic
read/write

Signed-off-by: liaoweixiong 
---
 Documentation/admin-guide/pstore-block.rst | 233 +
 MAINTAINERS|   1 +
 fs/pstore/Kconfig  |   4 +
 3 files changed, 238 insertions(+)
 create mode 100644 Documentation/admin-guide/pstore-block.rst

diff --git a/Documentation/admin-guide/pstore-block.rst 
b/Documentation/admin-guide/pstore-block.rst
new file mode 100644
index 000..a828274
--- /dev/null
+++ b/Documentation/admin-guide/pstore-block.rst
@@ -0,0 +1,233 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Pstore block oops/panic logger
+==
+
+Introduction
+
+
+Pstore block (pstore_blk) is an oops/panic logger that write its logs to block
+device before the system crashes. Pstore_blk needs block device driver
+registering a partition path of the block device, like /dev/mmcblk0p7 for mmc
+driver, and read/write APIs for this partition when on panic.
+
+Pstore block concepts
+-
+
+Pstore block begins at function ``blkz_register``, by which block driver
+registers to pstore_blk. Note that, block driver should register to pstore_blk
+after block device has registered. Block driver transfers a structure
+``blkz_info`` which is defined in *linux/pstore_blk.h*.
+
+The following key members of ``struct blkz_info`` may be of interest to you.
+
+blkdev
+~~
+
+The block device to use. Most of the time, it is a partition of block device.
+It's ok to keep it as NULL if you passing ``read`` and ``write`` in blkz_info 
as
+``blkdev`` is used by blkz_default_general_read/write. If both of ``blkdev``,
+``read`` and ``write`` are NULL, no block device is effective and the data will
+be saved in ddr buffer.
+
+It accept the following variants:
+
+1.  device number in hexadecimal represents itself no
+   leading 0x, for example b302.
+#. /dev/ represents the device number of disk
+#. /dev/ represents the device number of partition - device
+   number of disk plus the partition number
+#. /dev/p - same as the above, that form is used when disk
+   name of partitioned disk ends on a digit.
+#. PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF representing the unique id of
+   a partition if the partition table provides it. The UUID may be either an
+   EFI/GPT UUID, or refer to an MSDOS partition using the format -PP,
+   where  is a zero-filled hex representation of the 32-bit
+   "NT disk signature", and PP is a zero-filled hex representation of the
+   1-based partition number.
+#. PARTUUID=/PARTNROFF= to select a partition in relation to a
+   partition with a known unique id.
+#. : major and minor number of the device separated by a colon.
+
+See more on section **read/write**.
+
+total_size
+~~
+
+The total size in bytes of block device used for pstore_blk. It **MUST** be 
less
+than or equal to size of block device if ``blkdev`` valid. It **MUST** be a
+multiple of 4096. If ``total_size`` is zero with ``blkdev``, ``total_size`` 
will be
+set to equal to size of ``blkdev``.
+
+The block device area is divided into many chunks, and each event writes a 
chunk
+of information.
+
+dmesg_size
+~~
+
+The chunk size in bytes for dmesg(oops/panic). It **MUST** be a multiple of
+SECTOR_SIZE (Most of the time, the SECTOR_SIZE is 512). If you don't need 
dmesg,
+you are safely to set it to 0.
+
+NOTE that, the remaining space, except ``pmsg_size`` and others, belongs to
+dmesg. It means that there are multiple chunks for dmesg.
+
+Psotre_blk will log to dmesg chunks one by one, and always overwrite the oldest
+chunk if no free chunk.
+
+pmsg_size
+~
+
+The chunk size in bytes for pmsg. It **MUST** be a multiple of SECTOR_SIZE 
(Most
+of the time, the SECTOR_SIZE is 512). If you don't need pmsg, you are safely to
+set it to 0.
+
+There is only one chunk for pmsg.
+
+Pmsg is a user space accessible pstore object. Writes to */dev/pmsg0* are
+appended to the chunk. On reboot the contents are available in
+/sys/fs/pstore/pmsg-pstore-blk-0.
+
+dump_oops
+~
+
+Dumping both oopses and panics can be done by setting 1 in the ``dump_oops``
+member while setting 0 in that variable dumps only the panics.
+
+read/write
+~~
+
+They are general ``read/write`` APIs. It is safely and recommended to ignore 
it,
+but set ``blkdev``.
+
+These general APIs are used all the time expect panic. The ``read`` API is
+usually used to recover data from block device, and the ``write`` API is 
usually
+to flush new data and erase to block device.
+
+Pstore_blk will temporarily hold all new data before block device is ready. If
+you ignore both of ``read/write`` and ``blkdev``, the old data will be lost.
+
+NOTE that, the general APIs must check whether the block device is ready if
+self-defined.
+
+panic_read/p

[RFC v10 3/4] pstore/blk: support pmsg for pstore block

2019-02-25 Thread liaoweixiong
To enable pmsg, just set pmsg_size when block device register blkzone.

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig  |  21 
 fs/pstore/blkoops.c|  10 ++
 fs/pstore/blkzone.c| 253 +
 include/linux/pstore_blk.h |   1 +
 4 files changed, 264 insertions(+), 21 deletions(-)

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index 7dfe00b..b417bf5 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -210,6 +210,27 @@ config PSTORE_BLKOOPS_DMESG_SIZE
 It is the first priority. Take care of that blkoops will take lower
 priority settings if higher priority one do not set.
 
+config PSTORE_BLKOOPS_PMSG_SIZE
+   int "pmsg size in kbytes for blkoops"
+   depends on PSTORE_BLKOOPS
+   default 64
+   help
+ This just sets size of pmsg (pmsg_size) for pstore/blk. The value must
+ be a multiple of 4096. Pmsg work only if "blkdev" is set.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. device tree
+It is set on device tree, which will overwrites value from Kconfig,
+but can also be overwritten by module parameters.
+ 3. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
 config PSTORE_BLKOOPS_TOTAL_SIZE
int "total size in kbytes for blkoops"
depends on PSTORE_BLKOOPS
diff --git a/fs/pstore/blkoops.c b/fs/pstore/blkoops.c
index 22c0c84..05140fd 100644
--- a/fs/pstore/blkoops.c
+++ b/fs/pstore/blkoops.c
@@ -30,6 +30,10 @@
 module_param(dmesg_size, long, 0400);
 MODULE_PARM_DESC(dmesg_size, "demsg size in kbytes");
 
+static long pmsg_size = -1;
+module_param(pmsg_size, long, 0400);
+MODULE_PARM_DESC(pmsg_size, "pmsg size in kbytes");
+
 static long total_size = -1;
 module_param(total_size, long, 0400);
 MODULE_PARM_DESC(total_size, "total size in kbytes");
@@ -47,11 +51,13 @@ struct blkz_info blkz_info = {
 
 struct blkoops_info {
unsigned long dmesg_size;
+   unsigned long pmsg_size;
unsigned long total_size;
const char *blkdev;
 };
 struct blkoops_info blkoops_info = {
.dmesg_size = CONFIG_PSTORE_BLKOOPS_DMESG_SIZE * 1024,
+   .pmsg_size = CONFIG_PSTORE_BLKOOPS_PMSG_SIZE * 1024,
.total_size = CONFIG_PSTORE_BLKOOPS_TOTAL_SIZE * 1024,
.blkdev = CONFIG_PSTORE_BLKOOPS_BLKDEV,
 };
@@ -104,6 +110,7 @@ static int blkoops_probe(struct platform_device *pdev)
 
check_size(total_size, 4096);
check_size(dmesg_size, 4096);
+   check_size(pmsg_size, 4096);
 
 #undef check_size
 
@@ -112,6 +119,7 @@ static int blkoops_probe(struct platform_device *pdev)
 * through /sys/module/blkoops/parameters/
 */
dmesg_size = blkz_info.dmesg_size;
+   pmsg_size = blkz_info.pmsg_size;
total_size = blkz_info.total_size;
if (blkz_info.blkdev)
strncpy(blkdev, blkz_info.blkdev, 80 - 1);
@@ -156,6 +164,8 @@ void blkoops_register_dummy(void)
info->blkdev = (const char *)blkdev;
if (dmesg_size >= 0)
info->dmesg_size = (unsigned long)dmesg_size * 1024;
+   if (pmsg_size >= 0)
+   info->pmsg_size = (unsigned long)pmsg_size * 1024;
} else if (info->total_size > 0 || strlen(info->blkdev)) {
pr_info("using kconfig value\n");
} else {
diff --git a/fs/pstore/blkzone.c b/fs/pstore/blkzone.c
index cba55b3..cd3d4ed 100644
--- a/fs/pstore/blkzone.c
+++ b/fs/pstore/blkzone.c
@@ -40,12 +40,14 @@
  *
  * @sig: signature to indicate header (BLK_SIG xor BLKZONE-type value)
  * @datalen: length of data in @data
+ * @start: offset into @data where the beginning of the stored bytes begin
  * @data: zone data.
  */
 struct blkz_buffer {
 #define BLK_SIG (0x43474244) /* DBGC */
uint32_t sig;
atomic_t datalen;
+   atomic_t start;
uint8_t data[];
 };
 
@@ -78,6 +80,9 @@ struct blkz_dmesg_header {
  * frontent name for this zone
  * @buffer:
  * pointer to data buffer managed by this zone
+ * @oldbuf:
+ * pointer to old data buffer. It is used for single zone such as pmsg,
+ * saving the old buffer.
  * @buffer_size:
  * bytes in @buffer->data
  * @should_recover:
@@ -91,6 +96,7 @@ struct blkz_zone {
enum pstore_type_id type;
 
struct blkz_buffer *buffer;
+   struct blkz_buffer *oldbuf;
size_t buffer_size;
bool should_recover;

[RFC v10 1/4] pstore/blk: new support logger for block devices

2019-02-25 Thread liaoweixiong
pstore_blk is similar to pstore_ram, but dump log to block devices
rather than persistent ram.

Why should we need pstore_blk?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fact, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

pstore_blk can only dump Oops/Panic log to block devices. It only
supports dmesg now. To make pstore_blk work, the block driver should
provide the block device and the read/write apis when on panic.

pstore_blk begins at 'blkz_register', by witch block device can register
a block device to pstore_blk. Then pstore_blk divide and manage the
block device as zones, which is similar to pstore_ram.

Recommend that, block driver register pstore_blk after block device is
ready.

pstore_blk works well on allwinner(sunxi) platform.

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig  |8 +
 fs/pstore/Makefile |3 +
 fs/pstore/blkzone.c| 1031 
 include/linux/pstore_blk.h |   80 
 4 files changed, 1122 insertions(+)
 create mode 100644 fs/pstore/blkzone.c
 create mode 100644 include/linux/pstore_blk.h

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index 8b3ba27..defcb75 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -152,3 +152,11 @@ config PSTORE_RAM
  "ramoops.ko".
 
  For more information, see Documentation/admin-guide/ramoops.rst.
+
+config PSTORE_BLK
+   tristate "Log panic/oops to a block device"
+   depends on PSTORE
+   depends on BLOCK
+   help
+ This enables panic and oops message to be logged to a block dev
+ where it can be read back at some later point.
diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
index 967b589..0ee2fc8 100644
--- a/fs/pstore/Makefile
+++ b/fs/pstore/Makefile
@@ -12,3 +12,6 @@ pstore-$(CONFIG_PSTORE_PMSG)  += pmsg.o
 
 ramoops-objs += ram.o ram_core.o
 obj-$(CONFIG_PSTORE_RAM)   += ramoops.o
+
+obj-$(CONFIG_PSTORE_BLK) += pstore_blk.o
+pstore_blk-y += blkzone.o
diff --git a/fs/pstore/blkzone.c b/fs/pstore/blkzone.c
new file mode 100644
index 000..cba55b3
--- /dev/null
+++ b/fs/pstore/blkzone.c
@@ -0,0 +1,1031 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *
+ * blkzone.c: Block device Oops/Panic logger
+ *
+ * Copyright (C) 2019 liaoweixiong 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define MODNAME "pstore-blk"
+#define pr_fmt(fmt) MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define PSTORE_BLKDEV "/dev/pstore-blk"
+
+/**
+ * struct blkz_head - head of zone to flush to storage
+ *
+ * @sig: signature to indicate header (BLK_SIG xor BLKZONE-type value)
+ * @datalen: length of data in @data
+ * @data: zone data.
+ */
+struct blkz_buffer {
+#define BLK_SIG (0x43474244) /* DBGC */
+   uint32_t sig;
+   atomic_t datalen;
+   uint8_t data[];
+};
+
+/**
+ * struct blkz_dmesg_header: dmesg information
+ *
+ * @magic: magic num for dmesg header
+ * @time: trigger time
+ * @compressed: whether conpressed
+ * @count: oops/panic counter
+ * @reason: identify oops or panic
+ */
+struct blkz_dmesg_header {
+#define DMESG_HEADER_MAGIC 0x4dfc3ae5
+   uint32_t magic;
+   struct timespec64 time;
+   bool compressed;
+   uint32_t counter;
+   enum kmsg_dump_reason reason;
+   uint8_t data[0];
+};
+
+/**
+ * struct blkz_zone - zone information
+ * @off:
+ * zone offset of block device
+ * @type:
+ * frontent type for this zone
+ * @name:
+ * frontent name for this zone
+ * @buffer:
+ * pointer to data buffer managed by this zone
+ * @buffer_size:
+ * bytes in @buffer->data
+ * @should_recover:
+ * should recover from storage
+ * @dirty:
+ * mark whether the data in @buffer are dirty (not flush to storage yet)
+ */
+struct blkz_zone {
+   unsigned long off;
+   const char *name;
+   enum pstore_type_id type;
+
+   struct blkz_buffer *buffer;
+   size_t buffer_size;
+   bool should_recover;
+   atomic_t dirty;
+};
+
+struct blkz_context {
+   struct blkz_zone **dbzs;/* dmesg block zones */
+   unsigned int dmesg_max_cnt;
+   unsigned int

Re: [RFC v9 2/5] dt-bindings: pstore-block: new support for blkoops

2019-02-25 Thread liaoweixiong


On 2019-02-22 23:36, Rob Herring wrote:
> +boot-architecture list
> 
> On Tue, Feb 19, 2019 at 07:52:47PM +0800, liaoweixiong wrote:
>> Create DT binding document for blkoops.
>>
>> Signed-off-by: liaoweixiong 
>> ---
>>  .../devicetree/bindings/pstore/blkoops.txt | 53 
>> ++
>>  MAINTAINERS|  1 +
>>  2 files changed, 54 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/pstore/blkoops.txt
>>
>> diff --git a/Documentation/devicetree/bindings/pstore/blkoops.txt 
>> b/Documentation/devicetree/bindings/pstore/blkoops.txt
>> new file mode 100644
>> index 000..5462915
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pstore/blkoops.txt
>> @@ -0,0 +1,53 @@
>> +Blkoops oops logger
>> +===
>> +
>> +Blkoops provides a block partition for oops, excluding panics now, so they 
>> can
>> +be recovered after a reboot.
>> +
>> +Any space of block device will be used for a circular buffer of oops 
>> records.
>> +These records have a configurable size, with a size of 0 indicating that 
>> they
>> +should be disabled.
>> +
>> +At least one of "block-device" and "total_size" must be set.
>> +
>> +At least one of "dmesg-size" or "pmsg-size" must be set non-zero.
>> +
>> +Required properties:
>> +
>> +- compatible: must be "blkoops".
>> +
>> +Optional properties:
>> +
>> +- block-device: The block device to use. Most of the time, it is a 
>> partition of
>> +device. If block-device is NULL, no block device is effective
>> +and the data will be lost after rebooting.
>> +It accept the following variants:
>> +1)  device number in hexadecimal
>> +   represents itself no leading 0x, for example b302.
>> +2) /dev/ represents the device number of disk
>> +3) /dev/ represents the device number of
>> +   partition - device number of disk plus the partition number
>> +4) /dev/p - same as the above, that form is
>> +   used when disk name of partitioned disk ends on a digit.
>> +5) PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF representing
>> +   the unique id of a partition if the partition table provides
>> +   it. The UUID may be either an EFI/GPT UUID, or refer to an
>> +   MSDOS partition using the format -PP, where 
>> +   is a zero-filled hex representation of the 32-bit
>> +   "NT disk signature", and PP is a zero-filled hex
>> +   representation of the 1-based partition number.
>> +6) PARTUUID=/PARTNROFF= to select a partition in
>> +   relation to a partition with a known unique id.
>> +7) : major and minor number of the device
>> +   separated by a colon.
> 
> No.
> 
> I didn't suggest to go look at PARTUUID to copy it into the binding, but 
> rather to point out that the kernel can already mount by UUID. 
> Specifying the UUID in DT is also not what I suggested. My suggestion is 
> to define a known UUID so that the kernel (and bootloaders, userspace, 
> the world) can just know the UUID. Just like the EFI system partition. 
> Now this means you have to get it defined in the UEFI specification 
> (or maybe EBBR[1]). If you want help with how to do that, the 
> boot-architecture list is a good place to start.
> 

Thanks for your suggestion. I don't know whether it is a good idea to
define a known UUID for pstore/blk in the UEFI specification. This
property is only used for pstore/blk to know which block device it can
use. It only works on linux. I think more thorough and rigorous
consideration is needed.
Besides that, mbr partition table has no partition UUID, how can it to
be compatible with mbr?

> major/minor numbers are a Linux thing, so they don't go in DT.
> /dev/* is Linux thing, so it doesn't go in DT.
> 
> You can always define all these parameters as kernel command line 
> options and avoid DT. That would also make this work on *all* systems, 
> not just DT based systems. (Though I still believe that the partition 
> should be discoverable.)
> 

The pstore/blk has already support command line. It now has 3
configuration methods, they are kconfig, DT and module parameters. I
will cancel DT support on next version until we discuss a viable
approach by this mail and than i will submit other patches to implement
DT. Is this ok?

> Rob
> 
> [1] https://github.com/ARM-software/ebbr
> 

-- 
liaoweixiong


[RFC v9 1/5] pstore/blk: new support logger for block devices

2019-02-19 Thread liaoweixiong
pstore_blk is similar to pstore_ram, but dump log to block devices
rather than persistent ram.

Why should we need pstore_blk?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fact, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

pstore_blk can only dump Oops/Panic log to block devices. It only
supports dmesg now. To make pstore_blk work, the block driver should
provide the block device and the read/write apis when on panic.

pstore_blk begins at 'blkz_register', by witch block device can register
a block device to pstore_blk. Then pstore_blk divide and manage the
block device as zones, which is similar to pstore_ram.

Recommend that, block driver register pstore_blk after block device is
ready.

pstore_blk works well on allwinner(sunxi) platform.

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig  |8 +
 fs/pstore/Makefile |3 +
 fs/pstore/blkzone.c| 1013 
 include/linux/pstore_blk.h |   80 
 4 files changed, 1104 insertions(+)
 create mode 100644 fs/pstore/blkzone.c
 create mode 100644 include/linux/pstore_blk.h

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index 8b3ba27..defcb75 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -152,3 +152,11 @@ config PSTORE_RAM
  "ramoops.ko".
 
  For more information, see Documentation/admin-guide/ramoops.rst.
+
+config PSTORE_BLK
+   tristate "Log panic/oops to a block device"
+   depends on PSTORE
+   depends on BLOCK
+   help
+ This enables panic and oops message to be logged to a block dev
+ where it can be read back at some later point.
diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
index 967b589..0ee2fc8 100644
--- a/fs/pstore/Makefile
+++ b/fs/pstore/Makefile
@@ -12,3 +12,6 @@ pstore-$(CONFIG_PSTORE_PMSG)  += pmsg.o
 
 ramoops-objs += ram.o ram_core.o
 obj-$(CONFIG_PSTORE_RAM)   += ramoops.o
+
+obj-$(CONFIG_PSTORE_BLK) += pstore_blk.o
+pstore_blk-y += blkzone.o
diff --git a/fs/pstore/blkzone.c b/fs/pstore/blkzone.c
new file mode 100644
index 000..83dd181
--- /dev/null
+++ b/fs/pstore/blkzone.c
@@ -0,0 +1,1013 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *
+ * blkzone.c: Block device Oops/Panic logger
+ *
+ * Copyright (C) 2019 liaoweixiong 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define MODNAME "pstore-blk"
+#define pr_fmt(fmt) MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+
+#define PSTORE_BLKDEV "/dev/pstore-blk"
+
+/**
+ * struct blkz_head - head of zone to flush to storage
+ *
+ * @sig: signature to indicate header (BLK_SIG xor BLKZONE-type value)
+ * @datalen: length of data in @data
+ * @data: zone data.
+ */
+struct blkz_buffer {
+#define BLK_SIG (0x43474244) /* DBGC */
+   uint32_t sig;
+   atomic_t datalen;
+   uint8_t data[];
+};
+
+/**
+ * struct blkz_dmesg_header: dmesg information
+ *
+ * @magic: magic num for dmesg header
+ * @time: trigger time
+ * @compressed: whether conpressed
+ * @count: oops/panic counter
+ * @reason: identify oops or panic
+ */
+struct blkz_dmesg_header {
+#define DMESG_HEADER_MAGIC 0x4dfc3ae5
+   uint32_t magic;
+   struct timespec64 time;
+   bool compressed;
+   uint32_t counter;
+   enum kmsg_dump_reason reason;
+   uint8_t data[0];
+};
+
+/**
+ * struct blkz_zone - zone information
+ * @off:
+ * zone offset of block device
+ * @type:
+ * frontent type for this zone
+ * @name:
+ * frontent name for this zone
+ * @buffer:
+ * pointer to data buffer managed by this zone
+ * @buffer_size:
+ * bytes in @buffer->data
+ * @should_recover:
+ * should recover from storage
+ * @dirty:
+ * mark whether the data in @buffer are dirty (not flush to storage yet)
+ */
+struct blkz_zone {
+   unsigned long off;
+   const char *name;
+   enum pstore_type_id type;
+
+   struct blkz_buffer *buffer;
+   size_t buffer_size;
+   bool should_recover;
+   atomic_t dirty;
+};
+
+struct blkz_context {
+   struct blkz_zone **dbzs;/* dmesg block zones */
+   unsigned int dmesg_max_cnt;
+   unsigned int

[RFC v9 5/5] Documentation: pstore/blk: create document for pstore_blk

2019-02-19 Thread liaoweixiong
The document, at Documentation/admin-guide/pstore-block.rst,
tells user how to use pstore_blk and the attentions about panic
read/write

Signed-off-by: liaoweixiong 
---
 Documentation/admin-guide/pstore-block.rst | 233 +
 MAINTAINERS|   1 +
 fs/pstore/Kconfig  |   4 +
 3 files changed, 238 insertions(+)
 create mode 100644 Documentation/admin-guide/pstore-block.rst

diff --git a/Documentation/admin-guide/pstore-block.rst 
b/Documentation/admin-guide/pstore-block.rst
new file mode 100644
index 000..a828274
--- /dev/null
+++ b/Documentation/admin-guide/pstore-block.rst
@@ -0,0 +1,233 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Pstore block oops/panic logger
+==
+
+Introduction
+
+
+Pstore block (pstore_blk) is an oops/panic logger that write its logs to block
+device before the system crashes. Pstore_blk needs block device driver
+registering a partition path of the block device, like /dev/mmcblk0p7 for mmc
+driver, and read/write APIs for this partition when on panic.
+
+Pstore block concepts
+-
+
+Pstore block begins at function ``blkz_register``, by which block driver
+registers to pstore_blk. Note that, block driver should register to pstore_blk
+after block device has registered. Block driver transfers a structure
+``blkz_info`` which is defined in *linux/pstore_blk.h*.
+
+The following key members of ``struct blkz_info`` may be of interest to you.
+
+blkdev
+~~
+
+The block device to use. Most of the time, it is a partition of block device.
+It's ok to keep it as NULL if you passing ``read`` and ``write`` in blkz_info 
as
+``blkdev`` is used by blkz_default_general_read/write. If both of ``blkdev``,
+``read`` and ``write`` are NULL, no block device is effective and the data will
+be saved in ddr buffer.
+
+It accept the following variants:
+
+1.  device number in hexadecimal represents itself no
+   leading 0x, for example b302.
+#. /dev/ represents the device number of disk
+#. /dev/ represents the device number of partition - device
+   number of disk plus the partition number
+#. /dev/p - same as the above, that form is used when disk
+   name of partitioned disk ends on a digit.
+#. PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF representing the unique id of
+   a partition if the partition table provides it. The UUID may be either an
+   EFI/GPT UUID, or refer to an MSDOS partition using the format -PP,
+   where  is a zero-filled hex representation of the 32-bit
+   "NT disk signature", and PP is a zero-filled hex representation of the
+   1-based partition number.
+#. PARTUUID=/PARTNROFF= to select a partition in relation to a
+   partition with a known unique id.
+#. : major and minor number of the device separated by a colon.
+
+See more on section **read/write**.
+
+total_size
+~~
+
+The total size in bytes of block device used for pstore_blk. It **MUST** be 
less
+than or equal to size of block device if ``blkdev`` valid. It **MUST** be a
+multiple of 4096. If ``total_size`` is zero with ``blkdev``, ``total_size`` 
will be
+set to equal to size of ``blkdev``.
+
+The block device area is divided into many chunks, and each event writes a 
chunk
+of information.
+
+dmesg_size
+~~
+
+The chunk size in bytes for dmesg(oops/panic). It **MUST** be a multiple of
+SECTOR_SIZE (Most of the time, the SECTOR_SIZE is 512). If you don't need 
dmesg,
+you are safely to set it to 0.
+
+NOTE that, the remaining space, except ``pmsg_size`` and others, belongs to
+dmesg. It means that there are multiple chunks for dmesg.
+
+Psotre_blk will log to dmesg chunks one by one, and always overwrite the oldest
+chunk if no free chunk.
+
+pmsg_size
+~
+
+The chunk size in bytes for pmsg. It **MUST** be a multiple of SECTOR_SIZE 
(Most
+of the time, the SECTOR_SIZE is 512). If you don't need pmsg, you are safely to
+set it to 0.
+
+There is only one chunk for pmsg.
+
+Pmsg is a user space accessible pstore object. Writes to */dev/pmsg0* are
+appended to the chunk. On reboot the contents are available in
+/sys/fs/pstore/pmsg-pstore-blk-0.
+
+dump_oops
+~
+
+Dumping both oopses and panics can be done by setting 1 in the ``dump_oops``
+member while setting 0 in that variable dumps only the panics.
+
+read/write
+~~
+
+They are general ``read/write`` APIs. It is safely and recommended to ignore 
it,
+but set ``blkdev``.
+
+These general APIs are used all the time expect panic. The ``read`` API is
+usually used to recover data from block device, and the ``write`` API is 
usually
+to flush new data and erase to block device.
+
+Pstore_blk will temporarily hold all new data before block device is ready. If
+you ignore both of ``read/write`` and ``blkdev``, the old data will be lost.
+
+NOTE that, the general APIs must check whether the block device is ready if
+self-defined.
+
+panic_read/p

[RFC v9 4/5] pstore/blk: support pmsg for pstore block

2019-02-19 Thread liaoweixiong
To enable pmsg, just set pmsg_size when block device register blkzone.

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig  |  21 
 fs/pstore/blkoops.c|  11 ++
 fs/pstore/blkzone.c| 254 +
 include/linux/pstore_blk.h |   1 +
 4 files changed, 265 insertions(+), 22 deletions(-)

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index a3c3f34..50d196e 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -210,6 +210,27 @@ config PSTORE_BLKOOPS_DMESG_SIZE
 It is the first priority. Take care of that blkoops will take lower
 priority settings if higher priority one do not set.
 
+config PSTORE_BLKOOPS_PMSG_SIZE
+   int "pmsg size in kbytes for blkoops"
+   depends on PSTORE_BLKOOPS
+   default 64
+   help
+ This just sets size of pmsg (pmsg_size) for pstore/blk. The value must
+ be a multiple of 4096. Pmsg work only if "blkdev" is set.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. device tree
+It is set on device tree, which will overwrites value from Kconfig,
+but can also be overwritten by module parameters.
+ 3. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
 config PSTORE_BLKOOPS_TOTAL_SIZE
int "total size in kbytes for blkoops"
depends on PSTORE_BLKOOPS
diff --git a/fs/pstore/blkoops.c b/fs/pstore/blkoops.c
index 3885584..5363b7f 100644
--- a/fs/pstore/blkoops.c
+++ b/fs/pstore/blkoops.c
@@ -30,6 +30,10 @@
 module_param(dmesg_size, long, 0400);
 MODULE_PARM_DESC(dmesg_size, "demsg size in kbytes");
 
+static long pmsg_size = -1;
+module_param(pmsg_size, long, 0400);
+MODULE_PARM_DESC(pmsg_size, "pmsg size in kbytes");
+
 static long total_size = -1;
 module_param(total_size, long, 0400);
 MODULE_PARM_DESC(total_size, "total size in kbytes");
@@ -47,11 +51,13 @@ struct blkz_info blkz_info = {
 
 struct blkoops_info {
unsigned long dmesg_size;
+   unsigned long pmsg_size;
unsigned long total_size;
const char *blkdev;
 };
 struct blkoops_info blkoops_info = {
.dmesg_size = CONFIG_PSTORE_BLKOOPS_DMESG_SIZE * 1024,
+   .pmsg_size = CONFIG_PSTORE_BLKOOPS_PMSG_SIZE * 1024,
.total_size = CONFIG_PSTORE_BLKOOPS_TOTAL_SIZE * 1024,
.blkdev = CONFIG_PSTORE_BLKOOPS_BLKDEV,
 };
@@ -123,6 +129,7 @@ static int __init blkoops_parse_dt(struct blkoops_info 
*info,
 
parse_size("total-size", info->total_size);
parse_size("dmesg-size", info->dmesg_size);
+   parse_size("pmsg-size", info->pmsg_size);
 
 #undef parse_size
return 0;
@@ -162,6 +169,7 @@ static int blkoops_probe(struct platform_device *pdev)
 
check_size(total_size, 4096);
check_size(dmesg_size, 4096);
+   check_size(pmsg_size, 4096);
 
 #undef check_size
 
@@ -170,6 +178,7 @@ static int blkoops_probe(struct platform_device *pdev)
 * through /sys/module/blkoops/parameters/
 */
dmesg_size = blkz_info.dmesg_size;
+   pmsg_size = blkz_info.pmsg_size;
total_size = blkz_info.total_size;
if (blkz_info.blkdev)
strncpy(blkdev, blkz_info.blkdev, 80 - 1);
@@ -217,6 +226,8 @@ void blkoops_register_dummy(void)
info->blkdev = (const char *)blkdev;
if (dmesg_size >= 0)
info->dmesg_size = (unsigned long)dmesg_size * 1024;
+   if (pmsg_size >= 0)
+   info->pmsg_size = (unsigned long)pmsg_size * 1024;
 
dummy = platform_device_register_data(NULL, MODNAME, -1, info,
sizeof(*info));
diff --git a/fs/pstore/blkzone.c b/fs/pstore/blkzone.c
index 83dd181..7a0129c 100644
--- a/fs/pstore/blkzone.c
+++ b/fs/pstore/blkzone.c
@@ -41,12 +41,14 @@
  *
  * @sig: signature to indicate header (BLK_SIG xor BLKZONE-type value)
  * @datalen: length of data in @data
+ * @start: offset into @data where the beginning of the stored bytes begin
  * @data: zone data.
  */
 struct blkz_buffer {
 #define BLK_SIG (0x43474244) /* DBGC */
uint32_t sig;
atomic_t datalen;
+   atomic_t start;
uint8_t data[];
 };
 
@@ -79,6 +81,9 @@ struct blkz_dmesg_header {
  * frontent name for this zone
  * @buffer:
  * pointer to data buffer managed by this zone
+ * @oldbuf:
+ * pointer to old data buffer. It is used for single zone such as pmsg,
+ * saving the old buffer.
  * @buffer_size:
  * bytes in @b

[RFC v9 3/5] pstore/blk: add blkoops for pstore_blk

2019-02-19 Thread liaoweixiong
blkoops is a sample for pstore/blk. It can only record oops, excluding
panics as no read/write apis for panic registered. It support settings
on Kconfg/device tree/module parameters. It can record oops log even
power failure if "PSTORE_BLKOOPS_BLKDEV" on Kconfig or "block-device"
on dts or "blkdev" on module parameter is valid.
Otherwise, it can only record data to ram buffer, which will be dropped
when reboot.

Signed-off-by: liaoweixiong 
---
 MAINTAINERS|   2 +-
 fs/pstore/Kconfig  | 114 
 fs/pstore/Makefile |   2 +
 fs/pstore/blkoops.c| 254 +
 include/linux/pstore_blk.h |  14 ++-
 5 files changed, 381 insertions(+), 5 deletions(-)
 create mode 100644 fs/pstore/blkoops.c

diff --git a/MAINTAINERS b/MAINTAINERS
index f49dd37..44647a8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12319,7 +12319,7 @@ F:  drivers/acpi/apei/erst.c
 F: Documentation/admin-guide/ramoops.rst
 F: Documentation/devicetree/bindings/reserved-memory/ramoops.txt
 F: Documentation/devicetree/bindings/pstore-block/
-K: \b(pstore|ramoops)
+K: \b(pstore|ramoops|blkoops)
 
 PTP HARDWARE CLOCK SUPPORT
 M: Richard Cochran 
diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index defcb75..a3c3f34 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -160,3 +160,117 @@ config PSTORE_BLK
help
  This enables panic and oops message to be logged to a block dev
  where it can be read back at some later point.
+
+config PSTORE_BLKOOPS
+   tristate "pstore block with oops logger"
+   depends on PSTORE_BLK
+   help
+ This is a sample for pstore block with oops logger.
+
+ It CANNOT record panic log as no read/write apis for panic registered.
+
+ It CAN record oops log even power failure if
+ "PSTORE_BLKOOPS_BLKDEV" on Kconfig or "block-device" on dts or
+ "blkdev" on module parameter is valid.
+
+ Otherwise, it can only record data to ram buffer, which will be
+ dropped when reboot.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. device tree
+It is set on device tree, which will overwrites value from Kconfig,
+but can also be overwritten by module parameters.
+ 3. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
+config PSTORE_BLKOOPS_DMESG_SIZE
+   int "dmesg size in kbytes for blkoops"
+   depends on PSTORE_BLKOOPS
+   default 64
+   help
+ This just sets size of dmesg (dmesg_size) for pstore/blk. The value
+ must be a multiple of 4096.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. device tree
+It is set on device tree, which will overwrites value from Kconfig,
+but can also be overwritten by module parameters.
+ 3. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
+config PSTORE_BLKOOPS_TOTAL_SIZE
+   int "total size in kbytes for blkoops"
+   depends on PSTORE_BLKOOPS
+   default 1024
+   help
+ The total size in kbytes pstore/blk can use. It must be less than or
+ equal to size of block device if @blkdev valid. If @total_size is zero
+ with @blkdev, @total_size will be set to equal to size of @blkdev.
+ The value must be a multiple of 4096.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. device tree
+It is set on device tree, which will overwrites value from Kconfig,
+but can also be overwritten by module parameters.
+ 3. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.

[RFC v9 2/5] dt-bindings: pstore-block: new support for blkoops

2019-02-19 Thread liaoweixiong
Create DT binding document for blkoops.

Signed-off-by: liaoweixiong 
---
 .../devicetree/bindings/pstore/blkoops.txt | 53 ++
 MAINTAINERS|  1 +
 2 files changed, 54 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pstore/blkoops.txt

diff --git a/Documentation/devicetree/bindings/pstore/blkoops.txt 
b/Documentation/devicetree/bindings/pstore/blkoops.txt
new file mode 100644
index 000..5462915
--- /dev/null
+++ b/Documentation/devicetree/bindings/pstore/blkoops.txt
@@ -0,0 +1,53 @@
+Blkoops oops logger
+===
+
+Blkoops provides a block partition for oops, excluding panics now, so they can
+be recovered after a reboot.
+
+Any space of block device will be used for a circular buffer of oops records.
+These records have a configurable size, with a size of 0 indicating that they
+should be disabled.
+
+At least one of "block-device" and "total_size" must be set.
+
+At least one of "dmesg-size" or "pmsg-size" must be set non-zero.
+
+Required properties:
+
+- compatible: must be "blkoops".
+
+Optional properties:
+
+- block-device: The block device to use. Most of the time, it is a partition of
+   device. If block-device is NULL, no block device is effective
+   and the data will be lost after rebooting.
+   It accept the following variants:
+   1)  device number in hexadecimal
+  represents itself no leading 0x, for example b302.
+   2) /dev/ represents the device number of disk
+   3) /dev/ represents the device number of
+  partition - device number of disk plus the partition number
+   4) /dev/p - same as the above, that form is
+  used when disk name of partitioned disk ends on a digit.
+   5) PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF representing
+  the unique id of a partition if the partition table provides
+  it. The UUID may be either an EFI/GPT UUID, or refer to an
+  MSDOS partition using the format -PP, where 
+  is a zero-filled hex representation of the 32-bit
+  "NT disk signature", and PP is a zero-filled hex
+  representation of the 1-based partition number.
+   6) PARTUUID=/PARTNROFF= to select a partition in
+  relation to a partition with a known unique id.
+   7) : major and minor number of the device
+  separated by a colon.
+
+- total-size: The total size in kbytes pstore/blk can use. It must be a 
multiple
+ of 4. It must be less than or equal to size of block-device. If
+ total-size is zero with block-devce valid, it will be set to equal
+ to size of block-device.
+
+- dmesg-size: maximum size in kbytes of each dump done on oops, which must be a
+ multiple of 4.
+
+- pmsg-size: maximum size in kbytes for userspace messages, which must be a
+multiple of 4.
diff --git a/MAINTAINERS b/MAINTAINERS
index 51029a4..f49dd37 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12318,6 +12318,7 @@ F:  drivers/firmware/efi/efi-pstore.c
 F: drivers/acpi/apei/erst.c
 F: Documentation/admin-guide/ramoops.rst
 F: Documentation/devicetree/bindings/reserved-memory/ramoops.txt
+F: Documentation/devicetree/bindings/pstore-block/
 K: \b(pstore|ramoops)
 
 PTP HARDWARE CLOCK SUPPORT
-- 
1.9.1



[RFC v9 0/5] pstore/block: new support logger for block devices

2019-02-19 Thread liaoweixiong
Why should we need pstore_block?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fast, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

[PATCH v9]
On patch 1:
1. rename part_path/part_size, members of blkz_info, to blkdev/total_size
2. if total_size is zero, get size from @blkdev
3. support multiple variants for @blkdev, such as partuuid, major with minor,
   and /dev/. See details on Documentation.
4. get size from block device
5. add depends on CONFIG_BLOCK
On patch 2:
1. update document
On patch 3:
1. update codes for new blkzone. Blkoops support insmod without total_size.
   for example: "insmod ./blkoops.ko blkdev=93:6" (major:minor).
2. use late_initcalls rather than module_init, to avoid block device not ready.
3. support for block driver to add panic apis to blkoops. By this, block
   driver can do the least work that just provides panic operations.
On patch 5:
1. update document

[PATCH v8]
On patch 2:
1. move DT to /bindings/pstore
2. Delete details for kernel.

[PATCH v7]
On patch 1:
1. Fix line over 80 characters.
On patch 2:
1. Insert a separate patch for DT bindings.

[PATCH v6]
On patch 1:
1. Fix according to email from Kees Cook, including spelling mistakes,
   explicit overflow test, none of the zeroing etc.
2. Do not recover data but metadata of dmesg when panic.
3. No need to take recovery when do erase.
4. Do not use "blkoops" for blkzone any more because "blkoops" is used for
   other module now. (rename blkbuf to blkoops)
On patch 2:
1. Rename blkbuf to blkoops.
2. Add Kconfig/device tree/module parameters settings for blkoops.
3. Add document for device tree.
On patch 3:
1. Blkoops support pmsg.
2. Fix description for new version patch.
On patch 4:
1. Fix description for new version patch.

[PATCH v5]
On patch 1:
1. rename pstore/rom to pstore/blk
2. Do not allocate any memory in the write path of panic. So, use local
array instead in function romz_recover_dmesg_meta.
3. Add C header file "linux/fs.h" to fix implicit declaration of function
   'filp_open','kernel_read'...
On patch 3:
1. If panic, do not recover pmsg but flush if it is dirty.
2. Fix erase pmsg failed.
On patch 4:
1. Create a document for pstore/blk

[PATCH v4]
On patch 1:
1. Fix always true condition '(--i >= 0) => (0-u32max >= 0)' in function
   romz_init_zones by defining variable i to 'int' rahter than
   'unsigned int'.
2. To make codes more easily to read, we use macro READ_NEXT_ZONE for
   return value of romz_dmesg_read if it need to read next zone.
   Moveover, we assign READ_NEXT_ZONE -1024 rather than 0.
3. Add 'FLUSH_META' to 'enum romz_flush_mode' and rename 'NOT_FLUSH' to
   'FLUSH_NONE'
4. Function romz_zone_write work badly with FLUSH_PART mode as badly
   address and offset to write.
On patch 3:
NEW SUPPORT psmg for pstore_rom.

[PATCH v3]
On patch 1:
Fix build as module error for undefined 'vfs_read' and 'vfs_write'
Both of 'vfs_read' and 'vfs_write' haven't be exproted yet, so we use
'kernel_read' and 'kernel_write' instead.

[PATCH v2]
On patch 1:
Fix build as module error for redefinition of 'romz_unregister' and
'romz_register'

[PATCH v1]
On patch 1:
Core codes of pstore_rom, which works well on allwinner(sunxi) platform.
On patch 2:
A sample for pstore_rom, using general ram rather than block device.

liaoweixiong (5):
  pstore/blk: new support logger for block devices
  dt-bindings: pstore-block: new support for blkoops
  pstore/blk: add blkoops for pstore_blk
  pstore/blk: support pmsg for pstore block
  Documentation: pstore/blk: create document for pstore_blk

 Documentation/admin-guide/pstore-block.rst |  233 
 .../devicetree/bindings/pstore/blkoops.txt |   53 +
 MAINTAINERS|4 +-
 fs/pstore/Kconfig  |  147 +++
 fs/pstore/Makefile |5 +
 fs/pstore/blkoops.c|  265 +
 fs/pstore/blkzone.c| 1223 
 include/linux/pstore_blk.h |   87 ++
 8 files changed, 2016 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/admin-guide/pstore-block.rst
 create mode 100644 Documentation/devicetree/bindings/pstore/blkoops.txt
 create mode 100644 fs/pstore/blkoops.c
 create mode 100644 fs/pstore/blkzone.c
 create mode 100644 include/linux/pstore_blk.h

-- 
1.9.1



Re: [RFC v7 2/5] dt-bindings: pstore-block: new support for blkoops

2019-02-14 Thread liaoweixiong
On 2019-02-14 04:30, Rob Herring wrote:
> On Wed, Feb 13, 2019 at 7:51 AM liaoweixiong
>  wrote:
>>
>>
>> On 2019-01-31 00:07, Rob Herring wrote:> On Wed, Jan 23, 2019 at
>> 08:05:13PM +0800, liaoweixiong wrote:
>>>> Create DT binding document for blkoops.
>>>>
>>>> Signed-off-by: liaoweixiong 
>>>> ---
>>>>  .../devicetree/bindings/pstore-block/blkoops.txt   | 32 
>>>> ++
>>>
>>> /bindings/pstore/...
>>>
>>> I wouldn't call it blkoops either. I believe ramoops is called that to
>>> maintain compatibility keeping the same kernel module name that
>>> preceeded pstore.
>>>
>>
>> Fixed.
>>
>> In addition, I don't known whether should we move
>> ramreserved-memory/ooos.txt to /bindings/pstore. This is for maintainer
>> to decide, and do it on other patch.
>>
>>>>  MAINTAINERS|  1 +
>>>>  2 files changed, 33 insertions(+)
>>>>  create mode 100644 
>>>> Documentation/devicetree/bindings/pstore-block/blkoops.txt
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/pstore-block/blkoops.txt 
>>>> b/Documentation/devicetree/bindings/pstore-block/blkoops.txt
>>>> new file mode 100644
>>>> index 000..a25835b
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/pstore-block/blkoops.txt
>>>> @@ -0,0 +1,32 @@
>>>> +Blkoops oops logger
>>>> +===
>>>> +
>>>> +Blkoops provides a block partition for oops, excluding panics now, so 
>>>> they can
>>>> +be recovered after a reboot.
>>>> +
>>>> +Any space of block partition will be used for a circular buffer of oops 
>>>> records.
>>>> +These records have a configurable size, with a size of 0 indicating that 
>>>> they
>>>> +should be disabled.
>>>> +
>>>> +"partition-size" and at least one of "dmesg-size" or "pmsg-size" must be 
>>>> set
>>>> +non-zero, but are otherwise optional as listed below.
>>>> +
>>>> +Blkoops will take value from Kconfig if device tree do not set, but 
>>>> settings
>>>> +from module parameters can also overwrite them.
>>>
>>> That's all kernel details not relevant to the binidng.
>>>
>>
>> Deleted.
>>
>>>> +
>>>> +Required properties:
>>>> +
>>>> +- compatible: must be "blkoops".
>>>> +
>>>> +- partition-size: size in kbytes, must be a multiple of 4.
>>>
>>> This seems unnecessary given a partition has a known size.
>>>
>>
>> partition-size is necessary for psotre/blk. User should tell pstore/blk
>> how large space can it use.
> 
> The partition table says how big a partition is. If you only want to
> use part of it, then make the partition smaller or use a file system.
> This is a solved problem, so we don't need a new way in DT to handle
> this.
> 

You are right, partition size is known and pstore/blk can get it
automatically from specified block device. I will try to do it on next
version patch.
But i prefer to rename partition-size to total-size and move it to
optional properties. Total-size means how big space pstore/blk can use.
It is not only about partition size as pstore/blk can use ram if no
partition specified.
So, I will process as follow logic:
1. If specify total size, use total size.
2. If no total size but specify partition, get size from partition.

>>>> +Optional properties:
>>>> +
>>>> +- partition-path: strings must begin with "/dev", tell blkoops which 
>>>> partition
>>>> +  it can used. If it is not set, blkoops will drop all data when reboot.
>>>
>>> No. '/dev/...' is a Linux thing and doesn't belong in DT.
>>>
>>> You should define a partition UUID and/or label and the kernel can find
>>> the right partition to use.
>>>
>>
>> pstore/blk do general read/write by filp_open/kernel_read/kernel_write,
>> which need device path.
>> In addition, i have no idea how to use UUID and/or label to do general
>> read/write on kernel layer, can you give me a tip?
> 
> The kernel can mount a filesystem by label or UUID though I think
> those are filesystem UUID and label, not partition UUID and label. But
> certainly bootloaders find the EFI system partition by UUID.
> 

As your words, those are file system UUID and label, not partition
UUID/label. Pstore is a file system, there is no other file system any
more for specified partition. Pstore/blk can't get specified partition
by UUID or label.
As far as i know, block device manager on user space scans each block
device and matches file system table to get UUID and label. Not even all
file systems have UUID/label.
MTD device may has label, but it is not suitable for all block device.
How if i cancel the prefix requirement for /dev and add it to the codes?
Then rename partition-path to block-device, by this, DT property may be
"mmcblk0p10" or "sda6" .

> Rob
> 

-- 
liaoweixiong


[RFC v8 1/5] pstore/blk: new support logger for block devices

2019-02-13 Thread liaoweixiong
pstore_blk is similar to pstore_ram, but dump log to block devices
rather than persistent ram.

Why should we need pstore_blk?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fact, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

pstore_blk can only dump Oops/Panic log to block devices. It only
supports dmesg now. To make pstore_blk work, the block driver should
provide the path of a block partition device (/dev/) and the
read/write apis when on panic.

pstore_blk begins at 'blkz_register', by witch block device can register
a block partition to pstore_blk. Then pstore_blk divide and manage the
partition as zones, which is similar to pstore_ram.

Recommend that, block driver register pstore_blk after block device is
ready.

pstore_blk works well on allwinner(sunxi) platform.

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig  |   7 +
 fs/pstore/Makefile |   3 +
 fs/pstore/blkzone.c| 954 +
 include/linux/pstore_blk.h |  61 +++
 4 files changed, 1025 insertions(+)
 create mode 100644 fs/pstore/blkzone.c
 create mode 100644 include/linux/pstore_blk.h

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index 8b3ba27..a881c53 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -152,3 +152,10 @@ config PSTORE_RAM
  "ramoops.ko".
 
  For more information, see Documentation/admin-guide/ramoops.rst.
+
+config PSTORE_BLK
+   tristate "Log panic/oops to a block device"
+   depends on PSTORE
+   help
+ This enables panic and oops message to be logged to a block dev
+ where it can be read back at some later point.
diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
index 967b589..0ee2fc8 100644
--- a/fs/pstore/Makefile
+++ b/fs/pstore/Makefile
@@ -12,3 +12,6 @@ pstore-$(CONFIG_PSTORE_PMSG)  += pmsg.o
 
 ramoops-objs += ram.o ram_core.o
 obj-$(CONFIG_PSTORE_RAM)   += ramoops.o
+
+obj-$(CONFIG_PSTORE_BLK) += pstore_blk.o
+pstore_blk-y += blkzone.o
diff --git a/fs/pstore/blkzone.c b/fs/pstore/blkzone.c
new file mode 100644
index 000..aca8c2a
--- /dev/null
+++ b/fs/pstore/blkzone.c
@@ -0,0 +1,954 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *
+ * blkzone.c: Block device Oops/Panic logger
+ *
+ * Copyright (C) 2019 liaoweixiong 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define MODNAME "pstore-blk"
+#define pr_fmt(fmt) MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * struct blkz_head - head of zone to flush to storage
+ *
+ * @sig: signature to indicate header (BLK_SIG xor BLKZONE-type value)
+ * @datalen: length of data in @data
+ * @data: zone data.
+ */
+struct blkz_buffer {
+#define BLK_SIG (0x43474244) /* DBGC */
+   uint32_t sig;
+   atomic_t datalen;
+   uint8_t data[];
+};
+
+/**
+ * struct blkz_dmesg_header: dmesg information
+ *
+ * @magic: magic num for dmesg header
+ * @time: trigger time
+ * @compressed: whether conpressed
+ * @count: oops/panic counter
+ * @reason: identify oops or panic
+ */
+struct blkz_dmesg_header {
+#define DMESG_HEADER_MAGIC 0x4dfc3ae5
+   uint32_t magic;
+   struct timespec64 time;
+   bool compressed;
+   uint32_t counter;
+   enum kmsg_dump_reason reason;
+   uint8_t data[0];
+};
+
+/**
+ * struct blkz_zone - zone information
+ * @off:
+ * zone offset of partition
+ * @type:
+ * frontent type for this zone
+ * @name:
+ * frontent name for this zone
+ * @buffer:
+ * pointer to data buffer managed by this zone
+ * @buffer_size:
+ * bytes in @buffer->data
+ * @should_recover:
+ * should recover from storage
+ * @dirty:
+ * mark whether the data in @buffer are dirty (not flush to storage yet)
+ */
+struct blkz_zone {
+   unsigned long off;
+   const char *name;
+   enum pstore_type_id type;
+
+   struct blkz_buffer *buffer;
+   size_t buffer_size;
+   bool should_recover;
+   atomic_t dirty;
+};
+
+struct blkz_context {
+   struct blkz_zone **dbzs;/* dmesg block zones */
+   unsigned int dmesg_max_cnt;
+   unsigned int dmesg_read_cnt;
+   unsigned int dmesg_write_cnt;
+   /**
+* the counter should be recovered when do re

[RFC v8 4/5] pstore/blk: support pmsg for pstore block

2019-02-13 Thread liaoweixiong
To enable pmsg, just set pmsg_size when block device register blkzone.

Signed-off-by: liaoweixiong 
---
 fs/pstore/blkoops.c|  11 ++
 fs/pstore/blkzone.c| 254 +
 include/linux/pstore_blk.h |   1 +
 3 files changed, 244 insertions(+), 22 deletions(-)

diff --git a/fs/pstore/blkoops.c b/fs/pstore/blkoops.c
index fd926a5..b4b658e 100644
--- a/fs/pstore/blkoops.c
+++ b/fs/pstore/blkoops.c
@@ -30,6 +30,10 @@
 module_param(dmesg_size, long, 0400);
 MODULE_PARM_DESC(dmesg_size, "demsg size in kbytes");
 
+static long pmsg_size = -1;
+module_param(pmsg_size, long, 0400);
+MODULE_PARM_DESC(pmsg_size, "pmsg size in kbytes");
+
 static long part_size = -1;
 module_param(part_size, long, 0400);
 MODULE_PARM_DESC(part_size, "partition size in kbytes");
@@ -47,11 +51,13 @@ struct blkz_info blkz_info = {
 
 struct blkoops_info {
unsigned long dmesg_size;
+   unsigned long pmsg_size;
unsigned long part_size;
const char *part_path;
 };
 struct blkoops_info blkoops_info = {
.dmesg_size = CONFIG_PSTORE_BLKOOPS_DMESG_SIZE * 1024,
+   .pmsg_size = CONFIG_PSTORE_BLKOOPS_PMSG_SIZE * 1024,
.part_size = CONFIG_PSTORE_BLKOOPS_PART_SIZE * 1024,
.part_path = CONFIG_PSTORE_BLKOOPS_PART_PATH,
 };
@@ -106,6 +112,7 @@ static int __init blkoops_parse_dt(struct blkoops_info 
*info,
 
parse_size("partition-size", info->part_size);
parse_size("dmesg-size", info->dmesg_size);
+   parse_size("pmsg-size", info->pmsg_size);
 
 #undef parse_size
return 0;
@@ -148,6 +155,7 @@ static int blkoops_probe(struct platform_device *pdev)
 
check_size(part_size, 4096);
check_size(dmesg_size, 4096);
+   check_size(pmsg_size, 4096);
 
 #undef check_size
 
@@ -156,6 +164,7 @@ static int blkoops_probe(struct platform_device *pdev)
 * through /sys/module/blkoops/parameters/
 */
dmesg_size = blkz_info.dmesg_size;
+   pmsg_size = blkz_info.pmsg_size;
part_size = blkz_info.part_size;
if (blkz_info.part_path)
strncpy(part_path, blkz_info.part_path, 80 - 1);
@@ -202,6 +211,8 @@ void blkoops_register_dummy(void)
info->part_path = (const char *)part_path;
if (dmesg_size >= 0)
info->dmesg_size = (unsigned long)dmesg_size * 1024;
+   if (pmsg_size >= 0)
+   info->pmsg_size = (unsigned long)pmsg_size * 1024;
 
dummy = platform_device_register_data(NULL, MODNAME, -1, info,
sizeof(*info));
diff --git a/fs/pstore/blkzone.c b/fs/pstore/blkzone.c
index aca8c2a..0736472 100644
--- a/fs/pstore/blkzone.c
+++ b/fs/pstore/blkzone.c
@@ -34,12 +34,14 @@
  *
  * @sig: signature to indicate header (BLK_SIG xor BLKZONE-type value)
  * @datalen: length of data in @data
+ * @start: offset into @data where the beginning of the stored bytes begin
  * @data: zone data.
  */
 struct blkz_buffer {
 #define BLK_SIG (0x43474244) /* DBGC */
uint32_t sig;
atomic_t datalen;
+   atomic_t start;
uint8_t data[];
 };
 
@@ -72,6 +74,9 @@ struct blkz_dmesg_header {
  * frontent name for this zone
  * @buffer:
  * pointer to data buffer managed by this zone
+ * @oldbuf:
+ * pointer to old data buffer. It is used for single zone such as pmsg,
+ * saving the old buffer.
  * @buffer_size:
  * bytes in @buffer->data
  * @should_recover:
@@ -85,6 +90,7 @@ struct blkz_zone {
enum pstore_type_id type;
 
struct blkz_buffer *buffer;
+   struct blkz_buffer *oldbuf;
size_t buffer_size;
bool should_recover;
atomic_t dirty;
@@ -92,8 +98,10 @@ struct blkz_zone {
 
 struct blkz_context {
struct blkz_zone **dbzs;/* dmesg block zones */
+   struct blkz_zone *pbz;  /* Pmsg block zone */
unsigned int dmesg_max_cnt;
unsigned int dmesg_read_cnt;
+   unsigned int pmsg_read_cnt;
unsigned int dmesg_write_cnt;
/**
 * the counter should be recovered when do recovery
@@ -127,6 +135,11 @@ static inline int buffer_datalen(struct blkz_zone *zone)
return atomic_read(>buffer->datalen);
 }
 
+static inline int buffer_start(struct blkz_zone *zone)
+{
+   return atomic_read(>buffer->start);
+}
+
 static inline bool is_on_panic(void)
 {
struct blkz_context *cxt = _cxt;
@@ -401,6 +414,72 @@ static int blkz_recover_dmesg(struct blkz_context *cxt)
return ret;
 }
 
+static int blkz_recover_pmsg(struct blkz_context *cxt)
+{
+   struct blkz_info *info = cxt->bzinfo;
+   struct blkz_buffer *oldbuf;
+   struct blkz_zone *zone = NULL;
+   ssize_t (*readop)(char *buf, size_t bytes, loff_t pos);
+   int ret = 0;
+   ssize_t rcnt, len;
+
+   zone = cxt->pbz;
+   if (!zone || zone->oldbuf)
+   return 0

[RFC v8 5/5] Documentation: pstore/blk: create document for pstore_blk

2019-02-13 Thread liaoweixiong
The document, at Documentation/admin-guide/pstore-block.rst,
tells user how to use pstore_blk and the attentions about panic
read/write

Signed-off-by: liaoweixiong 
---
 Documentation/admin-guide/pstore-block.rst | 227 +
 MAINTAINERS|   1 +
 fs/pstore/Kconfig  |   4 +
 3 files changed, 232 insertions(+)
 create mode 100644 Documentation/admin-guide/pstore-block.rst

diff --git a/Documentation/admin-guide/pstore-block.rst 
b/Documentation/admin-guide/pstore-block.rst
new file mode 100644
index 000..4bb8c4c
--- /dev/null
+++ b/Documentation/admin-guide/pstore-block.rst
@@ -0,0 +1,227 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Pstore block oops/panic logger
+==
+
+Introduction
+
+
+Pstore block (pstore_blk) is an oops/panic logger that write its logs to block
+device before the system crashes. Pstore_blk needs block device driver
+registering a partition path of the block device, like /dev/mmcblk0p7 for mmc
+driver, and read/write APIs for this partition when on panic.
+
+Pstore block concepts
+-
+
+Pstore block begins at function ``blkz_register``, by which block driver
+registers to pstore_blk. Recomemd that, block driver should register to
+pstore_blk after block device is ready. Block driver transfers a structure
+``blkz_info`` which is defined in *linux/pstore_blk.h*.
+
+The following key members of ``struct blkz_info`` may be of interest to you.
+
+part_path
+~
+
+The path of partition used for pstore_blk. It may be ``/dev/mmcblk[N]p[M]`` for
+mmc, and ``/dev/mtdblock[N]`` for mtd device.
+
+The ``part_path`` is not necessarily if you self-defined general read/write 
APIs
+on ``blkz_info``. In other words, the ``part_path`` is only used (by function
+blkz_default_general_read/write) when general read/write APIs are not defined.
+
+See more on section **read/write**.
+
+part_size
+~
+
+The total size in bytes of partition used for pstore_blk. This member **MUST**
+be effective and a multiple of 4096. It is recommended to 1M or larger for 
block
+device.
+
+The block device area is divided into many chunks, and each event writes
+a chunk of information.
+
+dmesg_size
+~~
+
+The chunk size in bytes for dmesg(oops/panic). It **MUST** be a multiple of
+SECTOR_SIZE (Most of the time, the SECTOR_SIZE is 512). If you don't need 
dmesg,
+you are safely to set it to 0.
+
+NOTE that, the remaining space, except ``pmsg_size`` and others, belongs to
+dmesg. It means that there are multiple chunks for dmesg.
+
+Psotre_blk will log to dmesg chunks one by one, and always overwrite the oldest
+chunk if no free chunk.
+
+pmsg_size
+~
+
+The chunk size in bytes for pmsg. It **MUST** be a multiple of SECTOR_SIZE 
(Most
+of the time, the SECTOR_SIZE is 512). If you don't need pmsg, you are safely to
+set it to 0.
+
+There is only one chunk for pmsg.
+
+Pmsg is a user space accessible pstore object. Writes to */dev/pmsg0* are
+appended to the chunk. On reboot the contents are available in
+/sys/fs/pstore/pmsg-pstore-blk-0.
+
+dump_oops
+~
+
+Dumping both oopses and panics can be done by setting 1 in the ``dump_oops``
+member while setting 0 in that variable dumps only the panics.
+
+read/write
+~~
+
+They are general ``read/write`` APIs. It is safely and recommended to ignore 
it,
+but set ``part_path``.
+
+These general APIs are used all the time expect panic. The ``read`` API is
+usually used to recover data from block device, and the ``write`` API is 
usually
+to flush new data and erase to block device.
+
+Pstore_blk will temporarily hold all new data before block device is ready. If
+you ignore both of ``read/write`` and ``part_path``, the old data will not be
+recovered and the new data will not be flushed until panic, using panic APIs.
+If you don't have panic APIs neither, all the data will be dropped when reboot.
+
+NOTE that, the general APIs must check whether the block device is ready if
+self-defined.
+
+panic_read/panic_write
+~~
+
+They are ``read/write`` APIs for panic. They are likely to general
+``read/write`` but will be used only when on panic.
+
+The attentions for panic read/write see section
+**Attentions in panic read/write APIs**.
+
+Register to pstore block
+
+
+Block device driver call ``blkz_register`` to register to Psotre_blk.
+For example:
+
+.. code-block:: c
+
+ #include 
+ [...]
+
+ static ssize_t _panic_read(char *buf, size bytes, loff_t pos)
+ {
+[...]
+ }
+
+ static ssize_t _panic_write(const char *buf, size_t bytes, loff_t pos)
+ {
+[...]
+ }
+
+ struct blkz_info _info = {
+.onwer = THIS_MODULE,
+.name = <...>,
+.dmesg_size = <...>,
+.pmsg_size = <...>,
+.dump_oops = true,
+.panic_read = _panic_read,
+.panic_write = _panic_write,
+ };
+
+

[RFC v8 2/5] dt-bindings: pstore-block: new support for blkoops

2019-02-13 Thread liaoweixiong
Create DT binding document for blkoops.

Signed-off-by: liaoweixiong 
---
 .../devicetree/bindings/pstore/blkoops.txt | 29 ++
 MAINTAINERS|  1 +
 2 files changed, 30 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pstore/blkoops.txt

diff --git a/Documentation/devicetree/bindings/pstore/blkoops.txt 
b/Documentation/devicetree/bindings/pstore/blkoops.txt
new file mode 100644
index 000..8f3d85f
--- /dev/null
+++ b/Documentation/devicetree/bindings/pstore/blkoops.txt
@@ -0,0 +1,29 @@
+Blkoops oops logger
+===
+
+Blkoops provides a block partition for oops, excluding panics now, so they can
+be recovered after a reboot.
+
+Any space of block partition will be used for a circular buffer of oops 
records.
+These records have a configurable size, with a size of 0 indicating that they
+should be disabled.
+
+"partition-size" and at least one of "dmesg-size" or "pmsg-size" must be set
+non-zero, but are otherwise optional as listed below.
+
+Required properties:
+
+- compatible: must be "blkoops".
+
+- partition-size: size in kbytes, must be a multiple of 4.
+
+Optional properties:
+
+- partition-path: strings must begin with "/dev", tell blkoops which partition
+  it can used. If it is not set, blkoops will drop all data when reboot.
+
+- dmesg-size: maximum size in kbytes of each dump done on oops, which must be a
+  multiple of 4.
+
+- pmsg-size: maximum size in kbytes for userspace messages, which must be a
+  multiple of 4.
diff --git a/MAINTAINERS b/MAINTAINERS
index 51029a4..f49dd37 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12318,6 +12318,7 @@ F:  drivers/firmware/efi/efi-pstore.c
 F: drivers/acpi/apei/erst.c
 F: Documentation/admin-guide/ramoops.rst
 F: Documentation/devicetree/bindings/reserved-memory/ramoops.txt
+F: Documentation/devicetree/bindings/pstore-block/
 K: \b(pstore|ramoops)
 
 PTP HARDWARE CLOCK SUPPORT
-- 
1.9.1



[RFC v8 3/5] pstore/blk: add blkoops for pstore_blk

2019-02-13 Thread liaoweixiong
blkoops is a sample for pstore/blk. It can only record oops, excluding
panics as no read/write apis for panic registered. It support settings
on Kconfg/device tree/module parameters. It can record oops log even
power failure if "PSTORE_BLKOOPS_PART_PATH" on Kconfig or
"partition-path" on dts or "part_path" on module parameter is valid.
Otherwise, it can only record data to ram buffer, which will be dropped
when reboot.

Signed-off-by: liaoweixiong 
---
 MAINTAINERS |   2 +-
 fs/pstore/Kconfig   | 117 +
 fs/pstore/Makefile  |   2 +
 fs/pstore/blkoops.c | 239 
 4 files changed, 359 insertions(+), 1 deletion(-)
 create mode 100644 fs/pstore/blkoops.c

diff --git a/MAINTAINERS b/MAINTAINERS
index f49dd37..44647a8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12319,7 +12319,7 @@ F:  drivers/acpi/apei/erst.c
 F: Documentation/admin-guide/ramoops.rst
 F: Documentation/devicetree/bindings/reserved-memory/ramoops.txt
 F: Documentation/devicetree/bindings/pstore-block/
-K: \b(pstore|ramoops)
+K: \b(pstore|ramoops|blkoops)
 
 PTP HARDWARE CLOCK SUPPORT
 M: Richard Cochran 
diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index a881c53..f0a1a49 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -159,3 +159,120 @@ config PSTORE_BLK
help
  This enables panic and oops message to be logged to a block dev
  where it can be read back at some later point.
+
+config PSTORE_BLKOOPS
+   tristate "pstore block with oops logger"
+   depends on PSTORE_BLK
+   help
+ This is a sample for pstore block with oops logger.
+
+ It CANNOT record panic log as no read/write apis for panic registered.
+
+ It CAN record oops log even power failure if
+ "PSTORE_BLKOOPS_PART_PATH" on Kconfig or "partition-path" on dts or
+ "part_path" on module parameter is valid.
+
+ Otherwise, it can only record data to ram buffer, which will be
+ dropped when reboot.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. device tree
+It is set on device tree, which will overwrites value from Kconfig,
+but can also be overwritten by module parameters.
+ 3. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
+config PSTORE_BLKOOPS_DMESG_SIZE
+   int "dmesg_size in kbytes for blkoops"
+   depends on PSTORE_BLKOOPS
+   default 64
+   help
+ This just sets size of dmesg (dmesg_size) for pstore/blk. The value
+ must be a multiple of 4096.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. device tree
+It is set on device tree, which will overwrites value from Kconfig,
+but can also be overwritten by module parameters.
+ 3. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
+config PSTORE_BLKOOPS_PMSG_SIZE
+   int "pmsg_size in kbytes for blkoops"
+   depends on PSTORE_BLKOOPS
+   default 64
+   help
+ This just sets size of pmsg (pmsg_size) for pstore/blk. The value must
+ be a multiple of 4096. Pmsg work only if "part_path" is set.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. device tree
+It is set on device tree, which will overwrites value from Kconfig,
+but can also be overwritten by module parameters.
+ 3. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
+config PSTORE_BLKOOPS_PART_SIZE
+   int "part_size in kbytes for blkoops"
+   depends on PSTORE_BLKOOPS
+   default 1024
+   help
+ This just 

[RFC v8 0/5] pstore/block: new support logger for block devices

2019-02-13 Thread liaoweixiong
Why should we need pstore_block?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fast, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

[PATCH v8]
On patch 2:
1. move DT to /bindings/pstore
2. Delete details for kernel.

[PATCH v7]
On patch 1:
1. Fix line over 80 characters.
On patch 2:
1. Insert a separate patch for DT bindings.

[PATCH v6]
On patch 1:
1. Fix according to email from Kees Cook, including spelling mistakes,
   explicit overflow test, none of the zeroing etc.
2. Do not recover data but metadata of dmesg when panic.
3. No need to take recovery when do erase.
4. Do not use "blkoops" for blkzone any more because "blkoops" is used for
   other module now. (rename blkbuf to blkoops)
On patch 2:
1. Rename blkbuf to blkoops.
2. Add Kconfig/device tree/module parameters settings for blkoops.
3. Add document for device tree.
On patch 3:
1. Blkoops support pmsg.
2. Fix description for new version patch.
On patch 4:
1. Fix description for new version patch.

[PATCH v5]
On patch 1:
1. rename pstore/rom to pstore/blk
2. Do not allocate any memory in the write path of panic. So, use local
array instead in function romz_recover_dmesg_meta.
3. Add C header file "linux/fs.h" to fix implicit declaration of function
   'filp_open','kernel_read'...
On patch 3:
1. If panic, do not recover pmsg but flush if it is dirty.
2. Fix erase pmsg failed.
On patch 4:
1. Create a document for pstore/blk

[PATCH v4]
On patch 1:
1. Fix always true condition '(--i >= 0) => (0-u32max >= 0)' in function
   romz_init_zones by defining variable i to 'int' rahter than
   'unsigned int'.
2. To make codes more easily to read, we use macro READ_NEXT_ZONE for
   return value of romz_dmesg_read if it need to read next zone.
   Moveover, we assign READ_NEXT_ZONE -1024 rather than 0.
3. Add 'FLUSH_META' to 'enum romz_flush_mode' and rename 'NOT_FLUSH' to
   'FLUSH_NONE'
4. Function romz_zone_write work badly with FLUSH_PART mode as badly
   address and offset to write.
On patch 3:
NEW SUPPORT psmg for pstore_rom.

[PATCH v3]
On patch 1:
Fix build as module error for undefined 'vfs_read' and 'vfs_write'
Both of 'vfs_read' and 'vfs_write' haven't be exproted yet, so we use
'kernel_read' and 'kernel_write' instead.

[PATCH v2]
On patch 1:
Fix build as module error for redefinition of 'romz_unregister' and
'romz_register'

[PATCH v1]
On patch 1:
Core codes of pstore_rom, which works well on allwinner(sunxi) platform.
On patch 2:
A sample for pstore_rom, using general ram rather than block device.

liaoweixiong (5):
  pstore/blk: new support logger for block devices
  dt-bindings: pstore-block: new support for blkoops
  pstore/blk: add blkoops for pstore_blk
  pstore/blk: support pmsg for pstore block
  Documentation: pstore/blk: create document for pstore_blk

 Documentation/admin-guide/pstore-block.rst |  227 
 .../devicetree/bindings/pstore/blkoops.txt |   29 +
 MAINTAINERS|4 +-
 fs/pstore/Kconfig  |  128 +++
 fs/pstore/Makefile |5 +
 fs/pstore/blkoops.c|  250 +
 fs/pstore/blkzone.c| 1164 
 include/linux/pstore_blk.h |   62 ++
 8 files changed, 1868 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/admin-guide/pstore-block.rst
 create mode 100644 Documentation/devicetree/bindings/pstore/blkoops.txt
 create mode 100644 fs/pstore/blkoops.c
 create mode 100644 fs/pstore/blkzone.c
 create mode 100644 include/linux/pstore_blk.h

-- 
1.9.1



Re: [RFC v7 2/5] dt-bindings: pstore-block: new support for blkoops

2019-02-13 Thread liaoweixiong


On 2019-01-31 00:07, Rob Herring wrote:> On Wed, Jan 23, 2019 at
08:05:13PM +0800, liaoweixiong wrote:
>> Create DT binding document for blkoops.
>>
>> Signed-off-by: liaoweixiong 
>> ---
>>  .../devicetree/bindings/pstore-block/blkoops.txt   | 32 
>> ++
> 
> /bindings/pstore/...
> 
> I wouldn't call it blkoops either. I believe ramoops is called that to 
> maintain compatibility keeping the same kernel module name that 
> preceeded pstore.
> 

Fixed.

In addition, I don't known whether should we move
ramreserved-memory/ooos.txt to /bindings/pstore. This is for maintainer
to decide, and do it on other patch.

>>  MAINTAINERS|  1 +
>>  2 files changed, 33 insertions(+)
>>  create mode 100644 
>> Documentation/devicetree/bindings/pstore-block/blkoops.txt
>>
>> diff --git a/Documentation/devicetree/bindings/pstore-block/blkoops.txt 
>> b/Documentation/devicetree/bindings/pstore-block/blkoops.txt
>> new file mode 100644
>> index 000..a25835b
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pstore-block/blkoops.txt
>> @@ -0,0 +1,32 @@
>> +Blkoops oops logger
>> +===
>> +
>> +Blkoops provides a block partition for oops, excluding panics now, so they 
>> can
>> +be recovered after a reboot.
>> +
>> +Any space of block partition will be used for a circular buffer of oops 
>> records.
>> +These records have a configurable size, with a size of 0 indicating that 
>> they
>> +should be disabled.
>> +
>> +"partition-size" and at least one of "dmesg-size" or "pmsg-size" must be set
>> +non-zero, but are otherwise optional as listed below.
>> +
>> +Blkoops will take value from Kconfig if device tree do not set, but settings
>> +from module parameters can also overwrite them.
> 
> That's all kernel details not relevant to the binidng.
> 

Deleted.

>> +
>> +Required properties:
>> +
>> +- compatible: must be "blkoops".
>> +
>> +- partition-size: size in kbytes, must be a multiple of 4.
> 
> This seems unnecessary given a partition has a known size.
> 

partition-size is necessary for psotre/blk. User should tell pstore/blk
how large space can it use.

>> +
>> +Optional properties:
>> +
>> +- partition-path: strings must begin with "/dev", tell blkoops which 
>> partition
>> +  it can used. If it is not set, blkoops will drop all data when reboot.
> 
> No. '/dev/...' is a Linux thing and doesn't belong in DT.
> 
> You should define a partition UUID and/or label and the kernel can find 
> the right partition to use.
> 

pstore/blk do general read/write by filp_open/kernel_read/kernel_write,
which need device path.
In addition, i have no idea how to use UUID and/or label to do general
read/write on kernel layer, can you give me a tip?

>> +
>> +- dmesg-size: maximum size in kbytes of each dump done on oops, which must 
>> be a
>> +  multiple of 4.
>> +
>> +- pmsg-size: maximum size in kbytes for userspace messages, which must be a
>> +  multiple of 4.
> 
> Common properties shared with ramoops should be in a common doc.
> 

The size limit are different. Size for ramoops must be power of 2, but
be a multiple of 4k for pstore/blk.

> Rob
> 

-- 
liaoweixiong


Re: [RFC v7 0/5] pstore/block: new support logger for block devices

2019-02-12 Thread liaoweixiong
On 2019-02-13 04:54, Kees Cook wrote:
> On Wed, Jan 23, 2019 at 4:06 AM liaoweixiong
>  wrote:
>>
>> Why should we need pstore_block?
>> 1. Most embedded intelligent equipment have no persistent ram, which
>> increases costs. We perfer to cheaper solutions, like block devices.
>> In fast, there is already a sample for block device logger in driver
>> MTD (drivers/mtd/mtdoops.c).
>> 2. Do not any equipment have battery, which means that it lost all data
>> on general ram if power failure. Pstore has little to do for these
>> equipments.
>>
>> [PATCH v7]
>> On patch 1:
>> 1. Fix line over 80 characters.
>> On patch 2:
>> 1. Insert a separate patch for DT bindings.
> 
> This is looking good. Can you address the DT bindings review concerns,
> and send a v8?
> 

Sure. I had little time to send patches as i caught up with the Spring
Festival some days ago, the most grand festival of China. I'll do it
before this weekend, which is already in my plan.

> Thanks!
> 

-- 
liaoweixiong


Re: [RFC v5 1/4] pstore/blk: new support logger for block devices

2019-01-24 Thread liaoweixiong
On 2019-01-24 02:19, Aaro Koskinen wrote:
> Hi,
> 
> On Sat, Jan 19, 2019 at 04:53:48PM +0800, liaoweixiong wrote:
>> On 2019-01-18 08:12, Kees Cook wrote:
>>>> MTD (drivers/mtd/mtdoops.c).
>>>
>>> Would mtdoops get dropped in favor of pstore/blk, or do they not share
>>> features?
>>
>> We can show them what pstore/blk do. I think they will be interested in it.
>> They should do a little work, including make a function for panic read,
>> then they gain enhanced features, including present logs as a file,
>> record multiple logs.
> 
> mtdoops has been in use over a decade and known working. What benefits
> this new framework would offer? (BTW I don't see MTD as "block device".)
> 

Pstore/blk is NOT to replace mtdoops, but to enhance it. Mtdoops provides
operation interface for panic and pstore/blk manage the special
partition space.

The combination of pstore/blk and mtdoops brings follow benefits:
1. Not only panic/oops, but also all feature of pstore, such as console,
ftrace, pmsg, etc.
2. Display log as a file. Pstore/blk can save multiple records and
display all of them as files. Users have no need to parse the partition,
just read files to get what they wants.
3. User can get more information, such as the trigger time, the trigger
count, etc.
4. ... perhaps other benefits that I can't think of right now

> Why should there be a panic read? That adds complexity. This codes runs
> on panic path, so it should be as simple and fast as possible.
> 

Read operation is only used to recover old data. Pstore/blk will do
recovery only one time before write (when trigger a new crash) and read
(when mount pstore filesystem). Most of the time, pstore/blk will do
read by general operation rather than panic read. However, how if kernel
panic when pstore/blk do not recover yet? That's why we need panic read.

In addition, pstore/blk do not recover log when panic. It just recover
the trigger counter and next position. Pstore/blk need old count to
accumulate count, next position to avoid damage to old records.

> Also compatibility has to be there. E.g. user upgrades an old system
> (with mtdoops and related userspace) to a new kernel. Upgrade fails,
> so the old software must be able to read the panic dumps properly to
> tell the user why.
> 

This is really a problem, because the header of each records is very
different between pstore/blk and mtdoops. But i think it is not fatal.

> A.
> 

-- 
liaoweixiong


Re: [RFC v7 0/5] pstore/block: new support logger for block devices

2019-01-24 Thread liaoweixiong
On 2019-01-24 02:26, Aaro Koskinen wrote:
> Hi,
> 
> On Wed, Jan 23, 2019 at 08:05:11PM +0800, liaoweixiong wrote:
>> Why should we need pstore_block?
>> 1. Most embedded intelligent equipment have no persistent ram, which
>> increases costs. We perfer to cheaper solutions, like block devices.
>> In fast, there is already a sample for block device logger in driver
>> MTD (drivers/mtd/mtdoops.c).
> 
> I think you should add a patch for some actual block device using this
> new framework to show that it can work. What HW you think would be
> using things?
> 

I will try to add a patch. Actually, I have implemented it on allwinner
platform, but unfortunately these codes are unsuitable to submit to
upper stream.

In addition, there is already a sample for pstore/blk on patch 3 of
version 7. It names
blkoops. Blkoops is suitable for most block device as what it need is
just a path of a partition. We can use it to test most of features but
panic.

> A.
> 

-- 
liaoweixiong


[RFC v7 4/5] pstore/blk: support pmsg for pstore block

2019-01-23 Thread liaoweixiong
To enable pmsg, just set pmsg_size when block device register blkzone.

Signed-off-by: liaoweixiong 
---
 fs/pstore/blkoops.c|  11 ++
 fs/pstore/blkzone.c| 254 +
 include/linux/pstore_blk.h |   1 +
 3 files changed, 244 insertions(+), 22 deletions(-)

diff --git a/fs/pstore/blkoops.c b/fs/pstore/blkoops.c
index fd926a5..b4b658e 100644
--- a/fs/pstore/blkoops.c
+++ b/fs/pstore/blkoops.c
@@ -30,6 +30,10 @@
 module_param(dmesg_size, long, 0400);
 MODULE_PARM_DESC(dmesg_size, "demsg size in kbytes");
 
+static long pmsg_size = -1;
+module_param(pmsg_size, long, 0400);
+MODULE_PARM_DESC(pmsg_size, "pmsg size in kbytes");
+
 static long part_size = -1;
 module_param(part_size, long, 0400);
 MODULE_PARM_DESC(part_size, "partition size in kbytes");
@@ -47,11 +51,13 @@ struct blkz_info blkz_info = {
 
 struct blkoops_info {
unsigned long dmesg_size;
+   unsigned long pmsg_size;
unsigned long part_size;
const char *part_path;
 };
 struct blkoops_info blkoops_info = {
.dmesg_size = CONFIG_PSTORE_BLKOOPS_DMESG_SIZE * 1024,
+   .pmsg_size = CONFIG_PSTORE_BLKOOPS_PMSG_SIZE * 1024,
.part_size = CONFIG_PSTORE_BLKOOPS_PART_SIZE * 1024,
.part_path = CONFIG_PSTORE_BLKOOPS_PART_PATH,
 };
@@ -106,6 +112,7 @@ static int __init blkoops_parse_dt(struct blkoops_info 
*info,
 
parse_size("partition-size", info->part_size);
parse_size("dmesg-size", info->dmesg_size);
+   parse_size("pmsg-size", info->pmsg_size);
 
 #undef parse_size
return 0;
@@ -148,6 +155,7 @@ static int blkoops_probe(struct platform_device *pdev)
 
check_size(part_size, 4096);
check_size(dmesg_size, 4096);
+   check_size(pmsg_size, 4096);
 
 #undef check_size
 
@@ -156,6 +164,7 @@ static int blkoops_probe(struct platform_device *pdev)
 * through /sys/module/blkoops/parameters/
 */
dmesg_size = blkz_info.dmesg_size;
+   pmsg_size = blkz_info.pmsg_size;
part_size = blkz_info.part_size;
if (blkz_info.part_path)
strncpy(part_path, blkz_info.part_path, 80 - 1);
@@ -202,6 +211,8 @@ void blkoops_register_dummy(void)
info->part_path = (const char *)part_path;
if (dmesg_size >= 0)
info->dmesg_size = (unsigned long)dmesg_size * 1024;
+   if (pmsg_size >= 0)
+   info->pmsg_size = (unsigned long)pmsg_size * 1024;
 
dummy = platform_device_register_data(NULL, MODNAME, -1, info,
sizeof(*info));
diff --git a/fs/pstore/blkzone.c b/fs/pstore/blkzone.c
index aca8c2a..0736472 100644
--- a/fs/pstore/blkzone.c
+++ b/fs/pstore/blkzone.c
@@ -34,12 +34,14 @@
  *
  * @sig: signature to indicate header (BLK_SIG xor BLKZONE-type value)
  * @datalen: length of data in @data
+ * @start: offset into @data where the beginning of the stored bytes begin
  * @data: zone data.
  */
 struct blkz_buffer {
 #define BLK_SIG (0x43474244) /* DBGC */
uint32_t sig;
atomic_t datalen;
+   atomic_t start;
uint8_t data[];
 };
 
@@ -72,6 +74,9 @@ struct blkz_dmesg_header {
  * frontent name for this zone
  * @buffer:
  * pointer to data buffer managed by this zone
+ * @oldbuf:
+ * pointer to old data buffer. It is used for single zone such as pmsg,
+ * saving the old buffer.
  * @buffer_size:
  * bytes in @buffer->data
  * @should_recover:
@@ -85,6 +90,7 @@ struct blkz_zone {
enum pstore_type_id type;
 
struct blkz_buffer *buffer;
+   struct blkz_buffer *oldbuf;
size_t buffer_size;
bool should_recover;
atomic_t dirty;
@@ -92,8 +98,10 @@ struct blkz_zone {
 
 struct blkz_context {
struct blkz_zone **dbzs;/* dmesg block zones */
+   struct blkz_zone *pbz;  /* Pmsg block zone */
unsigned int dmesg_max_cnt;
unsigned int dmesg_read_cnt;
+   unsigned int pmsg_read_cnt;
unsigned int dmesg_write_cnt;
/**
 * the counter should be recovered when do recovery
@@ -127,6 +135,11 @@ static inline int buffer_datalen(struct blkz_zone *zone)
return atomic_read(>buffer->datalen);
 }
 
+static inline int buffer_start(struct blkz_zone *zone)
+{
+   return atomic_read(>buffer->start);
+}
+
 static inline bool is_on_panic(void)
 {
struct blkz_context *cxt = _cxt;
@@ -401,6 +414,72 @@ static int blkz_recover_dmesg(struct blkz_context *cxt)
return ret;
 }
 
+static int blkz_recover_pmsg(struct blkz_context *cxt)
+{
+   struct blkz_info *info = cxt->bzinfo;
+   struct blkz_buffer *oldbuf;
+   struct blkz_zone *zone = NULL;
+   ssize_t (*readop)(char *buf, size_t bytes, loff_t pos);
+   int ret = 0;
+   ssize_t rcnt, len;
+
+   zone = cxt->pbz;
+   if (!zone || zone->oldbuf)
+   return 0

[RFC v7 0/5] pstore/block: new support logger for block devices

2019-01-23 Thread liaoweixiong
Why should we need pstore_block?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fast, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

[PATCH v7]
On patch 1:
1. Fix line over 80 characters.
On patch 2:
1. Insert a separate patch for DT bindings.

[PATCH v6]
On patch 1:
1. Fix according to email from Kees Cook, including spelling mistakes,
   explicit overflow test, none of the zeroing etc.
2. Do not recover data but metadata of dmesg when panic.
3. No need to take recovery when do erase.
4. Do not use "blkoops" for blkzone any more because "blkoops" is used for
   other module now. (rename blkbuf to blkoops)
On patch 2:
1. Rename blkbuf to blkoops.
2. Add Kconfig/device tree/module parameters settings for blkoops.
3. Add document for device tree.
On patch 3:
1. Blkoops support pmsg.
2. Fix description for new version patch.
On patch 4:
1. Fix description for new version patch.

[PATCH v5]
On patch 1:
1. rename pstore/rom to pstore/blk
2. Do not allocate any memory in the write path of panic. So, use local
array instead in function romz_recover_dmesg_meta.
3. Add C header file "linux/fs.h" to fix implicit declaration of function
   'filp_open','kernel_read'...
On patch 3:
1. If panic, do not recover pmsg but flush if it is dirty.
2. Fix erase pmsg failed.
On patch 4:
1. Create a document for pstore/blk

[PATCH v4]
On patch 1:
1. Fix always true condition '(--i >= 0) => (0-u32max >= 0)' in function
   romz_init_zones by defining variable i to 'int' rahter than
   'unsigned int'.
2. To make codes more easily to read, we use macro READ_NEXT_ZONE for
   return value of romz_dmesg_read if it need to read next zone.
   Moveover, we assign READ_NEXT_ZONE -1024 rather than 0.
3. Add 'FLUSH_META' to 'enum romz_flush_mode' and rename 'NOT_FLUSH' to
   'FLUSH_NONE'
4. Function romz_zone_write work badly with FLUSH_PART mode as badly
   address and offset to write.
On patch 3:
NEW SUPPORT psmg for pstore_rom.

[PATCH v3]
On patch 1:
Fix build as module error for undefined 'vfs_read' and 'vfs_write'
Both of 'vfs_read' and 'vfs_write' haven't be exproted yet, so we use
'kernel_read' and 'kernel_write' instead.

[PATCH v2]
On patch 1:
Fix build as module error for redefinition of 'romz_unregister' and
'romz_register'

[PATCH v1]
On patch 1:
Core codes of pstore_rom, which works well on allwinner(sunxi) platform.
On patch 2:
A sample for pstore_rom, using general ram rather than block device.

liaoweixiong (5):
  pstore/blk: new support logger for block devices
  dt-bindings: pstore-block: new support for blkoops
  pstore/blk: add blkoops for pstore_blk
  pstore/blk: support pmsg for pstore block
  Documentation: pstore/blk: create document for pstore_blk

 Documentation/admin-guide/pstore-block.rst |  227 
 .../devicetree/bindings/pstore-block/blkoops.txt   |   32 +
 MAINTAINERS|4 +-
 fs/pstore/Kconfig  |  128 +++
 fs/pstore/Makefile |5 +
 fs/pstore/blkoops.c|  250 +
 fs/pstore/blkzone.c| 1164 
 include/linux/pstore_blk.h |   62 ++
 8 files changed, 1871 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/admin-guide/pstore-block.rst
 create mode 100644 Documentation/devicetree/bindings/pstore-block/blkoops.txt
 create mode 100644 fs/pstore/blkoops.c
 create mode 100644 fs/pstore/blkzone.c
 create mode 100644 include/linux/pstore_blk.h

-- 
1.9.1



[RFC v7 2/5] dt-bindings: pstore-block: new support for blkoops

2019-01-23 Thread liaoweixiong
Create DT binding document for blkoops.

Signed-off-by: liaoweixiong 
---
 .../devicetree/bindings/pstore-block/blkoops.txt   | 32 ++
 MAINTAINERS|  1 +
 2 files changed, 33 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pstore-block/blkoops.txt

diff --git a/Documentation/devicetree/bindings/pstore-block/blkoops.txt 
b/Documentation/devicetree/bindings/pstore-block/blkoops.txt
new file mode 100644
index 000..a25835b
--- /dev/null
+++ b/Documentation/devicetree/bindings/pstore-block/blkoops.txt
@@ -0,0 +1,32 @@
+Blkoops oops logger
+===
+
+Blkoops provides a block partition for oops, excluding panics now, so they can
+be recovered after a reboot.
+
+Any space of block partition will be used for a circular buffer of oops 
records.
+These records have a configurable size, with a size of 0 indicating that they
+should be disabled.
+
+"partition-size" and at least one of "dmesg-size" or "pmsg-size" must be set
+non-zero, but are otherwise optional as listed below.
+
+Blkoops will take value from Kconfig if device tree do not set, but settings
+from module parameters can also overwrite them.
+
+Required properties:
+
+- compatible: must be "blkoops".
+
+- partition-size: size in kbytes, must be a multiple of 4.
+
+Optional properties:
+
+- partition-path: strings must begin with "/dev", tell blkoops which partition
+  it can used. If it is not set, blkoops will drop all data when reboot.
+
+- dmesg-size: maximum size in kbytes of each dump done on oops, which must be a
+  multiple of 4.
+
+- pmsg-size: maximum size in kbytes for userspace messages, which must be a
+  multiple of 4.
diff --git a/MAINTAINERS b/MAINTAINERS
index 0abecc5..91c70df 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12055,6 +12055,7 @@ F:  drivers/firmware/efi/efi-pstore.c
 F: drivers/acpi/apei/erst.c
 F: Documentation/admin-guide/ramoops.rst
 F: Documentation/devicetree/bindings/reserved-memory/ramoops.txt
+F: Documentation/devicetree/bindings/pstore-block/
 K: \b(pstore|ramoops)
 
 PTP HARDWARE CLOCK SUPPORT
-- 
1.9.1



[RFC v7 5/5] Documentation: pstore/blk: create document for pstore_blk

2019-01-23 Thread liaoweixiong
The document, at Documentation/admin-guide/pstore-block.rst,
tells user how to use pstore_blk and the attentions about panic
read/write

Signed-off-by: liaoweixiong 
---
 Documentation/admin-guide/pstore-block.rst | 227 +
 MAINTAINERS|   1 +
 fs/pstore/Kconfig  |   4 +
 3 files changed, 232 insertions(+)
 create mode 100644 Documentation/admin-guide/pstore-block.rst

diff --git a/Documentation/admin-guide/pstore-block.rst 
b/Documentation/admin-guide/pstore-block.rst
new file mode 100644
index 000..4bb8c4c
--- /dev/null
+++ b/Documentation/admin-guide/pstore-block.rst
@@ -0,0 +1,227 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Pstore block oops/panic logger
+==
+
+Introduction
+
+
+Pstore block (pstore_blk) is an oops/panic logger that write its logs to block
+device before the system crashes. Pstore_blk needs block device driver
+registering a partition path of the block device, like /dev/mmcblk0p7 for mmc
+driver, and read/write APIs for this partition when on panic.
+
+Pstore block concepts
+-
+
+Pstore block begins at function ``blkz_register``, by which block driver
+registers to pstore_blk. Recomemd that, block driver should register to
+pstore_blk after block device is ready. Block driver transfers a structure
+``blkz_info`` which is defined in *linux/pstore_blk.h*.
+
+The following key members of ``struct blkz_info`` may be of interest to you.
+
+part_path
+~
+
+The path of partition used for pstore_blk. It may be ``/dev/mmcblk[N]p[M]`` for
+mmc, and ``/dev/mtdblock[N]`` for mtd device.
+
+The ``part_path`` is not necessarily if you self-defined general read/write 
APIs
+on ``blkz_info``. In other words, the ``part_path`` is only used (by function
+blkz_default_general_read/write) when general read/write APIs are not defined.
+
+See more on section **read/write**.
+
+part_size
+~
+
+The total size in bytes of partition used for pstore_blk. This member **MUST**
+be effective and a multiple of 4096. It is recommended to 1M or larger for 
block
+device.
+
+The block device area is divided into many chunks, and each event writes
+a chunk of information.
+
+dmesg_size
+~~
+
+The chunk size in bytes for dmesg(oops/panic). It **MUST** be a multiple of
+SECTOR_SIZE (Most of the time, the SECTOR_SIZE is 512). If you don't need 
dmesg,
+you are safely to set it to 0.
+
+NOTE that, the remaining space, except ``pmsg_size`` and others, belongs to
+dmesg. It means that there are multiple chunks for dmesg.
+
+Psotre_blk will log to dmesg chunks one by one, and always overwrite the oldest
+chunk if no free chunk.
+
+pmsg_size
+~
+
+The chunk size in bytes for pmsg. It **MUST** be a multiple of SECTOR_SIZE 
(Most
+of the time, the SECTOR_SIZE is 512). If you don't need pmsg, you are safely to
+set it to 0.
+
+There is only one chunk for pmsg.
+
+Pmsg is a user space accessible pstore object. Writes to */dev/pmsg0* are
+appended to the chunk. On reboot the contents are available in
+/sys/fs/pstore/pmsg-pstore-blk-0.
+
+dump_oops
+~
+
+Dumping both oopses and panics can be done by setting 1 in the ``dump_oops``
+member while setting 0 in that variable dumps only the panics.
+
+read/write
+~~
+
+They are general ``read/write`` APIs. It is safely and recommended to ignore 
it,
+but set ``part_path``.
+
+These general APIs are used all the time expect panic. The ``read`` API is
+usually used to recover data from block device, and the ``write`` API is 
usually
+to flush new data and erase to block device.
+
+Pstore_blk will temporarily hold all new data before block device is ready. If
+you ignore both of ``read/write`` and ``part_path``, the old data will not be
+recovered and the new data will not be flushed until panic, using panic APIs.
+If you don't have panic APIs neither, all the data will be dropped when reboot.
+
+NOTE that, the general APIs must check whether the block device is ready if
+self-defined.
+
+panic_read/panic_write
+~~
+
+They are ``read/write`` APIs for panic. They are likely to general
+``read/write`` but will be used only when on panic.
+
+The attentions for panic read/write see section
+**Attentions in panic read/write APIs**.
+
+Register to pstore block
+
+
+Block device driver call ``blkz_register`` to register to Psotre_blk.
+For example:
+
+.. code-block:: c
+
+ #include 
+ [...]
+
+ static ssize_t _panic_read(char *buf, size bytes, loff_t pos)
+ {
+[...]
+ }
+
+ static ssize_t _panic_write(const char *buf, size_t bytes, loff_t pos)
+ {
+[...]
+ }
+
+ struct blkz_info _info = {
+.onwer = THIS_MODULE,
+.name = <...>,
+.dmesg_size = <...>,
+.pmsg_size = <...>,
+.dump_oops = true,
+.panic_read = _panic_read,
+.panic_write = _panic_write,
+ };
+
+

[RFC v7 3/5] pstore/blk: add blkoops for pstore_blk

2019-01-23 Thread liaoweixiong
blkoops is a sample for pstore/blk. It can only record oops, excluding
panics as no read/write apis for panic registered. It support settings
on Kconfg/device tree/module parameters. It can record oops log even
power failure if "PSTORE_BLKOOPS_PART_PATH" on Kconfig or
"partition-path" on dts or "part_path" on module parameter is valid.
Otherwise, it can only record data to ram buffer, which will be dropped
when reboot.

Signed-off-by: liaoweixiong 
---
 MAINTAINERS |   2 +-
 fs/pstore/Kconfig   | 117 +
 fs/pstore/Makefile  |   2 +
 fs/pstore/blkoops.c | 239 
 4 files changed, 359 insertions(+), 1 deletion(-)
 create mode 100644 fs/pstore/blkoops.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 91c70df..534c574 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12056,7 +12056,7 @@ F:  drivers/acpi/apei/erst.c
 F: Documentation/admin-guide/ramoops.rst
 F: Documentation/devicetree/bindings/reserved-memory/ramoops.txt
 F: Documentation/devicetree/bindings/pstore-block/
-K: \b(pstore|ramoops)
+K: \b(pstore|ramoops|blkoops)
 
 PTP HARDWARE CLOCK SUPPORT
 M: Richard Cochran 
diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index a881c53..f0a1a49 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -159,3 +159,120 @@ config PSTORE_BLK
help
  This enables panic and oops message to be logged to a block dev
  where it can be read back at some later point.
+
+config PSTORE_BLKOOPS
+   tristate "pstore block with oops logger"
+   depends on PSTORE_BLK
+   help
+ This is a sample for pstore block with oops logger.
+
+ It CANNOT record panic log as no read/write apis for panic registered.
+
+ It CAN record oops log even power failure if
+ "PSTORE_BLKOOPS_PART_PATH" on Kconfig or "partition-path" on dts or
+ "part_path" on module parameter is valid.
+
+ Otherwise, it can only record data to ram buffer, which will be
+ dropped when reboot.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. device tree
+It is set on device tree, which will overwrites value from Kconfig,
+but can also be overwritten by module parameters.
+ 3. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
+config PSTORE_BLKOOPS_DMESG_SIZE
+   int "dmesg_size in kbytes for blkoops"
+   depends on PSTORE_BLKOOPS
+   default 64
+   help
+ This just sets size of dmesg (dmesg_size) for pstore/blk. The value
+ must be a multiple of 4096.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. device tree
+It is set on device tree, which will overwrites value from Kconfig,
+but can also be overwritten by module parameters.
+ 3. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
+config PSTORE_BLKOOPS_PMSG_SIZE
+   int "pmsg_size in kbytes for blkoops"
+   depends on PSTORE_BLKOOPS
+   default 64
+   help
+ This just sets size of pmsg (pmsg_size) for pstore/blk. The value must
+ be a multiple of 4096. Pmsg work only if "part_path" is set.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. device tree
+It is set on device tree, which will overwrites value from Kconfig,
+but can also be overwritten by module parameters.
+ 3. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
+config PSTORE_BLKOOPS_PART_SIZE
+   int "part_size in kbytes for blkoops"
+   depends on PSTORE_BLKOOPS
+   default 1024
+   help
+ This just 

[RFC v7 1/5] pstore/blk: new support logger for block devices

2019-01-23 Thread liaoweixiong
pstore_blk is similar to pstore_ram, but dump log to block devices
rather than persistent ram.

Why should we need pstore_blk?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fact, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

pstore_blk can only dump Oops/Panic log to block devices. It only
supports dmesg now. To make pstore_blk work, the block driver should
provide the path of a block partition device (/dev/) and the
read/write apis when on panic.

pstore_blk begins at 'blkz_register', by witch block device can register
a block partition to pstore_blk. Then pstore_blk divide and manage the
partition as zones, which is similar to pstore_ram.

Recommend that, block driver register pstore_blk after block device is
ready.

pstore_blk works well on allwinner(sunxi) platform.

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig  |   7 +
 fs/pstore/Makefile |   3 +
 fs/pstore/blkzone.c| 954 +
 include/linux/pstore_blk.h |  61 +++
 4 files changed, 1025 insertions(+)
 create mode 100644 fs/pstore/blkzone.c
 create mode 100644 include/linux/pstore_blk.h

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index 8b3ba27..a881c53 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -152,3 +152,10 @@ config PSTORE_RAM
  "ramoops.ko".
 
  For more information, see Documentation/admin-guide/ramoops.rst.
+
+config PSTORE_BLK
+   tristate "Log panic/oops to a block device"
+   depends on PSTORE
+   help
+ This enables panic and oops message to be logged to a block dev
+ where it can be read back at some later point.
diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
index 967b589..0ee2fc8 100644
--- a/fs/pstore/Makefile
+++ b/fs/pstore/Makefile
@@ -12,3 +12,6 @@ pstore-$(CONFIG_PSTORE_PMSG)  += pmsg.o
 
 ramoops-objs += ram.o ram_core.o
 obj-$(CONFIG_PSTORE_RAM)   += ramoops.o
+
+obj-$(CONFIG_PSTORE_BLK) += pstore_blk.o
+pstore_blk-y += blkzone.o
diff --git a/fs/pstore/blkzone.c b/fs/pstore/blkzone.c
new file mode 100644
index 000..aca8c2a
--- /dev/null
+++ b/fs/pstore/blkzone.c
@@ -0,0 +1,954 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *
+ * blkzone.c: Block device Oops/Panic logger
+ *
+ * Copyright (C) 2019 liaoweixiong 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define MODNAME "pstore-blk"
+#define pr_fmt(fmt) MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * struct blkz_head - head of zone to flush to storage
+ *
+ * @sig: signature to indicate header (BLK_SIG xor BLKZONE-type value)
+ * @datalen: length of data in @data
+ * @data: zone data.
+ */
+struct blkz_buffer {
+#define BLK_SIG (0x43474244) /* DBGC */
+   uint32_t sig;
+   atomic_t datalen;
+   uint8_t data[];
+};
+
+/**
+ * struct blkz_dmesg_header: dmesg information
+ *
+ * @magic: magic num for dmesg header
+ * @time: trigger time
+ * @compressed: whether conpressed
+ * @count: oops/panic counter
+ * @reason: identify oops or panic
+ */
+struct blkz_dmesg_header {
+#define DMESG_HEADER_MAGIC 0x4dfc3ae5
+   uint32_t magic;
+   struct timespec64 time;
+   bool compressed;
+   uint32_t counter;
+   enum kmsg_dump_reason reason;
+   uint8_t data[0];
+};
+
+/**
+ * struct blkz_zone - zone information
+ * @off:
+ * zone offset of partition
+ * @type:
+ * frontent type for this zone
+ * @name:
+ * frontent name for this zone
+ * @buffer:
+ * pointer to data buffer managed by this zone
+ * @buffer_size:
+ * bytes in @buffer->data
+ * @should_recover:
+ * should recover from storage
+ * @dirty:
+ * mark whether the data in @buffer are dirty (not flush to storage yet)
+ */
+struct blkz_zone {
+   unsigned long off;
+   const char *name;
+   enum pstore_type_id type;
+
+   struct blkz_buffer *buffer;
+   size_t buffer_size;
+   bool should_recover;
+   atomic_t dirty;
+};
+
+struct blkz_context {
+   struct blkz_zone **dbzs;/* dmesg block zones */
+   unsigned int dmesg_max_cnt;
+   unsigned int dmesg_read_cnt;
+   unsigned int dmesg_write_cnt;
+   /**
+* the counter should be recovered when do re

Re: [RFC v5 3/4] pstore/blk: support pmsg for pstore block

2019-01-23 Thread liaoweixiong
Resend this mail.

On 2019-01-18 08:17, Kees Cook wrote:
> On Mon, Jan 7, 2019 at 4:01 AM liaoweixiong
>  wrote:
>>
>> To enable pmsg, just set pmsg_size when block device register blkzone.
> 
> At first pass, this looks like a reasonable extension of blkzone. Is
> it possible to add console, ftrace, etc, too?
> 

I plan to do that on other patch, because i am going to refine the
public codes for all extensions before add console, ftrace, etc. It
takes some time.

> -Kees
> 
>>
>> Signed-off-by: liaoweixiong 
>> ---
>>  fs/pstore/blkzone.c| 254 
>> +
>>  include/linux/pstore_blk.h |   1 +
>>  2 files changed, 233 insertions(+), 22 deletions(-)
>>
>> diff --git a/fs/pstore/blkzone.c b/fs/pstore/blkzone.c
>> index e1b7f26..157f1cfd 100644
>> --- a/fs/pstore/blkzone.c
>> +++ b/fs/pstore/blkzone.c
>> @@ -32,12 +32,14 @@
>>   *
>>   * @sig: signature to indicate header (BLK_SIG xor BLKZONE-type value)
>>   * @datalen: length of data in @data
>> + * @start: offset into @data where the beginning of the stored bytes begin
>>   * @data: zone data.
>>   */
>>  struct blkz_buffer {
>>  #define BLK_SIG (0x43474244) /* DBGC */
>> uint32_t sig;
>> atomic_t datalen;
>> +   atomic_t start;
>> uint8_t data[0];
>>  };
>>
>> @@ -70,6 +72,9 @@ struct blkz_dmesg_header {
>>   * frontent name for this zone
>>   * @buffer:
>>   * pointer to data buffer managed by this zone
>> + * @oldbuf:
>> + * pointer to old data buffer. It is used for single zone such as pmsg,
>> + * saving the old buffer.
>>   * @buffer_size:
>>   * bytes in @buffer->data
>>   * @should_recover:
>> @@ -83,6 +88,7 @@ struct blkz_zone {
>> enum pstore_type_id type;
>>
>> struct blkz_buffer *buffer;
>> +   struct blkz_buffer *oldbuf;
>> size_t buffer_size;
>> bool should_recover;
>> atomic_t dirty;
>> @@ -90,8 +96,10 @@ struct blkz_zone {
>>
>>  struct blkoops_context {
>> struct blkz_zone **dbzs;/* dmesg block zones */
>> +   struct blkz_zone *pbz;  /* Pmsg block zone */
>> unsigned int dmesg_max_cnt;
>> unsigned int dmesg_read_cnt;
>> +   unsigned int pmsg_read_cnt;
>> unsigned int dmesg_write_cnt;
>> /**
>>  * the counter should be recovered when do recovery
>> @@ -125,6 +133,11 @@ static inline int buffer_datalen(struct blkz_zone *zone)
>> return atomic_read(>buffer->datalen);
>>  }
>>
>> +static inline int buffer_start(struct blkz_zone *zone)
>> +{
>> +   return atomic_read(>buffer->start);
>> +}
>> +
>>  static inline bool is_on_panic(void)
>>  {
>> struct blkoops_context *cxt = _cxt;
>> @@ -394,6 +407,72 @@ static int blkz_recover_dmesg(struct blkoops_context 
>> *cxt)
>> return ret;
>>  }
>>
>> +static int blkz_recover_pmsg(struct blkoops_context *cxt)
>> +{
>> +   struct blkz_info *info = cxt->bzinfo;
>> +   struct blkz_buffer *oldbuf;
>> +   struct blkz_zone *zone = NULL;
>> +   ssize_t (*readop)(char *buf, size_t bytes, loff_t pos);
>> +   int ret = 0;
>> +   ssize_t rcnt, len;
>> +
>> +   zone = cxt->pbz;
>> +   if (!zone || zone->oldbuf)
>> +   return 0;
>> +
>> +   if (is_on_panic())
>> +   goto out;
>> +
>> +   readop = info->read;
>> +   if (unlikely(!readop))
>> +   return -EINVAL;
>> +
>> +   len = zone->buffer_size + sizeof(*oldbuf);
>> +   oldbuf = kzalloc(len, GFP_KERNEL);
>> +   if (!oldbuf)
>> +   return -ENOMEM;
>> +
>> +   rcnt = readop((char *)oldbuf, len, zone->off);
>> +   if (rcnt != len) {
>> +   pr_debug("recovery pmsg failed\n");
>> +   ret = (int)rcnt < 0 ? (int)rcnt : -EIO;
>> +   goto free_oldbuf;
>> +   }
>> +
>> +   if (oldbuf->sig != zone->buffer->sig) {
>> +   pr_debug("no valid data in zone %s\n", zone->name);
>> +   goto free_oldbuf;
>> +   }
>> +
>> +   if (zone->buffer_size < atomic_read(>datalen) ||
>> +   zone->buffer_size < atomic_read(>start)) {
>> +   pr_info("found over

[RFC v6 4/4] Documentation: pstore/blk: create document for pstore_blk

2019-01-23 Thread liaoweixiong
The document, at Documentation/admin-guide/pstore-block.rst,
tells user how to use pstore_blk and the attentions about panic
read/write

Signed-off-by: liaoweixiong 
---
 Documentation/admin-guide/pstore-block.rst | 227 +
 MAINTAINERS|   1 +
 fs/pstore/Kconfig  |   4 +
 3 files changed, 232 insertions(+)
 create mode 100644 Documentation/admin-guide/pstore-block.rst

diff --git a/Documentation/admin-guide/pstore-block.rst 
b/Documentation/admin-guide/pstore-block.rst
new file mode 100644
index 000..4bb8c4c
--- /dev/null
+++ b/Documentation/admin-guide/pstore-block.rst
@@ -0,0 +1,227 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Pstore block oops/panic logger
+==
+
+Introduction
+
+
+Pstore block (pstore_blk) is an oops/panic logger that write its logs to block
+device before the system crashes. Pstore_blk needs block device driver
+registering a partition path of the block device, like /dev/mmcblk0p7 for mmc
+driver, and read/write APIs for this partition when on panic.
+
+Pstore block concepts
+-
+
+Pstore block begins at function ``blkz_register``, by which block driver
+registers to pstore_blk. Recomemd that, block driver should register to
+pstore_blk after block device is ready. Block driver transfers a structure
+``blkz_info`` which is defined in *linux/pstore_blk.h*.
+
+The following key members of ``struct blkz_info`` may be of interest to you.
+
+part_path
+~
+
+The path of partition used for pstore_blk. It may be ``/dev/mmcblk[N]p[M]`` for
+mmc, and ``/dev/mtdblock[N]`` for mtd device.
+
+The ``part_path`` is not necessarily if you self-defined general read/write 
APIs
+on ``blkz_info``. In other words, the ``part_path`` is only used (by function
+blkz_default_general_read/write) when general read/write APIs are not defined.
+
+See more on section **read/write**.
+
+part_size
+~
+
+The total size in bytes of partition used for pstore_blk. This member **MUST**
+be effective and a multiple of 4096. It is recommended to 1M or larger for 
block
+device.
+
+The block device area is divided into many chunks, and each event writes
+a chunk of information.
+
+dmesg_size
+~~
+
+The chunk size in bytes for dmesg(oops/panic). It **MUST** be a multiple of
+SECTOR_SIZE (Most of the time, the SECTOR_SIZE is 512). If you don't need 
dmesg,
+you are safely to set it to 0.
+
+NOTE that, the remaining space, except ``pmsg_size`` and others, belongs to
+dmesg. It means that there are multiple chunks for dmesg.
+
+Psotre_blk will log to dmesg chunks one by one, and always overwrite the oldest
+chunk if no free chunk.
+
+pmsg_size
+~
+
+The chunk size in bytes for pmsg. It **MUST** be a multiple of SECTOR_SIZE 
(Most
+of the time, the SECTOR_SIZE is 512). If you don't need pmsg, you are safely to
+set it to 0.
+
+There is only one chunk for pmsg.
+
+Pmsg is a user space accessible pstore object. Writes to */dev/pmsg0* are
+appended to the chunk. On reboot the contents are available in
+/sys/fs/pstore/pmsg-pstore-blk-0.
+
+dump_oops
+~
+
+Dumping both oopses and panics can be done by setting 1 in the ``dump_oops``
+member while setting 0 in that variable dumps only the panics.
+
+read/write
+~~
+
+They are general ``read/write`` APIs. It is safely and recommended to ignore 
it,
+but set ``part_path``.
+
+These general APIs are used all the time expect panic. The ``read`` API is
+usually used to recover data from block device, and the ``write`` API is 
usually
+to flush new data and erase to block device.
+
+Pstore_blk will temporarily hold all new data before block device is ready. If
+you ignore both of ``read/write`` and ``part_path``, the old data will not be
+recovered and the new data will not be flushed until panic, using panic APIs.
+If you don't have panic APIs neither, all the data will be dropped when reboot.
+
+NOTE that, the general APIs must check whether the block device is ready if
+self-defined.
+
+panic_read/panic_write
+~~
+
+They are ``read/write`` APIs for panic. They are likely to general
+``read/write`` but will be used only when on panic.
+
+The attentions for panic read/write see section
+**Attentions in panic read/write APIs**.
+
+Register to pstore block
+
+
+Block device driver call ``blkz_register`` to register to Psotre_blk.
+For example:
+
+.. code-block:: c
+
+ #include 
+ [...]
+
+ static ssize_t _panic_read(char *buf, size bytes, loff_t pos)
+ {
+[...]
+ }
+
+ static ssize_t _panic_write(const char *buf, size_t bytes, loff_t pos)
+ {
+[...]
+ }
+
+ struct blkz_info _info = {
+.onwer = THIS_MODULE,
+.name = <...>,
+.dmesg_size = <...>,
+.pmsg_size = <...>,
+.dump_oops = true,
+.panic_read = _panic_read,
+.panic_write = _panic_write,
+ };
+
+

[RFC v6 2/4] pstore/blk: add blkoops for pstore_blk

2019-01-23 Thread liaoweixiong
blkoops is a sample for pstore/blk. It can only record oops, excluding
panics as no read/write apis for panic registered. It support settings
on Kconfg/device tree/module parameters. It can record oops log even
power failure if "PSTORE_BLKOOPS_PART_PATH" on Kconfig or
"partition-path" on dts or "part_path" on module parameter is valid.
Otherwise, it can only record data to ram buffer, which will be dropped
when reboot.

Signed-off-by: liaoweixiong 
---
 .../devicetree/bindings/pstore-block/blkoops.txt   |  32 +++
 MAINTAINERS|   3 +-
 fs/pstore/Kconfig  | 117 ++
 fs/pstore/Makefile |   2 +
 fs/pstore/blkoops.c| 239 +
 5 files changed, 392 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/pstore-block/blkoops.txt
 create mode 100644 fs/pstore/blkoops.c

diff --git a/Documentation/devicetree/bindings/pstore-block/blkoops.txt 
b/Documentation/devicetree/bindings/pstore-block/blkoops.txt
new file mode 100644
index 000..a25835b
--- /dev/null
+++ b/Documentation/devicetree/bindings/pstore-block/blkoops.txt
@@ -0,0 +1,32 @@
+Blkoops oops logger
+===
+
+Blkoops provides a block partition for oops, excluding panics now, so they can
+be recovered after a reboot.
+
+Any space of block partition will be used for a circular buffer of oops 
records.
+These records have a configurable size, with a size of 0 indicating that they
+should be disabled.
+
+"partition-size" and at least one of "dmesg-size" or "pmsg-size" must be set
+non-zero, but are otherwise optional as listed below.
+
+Blkoops will take value from Kconfig if device tree do not set, but settings
+from module parameters can also overwrite them.
+
+Required properties:
+
+- compatible: must be "blkoops".
+
+- partition-size: size in kbytes, must be a multiple of 4.
+
+Optional properties:
+
+- partition-path: strings must begin with "/dev", tell blkoops which partition
+  it can used. If it is not set, blkoops will drop all data when reboot.
+
+- dmesg-size: maximum size in kbytes of each dump done on oops, which must be a
+  multiple of 4.
+
+- pmsg-size: maximum size in kbytes for userspace messages, which must be a
+  multiple of 4.
diff --git a/MAINTAINERS b/MAINTAINERS
index 0abecc5..534c574 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12055,7 +12055,8 @@ F:  drivers/firmware/efi/efi-pstore.c
 F: drivers/acpi/apei/erst.c
 F: Documentation/admin-guide/ramoops.rst
 F: Documentation/devicetree/bindings/reserved-memory/ramoops.txt
-K: \b(pstore|ramoops)
+F: Documentation/devicetree/bindings/pstore-block/
+K: \b(pstore|ramoops|blkoops)
 
 PTP HARDWARE CLOCK SUPPORT
 M: Richard Cochran 
diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index a881c53..f0a1a49 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -159,3 +159,120 @@ config PSTORE_BLK
help
  This enables panic and oops message to be logged to a block dev
  where it can be read back at some later point.
+
+config PSTORE_BLKOOPS
+   tristate "pstore block with oops logger"
+   depends on PSTORE_BLK
+   help
+ This is a sample for pstore block with oops logger.
+
+ It CANNOT record panic log as no read/write apis for panic registered.
+
+ It CAN record oops log even power failure if
+ "PSTORE_BLKOOPS_PART_PATH" on Kconfig or "partition-path" on dts or
+ "part_path" on module parameter is valid.
+
+ Otherwise, it can only record data to ram buffer, which will be
+ dropped when reboot.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module parameters. It means that the value can
+ be overwritten by higher priority settings.
+ 1. Kconfig
+It just sets a default value.
+ 2. device tree
+It is set on device tree, which will overwrites value from Kconfig,
+but can also be overwritten by module parameters.
+ 3. module parameters
+It is the first priority. Take care of that blkoops will take lower
+priority settings if higher priority one do not set.
+
+config PSTORE_BLKOOPS_DMESG_SIZE
+   int "dmesg_size in kbytes for blkoops"
+   depends on PSTORE_BLKOOPS
+   default 64
+   help
+ This just sets size of dmesg (dmesg_size) for pstore/blk. The value
+ must be a multiple of 4096.
+
+ NOTE that, there are three ways to set parameters of blkoops and
+ prioritize according to configuration flexibility. That is
+ Kconfig < device tree < module paramete

[RFC v6 0/4] pstore/block: new support logger for block devices

2019-01-23 Thread liaoweixiong
Why should we need pstore_block?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fast, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

[PATCH v6]
On patch 1:
1. Fix according to email from Kees Cook, including spelling mistakes, explicit
   overflow test, none of the zeroing etc.
2. Do not recover data but metadata of dmesg when panic.
3. No need to take recovery when do erase.
4. Do not use "blkoops" for blkzone any more because "blkoops" is used for other
   module now.(rename blkbuf to blkoops)
On patch 2:
1. Rename blkbuf to blkoops.
2. Add Kconfig/device tree/module parameters settings for blkoops.
3. Add document for device tree.
On patch 3:
1. Blkoops support pmsg.
2. Fix description for new version patch.
On patch 4:
1. Fix description for new version patch.

[PATCH v5]
On patch 1:
1. rename pstore/rom to pstore/blk
2. Do not allocate any memory in the write path of panic. So, use local
array instead in function romz_recover_dmesg_meta.
3. Add C header file "linux/fs.h" to fix implicit declaration of function
   'filp_open','kernel_read'...
On patch 3:
1. If panic, do not recover pmsg but flush if it is dirty.
2. Fix erase pmsg failed.
On patch 4:
1. Create a document for pstore/blk

[PATCH v4]
On patch 1:
1. Fix always true condition '(--i >= 0) => (0-u32max >= 0)' in function
   romz_init_zones by defining variable i to 'int' rahter than
   'unsigned int'.
2. To make codes more easily to read, we use macro READ_NEXT_ZONE for
   return value of romz_dmesg_read if it need to read next zone.
   Moveover, we assign READ_NEXT_ZONE -1024 rather than 0.
3. Add 'FLUSH_META' to 'enum romz_flush_mode' and rename 'NOT_FLUSH' to
   'FLUSH_NONE'
4. Function romz_zone_write work badly with FLUSH_PART mode as badly
   address and offset to write.
On patch 3:
NEW SUPPORT psmg for pstore_rom.

[PATCH v3]
On patch 1:
Fix build as module error for undefined 'vfs_read' and 'vfs_write'
Both of 'vfs_read' and 'vfs_write' haven't be exproted yet, so we use
'kernel_read' and 'kernel_write' instead.

[PATCH v2]
On patch 1:
Fix build as module error for redefinition of 'romz_unregister' and
'romz_register'

[PATCH v1]
On patch 1:
Core codes of pstore_rom, which works well on allwinner(sunxi) platform.
On patch 2:
A sample for pstore_rom, using general ram rather than block device.

liaoweixiong (4):
  pstore/blk: new support logger for block devices
  pstore/blk: add blkoops for pstore_blk
  pstore/blk: support pmsg for pstore block
  Documentation: pstore/blk: create document for pstore_blk

 Documentation/admin-guide/pstore-block.rst |  227 
 .../devicetree/bindings/pstore-block/blkoops.txt   |   32 +
 MAINTAINERS|4 +-
 fs/pstore/Kconfig  |  128 +++
 fs/pstore/Makefile |5 +
 fs/pstore/blkoops.c|  250 +
 fs/pstore/blkzone.c| 1163 
 include/linux/pstore_blk.h |   62 ++
 8 files changed, 1870 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/admin-guide/pstore-block.rst
 create mode 100644 Documentation/devicetree/bindings/pstore-block/blkoops.txt
 create mode 100644 fs/pstore/blkoops.c
 create mode 100644 fs/pstore/blkzone.c
 create mode 100644 include/linux/pstore_blk.h

-- 
1.9.1



[RFC v6 1/4] pstore/blk: new support logger for block devices

2019-01-23 Thread liaoweixiong
pstore_blk is similar to pstore_ram, but dump log to block devices
rather than persistent ram.

Why should we need pstore_blk?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fact, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

pstore_blk can only dump Oops/Panic log to block devices. It only
supports dmesg now. To make pstore_blk work, the block driver should
provide the path of a block partition device (/dev/) and the
read/write apis when on panic.

pstore_blk begins at 'blkz_register', by witch block device can register
a block partition to pstore_blk. Then pstore_blk divide and manage the
partition as zones, which is similar to pstore_ram.

Recommend that, block driver register pstore_blk after block device is
ready.

pstore_blk works well on allwinner(sunxi) platform.

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig  |   7 +
 fs/pstore/Makefile |   3 +
 fs/pstore/blkzone.c| 953 +
 include/linux/pstore_blk.h |  61 +++
 4 files changed, 1024 insertions(+)
 create mode 100644 fs/pstore/blkzone.c
 create mode 100644 include/linux/pstore_blk.h

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index 8b3ba27..a881c53 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -152,3 +152,10 @@ config PSTORE_RAM
  "ramoops.ko".
 
  For more information, see Documentation/admin-guide/ramoops.rst.
+
+config PSTORE_BLK
+   tristate "Log panic/oops to a block device"
+   depends on PSTORE
+   help
+ This enables panic and oops message to be logged to a block dev
+ where it can be read back at some later point.
diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
index 967b589..0ee2fc8 100644
--- a/fs/pstore/Makefile
+++ b/fs/pstore/Makefile
@@ -12,3 +12,6 @@ pstore-$(CONFIG_PSTORE_PMSG)  += pmsg.o
 
 ramoops-objs += ram.o ram_core.o
 obj-$(CONFIG_PSTORE_RAM)   += ramoops.o
+
+obj-$(CONFIG_PSTORE_BLK) += pstore_blk.o
+pstore_blk-y += blkzone.o
diff --git a/fs/pstore/blkzone.c b/fs/pstore/blkzone.c
new file mode 100644
index 000..c26b919d
--- /dev/null
+++ b/fs/pstore/blkzone.c
@@ -0,0 +1,953 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *
+ * blkzone.c: Block device Oops/Panic logger
+ *
+ * Copyright (C) 2019 liaoweixiong 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define MODNAME "pstore-blk"
+#define pr_fmt(fmt) MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * struct blkz_head - head of zone to flush to storage
+ *
+ * @sig: signature to indicate header (BLK_SIG xor BLKZONE-type value)
+ * @datalen: length of data in @data
+ * @data: zone data.
+ */
+struct blkz_buffer {
+#define BLK_SIG (0x43474244) /* DBGC */
+   uint32_t sig;
+   atomic_t datalen;
+   uint8_t data[];
+};
+
+/**
+ * struct blkz_dmesg_header: dmesg information
+ *
+ * @magic: magic num for dmesg header
+ * @time: trigger time
+ * @compressed: whether conpressed
+ * @count: oops/panic counter
+ * @reason: identify oops or panic
+ */
+struct blkz_dmesg_header {
+#define DMESG_HEADER_MAGIC 0x4dfc3ae5
+   uint32_t magic;
+   struct timespec64 time;
+   bool compressed;
+   uint32_t counter;
+   enum kmsg_dump_reason reason;
+   uint8_t data[0];
+};
+
+/**
+ * struct blkz_zone - zone information
+ * @off:
+ * zone offset of partition
+ * @type:
+ * frontent type for this zone
+ * @name:
+ * frontent name for this zone
+ * @buffer:
+ * pointer to data buffer managed by this zone
+ * @buffer_size:
+ * bytes in @buffer->data
+ * @should_recover:
+ * should recover from storage
+ * @dirty:
+ * mark whether the data in @buffer are dirty (not flush to storage yet)
+ */
+struct blkz_zone {
+   unsigned long off;
+   const char *name;
+   enum pstore_type_id type;
+
+   struct blkz_buffer *buffer;
+   size_t buffer_size;
+   bool should_recover;
+   atomic_t dirty;
+};
+
+struct blkz_context {
+   struct blkz_zone **dbzs;/* dmesg block zones */
+   unsigned int dmesg_max_cnt;
+   unsigned int dmesg_read_cnt;
+   unsigned int dmesg_write_cnt;
+   /**
+* the counter should be recovered when do re

[RFC v6 3/4] pstore/blk: support pmsg for pstore block

2019-01-23 Thread liaoweixiong
To enable pmsg, just set pmsg_size when block device register blkzone.

Signed-off-by: liaoweixiong 
---
 fs/pstore/blkoops.c|  11 ++
 fs/pstore/blkzone.c| 254 +
 include/linux/pstore_blk.h |   1 +
 3 files changed, 244 insertions(+), 22 deletions(-)

diff --git a/fs/pstore/blkoops.c b/fs/pstore/blkoops.c
index fd926a5..b4b658e 100644
--- a/fs/pstore/blkoops.c
+++ b/fs/pstore/blkoops.c
@@ -30,6 +30,10 @@
 module_param(dmesg_size, long, 0400);
 MODULE_PARM_DESC(dmesg_size, "demsg size in kbytes");
 
+static long pmsg_size = -1;
+module_param(pmsg_size, long, 0400);
+MODULE_PARM_DESC(pmsg_size, "pmsg size in kbytes");
+
 static long part_size = -1;
 module_param(part_size, long, 0400);
 MODULE_PARM_DESC(part_size, "partition size in kbytes");
@@ -47,11 +51,13 @@ struct blkz_info blkz_info = {
 
 struct blkoops_info {
unsigned long dmesg_size;
+   unsigned long pmsg_size;
unsigned long part_size;
const char *part_path;
 };
 struct blkoops_info blkoops_info = {
.dmesg_size = CONFIG_PSTORE_BLKOOPS_DMESG_SIZE * 1024,
+   .pmsg_size = CONFIG_PSTORE_BLKOOPS_PMSG_SIZE * 1024,
.part_size = CONFIG_PSTORE_BLKOOPS_PART_SIZE * 1024,
.part_path = CONFIG_PSTORE_BLKOOPS_PART_PATH,
 };
@@ -106,6 +112,7 @@ static int __init blkoops_parse_dt(struct blkoops_info 
*info,
 
parse_size("partition-size", info->part_size);
parse_size("dmesg-size", info->dmesg_size);
+   parse_size("pmsg-size", info->pmsg_size);
 
 #undef parse_size
return 0;
@@ -148,6 +155,7 @@ static int blkoops_probe(struct platform_device *pdev)
 
check_size(part_size, 4096);
check_size(dmesg_size, 4096);
+   check_size(pmsg_size, 4096);
 
 #undef check_size
 
@@ -156,6 +164,7 @@ static int blkoops_probe(struct platform_device *pdev)
 * through /sys/module/blkoops/parameters/
 */
dmesg_size = blkz_info.dmesg_size;
+   pmsg_size = blkz_info.pmsg_size;
part_size = blkz_info.part_size;
if (blkz_info.part_path)
strncpy(part_path, blkz_info.part_path, 80 - 1);
@@ -202,6 +211,8 @@ void blkoops_register_dummy(void)
info->part_path = (const char *)part_path;
if (dmesg_size >= 0)
info->dmesg_size = (unsigned long)dmesg_size * 1024;
+   if (pmsg_size >= 0)
+   info->pmsg_size = (unsigned long)pmsg_size * 1024;
 
dummy = platform_device_register_data(NULL, MODNAME, -1, info,
sizeof(*info));
diff --git a/fs/pstore/blkzone.c b/fs/pstore/blkzone.c
index c26b919d..e7cd7c6 100644
--- a/fs/pstore/blkzone.c
+++ b/fs/pstore/blkzone.c
@@ -34,12 +34,14 @@
  *
  * @sig: signature to indicate header (BLK_SIG xor BLKZONE-type value)
  * @datalen: length of data in @data
+ * @start: offset into @data where the beginning of the stored bytes begin
  * @data: zone data.
  */
 struct blkz_buffer {
 #define BLK_SIG (0x43474244) /* DBGC */
uint32_t sig;
atomic_t datalen;
+   atomic_t start;
uint8_t data[];
 };
 
@@ -72,6 +74,9 @@ struct blkz_dmesg_header {
  * frontent name for this zone
  * @buffer:
  * pointer to data buffer managed by this zone
+ * @oldbuf:
+ * pointer to old data buffer. It is used for single zone such as pmsg,
+ * saving the old buffer.
  * @buffer_size:
  * bytes in @buffer->data
  * @should_recover:
@@ -85,6 +90,7 @@ struct blkz_zone {
enum pstore_type_id type;
 
struct blkz_buffer *buffer;
+   struct blkz_buffer *oldbuf;
size_t buffer_size;
bool should_recover;
atomic_t dirty;
@@ -92,8 +98,10 @@ struct blkz_zone {
 
 struct blkz_context {
struct blkz_zone **dbzs;/* dmesg block zones */
+   struct blkz_zone *pbz;  /* Pmsg block zone */
unsigned int dmesg_max_cnt;
unsigned int dmesg_read_cnt;
+   unsigned int pmsg_read_cnt;
unsigned int dmesg_write_cnt;
/**
 * the counter should be recovered when do recovery
@@ -127,6 +135,11 @@ static inline int buffer_datalen(struct blkz_zone *zone)
return atomic_read(>buffer->datalen);
 }
 
+static inline int buffer_start(struct blkz_zone *zone)
+{
+   return atomic_read(>buffer->start);
+}
+
 static inline bool is_on_panic(void)
 {
struct blkz_context *cxt = _cxt;
@@ -401,6 +414,72 @@ static int blkz_recover_dmesg(struct blkz_context *cxt)
return ret;
 }
 
+static int blkz_recover_pmsg(struct blkz_context *cxt)
+{
+   struct blkz_info *info = cxt->bzinfo;
+   struct blkz_buffer *oldbuf;
+   struct blkz_zone *zone = NULL;
+   ssize_t (*readop)(char *buf, size_t bytes, loff_t pos);
+   int ret = 0;
+   ssize_t rcnt, len;
+
+   zone = cxt->pbz;
+   if (!zone || zone->oldbuf)
+   return 0

Re: [RFC v5 2/4] pstore/blk: add sample for pstore_blk

2019-01-19 Thread liaoweixiong
resend this email.

On 2019-01-18 08:21, Kees Cook wrote:
> On Thu, Jan 17, 2019 at 4:15 PM Kees Cook  wrote:
>>
>> On Mon, Jan 7, 2019 at 4:01 AM liaoweixiong
>>  wrote:
>>>
>>> It is a sample for pstore_blk, using general ram rather than block device.
>>> According to pstore_blk, the data will be saved to ram buffer if not
>>> register device path and apis for panic. So, it can only used to dump
>>> Oops and some things will not reboot.
>>
>> I'm not sure I see the purpose of this implementation? Doesn't this
>> just cause all the pstore machinery to skip any actions? i.e. without
>> bzinfo->part_path, won't blkz_sample_write() just return -EINVAL, etc?
> 
> Say, instead of a no-op driver, can you build something like the how
> ramoops processes module parameters, so that a person can define an
> arbitrary device at boot time for blkoops? This also allows for easier
> runtime testing too.

Sure, i will do it in next version. But it can only use for oops,
excluding panic.
I have no idea how to pass panic operation parameters.

> 
> This all looks good, with some minor tweaks as mentioned. And on
> closer review, yeah, it doesn't look like it shares much with ramoops.
> :)
> 
> Thanks for sending this series; I look forward to the next version. :)
> 
> -Kees
> 


Re: [RFC v5 2/4] pstore/blk: add sample for pstore_blk

2019-01-19 Thread liaoweixiong
On 2019-01-18 08:15, Kees Cook wrote:
> On Mon, Jan 7, 2019 at 4:01 AM liaoweixiong
>  wrote:
>>
>> It is a sample for pstore_blk, using general ram rather than block device.
>> According to pstore_blk, the data will be saved to ram buffer if not
>> register device path and apis for panic. So, it can only used to dump
>> Oops and some things will not reboot.
> 
> I'm not sure I see the purpose of this implementation? Doesn't this
> just cause all the pstore machinery to skip any actions?

It just a sample for pstore_blk, which can used to record OOPS log on
ram buffer. This module make it easier for device, without panic apis,
to record oops log only.

> i.e. without bzinfo->part_path, won't blkz_sample_write() just return
-EINVAL, etc?

Sure, blkz_sample_write (named blkz_default_general_write now) just
return -EINVAL without bzinfo->part_path. How is the write path? It is
blkoops_pstore_write->blkz_dmesg_write->blkz_zone_write->blkz_default_general_write.
The blkz_zone_write will save the log to ram buffer even
blkz_default_general_write return failure.

>>
>> Signed-off-by: liaoweixiong 
>> ---
>>  fs/pstore/Kconfig  |  9 +
>>  fs/pstore/Makefile |  2 ++
>>  fs/pstore/blkbuf.c | 46 ++
>>  3 files changed, 57 insertions(+)
>>  create mode 100644 fs/pstore/blkbuf.c
>>
>> diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
>> index a881c53..18b1fe6 100644
>> --- a/fs/pstore/Kconfig
>> +++ b/fs/pstore/Kconfig
>> @@ -159,3 +159,12 @@ config PSTORE_BLK
>> help
>>   This enables panic and oops message to be logged to a block dev
>>   where it can be read back at some later point.
>> +
>> +config PSTORE_BLKBUF
>> +   tristate "pstore block buffer sample"
>> +   depends on PSTORE_BLK
>> +   help
>> + This is a sample for pstore block, but do NOT have a block dev.
>> + According to pstore_blk, the data will be saved to ram buffer and
>> + dropped when reboot. So, it can only used to dump Oops and some
>> + things will not reboot.
>> diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
>> index c431700..4a6cde1 100644
>> --- a/fs/pstore/Makefile
>> +++ b/fs/pstore/Makefile
>> @@ -15,3 +15,5 @@ obj-$(CONFIG_PSTORE_RAM)  += ramoops.o
>>
>>  obj-$(CONFIG_PSTORE_BLK)   += pstore_blk.o
>>  pstore_blk-y += blkzone.o
>> +
>> +obj-$(CONFIG_PSTORE_BLKBUF)+= blkbuf.o
>> diff --git a/fs/pstore/blkbuf.c b/fs/pstore/blkbuf.c
>> new file mode 100644
>> index 000..f1c6f57
>> --- /dev/null
>> +++ b/fs/pstore/blkbuf.c
>> @@ -0,0 +1,46 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + *
>> + * blkbuf.c: Block device Oops/Panic logger
>> + *
>> + * Copyright (C) 2019 liaoweixiong 
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + */
>> +#define pr_fmt(fmt) "blkbuf: " fmt
>> +
>> +#include 
>> +#include 
>> +#include 
>> +
>> +struct blkz_info blkbuf_info = {
>> +   .owner = THIS_MODULE,
>> +   .name = "blkbuf",
>> +   .part_size = 512 * 1024,
>> +   .dmesg_size = 64 * 1024,
>> +   .dump_oops = true,
>> +};
>> +
>> +static int __init blkbuf_init(void)
>> +{
>> +   return blkz_register(_info);
>> +}
>> +module_init(blkbuf_init);
>> +
>> +static void __exit blkbuf_exit(void)
>> +{
>> +   blkz_unregister(_info);
>> +}
>> +module_exit(blkbuf_exit);
>> +
>> +MODULE_LICENSE("GPL");
>> +MODULE_AUTHOR("liaoweixiong ");
>> +MODULE_DESCRIPTION("Sample for Pstore BLK with Oops logger");
>> --
>> 1.9.1
>>
> 
> 


Re: [RFC v5 1/4] pstore/blk: new support logger for block devices

2019-01-19 Thread liaoweixiong
On 2019-01-18 08:12, Kees Cook wrote:
> On Mon, Jan 7, 2019 at 4:01 AM liaoweixiong
>  wrote:
>>
>> pstore_blk is similar to pstore_ram, but dump log to block devices
>> rather than persistent ram.
>>
>> Why should we need pstore_blk?
>> 1. Most embedded intelligent equipment have no persistent ram, which
>> increases costs. We perfer to cheaper solutions, like block devices.
>> In fast, there is already a sample for block device logger in driver
> 
> typo: fast -> fact

Fixed. Thank you for your careful correction.

> 
>> MTD (drivers/mtd/mtdoops.c).
> 
> Would mtdoops get dropped in favor of pstore/blk, or do they not share 
> features?
> 

We can show them what pstore/blk do. I think they will be interested in it.
They should do a little work, including make a function for panic read,
then they gain enhanced features, including present logs as a file,
record multiple logs.

>> 2. Do not any equipment have battery, which means that it lost all data
>> on general ram if power failure. Pstore has little to do for these
>> equipments.
>>
>> pstore_blk can only dump Oops/Panic log to block devices. It only
>> supports dmesg now. To make pstore_blk work, the block driver should
>> provide the path of a block partition device (/dev/) and the
>> read/write apis when on panic.
>>
>> pstore_blk begins at 'blkz_register', by witch block device can register
>> a block partition to pstore_blk. Then pstore_blk divide and manage the
>> partition as zones, which is similar to pstore_ram.
>>
>> Recommend that, block driver register pstore_blk after block device is
>> ready.
>>
>> pstore_blk works well on allwinner(sunxi) platform.
>>
>> Signed-off-by: liaoweixiong 
>> ---
>>  fs/pstore/Kconfig  |   7 +
>>  fs/pstore/Makefile |   3 +
>>  fs/pstore/blkzone.c| 958 
>> +
>>  include/linux/pstore_blk.h |  61 +++
>>  4 files changed, 1029 insertions(+)
>>  create mode 100644 fs/pstore/blkzone.c
>>  create mode 100644 include/linux/pstore_blk.h
>>
>> diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
>> index 8b3ba27..a881c53 100644
>> --- a/fs/pstore/Kconfig
>> +++ b/fs/pstore/Kconfig
>> @@ -152,3 +152,10 @@ config PSTORE_RAM
>>   "ramoops.ko".
>>
>>   For more information, see Documentation/admin-guide/ramoops.rst.
>> +
>> +config PSTORE_BLK
>> +   tristate "Log panic/oops to a block device"
>> +   depends on PSTORE
>> +   help
>> + This enables panic and oops message to be logged to a block dev
>> + where it can be read back at some later point.
>> diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
>> index 967b589..c431700 100644
>> --- a/fs/pstore/Makefile
>> +++ b/fs/pstore/Makefile
>> @@ -12,3 +12,6 @@ pstore-$(CONFIG_PSTORE_PMSG)  += pmsg.o
>>
>>  ramoops-objs += ram.o ram_core.o
>>  obj-$(CONFIG_PSTORE_RAM)   += ramoops.o
>> +
>> +obj-$(CONFIG_PSTORE_BLK)   += pstore_blk.o
>> +pstore_blk-y += blkzone.o
>> diff --git a/fs/pstore/blkzone.c b/fs/pstore/blkzone.c
>> new file mode 100644
>> index 000..e1b7f26
>> --- /dev/null
>> +++ b/fs/pstore/blkzone.c
>> @@ -0,0 +1,958 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + *
>> + * blkzone.c: Block device Oops/Panic logger
>> + *
>> + * Copyright (C) 2019 liaoweixiong 
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + * GNU General Public License for more details.
>> + *
>> + */
>> +
>> +#define pr_fmt(fmt) "blkzone: " fmt
> 
> To follow with "ramoops", maybe this should be "blkoops"? I don't have
> a strong opinion, but "zone" is only used internally in ram.c for the
> memory segments (zones), so it's not clear to me if "blkzone" is
> meaningful to a given pstore end user.
> 

You are right, "zone" will cause misunderstanding. How about "pstore_blk"?
I change it as follow:

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

>> +
>> +#include 
>> +#include 
>> +#include 
>>

[RFC v5 4/4] Documentation: pstore/blk: create document for pstore_blk

2019-01-07 Thread liaoweixiong
The documemt, at Documentation/admin-guide/pstore-block.rst,
tells user how to use pstore_blk and the attentions about panic
read/write

Signed-off-by: liaoweixiong 
---
 Documentation/admin-guide/pstore-block.rst | 226 +
 MAINTAINERS|   1 +
 fs/pstore/Kconfig  |   4 +
 3 files changed, 231 insertions(+)
 create mode 100644 Documentation/admin-guide/pstore-block.rst

diff --git a/Documentation/admin-guide/pstore-block.rst 
b/Documentation/admin-guide/pstore-block.rst
new file mode 100644
index 000..2fc9fd8
--- /dev/null
+++ b/Documentation/admin-guide/pstore-block.rst
@@ -0,0 +1,226 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Pstore block oops/panic logger
+==
+
+Introduction
+
+
+Pstore block (pstore_blk) is an oops/panic logger that write its logs to block
+device before the system crashes. Pstore_blk needs block device driver
+registering a partition path of the block device, like /dev/mmcblk0p7 for mmc
+driver, and read/write APIs for this partition when on panic.
+
+Pstore block concepts
+-
+
+Pstore block begins at function ``blkz_register``, by which block driver
+registers to pstore_blk. Recomemd that, block driver should register to
+pstore_blk after block device is ready. Block driver transfers a structure
+``blkz_info`` which is defined in *linux/pstore_blk.h*.
+
+The following key members of ``struct blkz_info`` may be of interest to you.
+
+part_path
+~
+
+The path of partition used for pstore_blk. It may be ``/dev/mmcblk[N]p[M]`` for
+mmc, and ``/dev/mtdblock[N]`` for mtd device.
+
+The ``part_path`` is not necessarily if you self-defined general read/write 
APIs
+on ``blkz_info``. In other words, the ``part_path`` is only used (by function
+blkz_sample_read/write) when general read/write APIs are not defined.
+
+See more on section **read/write**.
+
+part_size
+~
+
+The total size in bytes of partition used for pstore_blk. This member **MUST**
+be effective and a multiple of 4096. It is recommended to 1M or larger for 
block
+device.
+
+The block device area is divided into many chunks, and each event writes
+a chunk of information.
+
+dmesg_size
+~~
+
+The chunk size in bytes for dmesg(oops/panic). It **MUST** be a multiple of
+SECTOR_SIZE (Most of the time, the SECTOR_SIZE is 512). If you don't need 
dmesg,
+you are safely to set it to 0.
+
+NOTE that, the remaining space, except ``pmsg_size`` and others, belongs to
+dmesg. It means that there are multiple chunks for dmesg.
+
+Psotre_blk will log to dmesg chunks one by one, and always overwrite the oldest
+chunk if no free chunk.
+
+pmsg_size
+~
+
+The chunk size in bytes for pmsg. It **MUST** be a multiple of SECTOR_SIZE 
(Most
+of the time, the SECTOR_SIZE is 512). If you don't need pmsg, you are safely to
+set it to 0.
+
+There is only one chunk for pmsg.
+
+Pmsg is a user space accessible pstore object. Writes to */dev/pmsg0* are
+appended to the chunk. On reboot the contents are available in
+/sys/fs/pstore/pmsg-blkoops-0.
+
+dump_oops
+~
+
+Dumping both oopses and panics can be done by setting 1 in the ``dump_oops``
+member while setting 0 in that variable dumps only the panics.
+
+read/write
+~~
+
+They are general ``read/write`` APIs. It is safely and recommended to ignore 
it,
+but set ``part_path``.
+
+These general APIs are used all the time expect panic. The ``read`` API is
+usually used to recover data from block device, and the ``write`` API is 
usually
+to flush new data and erase to block device.
+
+Pstore_blk will temporarily hold all new data before block device is ready. If
+you ignore both of ``read/write`` and ``part_path``, the old data will not be
+recovered and the new data will not be flushed until panic, using panic APIs.
+If you don't have panic APIs neither, all the data will be dropped when reboot.
+
+NOTE that, the general APIs must check whether the block device is ready if
+self-defined.
+
+panic_read/panic_write
+~~
+
+They are ``read/write`` APIs for panic. They are likely to general
+``read/write`` but will be used only when on panic.
+
+The attentions for panic read/write see section
+**Attentions in panic read/write APIs**.
+
+Register to pstore block
+
+
+Block device driver call ``blkz_register`` to register to Psotre_blk.
+For example:
+
+.. code-block:: c
+
+ #include 
+ [...]
+
+ static ssize_t _panic_read(char *buf, size bytes, loff_t pos)
+ {
+[...]
+ }
+
+ static ssize_t _panic_write(const char *buf, size_t bytes, loff_t pos)
+ {
+[...]
+ }
+
+ struct blkz_info _info = {
+.onwer = THIS_MODULE,
+.name = <...>,
+.dmesg_size = <...>,
+.pmsg_size = <...>,
+.dump_oops = true,
+.panic_read = _panic_read,
+.panic_write = _panic_write,
+ };
+
+ static int __i

[RFC v5 2/4] pstore/blk: add sample for pstore_blk

2019-01-07 Thread liaoweixiong
It is a sample for pstore_blk, using general ram rather than block device.
According to pstore_blk, the data will be saved to ram buffer if not
register device path and apis for panic. So, it can only used to dump
Oops and some things will not reboot.

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig  |  9 +
 fs/pstore/Makefile |  2 ++
 fs/pstore/blkbuf.c | 46 ++
 3 files changed, 57 insertions(+)
 create mode 100644 fs/pstore/blkbuf.c

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index a881c53..18b1fe6 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -159,3 +159,12 @@ config PSTORE_BLK
help
  This enables panic and oops message to be logged to a block dev
  where it can be read back at some later point.
+
+config PSTORE_BLKBUF
+   tristate "pstore block buffer sample"
+   depends on PSTORE_BLK
+   help
+ This is a sample for pstore block, but do NOT have a block dev.
+ According to pstore_blk, the data will be saved to ram buffer and
+ dropped when reboot. So, it can only used to dump Oops and some
+ things will not reboot.
diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
index c431700..4a6cde1 100644
--- a/fs/pstore/Makefile
+++ b/fs/pstore/Makefile
@@ -15,3 +15,5 @@ obj-$(CONFIG_PSTORE_RAM)  += ramoops.o
 
 obj-$(CONFIG_PSTORE_BLK)   += pstore_blk.o
 pstore_blk-y += blkzone.o
+
+obj-$(CONFIG_PSTORE_BLKBUF)+= blkbuf.o
diff --git a/fs/pstore/blkbuf.c b/fs/pstore/blkbuf.c
new file mode 100644
index 000..f1c6f57
--- /dev/null
+++ b/fs/pstore/blkbuf.c
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *
+ * blkbuf.c: Block device Oops/Panic logger
+ *
+ * Copyright (C) 2019 liaoweixiong 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#define pr_fmt(fmt) "blkbuf: " fmt
+
+#include 
+#include 
+#include 
+
+struct blkz_info blkbuf_info = {
+   .owner = THIS_MODULE,
+   .name = "blkbuf",
+   .part_size = 512 * 1024,
+   .dmesg_size = 64 * 1024,
+   .dump_oops = true,
+};
+
+static int __init blkbuf_init(void)
+{
+   return blkz_register(_info);
+}
+module_init(blkbuf_init);
+
+static void __exit blkbuf_exit(void)
+{
+   blkz_unregister(_info);
+}
+module_exit(blkbuf_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("liaoweixiong ");
+MODULE_DESCRIPTION("Sample for Pstore BLK with Oops logger");
-- 
1.9.1



[RFC v5 1/4] pstore/blk: new support logger for block devices

2019-01-07 Thread liaoweixiong
pstore_blk is similar to pstore_ram, but dump log to block devices
rather than persistent ram.

Why should we need pstore_blk?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fast, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

pstore_blk can only dump Oops/Panic log to block devices. It only
supports dmesg now. To make pstore_blk work, the block driver should
provide the path of a block partition device (/dev/) and the
read/write apis when on panic.

pstore_blk begins at 'blkz_register', by witch block device can register
a block partition to pstore_blk. Then pstore_blk divide and manage the
partition as zones, which is similar to pstore_ram.

Recommend that, block driver register pstore_blk after block device is
ready.

pstore_blk works well on allwinner(sunxi) platform.

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig  |   7 +
 fs/pstore/Makefile |   3 +
 fs/pstore/blkzone.c| 958 +
 include/linux/pstore_blk.h |  61 +++
 4 files changed, 1029 insertions(+)
 create mode 100644 fs/pstore/blkzone.c
 create mode 100644 include/linux/pstore_blk.h

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index 8b3ba27..a881c53 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -152,3 +152,10 @@ config PSTORE_RAM
  "ramoops.ko".
 
  For more information, see Documentation/admin-guide/ramoops.rst.
+
+config PSTORE_BLK
+   tristate "Log panic/oops to a block device"
+   depends on PSTORE
+   help
+ This enables panic and oops message to be logged to a block dev
+ where it can be read back at some later point.
diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
index 967b589..c431700 100644
--- a/fs/pstore/Makefile
+++ b/fs/pstore/Makefile
@@ -12,3 +12,6 @@ pstore-$(CONFIG_PSTORE_PMSG)  += pmsg.o
 
 ramoops-objs += ram.o ram_core.o
 obj-$(CONFIG_PSTORE_RAM)   += ramoops.o
+
+obj-$(CONFIG_PSTORE_BLK)   += pstore_blk.o
+pstore_blk-y += blkzone.o
diff --git a/fs/pstore/blkzone.c b/fs/pstore/blkzone.c
new file mode 100644
index 000..e1b7f26
--- /dev/null
+++ b/fs/pstore/blkzone.c
@@ -0,0 +1,958 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *
+ * blkzone.c: Block device Oops/Panic logger
+ *
+ * Copyright (C) 2019 liaoweixiong 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define pr_fmt(fmt) "blkzone: " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * struct blkz_head - head of zone to flush to storage
+ *
+ * @sig: signature to indicate header (BLK_SIG xor BLKZONE-type value)
+ * @datalen: length of data in @data
+ * @data: zone data.
+ */
+struct blkz_buffer {
+#define BLK_SIG (0x43474244) /* DBGC */
+   uint32_t sig;
+   atomic_t datalen;
+   uint8_t data[0];
+};
+
+/**
+ * sruct blkz_dmesg_header: dmesg information
+ *
+ * @magic: magic num for dmesg header
+ * @time: trigger time
+ * @compressed: whether conpressed
+ * @count: oops/panic counter
+ * @reason: identify oops or panic
+ */
+struct blkz_dmesg_header {
+#define DMESG_HEADER_MAGIC 0x4dfc3ae5
+   uint32_t magic;
+   struct timespec64 time;
+   bool compressed;
+   uint32_t counter;
+   enum kmsg_dump_reason reason;
+   uint8_t data[0];
+};
+
+/**
+ * struct blkz_zone - zone information
+ * @off:
+ * zone offset of partition
+ * @type:
+ * frontent type for this zone
+ * @name:
+ * frontent name for this zone
+ * @buffer:
+ * pointer to data buffer managed by this zone
+ * @buffer_size:
+ * bytes in @buffer->data
+ * @should_recover:
+ * should recover from storage
+ * @dirty:
+ * mark whether the data in @buffer are dirty (not flush to storage yet)
+ */
+struct blkz_zone {
+   unsigned long off;
+   const char *name;
+   enum pstore_type_id type;
+
+   struct blkz_buffer *buffer;
+   size_t buffer_size;
+   bool should_recover;
+   atomic_t dirty;
+};
+
+struct blkoops_context {
+   struct blkz_zone **dbzs;/* dmesg block zones */
+   unsigned int dmesg_max_cnt;
+   unsigned int dmesg_read_cnt;
+   unsigned int dmesg_write_cnt;
+   /**
+* the counter should be recovered when do recovery
+* It records the oops/pani

[RFC v5 3/4] pstore/blk: support pmsg for pstore block

2019-01-07 Thread liaoweixiong
To enable pmsg, just set pmsg_size when block device register blkzone.

Signed-off-by: liaoweixiong 
---
 fs/pstore/blkzone.c| 254 +
 include/linux/pstore_blk.h |   1 +
 2 files changed, 233 insertions(+), 22 deletions(-)

diff --git a/fs/pstore/blkzone.c b/fs/pstore/blkzone.c
index e1b7f26..157f1cfd 100644
--- a/fs/pstore/blkzone.c
+++ b/fs/pstore/blkzone.c
@@ -32,12 +32,14 @@
  *
  * @sig: signature to indicate header (BLK_SIG xor BLKZONE-type value)
  * @datalen: length of data in @data
+ * @start: offset into @data where the beginning of the stored bytes begin
  * @data: zone data.
  */
 struct blkz_buffer {
 #define BLK_SIG (0x43474244) /* DBGC */
uint32_t sig;
atomic_t datalen;
+   atomic_t start;
uint8_t data[0];
 };
 
@@ -70,6 +72,9 @@ struct blkz_dmesg_header {
  * frontent name for this zone
  * @buffer:
  * pointer to data buffer managed by this zone
+ * @oldbuf:
+ * pointer to old data buffer. It is used for single zone such as pmsg,
+ * saving the old buffer.
  * @buffer_size:
  * bytes in @buffer->data
  * @should_recover:
@@ -83,6 +88,7 @@ struct blkz_zone {
enum pstore_type_id type;
 
struct blkz_buffer *buffer;
+   struct blkz_buffer *oldbuf;
size_t buffer_size;
bool should_recover;
atomic_t dirty;
@@ -90,8 +96,10 @@ struct blkz_zone {
 
 struct blkoops_context {
struct blkz_zone **dbzs;/* dmesg block zones */
+   struct blkz_zone *pbz;  /* Pmsg block zone */
unsigned int dmesg_max_cnt;
unsigned int dmesg_read_cnt;
+   unsigned int pmsg_read_cnt;
unsigned int dmesg_write_cnt;
/**
 * the counter should be recovered when do recovery
@@ -125,6 +133,11 @@ static inline int buffer_datalen(struct blkz_zone *zone)
return atomic_read(>buffer->datalen);
 }
 
+static inline int buffer_start(struct blkz_zone *zone)
+{
+   return atomic_read(>buffer->start);
+}
+
 static inline bool is_on_panic(void)
 {
struct blkoops_context *cxt = _cxt;
@@ -394,6 +407,72 @@ static int blkz_recover_dmesg(struct blkoops_context *cxt)
return ret;
 }
 
+static int blkz_recover_pmsg(struct blkoops_context *cxt)
+{
+   struct blkz_info *info = cxt->bzinfo;
+   struct blkz_buffer *oldbuf;
+   struct blkz_zone *zone = NULL;
+   ssize_t (*readop)(char *buf, size_t bytes, loff_t pos);
+   int ret = 0;
+   ssize_t rcnt, len;
+
+   zone = cxt->pbz;
+   if (!zone || zone->oldbuf)
+   return 0;
+
+   if (is_on_panic())
+   goto out;
+
+   readop = info->read;
+   if (unlikely(!readop))
+   return -EINVAL;
+
+   len = zone->buffer_size + sizeof(*oldbuf);
+   oldbuf = kzalloc(len, GFP_KERNEL);
+   if (!oldbuf)
+   return -ENOMEM;
+
+   rcnt = readop((char *)oldbuf, len, zone->off);
+   if (rcnt != len) {
+   pr_debug("recovery pmsg failed\n");
+   ret = (int)rcnt < 0 ? (int)rcnt : -EIO;
+   goto free_oldbuf;
+   }
+
+   if (oldbuf->sig != zone->buffer->sig) {
+   pr_debug("no valid data in zone %s\n", zone->name);
+   goto free_oldbuf;
+   }
+
+   if (zone->buffer_size < atomic_read(>datalen) ||
+   zone->buffer_size < atomic_read(>start)) {
+   pr_info("found overtop zone: %s: off %lu, size %zu\n",
+   zone->name, zone->off, zone->buffer_size);
+   goto free_oldbuf;
+   }
+
+   if (!atomic_read(>datalen)) {
+   pr_debug("found erased zone: %s: id 0, off %lu, size %zu, 
datalen %d\n",
+   zone->name, zone->off, zone->buffer_size,
+   atomic_read(>datalen));
+   kfree(oldbuf);
+   goto out;
+   }
+
+   pr_debug("found nice zone: %s: id 0, off %lu, size %zu, datalen %d\n",
+   zone->name, zone->off, zone->buffer_size,
+   atomic_read(>datalen));
+   zone->oldbuf = oldbuf;
+out:
+   if (atomic_read(>dirty))
+   blkz_zone_write(zone, FLUSH_ALL, NULL, buffer_datalen(zone), 0);
+   return 0;
+
+free_oldbuf:
+   kfree(oldbuf);
+   return ret;
+}
+
 static inline int blkz_recovery(struct blkoops_context *cxt)
 {
int ret = -EBUSY;
@@ -408,6 +487,10 @@ static inline int blkz_recovery(struct blkoops_context 
*cxt)
if (ret)
goto recover_fail;
 
+   ret = blkz_recover_pmsg(cxt);
+   if (ret)
+   goto recover_fail;
+
atomic_set(>recovery, 1);
pr_debug("recover end!\n");
return 0;
@@ -425,11 +508,18 @@ static int blkoops_pstore_open(

[RFC v5 0/4] pstore/block: new support logger for block devices

2019-01-07 Thread liaoweixiong
Why should we need pstore_block?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fast, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

[PATCH v5]
On patch 1:
1. rename pstore/rom to pstore/blk
2. Do not allocate any memory in the write path of panic. So, use local
array instead in function romz_recover_dmesg_meta.
3. Add C header file "linux/fs.h" to fix implicit declaration of function
   'filp_open','kernel_read'...
On patch 3:
1. If panic, do not recover pmsg but flush if it is dirty.
2. Fix erase pmsg failed.
On patch 4:
1. Create a document for pstore/blk

[PATCH v4]
On patch 1:
1. Fix always true condition '(--i >= 0) => (0-u32max >= 0)' in function
   romz_init_zones by defining variable i to 'int' rahter than
   'unsigned int'.
2. To make codes more easily to read, we use macro READ_NEXT_ZONE for
   return value of romz_dmesg_read if it need to read next zone.
   Moveover, we assign READ_NEXT_ZONE -1024 rather than 0.
3. Add 'FLUSH_META' to 'enum romz_flush_mode' and rename 'NOT_FLUSH' to
   'FLUSH_NONE'
4. Function romz_zone_write work badly with FLUSH_PART mode as badly
   address and offset to write.
On patch 3:
NEW SUPPORT psmg for pstore_rom.

[PATCH v3]
On patch 1:
Fix build as module error for undefined 'vfs_read' and 'vfs_write'
Both of 'vfs_read' and 'vfs_write' haven't be exproted yet, so we use
'kernel_read' and 'kernel_write' instead.

[PATCH v2]
On patch 1:
Fix build as module error for redefinition of 'romz_unregister' and
'romz_register'

[PATCH v1]
On patch 1:
Core codes of pstore_rom, which works well on allwinner(sunxi) platform.
On patch 2:
A sample for pstore_rom, using general ram rather than block device.

liaoweixiong (4):
  pstore/blk: new support logger for block devices
  pstore/blk: add sample for pstore_blk
  pstore/blk: support pmsg for pstore block
  Documentation: pstore/blk: create document for pstore_blk

 Documentation/admin-guide/pstore-block.rst |  226 ++
 MAINTAINERS|1 +
 fs/pstore/Kconfig  |   20 +
 fs/pstore/Makefile |5 +
 fs/pstore/blkbuf.c |   46 ++
 fs/pstore/blkzone.c| 1168 
 include/linux/pstore_blk.h |   62 ++
 7 files changed, 1528 insertions(+)
 create mode 100644 Documentation/admin-guide/pstore-block.rst
 create mode 100644 fs/pstore/blkbuf.c
 create mode 100644 fs/pstore/blkzone.c
 create mode 100644 include/linux/pstore_blk.h

-- 
1.9.1



[RFC v4 0/3] pstore/rom: new support logger for block devices

2019-01-02 Thread liaoweixiong
Why should we need pstore_rom?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fast, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

[PATCH v4]
On patch 1:
1. Fix always true condition '(--i >= 0) => (0-u32max >= 0)' in function
   romz_init_zones by defining variable i to 'int' rahter than
   'unsigned int'.
2. To make codes more easily to read, we use macro READ_NEXT_ZONE for
   return value of romz_dmesg_read if it need to read next zone.
   Moveover, we assign READ_NEXT_ZONE -1024 rather than 0.
3. Add 'FLUSH_META' to 'enum romz_flush_mode' and rename 'NOT_FLUSH' to
   'FLUSH_NONE'
4. Function romz_zone_write work badly with FLUSH_PART mode as badly
   address and offset to write.
On patch 3:
NEW SUPPORT psmg for pstore_rom.

[PATCH v3]
On patch 1:
Fix build as module error for undefined 'vfs_read' and 'vfs_write'
Both of 'vfs_read' and 'vfs_write' haven't be exproted yet, so we use
'kernel_read' and 'kernel_write' instead.

[PATCH v2]
On patch 1:
Fix build as module error for redefinition of 'romz_unregister' and
'romz_register'

[PATCH v1]
On patch 1:
Core codes of pstore_rom, which works well on allwinner(sunxi) platform.
On patch 2:
A sample for pstore_rom, using general ram rather than block device.

liaoweixiong (3):
  pstore/rom: new support logger for block devices
  pstore/rom: add sample for pstore_rom
  pstore/rom: support pmsg for pstore_rom

 fs/pstore/Kconfig  |   16 +
 fs/pstore/Makefile |5 +
 fs/pstore/rombuf.c |   46 ++
 fs/pstore/romzone.c| 1138 
 include/linux/pstore_rom.h |   62 +++
 5 files changed, 1267 insertions(+)
 create mode 100644 fs/pstore/rombuf.c
 create mode 100644 fs/pstore/romzone.c
 create mode 100644 include/linux/pstore_rom.h

-- 
1.9.1



[RFC v4 3/3] pstore/rom: support pmsg for pstore_rom

2019-01-02 Thread liaoweixiong
To enable pmsg, just set pmsg_size when block device register romzone.
The pmsg have a single-boot lifetime, which means that zone of pmsg gets
wiped after its contents get copied out after boot.

Signed-off-by: liaoweixiong 
---
 fs/pstore/romzone.c| 194 +++--
 include/linux/pstore_rom.h |   1 +
 2 files changed, 187 insertions(+), 8 deletions(-)

diff --git a/fs/pstore/romzone.c b/fs/pstore/romzone.c
index 76a2648..d035694 100644
--- a/fs/pstore/romzone.c
+++ b/fs/pstore/romzone.c
@@ -31,12 +31,14 @@
  *
  * @sig: signature to indicate header (ROM_SIG xor ROMZONE-type value)
  * @datalen: length of data in @data
+ * @start: offset into @data where the beginning of the stored bytes begin
  * @data: zone data.
  */
 struct romz_buffer {
 #define ROM_SIG (0x43474244) /* DBGC */
uint32_t sig;
atomic_t datalen;
+   atomic_t start;
uint8_t data[0];
 };
 
@@ -69,6 +71,10 @@ struct romz_dmesg_header {
  * frontent name for this zone
  * @buffer:
  * pointer to data buffer managed by this zone
+ * @oldbuf:
+ * pointer to old data buffer. It is used for zone who have a single-boot
+ * lifetime, which means that this zone gets wiped after its contents get
+ * copied out after boot.
  * @buffer_size:
  * bytes in @buffer->data
  * @should_recover:
@@ -82,6 +88,7 @@ struct romz_zone {
enum pstore_type_id type;
 
struct romz_buffer *buffer;
+   struct romz_buffer *oldbuf;
size_t buffer_size;
bool should_recover;
atomic_t dirty;
@@ -89,8 +96,10 @@ struct romz_zone {
 
 struct romoops_context {
struct romz_zone **drzs;/* Oops dump zones */
+   struct romz_zone *prz;  /* Pmsg dump zones */
unsigned int dmesg_max_cnt;
unsigned int dmesg_read_cnt;
+   unsigned int pmsg_read_cnt;
unsigned int dmesg_write_cnt;
/**
 * the counter should be recovered when do recovery
@@ -124,6 +133,11 @@ static inline int buffer_datalen(struct romz_zone *zone)
return atomic_read(>buffer->datalen);
 }
 
+static inline int buffer_start(struct romz_zone *zone)
+{
+   return atomic_read(>buffer->start);
+}
+
 static inline bool is_on_panic(void)
 {
struct romoops_context *cxt = _cxt;
@@ -398,6 +412,65 @@ static int romz_recover_dmesg(struct romoops_context *cxt)
return ret;
 }
 
+static int romz_recover_pmsg(struct romoops_context *cxt)
+{
+   struct romz_info *info = cxt->rzinfo;
+   struct romz_buffer *oldbuf;
+   struct romz_zone *zone = NULL;
+   ssize_t (*readop)(char *buf, size_t bytes, loff_t pos);
+   int ret = 0;
+   ssize_t rcnt, len;
+
+   zone = cxt->prz;
+   if (!zone)
+   return -EINVAL;
+
+   if (zone->oldbuf)
+   return 0;
+
+   readop = info->read;
+   if (is_on_panic())
+   readop = info->panic_read;
+   if (!readop)
+   return -EINVAL;
+
+   len = zone->buffer_size + sizeof(*oldbuf);
+   oldbuf = kzalloc(len, GFP_KERNEL);
+   if (!oldbuf)
+   return -ENOMEM;
+
+   rcnt = readop((char *)oldbuf, len, zone->off);
+   if (rcnt != len) {
+   pr_debug("recovery pmsg failed\n");
+   ret = -EIO;
+   goto free_oldbuf;
+   }
+
+   if (oldbuf->sig != zone->buffer->sig) {
+   pr_debug("no valid data in zone %s\n", zone->name);
+   goto free_oldbuf;
+   }
+
+   if (zone->buffer_size < atomic_read(>datalen) ||
+   zone->buffer_size < atomic_read(>start)) {
+   pr_info("found overtop zone: %s: off %lu, size %zu\n",
+   zone->name, zone->off, zone->buffer_size);
+   goto free_oldbuf;
+   }
+
+   if (atomic_read(>dirty))
+   romz_zone_write(zone, FLUSH_ALL, NULL, buffer_datalen(zone), 0);
+   else
+   romz_zone_write(zone, FLUSH_META, NULL, 0, 0);
+
+   zone->oldbuf = oldbuf;
+   return 0;
+
+free_oldbuf:
+   kfree(oldbuf);
+   return ret;
+}
+
 static inline int romz_recovery(struct romoops_context *cxt)
 {
int ret = -EBUSY;
@@ -412,6 +485,10 @@ static inline int romz_recovery(struct romoops_context 
*cxt)
if (ret)
goto recover_fail;
 
+   ret = romz_recover_pmsg(cxt);
+   if (ret)
+   goto recover_fail;
+
atomic_set(>recovery, 1);
pr_debug("recover end!\n");
return 0;
@@ -520,6 +597,55 @@ static int notrace romz_dmesg_write(struct romoops_context 
*cxt,
return 0;
 }
 
+static int notrace romz_pmsg_write(struct romoops_context *cxt,
+   struct pstore_record *record)
+{
+   struct romz_zone *zone;
+   size_t start, rem;
+   int cnt = record->size;
+   b

[RFC v4 2/3] pstore/rom: add sample for pstore_rom

2019-01-02 Thread liaoweixiong
It is a sample for pstore_rom, using general ram rather than block device.
According to pstore_rom, the data will be saved to ram buffer if not
register device path and apis for panic. So, it can only used to dump
Oops and some things will not reboot.

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig  |  9 +
 fs/pstore/Makefile |  2 ++
 fs/pstore/rombuf.c | 46 ++
 3 files changed, 57 insertions(+)
 create mode 100644 fs/pstore/rombuf.c

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index abf0453..426b5ea 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -159,3 +159,12 @@ config PSTORE_ROM
help
  This enables panic and oops message to be logged to a block dev
  where it can be read back at some later point.
+
+config PSTORE_ROMBUF
+   tristate "romoop buffer sample"
+   depends on PSTORE_ROM
+   help
+ This is a sample for pstore rom, but do NOT have a block dev.
+ According to pstore_rom, the data will be saved to ram buffer and
+ dropped when reboot. So, it can only used to dump Oops and some
+ things will not reboot.
diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
index ea38d6e..21c1226 100644
--- a/fs/pstore/Makefile
+++ b/fs/pstore/Makefile
@@ -15,3 +15,5 @@ obj-$(CONFIG_PSTORE_RAM)  += ramoops.o
 
 obj-$(CONFIG_PSTORE_ROM)   += romoops.o
 romoops-y += romzone.o
+
+obj-$(CONFIG_PSTORE_ROMBUF)+= rombuf.o
diff --git a/fs/pstore/rombuf.c b/fs/pstore/rombuf.c
new file mode 100644
index 000..bb21a85
--- /dev/null
+++ b/fs/pstore/rombuf.c
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *
+ * rombuf.c: ROM Oops/Panic logger
+ *
+ * Copyright (C) 2019 liaoweixiong 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#define pr_fmt(fmt) "rombuf: " fmt
+
+#include 
+#include 
+#include 
+
+struct romz_info rombuf_info = {
+   .owner = THIS_MODULE,
+   .name = "rombuf",
+   .part_size = 512 * 1024,
+   .dmesg_size = 64 * 1024,
+   .dump_oops = true,
+};
+
+static int __init rombuf_init(void)
+{
+   return romz_register(_info);
+}
+module_init(rombuf_init);
+
+static void __exit rombuf_exit(void)
+{
+   romz_unregister(_info);
+}
+module_exit(rombuf_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("liaoweixiong ");
+MODULE_DESCRIPTION("Sample for Pstore ROM with Oops logger");
-- 
1.9.1



[RFC v4 1/3] pstore/rom: new support logger for block devices

2019-01-02 Thread liaoweixiong
pstore_rom is similar to pstore_ram, but dump log to block devices
rather than persistent ram.

Why should we need pstore_rom?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fast, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

pstore_rom can only dump Oops/Panic log to block devices. It only
supports dmesg now. To make pstore_rom work, the block driver should
provide the path of a block partition device (/dev/) and the
read/write apis when on panic.

pstore_rom begins at 'romz_register', by witch block device can register
a block partition to pstore_rom. Then pstore_rom divide and manage the
partition as zones, which is similar to pstore_ram.

Recommend that, block driver register pstore_rom after block device is
ready.

pstore_rom works well on allwinner(sunxi) platform.

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig  |   7 +
 fs/pstore/Makefile |   3 +
 fs/pstore/romzone.c| 961 +
 include/linux/pstore_rom.h |  61 +++
 4 files changed, 1032 insertions(+)
 create mode 100644 fs/pstore/romzone.c
 create mode 100644 include/linux/pstore_rom.h

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index 8b3ba27..abf0453 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -152,3 +152,10 @@ config PSTORE_RAM
  "ramoops.ko".
 
  For more information, see Documentation/admin-guide/ramoops.rst.
+
+config PSTORE_ROM
+   tristate "Log panic/oops to a block device"
+   depends on PSTORE
+   help
+ This enables panic and oops message to be logged to a block dev
+ where it can be read back at some later point.
diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
index 967b589..ea38d6e 100644
--- a/fs/pstore/Makefile
+++ b/fs/pstore/Makefile
@@ -12,3 +12,6 @@ pstore-$(CONFIG_PSTORE_PMSG)  += pmsg.o
 
 ramoops-objs += ram.o ram_core.o
 obj-$(CONFIG_PSTORE_RAM)   += ramoops.o
+
+obj-$(CONFIG_PSTORE_ROM)   += romoops.o
+romoops-y += romzone.o
diff --git a/fs/pstore/romzone.c b/fs/pstore/romzone.c
new file mode 100644
index 000..76a2648
--- /dev/null
+++ b/fs/pstore/romzone.c
@@ -0,0 +1,961 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *
+ * romzone.c: ROM Oops/Panic logger
+ *
+ * Copyright (C) 2019 liaoweixiong 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define pr_fmt(fmt) "romzone: " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * struct romz_head - head of zone to flush to storage
+ *
+ * @sig: signature to indicate header (ROM_SIG xor ROMZONE-type value)
+ * @datalen: length of data in @data
+ * @data: zone data.
+ */
+struct romz_buffer {
+#define ROM_SIG (0x43474244) /* DBGC */
+   uint32_t sig;
+   atomic_t datalen;
+   uint8_t data[0];
+};
+
+/**
+ * sruct romz_dmesg_header: dmesg information
+ *
+ * @magic: magic num for dmesg header
+ * @time: trigger time
+ * @compressed: whether conpressed
+ * @count: oops/panic counter
+ * @reason: identify oops or panic
+ */
+struct romz_dmesg_header {
+#define DMESG_HEADER_MAGIC 0x4dfc3ae5
+   uint32_t magic;
+   struct timespec64 time;
+   bool compressed;
+   uint32_t counter;
+   enum kmsg_dump_reason reason;
+   uint8_t data[0];
+};
+
+/**
+ * struct romz_zone - zone information
+ * @off:
+ * zone offset of partition
+ * @type:
+ * frontent type for this zone
+ * @name:
+ * frontent name for this zone
+ * @buffer:
+ * pointer to data buffer managed by this zone
+ * @buffer_size:
+ * bytes in @buffer->data
+ * @should_recover:
+ * should recover from storage
+ * @dirty:
+ * mark whether the data in @buffer are dirty (not flush to storage yet)
+ */
+struct romz_zone {
+   unsigned long off;
+   const char *name;
+   enum pstore_type_id type;
+
+   struct romz_buffer *buffer;
+   size_t buffer_size;
+   bool should_recover;
+   atomic_t dirty;
+};
+
+struct romoops_context {
+   struct romz_zone **drzs;/* Oops dump zones */
+   unsigned int dmesg_max_cnt;
+   unsigned int dmesg_read_cnt;
+   unsigned int dmesg_write_cnt;
+   /**
+* the counter should be recovered when do recovery
+* It records the oops/panic times 

[RFC v3 2/2] pstore/rom: add sample for pstore_rom

2019-01-01 Thread liaoweixiong
It is a sample for pstore_rom, using general ram rather than block device.
According to pstore_rom, the data will be saved to ram buffer if not
register device path and apis for panic. So, it can only used to dump
Oops and some things will not reboot.

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig  |  9 +
 fs/pstore/Makefile |  2 ++
 fs/pstore/rombuf.c | 46 ++
 3 files changed, 57 insertions(+)
 create mode 100644 fs/pstore/rombuf.c

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index abf0453..426b5ea 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -159,3 +159,12 @@ config PSTORE_ROM
help
  This enables panic and oops message to be logged to a block dev
  where it can be read back at some later point.
+
+config PSTORE_ROMBUF
+   tristate "romoop buffer sample"
+   depends on PSTORE_ROM
+   help
+ This is a sample for pstore rom, but do NOT have a block dev.
+ According to pstore_rom, the data will be saved to ram buffer and
+ dropped when reboot. So, it can only used to dump Oops and some
+ things will not reboot.
diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
index ea38d6e..21c1226 100644
--- a/fs/pstore/Makefile
+++ b/fs/pstore/Makefile
@@ -15,3 +15,5 @@ obj-$(CONFIG_PSTORE_RAM)  += ramoops.o
 
 obj-$(CONFIG_PSTORE_ROM)   += romoops.o
 romoops-y += romzone.o
+
+obj-$(CONFIG_PSTORE_ROMBUF)+= rombuf.o
diff --git a/fs/pstore/rombuf.c b/fs/pstore/rombuf.c
new file mode 100644
index 000..bb21a85
--- /dev/null
+++ b/fs/pstore/rombuf.c
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *
+ * rombuf.c: ROM Oops/Panic logger
+ *
+ * Copyright (C) 2019 liaoweixiong 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#define pr_fmt(fmt) "rombuf: " fmt
+
+#include 
+#include 
+#include 
+
+struct romz_info rombuf_info = {
+   .owner = THIS_MODULE,
+   .name = "rombuf",
+   .part_size = 512 * 1024,
+   .dmesg_size = 64 * 1024,
+   .dump_oops = true,
+};
+
+static int __init rombuf_init(void)
+{
+   return romz_register(_info);
+}
+module_init(rombuf_init);
+
+static void __exit rombuf_exit(void)
+{
+   romz_unregister(_info);
+}
+module_exit(rombuf_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("liaoweixiong ");
+MODULE_DESCRIPTION("Sample for Pstore ROM with Oops logger");
-- 
1.9.1



[RFC v3 1/2] pstore/rom: new support logger for block devices

2019-01-01 Thread liaoweixiong
pstore_rom is similar to pstore_ram, but dump log to block devices
rather than persistent ram.

Why should we need pstore_rom?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fast, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

pstore_rom can only dump Oops/Panic log to block devices. It only
supports dmesg now. To make pstore_rom work, the block driver should
provide the path of a block partition device (/dev/) and the
read/write apis when on panic.

pstore_rom begins at 'romz_register', by witch block device can register
a block partition to pstore_rom. Then pstore_rom divide and manage the
partition as zones, which is similar to pstore_ram.

Recommend that, block driver register pstore_rom after block device is
ready.

pstore_rom works well on allwinner(sunxi) platform.

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig  |   7 +
 fs/pstore/Makefile |   3 +
 fs/pstore/romzone.c| 957 +
 include/linux/pstore_rom.h |  61 +++
 4 files changed, 1028 insertions(+)
 create mode 100644 fs/pstore/romzone.c
 create mode 100644 include/linux/pstore_rom.h

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index 8b3ba27..abf0453 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -152,3 +152,10 @@ config PSTORE_RAM
  "ramoops.ko".
 
  For more information, see Documentation/admin-guide/ramoops.rst.
+
+config PSTORE_ROM
+   tristate "Log panic/oops to a block device"
+   depends on PSTORE
+   help
+ This enables panic and oops message to be logged to a block dev
+ where it can be read back at some later point.
diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
index 967b589..ea38d6e 100644
--- a/fs/pstore/Makefile
+++ b/fs/pstore/Makefile
@@ -12,3 +12,6 @@ pstore-$(CONFIG_PSTORE_PMSG)  += pmsg.o
 
 ramoops-objs += ram.o ram_core.o
 obj-$(CONFIG_PSTORE_RAM)   += ramoops.o
+
+obj-$(CONFIG_PSTORE_ROM)   += romoops.o
+romoops-y += romzone.o
diff --git a/fs/pstore/romzone.c b/fs/pstore/romzone.c
new file mode 100644
index 000..afebfbc
--- /dev/null
+++ b/fs/pstore/romzone.c
@@ -0,0 +1,957 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *
+ * romzone.c: ROM Oops/Panic logger
+ *
+ * Copyright (C) 2019 liaoweixiong 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define pr_fmt(fmt) "romzone: " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * struct romz_head - head of zone to flush to storage
+ *
+ * @sig: signature to indicate header (ROM_SIG xor ROMZONE-type value)
+ * @datalen: length of data in @data
+ * @data: zone data.
+ */
+struct romz_buffer {
+#define ROM_SIG (0x43474244) /* DBGC */
+   uint32_t sig;
+   atomic_t datalen;
+   uint8_t data[0];
+};
+
+/**
+ * sruct romz_dmesg_header: dmesg information
+ *
+ * @magic: magic num for dmesg header
+ * @time: trigger time
+ * @compressed: whether conpressed
+ * @count: oops/panic counter
+ * @reason: identify oops or panic
+ */
+struct romz_dmesg_header {
+#define DMESG_HEADER_MAGIC 0x4dfc3ae5
+   uint32_t magic;
+   struct timespec64 time;
+   bool compressed;
+   uint32_t counter;
+   enum kmsg_dump_reason reason;
+   uint8_t data[0];
+};
+
+/**
+ * struct romz_zone - zone information
+ * @off:
+ * zone offset of partition
+ * @type:
+ * frontent type for this zone
+ * @name:
+ * frontent name for this zone
+ * @buffer:
+ * pointer to data buffer managed by this zone
+ * @buffer_size:
+ * bytes in @buffer->data
+ * @should_recover:
+ * should recover from storage
+ * @dirty:
+ * mark whether the data in @buffer are dirty (not flush to storage yet)
+ */
+struct romz_zone {
+   unsigned long off;
+   const char *name;
+   enum pstore_type_id type;
+
+   struct romz_buffer *buffer;
+   size_t buffer_size;
+   bool should_recover;
+   atomic_t dirty;
+};
+
+struct romoops_context {
+   struct romz_zone **drzs;/* Oops dump zones */
+   unsigned int dmesg_max_cnt;
+   unsigned int dmesg_read_cnt;
+   unsigned int dmesg_write_cnt;
+   /**
+* the counter should be recovered when do recovery
+* It records the oops/panic times 

[RFC v3 0/2] pstore/rom: new support logger for block devices

2019-01-01 Thread liaoweixiong
Why should we need pstore_rom?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fast, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

[PATCH v1]
On patch 1:
Core codes of pstore_rom, which works well on allwinner(sunxi) platform.
On patch 2:
A sample for pstore_rom, using general ram rather than block device.

[PATCH v2]
On patch 1:
Fix build as module error for redefinition of 'romz_unregister' and 
'romz_register'

[PATCH v3]
On patch 1:
Fix build as module error for undefined 'vfs_read' and 'vfs_write'
Both of 'vfs_read' and 'vfs_write' haven't be exproted yet, so we use 
'kernel_read'
and 'kernel_write' instead.

liaoweixiong (2):
  pstore/rom: new support logger for block devices
  pstore/rom: add sample for pstore_rom

 fs/pstore/Kconfig  |  16 +
 fs/pstore/Makefile |   5 +
 fs/pstore/rombuf.c |  46 +++
 fs/pstore/romzone.c| 957 +
 include/linux/pstore_rom.h |  61 +++
 5 files changed, 1085 insertions(+)
 create mode 100644 fs/pstore/rombuf.c
 create mode 100644 fs/pstore/romzone.c
 create mode 100644 include/linux/pstore_rom.h

-- 
1.9.1



[RFC v2 2/2] pstore/rom: add sample for pstore_rom

2019-01-01 Thread liaoweixiong
It is a sample for pstore_rom, using general ram rather than block device.
According to pstore_rom, the data will be saved to ram buffer if not
register device path and apis for panic. So, it can only used to dump
Oops and some things will not reboot.

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig  |  9 +
 fs/pstore/Makefile |  2 ++
 fs/pstore/rombuf.c | 46 ++
 3 files changed, 57 insertions(+)
 create mode 100644 fs/pstore/rombuf.c

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index abf0453..426b5ea 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -159,3 +159,12 @@ config PSTORE_ROM
help
  This enables panic and oops message to be logged to a block dev
  where it can be read back at some later point.
+
+config PSTORE_ROMBUF
+   tristate "romoop buffer sample"
+   depends on PSTORE_ROM
+   help
+ This is a sample for pstore rom, but do NOT have a block dev.
+ According to pstore_rom, the data will be saved to ram buffer and
+ dropped when reboot. So, it can only used to dump Oops and some
+ things will not reboot.
diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
index ea38d6e..21c1226 100644
--- a/fs/pstore/Makefile
+++ b/fs/pstore/Makefile
@@ -15,3 +15,5 @@ obj-$(CONFIG_PSTORE_RAM)  += ramoops.o
 
 obj-$(CONFIG_PSTORE_ROM)   += romoops.o
 romoops-y += romzone.o
+
+obj-$(CONFIG_PSTORE_ROMBUF)+= rombuf.o
diff --git a/fs/pstore/rombuf.c b/fs/pstore/rombuf.c
new file mode 100644
index 000..bb21a85
--- /dev/null
+++ b/fs/pstore/rombuf.c
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *
+ * rombuf.c: ROM Oops/Panic logger
+ *
+ * Copyright (C) 2019 liaoweixiong 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#define pr_fmt(fmt) "rombuf: " fmt
+
+#include 
+#include 
+#include 
+
+struct romz_info rombuf_info = {
+   .owner = THIS_MODULE,
+   .name = "rombuf",
+   .part_size = 512 * 1024,
+   .dmesg_size = 64 * 1024,
+   .dump_oops = true,
+};
+
+static int __init rombuf_init(void)
+{
+   return romz_register(_info);
+}
+module_init(rombuf_init);
+
+static void __exit rombuf_exit(void)
+{
+   romz_unregister(_info);
+}
+module_exit(rombuf_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("liaoweixiong ");
+MODULE_DESCRIPTION("Sample for Pstore ROM with Oops logger");
-- 
1.9.1



[RFC v2 0/2] pstore/rom: new support logger for block devices

2019-01-01 Thread liaoweixiong
Why should we need pstore_rom?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fast, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

[PATCH v1]
On patch 1:
Core codes of pstore_rom, which works well on allwinner(sunxi) platform.
On patch 2:
A sample for pstore_rom, using general ram rather than block device.

[PATCH v2]
On patch 1:
Fix build as module error for redefinition of 'romz_unregister' and 
'romz_register'

liaoweixiong (2):
  pstore/rom: new support logger for block devices
  pstore/rom: add sample for pstore_rom

 fs/pstore/Kconfig  |  16 +
 fs/pstore/Makefile |   5 +
 fs/pstore/rombuf.c |  46 +++
 fs/pstore/romzone.c| 965 +
 include/linux/pstore_rom.h |  61 +++
 5 files changed, 1093 insertions(+)
 create mode 100644 fs/pstore/rombuf.c
 create mode 100644 fs/pstore/romzone.c
 create mode 100644 include/linux/pstore_rom.h

-- 
1.9.1



[RFC v2 1/2] pstore/rom: new support logger for block devices

2019-01-01 Thread liaoweixiong
pstore_rom is similar to pstore_ram, but dump log to block devices
rather than persistent ram.

Why should we need pstore_rom?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fast, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

pstore_rom can only dump Oops/Panic log to block devices. It only
supports dmesg now. To make pstore_rom work, the block driver should
provide the path of a block partition device (/dev/) and the
read/write apis when on panic.

pstore_rom begins at 'romz_register', by witch block device can register
a block partition to pstore_rom. Then pstore_rom divide and manage the
partition as zones, which is similar to pstore_ram.

Recommend that, block driver register pstore_rom after block device is
ready.

pstore_rom works well on allwinner(sunxi) platform.

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig  |   7 +
 fs/pstore/Makefile |   3 +
 fs/pstore/romzone.c| 965 +
 include/linux/pstore_rom.h |  61 +++
 4 files changed, 1036 insertions(+)
 create mode 100644 fs/pstore/romzone.c
 create mode 100644 include/linux/pstore_rom.h

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index 8b3ba27..abf0453 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -152,3 +152,10 @@ config PSTORE_RAM
  "ramoops.ko".
 
  For more information, see Documentation/admin-guide/ramoops.rst.
+
+config PSTORE_ROM
+   tristate "Log panic/oops to a block device"
+   depends on PSTORE
+   help
+ This enables panic and oops message to be logged to a block dev
+ where it can be read back at some later point.
diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
index 967b589..ea38d6e 100644
--- a/fs/pstore/Makefile
+++ b/fs/pstore/Makefile
@@ -12,3 +12,6 @@ pstore-$(CONFIG_PSTORE_PMSG)  += pmsg.o
 
 ramoops-objs += ram.o ram_core.o
 obj-$(CONFIG_PSTORE_RAM)   += ramoops.o
+
+obj-$(CONFIG_PSTORE_ROM)   += romoops.o
+romoops-y += romzone.o
diff --git a/fs/pstore/romzone.c b/fs/pstore/romzone.c
new file mode 100644
index 000..405fbb1
--- /dev/null
+++ b/fs/pstore/romzone.c
@@ -0,0 +1,965 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *
+ * romzone.c: ROM Oops/Panic logger
+ *
+ * Copyright (C) 2019 liaoweixiong 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define pr_fmt(fmt) "romzone: " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * struct romz_head - head of zone to flush to storage
+ *
+ * @sig: signature to indicate header (ROM_SIG xor ROMZONE-type value)
+ * @datalen: length of data in @data
+ * @data: zone data.
+ */
+struct romz_buffer {
+#define ROM_SIG (0x43474244) /* DBGC */
+   uint32_t sig;
+   atomic_t datalen;
+   uint8_t data[0];
+};
+
+/**
+ * sruct romz_dmesg_header: dmesg information
+ *
+ * @magic: magic num for dmesg header
+ * @time: trigger time
+ * @compressed: whether conpressed
+ * @count: oops/panic counter
+ * @reason: identify oops or panic
+ */
+struct romz_dmesg_header {
+#define DMESG_HEADER_MAGIC 0x4dfc3ae5
+   uint32_t magic;
+   struct timespec64 time;
+   bool compressed;
+   uint32_t counter;
+   enum kmsg_dump_reason reason;
+   uint8_t data[0];
+};
+
+/**
+ * struct romz_zone - zone information
+ * @off:
+ * zone offset of partition
+ * @type:
+ * frontent type for this zone
+ * @name:
+ * frontent name for this zone
+ * @buffer:
+ * pointer to data buffer managed by this zone
+ * @buffer_size:
+ * bytes in @buffer->data
+ * @should_recover:
+ * should recover from storage
+ * @dirty:
+ * mark whether the data in @buffer are dirty (not flush to storage yet)
+ */
+struct romz_zone {
+   unsigned long off;
+   const char *name;
+   enum pstore_type_id type;
+
+   struct romz_buffer *buffer;
+   size_t buffer_size;
+   bool should_recover;
+   atomic_t dirty;
+};
+
+struct romoops_context {
+   struct romz_zone **drzs;/* Oops dump zones */
+   unsigned int dmesg_max_cnt;
+   unsigned int dmesg_read_cnt;
+   unsigned int dmesg_write_cnt;
+   /**
+* the counter should be recovered when do recovery
+* It records the oops/panic times 

[RFC 1/2] pstore/rom: new support logger for block devices

2019-01-01 Thread liaoweixiong
pstore_rom is similar to pstore_ram, but dump log to block devices
rather than persistent ram.

Why should we need pstore_rom?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fast, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

pstore_rom can only dump Oops/Panic log to block devices. It only
supports dmesg now. To make pstore_rom work, the block driver should
provide the path of a block partition device (/dev/) and the
read/write apis when on panic.

pstore_rom begins at 'romz_register', by witch block device can register
a block partition to pstore_rom. Then pstore_rom divide and manage the
partition as zones, which is similar to pstore_ram.

Recommend that, block driver register pstore_rom after block device is
ready.

pstore_rom works well on allwinner(sunxi) platform.

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig  |   7 +
 fs/pstore/Makefile |   3 +
 fs/pstore/romzone.c| 965 +
 include/linux/pstore_rom.h |  68 
 4 files changed, 1043 insertions(+)
 create mode 100644 fs/pstore/romzone.c
 create mode 100644 include/linux/pstore_rom.h

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index 8b3ba27..abf0453 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -152,3 +152,10 @@ config PSTORE_RAM
  "ramoops.ko".
 
  For more information, see Documentation/admin-guide/ramoops.rst.
+
+config PSTORE_ROM
+   tristate "Log panic/oops to a block device"
+   depends on PSTORE
+   help
+ This enables panic and oops message to be logged to a block dev
+ where it can be read back at some later point.
diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
index 967b589..ea38d6e 100644
--- a/fs/pstore/Makefile
+++ b/fs/pstore/Makefile
@@ -12,3 +12,6 @@ pstore-$(CONFIG_PSTORE_PMSG)  += pmsg.o
 
 ramoops-objs += ram.o ram_core.o
 obj-$(CONFIG_PSTORE_RAM)   += ramoops.o
+
+obj-$(CONFIG_PSTORE_ROM)   += romoops.o
+romoops-y += romzone.o
diff --git a/fs/pstore/romzone.c b/fs/pstore/romzone.c
new file mode 100644
index 000..405fbb1
--- /dev/null
+++ b/fs/pstore/romzone.c
@@ -0,0 +1,965 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *
+ * romzone.c: ROM Oops/Panic logger
+ *
+ * Copyright (C) 2019 liaoweixiong 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define pr_fmt(fmt) "romzone: " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * struct romz_head - head of zone to flush to storage
+ *
+ * @sig: signature to indicate header (ROM_SIG xor ROMZONE-type value)
+ * @datalen: length of data in @data
+ * @data: zone data.
+ */
+struct romz_buffer {
+#define ROM_SIG (0x43474244) /* DBGC */
+   uint32_t sig;
+   atomic_t datalen;
+   uint8_t data[0];
+};
+
+/**
+ * sruct romz_dmesg_header: dmesg information
+ *
+ * @magic: magic num for dmesg header
+ * @time: trigger time
+ * @compressed: whether conpressed
+ * @count: oops/panic counter
+ * @reason: identify oops or panic
+ */
+struct romz_dmesg_header {
+#define DMESG_HEADER_MAGIC 0x4dfc3ae5
+   uint32_t magic;
+   struct timespec64 time;
+   bool compressed;
+   uint32_t counter;
+   enum kmsg_dump_reason reason;
+   uint8_t data[0];
+};
+
+/**
+ * struct romz_zone - zone information
+ * @off:
+ * zone offset of partition
+ * @type:
+ * frontent type for this zone
+ * @name:
+ * frontent name for this zone
+ * @buffer:
+ * pointer to data buffer managed by this zone
+ * @buffer_size:
+ * bytes in @buffer->data
+ * @should_recover:
+ * should recover from storage
+ * @dirty:
+ * mark whether the data in @buffer are dirty (not flush to storage yet)
+ */
+struct romz_zone {
+   unsigned long off;
+   const char *name;
+   enum pstore_type_id type;
+
+   struct romz_buffer *buffer;
+   size_t buffer_size;
+   bool should_recover;
+   atomic_t dirty;
+};
+
+struct romoops_context {
+   struct romz_zone **drzs;/* Oops dump zones */
+   unsigned int dmesg_max_cnt;
+   unsigned int dmesg_read_cnt;
+   unsigned int dmesg_write_cnt;
+   /**
+* the counter should be recovered when do recovery
+* It records the oops/panic times 

[RFC 0/2] pstore/rom: new support logger for block devices

2019-01-01 Thread liaoweixiong
pstore_rom is similar to pstore_ram, but dump log to block devices
rather than persistent ram.

Why should we need pstore_rom?
1. Most embedded intelligent equipment have no persistent ram, which
increases costs. We perfer to cheaper solutions, like block devices.
In fast, there is already a sample for block device logger in driver
MTD (drivers/mtd/mtdoops.c).
2. Do not any equipment have battery, which means that it lost all data
on general ram if power failure. Pstore has little to do for these
equipments.

On patch 1:
Core codes of pstore_rom, which works well on allwinner(sunxi) platform.
On patch 2:
A sample for pstore_rom, using general ram rather than block device.

liaoweixiong (2):
  pstore/rom: new support logger for block devices
  pstore/rom: add sample for pstore_rom

 fs/pstore/Kconfig  |  16 +
 fs/pstore/Makefile |   5 +
 fs/pstore/rombuf.c |  46 +++
 fs/pstore/romzone.c| 965 +
 include/linux/pstore_rom.h |  68 
 5 files changed, 1100 insertions(+)
 create mode 100644 fs/pstore/rombuf.c
 create mode 100644 fs/pstore/romzone.c
 create mode 100644 include/linux/pstore_rom.h

-- 
1.9.1



[RFC 2/2] pstore/rom: add sample for pstore_rom

2019-01-01 Thread liaoweixiong
It is a sample for pstore_rom, using general ram rather than block device.
According to pstore_rom, the data will be saved to ram buffer if not
register device path and apis for panic. So, it can only used to dump
Oops and some things will not reboot.

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig  |  9 +
 fs/pstore/Makefile |  2 ++
 fs/pstore/rombuf.c | 46 ++
 3 files changed, 57 insertions(+)
 create mode 100644 fs/pstore/rombuf.c

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index abf0453..426b5ea 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -159,3 +159,12 @@ config PSTORE_ROM
help
  This enables panic and oops message to be logged to a block dev
  where it can be read back at some later point.
+
+config PSTORE_ROMBUF
+   tristate "romoop buffer sample"
+   depends on PSTORE_ROM
+   help
+ This is a sample for pstore rom, but do NOT have a block dev.
+ According to pstore_rom, the data will be saved to ram buffer and
+ dropped when reboot. So, it can only used to dump Oops and some
+ things will not reboot.
diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
index ea38d6e..21c1226 100644
--- a/fs/pstore/Makefile
+++ b/fs/pstore/Makefile
@@ -15,3 +15,5 @@ obj-$(CONFIG_PSTORE_RAM)  += ramoops.o
 
 obj-$(CONFIG_PSTORE_ROM)   += romoops.o
 romoops-y += romzone.o
+
+obj-$(CONFIG_PSTORE_ROMBUF)+= rombuf.o
diff --git a/fs/pstore/rombuf.c b/fs/pstore/rombuf.c
new file mode 100644
index 000..bb21a85
--- /dev/null
+++ b/fs/pstore/rombuf.c
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *
+ * rombuf.c: ROM Oops/Panic logger
+ *
+ * Copyright (C) 2019 liaoweixiong 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#define pr_fmt(fmt) "rombuf: " fmt
+
+#include 
+#include 
+#include 
+
+struct romz_info rombuf_info = {
+   .owner = THIS_MODULE,
+   .name = "rombuf",
+   .part_size = 512 * 1024,
+   .dmesg_size = 64 * 1024,
+   .dump_oops = true,
+};
+
+static int __init rombuf_init(void)
+{
+   return romz_register(_info);
+}
+module_init(rombuf_init);
+
+static void __exit rombuf_exit(void)
+{
+   romz_unregister(_info);
+}
+module_exit(rombuf_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("liaoweixiong ");
+MODULE_DESCRIPTION("Sample for Pstore ROM with Oops logger");
-- 
1.9.1



[PATCH v2] pstore: turn compression options back to 'bool'

2018-12-14 Thread liaoweixiong
On commit 58eb5b670747 ("pstore: fix crypto dependencies"),
dependency bug was fixed by selecting the crypto core rather than
turned compression sub-options to 'tristate'.
In addition, these options are used to enable/disable compression. They
are not modules, and mean nothing when set to 'M'.
So, this patch is going to turn them back to 'bool'.

Fixes: 58eb5b670747 ("pstore: fix crypto dependencies")
Acked-by: Kees Cook 
Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index 0d19d19..8b3ba27 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -14,7 +14,7 @@ config PSTORE
   say N.
 
 config PSTORE_DEFLATE_COMPRESS
-   tristate "DEFLATE (ZLIB) compression"
+   bool "DEFLATE (ZLIB) compression"
default y
depends on PSTORE
select CRYPTO_DEFLATE
@@ -23,21 +23,21 @@ config PSTORE_DEFLATE_COMPRESS
  algorithm support.
 
 config PSTORE_LZO_COMPRESS
-   tristate "LZO compression"
+   bool "LZO compression"
depends on PSTORE
select CRYPTO_LZO
help
  This option enables LZO compression algorithm support.
 
 config PSTORE_LZ4_COMPRESS
-   tristate "LZ4 compression"
+   bool "LZ4 compression"
depends on PSTORE
select CRYPTO_LZ4
help
  This option enables LZ4 compression algorithm support.
 
 config PSTORE_LZ4HC_COMPRESS
-   tristate "LZ4HC compression"
+   bool "LZ4HC compression"
depends on PSTORE
select CRYPTO_LZ4HC
help
-- 
1.9.1



[PATCH] pstore: fix crypto dependencies of 842/zstd compression

2018-12-12 Thread liaoweixiong
Reference to commit 58eb5b670747 ("pstore: fix crypto dependencies"),
which fixed crypto dependencies of deflate, lzo, lz4 and lz4hc
compression, but omitted 842 and newer compression zstd from
commit 1021bcf44d0e ("pstore: add zstd compression support")

Signed-off-by: liaoweixiong 
---
 fs/pstore/Kconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index 0d19d19..7068f45 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -44,14 +44,14 @@ config PSTORE_LZ4HC_COMPRESS
  This option enables LZ4HC (high compression) mode algorithm.
 
 config PSTORE_842_COMPRESS
-   bool "842 compression"
+   tristate "842 compression"
depends on PSTORE
select CRYPTO_842
help
  This option enables 842 compression algorithm support.
 
 config PSTORE_ZSTD_COMPRESS
-   bool "zstd compression"
+   tristate "zstd compression"
depends on PSTORE
select CRYPTO_ZSTD
help
-- 
1.9.1