Re: [PATCH 4/8] Read/Write oops nvram partition via pstore

2013-04-16 Thread Aruna Balakrishnaiah

Hi Michael,

Thanks for reviewing my patches.

On Monday 15 April 2013 01:25 PM, Michael Ellerman wrote:

On Wed, Apr 10, 2013 at 12:53:03PM +0530, Aruna Balakrishnaiah wrote:

This patch exploits pstore infrastructure in power systems.
IBM's system p machines provide persistent storage for LPARs

In the kernel we use pseries instead of system p.



Sure, will change it.


through NVRAM. NVRAM's lnx,oops-log partition is used to log
oops messages. In case pstore registration fails it will
fall back to kmsg_dump mechanism.

What are the implications of falling back to kmsg_dump()?



Logging oops messages to nvram should not fail in case pstore registration
fails. So it falls back to existing kmsg_dump infrastructure where
oops_to_nvram will be called. The users would need to use existing tools
to read nvram data as it is now.


Is there any reason we would not want to enable CONFIG_PSTORE ? ie.
should the pseries platform just select it?


Since current patchset does not support compression, selecting PSTORE by
default will lose the existing compression feature.
Once the compression feature for PSTORE is in place we can make PSTORE as
default on power.

I will post the compression patches soon. The reason for posting it
separately is stated below.


diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 6701b71..82d32a2 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -18,6 +18,7 @@
  #include linux/spinlock.h
  #include linux/slab.h
  #include linux/kmsg_dump.h
+#include linux/pstore.h
  #include linux/ctype.h
  #include linux/zlib.h
  #include asm/uaccess.h
@@ -87,6 +88,25 @@ static struct kmsg_dumper nvram_kmsg_dumper = {
.dump = oops_to_nvram
  };
  
+static int nvram_pstore_open(struct pstore_info *psi);

+
+static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type,
+   int *count, struct timespec *time, char **buf,
+   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 size,
+   struct pstore_info *psi);

I think you should be able to rearrange this so that you don't need the
forward declarations.


Sure. This would result in moving the callback functions just before pstore
registration for which I need to move clobbering_unread_rtas_event() which
is used by nvram_pstore_write.


+
+static struct pstore_info nvram_pstore_info = {
+   .owner = THIS_MODULE,
+   .name = nvram,
+   .open = nvram_pstore_open,
+   .read = nvram_pstore_read,
+   .write = nvram_pstore_write,
+};
+
  /* See clobbering_unread_rtas_event() */
  #define NVRAM_RTAS_READ_TIMEOUT 5 /* seconds */
  static unsigned long last_unread_rtas_event;  /* timestamp */
@@ -121,6 +141,13 @@ static char *big_oops_buf, *oops_buf;
  static char *oops_data;
  static size_t oops_data_sz;
  
+#ifdef CONFIG_PSTORE

If we are going to have CONFIG_PSTORE #ifdefs in this file, I don't see
why there can't be just a single block of code that is #ifdef'ed, rather
than several like you have.


Sure. I will have one #ifdef for declarations and one for function
definitions.


+static enum pstore_type_id nvram_type_ids[] = {
+   PSTORE_TYPE_DMESG,
+   -1
+};
+static int read_type;

I don't understand what you're doing with read_type. It looks fishy.


read_type is an iterator to traverse the partition types. It is to know
which partition we need to read.


+#endif
  /* Compression parameters */
  #define COMPR_LEVEL 6
  #define WINDOW_BITS 12
@@ -455,6 +482,23 @@ 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);
  
+	nvram_pstore_info.buf = oops_data;

+   nvram_pstore_info.bufsize = oops_data_sz;
+
+   rc = pstore_register(nvram_pstore_info);
+
+   if (rc != 0) {
+   pr_err(nvram: pstore_register() failed, defaults to 
+   kmsg_dump; returned %d\n, rc);
+   goto kmsg_dump;

You don't need the goto.


Yeah, my bad. Will fix it.


+   } else {
+   /*TODO: Support compression when pstore is configured */

What is the issue here?



Currently with this patchset, pstore is not supporting compression of 
oops-messages
since it involves some changes in the pstore framework.

big_oops_buf will hold the large part of oops data which will be compressed and 
put
to oops_buf.

big_oops_buf: (1.45 of oops_partition_size)
_
|  header |   oops-text |
|_|_|

header is added by the pstore.

So in case compression fails:

we would need to log the header + last few bytes of big_oops_buf

Re: [PATCH 5/8] Read rtas partition via pstore

2013-04-16 Thread Aruna Balakrishnaiah

On Monday 15 April 2013 01:31 PM, Michael Ellerman wrote:

On Wed, Apr 10, 2013 at 12:53:27PM +0530, Aruna Balakrishnaiah wrote:

This patch exploits pstore infrastructure to read the details
from NVRAM's rtas partition.

Does that mean it's exposed in the pstore filesystem?


Yeah thats right.


Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
  arch/powerpc/platforms/pseries/nvram.c |   33 +---
  fs/pstore/inode.c  |3 +++
  include/linux/pstore.h |2 ++
  3 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 82d32a2..d420b1d 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -144,9 +144,11 @@ static size_t oops_data_sz;
  #ifdef CONFIG_PSTORE
  static enum pstore_type_id nvram_type_ids[] = {
PSTORE_TYPE_DMESG,
+   PSTORE_TYPE_RTAS,
-1
  };
  static int read_type;
+static unsigned long last_rtas_event;
  #endif
  /* Compression parameters */
  #define COMPR_LEVEL 6
@@ -315,8 +317,13 @@ int nvram_write_error_log(char * buff, int length,
  {
int rc = nvram_write_os_partition(rtas_log_partition, buff, length,
err_type, error_log_cnt);
-   if (!rc)
+   if (!rc) {
last_unread_rtas_event = get_seconds();
+#ifdef CONFIG_PSTORE
+   last_rtas_event = get_seconds();
+#endif
+   }
+
return rc;
  }
  
@@ -745,7 +752,7 @@ static int nvram_pstore_write(enum pstore_type_id type,

  }
  
  /*

- * Reads the oops/panic report.
+ * Reads the oops/panic report and ibm,rtas-log partition.
   * Returns the length of the data we read from each partition.
   * Returns 0 if we've been called before.
   */
@@ -765,6 +772,12 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
part = oops_log_partition;
*type = PSTORE_TYPE_DMESG;
break;
+   case PSTORE_TYPE_RTAS:
+   part = rtas_log_partition;
+   *type = PSTORE_TYPE_RTAS;
+   time-tv_sec = last_rtas_event;
+   time-tv_nsec = 0;
+   break;
default:
return 0;
}
@@ -781,11 +794,17 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
  
  	*count = 0;

*id = id_no;
-   oops_hdr = (struct oops_log_info *)buff;
-   *buf = buff + sizeof(*oops_hdr);
-   time-tv_sec = oops_hdr-timestamp;
-   time-tv_nsec = 0;
-   return oops_hdr-report_length;
+
+   if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) {
+   oops_hdr = (struct oops_log_info *)buff;
+   *buf = buff + sizeof(*oops_hdr);
+   time-tv_sec = oops_hdr-timestamp;
+   time-tv_nsec = 0;
+   return oops_hdr-report_length;
+   }
+
+   *buf = buff;
+   return part-size;
  }
  #else
  static int nvram_pstore_open(struct pstore_info *psi)
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index e4bcb2c..59b1454 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -324,6 +324,9 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, 
u64 id, int count,
case PSTORE_TYPE_MCE:
sprintf(name, mce-%s-%lld, psname, id);
break;
+   case PSTORE_TYPE_RTAS:
+   sprintf(name, rtas-%s-%lld, psname, id);
+   break;
case PSTORE_TYPE_UNKNOWN:
sprintf(name, unknown-%s-%lld, psname, id);
break;
diff --git a/include/linux/pstore.h b/include/linux/pstore.h
index 75d0176..4eb94c9 100644
--- a/include/linux/pstore.h
+++ b/include/linux/pstore.h
@@ -35,6 +35,8 @@ enum pstore_type_id {
PSTORE_TYPE_MCE = 1,
PSTORE_TYPE_CONSOLE = 2,
PSTORE_TYPE_FTRACE  = 3,
+   /* PPC64 partition types */
+   PSTORE_TYPE_RTAS= 10,
PSTORE_TYPE_UNKNOWN = 255

I think you should probably just continue at 4, and call it
PSTORE_TYPE_PPC_RTAS. But you must get an ACK from the pstore
maintainers for this and the previous hunk, and I don't see them on CC.


Sure, will add them on cc in my next version of the patches.



cheers



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


Re: [PATCH 4/8] Read/Write oops nvram partition via pstore

2013-04-16 Thread Aruna Balakrishnaiah

On Tuesday 16 April 2013 12:44 PM, Benjamin Herrenschmidt wrote:

On Tue, 2013-04-16 at 11:50 +0530, Aruna Balakrishnaiah wrote:

Sure. I will have one #ifdef for declarations and one for function
definitions.

Declarations generally don't need #ifdef's


Sorry by declarations I meant variable declarations (used by pstore) not 
function
declarations.


Cheers,
Ben.




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


Re: [PATCH 4/8] Read/Write oops nvram partition via pstore

2013-04-16 Thread Aruna Balakrishnaiah

On Tuesday 16 April 2013 11:50 AM, Aruna Balakrishnaiah wrote:


Currently with this patchset, pstore is not supporting compression of 
oops-messages

since it involves some changes in the pstore framework.

big_oops_buf will hold the large part of oops data which will be compressed 
and put

to oops_buf.

big_oops_buf: (1.45 of oops_partition_size)


Sorry, big_oops_buf is (2.22 of oops_data_sz)

where oops_data_sz is oops_partition_size - sizeof(oops_log_info).

where oops_log_info is oops header.


_
|  header |   oops-text |
|_|_|

header is added by the pstore.

So in case compression fails:

we would need to log the header + last few bytes of big_oops_buf to oops_buf.
oops_buf: (this is of oops_partition_size)



We would need to log the header + last oops_data_sz bytes of big_oops_buf to 
oops_buf.

So that we can have the header while throwing away the data that immediately
follows it.


we need last few bytes of big_oops_buf as we need to log the recent messages of
printk buffer. For which we need to know the header size and it involves some
changes in the pstore framework.



Just communicating the header size from pstore would do the job for us.


I have the compression patches ready, will be posting it soon as a separate set.


cheers





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


[PATCH 0/8] Nvram-to-pstore

2013-04-10 Thread Aruna Balakrishnaiah
Currently the kernel provides the contents of p-series NVRAM only as a
simple stream of bytes via /dev/nvram, which must be interpreted in user
space by the nvram command in the powerpc-utils package.  This patch set
exploits the pstore subsystem to expose each partition in NVRAM as a
separate file in /dev/pstore. For instance Oops messages will stored in a
file named [dmesg-nvram-2].

---

Aruna Balakrishnaiah (8):
  Remove syslog prefix in uncompressed oops text
  Add version and timestamp to oops header
  Introduce generic read function to read nvram-partitions
  Read/Write oops nvram partition via pstore
  Read rtas partition via pstore
  Distinguish between a os-partition and non-os partition
  Read of-config partition via pstore
  Read common partition via pstore


 arch/powerpc/platforms/pseries/nvram.c |  329 
 fs/pstore/inode.c  |9 +
 include/linux/pstore.h |4 
 3 files changed, 304 insertions(+), 38 deletions(-)

-- 

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


[PATCH 1/8] Remove syslog prefix in uncompressed oops text

2013-04-10 Thread Aruna Balakrishnaiah
Removal of syslog prefix in the uncompressed oops text will
help in capturing more oops data.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 8733a86..e54a8b7 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -619,7 +619,7 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
}
if (rc != 0) {
kmsg_dump_rewind(dumper);
-   kmsg_dump_get_buffer(dumper, true,
+   kmsg_dump_get_buffer(dumper, false,
 oops_data, oops_data_sz, text_len);
err_type = ERR_TYPE_KERNEL_PANIC;
*oops_len = (u16) text_len;

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


[PATCH 2/8] Add version and timestamp to oops header

2013-04-10 Thread Aruna Balakrishnaiah
Introduce version and timestamp information in the oops header.
oops_log_info (oops header) holds version (to distinguish between old
and new format oops header), length of the oops text
(compressed or uncompressed) and timestamp.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |   57 +---
 1 file changed, 38 insertions(+), 19 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index e54a8b7..742735a 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -29,6 +29,13 @@
 /* Max bytes to read/write in one go */
 #define NVRW_CNT 0x20
 
+/*
+ * Set oops header version to distingush between old and new format header.
+ * lnx,oops-log partition max size is 4000, header version  4000 will
+ * help in identifying new header.
+ */
+#define OOPS_HDR_VERSION 5000
+
 static unsigned int nvram_size;
 static int nvram_fetch, nvram_store;
 static char nvram_buf[NVRW_CNT];   /* assume this is in the first 4GB */
@@ -67,6 +74,12 @@ static const char *pseries_nvram_os_partitions[] = {
NULL
 };
 
+struct oops_log_info {
+   u16 version;
+   u16 report_length;
+   u64 timestamp;
+} __attribute__((packed));
+
 static void oops_to_nvram(struct kmsg_dumper *dumper,
  enum kmsg_dump_reason reason);
 
@@ -83,28 +96,28 @@ static unsigned long last_unread_rtas_event;/* 
timestamp */
 
  * big_oops_buf[] holds the uncompressed text we're capturing.
  *
- * oops_buf[] holds the compressed text, preceded by a prefix.
- * The prefix is just a u16 holding the length of the compressed* text.
- * (*Or uncompressed, if compression fails.)  oops_buf[] gets written
- * to NVRAM.
+ * oops_buf[] holds the compressed text, preceded by a oops header.
+ * oops header has u16 holding the version of oops header (to differentiate
+ * between old and new format header) followed by u16 holding the length of
+ * the compressed* text (*Or uncompressed, if compression fails.) and u64
+ * holding the timestamp. oops_buf[] gets written to NVRAM.
  *
- * oops_len points to the prefix.  oops_data points to the compressed text.
+ * oops_log_info points to the header. oops_data points to the compressed text.
  *
  * +- oops_buf
- * |   +- oops_data
- * v   v
- * ++---+
- * | length| text  |
- * | (2 bytes) | (oops_data_sz bytes)  |
- * ++---+
+ * |   +- oops_data
+ * v   v
+ * +---+---+---++
+ * | version   | length| timestamp | text   |
+ * | (2 bytes) | (2 bytes) | (8 bytes) | (oops_data_sz bytes)   |
+ * +---+---+---++
  * ^
- * +- oops_len
+ * +- oops_log_info
  *
  * We preallocate these buffers during init to avoid kmalloc during oops/panic.
  */
 static size_t big_oops_buf_sz;
 static char *big_oops_buf, *oops_buf;
-static u16 *oops_len;
 static char *oops_data;
 static size_t oops_data_sz;
 
@@ -425,9 +438,8 @@ static void __init nvram_init_oops_partition(int 
rtas_partition_exists)
oops_log_partition.name);
return;
}
-   oops_len = (u16*) oops_buf;
-   oops_data = oops_buf + sizeof(u16);
-   oops_data_sz = oops_log_partition.size - sizeof(u16);
+   oops_data = oops_buf + sizeof(struct oops_log_info);
+   oops_data_sz = oops_log_partition.size - sizeof(struct oops_log_info);
 
/*
 * Figure compression (preceded by elimination of each line's n
@@ -555,6 +567,7 @@ error:
 /* Compress the text from big_oops_buf into oops_buf. */
 static int zip_oops(size_t text_len)
 {
+   struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf;
int zipped_len = nvram_compress(big_oops_buf, oops_data, text_len,
oops_data_sz);
if (zipped_len  0) {
@@ -562,7 +575,9 @@ static int zip_oops(size_t text_len)
pr_err(nvram: logging uncompressed oops/panic report\n);
return -1;
}
-   *oops_len = (u16) zipped_len;
+   oops_hdr-version = OOPS_HDR_VERSION;
+   oops_hdr-report_length = (u16) zipped_len;
+   oops_hdr-timestamp = get_seconds();
return 0;
 }
 
@@ -576,6 +591,7 @@ static int zip_oops(size_t text_len)
 static void oops_to_nvram(struct kmsg_dumper *dumper,
  enum kmsg_dump_reason reason)
 {
+   struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf;
static unsigned int oops_count = 0;
static bool

[PATCH 3/8] Introduce generic read function to read nvram-partitions

2013-04-10 Thread Aruna Balakrishnaiah
Introduce generic read function to read nvram partitions other than rtas.
nvram_read_error_log will be retained which is used to read rtas partition
from rtasd. nvram_read_partition is the generic read function to read from
any nvram partition.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |   34 +++-
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 742735a..6701b71 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -293,34 +293,37 @@ int nvram_write_error_log(char * buff, int length,
return rc;
 }
 
-/* nvram_read_error_log
+/* nvram_read_partition
  *
- * Reads nvram for error log for at most 'length'
+ * Reads nvram partition for at most 'length'
  */
-int nvram_read_error_log(char * buff, int length,
- unsigned int * err_type, unsigned int * error_log_cnt)
+int nvram_read_partition(struct nvram_os_partition *part, char *buff,
+   int length, unsigned int *err_type,
+   unsigned int *error_log_cnt)
 {
int rc;
loff_t tmp_index;
struct err_log_info info;

-   if (rtas_log_partition.index == -1)
+   if (part-index == -1)
return -1;
 
-   if (length  rtas_log_partition.size)
-   length = rtas_log_partition.size;
+   if (length  part-size)
+   length = part-size;
 
-   tmp_index = rtas_log_partition.index;
+   tmp_index = part-index;
 
rc = ppc_md.nvram_read((char *)info, sizeof(struct err_log_info), 
tmp_index);
if (rc = 0) {
-   printk(KERN_ERR nvram_read_error_log: Failed nvram_read 
(%d)\n, rc);
+   printk(KERN_ERR nvram_read_partition: 
+   Failed nvram_read (%d)\n, rc);
return rc;
}
 
rc = ppc_md.nvram_read(buff, length, tmp_index);
if (rc = 0) {
-   printk(KERN_ERR nvram_read_error_log: Failed nvram_read 
(%d)\n, rc);
+   printk(KERN_ERR nvram_read_partition: 
+   Failed nvram_read (%d)\n, rc);
return rc;
}
 
@@ -330,6 +333,17 @@ int nvram_read_error_log(char * buff, int length,
return 0;
 }
 
+/* nvram_read_error_log
+ *
+ * Reads nvram for error log for at most 'length'
+ */
+int nvram_read_error_log(char *buff, int length,
+   unsigned int *err_type, unsigned int *error_log_cnt)
+{
+   return nvram_read_partition(rtas_log_partition, buff, length,
+   err_type, error_log_cnt);
+}
+
 /* This doesn't actually zero anything, but it sets the event_logged
  * word to tell that this event is safely in syslog.
  */

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


[PATCH 4/8] Read/Write oops nvram partition via pstore

2013-04-10 Thread Aruna Balakrishnaiah
This patch exploits pstore infrastructure in power systems.
IBM's system p machines provide persistent storage for LPARs
through NVRAM. NVRAM's lnx,oops-log partition is used to log
oops messages. In case pstore registration fails it will
fall back to kmsg_dump mechanism.

This patch will read/write the oops messages from/to this
partition via pstore.

Signed-off-by: Jim Keniston jkeni...@us.ibm.com
Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |  145 
 1 file changed, 145 insertions(+)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 6701b71..82d32a2 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -18,6 +18,7 @@
 #include linux/spinlock.h
 #include linux/slab.h
 #include linux/kmsg_dump.h
+#include linux/pstore.h
 #include linux/ctype.h
 #include linux/zlib.h
 #include asm/uaccess.h
@@ -87,6 +88,25 @@ static struct kmsg_dumper nvram_kmsg_dumper = {
.dump = oops_to_nvram
 };
 
+static int nvram_pstore_open(struct pstore_info *psi);
+
+static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type,
+   int *count, struct timespec *time, char **buf,
+   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 size,
+   struct pstore_info *psi);
+
+static struct pstore_info nvram_pstore_info = {
+   .owner = THIS_MODULE,
+   .name = nvram,
+   .open = nvram_pstore_open,
+   .read = nvram_pstore_read,
+   .write = nvram_pstore_write,
+};
+
 /* See clobbering_unread_rtas_event() */
 #define NVRAM_RTAS_READ_TIMEOUT 5  /* seconds */
 static unsigned long last_unread_rtas_event;   /* timestamp */
@@ -121,6 +141,13 @@ static char *big_oops_buf, *oops_buf;
 static char *oops_data;
 static size_t oops_data_sz;
 
+#ifdef CONFIG_PSTORE
+static enum pstore_type_id nvram_type_ids[] = {
+   PSTORE_TYPE_DMESG,
+   -1
+};
+static int read_type;
+#endif
 /* Compression parameters */
 #define COMPR_LEVEL 6
 #define WINDOW_BITS 12
@@ -455,6 +482,23 @@ 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);
 
+   nvram_pstore_info.buf = oops_data;
+   nvram_pstore_info.bufsize = oops_data_sz;
+
+   rc = pstore_register(nvram_pstore_info);
+
+   if (rc != 0) {
+   pr_err(nvram: pstore_register() failed, defaults to 
+   kmsg_dump; returned %d\n, rc);
+   goto kmsg_dump;
+   } else {
+   /*TODO: Support compression when pstore is configured */
+   pr_info(nvram: Compression of oops text supported only when 
+   pstore is not configured);
+   return;
+   }
+
+kmsg_dump:
/*
 * Figure compression (preceded by elimination of each line's n
 * severity prefix) will reduce the oops/panic report to at most
@@ -663,3 +707,104 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
 
spin_unlock_irqrestore(lock, flags);
 }
+
+#ifdef CONFIG_PSTORE
+static int nvram_pstore_open(struct pstore_info *psi)
+{
+   read_type = -1;
+   return 0;
+}
+
+/*
+ * Called by pstore_dump() when an oops or panic report is logged to the printk
+ * buffer. @size bytes have been written to oops_buf, starting after the
+ * oops_log_info header.
+ */
+static int nvram_pstore_write(enum pstore_type_id type,
+   enum kmsg_dump_reason reason,
+   u64 *id, unsigned int part, int count,
+   size_t size, struct pstore_info *psi)
+{
+   struct oops_log_info *oops_hdr = (struct oops_log_info *) oops_buf;
+
+   /* part 1 has the recent messages from printk buffer */
+   if (part  1 || clobbering_unread_rtas_event())
+   return -1;
+
+   BUG_ON(type != PSTORE_TYPE_DMESG);
+   BUG_ON(sizeof(*oops_hdr) + size  oops_log_partition.size);
+   oops_hdr-version = OOPS_HDR_VERSION;
+   oops_hdr-report_length = (u16) size;
+   oops_hdr-timestamp = get_seconds();
+   (void) nvram_write_os_partition(oops_log_partition, oops_buf,
+   (int) (sizeof(*oops_hdr) + size), ERR_TYPE_KERNEL_PANIC,
+   count);
+   *id = part;
+
+   return 0;
+}
+
+/*
+ * Reads the oops/panic report.
+ * Returns the length of the data we read from each partition.
+ * Returns 0 if we've been called before.
+ */
+static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type,
+   int *count

[PATCH 6/8] Distinguish between a os-partition and non-os partition

2013-04-10 Thread Aruna Balakrishnaiah
Introduce os_partition member in nvram_os_partition structure
to identify if the partition is an os partition or not. This
will be useful to handle non-os partitions of-config and
common in subsequent patches.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index d420b1d..6a3a7cd 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -53,20 +53,23 @@ struct nvram_os_partition {
int min_size;   /* minimum acceptable size (0 means req_size) */
long size;  /* size of data portion (excluding err_log_info) */
long index; /* offset of data portion of partition */
+   bool os_partition; /* partition initialized by OS, not FW */
 };
 
 static struct nvram_os_partition rtas_log_partition = {
.name = ibm,rtas-log,
.req_size = 2079,
.min_size = 1055,
-   .index = -1
+   .index = -1,
+   .os_partition = true
 };
 
 static struct nvram_os_partition oops_log_partition = {
.name = lnx,oops-log,
.req_size = 4000,
.min_size = 2000,
-   .index = -1
+   .index = -1,
+   .os_partition = true
 };
 
 static const char *pseries_nvram_os_partitions[] = {

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


[PATCH 7/8] Read of-config partition via pstore

2013-04-10 Thread Aruna Balakrishnaiah
This patch exploits pstore infrastructure to read the details
from NVRAM's of-config partition.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |   58 ++--
 fs/pstore/inode.c  |3 ++
 include/linux/pstore.h |1 +
 3 files changed, 52 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 6a3a7cd..b65a670 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -78,6 +78,14 @@ static const char *pseries_nvram_os_partitions[] = {
NULL
 };
 
+#ifdef CONFIG_PSTORE
+static struct nvram_os_partition of_config_partition = {
+   .name = of-config,
+   .index = -1,
+   .os_partition = false
+};
+#endif
+
 struct oops_log_info {
u16 version;
u16 report_length;
@@ -148,6 +156,7 @@ static size_t oops_data_sz;
 static enum pstore_type_id nvram_type_ids[] = {
PSTORE_TYPE_DMESG,
PSTORE_TYPE_RTAS,
+   PSTORE_TYPE_OF,
-1
 };
 static int read_type;
@@ -350,11 +359,15 @@ int nvram_read_partition(struct nvram_os_partition *part, 
char *buff,
 
tmp_index = part-index;
 
-   rc = ppc_md.nvram_read((char *)info, sizeof(struct err_log_info), 
tmp_index);
-   if (rc = 0) {
-   printk(KERN_ERR nvram_read_partition: 
-   Failed nvram_read (%d)\n, rc);
-   return rc;
+   if (part-os_partition) {
+   rc = ppc_md.nvram_read((char *)info,
+   sizeof(struct err_log_info),
+   tmp_index);
+   if (rc = 0) {
+   printk(KERN_ERR nvram_read_partition: 
+   Failed nvram_read (%d)\n, rc);
+   return rc;
+   }
}
 
rc = ppc_md.nvram_read(buff, length, tmp_index);
@@ -364,8 +377,10 @@ int nvram_read_partition(struct nvram_os_partition *part, 
char *buff,
return rc;
}
 
-   *error_log_cnt = info.seq_num;
-   *err_type = info.error_type;
+   if (part-os_partition) {
+   *error_log_cnt = info.seq_num;
+   *err_type = info.error_type;
+   }
 
return 0;
 }
@@ -755,7 +770,7 @@ static int nvram_pstore_write(enum pstore_type_id type,
 }
 
 /*
- * Reads the oops/panic report and ibm,rtas-log partition.
+ * Reads the oops/panic report, rtas-log and of-config partition.
  * Returns the length of the data we read from each partition.
  * Returns 0 if we've been called before.
  */
@@ -764,9 +779,11 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
struct pstore_info *psi)
 {
struct oops_log_info *oops_hdr;
-   unsigned int err_type, id_no;
+   unsigned int err_type, id_no, size = 0;
struct nvram_os_partition *part = NULL;
char *buff = NULL;
+   int sig = 0;
+   loff_t p;
 
read_type++;
 
@@ -781,10 +798,29 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
time-tv_sec = last_rtas_event;
time-tv_nsec = 0;
break;
+   case PSTORE_TYPE_OF:
+   sig = NVRAM_SIG_OF;
+   part = of_config_partition;
+   *type = PSTORE_TYPE_OF;
+   *id = PSTORE_TYPE_OF;
+   time-tv_sec = 0;
+   time-tv_nsec = 0;
+   break;
default:
return 0;
}
 
+   if (!part-os_partition) {
+   p = nvram_find_partition(part-name, sig, size);
+   if (p = 0) {
+   pr_err(nvram: Failed to find partition %s, 
+   err %d\n, part-name, (int)p);
+   return 0;
+   }
+   part-index = p;
+   part-size = size;
+   }
+
buff = kmalloc(part-size, GFP_KERNEL);
 
if (!buff)
@@ -796,7 +832,9 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
}
 
*count = 0;
-   *id = id_no;
+
+   if (part-os_partition)
+   *id = id_no;
 
if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) {
oops_hdr = (struct oops_log_info *)buff;
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index 59b1454..c3d1846 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -327,6 +327,9 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, 
u64 id, int count,
case PSTORE_TYPE_RTAS:
sprintf(name, rtas-%s-%lld, psname, id);
break;
+   case PSTORE_TYPE_OF:
+   sprintf(name, of-%s-%lld, psname, id);
+   break;
case PSTORE_TYPE_UNKNOWN:
sprintf(name

[PATCH 8/8] Read common partition via pstore

2013-04-10 Thread Aruna Balakrishnaiah
This patch exploits pstore infrastructure to read the details
from NVRAM's common partition.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |   17 -
 fs/pstore/inode.c  |3 +++
 include/linux/pstore.h |1 +
 3 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index b65a670..542dc7e 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -84,6 +84,12 @@ static struct nvram_os_partition of_config_partition = {
.index = -1,
.os_partition = false
 };
+
+static struct nvram_os_partition common_partition = {
+   .name = common,
+   .index = -1,
+   .os_partition = false
+};
 #endif
 
 struct oops_log_info {
@@ -157,6 +163,7 @@ static enum pstore_type_id nvram_type_ids[] = {
PSTORE_TYPE_DMESG,
PSTORE_TYPE_RTAS,
PSTORE_TYPE_OF,
+   PSTORE_TYPE_COMMON,
-1
 };
 static int read_type;
@@ -770,7 +777,7 @@ static int nvram_pstore_write(enum pstore_type_id type,
 }
 
 /*
- * Reads the oops/panic report, rtas-log and of-config partition.
+ * Reads the oops/panic report, rtas-log, of-config and common partition.
  * Returns the length of the data we read from each partition.
  * Returns 0 if we've been called before.
  */
@@ -806,6 +813,14 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
time-tv_sec = 0;
time-tv_nsec = 0;
break;
+   case PSTORE_TYPE_COMMON:
+   sig = NVRAM_SIG_SYS;
+   part = common_partition;
+   *type = PSTORE_TYPE_COMMON;
+   *id = PSTORE_TYPE_COMMON;
+   time-tv_sec = 0;
+   time-tv_nsec = 0;
+   break;
default:
return 0;
}
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index c3d1846..11cae64 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -330,6 +330,9 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, 
u64 id, int count,
case PSTORE_TYPE_OF:
sprintf(name, of-%s-%lld, psname, id);
break;
+   case PSTORE_TYPE_COMMON:
+   sprintf(name, common-%s-%lld, psname, id);
+   break;
case PSTORE_TYPE_UNKNOWN:
sprintf(name, unknown-%s-%lld, psname, id);
break;
diff --git a/include/linux/pstore.h b/include/linux/pstore.h
index a23d7d2..08224c2 100644
--- a/include/linux/pstore.h
+++ b/include/linux/pstore.h
@@ -38,6 +38,7 @@ enum pstore_type_id {
/* PPC64 partition types */
PSTORE_TYPE_RTAS= 10,
PSTORE_TYPE_OF  = 11,
+   PSTORE_TYPE_COMMON  = 12,
PSTORE_TYPE_UNKNOWN = 255
 };
 

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


[PATCH 5/8] Read rtas partition via pstore

2013-04-10 Thread Aruna Balakrishnaiah
This patch exploits pstore infrastructure to read the details
from NVRAM's rtas partition.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |   33 +---
 fs/pstore/inode.c  |3 +++
 include/linux/pstore.h |2 ++
 3 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 82d32a2..d420b1d 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -144,9 +144,11 @@ static size_t oops_data_sz;
 #ifdef CONFIG_PSTORE
 static enum pstore_type_id nvram_type_ids[] = {
PSTORE_TYPE_DMESG,
+   PSTORE_TYPE_RTAS,
-1
 };
 static int read_type;
+static unsigned long last_rtas_event;
 #endif
 /* Compression parameters */
 #define COMPR_LEVEL 6
@@ -315,8 +317,13 @@ int nvram_write_error_log(char * buff, int length,
 {
int rc = nvram_write_os_partition(rtas_log_partition, buff, length,
err_type, error_log_cnt);
-   if (!rc)
+   if (!rc) {
last_unread_rtas_event = get_seconds();
+#ifdef CONFIG_PSTORE
+   last_rtas_event = get_seconds();
+#endif
+   }
+
return rc;
 }
 
@@ -745,7 +752,7 @@ static int nvram_pstore_write(enum pstore_type_id type,
 }
 
 /*
- * Reads the oops/panic report.
+ * Reads the oops/panic report and ibm,rtas-log partition.
  * Returns the length of the data we read from each partition.
  * Returns 0 if we've been called before.
  */
@@ -765,6 +772,12 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
part = oops_log_partition;
*type = PSTORE_TYPE_DMESG;
break;
+   case PSTORE_TYPE_RTAS:
+   part = rtas_log_partition;
+   *type = PSTORE_TYPE_RTAS;
+   time-tv_sec = last_rtas_event;
+   time-tv_nsec = 0;
+   break;
default:
return 0;
}
@@ -781,11 +794,17 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
 
*count = 0;
*id = id_no;
-   oops_hdr = (struct oops_log_info *)buff;
-   *buf = buff + sizeof(*oops_hdr);
-   time-tv_sec = oops_hdr-timestamp;
-   time-tv_nsec = 0;
-   return oops_hdr-report_length;
+
+   if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) {
+   oops_hdr = (struct oops_log_info *)buff;
+   *buf = buff + sizeof(*oops_hdr);
+   time-tv_sec = oops_hdr-timestamp;
+   time-tv_nsec = 0;
+   return oops_hdr-report_length;
+   }
+
+   *buf = buff;
+   return part-size;
 }
 #else
 static int nvram_pstore_open(struct pstore_info *psi)
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index e4bcb2c..59b1454 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -324,6 +324,9 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, 
u64 id, int count,
case PSTORE_TYPE_MCE:
sprintf(name, mce-%s-%lld, psname, id);
break;
+   case PSTORE_TYPE_RTAS:
+   sprintf(name, rtas-%s-%lld, psname, id);
+   break;
case PSTORE_TYPE_UNKNOWN:
sprintf(name, unknown-%s-%lld, psname, id);
break;
diff --git a/include/linux/pstore.h b/include/linux/pstore.h
index 75d0176..4eb94c9 100644
--- a/include/linux/pstore.h
+++ b/include/linux/pstore.h
@@ -35,6 +35,8 @@ enum pstore_type_id {
PSTORE_TYPE_MCE = 1,
PSTORE_TYPE_CONSOLE = 2,
PSTORE_TYPE_FTRACE  = 3,
+   /* PPC64 partition types */
+   PSTORE_TYPE_RTAS= 10,
PSTORE_TYPE_UNKNOWN = 255
 };
 

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


Re: [PATCH 00/11] Add compression support to pstore

2013-08-05 Thread Aruna Balakrishnaiah

Hi Tony,

Thank you very much for testing my patches.

On Saturday 03 August 2013 03:42 AM, Tony Luck wrote:

A quick experiment to use your patchset - but with compression
disabled by tweaking this line in pstore_dump():

 zipped_len = -1; //zip_data(dst, hsize + len);

turned out well. This kernel dumps uncompressed dmesg blobs into pstore
and gets them back out again.  So it seems likely that the problems are
someplace in the compression/decompression code.


A quick look on my code suggests that problem could be in this part
of code.

In pstore_dump:

 if (zipped_len  0) {
dst = psinfo-buf;
hsize = sprintf(dst, %s#%d Part%d\n,
why, oopscount, part);
size = psinfo-bufsize - hsize;
dst += hsize;
compressed = false;

if (!kmsg_dump_get_buffer(dumper, true, dst,
size, len))
break;
} else {
compressed = true;
 ---   len = zipped_len;
}

I am returning zipped_len as the length of the compressed data (which also
has hsize compressed). So returning hsize + len in pstore_write callback
will be wrong. It should just have been zipped_len. This might be adding
junk characters.

Can you please replace this hunk with:

if (zipped_len  0) {
pr_err(Compression failed\n);
dst = psinfo-buf;
hsize = sprintf(dst, %s#%d Part%d\n,
why, oopscount, part);
size = psinfo-bufsize - hsize;
dst += hsize;
compressed = false;

if (!kmsg_dump_get_buffer(dumper, true, dst,
size, len))
break;
total_len = hsize + len;
} else {
compressed = true;
total_len = zipped_len;
}

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

total += total_len;
part++;

With the above hunk, atleast I dont see junk characters at the end in power.

I apologise, since I do not have the suitable machine to test this I am
not able to reproduce the scenarios you are stating. I need your help
in testing this.

- Aruna


-Tony
___
Linuxppc-dev mailing list
linuxppc-...@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev



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


Re: [PATCH 00/11] Add compression support to pstore

2013-08-05 Thread Aruna Balakrishnaiah
   je
8126d368 pstore_mkfile+0xd8
8126d314:   44 39 71 18 cmp
%r14d,0x18(%rcx)GP fault here
8126d318:   75 ee   jne
8126d308 pstore_mkfile+0x78
8126d31a:   4c 39 69 20 cmp%r13,0x20(%rcx)
8126d31e:   75 e8   jne
8126d308 pstore_mkfile+0x78
8126d320:   48 39 59 10 cmp%rbx,0x10(%rcx)
8126d324:   75 e2   jne
8126d308 pstore_mkfile+0x78
8126d326:   48 89 c6mov%rax,%rsi
8126d329:   48 c7 c7 e8 a7 0a 82mov$0x820aa7e8,%rdi
8126d330:   e8 1b 0d 39 00  callq
815fe050 _raw_spin_unlock_irqrestore

Booting a vanilla v3.11-rc4 kernel I can see the files pstore - but
they still seem to have
corruption/missing data at the end when I decode with openssl zlib -d :-(

So start by peering at the path that I applied to make sure I didn't mess up.


Strangely I am not ablereproduce this on power or on system-x. With system-x I 
was
able to loga single record and decompression did not give me any junk characters 
at the

end. Not sure if its the header which is missing.If it was I should have 
encountered
same issue on Power too. Please give a final try with the patch I have attached 
and I

will dig into this more tomorrow. Patch to be applied on top of my patch series
(without your fix patch).


- Aruna


-Tony


commit 35b489152ae8f673fa79e7eeffc0bc8503c608b6
Author: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Date:   Tue Aug 6 00:08:35 2013 +0530

pstore: fix for the junk characters at the end

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com

diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 8f3e5f0..3446c99 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -283,7 +283,7 @@ static void pstore_dump(struct kmsg_dumper *dumper,
 		unsigned long size, big_buf_sz;
 		int hsize = 0;
 		int zipped_len = -1;
-		size_t len;
+		size_t len, total_len;
 		bool compressed;
 
 		big_buf_sz = (psinfo-bufsize * 100) / 45;
@@ -293,9 +293,8 @@ static void pstore_dump(struct kmsg_dumper *dumper,
 			hsize = sprintf(dst, %s#%d Part%d\n, why,
 			oopscount, part);
 			size = big_buf_sz - hsize;
-			dst += hsize;
 
-			if (!kmsg_dump_get_buffer(dumper, true, dst,
+			if (!kmsg_dump_get_buffer(dumper, true, dst + hsize,
 size, len))
 break;
 
@@ -313,17 +312,18 @@ static void pstore_dump(struct kmsg_dumper *dumper,
 			if (!kmsg_dump_get_buffer(dumper, true, dst,
 size, len))
 break;
+			total_len = hsize + len;
 		} else {
 			compressed = true;
-			len = zipped_len;
+			total_len = zipped_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)) {


Re: [PATCH 00/11] Add compression support to pstore

2013-08-06 Thread Aruna Balakrishnaiah

On Wednesday 07 August 2013 05:06 AM, Tony Luck wrote:

On Mon, Aug 5, 2013 at 2:20 PM, Tony Luck tony.l...@gmail.com wrote:

Still have problems booting if there are any compressed images in ERST
to be inflated.

So I took another look at this part of the code ... and saw a couple of issues:

 while ((size = psi-read(id, type, count, time, buf, compressed,
 psi))  0) {
 if (compressed  (type == PSTORE_TYPE_DMESG)) {
 big_buf_sz = (psinfo-bufsize * 100) / 45;
 big_buf = allocate_buf_for_decompression(big_buf_sz);

 if (big_buf || stream.workspace)

Did you mean  here rather that ||?


Yes right, it should be .


 unzipped_len = pstore_decompress(buf, big_buf,
 size, big_buf_sz);

Need an else here to set unzipped_len to -1 (or set it to -1 down
at the bottom of the loop ready for next time around.

 if (unzipped_len  0) {
 buf = big_buf;

This sets us up for problems.  First, you just overwrote the address
of the buffer that psi-read allocated - so we have a memory leak. But
worse than that we now double free the same buffer below when we
kfree(buf) and then kfree(big_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,
   compressed, (size_t)size, time, psi);
 kfree(buf);
 kfree(stream.workspace);
 kfree(big_buf);
 buf = NULL;
 stream.workspace = NULL;
 big_buf = NULL;
 if (rc  (rc != -EEXIST || !quiet))
 failed++;
 }


See attached patch that fixes these - but the code still looks like it
could be cleaned up a bit more.


The patch looks right. I will clean it up. Does the issue still persist after 
this?


-Tony


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


Re: [PATCH 00/11] Add compression support to pstore

2013-08-06 Thread Aruna Balakrishnaiah

Hi Tony,

On Wednesday 07 August 2013 08:55 AM, Tony Luck wrote:

On Tue, Aug 6, 2013 at 6:58 PM, Aruna Balakrishnaiah
ar...@linux.vnet.ibm.com wrote:

The patch looks right. I will clean it up. Does the issue still persist
after this?

Things seem to be working - but testing has hardly been extensive (just
a couple of forced panics).

I do have one other question. In this code:


  if (compressed  (type == PSTORE_TYPE_DMESG)) {
  big_buf_sz = (psinfo-bufsize * 100) / 45;

Where does the magic multiply by 1.45 come from?  Is that always enough
for the decompression of dmesg type data to succeed?


I had this in my cover letter of the series, posting the same from it

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  which achieved a
significant compression of 12 % of uncompressed buffer size tried upto 36k.
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.


The significant compression that I have mentioned had repeated occurrences in 
the
text. When I tried with plain text I saw compression of around 45% with 
compression
parameters I have used.

If the record size is fixed across all the backends then it would be easy to 
come
up with a pre defined set of compression parameters as well as the buffer size 
of
compressed/decompressed data based on experiments. In power as of now, the 
maximum size
of the record is 4k. So compression support on power was provided with multiply 
(100/45)
considering the maximum record size to be 4k.

How is it with erst and efivars?

- Aruna


-Tony



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


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

2013-08-26 Thread Aruna Balakrishnaiah

On Friday 23 August 2013 04:47 AM, Luck, Tony wrote:

1[  383.209057] RIP  [813d3946] sysrq_handle_crash+0x16/0x20
4[  383.209057]  RSP 88006f551e80
4[  383.209057] CR2: 
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
linuxppc-...@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev



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


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

2013-08-27 Thread Aruna Balakrishnaiah

On Friday 23 August 2013 04:34 AM, Seiji Aguchi wrote:



-Original Message-
From: linux-kernel-ow...@vger.kernel.org 
[mailto:linux-kernel-ow...@vger.kernel.org] On Behalf Of Aruna Balakrishnaiah
Sent: Friday, August 16, 2013 9:18 AM
To: linuxppc-...@ozlabs.org; tony.l...@intel.com; linux-kernel@vger.kernel.org; 
keesc...@chromium.org
Cc: jkeni...@linux.vnet.ibm.com; ana...@in.ibm.com; b...@kernel.crashing.org; 
cbouatmai...@gmail.com;
mah...@linux.vnet.ibm.com; ccr...@android.com
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
linuxppc-...@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev



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


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

2013-08-16 Thread Aruna Balakrishnaiah
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(-)

-- 

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


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

2013-08-16 Thread Aruna Balakrishnaiah
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 ar...@linux.vnet.ibm.com
---
 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

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

2013-08-16 Thread Aruna Balakrishnaiah
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 ar...@linux.vnet.ibm.com
---
 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];

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


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

2013-08-16 Thread Aruna Balakrishnaiah
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 ar...@linux.vnet.ibm.com
---
 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 voidpstore_set_kmsg_bytes(int);
 extern voidpstore_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);

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


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

2013-08-16 Thread Aruna Balakrishnaiah
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 ar...@linux.vnet.ibm.com
---
 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;
+   boolcompressed;
 
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

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

2013-08-16 Thread Aruna Balakrishnaiah
(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 ar...@linux.vnet.ibm.com
---
 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

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

2013-08-16 Thread Aruna Balakrishnaiah
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 ar...@linux.vnet.ibm.com
---
 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;

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


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

2013-08-16 Thread Aruna Balakrishnaiah
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 ar...@linux.vnet.ibm.com
---
 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);

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


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

2013-08-16 Thread Aruna Balakrishnaiah
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 ar...@linux.vnet.ibm.com
---
 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;
}
 

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


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

2013-08-16 Thread Aruna Balakrishnaiah
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 ar...@linux.vnet.ibm.com
---
 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

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


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

2013-08-16 Thread Aruna Balakrishnaiah
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 ar...@linux.vnet.ibm.com
---
 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

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

2013-08-16 Thread Aruna Balakrishnaiah
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 ar...@linux.vnet.ibm.com
---
 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;
boolcompressed;
+   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++;
}

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


[PATCH 03/11] pstore/Kconfig: Select ZLIB_DEFLATE and ZLIB_INFLATE when PSTORE is selected

2013-07-15 Thread Aruna Balakrishnaiah
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 ar...@linux.vnet.ibm.com
---
 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

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


[PATCH 00/11] Add compression support to pstore

2013-07-15 Thread Aruna Balakrishnaiah
The patchset adds compression 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  which achieved a
significant compression of 12 % of uncompressed buffer size tried upto 36k.
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.
On Intel have only tested with erst backend.

Efi-pstore and RAM persistent buffer requires testing.


---

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: Provide 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 |  131 
 drivers/acpi/apei/erst.c   |   21 ++-
 drivers/firmware/efi/efi-pstore.c  |   27 +++-
 fs/pstore/Kconfig  |2 
 fs/pstore/inode.c  |9 +
 fs/pstore/internal.h   |5 -
 fs/pstore/platform.c   |  214 ++--
 fs/pstore/ram.c|   41 +-
 include/linux/pstore.h |6 -
 9 files changed, 307 insertions(+), 149 deletions(-)

-- 

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


[PATCH 02/11] pstore: Add new argument 'compressed' in pstore write callback

2013-07-15 Thread Aruna Balakrishnaiah
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 ar...@linux.vnet.ibm.com
---
 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 07c3c07..c5c9d78 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -613,7 +613,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
  *
@@ -624,7 +624,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

[PATCH 01/11] powerpc/pseries: Remove (de)compression in nvram with pstore enabled

2013-07-15 Thread Aruna Balakrishnaiah
(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 ar...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |   40 
 1 file changed, 40 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 9f8671a..07c3c07 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -640,27 +640,6 @@ 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);
@@ -751,25 +730,6 @@ read_partition:
if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) {
oops_hdr = (struct oops_log_info *)buff;
*buf = buff + sizeof(*oops_hdr);
-
-   if (err_type == ERR_TYPE_KERNEL_PANIC_GZ) {
-   big_buff = kmalloc(big_oops_buf_sz, GFP_KERNEL);
-   if (!big_buff)
-   return -ENOMEM;
-
-   rc = unzip_oops(buff, big_buff);
-
-   if (rc != 0) {
-   kfree(buff);
-   kfree(big_buff);
-   goto read_partition;
-   }
-
-   oops_hdr = (struct oops_log_info *)big_buff;
-   *buf = big_buff + sizeof(*oops_hdr);
-   kfree(buff);
-   }
-
time-tv_sec = oops_hdr-timestamp;
time-tv_nsec = 0;
return oops_hdr-report_length;

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


[PATCH 05/11] pstore: Introduce new argument 'compressed' in the read callback

2013-07-15 Thread Aruna Balakrishnaiah
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 ar...@linux.vnet.ibm.com
---
 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 c5c9d78..1ddc266 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -658,7 +658,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 5b95524..b1faf25 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -404,6 +404,7 @@ void pstore_get_records(int quiet)
enum pstore_type_id type;
struct timespec time;
int failed = 0, rc;
+   boolcompressed;
 
if (!psi)
return;
@@ -412,7 +413,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

[PATCH 07/11] pstore: Add file extension to pstore file if compressed

2013-07-15 Thread Aruna Balakrishnaiah
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 ar...@linux.vnet.ibm.com
---
 fs/pstore/inode.c|9 +
 fs/pstore/internal.h |5 +++--
 fs/pstore/platform.c |4 +++-
 3 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index 71bf5f4..259e92c 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);
@@ -328,7 +329,7 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, 
u64 id, int count,
break;
case PSTORE_TYPE_PPC_RTAS:
sprintf(name, rtas-%s-%lld, psname, id);
-   break;
+   break;
case PSTORE_TYPE_PPC_OF:
sprintf(name, powerpc-ofw-%s-%lld, psname, id);
break;
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 voidpstore_set_kmsg_bytes(int);
 extern voidpstore_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 119db58..8f3e5f0 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -481,13 +481,15 @@ void pstore_get_records(int quiet)
if (unzipped_len  0) {
buf = big_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);
kfree(buf);
kfree(stream.workspace);
kfree(big_buf);

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


[PATCH 06/11] pstore: Provide decompression support to pstore

2013-07-15 Thread Aruna Balakrishnaiah
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 ar...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |   59 -
 fs/pstore/platform.c   |   77 
 2 files changed, 76 insertions(+), 60 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 1ddc266..78c6f45 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -539,65 +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 unzip_oops(char *oops_buf, char *big_buf)
-{
-   struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf;
-   u64 timestamp = oops_hdr-timestamp;
-   char *big_oops_data = NULL;
-   char *oops_data_buf = NULL;
-   size_t big_oops_data_sz;
-   int unzipped_len;
-
-   big_oops_data = big_buf + sizeof(struct oops_log_info);
-   big_oops_data_sz = big_oops_buf_sz - sizeof(struct oops_log_info);
-   oops_data_buf = oops_buf + sizeof(struct oops_log_info);
-
-   unzipped_len = nvram_decompress(oops_data_buf, big_oops_data,
-   oops_hdr-report_length,
-   big_oops_data_sz);
-
-   if (unzipped_len  0) {
-   pr_err(nvram: decompression failed; returned %d\n,
-   unzipped_len);
-   return -1;
-   }
-   oops_hdr = (struct oops_log_info *)big_buf;
-   oops_hdr-version = OOPS_HDR_VERSION;
-   oops_hdr-report_length = (u16) unzipped_len;
-   oops_hdr-timestamp = timestamp;
-   return 0;
-}
-
 static int nvram_pstore_open(struct pstore_info *psi)
 {
/* Reset the iterator to start reading partitions again */
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index b1faf25..119db58 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -198,6 +198,59 @@ static char *allocate_buf_for_compression(unsigned long 
big_buf_sz)
 
return big_buf;
 }
+
+static char *allocate_buf_for_decompression(unsigned long size)
+{
+   char *big_buf;
+
+   big_buf = kmalloc(size, GFP_KERNEL);
+   if (big_buf) {
+   stream.workspace = kmalloc(zlib_inflate_workspacesize(),
+   GFP_KERNEL);
+   if (!stream.workspace) {
+   pr_err(pstore: No memory for decompression workspace; 
+   skipping decompression\n);
+   kfree(big_buf);
+   big_buf = NULL;
+   }
+   } else {
+   pr_err(No memory for decompressed data; 
+   skipping decompression\n);
+   stream.workspace = NULL;
+   }
+
+   return big_buf;
+}
+
+/* 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;
+}
 /*
  * callback from kmsg_dump. (s2,l2) has the most recently
  * written bytes, older bytes are in (s1,l1). Save as much
@@ -398,12 +451,14 @@ void pstore_get_records(int quiet)
 {
struct pstore_info *psi = psinfo;
char*buf = NULL;
-   ssize_t size;
+   char*big_buf = NULL;
+   ssize_t size, big_buf_sz;
u64

[PATCH 04/11] pstore: Add compression support to pstore

2013-07-15 Thread Aruna Balakrishnaiah
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 ar...@linux.vnet.ibm.com
---
 fs/pstore/platform.c |  124 ++
 1 file changed, 115 insertions(+), 9 deletions(-)

diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 20fa686..5b95524 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,12 @@ 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;
+
 /* How much of the console log to snapshot */
 static unsigned long kmsg_bytes = 10240;
 
@@ -117,6 +124,80 @@ 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;
+}
+
+/* Compress the text from dst into psinfo-buf. */
+static int zip_data(char *dst, size_t text_len)
+{
+   int zipped_len = pstore_compress(dst, psinfo-buf, text_len,
+psinfo-bufsize);
+
+   kfree(dst);
+   kfree(stream.workspace);
+   if (zipped_len  0) {
+   pr_err(pstore: compression failed; returned %d\n, zipped_len);
+   pr_err(pstore: logging uncompressed oops/panic report\n);
+   return -1;
+   }
+
+   return zipped_len;
+}
+
+static char *allocate_buf_for_compression(unsigned long big_buf_sz)
+{
+   char *big_buf;
+
+   big_buf = kmalloc(big_buf_sz, GFP_KERNEL);
+   if (big_buf) {
+   stream.workspace = kmalloc(zlib_deflate_workspacesize(
+   WINDOW_BITS, MEM_LEVEL), GFP_KERNEL);
+   if (!stream.workspace) {
+   pr_err(pstore: No memory for compression workspace; 
+   skipping compression\n);
+   kfree(big_buf);
+   big_buf = NULL;
+   }
+   } else {
+   pr_err(No memory for uncompressed data; 
+   skipping compression\n);
+   stream.workspace = NULL;
+   }
+
+   return big_buf;
+}
 /*
  * callback from kmsg_dump. (s2,l2) has the most recently
  * written bytes, older bytes are in (s1,l1). Save as much
@@ -146,18 +227,43 @@ static void pstore_dump(struct kmsg_dumper *dumper,
oopscount++;
while (total  kmsg_bytes) {
char *dst;
-   unsigned long size;
-   int hsize;
+   unsigned long size, big_buf_sz;
+   int hsize = 0;
+   int zipped_len = -1;
size_t len;
-   bool compressed = false;
+   bool compressed;
+
+   big_buf_sz = (psinfo-bufsize * 100) / 45;
+   dst = allocate_buf_for_compression(big_buf_sz);
 
-   dst = psinfo-buf;
-   hsize = sprintf(dst, %s#%d Part%d\n, why, oopscount, part);
-   size = psinfo-bufsize - hsize;
-   dst += hsize;
+   if (dst) {
+   hsize = sprintf(dst, %s#%d Part%d\n, why,
+   oopscount, part);
+   size = big_buf_sz - hsize;
+   dst += hsize;
 
-   if (!kmsg_dump_get_buffer(dumper, true, dst, size, len

[PATCH 08/11] powerpc/pseries: Read and write to the 'compressed' flag of pstore

2013-07-15 Thread Aruna Balakrishnaiah
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 ar...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |   34 +---
 1 file changed, 27 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 78c6f45..6f383eb 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) + oops_hdr-report_length), err_type,
count);
@@ -604,11 +607,10 @@ 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;
-   int rc, sig = 0;
+   char *buff = NULL;
+   int  sig = 0;
loff_t p;
 
-read_partition:
read_type++;
 
switch (nvram_type_ids[read_type]) {
@@ -669,14 +671,32 @@ read_partition:
*id = id_no;
 
if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) {
+   u16 length;
oops_hdr = (struct oops_log_info *)buff;
-   *buf = buff + sizeof(*oops_hdr);
-   time-tv_sec = oops_hdr-timestamp;
-   time-tv_nsec = 0;
-   return oops_hdr-report_length;
+
+   /* Provide backward compatibility with old format headers */
+   if (oops_hdr-version  OOPS_HDR_VERSION) {
+   *buf = buff + sizeof(u16);
+   length = oops_hdr-version;
+   time-tv_sec = 0;
+   time-tv_nsec = 0;
+   } else {
+   *buf = buff + sizeof(*oops_hdr);
+   length = oops_hdr-report_length;
+   time-tv_sec = oops_hdr-timestamp;
+   time-tv_nsec = 0;
+   }
+
+   if (err_type == ERR_TYPE_KERNEL_PANIC_GZ)
+   *compressed = true;
+   else
+   *compressed = false;
+
+   return length;
}
 
*buf = buff;
+   *compressed = false;
return part-size;
 }
 

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


[PATCH 10/11] efi-pstore: Read and write to the 'compressed' flag of pstore

2013-07-15 Thread Aruna Balakrishnaiah
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 ar...@linux.vnet.ibm.com
---
 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];

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


[PATCH 11/11] pstore/ram: Read and write to the 'compressed' flag of pstore

2013-07-15 Thread Aruna Balakrishnaiah
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 ar...@linux.vnet.ibm.com
---
 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);

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


[PATCH 09/11] erst: Read and write to the 'compressed' flag of pstore

2013-07-15 Thread Aruna Balakrishnaiah
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 ar...@linux.vnet.ibm.com
---
 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;

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


Re: [PATCH v4 0/8] Nvram-to-pstore

2013-06-19 Thread Aruna Balakrishnaiah

Hi Michael,

On Wednesday 19 June 2013 11:45 AM, Michael Neuling wrote:

Aruna Balakrishnaiah ar...@linux.vnet.ibm.com wrote:

Currently the kernel provides the contents of p-series NVRAM only as a
simple stream of bytes via /dev/nvram, which must be interpreted in user
space by the nvram command in the powerpc-utils package. This patch set
exploits the pstore subsystem to expose each partition in NVRAM as a
separate file in /dev/pstore. For instance, Oops messages will be stored
in a file named [dmesg-nvram-2].

Changes from v3:
- Change filename prefix for of-config and common partition

Changes from v2:
- Fix renaming of pstore type ids in nvram.c

Changes from v1:
- Reduce #ifdefs by and remove forward declarations of pstore callbacks
- Handle return value of nvram_write_os_partition
- Remove empty pstore callbacks and register pstore only when pstore
  is configured

When booted on pHyp, I see /dev/nvram but not /dev/pstore, even if I
turn on CONFIG_PSTORE.  Is there something else I need to add?


You need to mount pstore to access the files.

# mkdir /dev/pstore
# mount -t pstore - /dev/pstore

to unmount

# umount /dev/pstore

References: http://lwn.net/Articles/421297/
Documentation/ABI/testing/pstore



Should we update pseries_defconfig to include CONFIG_PSTORE (which it
doesn't include currently)?  Maybe turn on panic/oops via
CONFIG_PSTORE_RAM too?


Yes. We should enable CONFIG_PSTORE by default in pseries_defconfig.
We need not enable CONFIG_PSTORE_RAM for our case. Its for systems with
persistent RAM.


Other than that, the series looks clean.  It's passes my build and boot
tests.

I've not reviewed the contents of the patches.

Mikey


---

Aruna Balakrishnaiah (8):
   powerpc/pseries: Remove syslog prefix in uncompressed oops text
   powerpc/pseries: Add version and timestamp to oops header
   powerpc/pseries: Introduce generic read function to read nvram-partitions
   powerpc/pseries: Read/Write oops nvram partition via pstore
   powerpc/pseries: Read rtas partition via pstore
   powerpc/pseries: Distinguish between a os-partition and non-os partition
   powerpc/pseries: Read of-config partition via pstore
   powerpc/pseries: Read common partition via pstore


  arch/powerpc/platforms/pseries/nvram.c |  353 +++-
  fs/pstore/inode.c  |9 +
  include/linux/pstore.h |4
  3 files changed, 313 insertions(+), 53 deletions(-)

--

___
Linuxppc-dev mailing list
linuxppc-...@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


___
Linuxppc-dev mailing list
linuxppc-...@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev



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


[PATCH] powerpc/pseries: Enable PSTORE in pseries_defconfig

2013-06-21 Thread Aruna Balakrishnaiah
Enable PSTORE in pseries_defconfig

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
---
 arch/powerpc/configs/pseries_defconfig |1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/configs/pseries_defconfig 
b/arch/powerpc/configs/pseries_defconfig
index c4dfbaf..9630a50 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -347,3 +347,4 @@ CONFIG_VIRTUALIZATION=y
 CONFIG_KVM_BOOK3S_64=m
 CONFIG_KVM_BOOK3S_64_HV=y
 CONFIG_VHOST_NET=m
+CONFIG_PSTORE=y

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


[PATCH 1/3] pstore: Adjust buffer size for compression for smaller registered buffers

2013-09-11 Thread Aruna Balakrishnaiah
When backends (ex: efivars) have smaller registered buffers, the big_oops_buf
is quite too big for them as number of repeated occurences in the text captured
will be less. Patch takes care of adjusting the buffer size based on the
registered buffer size. cmpr values has been arrived after doing experiments 
with
plain text for buffers of size 1k - 4k (Smaller the buffer size repeated 
occurence
will be less) and with sample crash log for buffers ranging from 4k - 10k.

Reported-by: Seiji Aguchi seiji.agu...@hds.com
Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
---
 fs/pstore/platform.c |   23 ++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 4ffb7ab..4efaa75 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -195,8 +195,29 @@ error:
 static void allocate_buf_for_compression(void)
 {
size_t size;
+   size_t cmpr;
+
+   switch (psinfo-bufsize) {
+   /* buffer range for efivars */
+   case 1000 ... 2000:
+   cmpr = 56;
+   break;
+   case 2001 ... 3000:
+   cmpr = 54;
+   break;
+   case 3001 ... 3999:
+   cmpr = 52;
+   break;
+   /* buffer range for nvram, erst */
+   case 4000 ... 1:
+   cmpr = 48;
+   break;
+   default:
+   cmpr = 60;
+   break;
+   }
 
-   big_oops_buf_sz = (psinfo-bufsize * 100) / 45;
+   big_oops_buf_sz = (psinfo-bufsize * 100) / cmpr;
big_oops_buf = kmalloc(big_oops_buf_sz, GFP_KERNEL);
if (big_oops_buf) {
size = max(zlib_deflate_workspacesize(WINDOW_BITS, MEM_LEVEL),

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


[PATCH 3/3] pstore: Remove the messages related to compression failure

2013-09-11 Thread Aruna Balakrishnaiah
Remove the messages indicating compression failure as it will
add to the space during panic path.

Reported-by: Seiji Aguchi seiji.agu...@hds.com
Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
---
 fs/pstore/platform.c |4 
 1 file changed, 4 deletions(-)

diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 18924c7..4ad8c93 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -316,10 +316,6 @@ static void pstore_dump(struct kmsg_dumper *dumper,
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);
}

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


[PATCH 2/3] pstore: Use zlib_inflateInit2 instead of zlib_inflateInit

2013-09-11 Thread Aruna Balakrishnaiah
Since zlib_deflateInit2() is used for specifying window bit during compression,
zlib_inflateInit2() is appropriate for decompression.

Reported-by: Seiji Aguchi seiji.agu...@hds.com
Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
---
 fs/pstore/platform.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 4efaa75..18924c7 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -168,7 +168,7 @@ static int pstore_decompress(void *in, void *out, size_t 
inlen, size_t outlen)
int err, ret;
 
ret = -EIO;
-   err = zlib_inflateInit(stream);
+   err = zlib_inflateInit2(stream, WINDOW_BITS);
if (err != Z_OK)
goto error;
 

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


[PATCH v2] pstore: Adjust buffer size for compression for smaller registered buffers

2013-09-12 Thread Aruna Balakrishnaiah
When backends (ex: efivars) have smaller registered buffers, the big_oops_buf
is quite too big for them as number of repeated occurences in the text captured
will be less. Patch takes care of adjusting the buffer size based on the
registered buffer size. cmpr values has been arrived after doing experiments 
with
plain text for buffers of size 1k - 4k (Smaller the buffer size repeated 
occurence
will be less) and with sample crash log for buffers ranging from 4k - 10k.

Reported-by: Seiji Aguchi seiji.agu...@hds.com
Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
---
Changes from v1:
Retain the cmpr = 45 for buffers ranging of size 4k - 10k. 45 seems to 
work.
I added an additional headroom of 3%. Revert it back to 45.

 fs/pstore/platform.c |   23 ++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 4ffb7ab..57b4219 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -195,8 +195,29 @@ error:
 static void allocate_buf_for_compression(void)
 {
size_t size;
+   size_t cmpr;
+
+   switch (psinfo-bufsize) {
+   /* buffer range for efivars */
+   case 1000 ... 2000:
+   cmpr = 56;
+   break;
+   case 2001 ... 3000:
+   cmpr = 54;
+   break;
+   case 3001 ... 3999:
+   cmpr = 52;
+   break;
+   /* buffer range for nvram, erst */
+   case 4000 ... 1:
+   cmpr = 45;
+   break;
+   default:
+   cmpr = 60;
+   break;
+   }
 
-   big_oops_buf_sz = (psinfo-bufsize * 100) / 45;
+   big_oops_buf_sz = (psinfo-bufsize * 100) / cmpr;
big_oops_buf = kmalloc(big_oops_buf_sz, GFP_KERNEL);
if (big_oops_buf) {
size = max(zlib_deflate_workspacesize(WINDOW_BITS, MEM_LEVEL),

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


Re: [PATCH v2] pstore: Adjust buffer size for compression for smaller registered buffers

2013-09-12 Thread Aruna Balakrishnaiah

On Thursday 12 September 2013 11:13 PM, Luck, Tony wrote:

+   default:
+   cmpr = 60;
+   break;
+   }

Is this the right default?  It may be a good choice for a backend with a 
really
tiny buffer (1 ... 999).  But less good for a (theoretical) backend with a 
larger
buffer (10001 ... infinity and beyond).  Which are you trying to catch here?


Trying to catch lower buffers and also tried till 23k ( 10k * 100/45) of text 
with a
sample crash logit achieved a good compression of 25%. Since the upper limit is 
not known
and compression behavior is not tested above 10k chose to keep a higher default 
of 60.



-Tony

___
Linuxppc-dev mailing list
linuxppc-...@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev



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


Re: [PATCH 00/11] Add compression support to pstore

2013-08-01 Thread Aruna Balakrishnaiah

Hi Tony/Kees,

Could you please review and let me know your comments!!

Regards,
Aruna

On Monday 15 July 2013 10:25 PM, Aruna Balakrishnaiah wrote:

The patchset adds compression 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  which achieved a
significant compression of 12 % of uncompressed buffer size tried upto 36k.
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.
On Intel have only tested with erst backend.

Efi-pstore and RAM persistent buffer requires testing.


---

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: Provide 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 |  131 
  drivers/acpi/apei/erst.c   |   21 ++-
  drivers/firmware/efi/efi-pstore.c  |   27 +++-
  fs/pstore/Kconfig  |2
  fs/pstore/inode.c  |9 +
  fs/pstore/internal.h   |5 -
  fs/pstore/platform.c   |  214 ++--
  fs/pstore/ram.c|   41 +-
  include/linux/pstore.h |6 -
  9 files changed, 307 insertions(+), 149 deletions(-)



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


Re: [PATCH v3 8/8] powerpc/pseries: Read common partition via pstore

2013-06-04 Thread Aruna Balakrishnaiah

On Saturday 01 June 2013 10:22 AM, Benjamin Herrenschmidt wrote:

On Thu, 2013-04-25 at 15:49 +0530, Aruna Balakrishnaiah wrote:


diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index 8d4fb65..88cc050 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -330,6 +330,9 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, 
u64 id, int count,
case PSTORE_TYPE_PPC_OF:
sprintf(name, of-%s-%lld, psname, id);
break;

Call this powerpc-ofw-... Does it even contain something we use in Linux
at all ? Last I looked we only used the common one right ? Also it's
format afaik is defined in the CHRP bindings so it's not generic OFW
stuff, hence the powerpc prefix.


+   case PSTORE_TYPE_PPC_COMMON:
+   sprintf(name, common-%s-%lld, psname, id);
+   break;

Same deal, call that powerpc-common


Sure. Will change it to powerpc prefix.


case PSTORE_TYPE_UNKNOWN:
sprintf(name, unknown-%s-%lld, psname, id);
break;
diff --git a/include/linux/pstore.h b/include/linux/pstore.h
index 615dc18..656699f 100644
--- a/include/linux/pstore.h
+++ b/include/linux/pstore.h
@@ -38,6 +38,7 @@ enum pstore_type_id {
/* PPC64 partition types */
PSTORE_TYPE_PPC_RTAS= 4,
PSTORE_TYPE_PPC_OF  = 5,
+   PSTORE_TYPE_PPC_COMMON  = 6,
PSTORE_TYPE_UNKNOWN = 255
  };

Do we expose anything else or keep it hidden ?


We are exposing oops, rtas, of-config and common partition of nvram.


Cheers,
Ben.




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


Re: [PATCH 3/3] powerpc/pseries: Support compression of oops text via pstore

2013-06-04 Thread Aruna Balakrishnaiah

Hi Ben,

On Saturday 01 June 2013 10:24 AM, Benjamin Herrenschmidt wrote:

On Fri, 2013-04-26 at 15:26 +0530, Aruna Balakrishnaiah wrote:

The patch set supports compression of oops messages while writing to NVRAM,
this helps in capturing more of oops data to lnx,oops-log. The pstore file
for oops messages will be in decompressed format making it readable.

In case compression fails, the patch takes care of copying the header added
by pstore and last oops_data_sz bytes of big_oops_buf to NVRAM so that we
have recent oops messages in lnx,oops-log.

In case decompression fails, it will result in absence of oops file but still
have files (in /dev/pstore) for other partitions.

Any reason that isn't handled by pstore itself rather than here ? Ie
make a flag indicating that the partition supports compression and have
pstore do it (so we don't compress everything such as ofw common etc...)

Cheers,
Ben.



Since pstore does not have the compression support, I planned to reuse the
existing compression code in nvram but later we can add compression support
to pstore so that other platforms can make use of it.

Regards,
Aruna


Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
---
  arch/powerpc/platforms/pseries/nvram.c |  132 +---
  1 file changed, 118 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 0159d74..b5ba5e2 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -539,6 +539,65 @@ 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 unzip_oops(char *oops_buf, char *big_buf)
+{
+   struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf;
+   u64 timestamp = oops_hdr-timestamp;
+   char *big_oops_data = NULL;
+   char *oops_data_buf = NULL;
+   size_t big_oops_data_sz;
+   int unzipped_len;
+
+   big_oops_data = big_buf + sizeof(struct oops_log_info);
+   big_oops_data_sz = big_oops_buf_sz - sizeof(struct oops_log_info);
+   oops_data_buf = oops_buf + sizeof(struct oops_log_info);
+
+   unzipped_len = nvram_decompress(oops_data_buf, big_oops_data,
+   oops_hdr-report_length,
+   big_oops_data_sz);
+
+   if (unzipped_len  0) {
+   pr_err(nvram: decompression failed; returned %d\n,
+   unzipped_len);
+   return -1;
+   }
+   oops_hdr = (struct oops_log_info *)big_buf;
+   oops_hdr-version = OOPS_HDR_VERSION;
+   oops_hdr-report_length = (u16) unzipped_len;
+   oops_hdr-timestamp = timestamp;
+   return 0;
+}
+
  static int nvram_pstore_open(struct pstore_info *psi)
  {
/* Reset the iterator to start reading partitions again */
@@ -567,6 +626,7 @@ static int nvram_pstore_write(enum pstore_type_id type,
size_t size, struct pstore_info *psi)
  {
int rc;
+   unsigned int err_type = ERR_TYPE_KERNEL_PANIC;
struct oops_log_info *oops_hdr = (struct oops_log_info *) oops_buf;
  
  	/* part 1 has the recent messages from printk buffer */

@@ -577,8 +637,31 @@ static int nvram_pstore_write(enum pstore_type_id type,
oops_hdr-version = OOPS_HDR_VERSION;
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) {
+   int hsize = pstore_get_header_size();
+   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

Re: [PATCH v3 0/8] Nvram-to-pstore

2013-06-05 Thread Aruna Balakrishnaiah

Hi Ben,

On Saturday 01 June 2013 10:55 AM, Benjamin Herrenschmidt wrote:

Another question...

Should the core pstore fail to unlink partitions that don't have
an -erase callback ? IE. Why would you let anyone erase the OFW
common partition for example ? That means that userspace tools
can no longer manipulate it but we certainly don't want to remove
it from the nvram itself.


Since I do not have a callback for erase in nvram, pstore
simply unlinks the file and will not delete the partition.



That leads to a deeper concern. Looking at how efi-pstore works,
it looks like they create a file for each var.

This looks like something valuable we could do for something like
the common partition since typically it's made of name,value pairs.

However, pstore is a flat space, while we have patitions which
themselves can be organized in name,value pairs (some at least)

I wonder if it's time to introduce pstore directories... Or do
we stick to our special tools to interpret/change the name,value
pairs ?


Since pstore infrastructure creates the file in read-only mode
creating files for name, value pairs will not be useful to us.
So for now, we need to stick to our tools to interpret/change
the name,value pairs.

And also, pstore filenames are controlled by pstore infrastructure
so that would need quite some changes in the pstore infrastructure.

I think for now it would be better to dump the contents of common
partition as it is.



Also do we want to add an ability to resize partitions ? Possibly
based on how much is written to them ?


Yes it will be good to that.

If your fine with patchset apart from the filenames of-config and common
partitions. I will post the next version of it with powerpc prefix.



Cheers,
Ben.


___
Linuxppc-dev mailing list
linuxppc-...@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev



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


Re: [PATCH v3 0/8] Nvram-to-pstore

2013-06-05 Thread Aruna Balakrishnaiah

On Wednesday 05 June 2013 03:13 PM, Benjamin Herrenschmidt wrote:

On Wed, 2013-06-05 at 14:30 +0530, Aruna Balakrishnaiah wrote:

Hi Ben,

On Saturday 01 June 2013 10:55 AM, Benjamin Herrenschmidt wrote:

Another question...

Should the core pstore fail to unlink partitions that don't have
an -erase callback ? IE. Why would you let anyone erase the OFW
common partition for example ? That means that userspace tools
can no longer manipulate it but we certainly don't want to remove
it from the nvram itself.

Since I do not have a callback for erase in nvram, pstore
simply unlinks the file and will not delete the partition.

Right. My point is that it should probably refuse to unlink the file
too. What's the point in letting the user remove the file, potentially
making tools not working anymore, without any way to bring it back other
than a reboot ?

unlink makes sense if it also removes the partition. If it doesn't it
should just fail.


Right, makes sense. Will create a patch to fix it in pstore.


That leads to a deeper concern. Looking at how efi-pstore works,
it looks like they create a file for each var.

This looks like something valuable we could do for something like
the common partition since typically it's made of name,value pairs.

However, pstore is a flat space, while we have patitions which
themselves can be organized in name,value pairs (some at least)

I wonder if it's time to introduce pstore directories... Or do
we stick to our special tools to interpret/change the name,value
pairs ?

Since pstore infrastructure creates the file in read-only mode
creating files for name, value pairs will not be useful to us.
So for now, we need to stick to our tools to interpret/change
the name,value pairs.

And also, pstore filenames are controlled by pstore infrastructure
so that would need quite some changes in the pstore infrastructure.

I think for now it would be better to dump the contents of common
partition as it is.

Ok.


Also do we want to add an ability to resize partitions ? Possibly
based on how much is written to them ?

Yes it will be good to that.

If your fine with patchset apart from the filenames of-config and common
partitions. I will post the next version of it with powerpc prefix.

Yes, I'm ok with it.

Cheers,
Ben.


Cheers,
Ben.


___
Linuxppc-dev mailing list
linuxppc-...@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


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


___
Linuxppc-dev mailing list
linuxppc-...@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev



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


[PATCH v4 1/8] powerpc/pseries: Remove syslog prefix in uncompressed oops text

2013-06-05 Thread Aruna Balakrishnaiah
Removal of syslog prefix in the uncompressed oops text will
help in capturing more oops data.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 8733a86..e54a8b7 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -619,7 +619,7 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
}
if (rc != 0) {
kmsg_dump_rewind(dumper);
-   kmsg_dump_get_buffer(dumper, true,
+   kmsg_dump_get_buffer(dumper, false,
 oops_data, oops_data_sz, text_len);
err_type = ERR_TYPE_KERNEL_PANIC;
*oops_len = (u16) text_len;

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


[PATCH v4 0/8] Nvram-to-pstore

2013-06-05 Thread Aruna Balakrishnaiah
Currently the kernel provides the contents of p-series NVRAM only as a
simple stream of bytes via /dev/nvram, which must be interpreted in user
space by the nvram command in the powerpc-utils package. This patch set
exploits the pstore subsystem to expose each partition in NVRAM as a
separate file in /dev/pstore. For instance, Oops messages will be stored
in a file named [dmesg-nvram-2].

Changes from v3:
- Change filename prefix for of-config and common partition

Changes from v2:
- Fix renaming of pstore type ids in nvram.c

Changes from v1:
- Reduce #ifdefs by and remove forward declarations of pstore callbacks
- Handle return value of nvram_write_os_partition
- Remove empty pstore callbacks and register pstore only when pstore
  is configured
---

Aruna Balakrishnaiah (8):
  powerpc/pseries: Remove syslog prefix in uncompressed oops text
  powerpc/pseries: Add version and timestamp to oops header
  powerpc/pseries: Introduce generic read function to read nvram-partitions
  powerpc/pseries: Read/Write oops nvram partition via pstore
  powerpc/pseries: Read rtas partition via pstore
  powerpc/pseries: Distinguish between a os-partition and non-os partition
  powerpc/pseries: Read of-config partition via pstore
  powerpc/pseries: Read common partition via pstore


 arch/powerpc/platforms/pseries/nvram.c |  353 +++-
 fs/pstore/inode.c  |9 +
 include/linux/pstore.h |4 
 3 files changed, 313 insertions(+), 53 deletions(-)

-- 

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


[PATCH v4 2/8] powerpc/pseries: Add version and timestamp to oops header

2013-06-05 Thread Aruna Balakrishnaiah
Introduce version and timestamp information in the oops header.
oops_log_info (oops header) holds version (to distinguish between old
and new format oops header), length of the oops text
(compressed or uncompressed) and timestamp.

The version field will sit in the same place as the length in old
headers. version is assigned 5000 (greater than oops partition size)
so that existing tools will refuse to dump new style partitions as
the length is too large. The updated tools will work with both
old and new format headers.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |   57 +---
 1 file changed, 38 insertions(+), 19 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index e54a8b7..742735a 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -29,6 +29,13 @@
 /* Max bytes to read/write in one go */
 #define NVRW_CNT 0x20
 
+/*
+ * Set oops header version to distingush between old and new format header.
+ * lnx,oops-log partition max size is 4000, header version  4000 will
+ * help in identifying new header.
+ */
+#define OOPS_HDR_VERSION 5000
+
 static unsigned int nvram_size;
 static int nvram_fetch, nvram_store;
 static char nvram_buf[NVRW_CNT];   /* assume this is in the first 4GB */
@@ -67,6 +74,12 @@ static const char *pseries_nvram_os_partitions[] = {
NULL
 };
 
+struct oops_log_info {
+   u16 version;
+   u16 report_length;
+   u64 timestamp;
+} __attribute__((packed));
+
 static void oops_to_nvram(struct kmsg_dumper *dumper,
  enum kmsg_dump_reason reason);
 
@@ -83,28 +96,28 @@ static unsigned long last_unread_rtas_event;/* 
timestamp */
 
  * big_oops_buf[] holds the uncompressed text we're capturing.
  *
- * oops_buf[] holds the compressed text, preceded by a prefix.
- * The prefix is just a u16 holding the length of the compressed* text.
- * (*Or uncompressed, if compression fails.)  oops_buf[] gets written
- * to NVRAM.
+ * oops_buf[] holds the compressed text, preceded by a oops header.
+ * oops header has u16 holding the version of oops header (to differentiate
+ * between old and new format header) followed by u16 holding the length of
+ * the compressed* text (*Or uncompressed, if compression fails.) and u64
+ * holding the timestamp. oops_buf[] gets written to NVRAM.
  *
- * oops_len points to the prefix.  oops_data points to the compressed text.
+ * oops_log_info points to the header. oops_data points to the compressed text.
  *
  * +- oops_buf
- * |   +- oops_data
- * v   v
- * ++---+
- * | length| text  |
- * | (2 bytes) | (oops_data_sz bytes)  |
- * ++---+
+ * |   +- oops_data
+ * v   v
+ * +---+---+---++
+ * | version   | length| timestamp | text   |
+ * | (2 bytes) | (2 bytes) | (8 bytes) | (oops_data_sz bytes)   |
+ * +---+---+---++
  * ^
- * +- oops_len
+ * +- oops_log_info
  *
  * We preallocate these buffers during init to avoid kmalloc during oops/panic.
  */
 static size_t big_oops_buf_sz;
 static char *big_oops_buf, *oops_buf;
-static u16 *oops_len;
 static char *oops_data;
 static size_t oops_data_sz;
 
@@ -425,9 +438,8 @@ static void __init nvram_init_oops_partition(int 
rtas_partition_exists)
oops_log_partition.name);
return;
}
-   oops_len = (u16*) oops_buf;
-   oops_data = oops_buf + sizeof(u16);
-   oops_data_sz = oops_log_partition.size - sizeof(u16);
+   oops_data = oops_buf + sizeof(struct oops_log_info);
+   oops_data_sz = oops_log_partition.size - sizeof(struct oops_log_info);
 
/*
 * Figure compression (preceded by elimination of each line's n
@@ -555,6 +567,7 @@ error:
 /* Compress the text from big_oops_buf into oops_buf. */
 static int zip_oops(size_t text_len)
 {
+   struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf;
int zipped_len = nvram_compress(big_oops_buf, oops_data, text_len,
oops_data_sz);
if (zipped_len  0) {
@@ -562,7 +575,9 @@ static int zip_oops(size_t text_len)
pr_err(nvram: logging uncompressed oops/panic report\n);
return -1;
}
-   *oops_len = (u16) zipped_len;
+   oops_hdr-version = OOPS_HDR_VERSION;
+   oops_hdr-report_length = (u16) zipped_len;
+   oops_hdr-timestamp = get_seconds();
return 0;
 }
 
@@ -576,6 +591,7

[PATCH v4 3/8] powerpc/pseries: Introduce generic read function to read nvram-partitions

2013-06-05 Thread Aruna Balakrishnaiah
Introduce generic read function to read nvram partitions other than rtas.
nvram_read_error_log will be retained which is used to read rtas partition
from rtasd. nvram_read_partition is the generic read function to read from
any nvram partition.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |   32 ++--
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 742735a..088f023 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -293,34 +293,35 @@ int nvram_write_error_log(char * buff, int length,
return rc;
 }
 
-/* nvram_read_error_log
+/* nvram_read_partition
  *
- * Reads nvram for error log for at most 'length'
+ * Reads nvram partition for at most 'length'
  */
-int nvram_read_error_log(char * buff, int length,
- unsigned int * err_type, unsigned int * error_log_cnt)
+int nvram_read_partition(struct nvram_os_partition *part, char *buff,
+   int length, unsigned int *err_type,
+   unsigned int *error_log_cnt)
 {
int rc;
loff_t tmp_index;
struct err_log_info info;

-   if (rtas_log_partition.index == -1)
+   if (part-index == -1)
return -1;
 
-   if (length  rtas_log_partition.size)
-   length = rtas_log_partition.size;
+   if (length  part-size)
+   length = part-size;
 
-   tmp_index = rtas_log_partition.index;
+   tmp_index = part-index;
 
rc = ppc_md.nvram_read((char *)info, sizeof(struct err_log_info), 
tmp_index);
if (rc = 0) {
-   printk(KERN_ERR nvram_read_error_log: Failed nvram_read 
(%d)\n, rc);
+   pr_err(%s: Failed nvram_read (%d)\n, __FUNCTION__, rc);
return rc;
}
 
rc = ppc_md.nvram_read(buff, length, tmp_index);
if (rc = 0) {
-   printk(KERN_ERR nvram_read_error_log: Failed nvram_read 
(%d)\n, rc);
+   pr_err(%s: Failed nvram_read (%d)\n, __FUNCTION__, rc);
return rc;
}
 
@@ -330,6 +331,17 @@ int nvram_read_error_log(char * buff, int length,
return 0;
 }
 
+/* nvram_read_error_log
+ *
+ * Reads nvram for error log for at most 'length'
+ */
+int nvram_read_error_log(char *buff, int length,
+   unsigned int *err_type, unsigned int *error_log_cnt)
+{
+   return nvram_read_partition(rtas_log_partition, buff, length,
+   err_type, error_log_cnt);
+}
+
 /* This doesn't actually zero anything, but it sets the event_logged
  * word to tell that this event is safely in syslog.
  */

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


[PATCH v4 5/8] powerpc/pseries: Read rtas partition via pstore

2013-06-05 Thread Aruna Balakrishnaiah
This patch set exploits the pstore subsystem to read details of rtas partition
in NVRAM to a separate file in /dev/pstore. For instance, rtas details will be
stored in a file named [rtas-nvram-4].

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |   33 +---
 fs/pstore/inode.c  |3 +++
 include/linux/pstore.h |2 ++
 3 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 9edec8e..78d72f0 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -131,9 +131,11 @@ static struct z_stream_s stream;
 #ifdef CONFIG_PSTORE
 static enum pstore_type_id nvram_type_ids[] = {
PSTORE_TYPE_DMESG,
+   PSTORE_TYPE_PPC_RTAS,
-1
 };
 static int read_type;
+static unsigned long last_rtas_event;
 #endif
 
 static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index)
@@ -297,8 +299,13 @@ int nvram_write_error_log(char * buff, int length,
 {
int rc = nvram_write_os_partition(rtas_log_partition, buff, length,
err_type, error_log_cnt);
-   if (!rc)
+   if (!rc) {
last_unread_rtas_event = get_seconds();
+#ifdef CONFIG_PSTORE
+   last_rtas_event = get_seconds();
+#endif
+   }
+
return rc;
 }
 
@@ -506,7 +513,7 @@ static int nvram_pstore_write(enum pstore_type_id type,
 }
 
 /*
- * Reads the oops/panic report.
+ * Reads the oops/panic report and ibm,rtas-log partition.
  * Returns the length of the data we read from each partition.
  * Returns 0 if we've been called before.
  */
@@ -526,6 +533,12 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
part = oops_log_partition;
*type = PSTORE_TYPE_DMESG;
break;
+   case PSTORE_TYPE_PPC_RTAS:
+   part = rtas_log_partition;
+   *type = PSTORE_TYPE_PPC_RTAS;
+   time-tv_sec = last_rtas_event;
+   time-tv_nsec = 0;
+   break;
default:
return 0;
}
@@ -542,11 +555,17 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
 
*count = 0;
*id = id_no;
-   oops_hdr = (struct oops_log_info *)buff;
-   *buf = buff + sizeof(*oops_hdr);
-   time-tv_sec = oops_hdr-timestamp;
-   time-tv_nsec = 0;
-   return oops_hdr-report_length;
+
+   if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) {
+   oops_hdr = (struct oops_log_info *)buff;
+   *buf = buff + sizeof(*oops_hdr);
+   time-tv_sec = oops_hdr-timestamp;
+   time-tv_nsec = 0;
+   return oops_hdr-report_length;
+   }
+
+   *buf = buff;
+   return part-size;
 }
 
 static struct pstore_info nvram_pstore_info = {
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index e4bcb2c..ec24f9c 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -324,6 +324,9 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, 
u64 id, int count,
case PSTORE_TYPE_MCE:
sprintf(name, mce-%s-%lld, psname, id);
break;
+   case PSTORE_TYPE_PPC_RTAS:
+   sprintf(name, rtas-%s-%lld, psname, id);
+   break;
case PSTORE_TYPE_UNKNOWN:
sprintf(name, unknown-%s-%lld, psname, id);
break;
diff --git a/include/linux/pstore.h b/include/linux/pstore.h
index 75d0176..d7a8fe9 100644
--- a/include/linux/pstore.h
+++ b/include/linux/pstore.h
@@ -35,6 +35,8 @@ enum pstore_type_id {
PSTORE_TYPE_MCE = 1,
PSTORE_TYPE_CONSOLE = 2,
PSTORE_TYPE_FTRACE  = 3,
+   /* PPC64 partition types */
+   PSTORE_TYPE_PPC_RTAS= 4,
PSTORE_TYPE_UNKNOWN = 255
 };
 

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


[PATCH v4 6/8] powerpc/pseries: Distinguish between a os-partition and non-os partition

2013-06-05 Thread Aruna Balakrishnaiah
Introduce os_partition member in nvram_os_partition structure to identify
if the partition is an os partition or not. This will be useful to handle
non-os partitions of-config and common.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 78d72f0..714ed8a 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -53,20 +53,23 @@ struct nvram_os_partition {
int min_size;   /* minimum acceptable size (0 means req_size) */
long size;  /* size of data portion (excluding err_log_info) */
long index; /* offset of data portion of partition */
+   bool os_partition; /* partition initialized by OS, not FW */
 };
 
 static struct nvram_os_partition rtas_log_partition = {
.name = ibm,rtas-log,
.req_size = 2079,
.min_size = 1055,
-   .index = -1
+   .index = -1,
+   .os_partition = true
 };
 
 static struct nvram_os_partition oops_log_partition = {
.name = lnx,oops-log,
.req_size = 4000,
.min_size = 2000,
-   .index = -1
+   .index = -1,
+   .os_partition = true
 };
 
 static const char *pseries_nvram_os_partitions[] = {

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


[PATCH v4 7/8] powerpc/pseries: Read of-config partition via pstore

2013-06-05 Thread Aruna Balakrishnaiah
This patch set exploits the pstore subsystem to read details of
of-config partition in NVRAM to a separate file in /dev/pstore.
For instance, of-config partition details will be stored in a
file named [of-nvram-5].

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |   55 +++-
 fs/pstore/inode.c  |3 ++
 include/linux/pstore.h |1 +
 3 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 714ed8a..f7392f6 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -132,9 +132,16 @@ static size_t oops_data_sz;
 static struct z_stream_s stream;
 
 #ifdef CONFIG_PSTORE
+static struct nvram_os_partition of_config_partition = {
+   .name = of-config,
+   .index = -1,
+   .os_partition = false
+};
+
 static enum pstore_type_id nvram_type_ids[] = {
PSTORE_TYPE_DMESG,
PSTORE_TYPE_PPC_RTAS,
+   PSTORE_TYPE_PPC_OF,
-1
 };
 static int read_type;
@@ -332,10 +339,15 @@ int nvram_read_partition(struct nvram_os_partition *part, 
char *buff,
 
tmp_index = part-index;
 
-   rc = ppc_md.nvram_read((char *)info, sizeof(struct err_log_info), 
tmp_index);
-   if (rc = 0) {
-   pr_err(%s: Failed nvram_read (%d)\n, __FUNCTION__, rc);
-   return rc;
+   if (part-os_partition) {
+   rc = ppc_md.nvram_read((char *)info,
+   sizeof(struct err_log_info),
+   tmp_index);
+   if (rc = 0) {
+   pr_err(%s: Failed nvram_read (%d)\n, __FUNCTION__,
+   rc);
+   return rc;
+   }
}
 
rc = ppc_md.nvram_read(buff, length, tmp_index);
@@ -344,8 +356,10 @@ int nvram_read_partition(struct nvram_os_partition *part, 
char *buff,
return rc;
}
 
-   *error_log_cnt = info.seq_num;
-   *err_type = info.error_type;
+   if (part-os_partition) {
+   *error_log_cnt = info.seq_num;
+   *err_type = info.error_type;
+   }
 
return 0;
 }
@@ -516,7 +530,7 @@ static int nvram_pstore_write(enum pstore_type_id type,
 }
 
 /*
- * Reads the oops/panic report and ibm,rtas-log partition.
+ * Reads the oops/panic report, rtas and of-config partition.
  * Returns the length of the data we read from each partition.
  * Returns 0 if we've been called before.
  */
@@ -525,9 +539,11 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
struct pstore_info *psi)
 {
struct oops_log_info *oops_hdr;
-   unsigned int err_type, id_no;
+   unsigned int err_type, id_no, size = 0;
struct nvram_os_partition *part = NULL;
char *buff = NULL;
+   int sig = 0;
+   loff_t p;
 
read_type++;
 
@@ -542,10 +558,29 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
time-tv_sec = last_rtas_event;
time-tv_nsec = 0;
break;
+   case PSTORE_TYPE_PPC_OF:
+   sig = NVRAM_SIG_OF;
+   part = of_config_partition;
+   *type = PSTORE_TYPE_PPC_OF;
+   *id = PSTORE_TYPE_PPC_OF;
+   time-tv_sec = 0;
+   time-tv_nsec = 0;
+   break;
default:
return 0;
}
 
+   if (!part-os_partition) {
+   p = nvram_find_partition(part-name, sig, size);
+   if (p = 0) {
+   pr_err(nvram: Failed to find partition %s, 
+   err %d\n, part-name, (int)p);
+   return 0;
+   }
+   part-index = p;
+   part-size = size;
+   }
+
buff = kmalloc(part-size, GFP_KERNEL);
 
if (!buff)
@@ -557,7 +592,9 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
}
 
*count = 0;
-   *id = id_no;
+
+   if (part-os_partition)
+   *id = id_no;
 
if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) {
oops_hdr = (struct oops_log_info *)buff;
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index ec24f9c..73148ae 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -327,6 +327,9 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, 
u64 id, int count,
case PSTORE_TYPE_PPC_RTAS:
sprintf(name, rtas-%s-%lld, psname, id);
break;
+   case PSTORE_TYPE_PPC_OF:
+   sprintf(name, powerpc-ofw-%s-%lld, psname, id);
+   break;
case PSTORE_TYPE_UNKNOWN:
sprintf(name, unknown

[PATCH v4 4/8] powerpc/pseries: Read/Write oops nvram partition via pstore

2013-06-05 Thread Aruna Balakrishnaiah
IBM's p series machines provide persistent storage for LPARs through NVRAM.
NVRAM's lnx,oops-log partition is used to log oops messages.
Currently the kernel provides the contents of p-series NVRAM only as a
simple stream of bytes via /dev/nvram, which must be interpreted in user
space by the nvram command in the powerpc-utils package.

This patch set exploits the pstore subsystem to expose oops partition in
NVRAM as a separate file in /dev/pstore. For instance, Oops messages will be
stored in a file named [dmesg-nvram-2]. In case pstore registration fails it
will fall back to kmsg_dump mechanism.

This patch will read/write the oops messages from/to this partition via pstore.

Signed-off-by: Jim Keniston jkeni...@us.ibm.com
Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |  172 +---
 1 file changed, 157 insertions(+), 15 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 088f023..9edec8e 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -18,6 +18,7 @@
 #include linux/spinlock.h
 #include linux/slab.h
 #include linux/kmsg_dump.h
+#include linux/pstore.h
 #include linux/ctype.h
 #include linux/zlib.h
 #include asm/uaccess.h
@@ -127,6 +128,14 @@ static size_t oops_data_sz;
 #define MEM_LEVEL 4
 static struct z_stream_s stream;
 
+#ifdef CONFIG_PSTORE
+static enum pstore_type_id nvram_type_ids[] = {
+   PSTORE_TYPE_DMESG,
+   -1
+};
+static int read_type;
+#endif
+
 static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index)
 {
unsigned int i;
@@ -430,6 +439,149 @@ static int __init pseries_nvram_init_os_partition(struct 
nvram_os_partition
return 0;
 }
 
+/*
+ * Are we using the ibm,rtas-log for oops/panic reports?  And if so,
+ * would logging this oops/panic overwrite an RTAS event that rtas_errd
+ * hasn't had a chance to read and process?  Return 1 if so, else 0.
+ *
+ * We assume that if rtas_errd hasn't read the RTAS event in
+ * NVRAM_RTAS_READ_TIMEOUT seconds, it's probably not going to.
+ */
+static int clobbering_unread_rtas_event(void)
+{
+   return (oops_log_partition.index == rtas_log_partition.index
+last_unread_rtas_event
+get_seconds() - last_unread_rtas_event =
+   NVRAM_RTAS_READ_TIMEOUT);
+}
+
+#ifdef CONFIG_PSTORE
+static int nvram_pstore_open(struct pstore_info *psi)
+{
+   /* Reset the iterator to start reading partitions again */
+   read_type = -1;
+   return 0;
+}
+
+/**
+ * nvram_pstore_write - pstore write callback for nvram
+ * @type:   Type of message logged
+ * @reason: reason behind dump (oops/panic)
+ * @id: identifier to indicate the write performed
+ * @part:   pstore writes data to registered buffer in parts,
+ *  part number will indicate the same.
+ * @count:  Indicates oops count
+ * @size:   number of bytes written to the registered buffer
+ * @psi:registered pstore_info structure
+ *
+ * Called by pstore_dump() when an oops or panic report is logged in the
+ * printk buffer.
+ * Returns 0 on successful write.
+ */
+static int nvram_pstore_write(enum pstore_type_id type,
+   enum kmsg_dump_reason reason,
+   u64 *id, unsigned int part, int count,
+   size_t size, struct pstore_info *psi)
+{
+   int rc;
+   struct oops_log_info *oops_hdr = (struct oops_log_info *) oops_buf;
+
+   /* part 1 has the recent messages from printk buffer */
+   if (part  1 || type != PSTORE_TYPE_DMESG ||
+   clobbering_unread_rtas_event())
+   return -1;
+
+   oops_hdr-version = OOPS_HDR_VERSION;
+   oops_hdr-report_length = (u16) size;
+   oops_hdr-timestamp = get_seconds();
+   rc = nvram_write_os_partition(oops_log_partition, oops_buf,
+   (int) (sizeof(*oops_hdr) + size), ERR_TYPE_KERNEL_PANIC,
+   count);
+
+   if (rc != 0)
+   return rc;
+
+   *id = part;
+   return 0;
+}
+
+/*
+ * Reads the oops/panic report.
+ * Returns the length of the data we read from each partition.
+ * Returns 0 if we've been called before.
+ */
+static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type,
+   int *count, struct timespec *time, char **buf,
+   struct pstore_info *psi)
+{
+   struct oops_log_info *oops_hdr;
+   unsigned int err_type, id_no;
+   struct nvram_os_partition *part = NULL;
+   char *buff = NULL;
+
+   read_type++;
+
+   switch (nvram_type_ids[read_type]) {
+   case PSTORE_TYPE_DMESG:
+   part = oops_log_partition;
+   *type

[PATCH v4 8/8] powerpc/pseries: Read common partition via pstore

2013-06-05 Thread Aruna Balakrishnaiah
This patch exploits pstore subsystem to read details of common partition
in NVRAM to a separate file in /dev/pstore. For instance, common partition
details will be stored in a file named [common-nvram-6].

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |   17 -
 fs/pstore/inode.c  |3 +++
 include/linux/pstore.h |1 +
 3 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index f7392f6..14cc486 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -138,10 +138,17 @@ static struct nvram_os_partition of_config_partition = {
.os_partition = false
 };
 
+static struct nvram_os_partition common_partition = {
+   .name = common,
+   .index = -1,
+   .os_partition = false
+};
+
 static enum pstore_type_id nvram_type_ids[] = {
PSTORE_TYPE_DMESG,
PSTORE_TYPE_PPC_RTAS,
PSTORE_TYPE_PPC_OF,
+   PSTORE_TYPE_PPC_COMMON,
-1
 };
 static int read_type;
@@ -530,7 +537,7 @@ static int nvram_pstore_write(enum pstore_type_id type,
 }
 
 /*
- * Reads the oops/panic report, rtas and of-config partition.
+ * Reads the oops/panic report, rtas, of-config and common partition.
  * Returns the length of the data we read from each partition.
  * Returns 0 if we've been called before.
  */
@@ -566,6 +573,14 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
time-tv_sec = 0;
time-tv_nsec = 0;
break;
+   case PSTORE_TYPE_PPC_COMMON:
+   sig = NVRAM_SIG_SYS;
+   part = common_partition;
+   *type = PSTORE_TYPE_PPC_COMMON;
+   *id = PSTORE_TYPE_PPC_COMMON;
+   time-tv_sec = 0;
+   time-tv_nsec = 0;
+   break;
default:
return 0;
}
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index 73148ae..08c3d76 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -330,6 +330,9 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, 
u64 id, int count,
case PSTORE_TYPE_PPC_OF:
sprintf(name, powerpc-ofw-%s-%lld, psname, id);
break;
+   case PSTORE_TYPE_PPC_COMMON:
+   sprintf(name, powerpc-common-%s-%lld, psname, id);
+   break;
case PSTORE_TYPE_UNKNOWN:
sprintf(name, unknown-%s-%lld, psname, id);
break;
diff --git a/include/linux/pstore.h b/include/linux/pstore.h
index 615dc18..656699f 100644
--- a/include/linux/pstore.h
+++ b/include/linux/pstore.h
@@ -38,6 +38,7 @@ enum pstore_type_id {
/* PPC64 partition types */
PSTORE_TYPE_PPC_RTAS= 4,
PSTORE_TYPE_PPC_OF  = 5,
+   PSTORE_TYPE_PPC_COMMON  = 6,
PSTORE_TYPE_UNKNOWN = 255
 };
 

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


Re: [RFC PATCH 0/3] Nvram-to-pstore: compression support for oops data

2013-06-05 Thread Aruna Balakrishnaiah

Hi Ben,

There is no change in this patchset and it applies cleanly on top of
v4 of Nvram-to-pstorepatches.


The patchset takes care of compressing oops messages while writing to NVRAM,
so that more oops data can be captured in the given space.

big_oops_buf (2.22 * oops_data_sz) is allocated for compression.
oops_data_sz is oops header size less of oops partition size.

Pstore will internally call kmsg_dump to capture messages from printk
buffer. While returning the data to nvram it adds is own header.

For compression:
Register pstore with big_oops_buf.

In case compression fails, copy header added by pstore and
last oops_data_sz bytes (recent messages) of big_oops_buf to
nvram for which we need to know header size.

patch 01/03 will add a function in pstore to return the header size.

pstore read callback of nvram will read the compressed data and return the
decompressed data so that dmesg file (under /dev/pstore) is readable.

In case decompression fails, instead of having the compressed data (junk) in the
dmesg file it will skip and continue reading other partitions. This results in
absence of dmesg file but will still have files relating to other parititons.


---

Aruna Balakrishnaiah (3):
   Retreive header size from pstore.
   powerpc/pseries: Re-organise the oops compression code
   powerpc/pseries: Support compression of oops text via pstore


  arch/powerpc/platforms/pseries/nvram.c |  236 +++-
  fs/pstore/platform.c   |7 +
  include/linux/pstore.h |6 +
  3 files changed, 182 insertions(+), 67 deletions(-)



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


[RESEND PATCH 0/3] Nvram-to-pstore: compression support for oops data

2013-06-24 Thread Aruna Balakrishnaiah
The patchset takes care of compressing oops messages while writing to NVRAM,
so that more oops data can be captured in the given space.

big_oops_buf (2.22 * oops_data_sz) is allocated for compression.
oops_data_sz is oops header size less of oops partition size.

Pstore will internally call kmsg_dump to capture messages from printk
buffer. While returning the data to nvram it adds is own header.

For compression:
Register pstore with big_oops_buf. 

In case compression fails, copy header added by pstore and
last oops_data_sz bytes (recent messages) of big_oops_buf to
nvram for which we need to know header size. 

patch 01/03 will add a function in pstore to return the header size.

pstore read callback of nvram will read the compressed data and return the
decompressed data so that dmesg file (under /dev/pstore) is readable.

In case decompression fails, instead of having the compressed data (junk) in the
dmesg file it will skip and continue reading other partitions. This results in
absence of dmesg file but will still have files relating to other parititons.

---

Aruna Balakrishnaiah (3):
  Retreive header size from pstore
  powerpc/pseries: Re-organise the oops compression code
  powerpc/pseries: Support compression of oops text via pstore


 arch/powerpc/platforms/pseries/nvram.c |  236 +++-
 fs/pstore/platform.c   |7 +
 include/linux/pstore.h |6 +
 3 files changed, 182 insertions(+), 67 deletions(-)

-- 

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


[PATCH 1/3] Retreive header size from pstore

2013-06-24 Thread Aruna Balakrishnaiah
pstore_get_header_size will return the size of the header added by pstore
while logging messages to the registered buffer.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
---
 fs/pstore/platform.c   |7 ++-
 include/linux/pstore.h |6 ++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 86d1038..e8260ea 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -49,6 +49,7 @@ MODULE_PARM_DESC(update_ms, milliseconds before pstore 
updates its content 
 corruption on Oopses));
 
 static int pstore_new_entry;
+static int hsize;
 
 static void pstore_timefunc(unsigned long);
 static DEFINE_TIMER(pstore_timer, pstore_timefunc, 0, 0);
@@ -68,6 +69,11 @@ static char *backend;
 /* How much of the console log to snapshot */
 static unsigned long kmsg_bytes = 10240;
 
+int pstore_get_header_size(void)
+{
+   return hsize;
+}
+
 void pstore_set_kmsg_bytes(int bytes)
 {
kmsg_bytes = bytes;
@@ -147,7 +153,6 @@ static void pstore_dump(struct kmsg_dumper *dumper,
while (total  kmsg_bytes) {
char *dst;
unsigned long size;
-   int hsize;
size_t len;
 
dst = psinfo-buf;
diff --git a/include/linux/pstore.h b/include/linux/pstore.h
index 656699f..f43b64f 100644
--- a/include/linux/pstore.h
+++ b/include/linux/pstore.h
@@ -73,6 +73,7 @@ struct pstore_info {
 #ifdef CONFIG_PSTORE
 extern int pstore_register(struct pstore_info *);
 extern bool pstore_cannot_block_path(enum kmsg_dump_reason reason);
+extern int pstore_get_header_size(void);
 #else
 static inline int
 pstore_register(struct pstore_info *psi)
@@ -84,6 +85,11 @@ pstore_cannot_block_path(enum kmsg_dump_reason reason)
 {
return false;
 }
+static inline int
+pstore_get_header_size(void)
+{
+   return 0;
+}
 #endif
 
 #endif /*_LINUX_PSTORE_H*/

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


[PATCH 3/3] powerpc/pseries: Support compression of oops text via pstore

2013-06-24 Thread Aruna Balakrishnaiah
The patch set supports compression of oops messages while writing to NVRAM,
this helps in capturing more of oops data to lnx,oops-log. The pstore file
for oops messages will be in decompressed format making it readable.

In case compression fails, the patch takes care of copying the header added
by pstore and last oops_data_sz bytes of big_oops_buf to NVRAM so that we
have recent oops messages in lnx,oops-log.

In case decompression fails, it will result in absence of oops file but still
have files (in /dev/pstore) for other partitions.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |  132 +---
 1 file changed, 118 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 0159d74..b5ba5e2 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -539,6 +539,65 @@ 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 unzip_oops(char *oops_buf, char *big_buf)
+{
+   struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf;
+   u64 timestamp = oops_hdr-timestamp;
+   char *big_oops_data = NULL;
+   char *oops_data_buf = NULL;
+   size_t big_oops_data_sz;
+   int unzipped_len;
+
+   big_oops_data = big_buf + sizeof(struct oops_log_info);
+   big_oops_data_sz = big_oops_buf_sz - sizeof(struct oops_log_info);
+   oops_data_buf = oops_buf + sizeof(struct oops_log_info);
+
+   unzipped_len = nvram_decompress(oops_data_buf, big_oops_data,
+   oops_hdr-report_length,
+   big_oops_data_sz);
+
+   if (unzipped_len  0) {
+   pr_err(nvram: decompression failed; returned %d\n,
+   unzipped_len);
+   return -1;
+   }
+   oops_hdr = (struct oops_log_info *)big_buf;
+   oops_hdr-version = OOPS_HDR_VERSION;
+   oops_hdr-report_length = (u16) unzipped_len;
+   oops_hdr-timestamp = timestamp;
+   return 0;
+}
+
 static int nvram_pstore_open(struct pstore_info *psi)
 {
/* Reset the iterator to start reading partitions again */
@@ -567,6 +626,7 @@ static int nvram_pstore_write(enum pstore_type_id type,
size_t size, struct pstore_info *psi)
 {
int rc;
+   unsigned int err_type = ERR_TYPE_KERNEL_PANIC;
struct oops_log_info *oops_hdr = (struct oops_log_info *) oops_buf;
 
/* part 1 has the recent messages from printk buffer */
@@ -577,8 +637,31 @@ static int nvram_pstore_write(enum pstore_type_id type,
oops_hdr-version = OOPS_HDR_VERSION;
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) {
+   int hsize = pstore_get_header_size();
+   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) + size), ERR_TYPE_KERNEL_PANIC,
+   (int) (sizeof(*oops_hdr) + oops_hdr-report_length), err_type,
count);
 
if (rc != 0)
@@ -600,10 +683,11 @@ 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

[PATCH 2/3] powerpc/pseries: Re-organise the oops compression code

2013-06-24 Thread Aruna Balakrishnaiah
nvram_compress() and zip_oops() is used by the nvram_pstore_write
API to compress oops messages hence re-organise the functions
accordingly to avoid forward declarations.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |  104 
 1 file changed, 52 insertions(+), 52 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 14cc486..0159d74 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -486,6 +486,58 @@ static int clobbering_unread_rtas_event(void)
NVRAM_RTAS_READ_TIMEOUT);
 }
 
+/* Derived from logfs_compress() */
+static int nvram_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;
+}
+
+/* Compress the text from big_oops_buf into oops_buf. */
+static int zip_oops(size_t text_len)
+{
+   struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf;
+   int zipped_len = nvram_compress(big_oops_buf, oops_data, text_len,
+   oops_data_sz);
+   if (zipped_len  0) {
+   pr_err(nvram: compression failed; returned %d\n, zipped_len);
+   pr_err(nvram: logging uncompressed oops/panic report\n);
+   return -1;
+   }
+   oops_hdr-version = OOPS_HDR_VERSION;
+   oops_hdr-report_length = (u16) zipped_len;
+   oops_hdr-timestamp = get_seconds();
+   return 0;
+}
+
 #ifdef CONFIG_PSTORE
 static int nvram_pstore_open(struct pstore_info *psi)
 {
@@ -757,58 +809,6 @@ int __init pSeries_nvram_init(void)
 }
 
 
-/* Derived from logfs_compress() */
-static int nvram_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;
-}
-
-/* Compress the text from big_oops_buf into oops_buf. */
-static int zip_oops(size_t text_len)
-{
-   struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf;
-   int zipped_len = nvram_compress(big_oops_buf, oops_data, text_len,
-   oops_data_sz);
-   if (zipped_len  0) {
-   pr_err(nvram: compression failed; returned %d\n, zipped_len);
-   pr_err(nvram: logging uncompressed oops/panic report\n);
-   return -1;
-   }
-   oops_hdr-version = OOPS_HDR_VERSION;
-   oops_hdr-report_length = (u16) zipped_len;
-   oops_hdr-timestamp = get_seconds();
-   return 0;
-}
-
 /*
  * This is our kmsg_dump callback, called after an oops or panic report
  * has been written to the printk buffer.  We want to capture as much

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


[PATCH v2] powerpc/pseries: Enable PSTORE in pseries_defconfig

2013-06-24 Thread Aruna Balakrishnaiah
Since now we have pstore support for nvram in pseries, enable it
in the default config. With this config option enabled, pstore
infra-structure will be used to read/write the messages from/to nvram.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
---
 arch/powerpc/configs/pseries_defconfig |1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/configs/pseries_defconfig 
b/arch/powerpc/configs/pseries_defconfig
index c4dfbaf..9630a50 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -347,3 +347,4 @@ CONFIG_VIRTUALIZATION=y
 CONFIG_KVM_BOOK3S_64=m
 CONFIG_KVM_BOOK3S_64_HV=y
 CONFIG_VHOST_NET=m
+CONFIG_PSTORE=y

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


Re: [PATCH] powerpc/pseries: Enable PSTORE in pseries_defconfig

2013-06-24 Thread Aruna Balakrishnaiah

Hi Michael,

On Monday 24 June 2013 06:51 AM, Michael Neuling wrote:

Enable PSTORE in pseries_defconfig

Please add a why to your changelogs eg. Now we have pstore support for
nvram on pseries, enable it in the default config

Why you are changing something is more important than what, since
you can always determine what is being changed, by looking at the diff.
The why will be long forgotten.


Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
---
  arch/powerpc/configs/pseries_defconfig |1 +
  1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/configs/pseries_defconfig 
b/arch/powerpc/configs/pseries_defconfig
index c4dfbaf..9630a50 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -347,3 +347,4 @@ CONFIG_VIRTUALIZATION=y
  CONFIG_KVM_BOOK3S_64=m
  CONFIG_KVM_BOOK3S_64_HV=y
  CONFIG_VHOST_NET=m
+CONFIG_PSTORE=y

This should really be added in the right location on the config, not
just at the end.   ie.


Sorry, I overlooked this commentin my v2 patch. Will resend.


@@ -296,6 +293,7 @@
  CONFIG_SQUASHFS_XATTR=y
  CONFIG_SQUASHFS_LZO=y
  CONFIG_SQUASHFS_XZ=y
+CONFIG_PSTORE=y
  CONFIG_NFS_FS=y
  CONFIG_NFS_V3_ACL=y
  CONFIG_NFS_V4=y

___
Linuxppc-dev mailing list
linuxppc-...@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev



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


[PATCH v3] powerpc/pseries: Enable PSTORE in pseries_defconfig

2013-06-24 Thread Aruna Balakrishnaiah
Since now we have pstore support for nvram in pseries, enable it
in the default config. With this config option enabled, pstore
infra-structure will be used to read/write the messages from/to nvram.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
---
 v3:
Move pstore config to right place
 v2:
Change patch description

 arch/powerpc/configs/pseries_defconfig |1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/configs/pseries_defconfig 
b/arch/powerpc/configs/pseries_defconfig
index c4dfbaf..bea8587 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -296,6 +296,7 @@ CONFIG_SQUASHFS=m
 CONFIG_SQUASHFS_XATTR=y
 CONFIG_SQUASHFS_LZO=y
 CONFIG_SQUASHFS_XZ=y
+CONFIG_PSTORE=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y

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


[PATCH] pstore: Fail to unlink if a driver has not defined pstore_erase

2013-06-24 Thread Aruna Balakrishnaiah
pstore_erase is used to erase the record from the persistent store.
So if a driver has not defined pstore_erase callback return
-EINVAL instead of unlinking a file as deleting the file without
erasing its record in persistent store will give a wrong impression
to customers.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
---
 fs/pstore/inode.c |2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index e4bcb2c..fa6339a 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -178,6 +178,8 @@ static int pstore_unlink(struct inode *dir, struct dentry 
*dentry)
if (p-psi-erase)
p-psi-erase(p-type, p-id, p-count,
  dentry-d_inode-i_ctime, p-psi);
+   else
+   return -EINVAL;
 
return simple_unlink(dir, dentry);
 }

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


Re: [PATCH] pstore: Fail to unlink if a driver has not defined pstore_erase

2013-06-24 Thread Aruna Balakrishnaiah

Hi Keek,

On Monday 24 June 2013 10:33 PM, Kees Cook wrote:

On Mon, Jun 24, 2013 at 12:48 AM, Aruna Balakrishnaiah
ar...@linux.vnet.ibm.com wrote:

pstore_erase is used to erase the record from the persistent store.
So if a driver has not defined pstore_erase callback return
-EINVAL instead of unlinking a file as deleting the file without
erasing its record in persistent store will give a wrong impression
to customers.

This is probably true -- I originally liked the idea of being able to
clean up the entries, regardless of their storage state, but you're
probably right. They shouldn't be deleted unless they can _actually_
be deleted.

So, I support this change, but I think the return needs to be
different. EINVAL isn't listed, for example, in unlink(2)'s man-page.
Perhaps EROFS, EACCESS, or EPERM?


The filesystem (pstore) has privileges to unlink the file but only if the
callback function is defined. Since the filesystem has privileges I didn't
consider these error codes (EROFS, EACCESS or EPERM).

In the case where callback function is not defined unlinking the file would
be an invalid operation and hence EINVAL.

Since unlink(2) man page does not have EINVAL listed, I feel going with
EPERM will make more sense.




-Kees


Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
---
  fs/pstore/inode.c |2 ++
  1 file changed, 2 insertions(+)

diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index e4bcb2c..fa6339a 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -178,6 +178,8 @@ static int pstore_unlink(struct inode *dir, struct dentry 
*dentry)
 if (p-psi-erase)
 p-psi-erase(p-type, p-id, p-count,
   dentry-d_inode-i_ctime, p-psi);
+   else
+   return -EINVAL;

 return simple_unlink(dir, dentry);
  }




--
Kees Cook
Chrome OS Security



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


Re: [PATCH 3/3] powerpc/pseries: Support compression of oops text via pstore

2013-06-25 Thread Aruna Balakrishnaiah

Hi Kees,

On Monday 24 June 2013 11:27 PM, Kees Cook wrote:

On Sun, Jun 23, 2013 at 11:23 PM, Aruna Balakrishnaiah
ar...@linux.vnet.ibm.com wrote:

The patch set supports compression of oops messages while writing to NVRAM,
this helps in capturing more of oops data to lnx,oops-log. The pstore file
for oops messages will be in decompressed format making it readable.

In case compression fails, the patch takes care of copying the header added
by pstore and last oops_data_sz bytes of big_oops_buf to NVRAM so that we
have recent oops messages in lnx,oops-log.

In case decompression fails, it will result in absence of oops file but still
have files (in /dev/pstore) for other partitions.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
---
  arch/powerpc/platforms/pseries/nvram.c |  132 +---
  1 file changed, 118 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 0159d74..b5ba5e2 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -539,6 +539,65 @@ 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 unzip_oops(char *oops_buf, char *big_buf)
+{
+   struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf;
+   u64 timestamp = oops_hdr-timestamp;
+   char *big_oops_data = NULL;
+   char *oops_data_buf = NULL;
+   size_t big_oops_data_sz;
+   int unzipped_len;
+
+   big_oops_data = big_buf + sizeof(struct oops_log_info);
+   big_oops_data_sz = big_oops_buf_sz - sizeof(struct oops_log_info);
+   oops_data_buf = oops_buf + sizeof(struct oops_log_info);
+
+   unzipped_len = nvram_decompress(oops_data_buf, big_oops_data,
+   oops_hdr-report_length,
+   big_oops_data_sz);
+
+   if (unzipped_len  0) {
+   pr_err(nvram: decompression failed; returned %d\n,
+   unzipped_len);
+   return -1;
+   }
+   oops_hdr = (struct oops_log_info *)big_buf;
+   oops_hdr-version = OOPS_HDR_VERSION;
+   oops_hdr-report_length = (u16) unzipped_len;
+   oops_hdr-timestamp = timestamp;
+   return 0;
+}
+
  static int nvram_pstore_open(struct pstore_info *psi)
  {
 /* Reset the iterator to start reading partitions again */
@@ -567,6 +626,7 @@ static int nvram_pstore_write(enum pstore_type_id type,
 size_t size, struct pstore_info *psi)
  {
 int rc;
+   unsigned int err_type = ERR_TYPE_KERNEL_PANIC;
 struct oops_log_info *oops_hdr = (struct oops_log_info *) oops_buf;

 /* part 1 has the recent messages from printk buffer */
@@ -577,8 +637,31 @@ static int nvram_pstore_write(enum pstore_type_id type,
 oops_hdr-version = OOPS_HDR_VERSION;
 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) {
+   int hsize = pstore_get_header_size();

I think I would rather see the API to pstore_write() changed to
include explicit details about header sizes. Mkaing hsize a global
seems unwise, since it's not strictly going to be a constant value. It
could change between calls to the writer, for example.


Introducing headersize in pstore_write() API would need changes at
multiple places whereits being called. The idea is to move the
compression support to pstore infrastructure so that other platforms
could also make use of it. Once the compression support gets in,
header size argument in pstore_write() will have to be deprecated.

Till the time compression support for pstore goes in, can't we call
pstore_header_size before every write call to knowthe header size.


Beyond that, this all seems sensible, though it would be kind of cool
to move this compression logic into the pstore core so it would get
used by default (or through a module parameter).
-Kees

[PATCH v2] pstore: Fail to unlink if a driver has not defined pstore_erase

2013-06-25 Thread Aruna Balakrishnaiah
pstore_erase is used to erase the record from the persistent store.
So if a driver has not defined pstore_erase callback return
-EPERM instead of unlinking a file as deleting the file without
erasing its record in persistent store will give a wrong impression
to customers.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
---
Changes from v1:
Fix error return value

 fs/pstore/inode.c |2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index e4bcb2c..bfd95bf 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -178,6 +178,8 @@ static int pstore_unlink(struct inode *dir, struct dentry 
*dentry)
if (p-psi-erase)
p-psi-erase(p-type, p-id, p-count,
  dentry-d_inode-i_ctime, p-psi);
+   else
+   return -EPERM;
 
return simple_unlink(dir, dentry);
 }

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


Re: [PATCH v2] pstore: Fail to unlink if a driver has not defined pstore_erase

2013-06-26 Thread Aruna Balakrishnaiah

On Tuesday 25 June 2013 10:40 PM, Tony Luck wrote:

On Tue, Jun 25, 2013 at 9:41 AM, Kees Cook keesc...@chromium.org wrote:

On Tue, Jun 25, 2013 at 2:03 AM, Aruna Balakrishnaiah
ar...@linux.vnet.ibm.com wrote:

pstore_erase is used to erase the record from the persistent store.
So if a driver has not defined pstore_erase callback return

How do people manage devices like this?  With no erase function
they just keep getting more and more pstore entries. Eventually
they fill up.


We dont keep old records in the device. We have logs only of the
recent / last crash.  The device has a predefined space for each type
of messages.  For example:  Every time a crash occurs the data gets
overwritten in the device allocated to store crash log.




Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com

Acked-by: Kees Cook keesc...@chromium.org

Applied - thanks.

-Tony



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


[PATCH v2 0/8] powerpc/pseries: Nvram-to-pstore

2013-04-24 Thread Aruna Balakrishnaiah
Currently the kernel provides the contents of p-series NVRAM only as a
simple stream of bytes via /dev/nvram, which must be interpreted in user
space by the nvram command in the powerpc-utils package. This patch set
exploits the pstore subsystem to expose each partition in NVRAM as a
separate file in /dev/pstore. For instance Oops messages will stored in a
file named [dmesg-nvram-2].

Changes from v1:
- Reduce #ifdefs by and remove forward declarations of pstore callbacks
- Handle return value of nvram_write_os_partition
- Remove empty pstore callbacks and register pstore only when pstore
  is configured

---

Aruna Balakrishnaiah (8):
  powerpc/pseries: Remove syslog prefix in uncompressed oops text
  powerpc/pseries: Add version and timestamp to oops header
  powerpc/pseries: Introduce generic read function to read nvram-partitions
  powerpc/pseries: Read/Write oops nvram partition via pstore
  powerpc/pseries: Read rtas partition via pstore
  powerpc/pseries: Distinguish between a os-partition and non-os partition
  powerpc/pseries: Read of-config partition via pstore
  powerpc/pseries: Read common partition via pstore


 arch/powerpc/platforms/pseries/nvram.c |  353 +++-
 fs/pstore/inode.c  |9 +
 include/linux/pstore.h |4 
 3 files changed, 313 insertions(+), 53 deletions(-)

-- 

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


[PATCH v2 1/8] powerpc/pseries: Remove syslog prefix in uncompressed oops text

2013-04-24 Thread Aruna Balakrishnaiah
Removal of syslog prefix in the uncompressed oops text will
help in capturing more oops data.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 8733a86..e54a8b7 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -619,7 +619,7 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
}
if (rc != 0) {
kmsg_dump_rewind(dumper);
-   kmsg_dump_get_buffer(dumper, true,
+   kmsg_dump_get_buffer(dumper, false,
 oops_data, oops_data_sz, text_len);
err_type = ERR_TYPE_KERNEL_PANIC;
*oops_len = (u16) text_len;

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


[PATCH v2 4/8] powerpc/pseries: Read/Write oops nvram partition via pstore

2013-04-24 Thread Aruna Balakrishnaiah
IBM's p series machines provide persistent storage for LPARs through NVRAM.
NVRAM's lnx,oops-log partition is used to log oops messages.
Currently the kernel provides the contents of p-series NVRAM only as a
simple stream of bytes via /dev/nvram, which must be interpreted in user
space by the nvram command in the powerpc-utils package.

This patch set exploits the pstore subsystem to expose oops partition in
NVRAM as a separate file in /dev/pstore. For instance, Oops messages will be
stored in a file named [dmesg-nvram-2]. In case pstore registration fails it
will fall back to kmsg_dump mechanism.

This patch will read/write the oops messages from/to this partition via pstore.

Signed-off-by: Jim Keniston jkeni...@us.ibm.com
Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |  172 +---
 1 file changed, 157 insertions(+), 15 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 088f023..9edec8e 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -18,6 +18,7 @@
 #include linux/spinlock.h
 #include linux/slab.h
 #include linux/kmsg_dump.h
+#include linux/pstore.h
 #include linux/ctype.h
 #include linux/zlib.h
 #include asm/uaccess.h
@@ -127,6 +128,14 @@ static size_t oops_data_sz;
 #define MEM_LEVEL 4
 static struct z_stream_s stream;
 
+#ifdef CONFIG_PSTORE
+static enum pstore_type_id nvram_type_ids[] = {
+   PSTORE_TYPE_DMESG,
+   -1
+};
+static int read_type;
+#endif
+
 static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index)
 {
unsigned int i;
@@ -430,6 +439,149 @@ static int __init pseries_nvram_init_os_partition(struct 
nvram_os_partition
return 0;
 }
 
+/*
+ * Are we using the ibm,rtas-log for oops/panic reports?  And if so,
+ * would logging this oops/panic overwrite an RTAS event that rtas_errd
+ * hasn't had a chance to read and process?  Return 1 if so, else 0.
+ *
+ * We assume that if rtas_errd hasn't read the RTAS event in
+ * NVRAM_RTAS_READ_TIMEOUT seconds, it's probably not going to.
+ */
+static int clobbering_unread_rtas_event(void)
+{
+   return (oops_log_partition.index == rtas_log_partition.index
+last_unread_rtas_event
+get_seconds() - last_unread_rtas_event =
+   NVRAM_RTAS_READ_TIMEOUT);
+}
+
+#ifdef CONFIG_PSTORE
+static int nvram_pstore_open(struct pstore_info *psi)
+{
+   /* Reset the iterator to start reading partitions again */
+   read_type = -1;
+   return 0;
+}
+
+/**
+ * nvram_pstore_write - pstore write callback for nvram
+ * @type:   Type of message logged
+ * @reason: reason behind dump (oops/panic)
+ * @id: identifier to indicate the write performed
+ * @part:   pstore writes data to registered buffer in parts,
+ *  part number will indicate the same.
+ * @count:  Indicates oops count
+ * @size:   number of bytes written to the registered buffer
+ * @psi:registered pstore_info structure
+ *
+ * Called by pstore_dump() when an oops or panic report is logged in the
+ * printk buffer.
+ * Returns 0 on successful write.
+ */
+static int nvram_pstore_write(enum pstore_type_id type,
+   enum kmsg_dump_reason reason,
+   u64 *id, unsigned int part, int count,
+   size_t size, struct pstore_info *psi)
+{
+   int rc;
+   struct oops_log_info *oops_hdr = (struct oops_log_info *) oops_buf;
+
+   /* part 1 has the recent messages from printk buffer */
+   if (part  1 || type != PSTORE_TYPE_DMESG ||
+   clobbering_unread_rtas_event())
+   return -1;
+
+   oops_hdr-version = OOPS_HDR_VERSION;
+   oops_hdr-report_length = (u16) size;
+   oops_hdr-timestamp = get_seconds();
+   rc = nvram_write_os_partition(oops_log_partition, oops_buf,
+   (int) (sizeof(*oops_hdr) + size), ERR_TYPE_KERNEL_PANIC,
+   count);
+
+   if (rc != 0)
+   return rc;
+
+   *id = part;
+   return 0;
+}
+
+/*
+ * Reads the oops/panic report.
+ * Returns the length of the data we read from each partition.
+ * Returns 0 if we've been called before.
+ */
+static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type,
+   int *count, struct timespec *time, char **buf,
+   struct pstore_info *psi)
+{
+   struct oops_log_info *oops_hdr;
+   unsigned int err_type, id_no;
+   struct nvram_os_partition *part = NULL;
+   char *buff = NULL;
+
+   read_type++;
+
+   switch (nvram_type_ids[read_type]) {
+   case PSTORE_TYPE_DMESG:
+   part = oops_log_partition;
+   *type

[PATCH v2 3/8] powerpc/pseries: Introduce generic read function to read nvram-partitions

2013-04-24 Thread Aruna Balakrishnaiah
Introduce generic read function to read nvram partitions other than rtas.
nvram_read_error_log will be retained which is used to read rtas partition
from rtasd. nvram_read_partition is the generic read function to read from
any nvram partition.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |   32 ++--
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 742735a..088f023 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -293,34 +293,35 @@ int nvram_write_error_log(char * buff, int length,
return rc;
 }
 
-/* nvram_read_error_log
+/* nvram_read_partition
  *
- * Reads nvram for error log for at most 'length'
+ * Reads nvram partition for at most 'length'
  */
-int nvram_read_error_log(char * buff, int length,
- unsigned int * err_type, unsigned int * error_log_cnt)
+int nvram_read_partition(struct nvram_os_partition *part, char *buff,
+   int length, unsigned int *err_type,
+   unsigned int *error_log_cnt)
 {
int rc;
loff_t tmp_index;
struct err_log_info info;

-   if (rtas_log_partition.index == -1)
+   if (part-index == -1)
return -1;
 
-   if (length  rtas_log_partition.size)
-   length = rtas_log_partition.size;
+   if (length  part-size)
+   length = part-size;
 
-   tmp_index = rtas_log_partition.index;
+   tmp_index = part-index;
 
rc = ppc_md.nvram_read((char *)info, sizeof(struct err_log_info), 
tmp_index);
if (rc = 0) {
-   printk(KERN_ERR nvram_read_error_log: Failed nvram_read 
(%d)\n, rc);
+   pr_err(%s: Failed nvram_read (%d)\n, __FUNCTION__, rc);
return rc;
}
 
rc = ppc_md.nvram_read(buff, length, tmp_index);
if (rc = 0) {
-   printk(KERN_ERR nvram_read_error_log: Failed nvram_read 
(%d)\n, rc);
+   pr_err(%s: Failed nvram_read (%d)\n, __FUNCTION__, rc);
return rc;
}
 
@@ -330,6 +331,17 @@ int nvram_read_error_log(char * buff, int length,
return 0;
 }
 
+/* nvram_read_error_log
+ *
+ * Reads nvram for error log for at most 'length'
+ */
+int nvram_read_error_log(char *buff, int length,
+   unsigned int *err_type, unsigned int *error_log_cnt)
+{
+   return nvram_read_partition(rtas_log_partition, buff, length,
+   err_type, error_log_cnt);
+}
+
 /* This doesn't actually zero anything, but it sets the event_logged
  * word to tell that this event is safely in syslog.
  */

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


[PATCH v2 5/8] powerpc/pseries: Read rtas partition via pstore

2013-04-24 Thread Aruna Balakrishnaiah
This patch set exploits the pstore subsystem to read details of rtas partition
in NVRAM to a separate file in /dev/pstore. For instance, rtas details will be
stored in a file named [rtas-nvram-4].

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |   33 +---
 fs/pstore/inode.c  |3 +++
 include/linux/pstore.h |2 ++
 3 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 9edec8e..8a7eefb 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -131,9 +131,11 @@ static struct z_stream_s stream;
 #ifdef CONFIG_PSTORE
 static enum pstore_type_id nvram_type_ids[] = {
PSTORE_TYPE_DMESG,
+   PSTORE_TYPE_RTAS,
-1
 };
 static int read_type;
+static unsigned long last_rtas_event;
 #endif
 
 static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index)
@@ -297,8 +299,13 @@ int nvram_write_error_log(char * buff, int length,
 {
int rc = nvram_write_os_partition(rtas_log_partition, buff, length,
err_type, error_log_cnt);
-   if (!rc)
+   if (!rc) {
last_unread_rtas_event = get_seconds();
+#ifdef CONFIG_PSTORE
+   last_rtas_event = get_seconds();
+#endif
+   }
+
return rc;
 }
 
@@ -506,7 +513,7 @@ static int nvram_pstore_write(enum pstore_type_id type,
 }
 
 /*
- * Reads the oops/panic report.
+ * Reads the oops/panic report and ibm,rtas-log partition.
  * Returns the length of the data we read from each partition.
  * Returns 0 if we've been called before.
  */
@@ -526,6 +533,12 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
part = oops_log_partition;
*type = PSTORE_TYPE_DMESG;
break;
+   case PSTORE_TYPE_RTAS:
+   part = rtas_log_partition;
+   *type = PSTORE_TYPE_RTAS;
+   time-tv_sec = last_rtas_event;
+   time-tv_nsec = 0;
+   break;
default:
return 0;
}
@@ -542,11 +555,17 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
 
*count = 0;
*id = id_no;
-   oops_hdr = (struct oops_log_info *)buff;
-   *buf = buff + sizeof(*oops_hdr);
-   time-tv_sec = oops_hdr-timestamp;
-   time-tv_nsec = 0;
-   return oops_hdr-report_length;
+
+   if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) {
+   oops_hdr = (struct oops_log_info *)buff;
+   *buf = buff + sizeof(*oops_hdr);
+   time-tv_sec = oops_hdr-timestamp;
+   time-tv_nsec = 0;
+   return oops_hdr-report_length;
+   }
+
+   *buf = buff;
+   return part-size;
 }
 
 static struct pstore_info nvram_pstore_info = {
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index e4bcb2c..ec24f9c 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -324,6 +324,9 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, 
u64 id, int count,
case PSTORE_TYPE_MCE:
sprintf(name, mce-%s-%lld, psname, id);
break;
+   case PSTORE_TYPE_PPC_RTAS:
+   sprintf(name, rtas-%s-%lld, psname, id);
+   break;
case PSTORE_TYPE_UNKNOWN:
sprintf(name, unknown-%s-%lld, psname, id);
break;
diff --git a/include/linux/pstore.h b/include/linux/pstore.h
index 75d0176..d7a8fe9 100644
--- a/include/linux/pstore.h
+++ b/include/linux/pstore.h
@@ -35,6 +35,8 @@ enum pstore_type_id {
PSTORE_TYPE_MCE = 1,
PSTORE_TYPE_CONSOLE = 2,
PSTORE_TYPE_FTRACE  = 3,
+   /* PPC64 partition types */
+   PSTORE_TYPE_PPC_RTAS= 4,
PSTORE_TYPE_UNKNOWN = 255
 };
 

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


[PATCH v2 6/8] powerpc/pseries: Distinguish between a os-partition and non-os partition

2013-04-24 Thread Aruna Balakrishnaiah
Introduce os_partition member in nvram_os_partition structure to identify
if the partition is an os partition or not. This will be useful to handle
non-os partitions of-config and common.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 8a7eefb..b118382 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -53,20 +53,23 @@ struct nvram_os_partition {
int min_size;   /* minimum acceptable size (0 means req_size) */
long size;  /* size of data portion (excluding err_log_info) */
long index; /* offset of data portion of partition */
+   bool os_partition; /* partition initialized by OS, not FW */
 };
 
 static struct nvram_os_partition rtas_log_partition = {
.name = ibm,rtas-log,
.req_size = 2079,
.min_size = 1055,
-   .index = -1
+   .index = -1,
+   .os_partition = true
 };
 
 static struct nvram_os_partition oops_log_partition = {
.name = lnx,oops-log,
.req_size = 4000,
.min_size = 2000,
-   .index = -1
+   .index = -1,
+   .os_partition = true
 };
 
 static const char *pseries_nvram_os_partitions[] = {

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


[PATCH v2 7/8] powerpc/pseries: Read of-config partition via pstore

2013-04-24 Thread Aruna Balakrishnaiah
This patch set exploits the pstore subsystem to read details of
of-config partition in NVRAM to a separate file in /dev/pstore.
For instance, of-config partition details will be stored in a
file named [of-nvram-5].

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |   55 +++-
 fs/pstore/inode.c  |3 ++
 include/linux/pstore.h |1 +
 3 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index b118382..de448af 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -132,9 +132,16 @@ static size_t oops_data_sz;
 static struct z_stream_s stream;
 
 #ifdef CONFIG_PSTORE
+static struct nvram_os_partition of_config_partition = {
+   .name = of-config,
+   .index = -1,
+   .os_partition = false
+};
+
 static enum pstore_type_id nvram_type_ids[] = {
PSTORE_TYPE_DMESG,
PSTORE_TYPE_RTAS,
+   PSTORE_TYPE_OF,
-1
 };
 static int read_type;
@@ -332,10 +339,15 @@ int nvram_read_partition(struct nvram_os_partition *part, 
char *buff,
 
tmp_index = part-index;
 
-   rc = ppc_md.nvram_read((char *)info, sizeof(struct err_log_info), 
tmp_index);
-   if (rc = 0) {
-   pr_err(%s: Failed nvram_read (%d)\n, __FUNCTION__, rc);
-   return rc;
+   if (part-os_partition) {
+   rc = ppc_md.nvram_read((char *)info,
+   sizeof(struct err_log_info),
+   tmp_index);
+   if (rc = 0) {
+   pr_err(%s: Failed nvram_read (%d)\n, __FUNCTION__,
+   rc);
+   return rc;
+   }
}
 
rc = ppc_md.nvram_read(buff, length, tmp_index);
@@ -344,8 +356,10 @@ int nvram_read_partition(struct nvram_os_partition *part, 
char *buff,
return rc;
}
 
-   *error_log_cnt = info.seq_num;
-   *err_type = info.error_type;
+   if (part-os_partition) {
+   *error_log_cnt = info.seq_num;
+   *err_type = info.error_type;
+   }
 
return 0;
 }
@@ -516,7 +530,7 @@ static int nvram_pstore_write(enum pstore_type_id type,
 }
 
 /*
- * Reads the oops/panic report and ibm,rtas-log partition.
+ * Reads the oops/panic report, rtas and of-config partition.
  * Returns the length of the data we read from each partition.
  * Returns 0 if we've been called before.
  */
@@ -525,9 +539,11 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
struct pstore_info *psi)
 {
struct oops_log_info *oops_hdr;
-   unsigned int err_type, id_no;
+   unsigned int err_type, id_no, size = 0;
struct nvram_os_partition *part = NULL;
char *buff = NULL;
+   int sig = 0;
+   loff_t p;
 
read_type++;
 
@@ -542,10 +558,29 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
time-tv_sec = last_rtas_event;
time-tv_nsec = 0;
break;
+   case PSTORE_TYPE_OF:
+   sig = NVRAM_SIG_OF;
+   part = of_config_partition;
+   *type = PSTORE_TYPE_OF;
+   *id = PSTORE_TYPE_OF;
+   time-tv_sec = 0;
+   time-tv_nsec = 0;
+   break;
default:
return 0;
}
 
+   if (!part-os_partition) {
+   p = nvram_find_partition(part-name, sig, size);
+   if (p = 0) {
+   pr_err(nvram: Failed to find partition %s, 
+   err %d\n, part-name, (int)p);
+   return 0;
+   }
+   part-index = p;
+   part-size = size;
+   }
+
buff = kmalloc(part-size, GFP_KERNEL);
 
if (!buff)
@@ -557,7 +592,9 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
}
 
*count = 0;
-   *id = id_no;
+
+   if (part-os_partition)
+   *id = id_no;
 
if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) {
oops_hdr = (struct oops_log_info *)buff;
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index ec24f9c..8d4fb65 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -327,6 +327,9 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, 
u64 id, int count,
case PSTORE_TYPE_PPC_RTAS:
sprintf(name, rtas-%s-%lld, psname, id);
break;
+   case PSTORE_TYPE_PPC_OF:
+   sprintf(name, of-%s-%lld, psname, id);
+   break;
case PSTORE_TYPE_UNKNOWN:
sprintf(name, unknown-%s-%lld, psname, id

[PATCH v2 8/8] powerpc/pseries: Read common partition via pstore

2013-04-24 Thread Aruna Balakrishnaiah
This patch exploits pstore subsystem to read details of common partition
in NVRAM to a separate file in /dev/pstore. For instance, common partition
details will be stored in a file named [common-nvram-6].

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |   17 -
 fs/pstore/inode.c  |3 +++
 include/linux/pstore.h |1 +
 3 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index de448af..8417816 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -138,10 +138,17 @@ static struct nvram_os_partition of_config_partition = {
.os_partition = false
 };
 
+static struct nvram_os_partition common_partition = {
+   .name = common,
+   .index = -1,
+   .os_partition = false
+};
+
 static enum pstore_type_id nvram_type_ids[] = {
PSTORE_TYPE_DMESG,
PSTORE_TYPE_RTAS,
PSTORE_TYPE_OF,
+   PSTORE_TYPE_COMMON,
-1
 };
 static int read_type;
@@ -530,7 +537,7 @@ static int nvram_pstore_write(enum pstore_type_id type,
 }
 
 /*
- * Reads the oops/panic report, rtas and of-config partition.
+ * Reads the oops/panic report, rtas, of-config and common partition.
  * Returns the length of the data we read from each partition.
  * Returns 0 if we've been called before.
  */
@@ -566,6 +573,14 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
time-tv_sec = 0;
time-tv_nsec = 0;
break;
+   case PSTORE_TYPE_COMMON:
+   sig = NVRAM_SIG_SYS;
+   part = common_partition;
+   *type = PSTORE_TYPE_COMMON;
+   *id = PSTORE_TYPE_COMMON;
+   time-tv_sec = 0;
+   time-tv_nsec = 0;
+   break;
default:
return 0;
}
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index 8d4fb65..88cc050 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -330,6 +330,9 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, 
u64 id, int count,
case PSTORE_TYPE_PPC_OF:
sprintf(name, of-%s-%lld, psname, id);
break;
+   case PSTORE_TYPE_PPC_COMMON:
+   sprintf(name, common-%s-%lld, psname, id);
+   break;
case PSTORE_TYPE_UNKNOWN:
sprintf(name, unknown-%s-%lld, psname, id);
break;
diff --git a/include/linux/pstore.h b/include/linux/pstore.h
index 615dc18..656699f 100644
--- a/include/linux/pstore.h
+++ b/include/linux/pstore.h
@@ -38,6 +38,7 @@ enum pstore_type_id {
/* PPC64 partition types */
PSTORE_TYPE_PPC_RTAS= 4,
PSTORE_TYPE_PPC_OF  = 5,
+   PSTORE_TYPE_PPC_COMMON  = 6,
PSTORE_TYPE_UNKNOWN = 255
 };
 

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


[PATCH v2 2/8] powerpc/pseries: Add version and timestamp to oops header

2013-04-24 Thread Aruna Balakrishnaiah
Introduce version and timestamp information in the oops header.
oops_log_info (oops header) holds version (to distinguish between old
and new format oops header), length of the oops text
(compressed or uncompressed) and timestamp.

The version field will sit in the same place as the length in old
headers. version is assigned 5000 (greater than oops partition size)
so that existing tools will refuse to dump new style partitions as
the length is too large. The updated tools will work with both
old and new format headers.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |   57 +---
 1 file changed, 38 insertions(+), 19 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index e54a8b7..742735a 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -29,6 +29,13 @@
 /* Max bytes to read/write in one go */
 #define NVRW_CNT 0x20
 
+/*
+ * Set oops header version to distingush between old and new format header.
+ * lnx,oops-log partition max size is 4000, header version  4000 will
+ * help in identifying new header.
+ */
+#define OOPS_HDR_VERSION 5000
+
 static unsigned int nvram_size;
 static int nvram_fetch, nvram_store;
 static char nvram_buf[NVRW_CNT];   /* assume this is in the first 4GB */
@@ -67,6 +74,12 @@ static const char *pseries_nvram_os_partitions[] = {
NULL
 };
 
+struct oops_log_info {
+   u16 version;
+   u16 report_length;
+   u64 timestamp;
+} __attribute__((packed));
+
 static void oops_to_nvram(struct kmsg_dumper *dumper,
  enum kmsg_dump_reason reason);
 
@@ -83,28 +96,28 @@ static unsigned long last_unread_rtas_event;/* 
timestamp */
 
  * big_oops_buf[] holds the uncompressed text we're capturing.
  *
- * oops_buf[] holds the compressed text, preceded by a prefix.
- * The prefix is just a u16 holding the length of the compressed* text.
- * (*Or uncompressed, if compression fails.)  oops_buf[] gets written
- * to NVRAM.
+ * oops_buf[] holds the compressed text, preceded by a oops header.
+ * oops header has u16 holding the version of oops header (to differentiate
+ * between old and new format header) followed by u16 holding the length of
+ * the compressed* text (*Or uncompressed, if compression fails.) and u64
+ * holding the timestamp. oops_buf[] gets written to NVRAM.
  *
- * oops_len points to the prefix.  oops_data points to the compressed text.
+ * oops_log_info points to the header. oops_data points to the compressed text.
  *
  * +- oops_buf
- * |   +- oops_data
- * v   v
- * ++---+
- * | length| text  |
- * | (2 bytes) | (oops_data_sz bytes)  |
- * ++---+
+ * |   +- oops_data
+ * v   v
+ * +---+---+---++
+ * | version   | length| timestamp | text   |
+ * | (2 bytes) | (2 bytes) | (8 bytes) | (oops_data_sz bytes)   |
+ * +---+---+---++
  * ^
- * +- oops_len
+ * +- oops_log_info
  *
  * We preallocate these buffers during init to avoid kmalloc during oops/panic.
  */
 static size_t big_oops_buf_sz;
 static char *big_oops_buf, *oops_buf;
-static u16 *oops_len;
 static char *oops_data;
 static size_t oops_data_sz;
 
@@ -425,9 +438,8 @@ static void __init nvram_init_oops_partition(int 
rtas_partition_exists)
oops_log_partition.name);
return;
}
-   oops_len = (u16*) oops_buf;
-   oops_data = oops_buf + sizeof(u16);
-   oops_data_sz = oops_log_partition.size - sizeof(u16);
+   oops_data = oops_buf + sizeof(struct oops_log_info);
+   oops_data_sz = oops_log_partition.size - sizeof(struct oops_log_info);
 
/*
 * Figure compression (preceded by elimination of each line's n
@@ -555,6 +567,7 @@ error:
 /* Compress the text from big_oops_buf into oops_buf. */
 static int zip_oops(size_t text_len)
 {
+   struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf;
int zipped_len = nvram_compress(big_oops_buf, oops_data, text_len,
oops_data_sz);
if (zipped_len  0) {
@@ -562,7 +575,9 @@ static int zip_oops(size_t text_len)
pr_err(nvram: logging uncompressed oops/panic report\n);
return -1;
}
-   *oops_len = (u16) zipped_len;
+   oops_hdr-version = OOPS_HDR_VERSION;
+   oops_hdr-report_length = (u16) zipped_len;
+   oops_hdr-timestamp = get_seconds();
return 0;
 }
 
@@ -576,6 +591,7

Re: [PATCH v2 7/8] powerpc/pseries: Read of-config partition via pstore

2013-04-24 Thread Aruna Balakrishnaiah

On Thursday 25 April 2013 02:13 AM, Kees Cook wrote:

Hi Kees,


On Tue, Apr 23, 2013 at 11:20 PM, Aruna Balakrishnaiah
ar...@linux.vnet.ibm.com wrote:

This patch set exploits the pstore subsystem to read details of
of-config partition in NVRAM to a separate file in /dev/pstore.
For instance, of-config partition details will be stored in a
file named [of-nvram-5].

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
  arch/powerpc/platforms/pseries/nvram.c |   55 +++-
  fs/pstore/inode.c  |3 ++
  include/linux/pstore.h |1 +
  3 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index b118382..de448af 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -132,9 +132,16 @@ static size_t oops_data_sz;
  static struct z_stream_s stream;

  #ifdef CONFIG_PSTORE
+static struct nvram_os_partition of_config_partition = {
+   .name = of-config,
+   .index = -1,
+   .os_partition = false
+};
+
  static enum pstore_type_id nvram_type_ids[] = {
 PSTORE_TYPE_DMESG,
 PSTORE_TYPE_RTAS,
+   PSTORE_TYPE_OF,
 -1
  };
  static int read_type;
@@ -332,10 +339,15 @@ int nvram_read_partition(struct nvram_os_partition *part, 
char *buff,

 tmp_index = part-index;

-   rc = ppc_md.nvram_read((char *)info, sizeof(struct err_log_info), 
tmp_index);
-   if (rc = 0) {
-   pr_err(%s: Failed nvram_read (%d)\n, __FUNCTION__, rc);
-   return rc;
+   if (part-os_partition) {
+   rc = ppc_md.nvram_read((char *)info,
+   sizeof(struct err_log_info),
+   tmp_index);
+   if (rc = 0) {
+   pr_err(%s: Failed nvram_read (%d)\n, __FUNCTION__,
+   rc);
+   return rc;
+   }
 }

 rc = ppc_md.nvram_read(buff, length, tmp_index);
@@ -344,8 +356,10 @@ int nvram_read_partition(struct nvram_os_partition *part, 
char *buff,
 return rc;
 }

-   *error_log_cnt = info.seq_num;
-   *err_type = info.error_type;
+   if (part-os_partition) {
+   *error_log_cnt = info.seq_num;
+   *err_type = info.error_type;
+   }

 return 0;
  }
@@ -516,7 +530,7 @@ static int nvram_pstore_write(enum pstore_type_id type,
  }

  /*
- * Reads the oops/panic report and ibm,rtas-log partition.
+ * Reads the oops/panic report, rtas and of-config partition.
   * Returns the length of the data we read from each partition.
   * Returns 0 if we've been called before.
   */
@@ -525,9 +539,11 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
 struct pstore_info *psi)
  {
 struct oops_log_info *oops_hdr;
-   unsigned int err_type, id_no;
+   unsigned int err_type, id_no, size = 0;
 struct nvram_os_partition *part = NULL;
 char *buff = NULL;
+   int sig = 0;
+   loff_t p;

 read_type++;

@@ -542,10 +558,29 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
 time-tv_sec = last_rtas_event;
 time-tv_nsec = 0;
 break;
+   case PSTORE_TYPE_OF:
+   sig = NVRAM_SIG_OF;
+   part = of_config_partition;
+   *type = PSTORE_TYPE_OF;
+   *id = PSTORE_TYPE_OF;
+   time-tv_sec = 0;
+   time-tv_nsec = 0;
+   break;
 default:
 return 0;
 }

+   if (!part-os_partition) {
+   p = nvram_find_partition(part-name, sig, size);
+   if (p = 0) {
+   pr_err(nvram: Failed to find partition %s, 
+   err %d\n, part-name, (int)p);
+   return 0;
+   }
+   part-index = p;
+   part-size = size;
+   }
+
 buff = kmalloc(part-size, GFP_KERNEL);

 if (!buff)
@@ -557,7 +592,9 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
 }

 *count = 0;
-   *id = id_no;
+
+   if (part-os_partition)
+   *id = id_no;

 if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) {
 oops_hdr = (struct oops_log_info *)buff;
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index ec24f9c..8d4fb65 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -327,6 +327,9 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, 
u64 id, int count,
 case PSTORE_TYPE_PPC_RTAS:
 sprintf(name, rtas-%s-%lld, psname, id);
 break;
+   case

Re: [PATCH v2 0/8] powerpc/pseries: Nvram-to-pstore

2013-04-24 Thread Aruna Balakrishnaiah

Hi Kees,

On Thursday 25 April 2013 02:15 AM, Kees Cook wrote:

On Tue, Apr 23, 2013 at 11:19 PM, Aruna Balakrishnaiah
ar...@linux.vnet.ibm.com wrote:

Currently the kernel provides the contents of p-series NVRAM only as a
simple stream of bytes via /dev/nvram, which must be interpreted in user
space by the nvram command in the powerpc-utils package. This patch set
exploits the pstore subsystem to expose each partition in NVRAM as a
separate file in /dev/pstore. For instance Oops messages will stored in a
file named [dmesg-nvram-2].

Changes from v1:
 - Reduce #ifdefs by and remove forward declarations of pstore callbacks
 - Handle return value of nvram_write_os_partition
 - Remove empty pstore callbacks and register pstore only when pstore
   is configured

---

Aruna Balakrishnaiah (8):
   powerpc/pseries: Remove syslog prefix in uncompressed oops text
   powerpc/pseries: Add version and timestamp to oops header
   powerpc/pseries: Introduce generic read function to read nvram-partitions
   powerpc/pseries: Read/Write oops nvram partition via pstore
   powerpc/pseries: Read rtas partition via pstore
   powerpc/pseries: Distinguish between a os-partition and non-os partition
   powerpc/pseries: Read of-config partition via pstore
   powerpc/pseries: Read common partition via pstore


  arch/powerpc/platforms/pseries/nvram.c |  353 +++-
  fs/pstore/inode.c  |9 +
  include/linux/pstore.h |4
  3 files changed, 313 insertions(+), 53 deletions(-)

This series looks good! Other than the naming conventions (are these
new pstore types really PPC-only?) I think it's a fine addition.

Thanks!


The new pstore types are PPC specific. Hence it would be better to have the
(_PPC) in the type ids so that other does not end up using these ids.


-Kees

--
Kees Cook
Chrome OS Security



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


[PATCH v3 0/8] Nvram-to-pstore

2013-04-25 Thread Aruna Balakrishnaiah
Currently the kernel provides the contents of p-series NVRAM only as a
simple stream of bytes via /dev/nvram, which must be interpreted in user
space by the nvram command in the powerpc-utils package. This patch set
exploits the pstore subsystem to expose each partition in NVRAM as a
separate file in /dev/pstore. For instance Oops messages will stored in a
file named [dmesg-nvram-2].

Changes from v2:
- Fix renaming of pstore type ids in nvram.c

Changes from v1:
- Reduce #ifdefs by and remove forward declarations of pstore callbacks
- Handle return value of nvram_write_os_partition
- Remove empty pstore callbacks and register pstore only when pstore
  is configured
---

Aruna Balakrishnaiah (8):
  powerpc/pseries: Remove syslog prefix in uncompressed oops text
  powerpc/pseries: Add version and timestamp to oops header
  powerpc/pseries: Introduce generic read function to read nvram-partitions
  powerpc/pseries: Read/Write oops nvram partition via pstore
  powerpc/pseries: Read rtas partition via pstore
  powerpc/pseries: Distinguish between a os-partition and non-os partition
  powerpc/pseries: Read of-config partition via pstore
  powerpc/pseries: Read common partition via pstore


 arch/powerpc/platforms/pseries/nvram.c |  353 +++-
 fs/pstore/inode.c  |9 +
 include/linux/pstore.h |4 
 3 files changed, 313 insertions(+), 53 deletions(-)

-- 

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


[PATCH v3 1/8] powerpc/pseries: Remove syslog prefix in uncompressed oops text

2013-04-25 Thread Aruna Balakrishnaiah
Removal of syslog prefix in the uncompressed oops text will
help in capturing more oops data.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 8733a86..e54a8b7 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -619,7 +619,7 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
}
if (rc != 0) {
kmsg_dump_rewind(dumper);
-   kmsg_dump_get_buffer(dumper, true,
+   kmsg_dump_get_buffer(dumper, false,
 oops_data, oops_data_sz, text_len);
err_type = ERR_TYPE_KERNEL_PANIC;
*oops_len = (u16) text_len;

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


[PATCH v3 2/8] powerpc/pseries: Add version and timestamp to oops header

2013-04-25 Thread Aruna Balakrishnaiah
Introduce version and timestamp information in the oops header.
oops_log_info (oops header) holds version (to distinguish between old
and new format oops header), length of the oops text
(compressed or uncompressed) and timestamp.

The version field will sit in the same place as the length in old
headers. version is assigned 5000 (greater than oops partition size)
so that existing tools will refuse to dump new style partitions as
the length is too large. The updated tools will work with both
old and new format headers.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |   57 +---
 1 file changed, 38 insertions(+), 19 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index e54a8b7..742735a 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -29,6 +29,13 @@
 /* Max bytes to read/write in one go */
 #define NVRW_CNT 0x20
 
+/*
+ * Set oops header version to distingush between old and new format header.
+ * lnx,oops-log partition max size is 4000, header version  4000 will
+ * help in identifying new header.
+ */
+#define OOPS_HDR_VERSION 5000
+
 static unsigned int nvram_size;
 static int nvram_fetch, nvram_store;
 static char nvram_buf[NVRW_CNT];   /* assume this is in the first 4GB */
@@ -67,6 +74,12 @@ static const char *pseries_nvram_os_partitions[] = {
NULL
 };
 
+struct oops_log_info {
+   u16 version;
+   u16 report_length;
+   u64 timestamp;
+} __attribute__((packed));
+
 static void oops_to_nvram(struct kmsg_dumper *dumper,
  enum kmsg_dump_reason reason);
 
@@ -83,28 +96,28 @@ static unsigned long last_unread_rtas_event;/* 
timestamp */
 
  * big_oops_buf[] holds the uncompressed text we're capturing.
  *
- * oops_buf[] holds the compressed text, preceded by a prefix.
- * The prefix is just a u16 holding the length of the compressed* text.
- * (*Or uncompressed, if compression fails.)  oops_buf[] gets written
- * to NVRAM.
+ * oops_buf[] holds the compressed text, preceded by a oops header.
+ * oops header has u16 holding the version of oops header (to differentiate
+ * between old and new format header) followed by u16 holding the length of
+ * the compressed* text (*Or uncompressed, if compression fails.) and u64
+ * holding the timestamp. oops_buf[] gets written to NVRAM.
  *
- * oops_len points to the prefix.  oops_data points to the compressed text.
+ * oops_log_info points to the header. oops_data points to the compressed text.
  *
  * +- oops_buf
- * |   +- oops_data
- * v   v
- * ++---+
- * | length| text  |
- * | (2 bytes) | (oops_data_sz bytes)  |
- * ++---+
+ * |   +- oops_data
+ * v   v
+ * +---+---+---++
+ * | version   | length| timestamp | text   |
+ * | (2 bytes) | (2 bytes) | (8 bytes) | (oops_data_sz bytes)   |
+ * +---+---+---++
  * ^
- * +- oops_len
+ * +- oops_log_info
  *
  * We preallocate these buffers during init to avoid kmalloc during oops/panic.
  */
 static size_t big_oops_buf_sz;
 static char *big_oops_buf, *oops_buf;
-static u16 *oops_len;
 static char *oops_data;
 static size_t oops_data_sz;
 
@@ -425,9 +438,8 @@ static void __init nvram_init_oops_partition(int 
rtas_partition_exists)
oops_log_partition.name);
return;
}
-   oops_len = (u16*) oops_buf;
-   oops_data = oops_buf + sizeof(u16);
-   oops_data_sz = oops_log_partition.size - sizeof(u16);
+   oops_data = oops_buf + sizeof(struct oops_log_info);
+   oops_data_sz = oops_log_partition.size - sizeof(struct oops_log_info);
 
/*
 * Figure compression (preceded by elimination of each line's n
@@ -555,6 +567,7 @@ error:
 /* Compress the text from big_oops_buf into oops_buf. */
 static int zip_oops(size_t text_len)
 {
+   struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf;
int zipped_len = nvram_compress(big_oops_buf, oops_data, text_len,
oops_data_sz);
if (zipped_len  0) {
@@ -562,7 +575,9 @@ static int zip_oops(size_t text_len)
pr_err(nvram: logging uncompressed oops/panic report\n);
return -1;
}
-   *oops_len = (u16) zipped_len;
+   oops_hdr-version = OOPS_HDR_VERSION;
+   oops_hdr-report_length = (u16) zipped_len;
+   oops_hdr-timestamp = get_seconds();
return 0;
 }
 
@@ -576,6 +591,7

[PATCH v3 3/8] powerpc/pseries: Introduce generic read function to read nvram-partitions

2013-04-25 Thread Aruna Balakrishnaiah
Introduce generic read function to read nvram partitions other than rtas.
nvram_read_error_log will be retained which is used to read rtas partition
from rtasd. nvram_read_partition is the generic read function to read from
any nvram partition.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |   32 ++--
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 742735a..088f023 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -293,34 +293,35 @@ int nvram_write_error_log(char * buff, int length,
return rc;
 }
 
-/* nvram_read_error_log
+/* nvram_read_partition
  *
- * Reads nvram for error log for at most 'length'
+ * Reads nvram partition for at most 'length'
  */
-int nvram_read_error_log(char * buff, int length,
- unsigned int * err_type, unsigned int * error_log_cnt)
+int nvram_read_partition(struct nvram_os_partition *part, char *buff,
+   int length, unsigned int *err_type,
+   unsigned int *error_log_cnt)
 {
int rc;
loff_t tmp_index;
struct err_log_info info;

-   if (rtas_log_partition.index == -1)
+   if (part-index == -1)
return -1;
 
-   if (length  rtas_log_partition.size)
-   length = rtas_log_partition.size;
+   if (length  part-size)
+   length = part-size;
 
-   tmp_index = rtas_log_partition.index;
+   tmp_index = part-index;
 
rc = ppc_md.nvram_read((char *)info, sizeof(struct err_log_info), 
tmp_index);
if (rc = 0) {
-   printk(KERN_ERR nvram_read_error_log: Failed nvram_read 
(%d)\n, rc);
+   pr_err(%s: Failed nvram_read (%d)\n, __FUNCTION__, rc);
return rc;
}
 
rc = ppc_md.nvram_read(buff, length, tmp_index);
if (rc = 0) {
-   printk(KERN_ERR nvram_read_error_log: Failed nvram_read 
(%d)\n, rc);
+   pr_err(%s: Failed nvram_read (%d)\n, __FUNCTION__, rc);
return rc;
}
 
@@ -330,6 +331,17 @@ int nvram_read_error_log(char * buff, int length,
return 0;
 }
 
+/* nvram_read_error_log
+ *
+ * Reads nvram for error log for at most 'length'
+ */
+int nvram_read_error_log(char *buff, int length,
+   unsigned int *err_type, unsigned int *error_log_cnt)
+{
+   return nvram_read_partition(rtas_log_partition, buff, length,
+   err_type, error_log_cnt);
+}
+
 /* This doesn't actually zero anything, but it sets the event_logged
  * word to tell that this event is safely in syslog.
  */

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


[PATCH v3 4/8] powerpc/pseries: Read/Write oops nvram partition via pstore

2013-04-25 Thread Aruna Balakrishnaiah
IBM's p series machines provide persistent storage for LPARs through NVRAM.
NVRAM's lnx,oops-log partition is used to log oops messages.
Currently the kernel provides the contents of p-series NVRAM only as a
simple stream of bytes via /dev/nvram, which must be interpreted in user
space by the nvram command in the powerpc-utils package.

This patch set exploits the pstore subsystem to expose oops partition in
NVRAM as a separate file in /dev/pstore. For instance, Oops messages will be
stored in a file named [dmesg-nvram-2]. In case pstore registration fails it
will fall back to kmsg_dump mechanism.

This patch will read/write the oops messages from/to this partition via pstore.

Signed-off-by: Jim Keniston jkeni...@us.ibm.com
Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |  172 +---
 1 file changed, 157 insertions(+), 15 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 088f023..9edec8e 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -18,6 +18,7 @@
 #include linux/spinlock.h
 #include linux/slab.h
 #include linux/kmsg_dump.h
+#include linux/pstore.h
 #include linux/ctype.h
 #include linux/zlib.h
 #include asm/uaccess.h
@@ -127,6 +128,14 @@ static size_t oops_data_sz;
 #define MEM_LEVEL 4
 static struct z_stream_s stream;
 
+#ifdef CONFIG_PSTORE
+static enum pstore_type_id nvram_type_ids[] = {
+   PSTORE_TYPE_DMESG,
+   -1
+};
+static int read_type;
+#endif
+
 static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index)
 {
unsigned int i;
@@ -430,6 +439,149 @@ static int __init pseries_nvram_init_os_partition(struct 
nvram_os_partition
return 0;
 }
 
+/*
+ * Are we using the ibm,rtas-log for oops/panic reports?  And if so,
+ * would logging this oops/panic overwrite an RTAS event that rtas_errd
+ * hasn't had a chance to read and process?  Return 1 if so, else 0.
+ *
+ * We assume that if rtas_errd hasn't read the RTAS event in
+ * NVRAM_RTAS_READ_TIMEOUT seconds, it's probably not going to.
+ */
+static int clobbering_unread_rtas_event(void)
+{
+   return (oops_log_partition.index == rtas_log_partition.index
+last_unread_rtas_event
+get_seconds() - last_unread_rtas_event =
+   NVRAM_RTAS_READ_TIMEOUT);
+}
+
+#ifdef CONFIG_PSTORE
+static int nvram_pstore_open(struct pstore_info *psi)
+{
+   /* Reset the iterator to start reading partitions again */
+   read_type = -1;
+   return 0;
+}
+
+/**
+ * nvram_pstore_write - pstore write callback for nvram
+ * @type:   Type of message logged
+ * @reason: reason behind dump (oops/panic)
+ * @id: identifier to indicate the write performed
+ * @part:   pstore writes data to registered buffer in parts,
+ *  part number will indicate the same.
+ * @count:  Indicates oops count
+ * @size:   number of bytes written to the registered buffer
+ * @psi:registered pstore_info structure
+ *
+ * Called by pstore_dump() when an oops or panic report is logged in the
+ * printk buffer.
+ * Returns 0 on successful write.
+ */
+static int nvram_pstore_write(enum pstore_type_id type,
+   enum kmsg_dump_reason reason,
+   u64 *id, unsigned int part, int count,
+   size_t size, struct pstore_info *psi)
+{
+   int rc;
+   struct oops_log_info *oops_hdr = (struct oops_log_info *) oops_buf;
+
+   /* part 1 has the recent messages from printk buffer */
+   if (part  1 || type != PSTORE_TYPE_DMESG ||
+   clobbering_unread_rtas_event())
+   return -1;
+
+   oops_hdr-version = OOPS_HDR_VERSION;
+   oops_hdr-report_length = (u16) size;
+   oops_hdr-timestamp = get_seconds();
+   rc = nvram_write_os_partition(oops_log_partition, oops_buf,
+   (int) (sizeof(*oops_hdr) + size), ERR_TYPE_KERNEL_PANIC,
+   count);
+
+   if (rc != 0)
+   return rc;
+
+   *id = part;
+   return 0;
+}
+
+/*
+ * Reads the oops/panic report.
+ * Returns the length of the data we read from each partition.
+ * Returns 0 if we've been called before.
+ */
+static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type,
+   int *count, struct timespec *time, char **buf,
+   struct pstore_info *psi)
+{
+   struct oops_log_info *oops_hdr;
+   unsigned int err_type, id_no;
+   struct nvram_os_partition *part = NULL;
+   char *buff = NULL;
+
+   read_type++;
+
+   switch (nvram_type_ids[read_type]) {
+   case PSTORE_TYPE_DMESG:
+   part = oops_log_partition;
+   *type

[PATCH v3 5/8] powerpc/pseries: Read rtas partition via pstore

2013-04-25 Thread Aruna Balakrishnaiah
This patch set exploits the pstore subsystem to read details of rtas partition
in NVRAM to a separate file in /dev/pstore. For instance, rtas details will be
stored in a file named [rtas-nvram-4].

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |   33 +---
 fs/pstore/inode.c  |3 +++
 include/linux/pstore.h |2 ++
 3 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 9edec8e..78d72f0 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -131,9 +131,11 @@ static struct z_stream_s stream;
 #ifdef CONFIG_PSTORE
 static enum pstore_type_id nvram_type_ids[] = {
PSTORE_TYPE_DMESG,
+   PSTORE_TYPE_PPC_RTAS,
-1
 };
 static int read_type;
+static unsigned long last_rtas_event;
 #endif
 
 static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index)
@@ -297,8 +299,13 @@ int nvram_write_error_log(char * buff, int length,
 {
int rc = nvram_write_os_partition(rtas_log_partition, buff, length,
err_type, error_log_cnt);
-   if (!rc)
+   if (!rc) {
last_unread_rtas_event = get_seconds();
+#ifdef CONFIG_PSTORE
+   last_rtas_event = get_seconds();
+#endif
+   }
+
return rc;
 }
 
@@ -506,7 +513,7 @@ static int nvram_pstore_write(enum pstore_type_id type,
 }
 
 /*
- * Reads the oops/panic report.
+ * Reads the oops/panic report and ibm,rtas-log partition.
  * Returns the length of the data we read from each partition.
  * Returns 0 if we've been called before.
  */
@@ -526,6 +533,12 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
part = oops_log_partition;
*type = PSTORE_TYPE_DMESG;
break;
+   case PSTORE_TYPE_PPC_RTAS:
+   part = rtas_log_partition;
+   *type = PSTORE_TYPE_PPC_RTAS;
+   time-tv_sec = last_rtas_event;
+   time-tv_nsec = 0;
+   break;
default:
return 0;
}
@@ -542,11 +555,17 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
 
*count = 0;
*id = id_no;
-   oops_hdr = (struct oops_log_info *)buff;
-   *buf = buff + sizeof(*oops_hdr);
-   time-tv_sec = oops_hdr-timestamp;
-   time-tv_nsec = 0;
-   return oops_hdr-report_length;
+
+   if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) {
+   oops_hdr = (struct oops_log_info *)buff;
+   *buf = buff + sizeof(*oops_hdr);
+   time-tv_sec = oops_hdr-timestamp;
+   time-tv_nsec = 0;
+   return oops_hdr-report_length;
+   }
+
+   *buf = buff;
+   return part-size;
 }
 
 static struct pstore_info nvram_pstore_info = {
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index e4bcb2c..ec24f9c 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -324,6 +324,9 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, 
u64 id, int count,
case PSTORE_TYPE_MCE:
sprintf(name, mce-%s-%lld, psname, id);
break;
+   case PSTORE_TYPE_PPC_RTAS:
+   sprintf(name, rtas-%s-%lld, psname, id);
+   break;
case PSTORE_TYPE_UNKNOWN:
sprintf(name, unknown-%s-%lld, psname, id);
break;
diff --git a/include/linux/pstore.h b/include/linux/pstore.h
index 75d0176..d7a8fe9 100644
--- a/include/linux/pstore.h
+++ b/include/linux/pstore.h
@@ -35,6 +35,8 @@ enum pstore_type_id {
PSTORE_TYPE_MCE = 1,
PSTORE_TYPE_CONSOLE = 2,
PSTORE_TYPE_FTRACE  = 3,
+   /* PPC64 partition types */
+   PSTORE_TYPE_PPC_RTAS= 4,
PSTORE_TYPE_UNKNOWN = 255
 };
 

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


[PATCH v3 8/8] powerpc/pseries: Read common partition via pstore

2013-04-25 Thread Aruna Balakrishnaiah
This patch exploits pstore subsystem to read details of common partition
in NVRAM to a separate file in /dev/pstore. For instance, common partition
details will be stored in a file named [common-nvram-6].

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |   17 -
 fs/pstore/inode.c  |3 +++
 include/linux/pstore.h |1 +
 3 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index f7392f6..14cc486 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -138,10 +138,17 @@ static struct nvram_os_partition of_config_partition = {
.os_partition = false
 };
 
+static struct nvram_os_partition common_partition = {
+   .name = common,
+   .index = -1,
+   .os_partition = false
+};
+
 static enum pstore_type_id nvram_type_ids[] = {
PSTORE_TYPE_DMESG,
PSTORE_TYPE_PPC_RTAS,
PSTORE_TYPE_PPC_OF,
+   PSTORE_TYPE_PPC_COMMON,
-1
 };
 static int read_type;
@@ -530,7 +537,7 @@ static int nvram_pstore_write(enum pstore_type_id type,
 }
 
 /*
- * Reads the oops/panic report, rtas and of-config partition.
+ * Reads the oops/panic report, rtas, of-config and common partition.
  * Returns the length of the data we read from each partition.
  * Returns 0 if we've been called before.
  */
@@ -566,6 +573,14 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
time-tv_sec = 0;
time-tv_nsec = 0;
break;
+   case PSTORE_TYPE_PPC_COMMON:
+   sig = NVRAM_SIG_SYS;
+   part = common_partition;
+   *type = PSTORE_TYPE_PPC_COMMON;
+   *id = PSTORE_TYPE_PPC_COMMON;
+   time-tv_sec = 0;
+   time-tv_nsec = 0;
+   break;
default:
return 0;
}
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index 8d4fb65..88cc050 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -330,6 +330,9 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, 
u64 id, int count,
case PSTORE_TYPE_PPC_OF:
sprintf(name, of-%s-%lld, psname, id);
break;
+   case PSTORE_TYPE_PPC_COMMON:
+   sprintf(name, common-%s-%lld, psname, id);
+   break;
case PSTORE_TYPE_UNKNOWN:
sprintf(name, unknown-%s-%lld, psname, id);
break;
diff --git a/include/linux/pstore.h b/include/linux/pstore.h
index 615dc18..656699f 100644
--- a/include/linux/pstore.h
+++ b/include/linux/pstore.h
@@ -38,6 +38,7 @@ enum pstore_type_id {
/* PPC64 partition types */
PSTORE_TYPE_PPC_RTAS= 4,
PSTORE_TYPE_PPC_OF  = 5,
+   PSTORE_TYPE_PPC_COMMON  = 6,
PSTORE_TYPE_UNKNOWN = 255
 };
 

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


[PATCH v3 7/8] powerpc/pseries: Read of-config partition via pstore

2013-04-25 Thread Aruna Balakrishnaiah
This patch set exploits the pstore subsystem to read details of
of-config partition in NVRAM to a separate file in /dev/pstore.
For instance, of-config partition details will be stored in a
file named [of-nvram-5].

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |   55 +++-
 fs/pstore/inode.c  |3 ++
 include/linux/pstore.h |1 +
 3 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 714ed8a..f7392f6 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -132,9 +132,16 @@ static size_t oops_data_sz;
 static struct z_stream_s stream;
 
 #ifdef CONFIG_PSTORE
+static struct nvram_os_partition of_config_partition = {
+   .name = of-config,
+   .index = -1,
+   .os_partition = false
+};
+
 static enum pstore_type_id nvram_type_ids[] = {
PSTORE_TYPE_DMESG,
PSTORE_TYPE_PPC_RTAS,
+   PSTORE_TYPE_PPC_OF,
-1
 };
 static int read_type;
@@ -332,10 +339,15 @@ int nvram_read_partition(struct nvram_os_partition *part, 
char *buff,
 
tmp_index = part-index;
 
-   rc = ppc_md.nvram_read((char *)info, sizeof(struct err_log_info), 
tmp_index);
-   if (rc = 0) {
-   pr_err(%s: Failed nvram_read (%d)\n, __FUNCTION__, rc);
-   return rc;
+   if (part-os_partition) {
+   rc = ppc_md.nvram_read((char *)info,
+   sizeof(struct err_log_info),
+   tmp_index);
+   if (rc = 0) {
+   pr_err(%s: Failed nvram_read (%d)\n, __FUNCTION__,
+   rc);
+   return rc;
+   }
}
 
rc = ppc_md.nvram_read(buff, length, tmp_index);
@@ -344,8 +356,10 @@ int nvram_read_partition(struct nvram_os_partition *part, 
char *buff,
return rc;
}
 
-   *error_log_cnt = info.seq_num;
-   *err_type = info.error_type;
+   if (part-os_partition) {
+   *error_log_cnt = info.seq_num;
+   *err_type = info.error_type;
+   }
 
return 0;
 }
@@ -516,7 +530,7 @@ static int nvram_pstore_write(enum pstore_type_id type,
 }
 
 /*
- * Reads the oops/panic report and ibm,rtas-log partition.
+ * Reads the oops/panic report, rtas and of-config partition.
  * Returns the length of the data we read from each partition.
  * Returns 0 if we've been called before.
  */
@@ -525,9 +539,11 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
struct pstore_info *psi)
 {
struct oops_log_info *oops_hdr;
-   unsigned int err_type, id_no;
+   unsigned int err_type, id_no, size = 0;
struct nvram_os_partition *part = NULL;
char *buff = NULL;
+   int sig = 0;
+   loff_t p;
 
read_type++;
 
@@ -542,10 +558,29 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
time-tv_sec = last_rtas_event;
time-tv_nsec = 0;
break;
+   case PSTORE_TYPE_PPC_OF:
+   sig = NVRAM_SIG_OF;
+   part = of_config_partition;
+   *type = PSTORE_TYPE_PPC_OF;
+   *id = PSTORE_TYPE_PPC_OF;
+   time-tv_sec = 0;
+   time-tv_nsec = 0;
+   break;
default:
return 0;
}
 
+   if (!part-os_partition) {
+   p = nvram_find_partition(part-name, sig, size);
+   if (p = 0) {
+   pr_err(nvram: Failed to find partition %s, 
+   err %d\n, part-name, (int)p);
+   return 0;
+   }
+   part-index = p;
+   part-size = size;
+   }
+
buff = kmalloc(part-size, GFP_KERNEL);
 
if (!buff)
@@ -557,7 +592,9 @@ static ssize_t nvram_pstore_read(u64 *id, enum 
pstore_type_id *type,
}
 
*count = 0;
-   *id = id_no;
+
+   if (part-os_partition)
+   *id = id_no;
 
if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) {
oops_hdr = (struct oops_log_info *)buff;
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index ec24f9c..8d4fb65 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -327,6 +327,9 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, 
u64 id, int count,
case PSTORE_TYPE_PPC_RTAS:
sprintf(name, rtas-%s-%lld, psname, id);
break;
+   case PSTORE_TYPE_PPC_OF:
+   sprintf(name, of-%s-%lld, psname, id);
+   break;
case PSTORE_TYPE_UNKNOWN:
sprintf(name, unknown-%s-%lld

[PATCH v3 6/8] powerpc/pseries: Distinguish between a os-partition and non-os partition

2013-04-25 Thread Aruna Balakrishnaiah
Introduce os_partition member in nvram_os_partition structure to identify
if the partition is an os partition or not. This will be useful to handle
non-os partitions of-config and common.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
Reviewed-by: Jim Keniston jkeni...@us.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 78d72f0..714ed8a 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -53,20 +53,23 @@ struct nvram_os_partition {
int min_size;   /* minimum acceptable size (0 means req_size) */
long size;  /* size of data portion (excluding err_log_info) */
long index; /* offset of data portion of partition */
+   bool os_partition; /* partition initialized by OS, not FW */
 };
 
 static struct nvram_os_partition rtas_log_partition = {
.name = ibm,rtas-log,
.req_size = 2079,
.min_size = 1055,
-   .index = -1
+   .index = -1,
+   .os_partition = true
 };
 
 static struct nvram_os_partition oops_log_partition = {
.name = lnx,oops-log,
.req_size = 4000,
.min_size = 2000,
-   .index = -1
+   .index = -1,
+   .os_partition = true
 };
 
 static const char *pseries_nvram_os_partitions[] = {

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


[RFC PATCH 0/3] Nvram-to-pstore: compression support for oops data

2013-04-26 Thread Aruna Balakrishnaiah
The patchset takes care of compressing oops messages while writing to NVRAM,
so that more oops data can be captured in the given space.

big_oops_buf (2.22 * oops_data_sz) is allocated for compression.
oops_data_sz is oops header size less of oops partition size.

Pstore will internally call kmsg_dump to capture messages from printk
buffer. While returning the data to nvram it adds is own header.

For compression:
Register pstore with big_oops_buf. 

In case compression fails, copy header added by pstore and
last oops_data_sz bytes (recent messages) of big_oops_buf to
nvram for which we need to know header size. 

patch 01/03 will add a function in pstore to return the header size.

pstore read callback of nvram will read the compressed data and return the
decompressed data so that dmesg file (under /dev/pstore) is readable.

In case decompression fails, instead of having the compressed data (junk) in the
dmesg file it will skip and continue reading other partitions. This results in
absence of dmesg file but will still have files relating to other parititons.


---

Aruna Balakrishnaiah (3):
  Retreive header size from pstore.
  powerpc/pseries: Re-organise the oops compression code
  powerpc/pseries: Support compression of oops text via pstore


 arch/powerpc/platforms/pseries/nvram.c |  236 +++-
 fs/pstore/platform.c   |7 +
 include/linux/pstore.h |6 +
 3 files changed, 182 insertions(+), 67 deletions(-)

-- 

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


[PATCH 1/3] Retreive header size from pstore.

2013-04-26 Thread Aruna Balakrishnaiah
pstore_get_header_size will return the size of the header added by pstore
while logging messages to the registered buffer.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
---
 fs/pstore/platform.c   |7 ++-
 include/linux/pstore.h |6 ++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 86d1038..e8260ea 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -49,6 +49,7 @@ MODULE_PARM_DESC(update_ms, milliseconds before pstore 
updates its content 
 corruption on Oopses));
 
 static int pstore_new_entry;
+static int hsize;
 
 static void pstore_timefunc(unsigned long);
 static DEFINE_TIMER(pstore_timer, pstore_timefunc, 0, 0);
@@ -68,6 +69,11 @@ static char *backend;
 /* How much of the console log to snapshot */
 static unsigned long kmsg_bytes = 10240;
 
+int pstore_get_header_size(void)
+{
+   return hsize;
+}
+
 void pstore_set_kmsg_bytes(int bytes)
 {
kmsg_bytes = bytes;
@@ -147,7 +153,6 @@ static void pstore_dump(struct kmsg_dumper *dumper,
while (total  kmsg_bytes) {
char *dst;
unsigned long size;
-   int hsize;
size_t len;
 
dst = psinfo-buf;
diff --git a/include/linux/pstore.h b/include/linux/pstore.h
index 656699f..f43b64f 100644
--- a/include/linux/pstore.h
+++ b/include/linux/pstore.h
@@ -73,6 +73,7 @@ struct pstore_info {
 #ifdef CONFIG_PSTORE
 extern int pstore_register(struct pstore_info *);
 extern bool pstore_cannot_block_path(enum kmsg_dump_reason reason);
+extern int pstore_get_header_size(void);
 #else
 static inline int
 pstore_register(struct pstore_info *psi)
@@ -84,6 +85,11 @@ pstore_cannot_block_path(enum kmsg_dump_reason reason)
 {
return false;
 }
+static inline int
+pstore_get_header_size(void)
+{
+   return 0;
+}
 #endif
 
 #endif /*_LINUX_PSTORE_H*/

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


[PATCH 3/3] powerpc/pseries: Support compression of oops text via pstore

2013-04-26 Thread Aruna Balakrishnaiah
The patch set supports compression of oops messages while writing to NVRAM,
this helps in capturing more of oops data to lnx,oops-log. The pstore file
for oops messages will be in decompressed format making it readable.

In case compression fails, the patch takes care of copying the header added
by pstore and last oops_data_sz bytes of big_oops_buf to NVRAM so that we
have recent oops messages in lnx,oops-log.

In case decompression fails, it will result in absence of oops file but still
have files (in /dev/pstore) for other partitions.

Signed-off-by: Aruna Balakrishnaiah ar...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/pseries/nvram.c |  132 +---
 1 file changed, 118 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/nvram.c 
b/arch/powerpc/platforms/pseries/nvram.c
index 0159d74..b5ba5e2 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -539,6 +539,65 @@ 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 unzip_oops(char *oops_buf, char *big_buf)
+{
+   struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf;
+   u64 timestamp = oops_hdr-timestamp;
+   char *big_oops_data = NULL;
+   char *oops_data_buf = NULL;
+   size_t big_oops_data_sz;
+   int unzipped_len;
+
+   big_oops_data = big_buf + sizeof(struct oops_log_info);
+   big_oops_data_sz = big_oops_buf_sz - sizeof(struct oops_log_info);
+   oops_data_buf = oops_buf + sizeof(struct oops_log_info);
+
+   unzipped_len = nvram_decompress(oops_data_buf, big_oops_data,
+   oops_hdr-report_length,
+   big_oops_data_sz);
+
+   if (unzipped_len  0) {
+   pr_err(nvram: decompression failed; returned %d\n,
+   unzipped_len);
+   return -1;
+   }
+   oops_hdr = (struct oops_log_info *)big_buf;
+   oops_hdr-version = OOPS_HDR_VERSION;
+   oops_hdr-report_length = (u16) unzipped_len;
+   oops_hdr-timestamp = timestamp;
+   return 0;
+}
+
 static int nvram_pstore_open(struct pstore_info *psi)
 {
/* Reset the iterator to start reading partitions again */
@@ -567,6 +626,7 @@ static int nvram_pstore_write(enum pstore_type_id type,
size_t size, struct pstore_info *psi)
 {
int rc;
+   unsigned int err_type = ERR_TYPE_KERNEL_PANIC;
struct oops_log_info *oops_hdr = (struct oops_log_info *) oops_buf;
 
/* part 1 has the recent messages from printk buffer */
@@ -577,8 +637,31 @@ static int nvram_pstore_write(enum pstore_type_id type,
oops_hdr-version = OOPS_HDR_VERSION;
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) {
+   int hsize = pstore_get_header_size();
+   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) + size), ERR_TYPE_KERNEL_PANIC,
+   (int) (sizeof(*oops_hdr) + oops_hdr-report_length), err_type,
count);
 
if (rc != 0)
@@ -600,10 +683,11 @@ 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

  1   2   3   >