2013-08-16 13:17:44

by Aruna Balakrishnaiah

[permalink] [raw]
Subject: [RFC PATCH v2 00/11] Add (de)compression support to pstore

Changes from v1:
- Allocate compression workspace during initialisation as
per Tony's suggestion
- Copy the recent messages from big_oops_buf to psinfo->buf
when compression fails, since the printk buffer
would be fetched for compression calling it again when
compression fails would have moved the iterator of
printk buffer which results in fetching old contents.

The patchset adds compression and decompression support to pstore.

As the non-volatile storage space is limited, adding compression
support results in capturing more data within limited space.

Size of dmesg file in a powerpc/pseries box with nvram's
oops partition (to store oops-log) size 4k:

Without compression:
dmesg-nvram-1: ~ 4k (3980)
WIth compression:
dmesg-nvram-1: ~8.8k (8844)

Writing to persistent store
----------------------------
Compression will reduce the size of oops/panic report to atmost 45% of its
original size. (Based on experiments done while providing compression support
to nvram by Jim keniston).
Hence buffer of size ( (100/45 approx 2.22) *<registered_buffer> is allocated).
The compression parameters selected based on some experiments:
compression_level = 6, window_bits = 12, memory_level = 4 achieved a
significant compression.
Data is compressed from the bigger buffer to registered buffer which is
returned to backends.
Pstore will indicate that with a flag 'compressed' which is passed to backends.
Using this flag, backends will add a flag in their header to indicate the data
is compressed or not while writing to persistent store.


Reading from persistent store
-----------------------------
When backends read data from persistent store it will use the flag added by it
while writing to persistent store to determine if the data is compressed or not.
Using the information, it will set the flag in pstore's read call back.
Pstore will decompress the data based on the flag and writes decompressed data
to the file.

Test results:
Have tested the patches on powerpc/pseries.

Needs testing with erst backend, efivars and persistent ram.


---

Aruna Balakrishnaiah (11):
powerpc/pseries: Remove (de)compression in nvram with pstore enabled
pstore: Add new argument 'compressed' in pstore write callback
pstore/Kconfig: Select ZLIB_DEFLATE and ZLIB_INFLATE when PSTORE is selected
pstore: Add compression support to pstore
pstore: Introduce new argument 'compressed' in the read callback
pstore: Add decompression support to pstore
pstore: Add file extension to pstore file if compressed
powerpc/pseries: Read and write to the 'compressed' flag of pstore
erst: Read and write to the 'compressed' flag of pstore
efi-pstore: Read and write to the 'compressed' flag of pstore
pstore/ram: Read and write to the 'compressed' flag of pstore


arch/powerpc/platforms/pseries/nvram.c | 112 +++--------------
drivers/acpi/apei/erst.c | 21 ++-
drivers/firmware/efi/efi-pstore.c | 27 +++-
fs/pstore/Kconfig | 2
fs/pstore/inode.c | 7 +
fs/pstore/internal.h | 5 -
fs/pstore/platform.c | 212 ++++++++++++++++++++++++++++++--
fs/pstore/ram.c | 41 +++++-
include/linux/pstore.h | 6 -
9 files changed, 299 insertions(+), 134 deletions(-)

--


2013-08-16 13:17:58

by Aruna Balakrishnaiah

[permalink] [raw]
Subject: [RFC PATCH v2 01/11] powerpc/pseries: Remove (de)compression in nvram with pstore enabled

(De)compression support is provided in pstore in subsequent patches which
needs an additional argument 'compressed' to determine if the data
is compressed or not. This patch will take care of removing (de)compression
in nvram with pstore which was making use of 'hsize' argument in pstore write
as 'hsize' will be removed in the subsequent patch.

Signed-off-by: Aruna Balakrishnaiah <[email protected]>
---
arch/powerpc/platforms/pseries/nvram.c | 102 ++++----------------------------
1 file changed, 12 insertions(+), 90 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c
index 6a5f2b1..b966458 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -539,36 +539,6 @@ static int zip_oops(size_t text_len)
}

#ifdef CONFIG_PSTORE
-/* Derived from logfs_uncompress */
-int nvram_decompress(void *in, void *out, size_t inlen, size_t outlen)
-{
- int err, ret;
-
- ret = -EIO;
- err = zlib_inflateInit(&stream);
- if (err != Z_OK)
- goto error;
-
- stream.next_in = in;
- stream.avail_in = inlen;
- stream.total_in = 0;
- stream.next_out = out;
- stream.avail_out = outlen;
- stream.total_out = 0;
-
- err = zlib_inflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END)
- goto error;
-
- err = zlib_inflateEnd(&stream);
- if (err != Z_OK)
- goto error;
-
- ret = stream.total_out;
-error:
- return ret;
-}
-
static int nvram_pstore_open(struct pstore_info *psi)
{
/* Reset the iterator to start reading partitions again */
@@ -611,30 +581,8 @@ static int nvram_pstore_write(enum pstore_type_id type,
oops_hdr->report_length = (u16) size;
oops_hdr->timestamp = get_seconds();

- if (big_oops_buf) {
- rc = zip_oops(size);
- /*
- * If compression fails copy recent log messages from
- * big_oops_buf to oops_data.
- */
- if (rc != 0) {
- size_t diff = size - oops_data_sz + hsize;
-
- if (size > oops_data_sz) {
- memcpy(oops_data, big_oops_buf, hsize);
- memcpy(oops_data + hsize, big_oops_buf + diff,
- oops_data_sz - hsize);
-
- oops_hdr->report_length = (u16) oops_data_sz;
- } else
- memcpy(oops_data, big_oops_buf, size);
- } else
- err_type = ERR_TYPE_KERNEL_PANIC_GZ;
- }
-
rc = nvram_write_os_partition(&oops_log_partition, oops_buf,
- (int) (sizeof(*oops_hdr) + oops_hdr->report_length), err_type,
- count);
+ (int) (sizeof(*oops_hdr) + size), err_type, count);

if (rc != 0)
return rc;
@@ -655,7 +603,7 @@ static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type,
struct oops_log_info *oops_hdr;
unsigned int err_type, id_no, size = 0;
struct nvram_os_partition *part = NULL;
- char *buff = NULL, *big_buff = NULL;
+ char *buff = NULL;
int sig = 0;
loff_t p;

@@ -719,8 +667,7 @@ static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type,
*id = id_no;

if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) {
- int length, unzipped_len;
- size_t hdr_size;
+ size_t length, hdr_size;

oops_hdr = (struct oops_log_info *)buff;
if (oops_hdr->version < OOPS_HDR_VERSION) {
@@ -740,24 +687,6 @@ static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type,
return -ENOMEM;
memcpy(*buf, buff + hdr_size, length);
kfree(buff);
-
- if (err_type == ERR_TYPE_KERNEL_PANIC_GZ) {
- big_buff = kmalloc(big_oops_buf_sz, GFP_KERNEL);
- if (!big_buff)
- return -ENOMEM;
-
- unzipped_len = nvram_decompress(*buf, big_buff,
- length, big_oops_buf_sz);
-
- if (unzipped_len < 0) {
- pr_err("nvram: decompression failed, returned "
- "rc %d\n", unzipped_len);
- kfree(big_buff);
- } else {
- *buf = big_buff;
- length = unzipped_len;
- }
- }
return length;
}

@@ -777,13 +706,8 @@ static int nvram_pstore_init(void)
{
int rc = 0;

- if (big_oops_buf) {
- nvram_pstore_info.buf = big_oops_buf;
- nvram_pstore_info.bufsize = big_oops_buf_sz;
- } else {
- nvram_pstore_info.buf = oops_data;
- nvram_pstore_info.bufsize = oops_data_sz;
- }
+ nvram_pstore_info.buf = oops_data;
+ nvram_pstore_info.bufsize = oops_data_sz;

rc = pstore_register(&nvram_pstore_info);
if (rc != 0)
@@ -802,7 +726,6 @@ static int nvram_pstore_init(void)
static void __init nvram_init_oops_partition(int rtas_partition_exists)
{
int rc;
- size_t size;

rc = pseries_nvram_init_os_partition(&oops_log_partition);
if (rc != 0) {
@@ -823,6 +746,11 @@ static void __init nvram_init_oops_partition(int rtas_partition_exists)
oops_data = oops_buf + sizeof(struct oops_log_info);
oops_data_sz = oops_log_partition.size - sizeof(struct oops_log_info);

+ rc = nvram_pstore_init();
+
+ if (!rc)
+ return;
+
/*
* Figure compression (preceded by elimination of each line's <n>
* severity prefix) will reduce the oops/panic report to at most
@@ -831,9 +759,8 @@ static void __init nvram_init_oops_partition(int rtas_partition_exists)
big_oops_buf_sz = (oops_data_sz * 100) / 45;
big_oops_buf = kmalloc(big_oops_buf_sz, GFP_KERNEL);
if (big_oops_buf) {
- size = max(zlib_deflate_workspacesize(WINDOW_BITS, MEM_LEVEL),
- zlib_inflate_workspacesize());
- stream.workspace = kmalloc(size, GFP_KERNEL);
+ stream.workspace = kmalloc(zlib_deflate_workspacesize(
+ WINDOW_BITS, MEM_LEVEL), GFP_KERNEL);
if (!stream.workspace) {
pr_err("nvram: No memory for compression workspace; "
"skipping compression of %s partition data\n",
@@ -847,11 +774,6 @@ static void __init nvram_init_oops_partition(int rtas_partition_exists)
stream.workspace = NULL;
}

- rc = nvram_pstore_init();
-
- if (!rc)
- return;
-
rc = kmsg_dump_register(&nvram_kmsg_dumper);
if (rc != 0) {
pr_err("nvram: kmsg_dump_register() failed; returned %d\n", rc);

2013-08-16 13:18:05

by Aruna Balakrishnaiah

[permalink] [raw]
Subject: [RFC PATCH v2 02/11] pstore: Add new argument 'compressed' in pstore write callback

Addition of new argument 'compressed' in the write call back will
help the backend to know if the data passed from pstore is compressed
or not (In case where compression fails.). If compressed, the backend
can add a tag indicating the data is compressed while writing to
persistent store.

Signed-off-by: Aruna Balakrishnaiah <[email protected]>
---
arch/powerpc/platforms/pseries/nvram.c | 4 ++--
drivers/acpi/apei/erst.c | 4 ++--
drivers/firmware/efi/efi-pstore.c | 2 +-
fs/pstore/platform.c | 7 ++++---
fs/pstore/ram.c | 2 +-
include/linux/pstore.h | 4 ++--
6 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c
index b966458..dbe5dad 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -554,7 +554,7 @@ static int nvram_pstore_open(struct pstore_info *psi)
* @part: pstore writes data to registered buffer in parts,
* part number will indicate the same.
* @count: Indicates oops count
- * @hsize: Size of header added by pstore
+ * @compressed: Flag to indicate the log is compressed
* @size: number of bytes written to the registered buffer
* @psi: registered pstore_info structure
*
@@ -565,7 +565,7 @@ static int nvram_pstore_open(struct pstore_info *psi)
static int nvram_pstore_write(enum pstore_type_id type,
enum kmsg_dump_reason reason,
u64 *id, unsigned int part, int count,
- size_t hsize, size_t size,
+ bool compressed, size_t size,
struct pstore_info *psi)
{
int rc;
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c
index 88d0b0f..5e90796 100644
--- a/drivers/acpi/apei/erst.c
+++ b/drivers/acpi/apei/erst.c
@@ -935,7 +935,7 @@ static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, int *count,
struct timespec *time, char **buf,
struct pstore_info *psi);
static int erst_writer(enum pstore_type_id type, enum kmsg_dump_reason reason,
- u64 *id, unsigned int part, int count, size_t hsize,
+ u64 *id, unsigned int part, int count, bool compressed,
size_t size, struct pstore_info *psi);
static int erst_clearer(enum pstore_type_id type, u64 id, int count,
struct timespec time, struct pstore_info *psi);
@@ -1055,7 +1055,7 @@ out:
}

static int erst_writer(enum pstore_type_id type, enum kmsg_dump_reason reason,
- u64 *id, unsigned int part, int count, size_t hsize,
+ u64 *id, unsigned int part, int count, bool compressed,
size_t size, struct pstore_info *psi)
{
struct cper_pstore_record *rcd = (struct cper_pstore_record *)
diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c
index 73de5a9..fab6892 100644
--- a/drivers/firmware/efi/efi-pstore.c
+++ b/drivers/firmware/efi/efi-pstore.c
@@ -103,7 +103,7 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,

static int efi_pstore_write(enum pstore_type_id type,
enum kmsg_dump_reason reason, u64 *id,
- unsigned int part, int count, size_t hsize, size_t size,
+ unsigned int part, int count, bool compressed, size_t size,
struct pstore_info *psi)
{
char name[DUMP_NAME_LEN];
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 422962a..20fa686 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -149,6 +149,7 @@ static void pstore_dump(struct kmsg_dumper *dumper,
unsigned long size;
int hsize;
size_t len;
+ bool compressed = false;

dst = psinfo->buf;
hsize = sprintf(dst, "%s#%d Part%d\n", why, oopscount, part);
@@ -159,7 +160,7 @@ static void pstore_dump(struct kmsg_dumper *dumper,
break;

ret = psinfo->write(PSTORE_TYPE_DMESG, reason, &id, part,
- oopscount, hsize, hsize + len, psinfo);
+ oopscount, compressed, hsize + len, psinfo);
if (ret == 0 && reason == KMSG_DUMP_OOPS && pstore_is_mounted())
pstore_new_entry = 1;

@@ -221,10 +222,10 @@ static void pstore_register_console(void) {}
static int pstore_write_compat(enum pstore_type_id type,
enum kmsg_dump_reason reason,
u64 *id, unsigned int part, int count,
- size_t hsize, size_t size,
+ bool compressed, size_t size,
struct pstore_info *psi)
{
- return psi->write_buf(type, reason, id, part, psinfo->buf, hsize,
+ return psi->write_buf(type, reason, id, part, psinfo->buf, compressed,
size, psi);
}

diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index a6119f9..fe7188f 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -196,7 +196,7 @@ static int notrace ramoops_pstore_write_buf(enum pstore_type_id type,
enum kmsg_dump_reason reason,
u64 *id, unsigned int part,
const char *buf,
- size_t hsize, size_t size,
+ bool compressed, size_t size,
struct pstore_info *psi)
{
struct ramoops_context *cxt = psi->data;
diff --git a/include/linux/pstore.h b/include/linux/pstore.h
index 4aa80ba..abfca4f 100644
--- a/include/linux/pstore.h
+++ b/include/linux/pstore.h
@@ -58,11 +58,11 @@ struct pstore_info {
struct pstore_info *psi);
int (*write)(enum pstore_type_id type,
enum kmsg_dump_reason reason, u64 *id,
- unsigned int part, int count, size_t hsize,
+ unsigned int part, int count, bool compressed,
size_t size, struct pstore_info *psi);
int (*write_buf)(enum pstore_type_id type,
enum kmsg_dump_reason reason, u64 *id,
- unsigned int part, const char *buf, size_t hsize,
+ unsigned int part, const char *buf, bool compressed,
size_t size, struct pstore_info *psi);
int (*erase)(enum pstore_type_id type, u64 id,
int count, struct timespec time,

2013-08-16 13:18:21

by Aruna Balakrishnaiah

[permalink] [raw]
Subject: [RFC PATCH v2 04/11] pstore: Add compression support to pstore

Add compression support to pstore which will help in capturing more data.
Initially, pstore will make a call to kmsg_dump with a bigger buffer
and will pass the size of bigger buffer to kmsg_dump and then compress
the data to registered buffer of registered size.

In case compression fails, pstore will capture the uncompressed
data by making a call again to kmsg_dump with registered_buffer
of registered size.

Pstore will indicate the data is compressed or not with a flag
in the write callback.

Signed-off-by: Aruna Balakrishnaiah <[email protected]>
---
fs/pstore/platform.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 139 insertions(+), 9 deletions(-)

diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 20fa686..56218cb 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -26,6 +26,7 @@
#include <linux/console.h>
#include <linux/module.h>
#include <linux/pstore.h>
+#include <linux/zlib.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/slab.h>
@@ -65,6 +66,15 @@ struct pstore_info *psinfo;

static char *backend;

+/* Compression parameters */
+#define COMPR_LEVEL 6
+#define WINDOW_BITS 12
+#define MEM_LEVEL 4
+static struct z_stream_s stream;
+
+static char *big_oops_buf;
+static size_t big_oops_buf_sz;
+
/* How much of the console log to snapshot */
static unsigned long kmsg_bytes = 10240;

@@ -117,6 +127,91 @@ bool pstore_cannot_block_path(enum kmsg_dump_reason reason)
}
EXPORT_SYMBOL_GPL(pstore_cannot_block_path);

+/* Derived from logfs_compress() */
+static int pstore_compress(const void *in, void *out, size_t inlen,
+ size_t outlen)
+{
+ int err, ret;
+
+ ret = -EIO;
+ err = zlib_deflateInit2(&stream, COMPR_LEVEL, Z_DEFLATED, WINDOW_BITS,
+ MEM_LEVEL, Z_DEFAULT_STRATEGY);
+ if (err != Z_OK)
+ goto error;
+
+ stream.next_in = in;
+ stream.avail_in = inlen;
+ stream.total_in = 0;
+ stream.next_out = out;
+ stream.avail_out = outlen;
+ stream.total_out = 0;
+
+ err = zlib_deflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END)
+ goto error;
+
+ err = zlib_deflateEnd(&stream);
+ if (err != Z_OK)
+ goto error;
+
+ if (stream.total_out >= stream.total_in)
+ goto error;
+
+ ret = stream.total_out;
+error:
+ return ret;
+}
+
+static void allocate_buf_for_compression(void)
+{
+ size_t size;
+
+ big_oops_buf_sz = (psinfo->bufsize * 100) / 45;
+ big_oops_buf = kmalloc(big_oops_buf_sz, GFP_KERNEL);
+ if (big_oops_buf) {
+ size = max(zlib_deflate_workspacesize(WINDOW_BITS, MEM_LEVEL),
+ zlib_inflate_workspacesize());
+ stream.workspace = kmalloc(size, GFP_KERNEL);
+ if (!stream.workspace) {
+ pr_err("pstore: No memory for compression workspace; "
+ "skipping compression\n");
+ kfree(big_oops_buf);
+ big_oops_buf = NULL;
+ }
+ } else {
+ pr_err("No memory for uncompressed data; "
+ "skipping compression\n");
+ stream.workspace = NULL;
+ }
+
+}
+
+/*
+ * Called when compression fails, since the printk buffer
+ * would be fetched for compression calling it again when
+ * compression fails would have moved the iterator of
+ * printk buffer which results in fetching old contents.
+ * Copy the recent messages from big_oops_buf to psinfo->buf
+ */
+static size_t copy_kmsg_to_buffer(int hsize, size_t len)
+{
+ size_t total_len;
+ size_t diff;
+
+ total_len = hsize + len;
+
+ if (total_len > psinfo->bufsize) {
+ diff = total_len - psinfo->bufsize + hsize;
+ memcpy(psinfo->buf, big_oops_buf, hsize);
+ memcpy(psinfo->buf + hsize, big_oops_buf + diff,
+ psinfo->bufsize - hsize);
+ total_len = psinfo->bufsize;
+ } else
+ memcpy(psinfo->buf, big_oops_buf, total_len);
+
+ return total_len;
+}
+
/*
* callback from kmsg_dump. (s2,l2) has the most recently
* written bytes, older bytes are in (s1,l1). Save as much
@@ -148,23 +243,56 @@ static void pstore_dump(struct kmsg_dumper *dumper,
char *dst;
unsigned long size;
int hsize;
+ int zipped_len = -1;
size_t len;
- bool compressed = false;
+ bool compressed;
+ size_t total_len;

- dst = psinfo->buf;
- hsize = sprintf(dst, "%s#%d Part%d\n", why, oopscount, part);
- size = psinfo->bufsize - hsize;
- dst += hsize;
+ if (big_oops_buf) {
+ dst = big_oops_buf;
+ hsize = sprintf(dst, "%s#%d Part%d\n", why,
+ oopscount, part);
+ size = big_oops_buf_sz - hsize;

- if (!kmsg_dump_get_buffer(dumper, true, dst, size, &len))
- break;
+ if (!kmsg_dump_get_buffer(dumper, true, dst + hsize,
+ size, &len))
+ break;
+
+ zipped_len = pstore_compress(dst, psinfo->buf,
+ hsize + len, psinfo->bufsize);
+
+ if (zipped_len > 0) {
+ compressed = true;
+ total_len = zipped_len;
+ } else {
+ pr_err("pstore: compression failed for Part %d"
+ " returned %d\n", part, zipped_len);
+ pr_err("pstore: Capture uncompressed"
+ " oops/panic report of Part %d\n", part);
+ compressed = false;
+ total_len = copy_kmsg_to_buffer(hsize, len);
+ }
+ } else {
+ dst = psinfo->buf;
+ hsize = sprintf(dst, "%s#%d Part%d\n", why, oopscount,
+ part);
+ size = psinfo->bufsize - hsize;
+ dst += hsize;
+
+ if (!kmsg_dump_get_buffer(dumper, true, dst,
+ size, &len))
+ break;
+
+ compressed = false;
+ total_len = hsize + len;
+ }

ret = psinfo->write(PSTORE_TYPE_DMESG, reason, &id, part,
- oopscount, compressed, hsize + len, psinfo);
+ oopscount, compressed, total_len, psinfo);
if (ret == 0 && reason == KMSG_DUMP_OOPS && pstore_is_mounted())
pstore_new_entry = 1;

- total += hsize + len;
+ total += total_len;
part++;
}
if (pstore_cannot_block_path(reason)) {
@@ -262,6 +390,8 @@ int pstore_register(struct pstore_info *psi)
return -EINVAL;
}

+ allocate_buf_for_compression();
+
if (pstore_is_mounted())
pstore_get_records(0);

2013-08-16 13:18:11

by Aruna Balakrishnaiah

[permalink] [raw]
Subject: [RFC PATCH v2 03/11] pstore/Kconfig: Select ZLIB_DEFLATE and ZLIB_INFLATE when PSTORE is selected

Pstore will make use of deflate and inflate algorithm to compress and decompress
the data. So when Pstore is enabled select zlib_deflate and zlib_inflate.

Signed-off-by: Aruna Balakrishnaiah <[email protected]>
---
fs/pstore/Kconfig | 2 ++
1 file changed, 2 insertions(+)

diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index ca71db6..983d951 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -1,6 +1,8 @@
config PSTORE
bool "Persistent store support"
default n
+ select ZLIB_DEFLATE
+ select ZLIB_INFLATE
help
This option enables generic access to platform level
persistent storage via "pstore" filesystem that can

2013-08-16 13:18:29

by Aruna Balakrishnaiah

[permalink] [raw]
Subject: [RFC PATCH v2 05/11] pstore: Introduce new argument 'compressed' in the read callback

Backends will set the flag 'compressed' after reading the log from
persistent store to indicate the data being returned to pstore is
compressed or not.

Signed-off-by: Aruna Balakrishnaiah <[email protected]>
---
arch/powerpc/platforms/pseries/nvram.c | 2 +-
drivers/acpi/apei/erst.c | 4 ++--
drivers/firmware/efi/efi-pstore.c | 3 ++-
fs/pstore/platform.c | 4 +++-
fs/pstore/ram.c | 3 ++-
include/linux/pstore.h | 2 +-
6 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c
index dbe5dad..6c4dc52a 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -598,7 +598,7 @@ static int nvram_pstore_write(enum pstore_type_id type,
*/
static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type,
int *count, struct timespec *time, char **buf,
- struct pstore_info *psi)
+ bool *compressed, struct pstore_info *psi)
{
struct oops_log_info *oops_hdr;
unsigned int err_type, id_no, size = 0;
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c
index 5e90796..b0dca8e 100644
--- a/drivers/acpi/apei/erst.c
+++ b/drivers/acpi/apei/erst.c
@@ -933,7 +933,7 @@ static int erst_open_pstore(struct pstore_info *psi);
static int erst_close_pstore(struct pstore_info *psi);
static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, int *count,
struct timespec *time, char **buf,
- struct pstore_info *psi);
+ bool *compressed, struct pstore_info *psi);
static int erst_writer(enum pstore_type_id type, enum kmsg_dump_reason reason,
u64 *id, unsigned int part, int count, bool compressed,
size_t size, struct pstore_info *psi);
@@ -989,7 +989,7 @@ static int erst_close_pstore(struct pstore_info *psi)

static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, int *count,
struct timespec *time, char **buf,
- struct pstore_info *psi)
+ bool *compressed, struct pstore_info *psi)
{
int rc;
ssize_t len = 0;
diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c
index fab6892..9a5425f 100644
--- a/drivers/firmware/efi/efi-pstore.c
+++ b/drivers/firmware/efi/efi-pstore.c
@@ -87,7 +87,8 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)

static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
int *count, struct timespec *timespec,
- char **buf, struct pstore_info *psi)
+ char **buf, bool *compressed,
+ struct pstore_info *psi)
{
struct pstore_read_data data;

diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 56218cb..6418eb7 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -428,6 +428,7 @@ void pstore_get_records(int quiet)
enum pstore_type_id type;
struct timespec time;
int failed = 0, rc;
+ bool compressed;

if (!psi)
return;
@@ -436,7 +437,8 @@ void pstore_get_records(int quiet)
if (psi->open && psi->open(psi))
goto out;

- while ((size = psi->read(&id, &type, &count, &time, &buf, psi)) > 0) {
+ while ((size = psi->read(&id, &type, &count, &time, &buf, &compressed,
+ psi)) > 0) {
rc = pstore_mkfile(type, psi->name, id, count, buf,
(size_t)size, time, psi);
kfree(buf);
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index fe7188f..2927223 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -133,7 +133,8 @@ ramoops_get_next_prz(struct persistent_ram_zone *przs[], uint *c, uint max,

static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
int *count, struct timespec *time,
- char **buf, struct pstore_info *psi)
+ char **buf, bool *compressed,
+ struct pstore_info *psi)
{
ssize_t size;
ssize_t ecc_notice_size;
diff --git a/include/linux/pstore.h b/include/linux/pstore.h
index abfca4f..abd437d 100644
--- a/include/linux/pstore.h
+++ b/include/linux/pstore.h
@@ -55,7 +55,7 @@ struct pstore_info {
int (*close)(struct pstore_info *psi);
ssize_t (*read)(u64 *id, enum pstore_type_id *type,
int *count, struct timespec *time, char **buf,
- struct pstore_info *psi);
+ bool *compressed, struct pstore_info *psi);
int (*write)(enum pstore_type_id type,
enum kmsg_dump_reason reason, u64 *id,
unsigned int part, int count, bool compressed,

2013-08-16 13:18:46

by Aruna Balakrishnaiah

[permalink] [raw]
Subject: [RFC PATCH v2 07/11] pstore: Add file extension to pstore file if compressed

In case decompression fails, add a ".enc.z" to indicate the file has
compressed data. This will help user space utilities to figure
out the file contents.

Signed-off-by: Aruna Balakrishnaiah <[email protected]>
---
fs/pstore/inode.c | 7 ++++---
fs/pstore/internal.h | 5 +++--
fs/pstore/platform.c | 4 +++-
3 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index 71bf5f4..519d278 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -275,8 +275,8 @@ int pstore_is_mounted(void)
* Set the mtime & ctime to the date that this record was originally stored.
*/
int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id, int count,
- char *data, size_t size, struct timespec time,
- struct pstore_info *psi)
+ char *data, bool compressed, size_t size,
+ struct timespec time, struct pstore_info *psi)
{
struct dentry *root = pstore_sb->s_root;
struct dentry *dentry;
@@ -315,7 +315,8 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id, int count,

switch (type) {
case PSTORE_TYPE_DMESG:
- sprintf(name, "dmesg-%s-%lld", psname, id);
+ sprintf(name, "dmesg-%s-%lld%s", psname, id,
+ compressed ? ".enc.z" : "");
break;
case PSTORE_TYPE_CONSOLE:
sprintf(name, "console-%s", psname);
diff --git a/fs/pstore/internal.h b/fs/pstore/internal.h
index 937d820..3b3d305 100644
--- a/fs/pstore/internal.h
+++ b/fs/pstore/internal.h
@@ -50,8 +50,9 @@ extern struct pstore_info *psinfo;
extern void pstore_set_kmsg_bytes(int);
extern void pstore_get_records(int);
extern int pstore_mkfile(enum pstore_type_id, char *psname, u64 id,
- int count, char *data, size_t size,
- struct timespec time, struct pstore_info *psi);
+ int count, char *data, bool compressed,
+ size_t size, struct timespec time,
+ struct pstore_info *psi);
extern int pstore_is_mounted(void);

#endif
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 0195cca0..cf0b53f 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -479,13 +479,15 @@ void pstore_get_records(int quiet)
if (unzipped_len > 0) {
buf = big_oops_buf;
size = unzipped_len;
+ compressed = false;
} else {
pr_err("pstore: decompression failed;"
"returned %d\n", unzipped_len);
+ compressed = true;
}
}
rc = pstore_mkfile(type, psi->name, id, count, buf,
- (size_t)size, time, psi);
+ compressed, (size_t)size, time, psi);
if (unzipped_len < 0) {
/* Free buffer other than big oops */
kfree(buf);

2013-08-16 13:18:38

by Aruna Balakrishnaiah

[permalink] [raw]
Subject: [RFC PATCH v2 06/11] pstore: Add decompression support to pstore

Based on the flag 'compressed' set or not, pstore will decompress the
data returning a plain text file. If decompression fails for a particular
record it will have the compressed data in the file which can be
decompressed with 'openssl' command line tool.

Signed-off-by: Aruna Balakrishnaiah <[email protected]>
---
fs/pstore/platform.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 51 insertions(+), 2 deletions(-)

diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 6418eb7..0195cca0 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -162,6 +162,36 @@ error:
return ret;
}

+/* Derived from logfs_uncompress */
+int pstore_decompress(void *in, void *out, size_t inlen, size_t outlen)
+{
+ int err, ret;
+
+ ret = -EIO;
+ err = zlib_inflateInit(&stream);
+ if (err != Z_OK)
+ goto error;
+
+ stream.next_in = in;
+ stream.avail_in = inlen;
+ stream.total_in = 0;
+ stream.next_out = out;
+ stream.avail_out = outlen;
+ stream.total_out = 0;
+
+ err = zlib_inflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END)
+ goto error;
+
+ err = zlib_inflateEnd(&stream);
+ if (err != Z_OK)
+ goto error;
+
+ ret = stream.total_out;
+error:
+ return ret;
+}
+
static void allocate_buf_for_compression(void)
{
size_t size;
@@ -429,6 +459,7 @@ void pstore_get_records(int quiet)
struct timespec time;
int failed = 0, rc;
bool compressed;
+ int unzipped_len = -1;

if (!psi)
return;
@@ -439,10 +470,28 @@ void pstore_get_records(int quiet)

while ((size = psi->read(&id, &type, &count, &time, &buf, &compressed,
psi)) > 0) {
+ if (compressed && (type == PSTORE_TYPE_DMESG)) {
+ if (big_oops_buf)
+ unzipped_len = pstore_decompress(buf,
+ big_oops_buf, size,
+ big_oops_buf_sz);
+
+ if (unzipped_len > 0) {
+ buf = big_oops_buf;
+ size = unzipped_len;
+ } else {
+ pr_err("pstore: decompression failed;"
+ "returned %d\n", unzipped_len);
+ }
+ }
rc = pstore_mkfile(type, psi->name, id, count, buf,
(size_t)size, time, psi);
- kfree(buf);
- buf = NULL;
+ if (unzipped_len < 0) {
+ /* Free buffer other than big oops */
+ kfree(buf);
+ buf = NULL;
+ } else
+ unzipped_len = -1;
if (rc && (rc != -EEXIST || !quiet))
failed++;
}

2013-08-16 13:18:52

by Aruna Balakrishnaiah

[permalink] [raw]
Subject: [RFC PATCH v2 08/11] powerpc/pseries: Read and write to the 'compressed' flag of pstore

If data returned from pstore is compressed, nvram's write callback
will add a flag ERR_TYPE_KERNEL_PANIC_GZ indicating the data is compressed
while writing to nvram. If the data read from nvram is compressed, nvram's
read callback will set the flag 'compressed'. The patch adds backward
compatibilty with old format oops header when reading from pstore.

Signed-off-by: Aruna Balakrishnaiah <[email protected]>
---
arch/powerpc/platforms/pseries/nvram.c | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c
index 6c4dc52a..d276cd3 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -581,6 +581,9 @@ static int nvram_pstore_write(enum pstore_type_id type,
oops_hdr->report_length = (u16) size;
oops_hdr->timestamp = get_seconds();

+ if (compressed)
+ err_type = ERR_TYPE_KERNEL_PANIC_GZ;
+
rc = nvram_write_os_partition(&oops_log_partition, oops_buf,
(int) (sizeof(*oops_hdr) + size), err_type, count);

@@ -687,6 +690,11 @@ static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type,
return -ENOMEM;
memcpy(*buf, buff + hdr_size, length);
kfree(buff);
+
+ if (err_type == ERR_TYPE_KERNEL_PANIC_GZ)
+ *compressed = true;
+ else
+ *compressed = false;
return length;
}

2013-08-16 13:19:06

by Aruna Balakrishnaiah

[permalink] [raw]
Subject: [RFC PATCH v2 09/11] erst: Read and write to the 'compressed' flag of pstore

In pstore write, set the section type to CPER_SECTION_TYPE_DMESG_COMPR
if the data is compressed. In pstore read, read the section type and
update the 'compressed' flag accordingly.

Signed-off-by: Aruna Balakrishnaiah <[email protected]>
---
drivers/acpi/apei/erst.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c
index b0dca8e..62df189 100644
--- a/drivers/acpi/apei/erst.c
+++ b/drivers/acpi/apei/erst.c
@@ -956,6 +956,9 @@ static struct pstore_info erst_info = {
#define CPER_SECTION_TYPE_DMESG \
UUID_LE(0xc197e04e, 0xd545, 0x4a70, 0x9c, 0x17, 0xa5, 0x54, \
0x94, 0x19, 0xeb, 0x12)
+#define CPER_SECTION_TYPE_DMESG_Z \
+ UUID_LE(0x4f118707, 0x04dd, 0x4055, 0xb5, 0xdd, 0x95, 0x6d, \
+ 0x34, 0xdd, 0xfa, 0xc6)
#define CPER_SECTION_TYPE_MCE \
UUID_LE(0xfe08ffbe, 0x95e4, 0x4be7, 0xbc, 0x73, 0x40, 0x96, \
0x04, 0x4a, 0x38, 0xfc)
@@ -1034,7 +1037,12 @@ skip:
}
memcpy(*buf, rcd->data, len - sizeof(*rcd));
*id = record_id;
+ *compressed = false;
if (uuid_le_cmp(rcd->sec_hdr.section_type,
+ CPER_SECTION_TYPE_DMESG_Z) == 0) {
+ *type = PSTORE_TYPE_DMESG;
+ *compressed = true;
+ } else if (uuid_le_cmp(rcd->sec_hdr.section_type,
CPER_SECTION_TYPE_DMESG) == 0)
*type = PSTORE_TYPE_DMESG;
else if (uuid_le_cmp(rcd->sec_hdr.section_type,
@@ -1085,7 +1093,10 @@ static int erst_writer(enum pstore_type_id type, enum kmsg_dump_reason reason,
rcd->sec_hdr.flags = CPER_SEC_PRIMARY;
switch (type) {
case PSTORE_TYPE_DMESG:
- rcd->sec_hdr.section_type = CPER_SECTION_TYPE_DMESG;
+ if (compressed)
+ rcd->sec_hdr.section_type = CPER_SECTION_TYPE_DMESG_Z;
+ else
+ rcd->sec_hdr.section_type = CPER_SECTION_TYPE_DMESG;
break;
case PSTORE_TYPE_MCE:
rcd->sec_hdr.section_type = CPER_SECTION_TYPE_MCE;

2013-08-16 13:19:26

by Aruna Balakrishnaiah

[permalink] [raw]
Subject: [RFC PATCH v2 11/11] pstore/ram: Read and write to the 'compressed' flag of pstore

In pstore write, add character 'C'(compressed) or 'D'(decompressed)
in the header while writing to Ram persistent buffer. In pstore read,
read the header and update the 'compressed' flag accordingly.

Signed-off-by: Aruna Balakrishnaiah <[email protected]>
---
fs/pstore/ram.c | 36 ++++++++++++++++++++++++++++--------
1 file changed, 28 insertions(+), 8 deletions(-)

diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 2927223..4027c20 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -131,6 +131,27 @@ ramoops_get_next_prz(struct persistent_ram_zone *przs[], uint *c, uint max,
return prz;
}

+static void ramoops_read_kmsg_hdr(char *buffer, struct timespec *time,
+ bool *compressed)
+{
+ char data_type;
+
+ if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu-%c\n",
+ &time->tv_sec, &time->tv_nsec, &data_type) == 3) {
+ if (data_type == 'C')
+ *compressed = true;
+ else
+ *compressed = false;
+ } else if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu\n",
+ &time->tv_sec, &time->tv_nsec) == 2) {
+ *compressed = false;
+ } else {
+ time->tv_sec = 0;
+ time->tv_nsec = 0;
+ *compressed = false;
+ }
+}
+
static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
int *count, struct timespec *time,
char **buf, bool *compressed,
@@ -153,10 +174,6 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
if (!prz)
return 0;

- /* TODO(kees): Bogus time for the moment. */
- time->tv_sec = 0;
- time->tv_nsec = 0;
-
size = persistent_ram_old_size(prz);

/* ECC correction notice */
@@ -167,12 +184,14 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
return -ENOMEM;

memcpy(*buf, persistent_ram_old(prz), size);
+ ramoops_read_kmsg_hdr(*buf, time, compressed);
persistent_ram_ecc_string(prz, *buf + size, ecc_notice_size + 1);

return size + ecc_notice_size;
}

-static size_t ramoops_write_kmsg_hdr(struct persistent_ram_zone *prz)
+static size_t ramoops_write_kmsg_hdr(struct persistent_ram_zone *prz,
+ bool compressed)
{
char *hdr;
struct timespec timestamp;
@@ -183,8 +202,9 @@ static size_t ramoops_write_kmsg_hdr(struct persistent_ram_zone *prz)
timestamp.tv_sec = 0;
timestamp.tv_nsec = 0;
}
- hdr = kasprintf(GFP_ATOMIC, RAMOOPS_KERNMSG_HDR "%lu.%lu\n",
- (long)timestamp.tv_sec, (long)(timestamp.tv_nsec / 1000));
+ hdr = kasprintf(GFP_ATOMIC, RAMOOPS_KERNMSG_HDR "%lu.%lu-%c\n",
+ (long)timestamp.tv_sec, (long)(timestamp.tv_nsec / 1000),
+ compressed ? 'C' : 'D');
WARN_ON_ONCE(!hdr);
len = hdr ? strlen(hdr) : 0;
persistent_ram_write(prz, hdr, len);
@@ -243,7 +263,7 @@ static int notrace ramoops_pstore_write_buf(enum pstore_type_id type,

prz = cxt->przs[cxt->dump_write_cnt];

- hlen = ramoops_write_kmsg_hdr(prz);
+ hlen = ramoops_write_kmsg_hdr(prz, compressed);
if (size + hlen > prz->buffer_size)
size = prz->buffer_size - hlen;
persistent_ram_write(prz, buf, size);

2013-08-16 13:19:15

by Aruna Balakrishnaiah

[permalink] [raw]
Subject: [RFC PATCH v2 10/11] efi-pstore: Read and write to the 'compressed' flag of pstore

In pstore write, Efi will add a character 'C'(compressed) or
D'(decompressed) in its header while writing to persistent store.
In pstore read, read the header and update the 'compressed' flag
accordingly.

Signed-off-by: Aruna Balakrishnaiah <[email protected]>
---
drivers/firmware/efi/efi-pstore.c | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c
index 9a5425f..5002d50 100644
--- a/drivers/firmware/efi/efi-pstore.c
+++ b/drivers/firmware/efi/efi-pstore.c
@@ -35,6 +35,7 @@ struct pstore_read_data {
enum pstore_type_id *type;
int *count;
struct timespec *timespec;
+ bool *compressed;
char **buf;
};

@@ -42,7 +43,7 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
{
efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
struct pstore_read_data *cb_data = data;
- char name[DUMP_NAME_LEN];
+ char name[DUMP_NAME_LEN], data_type;
int i;
int cnt;
unsigned int part;
@@ -54,12 +55,23 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
for (i = 0; i < DUMP_NAME_LEN; i++)
name[i] = entry->var.VariableName[i];

- if (sscanf(name, "dump-type%u-%u-%d-%lu",
+ if (sscanf(name, "dump-type%u-%u-%d-%lu-%c",
+ cb_data->type, &part, &cnt, &time, &data_type) == 5) {
+ *cb_data->id = part;
+ *cb_data->count = cnt;
+ cb_data->timespec->tv_sec = time;
+ cb_data->timespec->tv_nsec = 0;
+ if (data_type == 'C')
+ *cb_data->compressed = true;
+ else
+ *cb_data->compressed = false;
+ } else if (sscanf(name, "dump-type%u-%u-%d-%lu",
cb_data->type, &part, &cnt, &time) == 4) {
*cb_data->id = part;
*cb_data->count = cnt;
cb_data->timespec->tv_sec = time;
cb_data->timespec->tv_nsec = 0;
+ *cb_data->compressed = false;
} else if (sscanf(name, "dump-type%u-%u-%lu",
cb_data->type, &part, &time) == 3) {
/*
@@ -71,6 +83,7 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
*cb_data->count = 0;
cb_data->timespec->tv_sec = time;
cb_data->timespec->tv_nsec = 0;
+ *cb_data->compressed = false;
} else
return 0;

@@ -96,6 +109,7 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
data.type = type;
data.count = count;
data.timespec = timespec;
+ data.compressed = compressed;
data.buf = buf;

return __efivar_entry_iter(efi_pstore_read_func, &efivar_sysfs_list, &data,
@@ -112,8 +126,8 @@ static int efi_pstore_write(enum pstore_type_id type,
efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
int i, ret = 0;

- sprintf(name, "dump-type%u-%u-%d-%lu", type, part, count,
- get_seconds());
+ sprintf(name, "dump-type%u-%u-%d-%lu-%c", type, part, count,
+ get_seconds(), compressed ? 'C' : 'D');

for (i = 0; i < DUMP_NAME_LEN; i++)
efi_name[i] = name[i];

2013-08-16 22:15:27

by Luck, Tony

[permalink] [raw]
Subject: RE: [RFC PATCH v2 00/11] Add (de)compression support to pstore

> Needs testing with erst backend, efivars and persistent ram.

Tested against ERST - works fine for me now.

Need to stare at the code to see if there are any more bits that could be cleaned up.

Thanks for addressing my issues from v1

-Tony
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2013-08-17 18:26:32

by Kees Cook

[permalink] [raw]
Subject: Re: [RFC PATCH v2 11/11] pstore/ram: Read and write to the 'compressed' flag of pstore

On Fri, Aug 16, 2013 at 6:19 AM, Aruna Balakrishnaiah
<[email protected]> wrote:
> In pstore write, add character 'C'(compressed) or 'D'(decompressed)
> in the header while writing to Ram persistent buffer. In pstore read,
> read the header and update the 'compressed' flag accordingly.
>
> Signed-off-by: Aruna Balakrishnaiah <[email protected]>

Nice work!

Acked-by: Kees Cook <[email protected]>

--
Kees Cook
Chrome OS Security

2013-08-17 18:32:54

by Kees Cook

[permalink] [raw]
Subject: Re: [RFC PATCH v2 00/11] Add (de)compression support to pstore

On Fri, Aug 16, 2013 at 3:15 PM, Luck, Tony <[email protected]> wrote:
>> Needs testing with erst backend, efivars and persistent ram.
>
> Tested against ERST - works fine for me now.
>
> Need to stare at the code to see if there are any more bits that could be cleaned up.
>
> Thanks for addressing my issues from v1

Yeah, this is great. While I haven't tested it myself yet, the code
seems to be in good shape. I acked the ram piece separately, but
consider the entire series:

Reviewed-by: Kees Cook <[email protected]>

Thanks!

-Kees

--
Kees Cook
Chrome OS Security

2013-08-19 17:29:21

by Tony Luck

[permalink] [raw]
Subject: Re: [RFC PATCH v2 00/11] Add (de)compression support to pstore

On Sat, Aug 17, 2013 at 11:32 AM, Kees Cook <[email protected]> wrote:
> Yeah, this is great. While I haven't tested it myself yet, the code
> seems to be in good shape. I acked the ram piece separately, but
> consider the entire series:
>
> Reviewed-by: Kees Cook <[email protected]>

Applied. This should show up in linux-next tomorrow.

Anyone using efivars as the pstore backend? Testing reports (positive
or negative) appreciated.

-Tony

2013-08-22 23:04:43

by Seiji Aguchi

[permalink] [raw]
Subject: RE: [RFC PATCH v2 06/11] pstore: Add decompression support to pstore



> -----Original Message-----
> From: [email protected] [mailto:[email protected]] On Behalf Of Aruna Balakrishnaiah
> Sent: Friday, August 16, 2013 9:18 AM
> To: [email protected]; [email protected]; [email protected]; [email protected]
> Cc: [email protected]; [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]
> Subject: [RFC PATCH v2 06/11] pstore: Add decompression support to pstore
>
> Based on the flag 'compressed' set or not, pstore will decompress the
> data returning a plain text file. If decompression fails for a particular
> record it will have the compressed data in the file which can be
> decompressed with 'openssl' command line tool.

If the decompression fails and openssl doesn't work, the worst case is that users can't read the entry.
In that case, pstore is meaningless at all.

Also, for users who want to get a single panic message, a compression is not needed.

So, I think we still have to support non-compression mode.
(IMO, pstore can take kdump as a model. Kdump supports both compression and non-compression mode.)

But, if you think my comment is outside this patchset, it's OK.
We can make it with a separate patch.

Seiji
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2013-08-22 23:08:23

by Seiji Aguchi

[permalink] [raw]
Subject: RE: [RFC PATCH v2 04/11] pstore: Add compression support to pstore



> * callback from kmsg_dump. (s2,l2) has the most recently
> * written bytes, older bytes are in (s1,l1). Save as much
> @@ -148,23 +243,56 @@ static void pstore_dump(struct kmsg_dumper *dumper,
> char *dst;
> unsigned long size;
> int hsize;
> + int zipped_len = -1;
> size_t len;
> - bool compressed = false;
> + bool compressed;
> + size_t total_len;
>
> - dst = psinfo->buf;
> - hsize = sprintf(dst, "%s#%d Part%d\n", why, oopscount, part);
> - size = psinfo->bufsize - hsize;
> - dst += hsize;
> + if (big_oops_buf) {
> + dst = big_oops_buf;
> + hsize = sprintf(dst, "%s#%d Part%d\n", why,
> + oopscount, part);
> + size = big_oops_buf_sz - hsize;
>
> - if (!kmsg_dump_get_buffer(dumper, true, dst, size, &len))
> - break;
> + if (!kmsg_dump_get_buffer(dumper, true, dst + hsize,
> + size, &len))
> + break;
> +
> + zipped_len = pstore_compress(dst, psinfo->buf,
> + hsize + len, psinfo->bufsize);
> +
> + if (zipped_len > 0) {
> + compressed = true;
> + total_len = zipped_len;
> + } else {
> + pr_err("pstore: compression failed for Part %d"
> + " returned %d\n", part, zipped_len);
> + pr_err("pstore: Capture uncompressed"
> + " oops/panic report of Part %d\n", part);

Why did you add these messages in pstore_dump()?
In my test case, they are not needed....

<snip>
# cat dmesg-efi-1
Panic#2 Part1
<4>[ 383.209057] RBP: ffff88006f551e80 R08: 0000000000000002 R09: 0000000000000000
<4>[ 383.209057] R10: 0000000000000382 R11: 0000000000000000 R12: 0000000000000063
<4>[ 383.209057] R13: 0000000000000286 R14: 000000000000000f R15: 0000000000000000
<4>[ 383.209057] FS: 00007f53317cc740(0000) GS:ffff88007c400000(0000) knlGS:0000000000000000
<4>[ 383.209057] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
<4>[ 383.209057] CR2: 0000000000000000 CR3: 0000000078a73000 CR4: 00000000000006f0
<4>[ 383.209057] Stack:
<4>[ 383.209057] ffff88006f551eb8 ffffffff813d40a2 0000000000000002 00007f53317db000
<4>[ 383.209057] ffff88006f551f50 0000000000000002 0000000000000000 ffff88006f551ed8
<4>[ 383.209057] ffffffff813d45aa 00007f53317db000 ffff88003f8c2b00 ffff88006f551ef8
<4>[ 383.209057] Call Trace:
<4>[ 383.209057] [<ffffffff813d40a2>] __handle_sysrq+0xa2/0x170
<4>[ 383.209057] [<ffffffff813d45aa>] write_sysrq_trigger+0x4a/0x50
<4>[ 383.209057] [<ffffffff8121981d>] proc_reg_write+0x3d/0x80
<4>[ 383.209057] [<ffffffff811aeb20>] vfs_write+0xc0/0x1f0
<4>[ 383.209057] [<ffffffff811af59c>] SyS_write+0x4c/0xa0
<4>[ 383.209057] [<ffffffff8168be82>] system_call_fastpath+0x16/0x1b
<4>[ 383.209057] Code: ef e8 ff f7 ff ff eb d8 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 0f 1f 44 00 00 55 c7 05 cc f3 c9 00 01 00 00 00 48 89 e5 0f ae f8 <c6> 04 25 00 00 00 00 01 5d c3 0f 1f 44 00 00 55 31 c0 c7 05 5e
<1>[ 383.209057] RIP [<ffffffff813d3946>] sysrq_handle_crash+0x16/0x20
<4>[ 383.209057] RSP <ffff88006f551e80>
<4>[ 383.209057] CR2: 0000000000000000
<4>[ 383.209057] ---[ end trace 04a1cddad37b4b33 ]---
<3>[ 383.209057] pstore: compression failed for Part 2 returned -5
<3>[ 383.209057] pstore: Capture uncompressed oops/panic report of Part 2
<3>[ 383.209057] pstore: compression failed for Part 5 returned -5
<3>[ 383.209057] pstore: Capture uncompressed oops/panic report of Part 5
<3>[ 383.209057] pstore: compression failed for Part 12 returned -5
<3>[ 383.209057] pstore: Capture uncompressed oops/panic report of Part 12
<0>[ 383.209057] Kernel panic - not syncing: Fatal exception
<3>[ 383.209057] drm_kms_helper: panic occurred, switching back to text console
<snip>


In efi-pstore case, after rebooting a system,
we are able to know which entry failed to compress with 'C' or 'D' as below.

#ls /sys/firmware/efi/vars/ |grep dump
dump-type0-10-1-1377204734-C-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-10-2-1377204734-C-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-11-1-1377204734-C-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-1-1-1377204734-C-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-11-2-1377204734-C-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-12-1-1377204734-D-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-1-2-1377204734-C-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-12-2-1377204734-D-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-13-1-1377204734-C-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-13-2-1377204734-C-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-2-1-1377204734-D-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-2-2-1377204734-D-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-3-1-1377204734-C-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-3-2-1377204734-D-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-4-1-1377204734-C-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-4-2-1377204734-C-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-5-1-1377204734-D-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-5-2-1377204734-C-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-6-1-1377204734-C-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-6-2-1377204734-C-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-7-1-1377204734-C-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-7-2-1377204734-C-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-8-1-1377204734-C-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-8-2-1377204734-C-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-9-1-1377204734-C-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0
dump-type0-9-2-1377204734-C-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0

Seiji
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2013-08-22 23:17:26

by Luck, Tony

[permalink] [raw]
Subject: RE: [RFC PATCH v2 04/11] pstore: Add compression support to pstore

<1>[ 383.209057] RIP [<ffffffff813d3946>] sysrq_handle_crash+0x16/0x20
<4>[ 383.209057] RSP <ffff88006f551e80>
<4>[ 383.209057] CR2: 0000000000000000
<4>[ 383.209057] ---[ end trace 04a1cddad37b4b33 ]---
<3>[ 383.209057] pstore: compression failed for Part 2 returned -5
<3>[ 383.209057] pstore: Capture uncompressed oops/panic report of Part 2
<3>[ 383.209057] pstore: compression failed for Part 5 returned -5

Interesting. With ERST backend I didn't see these messages. Traces in
pstore recovered files go as far as the line before the "---[ end trace 04a1cddad37b4b33 ]---"

Why the difference depending on which back end is in use?

But I agree that we shouldn't have these messages. They use up space
in the persistent store that could be better used saving some more lines
from earlier in the console log.

-Tony
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2013-08-22 23:47:27

by Seiji Aguchi

[permalink] [raw]
Subject: RE: [RFC PATCH v2 04/11] pstore: Add compression support to pstore



> -----Original Message-----
> From: Luck, Tony [mailto:[email protected]]
> Sent: Thursday, August 22, 2013 7:17 PM
> To: Seiji Aguchi; Aruna Balakrishnaiah; [email protected]; [email protected]; [email protected]
> Cc: [email protected]; [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]
> Subject: RE: [RFC PATCH v2 04/11] pstore: Add compression support to pstore
>
> <1>[ 383.209057] RIP [<ffffffff813d3946>] sysrq_handle_crash+0x16/0x20
> <4>[ 383.209057] RSP <ffff88006f551e80>
> <4>[ 383.209057] CR2: 0000000000000000
> <4>[ 383.209057] ---[ end trace 04a1cddad37b4b33 ]---
> <3>[ 383.209057] pstore: compression failed for Part 2 returned -5
> <3>[ 383.209057] pstore: Capture uncompressed oops/panic report of Part 2
> <3>[ 383.209057] pstore: compression failed for Part 5 returned -5
>
> Interesting. With ERST backend I didn't see these messages. Traces in
> pstore recovered files go as far as the line before the "---[ end trace 04a1cddad37b4b33 ]---"
>
> Why the difference depending on which back end is in use?

I think the difference doesn't depend on the back end.
Rather it depends on the environment.

I tested on a kvm guest with OVMF.

Seiji


>
> But I agree that we shouldn't have these messages. They use up space
> in the persistent store that could be better used saving some more lines
> from earlier in the console log.
>
> -Tony
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2013-08-27 05:19:57

by Aruna Balakrishnaiah

[permalink] [raw]
Subject: Re: [RFC PATCH v2 04/11] pstore: Add compression support to pstore

On Friday 23 August 2013 04:47 AM, Luck, Tony wrote:
> <1>[ 383.209057] RIP [<ffffffff813d3946>] sysrq_handle_crash+0x16/0x20
> <4>[ 383.209057] RSP <ffff88006f551e80>
> <4>[ 383.209057] CR2: 0000000000000000
> <4>[ 383.209057] ---[ end trace 04a1cddad37b4b33 ]---
> <3>[ 383.209057] pstore: compression failed for Part 2 returned -5
> <3>[ 383.209057] pstore: Capture uncompressed oops/panic report of Part 2
> <3>[ 383.209057] pstore: compression failed for Part 5 returned -5
>
> Interesting. With ERST backend I didn't see these messages. Traces in
> pstore recovered files go as far as the line before the "---[ end trace 04a1cddad37b4b33 ]---"
>
> Why the difference depending on which back end is in use?
>
> But I agree that we shouldn't have these messages. They use up space
> in the persistent store that could be better used saving some more lines
> from earlier in the console log.

Yeah. We can remove these messages as it will add to the space consumed. But it
would
be good to know why the compression failed with efivars case.

Seiji,

Could you let us know the efivars buffer size with which the pstore is
registered when
the failure occurred.

Regards,
Aruna


>
> -Tony
> _______________________________________________
> Linuxppc-dev mailing list
> [email protected]
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>

2013-08-27 09:39:57

by Aruna Balakrishnaiah

[permalink] [raw]
Subject: Re: [RFC PATCH v2 06/11] pstore: Add decompression support to pstore

On Friday 23 August 2013 04:34 AM, Seiji Aguchi wrote:
>
>> -----Original Message-----
>> From: [email protected] [mailto:[email protected]] On Behalf Of Aruna Balakrishnaiah
>> Sent: Friday, August 16, 2013 9:18 AM
>> To: [email protected]; [email protected]; [email protected]; [email protected]
>> Cc: [email protected]; [email protected]; [email protected]; [email protected];
>> [email protected]; [email protected]
>> Subject: [RFC PATCH v2 06/11] pstore: Add decompression support to pstore
>>
>> Based on the flag 'compressed' set or not, pstore will decompress the
>> data returning a plain text file. If decompression fails for a particular
>> record it will have the compressed data in the file which can be
>> decompressed with 'openssl' command line tool.
> If the decompression fails and openssl doesn't work, the worst case is that users can't read the entry.
> In that case, pstore is meaningless at all.

If decompression fails and openssl doesn't work. We have python module zlib to
decompress
the zlib data. zlib.decompress() should do the trick.

> Also, for users who want to get a single panic message, a compression is not needed.
>
> So, I think we still have to support non-compression mode.
> (IMO, pstore can take kdump as a model. Kdump supports both compression and non-compression mode.)
>
> But, if you think my comment is outside this patchset, it's OK.
> We can make it with a separate patch.
>
> Seiji
> _______________________________________________
> Linuxppc-dev mailing list
> [email protected]
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>

2013-09-04 01:45:16

by Seiji Aguchi

[permalink] [raw]
Subject: RE: [RFC PATCH v2 04/11] pstore: Add compression support to pstore

Aruna,

Sorry for the late response.

> Seiji,
>
> Could you let us know the efivars buffer size with which the pstore is
> registered when
> the failure occurred.

I looked into the issue today.

I added some debug message just before pstore_compress().
As you can see below, the buffer size is a fixed value(1024).
Therefore, the size doesn't seem to be related to the failure directly.

Also, in the failure case, zlib_deflate() returns Z_OK and stream.avail_out is zero.
So, I thought big_oops_buf_sz is too big in my environment.
And then, I tuned big_oops_buf_sz to (psinfo->bufsize * 100) / 53.

At the same time, while looking into this issue, I had two concerns about current cording.

1) In pstore_decompress(), why not use zlib_inflateInit2() instead of zlib_inflateInit()?
If you use zlib_deflateInit2() for specifying window_bit at compressing time,
zlib_inflateInit2() seems to be appropriate for decompressing.
(Please see a comment about inflateInit2() in include/linux/zlib.h and source code of crypto/deflate.c)

2) As looking at crypto/deflate.c, stream->workspace is kzalloced at the beginning of
compressing/decompressing time.
So, in pstore case, stream.workspace must be initialized to 0 with memset() in pstore_compress()/decompress().

I did three things above, tuning big_oops_buf_sz, using zlib_inflateInit2() and initializing stream.workspace , in my environment.
As a result, compressions/decmpressions of all entries succeeded with efivars driver.

<snip>
Panic#2 Part1
<4>[ 75.665020] [<ffffffff811af59c>] SyS_write+0x4c/0xa0
<4>[ 75.665020] [<ffffffff8168be82>] system_call_fastpath+0x16/0x1b
<4>[ 75.665020] Code: ef e8 ff f7 ff ff eb d8 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 0f 1f 44 00 00 55 c7 05 cc f3 c9 00 01 00 00 00 48 89 e5 0f ae f8 <c6> 04 25 00 00 00 00 01 5d c3 0f 1f 44 00 00 55 31 c0 c7 05 5e
<1>[ 75.665020] RIP [<ffffffff813d3946>] sysrq_handle_crash+0x16/0x20
<4>[ 75.665020] RSP <ffff88007852de80>
<4>[ 75.665020] CR2: 0000000000000000
<4>[ 75.665020] ---[ end trace 97bb4a1f8d3fe7b2 ]---
<3>[ 75.665020] pstore_dump hsize=13 len=2155 big_oops_buf_sz=2275 psinfo->bufsize=1024
<3>[ 75.665020] pstore_dump hsize=13 len=2246 big_oops_buf_sz=2275 psinfo->bufsize=1024
<3>[ 75.665020] pstore: compression failed for Part 2 returned -5
<3>[ 75.665020] pstore: Capture uncompressed oops/panic report of Part 2
<3>[ 75.665020] pstore_dump hsize=13 len=2239 big_oops_buf_sz=2275 psinfo->bufsize=1024
<3>[ 75.665020] pstore_dump hsize=13 len=2231 big_oops_buf_sz=2275 psinfo->bufsize=1024
<3>[ 75.665020] pstore_dump hsize=13 len=2185 big_oops_buf_sz=2275 psinfo->bufsize=1024
<3>[ 75.665020] pstore: compression failed for Part 5 returned -5
<3>[ 75.665020] pstore: Capture uncompressed oops/panic report of Part 5
<3>[ 75.665020] pstore_dump hsize=13 len=2234 big_oops_buf_sz=2275 psinfo->bufsize=1024
<3>[ 75.665020] pstore_dump hsize=13 len=2208 big_oops_buf_sz=2275 psinfo->bufsize=1024
<3>[ 75.665020] pstore_dump hsize=13 len=2218 big_oops_buf_sz=2275 psinfo->bufsize=1024
<3>[ 75.665020] pstore_dump hsize=13 len=2222 big_oops_buf_sz=2275 psinfo->bufsize=1024
<3>[ 75.665020] pstore: compression failed for Part 9 returned -5
<3>[ 75.665020] pstore: Capture uncompressed oops/panic report of Part 9
<3>[ 75.665020] pstore_dump hsize=14 len=2256 big_oops_buf_sz=2275 psinfo->bufsize=1024
<3>[ 75.665020] pstore_dump hsize=14 len=2219 big_oops_buf_sz=2275 psinfo->bufsize=1024
<3>[ 75.665020] pstore_dump hsize=14 len=2226 big_oops_buf_sz=2275 psinfo->bufsize=1024
<0>[ 75.665020] Kernel panic - not syncing: Fatal exception
<3>[ 75.665020] drm_kms_helper: panic occurred, switching back to text console
<snip>

Seiji

2013-09-04 06:01:13

by Aruna Balakrishnaiah

[permalink] [raw]
Subject: Re: [RFC PATCH v2 04/11] pstore: Add compression support to pstore

On Wednesday 04 September 2013 07:14 AM, Seiji Aguchi wrote:
> Aruna,
>
> Sorry for the late response.
>
>> Seiji,
>>
>> Could you let us know the efivars buffer size with which the pstore is
>> registered when
>> the failure occurred.
> I looked into the issue today.
>
> I added some debug message just before pstore_compress().
> As you can see below, the buffer size is a fixed value(1024).
> Therefore, the size doesn't seem to be related to the failure directly.
>
> Also, in the failure case, zlib_deflate() returns Z_OK and stream.avail_out is zero.
> So, I thought big_oops_buf_sz is too big in my environment.
> And then, I tuned big_oops_buf_sz to (psinfo->bufsize * 100) / 53.
Seiji,

Thank you for the analysis.

The reason behind compression failure is the size of big_oops_buf which is too
big for efivars case. I will do some experiments with different kind of texts
for buffer size 1024 to check if 100/53 suits for all the cases.

>
> At the same time, while looking into this issue, I had two concerns about current cording.
>
> 1) In pstore_decompress(), why not use zlib_inflateInit2() instead of zlib_inflateInit()?
> If you use zlib_deflateInit2() for specifying window_bit at compressing time,
> zlib_inflateInit2() seems to be appropriate for decompressing.
> (Please see a comment about inflateInit2() in include/linux/zlib.h and source code of crypto/deflate.c)

Yes this can be changed to zlib_inflateInit2().

> 2) As looking at crypto/deflate.c, stream->workspace is kzalloced at the beginning of
> compressing/decompressing time.
> So, in pstore case, stream.workspace must be initialized to 0 with memset() in pstore_compress()/decompress().

Hmm.. I don't think this is a issue. If you see fs/logfs/compr.c from which I
derived the compression
algorithms for pstore as well, they have not initialized stream.workspace. Since
the space will be overwritten
during the calculation, I dont think it will matter.

The above 2 things you have suggested are good to have. But the reason behind
compression failure is
the big_oops_buf_sz which is too big for efivars.

> I did three things above, tuning big_oops_buf_sz, using zlib_inflateInit2() and initializing stream.workspace , in my environment.
> As a result, compressions/decmpressions of all entries succeeded with efivars driver.
>
> <snip>
> Panic#2 Part1
> <4>[ 75.665020] [<ffffffff811af59c>] SyS_write+0x4c/0xa0
> <4>[ 75.665020] [<ffffffff8168be82>] system_call_fastpath+0x16/0x1b
> <4>[ 75.665020] Code: ef e8 ff f7 ff ff eb d8 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 0f 1f 44 00 00 55 c7 05 cc f3 c9 00 01 00 00 00 48 89 e5 0f ae f8 <c6> 04 25 00 00 00 00 01 5d c3 0f 1f 44 00 00 55 31 c0 c7 05 5e
> <1>[ 75.665020] RIP [<ffffffff813d3946>] sysrq_handle_crash+0x16/0x20
> <4>[ 75.665020] RSP <ffff88007852de80>
> <4>[ 75.665020] CR2: 0000000000000000
> <4>[ 75.665020] ---[ end trace 97bb4a1f8d3fe7b2 ]---
> <3>[ 75.665020] pstore_dump hsize=13 len=2155 big_oops_buf_sz=2275 psinfo->bufsize=1024
> <3>[ 75.665020] pstore_dump hsize=13 len=2246 big_oops_buf_sz=2275 psinfo->bufsize=1024
> <3>[ 75.665020] pstore: compression failed for Part 2 returned -5
> <3>[ 75.665020] pstore: Capture uncompressed oops/panic report of Part 2
> <3>[ 75.665020] pstore_dump hsize=13 len=2239 big_oops_buf_sz=2275 psinfo->bufsize=1024
> <3>[ 75.665020] pstore_dump hsize=13 len=2231 big_oops_buf_sz=2275 psinfo->bufsize=1024
> <3>[ 75.665020] pstore_dump hsize=13 len=2185 big_oops_buf_sz=2275 psinfo->bufsize=1024
> <3>[ 75.665020] pstore: compression failed for Part 5 returned -5
> <3>[ 75.665020] pstore: Capture uncompressed oops/panic report of Part 5
> <3>[ 75.665020] pstore_dump hsize=13 len=2234 big_oops_buf_sz=2275 psinfo->bufsize=1024
> <3>[ 75.665020] pstore_dump hsize=13 len=2208 big_oops_buf_sz=2275 psinfo->bufsize=1024
> <3>[ 75.665020] pstore_dump hsize=13 len=2218 big_oops_buf_sz=2275 psinfo->bufsize=1024
> <3>[ 75.665020] pstore_dump hsize=13 len=2222 big_oops_buf_sz=2275 psinfo->bufsize=1024
> <3>[ 75.665020] pstore: compression failed for Part 9 returned -5
> <3>[ 75.665020] pstore: Capture uncompressed oops/panic report of Part 9
> <3>[ 75.665020] pstore_dump hsize=14 len=2256 big_oops_buf_sz=2275 psinfo->bufsize=1024
> <3>[ 75.665020] pstore_dump hsize=14 len=2219 big_oops_buf_sz=2275 psinfo->bufsize=1024
> <3>[ 75.665020] pstore_dump hsize=14 len=2226 big_oops_buf_sz=2275 psinfo->bufsize=1024
> <0>[ 75.665020] Kernel panic - not syncing: Fatal exception
> <3>[ 75.665020] drm_kms_helper: panic occurred, switching back to text console
> <snip>
>
> Seiji
> _______________________________________________
> Linuxppc-dev mailing list
> [email protected]
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>

2013-09-04 16:11:22

by Luck, Tony

[permalink] [raw]
Subject: RE: [RFC PATCH v2 04/11] pstore: Add compression support to pstore

> The reason behind compression failure is the size of big_oops_buf which is too
> big for efivars case. I will do some experiments with different kind of texts
> for buffer size 1024 to check if 100/53 suits for all the cases.
...

> Yes this can be changed to zlib_inflateInit2().

Original patch series was just pulled by Linus ... so we'll need a patch on top
of current Linus git tree to fix these issues. But let's make sure that efivars, erst,
etc. are all happy with the changes we make before I ask Linus to pull another
pstore piece.

Thanks

-Tony

2013-09-04 16:40:52

by Seiji Aguchi

[permalink] [raw]
Subject: RE: [RFC PATCH v2 04/11] pstore: Add compression support to pstore

> But let's make sure that efivars, erst,
> etc. are all happy with the changes we make before I ask Linus to pull another
> pstore piece.

I will test efivars when Aruna posts the bugfix patches.

Seiji

> -----Original Message-----
> From: Luck, Tony [mailto:[email protected]]
> Sent: Wednesday, September 04, 2013 12:11 PM
> To: Aruna Balakrishnaiah; Seiji Aguchi
> Cc: [email protected]; [email protected]; [email protected]; [email protected]; linux-
> [email protected]; [email protected]; [email protected]
> Subject: RE: [RFC PATCH v2 04/11] pstore: Add compression support to pstore
>
> > The reason behind compression failure is the size of big_oops_buf which is too
> > big for efivars case. I will do some experiments with different kind of texts
> > for buffer size 1024 to check if 100/53 suits for all the cases.
> ...
>
> > Yes this can be changed to zlib_inflateInit2().
>
> Original patch series was just pulled by Linus ... so we'll need a patch on top
> of current Linus git tree to fix these issues. But let's make sure that efivars, erst,
> etc. are all happy with the changes we make before I ask Linus to pull another
> pstore piece.
>
> Thanks
>
> -Tony