* [PATCH 00/13] staging: Android updates
@ 2012-03-07 21:58 John Stultz
2012-03-07 21:58 ` [PATCH 01/13] android: lowmemorykiller: Fix warning on 64bit John Stultz
` (13 more replies)
0 siblings, 14 replies; 25+ messages in thread
From: John Stultz @ 2012-03-07 21:58 UTC (permalink / raw)
To: lkml; +Cc: John Stultz, Greg KH, Android Kernel Team
Hi Greg,
Just wanted to send along some Android updates to the staging-next tree
so they can be queued for 3.4. I've pulled these from the
common/android-3.3 branch, and made only some minor changes to keep
everything in the staging dir and to avoid compile issues on x86.
The patches can be browsed over here:
http://git.linaro.org/gitweb?p=people/jstultz/android-dev.git;a=shortlog;h=refs/heads/dev/android-staging-updates
thanks
-john
CC: Greg KH <gregkh@linuxfoundation.org>
CC: Android Kernel Team <kernel-team@android.com>
Colin Cross (10):
android: ram_console: move footer strings
android: ram_console: drop early buffer support
android: ram_console: drop verbose ram_console support
android: ram_console: split out persistent ram
android: persistent_ram: refactor ecc support
android: persistent_ram: handle reserving and mapping memory
android: persistent_ram: make persistent_ram_write atomic
android: persistent_ram: add notrace to persistent_ram_write
android: persistent_trace: ftrace into persistent_ram
android: staging: ram_console: fix crash in ram_console_late_init
Dima Zavin (1):
android: ram_console: set CON_ANYTIME console flag
John Stultz (1):
android: lowmemorykiller: Fix warning on 64bit
Nick Kralevich (1):
android: ram_console: honor dmesg_restrict
drivers/staging/android/Kconfig | 70 +---
drivers/staging/android/Makefile | 4 +
drivers/staging/android/lowmemorykiller.c | 2 +-
drivers/staging/android/persistent_ram.c | 470 ++++++++++++++++++++++++++++
drivers/staging/android/persistent_ram.h | 78 +++++
drivers/staging/android/ram_console.c | 412 +++++--------------------
drivers/staging/android/trace_persistent.c | 242 ++++++++++++++
7 files changed, 887 insertions(+), 391 deletions(-)
create mode 100644 drivers/staging/android/persistent_ram.c
create mode 100644 drivers/staging/android/persistent_ram.h
create mode 100644 drivers/staging/android/trace_persistent.c
--
1.7.3.2.146.gca209
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 01/13] android: lowmemorykiller: Fix warning on 64bit
2012-03-07 21:58 [PATCH 00/13] staging: Android updates John Stultz
@ 2012-03-07 21:58 ` John Stultz
2012-03-07 22:04 ` Greg KH
2012-03-07 21:58 ` [PATCH 02/13] android: ram_console: set CON_ANYTIME console flag John Stultz
` (12 subsequent siblings)
13 siblings, 1 reply; 25+ messages in thread
From: John Stultz @ 2012-03-07 21:58 UTC (permalink / raw)
To: lkml; +Cc: John Stultz, Greg KH, Android Kernel Team
Fixes the following warning on 64bit:
drivers/staging/android/lowmemorykiller.c: In function ‘__check_minfree’:
drivers/staging/android/lowmemorykiller.c:215: warning: return from incompatible pointer type
CC: Greg KH <gregkh@linuxfoundation.org>
CC: Android Kernel Team <kernel-team@android.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
drivers/staging/android/lowmemorykiller.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index 052b43e..15a59c1 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -212,7 +212,7 @@ static void __exit lowmem_exit(void)
module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR);
module_param_array_named(adj, lowmem_adj, int, &lowmem_adj_size,
S_IRUGO | S_IWUSR);
-module_param_array_named(minfree, lowmem_minfree, uint, &lowmem_minfree_size,
+module_param_array_named(minfree, lowmem_minfree, ulong, &lowmem_minfree_size,
S_IRUGO | S_IWUSR);
module_param_named(debug_level, lowmem_debug_level, uint, S_IRUGO | S_IWUSR);
--
1.7.3.2.146.gca209
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 02/13] android: ram_console: set CON_ANYTIME console flag
2012-03-07 21:58 [PATCH 00/13] staging: Android updates John Stultz
2012-03-07 21:58 ` [PATCH 01/13] android: lowmemorykiller: Fix warning on 64bit John Stultz
@ 2012-03-07 21:58 ` John Stultz
2012-03-07 22:07 ` Greg KH
2012-03-07 21:58 ` [PATCH 03/13] android: ram_console: move footer strings John Stultz
` (11 subsequent siblings)
13 siblings, 1 reply; 25+ messages in thread
From: John Stultz @ 2012-03-07 21:58 UTC (permalink / raw)
To: lkml; +Cc: Dima Zavin, Greg KH, Android Kernel Team, John Stultz
From: Dima Zavin <dima@android.com>
We want to ensure that we get all the console messages, even ones
that occur while the printing CPU is not yet online.
CC: Greg KH <gregkh@linuxfoundation.org>
CC: Android Kernel Team <kernel-team@android.com>
Change-Id: I1d2694d05ac9415669a92f38efdd8e71c927705b
Signed-off-by: Dima Zavin <dima@android.com>
[jstultz: tweaked commit subject line]
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
drivers/staging/android/ram_console.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c
index fabd398..f01a0c4 100644
--- a/drivers/staging/android/ram_console.c
+++ b/drivers/staging/android/ram_console.c
@@ -143,7 +143,7 @@ ram_console_write(struct console *console, const char *s, unsigned int count)
static struct console ram_console = {
.name = "ram",
.write = ram_console_write,
- .flags = CON_PRINTBUFFER | CON_ENABLED,
+ .flags = CON_PRINTBUFFER | CON_ENABLED | CON_ANYTIME,
.index = -1,
};
--
1.7.3.2.146.gca209
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 03/13] android: ram_console: move footer strings
2012-03-07 21:58 [PATCH 00/13] staging: Android updates John Stultz
2012-03-07 21:58 ` [PATCH 01/13] android: lowmemorykiller: Fix warning on 64bit John Stultz
2012-03-07 21:58 ` [PATCH 02/13] android: ram_console: set CON_ANYTIME console flag John Stultz
@ 2012-03-07 21:58 ` John Stultz
2012-03-07 21:58 ` [PATCH 04/13] android: ram_console: drop early buffer support John Stultz
` (10 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: John Stultz @ 2012-03-07 21:58 UTC (permalink / raw)
To: lkml; +Cc: Colin Cross, Greg KH, Android Kernel Team, John Stultz
From: Colin Cross <ccross@android.com>
Don't store the bootinfo string and the ecc status string with
the recovered old log data. This will simplify refactoring the
persistent ram code out of the ram console code later.
CC: Greg KH <gregkh@linuxfoundation.org>
CC: Android Kernel Team <kernel-team@android.com>
Change-Id: I883bb6eec5bad5c1b1247da807e982e744fe40ba
Signed-off-by: Colin Cross <ccross@android.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
drivers/staging/android/ram_console.c | 115 +++++++++++++++++++-------------
1 files changed, 68 insertions(+), 47 deletions(-)
diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c
index f01a0c4..2310a79 100644
--- a/drivers/staging/android/ram_console.c
+++ b/drivers/staging/android/ram_console.c
@@ -42,6 +42,8 @@ static char __initdata
#endif
static char *ram_console_old_log;
static size_t ram_console_old_log_size;
+static const char *bootinfo;
+static size_t bootinfo_size;
static struct ram_console_buffer *ram_console_buffer;
static size_t ram_console_buffer_size;
@@ -156,20 +158,13 @@ void ram_console_enable_console(int enabled)
}
static void __init
-ram_console_save_old(struct ram_console_buffer *buffer, const char *bootinfo,
- char *dest)
+ram_console_save_old(struct ram_console_buffer *buffer, char *dest)
{
size_t old_log_size = buffer->size;
- size_t bootinfo_size = 0;
- size_t total_size = old_log_size;
- char *ptr;
- const char *bootinfo_label = "Boot info:\n";
#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
uint8_t *block;
uint8_t *par;
- char strbuf[80];
- int strbuf_len = 0;
block = buffer->data;
par = ram_console_par_buffer;
@@ -195,24 +190,10 @@ ram_console_save_old(struct ram_console_buffer *buffer, const char *bootinfo,
block += ECC_BLOCK_SIZE;
par += ECC_SIZE;
}
- if (ram_console_corrected_bytes || ram_console_bad_blocks)
- strbuf_len = snprintf(strbuf, sizeof(strbuf),
- "\n%d Corrected bytes, %d unrecoverable blocks\n",
- ram_console_corrected_bytes, ram_console_bad_blocks);
- else
- strbuf_len = snprintf(strbuf, sizeof(strbuf),
- "\nNo errors detected\n");
- if (strbuf_len >= sizeof(strbuf))
- strbuf_len = sizeof(strbuf) - 1;
- total_size += strbuf_len;
#endif
- if (bootinfo)
- bootinfo_size = strlen(bootinfo) + strlen(bootinfo_label);
- total_size += bootinfo_size;
-
if (dest == NULL) {
- dest = kmalloc(total_size, GFP_KERNEL);
+ dest = kmalloc(old_log_size, GFP_KERNEL);
if (dest == NULL) {
printk(KERN_ERR
"ram_console: failed to allocate buffer\n");
@@ -221,27 +202,15 @@ ram_console_save_old(struct ram_console_buffer *buffer, const char *bootinfo,
}
ram_console_old_log = dest;
- ram_console_old_log_size = total_size;
+ ram_console_old_log_size = old_log_size;
memcpy(ram_console_old_log,
&buffer->data[buffer->start], buffer->size - buffer->start);
memcpy(ram_console_old_log + buffer->size - buffer->start,
&buffer->data[0], buffer->start);
- ptr = ram_console_old_log + old_log_size;
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
- memcpy(ptr, strbuf, strbuf_len);
- ptr += strbuf_len;
-#endif
- if (bootinfo) {
- memcpy(ptr, bootinfo_label, strlen(bootinfo_label));
- ptr += strlen(bootinfo_label);
- memcpy(ptr, bootinfo, bootinfo_size);
- ptr += bootinfo_size;
- }
}
static int __init ram_console_init(struct ram_console_buffer *buffer,
- size_t buffer_size, const char *bootinfo,
- char *old_buf)
+ size_t buffer_size, char *old_buf)
{
#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
int numerr;
@@ -308,7 +277,7 @@ static int __init ram_console_init(struct ram_console_buffer *buffer,
printk(KERN_INFO "ram_console: found existing buffer, "
"size %d, start %d\n",
buffer->size, buffer->start);
- ram_console_save_old(buffer, bootinfo, old_buf);
+ ram_console_save_old(buffer, old_buf);
}
} else {
printk(KERN_INFO "ram_console: no valid data in buffer "
@@ -326,6 +295,24 @@ static int __init ram_console_init(struct ram_console_buffer *buffer,
return 0;
}
+static ssize_t ram_console_ecc_string(char *str, size_t len)
+{
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+ ssize_t ret;
+
+ if (ram_console_corrected_bytes || ram_console_bad_blocks)
+ ret = snprintf(str, len, ""
+ "\n%d Corrected bytes, %d unrecoverable blocks\n",
+ ram_console_corrected_bytes, ram_console_bad_blocks);
+ else
+ ret = snprintf(str, len, "\nNo errors detected\n");
+
+ return ret;
+#else
+ return 0;
+#endif
+}
+
#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT
static int __init ram_console_early_init(void)
{
@@ -342,7 +329,6 @@ static int ram_console_driver_probe(struct platform_device *pdev)
size_t start;
size_t buffer_size;
void *buffer;
- const char *bootinfo = NULL;
struct ram_console_platform_data *pdata = pdev->dev.platform_data;
if (res == NULL || pdev->num_resources != 1 ||
@@ -361,10 +347,13 @@ static int ram_console_driver_probe(struct platform_device *pdev)
return -ENOMEM;
}
- if (pdata)
- bootinfo = pdata->bootinfo;
+ if (pdata) {
+ bootinfo = kstrdup(pdata->bootinfo, GFP_KERNEL);
+ if (bootinfo)
+ bootinfo_size = strlen(bootinfo);
+ }
- return ram_console_init(buffer, buffer_size, bootinfo, NULL/* allocate */);
+ return ram_console_init(buffer, buffer_size, NULL/* allocate */);
}
static struct platform_driver ram_console_driver = {
@@ -387,14 +376,46 @@ static ssize_t ram_console_read_old(struct file *file, char __user *buf,
{
loff_t pos = *offset;
ssize_t count;
+ char *str;
+ int ret;
+
+ /* Main last_kmsg log */
+ if (pos < ram_console_old_log_size) {
+ count = min(len, (size_t)(ram_console_old_log_size - pos));
+ if (copy_to_user(buf, ram_console_old_log + pos, count))
+ return -EFAULT;
+ goto out;
+ }
- if (pos >= ram_console_old_log_size)
- return 0;
+ /* ECC correction notice */
+ pos -= ram_console_old_log_size;
+ count = ram_console_ecc_string(NULL, 0);
+ if (pos < count) {
+ str = kmalloc(count, GFP_KERNEL);
+ if (!str)
+ return -ENOMEM;
+ ram_console_ecc_string(str, count + 1);
+ count = min(len, (size_t)(count - pos));
+ ret = copy_to_user(buf, str + pos, count);
+ kfree(str);
+ if (ret)
+ return -EFAULT;
+ goto out;
+ }
- count = min(len, (size_t)(ram_console_old_log_size - pos));
- if (copy_to_user(buf, ram_console_old_log + pos, count))
- return -EFAULT;
+ /* Boot info passed through pdata */
+ pos -= count;
+ if (pos < bootinfo_size) {
+ count = min(len, (size_t)(bootinfo_size - pos));
+ if (copy_to_user(buf, bootinfo + pos, count))
+ return -EFAULT;
+ goto out;
+ }
+
+ /* EOF */
+ return 0;
+out:
*offset += count;
return count;
}
--
1.7.3.2.146.gca209
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 04/13] android: ram_console: drop early buffer support
2012-03-07 21:58 [PATCH 00/13] staging: Android updates John Stultz
` (2 preceding siblings ...)
2012-03-07 21:58 ` [PATCH 03/13] android: ram_console: move footer strings John Stultz
@ 2012-03-07 21:58 ` John Stultz
2012-03-07 21:58 ` [PATCH 05/13] android: ram_console: drop verbose ram_console support John Stultz
` (9 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: John Stultz @ 2012-03-07 21:58 UTC (permalink / raw)
To: lkml; +Cc: Colin Cross, Greg KH, Android Kernel Team, John Stultz
From: Colin Cross <ccross@android.com>
Early ramconsole is not very useful, an early crash will prevent
getting the logged data out on the next boot, and CONFIG_DEBUG_LL=y
will get the same information. Drop it to simplify a future
refactoring.
CC: Greg KH <gregkh@linuxfoundation.org>
CC: Android Kernel Team <kernel-team@android.com>
Change-Id: Ifc306db9a8cceec4ca980cf24783c3fe764eb1fb
Signed-off-by: Colin Cross <ccross@android.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
drivers/staging/android/Kconfig | 16 ----------------
drivers/staging/android/ram_console.c | 29 -----------------------------
2 files changed, 0 insertions(+), 45 deletions(-)
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index f3b7c75..20034e6 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -39,7 +39,6 @@ menuconfig ANDROID_RAM_CONSOLE_ERROR_CORRECTION
bool "Android RAM Console Enable error correction"
default n
depends on ANDROID_RAM_CONSOLE
- depends on !ANDROID_RAM_CONSOLE_EARLY_INIT
select REED_SOLOMON
select REED_SOLOMON_ENC8
select REED_SOLOMON_DEC8
@@ -70,21 +69,6 @@ config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL
endif # ANDROID_RAM_CONSOLE_ERROR_CORRECTION
-config ANDROID_RAM_CONSOLE_EARLY_INIT
- bool "Start Android RAM console early"
- default n
- depends on ANDROID_RAM_CONSOLE
-
-config ANDROID_RAM_CONSOLE_EARLY_ADDR
- hex "Android RAM console virtual address"
- default 0
- depends on ANDROID_RAM_CONSOLE_EARLY_INIT
-
-config ANDROID_RAM_CONSOLE_EARLY_SIZE
- hex "Android RAM console buffer size"
- default 0
- depends on ANDROID_RAM_CONSOLE_EARLY_INIT
-
config ANDROID_TIMED_OUTPUT
bool "Timed output class driver"
default y
diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c
index 2310a79..ed7827b 100644
--- a/drivers/staging/android/ram_console.c
+++ b/drivers/staging/android/ram_console.c
@@ -36,10 +36,6 @@ struct ram_console_buffer {
#define RAM_CONSOLE_SIG (0x43474244) /* DBGC */
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT
-static char __initdata
- ram_console_old_log_init_buffer[CONFIG_ANDROID_RAM_CONSOLE_EARLY_SIZE];
-#endif
static char *ram_console_old_log;
static size_t ram_console_old_log_size;
static const char *bootinfo;
@@ -313,16 +309,6 @@ static ssize_t ram_console_ecc_string(char *str, size_t len)
#endif
}
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT
-static int __init ram_console_early_init(void)
-{
- return ram_console_init((struct ram_console_buffer *)
- CONFIG_ANDROID_RAM_CONSOLE_EARLY_ADDR,
- CONFIG_ANDROID_RAM_CONSOLE_EARLY_SIZE,
- NULL,
- ram_console_old_log_init_buffer);
-}
-#else
static int ram_console_driver_probe(struct platform_device *pdev)
{
struct resource *res = pdev->resource;
@@ -369,7 +355,6 @@ static int __init ram_console_module_init(void)
err = platform_driver_register(&ram_console_driver);
return err;
}
-#endif
static ssize_t ram_console_read_old(struct file *file, char __user *buf,
size_t len, loff_t *offset)
@@ -431,16 +416,6 @@ static int __init ram_console_late_init(void)
if (ram_console_old_log == NULL)
return 0;
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT
- ram_console_old_log = kmemdup(ram_console_old_log_init_buffer,
- ram_console_old_log_size, GFP_KERNEL);
- if (ram_console_old_log == NULL) {
- printk(KERN_ERR
- "ram_console: failed to allocate buffer for old log\n");
- ram_console_old_log_size = 0;
- return 0;
- }
-#endif
entry = create_proc_entry("last_kmsg", S_IFREG | S_IRUGO, NULL);
if (!entry) {
printk(KERN_ERR "ram_console: failed to create proc entry\n");
@@ -454,10 +429,6 @@ static int __init ram_console_late_init(void)
return 0;
}
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT
-console_initcall(ram_console_early_init);
-#else
postcore_initcall(ram_console_module_init);
-#endif
late_initcall(ram_console_late_init);
--
1.7.3.2.146.gca209
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 05/13] android: ram_console: drop verbose ram_console support
2012-03-07 21:58 [PATCH 00/13] staging: Android updates John Stultz
` (3 preceding siblings ...)
2012-03-07 21:58 ` [PATCH 04/13] android: ram_console: drop early buffer support John Stultz
@ 2012-03-07 21:58 ` John Stultz
2012-03-07 21:58 ` [PATCH 06/13] android: ram_console: split out persistent ram John Stultz
` (8 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: John Stultz @ 2012-03-07 21:58 UTC (permalink / raw)
To: lkml; +Cc: Colin Cross, Greg KH, Android Kernel Team, John Stultz
From: Colin Cross <ccross@android.com>
Equivalent functionality can be obtained with loglevel=15
CC: Greg KH <gregkh@linuxfoundation.org>
CC: Android Kernel Team <kernel-team@android.com>
Change-Id: I977d70f3b72fd48cfbb9f791de37e74ac711ce21
Signed-off-by: Colin Cross <ccross@android.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
drivers/staging/android/Kconfig | 5 -----
drivers/staging/android/ram_console.c | 3 ---
2 files changed, 0 insertions(+), 8 deletions(-)
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index 20034e6..3144ddb 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -30,11 +30,6 @@ config ANDROID_RAM_CONSOLE
depends on !S390 && !UML
default n
-config ANDROID_RAM_CONSOLE_ENABLE_VERBOSE
- bool "Enable verbose console messages on Android RAM console"
- default y
- depends on ANDROID_RAM_CONSOLE
-
menuconfig ANDROID_RAM_CONSOLE_ERROR_CORRECTION
bool "Android RAM Console Enable error correction"
default n
diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c
index ed7827b..73215e2 100644
--- a/drivers/staging/android/ram_console.c
+++ b/drivers/staging/android/ram_console.c
@@ -285,9 +285,6 @@ static int __init ram_console_init(struct ram_console_buffer *buffer,
buffer->size = 0;
register_console(&ram_console);
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ENABLE_VERBOSE
- console_verbose();
-#endif
return 0;
}
--
1.7.3.2.146.gca209
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 06/13] android: ram_console: split out persistent ram
2012-03-07 21:58 [PATCH 00/13] staging: Android updates John Stultz
` (4 preceding siblings ...)
2012-03-07 21:58 ` [PATCH 05/13] android: ram_console: drop verbose ram_console support John Stultz
@ 2012-03-07 21:58 ` John Stultz
2012-03-07 21:58 ` [PATCH 07/13] android: persistent_ram: refactor ecc support John Stultz
` (7 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: John Stultz @ 2012-03-07 21:58 UTC (permalink / raw)
To: lkml; +Cc: Colin Cross, Greg KH, Android Kernel Team, John Stultz
From: Colin Cross <ccross@android.com>
Split ram_console into two halves.
persistent_ram is a set of apis that handle a block of memory
that does not get erased across a reboot. It provides functions
to fill it as a single buffer or a ring buffer, and to extract
the old data after a reboot. It handles ecc on the data to
correct bit errors introduced during reboot.
ram_console is now a small wrapper around persistent_ram that
feeds console data into the ringbuffer, and exports the old
data to /proc/last_kmsg after a reboot.
CC: Greg KH <gregkh@linuxfoundation.org>
CC: Android Kernel Team <kernel-team@android.com>
Change-Id: I8c7495e3a6a3dd7cdf3cb067e1afceb3b6aaef3c
Signed-off-by: Colin Cross <ccross@android.com>
[jstultz: Moved persistent_ram.h to staging dir]
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
drivers/staging/android/Kconfig | 6 +-
drivers/staging/android/Makefile | 1 +
drivers/staging/android/persistent_ram.c | 302 +++++++++++++++++++++++++++++
drivers/staging/android/persistent_ram.h | 52 +++++
drivers/staging/android/ram_console.c | 309 ++++--------------------------
5 files changed, 396 insertions(+), 274 deletions(-)
create mode 100644 drivers/staging/android/persistent_ram.c
create mode 100644 drivers/staging/android/persistent_ram.h
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index 3144ddb..3f7dbc5 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -25,15 +25,19 @@ config ANDROID_LOGGER
tristate "Android log driver"
default n
+config ANDROID_PERSISTENT_RAM
+ bool
+
config ANDROID_RAM_CONSOLE
bool "Android RAM buffer console"
depends on !S390 && !UML
+ select ANDROID_PERSISTENT_RAM
default n
menuconfig ANDROID_RAM_CONSOLE_ERROR_CORRECTION
bool "Android RAM Console Enable error correction"
default n
- depends on ANDROID_RAM_CONSOLE
+ depends on ANDROID_PERSISTENT_RAM
select REED_SOLOMON
select REED_SOLOMON_ENC8
select REED_SOLOMON_DEC8
diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile
index 785f269..9b6c9ed 100644
--- a/drivers/staging/android/Makefile
+++ b/drivers/staging/android/Makefile
@@ -1,6 +1,7 @@
obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o
obj-$(CONFIG_ASHMEM) += ashmem.o
obj-$(CONFIG_ANDROID_LOGGER) += logger.o
+obj-$(CONFIG_ANDROID_PERSISTENT_RAM) += persistent_ram.o
obj-$(CONFIG_ANDROID_RAM_CONSOLE) += ram_console.o
obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o
obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o
diff --git a/drivers/staging/android/persistent_ram.c b/drivers/staging/android/persistent_ram.c
new file mode 100644
index 0000000..d0f4666
--- /dev/null
+++ b/drivers/staging/android/persistent_ram.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2012 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include "persistent_ram.h"
+
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+#include <linux/rslib.h>
+#endif
+
+struct persistent_ram_buffer {
+ uint32_t sig;
+ uint32_t start;
+ uint32_t size;
+ uint8_t data[0];
+};
+
+#define PERSISTENT_RAM_SIG (0x43474244) /* DBGC */
+
+static LIST_HEAD(zone_list);
+
+#define ECC_BLOCK_SIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE
+#define ECC_SIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE
+#define ECC_SYMSIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE
+#define ECC_POLY CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL
+
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+static void persistent_ram_encode_rs8(struct persistent_ram_zone *prz,
+ uint8_t *data, size_t len, uint8_t *ecc)
+{
+ int i;
+ uint16_t par[ECC_SIZE];
+ /* Initialize the parity buffer */
+ memset(par, 0, sizeof(par));
+ encode_rs8(prz->rs_decoder, data, len, par, 0);
+ for (i = 0; i < ECC_SIZE; i++)
+ ecc[i] = par[i];
+}
+
+static int persistent_ram_decode_rs8(struct persistent_ram_zone *prz,
+ void *data, size_t len, uint8_t *ecc)
+{
+ int i;
+ uint16_t par[ECC_SIZE];
+ for (i = 0; i < ECC_SIZE; i++)
+ par[i] = ecc[i];
+ return decode_rs8(prz->rs_decoder, data, par, len,
+ NULL, 0, NULL, 0, NULL);
+}
+#endif
+
+static void persistent_ram_update(struct persistent_ram_zone *prz,
+ const void *s, unsigned int count)
+{
+ struct persistent_ram_buffer *buffer = prz->buffer;
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+ uint8_t *buffer_end = buffer->data + prz->buffer_size;
+ uint8_t *block;
+ uint8_t *par;
+ int size = ECC_BLOCK_SIZE;
+#endif
+ memcpy(buffer->data + buffer->start, s, count);
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+ block = buffer->data + (buffer->start & ~(ECC_BLOCK_SIZE - 1));
+ par = prz->par_buffer +
+ (buffer->start / ECC_BLOCK_SIZE) * ECC_SIZE;
+ do {
+ if (block + ECC_BLOCK_SIZE > buffer_end)
+ size = buffer_end - block;
+ persistent_ram_encode_rs8(prz, block, size, par);
+ block += ECC_BLOCK_SIZE;
+ par += ECC_SIZE;
+ } while (block < buffer->data + buffer->start + count);
+#endif
+}
+
+static void persistent_ram_update_header(struct persistent_ram_zone *prz)
+{
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+ struct persistent_ram_buffer *buffer = prz->buffer;
+
+ persistent_ram_encode_rs8(prz, (uint8_t *)buffer, sizeof(*buffer),
+ prz->par_header);
+#endif
+}
+
+static void __init
+persistent_ram_save_old(struct persistent_ram_zone *prz)
+{
+ struct persistent_ram_buffer *buffer = prz->buffer;
+ size_t old_log_size = buffer->size;
+ char *dest;
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+ uint8_t *block;
+ uint8_t *par;
+
+ block = buffer->data;
+ par = prz->par_buffer;
+ while (block < buffer->data + buffer->size) {
+ int numerr;
+ int size = ECC_BLOCK_SIZE;
+ if (block + size > buffer->data + prz->buffer_size)
+ size = buffer->data + prz->buffer_size - block;
+ numerr = persistent_ram_decode_rs8(prz, block, size, par);
+ if (numerr > 0) {
+#if 0
+ pr_info("persistent_ram: error in block %p, %d\n",
+ block, numerr);
+#endif
+ prz->corrected_bytes += numerr;
+ } else if (numerr < 0) {
+#if 0
+ pr_info("persistent_ram: uncorrectable error in block %p\n",
+ block);
+#endif
+ prz->bad_blocks++;
+ }
+ block += ECC_BLOCK_SIZE;
+ par += ECC_SIZE;
+ }
+#endif
+
+ dest = kmalloc(old_log_size, GFP_KERNEL);
+ if (dest == NULL) {
+ pr_err("persistent_ram: failed to allocate buffer\n");
+ return;
+ }
+
+ prz->old_log = dest;
+ prz->old_log_size = old_log_size;
+ memcpy(prz->old_log,
+ &buffer->data[buffer->start], buffer->size - buffer->start);
+ memcpy(prz->old_log + buffer->size - buffer->start,
+ &buffer->data[0], buffer->start);
+}
+
+int persistent_ram_write(struct persistent_ram_zone *prz,
+ const void *s, unsigned int count)
+{
+ int rem;
+ int c = count;
+ struct persistent_ram_buffer *buffer = prz->buffer;
+
+ if (c > prz->buffer_size) {
+ s += c - prz->buffer_size;
+ c = prz->buffer_size;
+ }
+ rem = prz->buffer_size - buffer->start;
+ if (rem < c) {
+ persistent_ram_update(prz, s, rem);
+ s += rem;
+ c -= rem;
+ buffer->start = 0;
+ buffer->size = prz->buffer_size;
+ }
+ persistent_ram_update(prz, s, c);
+
+ buffer->start += c;
+ if (buffer->size < prz->buffer_size)
+ buffer->size += c;
+ persistent_ram_update_header(prz);
+
+ return count;
+}
+
+ssize_t persistent_ram_ecc_string(struct persistent_ram_zone *prz,
+ char *str, size_t len)
+{
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+ ssize_t ret;
+
+ if (prz->corrected_bytes || prz->bad_blocks)
+ ret = snprintf(str, len, ""
+ "\n%d Corrected bytes, %d unrecoverable blocks\n",
+ prz->corrected_bytes, prz->bad_blocks);
+ else
+ ret = snprintf(str, len, "\nNo errors detected\n");
+
+ return ret;
+#else
+ return 0;
+#endif
+}
+
+size_t persistent_ram_old_size(struct persistent_ram_zone *prz)
+{
+ return prz->old_log_size;
+}
+
+void *persistent_ram_old(struct persistent_ram_zone *prz)
+{
+ return prz->old_log;
+}
+
+void persistent_ram_free_old(struct persistent_ram_zone *prz)
+{
+ kfree(prz->old_log);
+ prz->old_log = NULL;
+ prz->old_log_size = 0;
+}
+
+static int __init __persistent_ram_init(struct persistent_ram_zone *prz,
+ void __iomem *mem, size_t buffer_size)
+{
+ struct persistent_ram_buffer *buffer = mem;
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+ int numerr;
+#endif
+
+ INIT_LIST_HEAD(&prz->node);
+
+ prz->buffer = buffer;
+ prz->buffer_size = buffer_size - sizeof(struct persistent_ram_buffer);
+
+ if (prz->buffer_size > buffer_size) {
+ pr_err("persistent_ram: buffer %p, invalid size %zu, datasize %zu\n",
+ buffer, buffer_size, prz->buffer_size);
+ return -EINVAL;
+ }
+
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+ prz->buffer_size -= (DIV_ROUND_UP(prz->buffer_size,
+ ECC_BLOCK_SIZE) + 1) * ECC_SIZE;
+
+ if (prz->buffer_size > buffer_size) {
+ pr_err("persistent_ram: buffer %p, invalid size %zu, non-ecc datasize %zu\n",
+ buffer, buffer_size, prz->buffer_size);
+ return -EINVAL;
+ }
+
+ prz->par_buffer = buffer->data + prz->buffer_size;
+ prz->par_header = prz->par_buffer +
+ DIV_ROUND_UP(prz->buffer_size, ECC_BLOCK_SIZE) * ECC_SIZE;
+
+
+ /* first consecutive root is 0
+ * primitive element to generate roots = 1
+ */
+ prz->rs_decoder = init_rs(ECC_SYMSIZE, ECC_POLY, 0, 1, ECC_SIZE);
+ if (prz->rs_decoder == NULL) {
+ pr_info("persistent_ram: init_rs failed\n");
+ return -EINVAL;
+ }
+
+ prz->corrected_bytes = 0;
+ prz->bad_blocks = 0;
+
+ numerr = persistent_ram_decode_rs8(prz, buffer, sizeof(*buffer),
+ prz->par_header);
+ if (numerr > 0) {
+ pr_info("persistent_ram: error in header, %d\n", numerr);
+ prz->corrected_bytes += numerr;
+ } else if (numerr < 0) {
+ pr_info("persistent_ram: uncorrectable error in header\n");
+ prz->bad_blocks++;
+ }
+#endif
+
+ if (buffer->sig == PERSISTENT_RAM_SIG) {
+ if (buffer->size > prz->buffer_size
+ || buffer->start > buffer->size)
+ pr_info("persistent_ram: found existing invalid buffer, size %d, start %d\n",
+ buffer->size, buffer->start);
+ else {
+ pr_info("persistent_ram: found existing buffer, size %d, start %d\n",
+ buffer->size, buffer->start);
+ persistent_ram_save_old(prz);
+ }
+ } else {
+ pr_info("persistent_ram: no valid data in buffer (sig = 0x%08x)\n",
+ buffer->sig);
+ }
+
+ buffer->sig = PERSISTENT_RAM_SIG;
+ buffer->start = 0;
+ buffer->size = 0;
+
+ list_add_tail(&prz->node, &zone_list);
+
+ return 0;
+}
+
+int __init persistent_ram_init_ringbuffer(struct persistent_ram_zone *prz,
+ void __iomem *mem, size_t buffer_size)
+{
+ return __persistent_ram_init(prz, mem, buffer_size);
+}
diff --git a/drivers/staging/android/persistent_ram.h b/drivers/staging/android/persistent_ram.h
new file mode 100644
index 0000000..f73fb08
--- /dev/null
+++ b/drivers/staging/android/persistent_ram.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __LINUX_PERSISTENT_RAM_H__
+#define __LINUX_PERSISTENT_RAM_H__
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct persistent_ram_buffer;
+
+struct persistent_ram_zone {
+ struct list_head node;
+ struct persistent_ram_buffer *buffer;
+ size_t buffer_size;
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+ char *par_buffer;
+ char *par_header;
+ struct rs_control *rs_decoder;
+ int corrected_bytes;
+ int bad_blocks;
+#endif
+ char *old_log;
+ size_t old_log_size;
+ size_t old_log_footer_size;
+ bool early;
+};
+
+int persistent_ram_init_ringbuffer(struct persistent_ram_zone *prz,
+ void __iomem *buffer, size_t buffer_size);
+
+int persistent_ram_write(struct persistent_ram_zone *prz, const void *s,
+ unsigned int count);
+
+size_t persistent_ram_old_size(struct persistent_ram_zone *prz);
+void *persistent_ram_old(struct persistent_ram_zone *prz);
+void persistent_ram_free_old(struct persistent_ram_zone *prz);
+ssize_t persistent_ram_ecc_string(struct persistent_ram_zone *prz,
+ char *str, size_t len);
+
+#endif
diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c
index 73215e2..689c3dc 100644
--- a/drivers/staging/android/ram_console.c
+++ b/drivers/staging/android/ram_console.c
@@ -21,121 +21,18 @@
#include <linux/string.h>
#include <linux/uaccess.h>
#include <linux/io.h>
+#include "persistent_ram.h"
#include "ram_console.h"
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
-#include <linux/rslib.h>
-#endif
-
-struct ram_console_buffer {
- uint32_t sig;
- uint32_t start;
- uint32_t size;
- uint8_t data[0];
-};
-
-#define RAM_CONSOLE_SIG (0x43474244) /* DBGC */
-
-static char *ram_console_old_log;
-static size_t ram_console_old_log_size;
+static struct persistent_ram_zone ram_console_zone;
static const char *bootinfo;
static size_t bootinfo_size;
-static struct ram_console_buffer *ram_console_buffer;
-static size_t ram_console_buffer_size;
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
-static char *ram_console_par_buffer;
-static struct rs_control *ram_console_rs_decoder;
-static int ram_console_corrected_bytes;
-static int ram_console_bad_blocks;
-#define ECC_BLOCK_SIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE
-#define ECC_SIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE
-#define ECC_SYMSIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE
-#define ECC_POLY CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL
-#endif
-
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
-static void ram_console_encode_rs8(uint8_t *data, size_t len, uint8_t *ecc)
-{
- int i;
- uint16_t par[ECC_SIZE];
- /* Initialize the parity buffer */
- memset(par, 0, sizeof(par));
- encode_rs8(ram_console_rs_decoder, data, len, par, 0);
- for (i = 0; i < ECC_SIZE; i++)
- ecc[i] = par[i];
-}
-
-static int ram_console_decode_rs8(void *data, size_t len, uint8_t *ecc)
-{
- int i;
- uint16_t par[ECC_SIZE];
- for (i = 0; i < ECC_SIZE; i++)
- par[i] = ecc[i];
- return decode_rs8(ram_console_rs_decoder, data, par, len,
- NULL, 0, NULL, 0, NULL);
-}
-#endif
-
-static void ram_console_update(const char *s, unsigned int count)
-{
- struct ram_console_buffer *buffer = ram_console_buffer;
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
- uint8_t *buffer_end = buffer->data + ram_console_buffer_size;
- uint8_t *block;
- uint8_t *par;
- int size = ECC_BLOCK_SIZE;
-#endif
- memcpy(buffer->data + buffer->start, s, count);
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
- block = buffer->data + (buffer->start & ~(ECC_BLOCK_SIZE - 1));
- par = ram_console_par_buffer +
- (buffer->start / ECC_BLOCK_SIZE) * ECC_SIZE;
- do {
- if (block + ECC_BLOCK_SIZE > buffer_end)
- size = buffer_end - block;
- ram_console_encode_rs8(block, size, par);
- block += ECC_BLOCK_SIZE;
- par += ECC_SIZE;
- } while (block < buffer->data + buffer->start + count);
-#endif
-}
-
-static void ram_console_update_header(void)
-{
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
- struct ram_console_buffer *buffer = ram_console_buffer;
- uint8_t *par;
- par = ram_console_par_buffer +
- DIV_ROUND_UP(ram_console_buffer_size, ECC_BLOCK_SIZE) * ECC_SIZE;
- ram_console_encode_rs8((uint8_t *)buffer, sizeof(*buffer), par);
-#endif
-}
-
static void
ram_console_write(struct console *console, const char *s, unsigned int count)
{
- int rem;
- struct ram_console_buffer *buffer = ram_console_buffer;
-
- if (count > ram_console_buffer_size) {
- s += count - ram_console_buffer_size;
- count = ram_console_buffer_size;
- }
- rem = ram_console_buffer_size - buffer->start;
- if (rem < count) {
- ram_console_update(s, rem);
- s += rem;
- count -= rem;
- buffer->start = 0;
- buffer->size = ram_console_buffer_size;
- }
- ram_console_update(s, count);
-
- buffer->start += count;
- if (buffer->size < ram_console_buffer_size)
- buffer->size += count;
- ram_console_update_header();
+ struct persistent_ram_zone *prz = console->data;
+ persistent_ram_write(prz, s, count);
}
static struct console ram_console = {
@@ -153,159 +50,6 @@ void ram_console_enable_console(int enabled)
ram_console.flags &= ~CON_ENABLED;
}
-static void __init
-ram_console_save_old(struct ram_console_buffer *buffer, char *dest)
-{
- size_t old_log_size = buffer->size;
-
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
- uint8_t *block;
- uint8_t *par;
-
- block = buffer->data;
- par = ram_console_par_buffer;
- while (block < buffer->data + buffer->size) {
- int numerr;
- int size = ECC_BLOCK_SIZE;
- if (block + size > buffer->data + ram_console_buffer_size)
- size = buffer->data + ram_console_buffer_size - block;
- numerr = ram_console_decode_rs8(block, size, par);
- if (numerr > 0) {
-#if 0
- printk(KERN_INFO "ram_console: error in block %p, %d\n",
- block, numerr);
-#endif
- ram_console_corrected_bytes += numerr;
- } else if (numerr < 0) {
-#if 0
- printk(KERN_INFO "ram_console: uncorrectable error in "
- "block %p\n", block);
-#endif
- ram_console_bad_blocks++;
- }
- block += ECC_BLOCK_SIZE;
- par += ECC_SIZE;
- }
-#endif
-
- if (dest == NULL) {
- dest = kmalloc(old_log_size, GFP_KERNEL);
- if (dest == NULL) {
- printk(KERN_ERR
- "ram_console: failed to allocate buffer\n");
- return;
- }
- }
-
- ram_console_old_log = dest;
- ram_console_old_log_size = old_log_size;
- memcpy(ram_console_old_log,
- &buffer->data[buffer->start], buffer->size - buffer->start);
- memcpy(ram_console_old_log + buffer->size - buffer->start,
- &buffer->data[0], buffer->start);
-}
-
-static int __init ram_console_init(struct ram_console_buffer *buffer,
- size_t buffer_size, char *old_buf)
-{
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
- int numerr;
- uint8_t *par;
-#endif
- ram_console_buffer = buffer;
- ram_console_buffer_size =
- buffer_size - sizeof(struct ram_console_buffer);
-
- if (ram_console_buffer_size > buffer_size) {
- pr_err("ram_console: buffer %p, invalid size %zu, "
- "datasize %zu\n", buffer, buffer_size,
- ram_console_buffer_size);
- return 0;
- }
-
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
- ram_console_buffer_size -= (DIV_ROUND_UP(ram_console_buffer_size,
- ECC_BLOCK_SIZE) + 1) * ECC_SIZE;
-
- if (ram_console_buffer_size > buffer_size) {
- pr_err("ram_console: buffer %p, invalid size %zu, "
- "non-ecc datasize %zu\n",
- buffer, buffer_size, ram_console_buffer_size);
- return 0;
- }
-
- ram_console_par_buffer = buffer->data + ram_console_buffer_size;
-
-
- /* first consecutive root is 0
- * primitive element to generate roots = 1
- */
- ram_console_rs_decoder = init_rs(ECC_SYMSIZE, ECC_POLY, 0, 1, ECC_SIZE);
- if (ram_console_rs_decoder == NULL) {
- printk(KERN_INFO "ram_console: init_rs failed\n");
- return 0;
- }
-
- ram_console_corrected_bytes = 0;
- ram_console_bad_blocks = 0;
-
- par = ram_console_par_buffer +
- DIV_ROUND_UP(ram_console_buffer_size, ECC_BLOCK_SIZE) * ECC_SIZE;
-
- numerr = ram_console_decode_rs8(buffer, sizeof(*buffer), par);
- if (numerr > 0) {
- printk(KERN_INFO "ram_console: error in header, %d\n", numerr);
- ram_console_corrected_bytes += numerr;
- } else if (numerr < 0) {
- printk(KERN_INFO
- "ram_console: uncorrectable error in header\n");
- ram_console_bad_blocks++;
- }
-#endif
-
- if (buffer->sig == RAM_CONSOLE_SIG) {
- if (buffer->size > ram_console_buffer_size
- || buffer->start > buffer->size)
- printk(KERN_INFO "ram_console: found existing invalid "
- "buffer, size %d, start %d\n",
- buffer->size, buffer->start);
- else {
- printk(KERN_INFO "ram_console: found existing buffer, "
- "size %d, start %d\n",
- buffer->size, buffer->start);
- ram_console_save_old(buffer, old_buf);
- }
- } else {
- printk(KERN_INFO "ram_console: no valid data in buffer "
- "(sig = 0x%08x)\n", buffer->sig);
- }
-
- buffer->sig = RAM_CONSOLE_SIG;
- buffer->start = 0;
- buffer->size = 0;
-
- register_console(&ram_console);
- return 0;
-}
-
-static ssize_t ram_console_ecc_string(char *str, size_t len)
-{
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
- ssize_t ret;
-
- if (ram_console_corrected_bytes || ram_console_bad_blocks)
- ret = snprintf(str, len, ""
- "\n%d Corrected bytes, %d unrecoverable blocks\n",
- ram_console_corrected_bytes, ram_console_bad_blocks);
- else
- ret = snprintf(str, len, "\nNo errors detected\n");
-
- return ret;
-#else
- return 0;
-#endif
-}
-
static int ram_console_driver_probe(struct platform_device *pdev)
{
struct resource *res = pdev->resource;
@@ -313,6 +57,7 @@ static int ram_console_driver_probe(struct platform_device *pdev)
size_t buffer_size;
void *buffer;
struct ram_console_platform_data *pdata = pdev->dev.platform_data;
+ int ret;
if (res == NULL || pdev->num_resources != 1 ||
!(res->flags & IORESOURCE_MEM)) {
@@ -330,13 +75,25 @@ static int ram_console_driver_probe(struct platform_device *pdev)
return -ENOMEM;
}
+ ret = persistent_ram_init_ringbuffer(&ram_console_zone, buffer,
+ buffer_size);
+ if (ret)
+ goto err;
+
if (pdata) {
bootinfo = kstrdup(pdata->bootinfo, GFP_KERNEL);
if (bootinfo)
bootinfo_size = strlen(bootinfo);
}
- return ram_console_init(buffer, buffer_size, NULL/* allocate */);
+ ram_console.data = &ram_console_zone;
+
+ register_console(&ram_console);
+ return 0;
+
+err:
+ iounmap(buffer);
+ return ret;
}
static struct platform_driver ram_console_driver = {
@@ -358,25 +115,28 @@ static ssize_t ram_console_read_old(struct file *file, char __user *buf,
{
loff_t pos = *offset;
ssize_t count;
+ struct persistent_ram_zone *prz = &ram_console_zone;
+ size_t old_log_size = persistent_ram_old_size(prz);
+ const char *old_log = persistent_ram_old(prz);
char *str;
int ret;
/* Main last_kmsg log */
- if (pos < ram_console_old_log_size) {
- count = min(len, (size_t)(ram_console_old_log_size - pos));
- if (copy_to_user(buf, ram_console_old_log + pos, count))
+ if (pos < old_log_size) {
+ count = min(len, (size_t)(old_log_size - pos));
+ if (copy_to_user(buf, old_log + pos, count))
return -EFAULT;
goto out;
}
/* ECC correction notice */
- pos -= ram_console_old_log_size;
- count = ram_console_ecc_string(NULL, 0);
+ pos -= old_log_size;
+ count = persistent_ram_ecc_string(prz, NULL, 0);
if (pos < count) {
str = kmalloc(count, GFP_KERNEL);
if (!str)
return -ENOMEM;
- ram_console_ecc_string(str, count + 1);
+ persistent_ram_ecc_string(prz, str, count + 1);
count = min(len, (size_t)(count - pos));
ret = copy_to_user(buf, str + pos, count);
kfree(str);
@@ -410,22 +170,25 @@ static const struct file_operations ram_console_file_ops = {
static int __init ram_console_late_init(void)
{
struct proc_dir_entry *entry;
+ struct persistent_ram_zone *prz = &ram_console_zone;
- if (ram_console_old_log == NULL)
+ if (persistent_ram_old_size(prz) == 0)
return 0;
+
entry = create_proc_entry("last_kmsg", S_IFREG | S_IRUGO, NULL);
if (!entry) {
printk(KERN_ERR "ram_console: failed to create proc entry\n");
- kfree(ram_console_old_log);
- ram_console_old_log = NULL;
+ persistent_ram_free_old(prz);
return 0;
}
entry->proc_fops = &ram_console_file_ops;
- entry->size = ram_console_old_log_size;
+ entry->size = persistent_ram_old_size(prz) +
+ persistent_ram_ecc_string(prz, NULL, 0) +
+ bootinfo_size;
+
return 0;
}
-postcore_initcall(ram_console_module_init);
late_initcall(ram_console_late_init);
-
+postcore_initcall(ram_console_module_init);
--
1.7.3.2.146.gca209
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 07/13] android: persistent_ram: refactor ecc support
2012-03-07 21:58 [PATCH 00/13] staging: Android updates John Stultz
` (5 preceding siblings ...)
2012-03-07 21:58 ` [PATCH 06/13] android: ram_console: split out persistent ram John Stultz
@ 2012-03-07 21:58 ` John Stultz
2012-03-07 22:21 ` Daniel Walker
2012-03-07 21:58 ` [PATCH 08/13] android: persistent_ram: handle reserving and mapping memory John Stultz
` (6 subsequent siblings)
13 siblings, 1 reply; 25+ messages in thread
From: John Stultz @ 2012-03-07 21:58 UTC (permalink / raw)
To: lkml; +Cc: Colin Cross, Greg KH, Android Kernel Team, John Stultz
From: Colin Cross <ccross@android.com>
Remove CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION and related
#ifdefs. Also allow persistent ram zones without ecc enabled.
For some use cases, like the data portion of the upcoming
persistent_vars patches, or a persistent ftrace ringbuffer,
ecc on every update is too expensive.
CC: Greg KH <gregkh@linuxfoundation.org>
CC: Android Kernel Team <kernel-team@android.com>
Change-Id: Ia710344b6c54fe252e0a87353955e063b3c054ab
Signed-off-by: Colin Cross <ccross@android.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
drivers/staging/android/Kconfig | 37 +-----
drivers/staging/android/persistent_ram.c | 239 ++++++++++++++++--------------
drivers/staging/android/persistent_ram.h | 12 +-
drivers/staging/android/ram_console.c | 2 +-
4 files changed, 143 insertions(+), 147 deletions(-)
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index 3f7dbc5..08a3b11 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -27,6 +27,9 @@ config ANDROID_LOGGER
config ANDROID_PERSISTENT_RAM
bool
+ select REED_SOLOMON
+ select REED_SOLOMON_ENC8
+ select REED_SOLOMON_DEC8
config ANDROID_RAM_CONSOLE
bool "Android RAM buffer console"
@@ -34,40 +37,6 @@ config ANDROID_RAM_CONSOLE
select ANDROID_PERSISTENT_RAM
default n
-menuconfig ANDROID_RAM_CONSOLE_ERROR_CORRECTION
- bool "Android RAM Console Enable error correction"
- default n
- depends on ANDROID_PERSISTENT_RAM
- select REED_SOLOMON
- select REED_SOLOMON_ENC8
- select REED_SOLOMON_DEC8
-
-if ANDROID_RAM_CONSOLE_ERROR_CORRECTION
-
-config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE
- int "Android RAM Console Data data size"
- default 128
- help
- Must be a power of 2.
-
-config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE
- int "Android RAM Console ECC size"
- default 16
-
-config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE
- int "Android RAM Console Symbol size"
- default 8
-
-config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL
- hex "Android RAM Console Polynomial"
- default 0x19 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 4)
- default 0x29 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 5)
- default 0x61 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 6)
- default 0x89 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 7)
- default 0x11d if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 8)
-
-endif # ANDROID_RAM_CONSOLE_ERROR_CORRECTION
-
config ANDROID_TIMED_OUTPUT
bool "Timed output class driver"
default y
diff --git a/drivers/staging/android/persistent_ram.c b/drivers/staging/android/persistent_ram.c
index d0f4666..35c57a0 100644
--- a/drivers/staging/android/persistent_ram.c
+++ b/drivers/staging/android/persistent_ram.c
@@ -16,13 +16,10 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
+#include <linux/rslib.h>
#include <linux/slab.h>
#include "persistent_ram.h"
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
-#include <linux/rslib.h>
-#endif
-
struct persistent_ram_buffer {
uint32_t sig;
uint32_t start;
@@ -34,21 +31,16 @@ struct persistent_ram_buffer {
static LIST_HEAD(zone_list);
-#define ECC_BLOCK_SIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE
-#define ECC_SIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE
-#define ECC_SYMSIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE
-#define ECC_POLY CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL
-
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
static void persistent_ram_encode_rs8(struct persistent_ram_zone *prz,
uint8_t *data, size_t len, uint8_t *ecc)
{
int i;
- uint16_t par[ECC_SIZE];
+ uint16_t par[prz->ecc_size];
+
/* Initialize the parity buffer */
memset(par, 0, sizeof(par));
encode_rs8(prz->rs_decoder, data, len, par, 0);
- for (i = 0; i < ECC_SIZE; i++)
+ for (i = 0; i < prz->ecc_size; i++)
ecc[i] = par[i];
}
@@ -56,84 +48,167 @@ static int persistent_ram_decode_rs8(struct persistent_ram_zone *prz,
void *data, size_t len, uint8_t *ecc)
{
int i;
- uint16_t par[ECC_SIZE];
- for (i = 0; i < ECC_SIZE; i++)
+ uint16_t par[prz->ecc_size];
+
+ for (i = 0; i < prz->ecc_size; i++)
par[i] = ecc[i];
return decode_rs8(prz->rs_decoder, data, par, len,
NULL, 0, NULL, 0, NULL);
}
-#endif
-static void persistent_ram_update(struct persistent_ram_zone *prz,
- const void *s, unsigned int count)
+static void persistent_ram_update_ecc(struct persistent_ram_zone *prz,
+ unsigned int count)
{
struct persistent_ram_buffer *buffer = prz->buffer;
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
uint8_t *buffer_end = buffer->data + prz->buffer_size;
uint8_t *block;
uint8_t *par;
- int size = ECC_BLOCK_SIZE;
-#endif
- memcpy(buffer->data + buffer->start, s, count);
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
- block = buffer->data + (buffer->start & ~(ECC_BLOCK_SIZE - 1));
+ int ecc_block_size = prz->ecc_block_size;
+ int ecc_size = prz->ecc_size;
+ int size = prz->ecc_block_size;
+
+ if (!prz->ecc)
+ return;
+
+ block = buffer->data + (buffer->start & ~(ecc_block_size - 1));
par = prz->par_buffer +
- (buffer->start / ECC_BLOCK_SIZE) * ECC_SIZE;
+ (buffer->start / ecc_block_size) * prz->ecc_size;
do {
- if (block + ECC_BLOCK_SIZE > buffer_end)
+ if (block + ecc_block_size > buffer_end)
size = buffer_end - block;
persistent_ram_encode_rs8(prz, block, size, par);
- block += ECC_BLOCK_SIZE;
- par += ECC_SIZE;
+ block += ecc_block_size;
+ par += ecc_size;
} while (block < buffer->data + buffer->start + count);
-#endif
}
-static void persistent_ram_update_header(struct persistent_ram_zone *prz)
+static void persistent_ram_update_header_ecc(struct persistent_ram_zone *prz)
{
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
struct persistent_ram_buffer *buffer = prz->buffer;
+ if (!prz->ecc)
+ return;
+
persistent_ram_encode_rs8(prz, (uint8_t *)buffer, sizeof(*buffer),
prz->par_header);
-#endif
}
-static void __init
-persistent_ram_save_old(struct persistent_ram_zone *prz)
+static void persistent_ram_ecc_old(struct persistent_ram_zone *prz)
{
struct persistent_ram_buffer *buffer = prz->buffer;
- size_t old_log_size = buffer->size;
- char *dest;
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
uint8_t *block;
uint8_t *par;
+ if (!prz->ecc)
+ return;
+
block = buffer->data;
par = prz->par_buffer;
while (block < buffer->data + buffer->size) {
int numerr;
- int size = ECC_BLOCK_SIZE;
+ int size = prz->ecc_block_size;
if (block + size > buffer->data + prz->buffer_size)
size = buffer->data + prz->buffer_size - block;
numerr = persistent_ram_decode_rs8(prz, block, size, par);
if (numerr > 0) {
-#if 0
- pr_info("persistent_ram: error in block %p, %d\n",
+ pr_devel("persistent_ram: error in block %p, %d\n",
block, numerr);
-#endif
prz->corrected_bytes += numerr;
} else if (numerr < 0) {
-#if 0
- pr_info("persistent_ram: uncorrectable error in block %p\n",
+ pr_devel("persistent_ram: uncorrectable error in block %p\n",
block);
-#endif
prz->bad_blocks++;
}
- block += ECC_BLOCK_SIZE;
- par += ECC_SIZE;
+ block += prz->ecc_block_size;
+ par += prz->ecc_size;
+ }
+}
+
+static int persistent_ram_init_ecc(struct persistent_ram_zone *prz,
+ size_t buffer_size)
+{
+ int numerr;
+ struct persistent_ram_buffer *buffer = prz->buffer;
+ int ecc_blocks;
+
+ if (!prz->ecc)
+ return 0;
+
+ prz->ecc_block_size = 128;
+ prz->ecc_size = 16;
+ prz->ecc_symsize = 8;
+ prz->ecc_poly = 0x11d;
+
+ ecc_blocks = DIV_ROUND_UP(prz->buffer_size, prz->ecc_block_size);
+ prz->buffer_size -= (ecc_blocks + 1) * prz->ecc_size;
+
+ if (prz->buffer_size > buffer_size) {
+ pr_err("persistent_ram: invalid size %zu, non-ecc datasize %zu\n",
+ buffer_size, prz->buffer_size);
+ return -EINVAL;
+ }
+
+ prz->par_buffer = buffer->data + prz->buffer_size;
+ prz->par_header = prz->par_buffer + ecc_blocks * prz->ecc_size;
+
+ /*
+ * first consecutive root is 0
+ * primitive element to generate roots = 1
+ */
+ prz->rs_decoder = init_rs(prz->ecc_symsize, prz->ecc_poly, 0, 1,
+ prz->ecc_size);
+ if (prz->rs_decoder == NULL) {
+ pr_info("persistent_ram: init_rs failed\n");
+ return -EINVAL;
}
-#endif
+
+ prz->corrected_bytes = 0;
+ prz->bad_blocks = 0;
+
+ numerr = persistent_ram_decode_rs8(prz, buffer, sizeof(*buffer),
+ prz->par_header);
+ if (numerr > 0) {
+ pr_info("persistent_ram: error in header, %d\n", numerr);
+ prz->corrected_bytes += numerr;
+ } else if (numerr < 0) {
+ pr_info("persistent_ram: uncorrectable error in header\n");
+ prz->bad_blocks++;
+ }
+
+ return 0;
+}
+
+ssize_t persistent_ram_ecc_string(struct persistent_ram_zone *prz,
+ char *str, size_t len)
+{
+ ssize_t ret;
+
+ if (prz->corrected_bytes || prz->bad_blocks)
+ ret = snprintf(str, len, ""
+ "\n%d Corrected bytes, %d unrecoverable blocks\n",
+ prz->corrected_bytes, prz->bad_blocks);
+ else
+ ret = snprintf(str, len, "\nNo errors detected\n");
+
+ return ret;
+}
+
+static void persistent_ram_update(struct persistent_ram_zone *prz,
+ const void *s, unsigned int count)
+{
+ struct persistent_ram_buffer *buffer = prz->buffer;
+ memcpy(buffer->data + buffer->start, s, count);
+ persistent_ram_update_ecc(prz, count);
+}
+
+static void __init
+persistent_ram_save_old(struct persistent_ram_zone *prz)
+{
+ struct persistent_ram_buffer *buffer = prz->buffer;
+ size_t old_log_size = buffer->size;
+ char *dest;
+
+ persistent_ram_ecc_old(prz);
dest = kmalloc(old_log_size, GFP_KERNEL);
if (dest == NULL) {
@@ -173,30 +248,11 @@ int persistent_ram_write(struct persistent_ram_zone *prz,
buffer->start += c;
if (buffer->size < prz->buffer_size)
buffer->size += c;
- persistent_ram_update_header(prz);
+ persistent_ram_update_header_ecc(prz);
return count;
}
-ssize_t persistent_ram_ecc_string(struct persistent_ram_zone *prz,
- char *str, size_t len)
-{
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
- ssize_t ret;
-
- if (prz->corrected_bytes || prz->bad_blocks)
- ret = snprintf(str, len, ""
- "\n%d Corrected bytes, %d unrecoverable blocks\n",
- prz->corrected_bytes, prz->bad_blocks);
- else
- ret = snprintf(str, len, "\nNo errors detected\n");
-
- return ret;
-#else
- return 0;
-#endif
-}
-
size_t persistent_ram_old_size(struct persistent_ram_zone *prz)
{
return prz->old_log_size;
@@ -215,12 +271,10 @@ void persistent_ram_free_old(struct persistent_ram_zone *prz)
}
static int __init __persistent_ram_init(struct persistent_ram_zone *prz,
- void __iomem *mem, size_t buffer_size)
+ void __iomem *mem, size_t buffer_size, bool ecc)
{
struct persistent_ram_buffer *buffer = mem;
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
- int numerr;
-#endif
+ int ret;
INIT_LIST_HEAD(&prz->node);
@@ -233,43 +287,10 @@ static int __init __persistent_ram_init(struct persistent_ram_zone *prz,
return -EINVAL;
}
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
- prz->buffer_size -= (DIV_ROUND_UP(prz->buffer_size,
- ECC_BLOCK_SIZE) + 1) * ECC_SIZE;
-
- if (prz->buffer_size > buffer_size) {
- pr_err("persistent_ram: buffer %p, invalid size %zu, non-ecc datasize %zu\n",
- buffer, buffer_size, prz->buffer_size);
- return -EINVAL;
- }
-
- prz->par_buffer = buffer->data + prz->buffer_size;
- prz->par_header = prz->par_buffer +
- DIV_ROUND_UP(prz->buffer_size, ECC_BLOCK_SIZE) * ECC_SIZE;
-
-
- /* first consecutive root is 0
- * primitive element to generate roots = 1
- */
- prz->rs_decoder = init_rs(ECC_SYMSIZE, ECC_POLY, 0, 1, ECC_SIZE);
- if (prz->rs_decoder == NULL) {
- pr_info("persistent_ram: init_rs failed\n");
- return -EINVAL;
- }
-
- prz->corrected_bytes = 0;
- prz->bad_blocks = 0;
-
- numerr = persistent_ram_decode_rs8(prz, buffer, sizeof(*buffer),
- prz->par_header);
- if (numerr > 0) {
- pr_info("persistent_ram: error in header, %d\n", numerr);
- prz->corrected_bytes += numerr;
- } else if (numerr < 0) {
- pr_info("persistent_ram: uncorrectable error in header\n");
- prz->bad_blocks++;
- }
-#endif
+ prz->ecc = ecc;
+ ret = persistent_ram_init_ecc(prz, buffer_size);
+ if (ret)
+ return ret;
if (buffer->sig == PERSISTENT_RAM_SIG) {
if (buffer->size > prz->buffer_size
@@ -296,7 +317,7 @@ static int __init __persistent_ram_init(struct persistent_ram_zone *prz,
}
int __init persistent_ram_init_ringbuffer(struct persistent_ram_zone *prz,
- void __iomem *mem, size_t buffer_size)
+ void __iomem *mem, size_t buffer_size, bool ecc)
{
- return __persistent_ram_init(prz, mem, buffer_size);
+ return __persistent_ram_init(prz, mem, buffer_size, true);
}
diff --git a/drivers/staging/android/persistent_ram.h b/drivers/staging/android/persistent_ram.h
index f73fb08..ab3995c 100644
--- a/drivers/staging/android/persistent_ram.h
+++ b/drivers/staging/android/persistent_ram.h
@@ -24,13 +24,19 @@ struct persistent_ram_zone {
struct list_head node;
struct persistent_ram_buffer *buffer;
size_t buffer_size;
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+
+ /* ECC correction */
+ bool ecc;
char *par_buffer;
char *par_header;
struct rs_control *rs_decoder;
int corrected_bytes;
int bad_blocks;
-#endif
+ int ecc_block_size;
+ int ecc_size;
+ int ecc_symsize;
+ int ecc_poly;
+
char *old_log;
size_t old_log_size;
size_t old_log_footer_size;
@@ -38,7 +44,7 @@ struct persistent_ram_zone {
};
int persistent_ram_init_ringbuffer(struct persistent_ram_zone *prz,
- void __iomem *buffer, size_t buffer_size);
+ void __iomem *buffer, size_t buffer_size, bool ecc);
int persistent_ram_write(struct persistent_ram_zone *prz, const void *s,
unsigned int count);
diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c
index 689c3dc..d920bd7 100644
--- a/drivers/staging/android/ram_console.c
+++ b/drivers/staging/android/ram_console.c
@@ -76,7 +76,7 @@ static int ram_console_driver_probe(struct platform_device *pdev)
}
ret = persistent_ram_init_ringbuffer(&ram_console_zone, buffer,
- buffer_size);
+ buffer_size, true);
if (ret)
goto err;
--
1.7.3.2.146.gca209
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 08/13] android: persistent_ram: handle reserving and mapping memory
2012-03-07 21:58 [PATCH 00/13] staging: Android updates John Stultz
` (6 preceding siblings ...)
2012-03-07 21:58 ` [PATCH 07/13] android: persistent_ram: refactor ecc support John Stultz
@ 2012-03-07 21:58 ` John Stultz
2012-03-07 22:08 ` Greg KH
2012-03-07 21:58 ` [PATCH 09/13] android: persistent_ram: make persistent_ram_write atomic John Stultz
` (5 subsequent siblings)
13 siblings, 1 reply; 25+ messages in thread
From: John Stultz @ 2012-03-07 21:58 UTC (permalink / raw)
To: lkml; +Cc: Colin Cross, Greg KH, Android Kernel Team, John Stultz
From: Colin Cross <ccross@android.com>
Replace the ioremapped memory passed in from the drivers with
a memblock_reserve and vmap. Adds a new function,
persistent_ram_early_init, designed to be called from the machine
init_early callback, that calls memblock_remove and saves the
provided persistent ram area layout.
Drivers only pass in their struct device * and ecc settings.
Locating and mapping the memory is now handled entirely within
persistent_ram.
Also, convert ram_console to the new persistent_ram_init
parameters that only take a struct device * and ecc settings.
CC: Greg KH <gregkh@linuxfoundation.org>
CC: Android Kernel Team <kernel-team@android.com>
Change-Id: Ibc87ec27b70ed1c928eaa487503469e199973058
Change-Id: I12b018381a2ed5965a8a4b0da40c3e640f92b6cf
Signed-off-by: Colin Cross <ccross@android.com>
[jstultz: Fix pr_info casting issues on 64bit, folded two
patches as the build breaks if they are apart. Also replaced
phys_to_page() w/ pfn_to_page(addr>>PAGE_SHIFT), as phys_to_page
is only on a few arches.]
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
drivers/staging/android/persistent_ram.c | 139 ++++++++++++++++++++++++------
drivers/staging/android/persistent_ram.h | 24 +++++-
drivers/staging/android/ram_console.c | 42 ++-------
3 files changed, 144 insertions(+), 61 deletions(-)
diff --git a/drivers/staging/android/persistent_ram.c b/drivers/staging/android/persistent_ram.c
index 35c57a0..81950e6 100644
--- a/drivers/staging/android/persistent_ram.c
+++ b/drivers/staging/android/persistent_ram.c
@@ -12,12 +12,17 @@
*
*/
+#include <linux/device.h>
+#include <linux/err.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/memblock.h>
#include <linux/rslib.h>
#include <linux/slab.h>
+#include <linux/vmalloc.h>
#include "persistent_ram.h"
struct persistent_ram_buffer {
@@ -29,7 +34,7 @@ struct persistent_ram_buffer {
#define PERSISTENT_RAM_SIG (0x43474244) /* DBGC */
-static LIST_HEAD(zone_list);
+static __initdata LIST_HEAD(persistent_ram_list);
static void persistent_ram_encode_rs8(struct persistent_ram_zone *prz,
uint8_t *data, size_t len, uint8_t *ecc)
@@ -270,54 +275,134 @@ void persistent_ram_free_old(struct persistent_ram_zone *prz)
prz->old_log_size = 0;
}
-static int __init __persistent_ram_init(struct persistent_ram_zone *prz,
- void __iomem *mem, size_t buffer_size, bool ecc)
+static int persistent_ram_buffer_map(phys_addr_t start, phys_addr_t size,
+ struct persistent_ram_zone *prz)
{
- struct persistent_ram_buffer *buffer = mem;
+ struct page **pages;
+ phys_addr_t page_start;
+ unsigned int page_count;
+ pgprot_t prot;
+ unsigned int i;
+
+ page_start = start - offset_in_page(start);
+ page_count = DIV_ROUND_UP(size + offset_in_page(start), PAGE_SIZE);
+
+ prot = pgprot_noncached(PAGE_KERNEL);
+
+ pages = kmalloc(sizeof(struct page *) * page_count, GFP_KERNEL);
+ if (!pages) {
+ pr_err("%s: Failed to allocate array for %u pages\n", __func__,
+ page_count);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < page_count; i++) {
+ phys_addr_t addr = page_start + i * PAGE_SIZE;
+ pages[i] = pfn_to_page(addr >> PAGE_SHIFT);
+ }
+ prz->vaddr = vmap(pages, page_count, VM_MAP, prot);
+ kfree(pages);
+ if (!prz->vaddr) {
+ pr_err("%s: Failed to map %u pages\n", __func__, page_count);
+ return -ENOMEM;
+ }
+
+ prz->buffer = prz->vaddr + offset_in_page(start);
+ prz->buffer_size = size - sizeof(struct persistent_ram_buffer);
+
+ return 0;
+}
+
+static int __init persistent_ram_buffer_init(const char *name,
+ struct persistent_ram_zone *prz)
+{
+ int i;
+ struct persistent_ram *ram;
+ struct persistent_ram_descriptor *desc;
+ phys_addr_t start;
+
+ list_for_each_entry(ram, &persistent_ram_list, node) {
+ start = ram->start;
+ for (i = 0; i < ram->num_descs; i++) {
+ desc = &ram->descs[i];
+ if (!strcmp(desc->name, name))
+ return persistent_ram_buffer_map(start,
+ desc->size, prz);
+ start += desc->size;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static __init
+struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc)
+{
+ struct persistent_ram_zone *prz;
int ret;
- INIT_LIST_HEAD(&prz->node);
+ prz = kzalloc(sizeof(struct persistent_ram_zone), GFP_KERNEL);
+ if (!prz) {
+ pr_err("persistent_ram: failed to allocate persistent ram zone\n");
+ return ERR_PTR(-ENOMEM);
+ }
- prz->buffer = buffer;
- prz->buffer_size = buffer_size - sizeof(struct persistent_ram_buffer);
+ INIT_LIST_HEAD(&prz->node);
- if (prz->buffer_size > buffer_size) {
- pr_err("persistent_ram: buffer %p, invalid size %zu, datasize %zu\n",
- buffer, buffer_size, prz->buffer_size);
- return -EINVAL;
+ ret = persistent_ram_buffer_init(dev_name(dev), prz);
+ if (ret) {
+ pr_err("persistent_ram: failed to initialize buffer\n");
+ return ERR_PTR(ret);
}
prz->ecc = ecc;
- ret = persistent_ram_init_ecc(prz, buffer_size);
+ ret = persistent_ram_init_ecc(prz, prz->buffer_size);
if (ret)
- return ret;
+ return ERR_PTR(ret);
- if (buffer->sig == PERSISTENT_RAM_SIG) {
- if (buffer->size > prz->buffer_size
- || buffer->start > buffer->size)
+ if (prz->buffer->sig == PERSISTENT_RAM_SIG) {
+ if (prz->buffer->size > prz->buffer_size
+ || prz->buffer->start > prz->buffer->size)
pr_info("persistent_ram: found existing invalid buffer, size %d, start %d\n",
- buffer->size, buffer->start);
+ prz->buffer->size, prz->buffer->start);
else {
pr_info("persistent_ram: found existing buffer, size %d, start %d\n",
- buffer->size, buffer->start);
+ prz->buffer->size, prz->buffer->start);
persistent_ram_save_old(prz);
}
} else {
pr_info("persistent_ram: no valid data in buffer (sig = 0x%08x)\n",
- buffer->sig);
+ prz->buffer->sig);
}
- buffer->sig = PERSISTENT_RAM_SIG;
- buffer->start = 0;
- buffer->size = 0;
+ prz->buffer->sig = PERSISTENT_RAM_SIG;
+ prz->buffer->start = 0;
+ prz->buffer->size = 0;
- list_add_tail(&prz->node, &zone_list);
+ return prz;
+}
- return 0;
+struct persistent_ram_zone * __init
+persistent_ram_init_ringbuffer(struct device *dev, bool ecc)
+{
+ return __persistent_ram_init(dev, ecc);
}
-int __init persistent_ram_init_ringbuffer(struct persistent_ram_zone *prz,
- void __iomem *mem, size_t buffer_size, bool ecc)
+int __init persistent_ram_early_init(struct persistent_ram *ram)
{
- return __persistent_ram_init(prz, mem, buffer_size, true);
+ int ret;
+
+ ret = memblock_reserve(ram->start, ram->size);
+ if (ret) {
+ pr_err("Failed to reserve persistent memory from %08lx-%08lx\n",
+ (long)ram->start, (long)(ram->start + ram->size - 1));
+ return ret;
+ }
+
+ list_add_tail(&ram->node, &persistent_ram_list);
+
+ pr_info("Initialized persistent memory from %08lx-%08lx\n",
+ (long)ram->start, (long)(ram->start + ram->size - 1));
+
+ return 0;
}
diff --git a/drivers/staging/android/persistent_ram.h b/drivers/staging/android/persistent_ram.h
index ab3995c..f41e208 100644
--- a/drivers/staging/android/persistent_ram.h
+++ b/drivers/staging/android/persistent_ram.h
@@ -15,13 +15,31 @@
#ifndef __LINUX_PERSISTENT_RAM_H__
#define __LINUX_PERSISTENT_RAM_H__
+#include <linux/device.h>
#include <linux/kernel.h>
+#include <linux/list.h>
#include <linux/types.h>
struct persistent_ram_buffer;
+struct persistent_ram_descriptor {
+ const char *name;
+ phys_addr_t size;
+};
+
+struct persistent_ram {
+ phys_addr_t start;
+ phys_addr_t size;
+
+ int num_descs;
+ struct persistent_ram_descriptor *descs;
+
+ struct list_head node;
+};
+
struct persistent_ram_zone {
struct list_head node;
+ void *vaddr;
struct persistent_ram_buffer *buffer;
size_t buffer_size;
@@ -43,8 +61,10 @@ struct persistent_ram_zone {
bool early;
};
-int persistent_ram_init_ringbuffer(struct persistent_ram_zone *prz,
- void __iomem *buffer, size_t buffer_size, bool ecc);
+int persistent_ram_early_init(struct persistent_ram *ram);
+
+struct persistent_ram_zone *persistent_ram_init_ringbuffer(struct device *dev,
+ bool ecc);
int persistent_ram_write(struct persistent_ram_zone *prz, const void *s,
unsigned int count);
diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c
index d920bd7..29d347e 100644
--- a/drivers/staging/android/ram_console.c
+++ b/drivers/staging/android/ram_console.c
@@ -24,7 +24,7 @@
#include "persistent_ram.h"
#include "ram_console.h"
-static struct persistent_ram_zone ram_console_zone;
+static struct persistent_ram_zone *ram_console_zone;
static const char *bootinfo;
static size_t bootinfo_size;
@@ -52,33 +52,13 @@ void ram_console_enable_console(int enabled)
static int ram_console_driver_probe(struct platform_device *pdev)
{
- struct resource *res = pdev->resource;
- size_t start;
- size_t buffer_size;
- void *buffer;
struct ram_console_platform_data *pdata = pdev->dev.platform_data;
- int ret;
+ struct persistent_ram_zone *prz;
- if (res == NULL || pdev->num_resources != 1 ||
- !(res->flags & IORESOURCE_MEM)) {
- printk(KERN_ERR "ram_console: invalid resource, %p %d flags "
- "%lx\n", res, pdev->num_resources, res ? res->flags : 0);
- return -ENXIO;
- }
- buffer_size = resource_size(res);
- start = res->start;
- printk(KERN_INFO "ram_console: got buffer at %zx, size %zx\n",
- start, buffer_size);
- buffer = ioremap(res->start, buffer_size);
- if (buffer == NULL) {
- printk(KERN_ERR "ram_console: failed to map memory\n");
- return -ENOMEM;
- }
+ prz = persistent_ram_init_ringbuffer(&pdev->dev, true);
+ if (IS_ERR(prz))
+ return PTR_ERR(prz);
- ret = persistent_ram_init_ringbuffer(&ram_console_zone, buffer,
- buffer_size, true);
- if (ret)
- goto err;
if (pdata) {
bootinfo = kstrdup(pdata->bootinfo, GFP_KERNEL);
@@ -86,14 +66,12 @@ static int ram_console_driver_probe(struct platform_device *pdev)
bootinfo_size = strlen(bootinfo);
}
- ram_console.data = &ram_console_zone;
+ ram_console_zone = prz;
+ ram_console.data = prz;
register_console(&ram_console);
- return 0;
-err:
- iounmap(buffer);
- return ret;
+ return 0;
}
static struct platform_driver ram_console_driver = {
@@ -115,7 +93,7 @@ static ssize_t ram_console_read_old(struct file *file, char __user *buf,
{
loff_t pos = *offset;
ssize_t count;
- struct persistent_ram_zone *prz = &ram_console_zone;
+ struct persistent_ram_zone *prz = ram_console_zone;
size_t old_log_size = persistent_ram_old_size(prz);
const char *old_log = persistent_ram_old(prz);
char *str;
@@ -170,7 +148,7 @@ static const struct file_operations ram_console_file_ops = {
static int __init ram_console_late_init(void)
{
struct proc_dir_entry *entry;
- struct persistent_ram_zone *prz = &ram_console_zone;
+ struct persistent_ram_zone *prz = ram_console_zone;
if (persistent_ram_old_size(prz) == 0)
return 0;
--
1.7.3.2.146.gca209
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 09/13] android: persistent_ram: make persistent_ram_write atomic
2012-03-07 21:58 [PATCH 00/13] staging: Android updates John Stultz
` (7 preceding siblings ...)
2012-03-07 21:58 ` [PATCH 08/13] android: persistent_ram: handle reserving and mapping memory John Stultz
@ 2012-03-07 21:58 ` John Stultz
2012-03-07 21:58 ` [PATCH 10/13] android: persistent_ram: add notrace to persistent_ram_write John Stultz
` (4 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: John Stultz @ 2012-03-07 21:58 UTC (permalink / raw)
To: lkml; +Cc: Colin Cross, Greg KH, Android Kernel Team, John Stultz
From: Colin Cross <ccross@android.com>
Allow persistent_ram_write to be called on multiple cpus at
the same time, as long as ecc is not in use. Uses atomics
for the buffer->start and buffer->size counters.
CC: Greg KH <gregkh@linuxfoundation.org>
CC: Android Kernel Team <kernel-team@android.com>
Change-Id: I49b70ec3bc7a651e6ed8e54b6f8f530babde680a
Signed-off-by: Colin Cross <ccross@android.com>
[jstultz: Fix up some pr_info casting issues on 64bit]
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
drivers/staging/android/persistent_ram.c | 140 +++++++++++++++++++++--------
1 files changed, 101 insertions(+), 39 deletions(-)
diff --git a/drivers/staging/android/persistent_ram.c b/drivers/staging/android/persistent_ram.c
index 81950e6..3eb2fb4 100644
--- a/drivers/staging/android/persistent_ram.c
+++ b/drivers/staging/android/persistent_ram.c
@@ -27,8 +27,8 @@
struct persistent_ram_buffer {
uint32_t sig;
- uint32_t start;
- uint32_t size;
+ atomic_t start;
+ atomic_t size;
uint8_t data[0];
};
@@ -36,6 +36,66 @@ struct persistent_ram_buffer {
static __initdata LIST_HEAD(persistent_ram_list);
+static inline size_t buffer_size(struct persistent_ram_zone *prz)
+{
+ return atomic_read(&prz->buffer->size);
+}
+
+static inline size_t buffer_start(struct persistent_ram_zone *prz)
+{
+ return atomic_read(&prz->buffer->start);
+}
+
+/* increase and wrap the start pointer, returning the old value */
+static inline size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a)
+{
+ int old;
+ int new;
+
+ do {
+ old = atomic_read(&prz->buffer->start);
+ new = old + a;
+ while (unlikely(new > prz->buffer_size))
+ new -= prz->buffer_size;
+ } while (atomic_cmpxchg(&prz->buffer->start, old, new) != old);
+
+ return old;
+}
+
+/* increase the size counter until it hits the max size */
+static inline void buffer_size_add(struct persistent_ram_zone *prz, size_t a)
+{
+ size_t old;
+ size_t new;
+
+ if (atomic_read(&prz->buffer->size) == prz->buffer_size)
+ return;
+
+ do {
+ old = atomic_read(&prz->buffer->size);
+ new = old + a;
+ if (new > prz->buffer_size)
+ new = prz->buffer_size;
+ } while (atomic_cmpxchg(&prz->buffer->size, old, new) != old);
+}
+
+/* increase the size counter, retuning an error if it hits the max size */
+static inline ssize_t buffer_size_add_clamp(struct persistent_ram_zone *prz,
+ size_t a)
+{
+ size_t old;
+ size_t new;
+
+ do {
+ old = atomic_read(&prz->buffer->size);
+ new = old + a;
+ if (new > prz->buffer_size)
+ return -ENOMEM;
+ } while (atomic_cmpxchg(&prz->buffer->size, old, new) != old);
+
+ return 0;
+}
+
static void persistent_ram_encode_rs8(struct persistent_ram_zone *prz,
uint8_t *data, size_t len, uint8_t *ecc)
{
@@ -62,7 +122,7 @@ static int persistent_ram_decode_rs8(struct persistent_ram_zone *prz,
}
static void persistent_ram_update_ecc(struct persistent_ram_zone *prz,
- unsigned int count)
+ unsigned int start, unsigned int count)
{
struct persistent_ram_buffer *buffer = prz->buffer;
uint8_t *buffer_end = buffer->data + prz->buffer_size;
@@ -75,16 +135,16 @@ static void persistent_ram_update_ecc(struct persistent_ram_zone *prz,
if (!prz->ecc)
return;
- block = buffer->data + (buffer->start & ~(ecc_block_size - 1));
- par = prz->par_buffer +
- (buffer->start / ecc_block_size) * prz->ecc_size;
+ block = buffer->data + (start & ~(ecc_block_size - 1));
+ par = prz->par_buffer + (start / ecc_block_size) * prz->ecc_size;
+
do {
if (block + ecc_block_size > buffer_end)
size = buffer_end - block;
persistent_ram_encode_rs8(prz, block, size, par);
block += ecc_block_size;
par += ecc_size;
- } while (block < buffer->data + buffer->start + count);
+ } while (block < buffer->data + start + count);
}
static void persistent_ram_update_header_ecc(struct persistent_ram_zone *prz)
@@ -109,7 +169,7 @@ static void persistent_ram_ecc_old(struct persistent_ram_zone *prz)
block = buffer->data;
par = prz->par_buffer;
- while (block < buffer->data + buffer->size) {
+ while (block < buffer->data + buffer_size(prz)) {
int numerr;
int size = prz->ecc_block_size;
if (block + size > buffer->data + prz->buffer_size)
@@ -199,34 +259,33 @@ ssize_t persistent_ram_ecc_string(struct persistent_ram_zone *prz,
}
static void persistent_ram_update(struct persistent_ram_zone *prz,
- const void *s, unsigned int count)
+ const void *s, unsigned int start, unsigned int count)
{
struct persistent_ram_buffer *buffer = prz->buffer;
- memcpy(buffer->data + buffer->start, s, count);
- persistent_ram_update_ecc(prz, count);
+ memcpy(buffer->data + start, s, count);
+ persistent_ram_update_ecc(prz, start, count);
}
static void __init
persistent_ram_save_old(struct persistent_ram_zone *prz)
{
struct persistent_ram_buffer *buffer = prz->buffer;
- size_t old_log_size = buffer->size;
+ size_t size = buffer_size(prz);
+ size_t start = buffer_start(prz);
char *dest;
persistent_ram_ecc_old(prz);
- dest = kmalloc(old_log_size, GFP_KERNEL);
+ dest = kmalloc(size, GFP_KERNEL);
if (dest == NULL) {
pr_err("persistent_ram: failed to allocate buffer\n");
return;
}
prz->old_log = dest;
- prz->old_log_size = old_log_size;
- memcpy(prz->old_log,
- &buffer->data[buffer->start], buffer->size - buffer->start);
- memcpy(prz->old_log + buffer->size - buffer->start,
- &buffer->data[0], buffer->start);
+ prz->old_log_size = size;
+ memcpy(prz->old_log, &buffer->data[start], size - start);
+ memcpy(prz->old_log + size - start, &buffer->data[0], start);
}
int persistent_ram_write(struct persistent_ram_zone *prz,
@@ -234,25 +293,26 @@ int persistent_ram_write(struct persistent_ram_zone *prz,
{
int rem;
int c = count;
- struct persistent_ram_buffer *buffer = prz->buffer;
+ size_t start;
- if (c > prz->buffer_size) {
+ if (unlikely(c > prz->buffer_size)) {
s += c - prz->buffer_size;
c = prz->buffer_size;
}
- rem = prz->buffer_size - buffer->start;
- if (rem < c) {
- persistent_ram_update(prz, s, rem);
+
+ buffer_size_add_clamp(prz, c);
+
+ start = buffer_start_add(prz, c);
+
+ rem = prz->buffer_size - start;
+ if (unlikely(rem < c)) {
+ persistent_ram_update(prz, s, start, rem);
s += rem;
c -= rem;
- buffer->start = 0;
- buffer->size = prz->buffer_size;
+ start = 0;
}
- persistent_ram_update(prz, s, c);
+ persistent_ram_update(prz, s, start, c);
- buffer->start += c;
- if (buffer->size < prz->buffer_size)
- buffer->size += c;
persistent_ram_update_header_ecc(prz);
return count;
@@ -361,23 +421,25 @@ struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc)
return ERR_PTR(ret);
if (prz->buffer->sig == PERSISTENT_RAM_SIG) {
- if (prz->buffer->size > prz->buffer_size
- || prz->buffer->start > prz->buffer->size)
- pr_info("persistent_ram: found existing invalid buffer, size %d, start %d\n",
- prz->buffer->size, prz->buffer->start);
+ if (buffer_size(prz) > prz->buffer_size ||
+ buffer_start(prz) > buffer_size(prz))
+ pr_info("persistent_ram: found existing invalid buffer,"
+ " size %ld, start %ld\n",
+ buffer_size(prz), buffer_start(prz));
else {
- pr_info("persistent_ram: found existing buffer, size %d, start %d\n",
- prz->buffer->size, prz->buffer->start);
+ pr_info("persistent_ram: found existing buffer,"
+ " size %ld, start %ld\n",
+ buffer_size(prz), buffer_start(prz));
persistent_ram_save_old(prz);
}
} else {
- pr_info("persistent_ram: no valid data in buffer (sig = 0x%08x)\n",
- prz->buffer->sig);
+ pr_info("persistent_ram: no valid data in buffer"
+ " (sig = 0x%08x)\n", prz->buffer->sig);
}
prz->buffer->sig = PERSISTENT_RAM_SIG;
- prz->buffer->start = 0;
- prz->buffer->size = 0;
+ atomic_set(&prz->buffer->start, 0);
+ atomic_set(&prz->buffer->size, 0);
return prz;
}
--
1.7.3.2.146.gca209
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 10/13] android: persistent_ram: add notrace to persistent_ram_write
2012-03-07 21:58 [PATCH 00/13] staging: Android updates John Stultz
` (8 preceding siblings ...)
2012-03-07 21:58 ` [PATCH 09/13] android: persistent_ram: make persistent_ram_write atomic John Stultz
@ 2012-03-07 21:58 ` John Stultz
2012-03-07 21:58 ` [PATCH 11/13] android: persistent_trace: ftrace into persistent_ram John Stultz
` (3 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: John Stultz @ 2012-03-07 21:58 UTC (permalink / raw)
To: lkml; +Cc: Colin Cross, Greg KH, Android Kernel Team, John Stultz
From: Colin Cross <ccross@android.com>
Add the notrace attribute to persistent_ram_write and the
non-ecc functions that it calls to allow persistent_ram to
be used for ftracing (only when ecc is disabled).
CC: Greg KH <gregkh@linuxfoundation.org>
CC: Android Kernel Team <kernel-team@android.com>
Change-Id: I9c96039d9a6281fc6a62ddb1c7128c26627cc258
Signed-off-by: Colin Cross <ccross@android.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
drivers/staging/android/persistent_ram.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/android/persistent_ram.c b/drivers/staging/android/persistent_ram.c
index 3eb2fb4..e08f257 100644
--- a/drivers/staging/android/persistent_ram.c
+++ b/drivers/staging/android/persistent_ram.c
@@ -96,7 +96,7 @@ static inline ssize_t buffer_size_add_clamp(struct persistent_ram_zone *prz,
return 0;
}
-static void persistent_ram_encode_rs8(struct persistent_ram_zone *prz,
+static void notrace persistent_ram_encode_rs8(struct persistent_ram_zone *prz,
uint8_t *data, size_t len, uint8_t *ecc)
{
int i;
@@ -121,7 +121,7 @@ static int persistent_ram_decode_rs8(struct persistent_ram_zone *prz,
NULL, 0, NULL, 0, NULL);
}
-static void persistent_ram_update_ecc(struct persistent_ram_zone *prz,
+static void notrace persistent_ram_update_ecc(struct persistent_ram_zone *prz,
unsigned int start, unsigned int count)
{
struct persistent_ram_buffer *buffer = prz->buffer;
@@ -258,7 +258,7 @@ ssize_t persistent_ram_ecc_string(struct persistent_ram_zone *prz,
return ret;
}
-static void persistent_ram_update(struct persistent_ram_zone *prz,
+static void notrace persistent_ram_update(struct persistent_ram_zone *prz,
const void *s, unsigned int start, unsigned int count)
{
struct persistent_ram_buffer *buffer = prz->buffer;
@@ -288,7 +288,7 @@ persistent_ram_save_old(struct persistent_ram_zone *prz)
memcpy(prz->old_log + size - start, &buffer->data[0], start);
}
-int persistent_ram_write(struct persistent_ram_zone *prz,
+int notrace persistent_ram_write(struct persistent_ram_zone *prz,
const void *s, unsigned int count)
{
int rem;
--
1.7.3.2.146.gca209
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 11/13] android: persistent_trace: ftrace into persistent_ram
2012-03-07 21:58 [PATCH 00/13] staging: Android updates John Stultz
` (9 preceding siblings ...)
2012-03-07 21:58 ` [PATCH 10/13] android: persistent_ram: add notrace to persistent_ram_write John Stultz
@ 2012-03-07 21:58 ` John Stultz
2012-03-07 22:10 ` Greg KH
2012-03-07 21:58 ` [PATCH 12/13] android: staging: ram_console: fix crash in ram_console_late_init John Stultz
` (2 subsequent siblings)
13 siblings, 1 reply; 25+ messages in thread
From: John Stultz @ 2012-03-07 21:58 UTC (permalink / raw)
To: lkml; +Cc: Colin Cross, Greg KH, Android Kernel Team, John Stultz
From: Colin Cross <ccross@android.com>
persistent_trace uses the ftrace infrastructure, but traces
into a persistent_ram buffer instead of the regular ftrace
ringbuffer. After a reset or panic, the trace can be
decoded with cat /sys/kernel/debug/persistent_trace.
CC: Greg KH <gregkh@linuxfoundation.org>
CC: Android Kernel Team <kernel-team@android.com>
Change-Id: Ia6025ccc323599c7844e0783af0386d32ed7419e
Signed-off-by: Colin Cross <ccross@android.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
drivers/staging/android/Kconfig | 14 ++
drivers/staging/android/Makefile | 3 +
drivers/staging/android/trace_persistent.c | 242 ++++++++++++++++++++++++++++
3 files changed, 259 insertions(+), 0 deletions(-)
create mode 100644 drivers/staging/android/trace_persistent.c
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index 08a3b11..bc33ab9 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -37,6 +37,20 @@ config ANDROID_RAM_CONSOLE
select ANDROID_PERSISTENT_RAM
default n
+config PERSISTENT_TRACER
+ bool "Persistent function tracer"
+ depends on HAVE_FUNCTION_TRACER
+ select FUNCTION_TRACER
+ select ANDROID_PERSISTENT_RAM
+ help
+ persistent_trace traces function calls into a persistent ram
+ buffer that can be decoded and dumped after reboot through
+ /sys/kernel/debug/persistent_trace. It can be used to
+ determine what function was last called before a reset or
+ panic.
+
+ If unsure, say N.
+
config ANDROID_TIMED_OUTPUT
bool "Timed output class driver"
default y
diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile
index 9b6c9ed..35ffdfe 100644
--- a/drivers/staging/android/Makefile
+++ b/drivers/staging/android/Makefile
@@ -9,3 +9,6 @@ obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o
obj-$(CONFIG_ANDROID_SWITCH) += switch/
obj-$(CONFIG_ANDROID_INTF_ALARM) += alarm.o
obj-$(CONFIG_ANDROID_INTF_ALARM_DEV) += alarm-dev.o
+obj-$(CONFIG_PERSISTENT_TRACER) += trace_persistent.o
+
+CFLAGS_REMOVE_trace_persistent.o = -pg
diff --git a/drivers/staging/android/trace_persistent.c b/drivers/staging/android/trace_persistent.c
new file mode 100644
index 0000000..176b4ff
--- /dev/null
+++ b/drivers/staging/android/trace_persistent.c
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2012 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/debugfs.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+
+#include "persistent_ram.h"
+#include "../../../kernel/trace/trace.h"
+
+struct persistent_trace_record {
+ unsigned long ip;
+ unsigned long parent_ip;
+};
+
+#define REC_SIZE sizeof(struct persistent_trace_record)
+
+static struct persistent_ram_zone *persistent_trace;
+
+static int persistent_trace_enabled;
+
+static struct trace_array *persistent_trace_array;
+
+static struct ftrace_ops trace_ops;
+
+static int persistent_tracer_init(struct trace_array *tr)
+{
+ persistent_trace_array = tr;
+ tr->cpu = get_cpu();
+ put_cpu();
+
+ tracing_start_cmdline_record();
+
+ persistent_trace_enabled = 0;
+ smp_wmb();
+
+ register_ftrace_function(&trace_ops);
+
+ smp_wmb();
+ persistent_trace_enabled = 1;
+
+ return 0;
+}
+
+static void persistent_trace_reset(struct trace_array *tr)
+{
+ persistent_trace_enabled = 0;
+ smp_wmb();
+
+ unregister_ftrace_function(&trace_ops);
+
+ tracing_stop_cmdline_record();
+}
+
+static void persistent_trace_start(struct trace_array *tr)
+{
+ tracing_reset_online_cpus(tr);
+}
+
+static void persistent_trace_call(unsigned long ip, unsigned long parent_ip)
+{
+ struct trace_array *tr = persistent_trace_array;
+ struct trace_array_cpu *data;
+ long disabled;
+ struct persistent_trace_record rec;
+ unsigned long flags;
+ int cpu;
+
+ smp_rmb();
+ if (unlikely(!persistent_trace_enabled))
+ return;
+
+ if (unlikely(oops_in_progress))
+ return;
+
+ /*
+ * Need to use raw, since this must be called before the
+ * recursive protection is performed.
+ */
+ local_irq_save(flags);
+ cpu = raw_smp_processor_id();
+ data = tr->data[cpu];
+ disabled = atomic_inc_return(&data->disabled);
+
+ if (likely(disabled == 1)) {
+ rec.ip = ip;
+ rec.parent_ip = parent_ip;
+ rec.ip |= cpu;
+ persistent_ram_write(persistent_trace, &rec, sizeof(rec));
+ }
+
+ atomic_dec(&data->disabled);
+ local_irq_restore(flags);
+}
+
+static struct ftrace_ops trace_ops __read_mostly = {
+ .func = persistent_trace_call,
+ .flags = FTRACE_OPS_FL_GLOBAL,
+};
+
+static struct tracer persistent_tracer __read_mostly = {
+ .name = "persistent",
+ .init = persistent_tracer_init,
+ .reset = persistent_trace_reset,
+ .start = persistent_trace_start,
+ .wait_pipe = poll_wait_pipe,
+};
+
+struct persistent_trace_seq_data {
+ const void *ptr;
+ size_t off;
+ size_t size;
+};
+
+void *persistent_trace_seq_start(struct seq_file *s, loff_t *pos)
+{
+ struct persistent_trace_seq_data *data;
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return NULL;
+
+ data->ptr = persistent_ram_old(persistent_trace);
+ data->size = persistent_ram_old_size(persistent_trace);
+ data->off = data->size % REC_SIZE;
+
+ data->off += *pos * REC_SIZE;
+
+ if (data->off + REC_SIZE > data->size) {
+ kfree(data);
+ return NULL;
+ }
+
+ return data;
+
+}
+void persistent_trace_seq_stop(struct seq_file *s, void *v)
+{
+ kfree(v);
+}
+
+void *persistent_trace_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+ struct persistent_trace_seq_data *data = v;
+
+ data->off += REC_SIZE;
+
+ if (data->off + REC_SIZE > data->size)
+ return NULL;
+
+ (*pos)++;
+
+ return data;
+}
+
+int persistent_trace_seq_show(struct seq_file *s, void *v)
+{
+ struct persistent_trace_seq_data *data = v;
+ struct persistent_trace_record *rec;
+
+ rec = (struct persistent_trace_record *)(data->ptr + data->off);
+
+ seq_printf(s, "%ld %08lx %08lx %pf <- %pF\n",
+ rec->ip & 3, rec->ip, rec->parent_ip,
+ (void *)rec->ip, (void *)rec->parent_ip);
+
+ return 0;
+}
+
+static const struct seq_operations persistent_trace_seq_ops = {
+ .start = persistent_trace_seq_start,
+ .next = persistent_trace_seq_next,
+ .stop = persistent_trace_seq_stop,
+ .show = persistent_trace_seq_show,
+};
+
+static int persistent_trace_old_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &persistent_trace_seq_ops);
+}
+
+static const struct file_operations persistent_trace_old_fops = {
+ .open = persistent_trace_old_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static int persistent_trace_probe(struct platform_device *pdev)
+{
+ struct dentry *d;
+ int ret;
+
+ persistent_trace = persistent_ram_init_ringbuffer(&pdev->dev, false);
+ if (IS_ERR(persistent_trace)) {
+ pr_err("persistent_trace: failed to init ringbuffer: %ld\n",
+ PTR_ERR(persistent_trace));
+ return PTR_ERR(persistent_trace);
+ }
+
+ ret = register_tracer(&persistent_tracer);
+ if (ret)
+ pr_err("persistent_trace: failed to register tracer");
+
+ if (persistent_ram_old_size(persistent_trace) > 0) {
+ d = debugfs_create_file("persistent_trace", S_IRUGO, NULL,
+ NULL, &persistent_trace_old_fops);
+ if (IS_ERR_OR_NULL(d))
+ pr_err("persistent_trace: failed to create old file\n");
+ }
+
+ return 0;
+}
+
+static struct platform_driver persistent_trace_driver = {
+ .probe = persistent_trace_probe,
+ .driver = {
+ .name = "persistent_trace",
+ },
+};
+
+static int __init persistent_trace_init(void)
+{
+ return platform_driver_register(&persistent_trace_driver);
+}
+core_initcall(persistent_trace_init);
--
1.7.3.2.146.gca209
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 12/13] android: staging: ram_console: fix crash in ram_console_late_init
2012-03-07 21:58 [PATCH 00/13] staging: Android updates John Stultz
` (10 preceding siblings ...)
2012-03-07 21:58 ` [PATCH 11/13] android: persistent_trace: ftrace into persistent_ram John Stultz
@ 2012-03-07 21:58 ` John Stultz
2012-03-07 21:58 ` [PATCH 13/13] android: ram_console: honor dmesg_restrict John Stultz
2012-03-07 22:11 ` [PATCH 00/13] staging: Android updates Greg KH
13 siblings, 0 replies; 25+ messages in thread
From: John Stultz @ 2012-03-07 21:58 UTC (permalink / raw)
To: lkml; +Cc: Colin Cross, Greg KH, Android Kernel Team, John Stultz
From: Colin Cross <ccross@android.com>
If the persistent ram buffer is not available, ram_console_late_init
would crash when dereferencing ram_console_zone. Return early if
ram console was not initialized.
CC: Greg KH <gregkh@linuxfoundation.org>
CC: Android Kernel Team <kernel-team@android.com>
Change-Id: Idff0f690406cdb2fe977bab64a39dc8b40dd4566
Signed-off-by: Colin Cross <ccross@android.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
drivers/staging/android/ram_console.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c
index 29d347e..d956b84 100644
--- a/drivers/staging/android/ram_console.c
+++ b/drivers/staging/android/ram_console.c
@@ -150,6 +150,9 @@ static int __init ram_console_late_init(void)
struct proc_dir_entry *entry;
struct persistent_ram_zone *prz = ram_console_zone;
+ if (!prz)
+ return 0;
+
if (persistent_ram_old_size(prz) == 0)
return 0;
--
1.7.3.2.146.gca209
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 13/13] android: ram_console: honor dmesg_restrict
2012-03-07 21:58 [PATCH 00/13] staging: Android updates John Stultz
` (11 preceding siblings ...)
2012-03-07 21:58 ` [PATCH 12/13] android: staging: ram_console: fix crash in ram_console_late_init John Stultz
@ 2012-03-07 21:58 ` John Stultz
2012-03-07 22:10 ` Greg KH
2012-03-07 22:11 ` [PATCH 00/13] staging: Android updates Greg KH
13 siblings, 1 reply; 25+ messages in thread
From: John Stultz @ 2012-03-07 21:58 UTC (permalink / raw)
To: lkml; +Cc: Nick Kralevich, Greg KH, Android Kernel Team, John Stultz
From: Nick Kralevich <nnk@google.com>
The Linux kernel has a setting called dmesg_restrict. When true,
only processes with CAP_SYSLOG can view the kernel dmesg logs. This
helps prevent leaking of kernel information into user space.
On Android, it's possible to bypass these restrictions by viewing
/proc/last_kmsg.
This change makes /proc/last_kmsg require the same permissions as
dmesg.
Bug: 5555691
CC: Greg KH <gregkh@linuxfoundation.org>
CC: Android Kernel Team <kernel-team@android.com>
Change-Id: I50ecb74012ef2ac0a3cff7325192634341fddae9
Signed-off-by: Nick Kralevich <nnk@google.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
drivers/staging/android/ram_console.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c
index d956b84..b242be2 100644
--- a/drivers/staging/android/ram_console.c
+++ b/drivers/staging/android/ram_console.c
@@ -99,6 +99,9 @@ static ssize_t ram_console_read_old(struct file *file, char __user *buf,
char *str;
int ret;
+ if (dmesg_restrict && !capable(CAP_SYSLOG))
+ return -EPERM;
+
/* Main last_kmsg log */
if (pos < old_log_size) {
count = min(len, (size_t)(old_log_size - pos));
--
1.7.3.2.146.gca209
^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH 01/13] android: lowmemorykiller: Fix warning on 64bit
2012-03-07 21:58 ` [PATCH 01/13] android: lowmemorykiller: Fix warning on 64bit John Stultz
@ 2012-03-07 22:04 ` Greg KH
2012-03-07 22:24 ` John Stultz
0 siblings, 1 reply; 25+ messages in thread
From: Greg KH @ 2012-03-07 22:04 UTC (permalink / raw)
To: John Stultz; +Cc: lkml, Android Kernel Team
On Wed, Mar 07, 2012 at 01:58:11PM -0800, John Stultz wrote:
> Fixes the following warning on 64bit:
> drivers/staging/android/lowmemorykiller.c: In function ‘__check_minfree’:
> drivers/staging/android/lowmemorykiller.c:215: warning: return from incompatible pointer type
>
> CC: Greg KH <gregkh@linuxfoundation.org>
> CC: Android Kernel Team <kernel-team@android.com>
> Signed-off-by: John Stultz <john.stultz@linaro.org>
> ---
> drivers/staging/android/lowmemorykiller.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
> index 052b43e..15a59c1 100644
> --- a/drivers/staging/android/lowmemorykiller.c
> +++ b/drivers/staging/android/lowmemorykiller.c
> @@ -212,7 +212,7 @@ static void __exit lowmem_exit(void)
> module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR);
> module_param_array_named(adj, lowmem_adj, int, &lowmem_adj_size,
> S_IRUGO | S_IWUSR);
> -module_param_array_named(minfree, lowmem_minfree, uint, &lowmem_minfree_size,
> +module_param_array_named(minfree, lowmem_minfree, ulong, &lowmem_minfree_size,
> S_IRUGO | S_IWUSR);
No, the correct fix for this is to make lowmem_minfree an int, not
size_t, right? I made that fix an hour ago in my tree.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 02/13] android: ram_console: set CON_ANYTIME console flag
2012-03-07 21:58 ` [PATCH 02/13] android: ram_console: set CON_ANYTIME console flag John Stultz
@ 2012-03-07 22:07 ` Greg KH
0 siblings, 0 replies; 25+ messages in thread
From: Greg KH @ 2012-03-07 22:07 UTC (permalink / raw)
To: John Stultz; +Cc: lkml, Dima Zavin, Android Kernel Team
On Wed, Mar 07, 2012 at 01:58:12PM -0800, John Stultz wrote:
> Change-Id: I1d2694d05ac9415669a92f38efdd8e71c927705b
What's this crud? It doesn't belong in kernel.org commits :(
Care to remove them all from this series so you don't forget to do it
next time if I were to do it for you?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 08/13] android: persistent_ram: handle reserving and mapping memory
2012-03-07 21:58 ` [PATCH 08/13] android: persistent_ram: handle reserving and mapping memory John Stultz
@ 2012-03-07 22:08 ` Greg KH
2012-03-07 22:16 ` John Stultz
0 siblings, 1 reply; 25+ messages in thread
From: Greg KH @ 2012-03-07 22:08 UTC (permalink / raw)
To: John Stultz; +Cc: lkml, Colin Cross, Android Kernel Team
On Wed, Mar 07, 2012 at 01:58:18PM -0800, John Stultz wrote:
> From: Colin Cross <ccross@android.com>
>
> Replace the ioremapped memory passed in from the drivers with
> a memblock_reserve and vmap. Adds a new function,
> persistent_ram_early_init, designed to be called from the machine
> init_early callback, that calls memblock_remove and saves the
> provided persistent ram area layout.
>
> Drivers only pass in their struct device * and ecc settings.
> Locating and mapping the memory is now handled entirely within
> persistent_ram.
>
> Also, convert ram_console to the new persistent_ram_init
> parameters that only take a struct device * and ecc settings.
>
> CC: Greg KH <gregkh@linuxfoundation.org>
> CC: Android Kernel Team <kernel-team@android.com>
> Change-Id: Ibc87ec27b70ed1c928eaa487503469e199973058
> Change-Id: I12b018381a2ed5965a8a4b0da40c3e640f92b6cf
> Signed-off-by: Colin Cross <ccross@android.com>
> [jstultz: Fix pr_info casting issues on 64bit, folded two
> patches as the build breaks if they are apart. Also replaced
> phys_to_page() w/ pfn_to_page(addr>>PAGE_SHIFT), as phys_to_page
> is only on a few arches.]
Please put your comments above the signed-off-by area, it makes it
easier on tools that parse this area.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 11/13] android: persistent_trace: ftrace into persistent_ram
2012-03-07 21:58 ` [PATCH 11/13] android: persistent_trace: ftrace into persistent_ram John Stultz
@ 2012-03-07 22:10 ` Greg KH
2012-03-07 22:40 ` John Stultz
0 siblings, 1 reply; 25+ messages in thread
From: Greg KH @ 2012-03-07 22:10 UTC (permalink / raw)
To: John Stultz; +Cc: lkml, Colin Cross, Android Kernel Team
On Wed, Mar 07, 2012 at 01:58:21PM -0800, John Stultz wrote:
> From: Colin Cross <ccross@android.com>
>
> persistent_trace uses the ftrace infrastructure, but traces
> into a persistent_ram buffer instead of the regular ftrace
> ringbuffer. After a reset or panic, the trace can be
> decoded with cat /sys/kernel/debug/persistent_trace.
Has this patch been run by the tracing kernel developers?
And what's the status on merging the persistent_ram stuff in with the
in-kernel api for this type of thing? That should then get rid of this
separate tracing module, or at the least, let it be accepted directly by
the tracing developers and not need to go through staging, right?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 13/13] android: ram_console: honor dmesg_restrict
2012-03-07 21:58 ` [PATCH 13/13] android: ram_console: honor dmesg_restrict John Stultz
@ 2012-03-07 22:10 ` Greg KH
0 siblings, 0 replies; 25+ messages in thread
From: Greg KH @ 2012-03-07 22:10 UTC (permalink / raw)
To: John Stultz; +Cc: lkml, Nick Kralevich, Android Kernel Team
On Wed, Mar 07, 2012 at 01:58:23PM -0800, John Stultz wrote:
> From: Nick Kralevich <nnk@google.com>
>
> The Linux kernel has a setting called dmesg_restrict. When true,
> only processes with CAP_SYSLOG can view the kernel dmesg logs. This
> helps prevent leaking of kernel information into user space.
>
> On Android, it's possible to bypass these restrictions by viewing
> /proc/last_kmsg.
>
> This change makes /proc/last_kmsg require the same permissions as
> dmesg.
>
> Bug: 5555691
In what bugzilla does this bug number reference? Random integers don't
do much for people when looking back at the history of things :)
thanks,
greg k-h
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 00/13] staging: Android updates
2012-03-07 21:58 [PATCH 00/13] staging: Android updates John Stultz
` (12 preceding siblings ...)
2012-03-07 21:58 ` [PATCH 13/13] android: ram_console: honor dmesg_restrict John Stultz
@ 2012-03-07 22:11 ` Greg KH
13 siblings, 0 replies; 25+ messages in thread
From: Greg KH @ 2012-03-07 22:11 UTC (permalink / raw)
To: John Stultz; +Cc: lkml, Android Kernel Team
On Wed, Mar 07, 2012 at 01:58:10PM -0800, John Stultz wrote:
> Hi Greg,
> Just wanted to send along some Android updates to the staging-next tree
> so they can be queued for 3.4. I've pulled these from the
> common/android-3.3 branch, and made only some minor changes to keep
> everything in the staging dir and to avoid compile issues on x86.
I've reviewed them a bit, care to resend them based on that review?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 08/13] android: persistent_ram: handle reserving and mapping memory
2012-03-07 22:08 ` Greg KH
@ 2012-03-07 22:16 ` John Stultz
2012-03-08 1:46 ` Greg KH
0 siblings, 1 reply; 25+ messages in thread
From: John Stultz @ 2012-03-07 22:16 UTC (permalink / raw)
To: Greg KH; +Cc: lkml, Colin Cross, Android Kernel Team
On Wed, 2012-03-07 at 14:08 -0800, Greg KH wrote:
> On Wed, Mar 07, 2012 at 01:58:18PM -0800, John Stultz wrote:
> > From: Colin Cross <ccross@android.com>
> >
> > Replace the ioremapped memory passed in from the drivers with
> > a memblock_reserve and vmap. Adds a new function,
> > persistent_ram_early_init, designed to be called from the machine
> > init_early callback, that calls memblock_remove and saves the
> > provided persistent ram area layout.
> >
> > Drivers only pass in their struct device * and ecc settings.
> > Locating and mapping the memory is now handled entirely within
> > persistent_ram.
> >
> > Also, convert ram_console to the new persistent_ram_init
> > parameters that only take a struct device * and ecc settings.
> >
> > CC: Greg KH <gregkh@linuxfoundation.org>
> > CC: Android Kernel Team <kernel-team@android.com>
> > Change-Id: Ibc87ec27b70ed1c928eaa487503469e199973058
> > Change-Id: I12b018381a2ed5965a8a4b0da40c3e640f92b6cf
> > Signed-off-by: Colin Cross <ccross@android.com>
> > [jstultz: Fix pr_info casting issues on 64bit, folded two
> > patches as the build breaks if they are apart. Also replaced
> > phys_to_page() w/ pfn_to_page(addr>>PAGE_SHIFT), as phys_to_page
> > is only on a few arches.]
>
> Please put your comments above the signed-off-by area, it makes it
> easier on tools that parse this area.
I can change it, but this is how SubmittingPatches suggests it be done:
Signed-off-by: Random J Developer <random@developer.example.org>
[lucky@maintainer.example.org: struct foo moved from foo.c to foo.h]
Signed-off-by: Lucky K Maintainer <lucky@maintainer.example.org>
thanks
-john
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 07/13] android: persistent_ram: refactor ecc support
2012-03-07 21:58 ` [PATCH 07/13] android: persistent_ram: refactor ecc support John Stultz
@ 2012-03-07 22:21 ` Daniel Walker
0 siblings, 0 replies; 25+ messages in thread
From: Daniel Walker @ 2012-03-07 22:21 UTC (permalink / raw)
To: John Stultz; +Cc: lkml, Colin Cross, Greg KH, Android Kernel Team
On 03/07/2012 01:58 PM, John Stultz wrote:
> From: Colin Cross<ccross@android.com>
>
> Remove CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION and related
> #ifdefs. Also allow persistent ram zones without ecc enabled.
> For some use cases, like the data portion of the upcoming
> persistent_vars patches, or a persistent ftrace ringbuffer,
> ecc on every update is too expensive.
>
> CC: Greg KH<gregkh@linuxfoundation.org>
> CC: Android Kernel Team<kernel-team@android.com>
> Change-Id: Ia710344b6c54fe252e0a87353955e063b3c054ab
Seems like you would want to drop the Change-Id: regardless of staging,
it doesn't carry any meaning outside of Google.
Daniel
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 01/13] android: lowmemorykiller: Fix warning on 64bit
2012-03-07 22:04 ` Greg KH
@ 2012-03-07 22:24 ` John Stultz
0 siblings, 0 replies; 25+ messages in thread
From: John Stultz @ 2012-03-07 22:24 UTC (permalink / raw)
To: Greg KH; +Cc: lkml, Android Kernel Team
On Wed, 2012-03-07 at 14:04 -0800, Greg KH wrote:
> On Wed, Mar 07, 2012 at 01:58:11PM -0800, John Stultz wrote:
> > Fixes the following warning on 64bit:
> > drivers/staging/android/lowmemorykiller.c: In function ‘__check_minfree’:
> > drivers/staging/android/lowmemorykiller.c:215: warning: return from incompatible pointer type
> >
> > CC: Greg KH <gregkh@linuxfoundation.org>
> > CC: Android Kernel Team <kernel-team@android.com>
> > Signed-off-by: John Stultz <john.stultz@linaro.org>
> > ---
> > drivers/staging/android/lowmemorykiller.c | 2 +-
> > 1 files changed, 1 insertions(+), 1 deletions(-)
> >
> > diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
> > index 052b43e..15a59c1 100644
> > --- a/drivers/staging/android/lowmemorykiller.c
> > +++ b/drivers/staging/android/lowmemorykiller.c
> > @@ -212,7 +212,7 @@ static void __exit lowmem_exit(void)
> > module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR);
> > module_param_array_named(adj, lowmem_adj, int, &lowmem_adj_size,
> > S_IRUGO | S_IWUSR);
> > -module_param_array_named(minfree, lowmem_minfree, uint, &lowmem_minfree_size,
> > +module_param_array_named(minfree, lowmem_minfree, ulong, &lowmem_minfree_size,
> > S_IRUGO | S_IWUSR);
>
> No, the correct fix for this is to make lowmem_minfree an int, not
> size_t, right? I made that fix an hour ago in my tree.
Looks ok to me. I'll go ahead and drop this then.
thanks
-john
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 11/13] android: persistent_trace: ftrace into persistent_ram
2012-03-07 22:10 ` Greg KH
@ 2012-03-07 22:40 ` John Stultz
0 siblings, 0 replies; 25+ messages in thread
From: John Stultz @ 2012-03-07 22:40 UTC (permalink / raw)
To: Greg KH; +Cc: lkml, Colin Cross, Android Kernel Team, tony.luck
On Wed, 2012-03-07 at 14:10 -0800, Greg KH wrote:
> On Wed, Mar 07, 2012 at 01:58:21PM -0800, John Stultz wrote:
> > From: Colin Cross <ccross@android.com>
> >
> > persistent_trace uses the ftrace infrastructure, but traces
> > into a persistent_ram buffer instead of the regular ftrace
> > ringbuffer. After a reset or panic, the trace can be
> > decoded with cat /sys/kernel/debug/persistent_trace.
>
> Has this patch been run by the tracing kernel developers?
Probably not. If you'd prefer, we can drop this one and come back to it
later.
> And what's the status on merging the persistent_ram stuff in with the
> in-kernel api for this type of thing? That should then get rid of this
> separate tracing module, or at the least, let it be accepted directly by
> the tracing developers and not need to go through staging, right?
>From my understanding, ram_console/persistent_ram functionality isn't
really the same as pstore/ramoops.
When asked earlier about this, Colin said:
"pstore is just an interface to write to a persistent storage, with a
tiny driver on it to dump console messages after a panic. With the
number of crashes we see on ARM cpus that are not panics (mostly
watchdog resets), logging only after a panic is not appropriate, so it
can't replace ramconsole. persistent_ram could easily be a pstore
driver, but that would not give any new useful functionality, since
ramconsole is better for us than pstore_dump.
Looking at ramoops, it is exactly the same as pstore on ioremapped
ram, but was originally implemented separately. I see patches now
that convert it to a pstore backend, which leaves us in the same state
as above - only logging panics."
As for the long term merging story, I think Colin's idea of using
persistent_ram a backing for pstore, then adapting pstore as needed to
provide similar continuous console logging like ram_console might be a
way forward, but I don't know of anyone actively working on that atm.
Tony: Do you have any thoughts here?
thanks
-john
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 08/13] android: persistent_ram: handle reserving and mapping memory
2012-03-07 22:16 ` John Stultz
@ 2012-03-08 1:46 ` Greg KH
0 siblings, 0 replies; 25+ messages in thread
From: Greg KH @ 2012-03-08 1:46 UTC (permalink / raw)
To: John Stultz; +Cc: lkml, Colin Cross, Android Kernel Team
On Wed, Mar 07, 2012 at 02:16:13PM -0800, John Stultz wrote:
> On Wed, 2012-03-07 at 14:08 -0800, Greg KH wrote:
> > On Wed, Mar 07, 2012 at 01:58:18PM -0800, John Stultz wrote:
> > > From: Colin Cross <ccross@android.com>
> > >
> > > Replace the ioremapped memory passed in from the drivers with
> > > a memblock_reserve and vmap. Adds a new function,
> > > persistent_ram_early_init, designed to be called from the machine
> > > init_early callback, that calls memblock_remove and saves the
> > > provided persistent ram area layout.
> > >
> > > Drivers only pass in their struct device * and ecc settings.
> > > Locating and mapping the memory is now handled entirely within
> > > persistent_ram.
> > >
> > > Also, convert ram_console to the new persistent_ram_init
> > > parameters that only take a struct device * and ecc settings.
> > >
> > > CC: Greg KH <gregkh@linuxfoundation.org>
> > > CC: Android Kernel Team <kernel-team@android.com>
> > > Change-Id: Ibc87ec27b70ed1c928eaa487503469e199973058
> > > Change-Id: I12b018381a2ed5965a8a4b0da40c3e640f92b6cf
> > > Signed-off-by: Colin Cross <ccross@android.com>
> > > [jstultz: Fix pr_info casting issues on 64bit, folded two
> > > patches as the build breaks if they are apart. Also replaced
> > > phys_to_page() w/ pfn_to_page(addr>>PAGE_SHIFT), as phys_to_page
> > > is only on a few arches.]
> >
> > Please put your comments above the signed-off-by area, it makes it
> > easier on tools that parse this area.
>
> I can change it, but this is how SubmittingPatches suggests it be done:
>
> Signed-off-by: Random J Developer <random@developer.example.org>
> [lucky@maintainer.example.org: struct foo moved from foo.c to foo.h]
> Signed-off-by: Lucky K Maintainer <lucky@maintainer.example.org>
Oops, you are right, nevermind then. But the change-id stuff needs to
still go.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2012-03-08 1:46 UTC | newest]
Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-03-07 21:58 [PATCH 00/13] staging: Android updates John Stultz
2012-03-07 21:58 ` [PATCH 01/13] android: lowmemorykiller: Fix warning on 64bit John Stultz
2012-03-07 22:04 ` Greg KH
2012-03-07 22:24 ` John Stultz
2012-03-07 21:58 ` [PATCH 02/13] android: ram_console: set CON_ANYTIME console flag John Stultz
2012-03-07 22:07 ` Greg KH
2012-03-07 21:58 ` [PATCH 03/13] android: ram_console: move footer strings John Stultz
2012-03-07 21:58 ` [PATCH 04/13] android: ram_console: drop early buffer support John Stultz
2012-03-07 21:58 ` [PATCH 05/13] android: ram_console: drop verbose ram_console support John Stultz
2012-03-07 21:58 ` [PATCH 06/13] android: ram_console: split out persistent ram John Stultz
2012-03-07 21:58 ` [PATCH 07/13] android: persistent_ram: refactor ecc support John Stultz
2012-03-07 22:21 ` Daniel Walker
2012-03-07 21:58 ` [PATCH 08/13] android: persistent_ram: handle reserving and mapping memory John Stultz
2012-03-07 22:08 ` Greg KH
2012-03-07 22:16 ` John Stultz
2012-03-08 1:46 ` Greg KH
2012-03-07 21:58 ` [PATCH 09/13] android: persistent_ram: make persistent_ram_write atomic John Stultz
2012-03-07 21:58 ` [PATCH 10/13] android: persistent_ram: add notrace to persistent_ram_write John Stultz
2012-03-07 21:58 ` [PATCH 11/13] android: persistent_trace: ftrace into persistent_ram John Stultz
2012-03-07 22:10 ` Greg KH
2012-03-07 22:40 ` John Stultz
2012-03-07 21:58 ` [PATCH 12/13] android: staging: ram_console: fix crash in ram_console_late_init John Stultz
2012-03-07 21:58 ` [PATCH 13/13] android: ram_console: honor dmesg_restrict John Stultz
2012-03-07 22:10 ` Greg KH
2012-03-07 22:11 ` [PATCH 00/13] staging: Android updates Greg KH
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox