diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-04 08:14:06 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-04 08:14:06 +0400 |
commit | f83b0a4e4c33aa31dac0b8b48f1f3a470edc933a (patch) | |
tree | fade92500aa68531de6cd4761cc4693ea901540b /arch | |
parent | 32dad03d164206ea886885d0740284ba215b0970 (diff) | |
parent | 3bd11cf56e4d9c9a79c0c1a4ebe381c674ec9709 (diff) | |
download | linux-f83b0a4e4c33aa31dac0b8b48f1f3a470edc933a.tar.xz |
Merge tag 'please-pull-pstore' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux
Pull pstore changes from Tony Luck:
"A big part of this is the addition of compression to the generic
pstore layer so that all backends can use the pitiful amounts of
storage they control more effectively. Three other small
fixes/cleanups too.
* tag 'please-pull-pstore' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux:
pstore/ram: (really) fix undefined usage of rounddown_pow_of_two
pstore/ram: Read and write to the 'compressed' flag of pstore
efi-pstore: Read and write to the 'compressed' flag of pstore
erst: Read and write to the 'compressed' flag of pstore
powerpc/pseries: Read and write to the 'compressed' flag of pstore
pstore: Add file extension to pstore file if compressed
pstore: Add decompression support to pstore
pstore: Introduce new argument 'compressed' in the read callback
pstore: Add compression support to pstore
pstore/Kconfig: Select ZLIB_DEFLATE and ZLIB_INFLATE when PSTORE is selected
pstore: Add new argument 'compressed' in pstore write callback
powerpc/pseries: Remove (de)compression in nvram with pstore enabled
pstore: d_alloc_name() doesn't return an ERR_PTR
acpi/apei/erst: Add missing iounmap() on error in erst_exec_move_data()
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/platforms/pseries/nvram.c | 112 |
1 files changed, 21 insertions, 91 deletions
diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index 6a5f2b1f32ca..d276cd3edd8f 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 */ @@ -584,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 * @@ -595,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; @@ -611,30 +581,11 @@ 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; - } + 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); + (int) (sizeof(*oops_hdr) + size), err_type, count); if (rc != 0) return rc; @@ -650,12 +601,12 @@ 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; struct nvram_os_partition *part = NULL; - char *buff = NULL, *big_buff = NULL; + char *buff = NULL; int sig = 0; loff_t p; @@ -719,8 +670,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) { @@ -741,23 +691,10 @@ static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type, 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; - } - } + if (err_type == ERR_TYPE_KERNEL_PANIC_GZ) + *compressed = true; + else + *compressed = false; return length; } @@ -777,13 +714,8 @@ static int nvram_pstore_init(void) { int rc = 0; - if (big_oops_buf) { - nvram_pstore_info.buf = big_oops_buf; - nvram_pstore_info.bufsize = big_oops_buf_sz; - } else { - nvram_pstore_info.buf = oops_data; - nvram_pstore_info.bufsize = oops_data_sz; - } + nvram_pstore_info.buf = oops_data; + nvram_pstore_info.bufsize = oops_data_sz; rc = pstore_register(&nvram_pstore_info); if (rc != 0) @@ -802,7 +734,6 @@ static int nvram_pstore_init(void) static void __init nvram_init_oops_partition(int rtas_partition_exists) { int rc; - size_t size; rc = pseries_nvram_init_os_partition(&oops_log_partition); if (rc != 0) { @@ -823,6 +754,11 @@ static void __init nvram_init_oops_partition(int rtas_partition_exists) oops_data = oops_buf + sizeof(struct oops_log_info); oops_data_sz = oops_log_partition.size - sizeof(struct oops_log_info); + rc = nvram_pstore_init(); + + if (!rc) + return; + /* * Figure compression (preceded by elimination of each line's <n> * severity prefix) will reduce the oops/panic report to at most @@ -831,9 +767,8 @@ static void __init nvram_init_oops_partition(int rtas_partition_exists) big_oops_buf_sz = (oops_data_sz * 100) / 45; big_oops_buf = kmalloc(big_oops_buf_sz, GFP_KERNEL); if (big_oops_buf) { - size = max(zlib_deflate_workspacesize(WINDOW_BITS, MEM_LEVEL), - zlib_inflate_workspacesize()); - stream.workspace = kmalloc(size, GFP_KERNEL); + stream.workspace = kmalloc(zlib_deflate_workspacesize( + WINDOW_BITS, MEM_LEVEL), GFP_KERNEL); if (!stream.workspace) { pr_err("nvram: No memory for compression workspace; " "skipping compression of %s partition data\n", @@ -847,11 +782,6 @@ static void __init nvram_init_oops_partition(int rtas_partition_exists) stream.workspace = NULL; } - rc = nvram_pstore_init(); - - if (!rc) - return; - rc = kmsg_dump_register(&nvram_kmsg_dumper); if (rc != 0) { pr_err("nvram: kmsg_dump_register() failed; returned %d\n", rc); |