Skip to contentSkip to conversation

staging: Android updates

PATCH In review John Stultz 3 participants 25 messages Mar 7, 2012 – Mar 8, 2012 Staging

lore
Share & tools
lore
#0 lore raw

cover staging: Android updates

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 <[email protected]>
CC Android Kernel Team <[email protected]>

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
Signature · 1 line
1.7.3.2.146.gca209
#1 lore raw

PATCH 1/13 android: lowmemorykiller: Fix warning on 64bit

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 <[email protected]>
CC Android Kernel Team <[email protected]>
---
 drivers/staging/android/lowmemorykiller.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/staging/android/lowmemorykiller.c +1 -1
index 052b43e..15a59c1 100644
@@ -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);
 
Signature · 1 line
1.7.3.2.146.gca209
maintainer
#2 lore raw

Re: [PATCH 01/13] android: lowmemorykiller: Fix warning on 64bit

Quoted 16 lines · John Stultz

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 <[email protected]>
CC Android Kernel Team <[email protected]>
---
 drivers/staging/android/lowmemorykiller.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/staging/android/lowmemorykiller.c +0 -0
index 052b43e..15a59c1 100644

drivers/staging/android/lowmemorykiller.c static void __exit lowmem_exit(void) · line 216

Quoted 6 lines
drivers/staging/android/lowmemorykiller.c +1 -1
@@ -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

#3 lore raw

Re: [PATCH 01/13] android: lowmemorykiller: Fix warning on 64bit

Quoted 12 lines · Greg KH
Quoted 11 lines · John Stultz

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 <[email protected]>
CC Android Kernel Team <[email protected]>
---
 drivers/staging/android/lowmemorykiller.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
Quoted 14 lines

drivers/staging/android/lowmemorykiller.c static void __exit lowmem_exit(void) · line 216

Quoted 11 lines
drivers/staging/android/lowmemorykiller.c +1 -1
index 052b43e..15a59c1 100644
@@ -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

#4 lore raw

PATCH 2/13 android: ram_console: set CON_ANYTIME console flag

In reply to John Stultz

From: Dima Zavin <[email protected]>

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 <[email protected]>
CC Android Kernel Team <[email protected]>
Change-Id I1d2694d05ac9415669a92f38efdd8e71c927705b
[jstultz: tweaked commit subject line]
---
 drivers/staging/android/ram_console.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/staging/android/ram_console.c +1 -1
index fabd398..f01a0c4 100644
@@ -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,
 };
 
Signature · 1 line
1.7.3.2.146.gca209
maintainer
#5 lore raw

Re: [PATCH 02/13] android: ram_console: set CON_ANYTIME console flag

Quoted 1 line · John Stultz

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

#6 lore raw

PATCH 3/13 android: ram_console: move footer strings

In reply to John Stultz

From: Colin Cross <[email protected]>

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 <[email protected]>
CC Android Kernel Team <[email protected]>
Change-Id I883bb6eec5bad5c1b1247da807e982e744fe40ba
---
 drivers/staging/android/ram_console.c |  115 +++++++++++++++++++-------------
 1 files changed, 68 insertions(+), 47 deletions(-)
drivers/staging/android/ram_console.c +68 -47
index f01a0c4..2310a79 100644
@@ -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;
 }
Signature · 1 line
1.7.3.2.146.gca209
#7 lore raw

PATCH 4/13 android: ram_console: drop early buffer support

In reply to John Stultz

From: Colin Cross <[email protected]>

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 <[email protected]>
CC Android Kernel Team <[email protected]>
Change-Id Ifc306db9a8cceec4ca980cf24783c3fe764eb1fb
---
 drivers/staging/android/Kconfig       |   16 ----------------
 drivers/staging/android/ram_console.c |   29 -----------------------------
 2 files changed, 0 insertions(+), 45 deletions(-)
drivers/staging/android/Kconfig +0 -16
index f3b7c75..20034e6 100644
@@ -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
drivers/staging/android/ram_console.c +0 -29
index 2310a79..ed7827b 100644
@@ -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);
 
Signature · 1 line
1.7.3.2.146.gca209
#8 lore raw

PATCH 5/13 android: ram_console: drop verbose ram_console support

In reply to John Stultz

From: Colin Cross <[email protected]>

Equivalent functionality can be obtained with loglevel=15

CC Greg KH <[email protected]>
CC Android Kernel Team <[email protected]>
Change-Id I977d70f3b72fd48cfbb9f791de37e74ac711ce21
---
 drivers/staging/android/Kconfig       |    5 -----
 drivers/staging/android/ram_console.c |    3 ---
 2 files changed, 0 insertions(+), 8 deletions(-)
drivers/staging/android/Kconfig +0 -5
index 20034e6..3144ddb 100644
@@ -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
drivers/staging/android/ram_console.c +0 -3
index ed7827b..73215e2 100644
@@ -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;
 }
 
Signature · 1 line
1.7.3.2.146.gca209
#9 lore raw

PATCH 6/13 android: ram_console: split out persistent ram

In reply to John Stultz

From: Colin Cross <[email protected]>

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 <[email protected]>
CC Android Kernel Team <[email protected]>
Change-Id I8c7495e3a6a3dd7cdf3cb067e1afceb3b6aaef3c
[jstultz: Moved persistent_ram.h to staging dir]
---
 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
drivers/staging/android/Kconfig +5 -1
index 3144ddb..3f7dbc5 100644
@@ -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
drivers/staging/android/Makefile +1 -0
index 785f269..9b6c9ed 100644
@@ -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
drivers/staging/android/persistent_ram.c new file +302 -0

302 lines not on this page · raw message

drivers/staging/android/persistent_ram.h new file +52 -0

52 lines not on this page · raw message

drivers/staging/android/ram_console.c +36 -273

382 lines not on this page · raw message

Signature · 1 line
1.7.3.2.146.gca209
#10 lore raw

PATCH 7/13 android: persistent_ram: refactor ecc support

In reply to John Stultz

From: Colin Cross <[email protected]>

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 <[email protected]>
CC Android Kernel Team <[email protected]>
Change-Id Ia710344b6c54fe252e0a87353955e063b3c054ab
---
 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(-)
drivers/staging/android/Kconfig +3 -34
index 3f7dbc5..08a3b11 100644
@@ -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
drivers/staging/android/persistent_ram.c +130 -109

340 lines not on this page · raw message

drivers/staging/android/persistent_ram.h +9 -3
index f73fb08..ab3995c 100644
@@ -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);
drivers/staging/android/ram_console.c +1 -1
index 689c3dc..d920bd7 100644
@@ -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;
 
Signature · 1 line
1.7.3.2.146.gca209
#11 lore raw

Re: [PATCH 07/13] android: persistent_ram: refactor ecc support

Quoted 11 lines · John Stultz

From: Colin Cross<[email protected]>

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<[email protected]>
CC: Android Kernel Team<[email protected]>
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

#12 lore raw

PATCH 8/13 android: persistent_ram: handle reserving and mapping memory

In reply to John Stultz

From: Colin Cross <[email protected]>

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 <[email protected]>
CC Android Kernel Team <[email protected]>
Change-Id Ibc87ec27b70ed1c928eaa487503469e199973058
Change-Id I12b018381a2ed5965a8a4b0da40c3e640f92b6cf

[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.]

---
 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(-)
drivers/staging/android/persistent_ram.c +112 -27
index 35c57a0..81950e6 100644
@@ -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;
 }
drivers/staging/android/persistent_ram.h +22 -2
index ab3995c..f41e208 100644
@@ -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);
drivers/staging/android/ram_console.c +10 -32

78 lines not on this page · raw message

Signature · 1 line
1.7.3.2.146.gca209
maintainer
#13 lore raw

Re: [PATCH 08/13] android: persistent_ram: handle reserving and mapping memory

Quoted 20 lines · John Stultz

From: Colin Cross <[email protected]>

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 <[email protected]>
CC Android Kernel Team <[email protected]>
Change-Id Ibc87ec27b70ed1c928eaa487503469e199973058
Change-Id I12b018381a2ed5965a8a4b0da40c3e640f92b6cf
Quoted 4 lines

[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

#14 lore raw

Re: [PATCH 08/13] android: persistent_ram: handle reserving and mapping memory

Quoted 26 lines · Greg KH
Quoted 20 lines · John Stultz

From: Colin Cross <[email protected]>

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 <[email protected]>
CC Android Kernel Team <[email protected]>
Change-Id Ibc87ec27b70ed1c928eaa487503469e199973058
Change-Id I12b018381a2ed5965a8a4b0da40c3e640f92b6cf
Quoted 4 lines

[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.]

Quoted 2 lines

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:

[[email protected]: struct foo moved from foo.c to foo.h]

thanks
-john

maintainer
#15 lore raw

Re: [PATCH 08/13] android: persistent_ram: handle reserving and mapping memory

Quoted 27 lines · John Stultz
Quoted 26 lines · Greg KH
Quoted 24 lines · John Stultz

From: Colin Cross <[email protected]>

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 <[email protected]>
CC Android Kernel Team <[email protected]>
Change-Id Ibc87ec27b70ed1c928eaa487503469e199973058
Change-Id I12b018381a2ed5965a8a4b0da40c3e640f92b6cf

[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.]

Quoted 8 lines
Quoted 2 lines

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:

[[email protected]: struct foo moved from foo.c to foo.h]

Oops, you are right, nevermind then. But the change-id stuff needs to still go.

thanks,

greg k-h

#16 lore raw

PATCH 9/13 android: persistent_ram: make persistent_ram_write atomic

In reply to John Stultz

From: Colin Cross <[email protected]>

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 <[email protected]>
CC Android Kernel Team <[email protected]>
Change-Id I49b70ec3bc7a651e6ed8e54b6f8f530babde680a
[jstultz: Fix up some pr_info casting issues on 64bit]
---
 drivers/staging/android/persistent_ram.c |  140 +++++++++++++++++++++--------
 1 files changed, 101 insertions(+), 39 deletions(-)
drivers/staging/android/persistent_ram.c +101 -39
index 81950e6..3eb2fb4 100644
@@ -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;
 }
Signature · 1 line
1.7.3.2.146.gca209
#17 lore raw

PATCH 10/13 android: persistent_ram: add notrace to persistent_ram_write

In reply to John Stultz

From: Colin Cross <[email protected]>

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 <[email protected]>
CC Android Kernel Team <[email protected]>
Change-Id I9c96039d9a6281fc6a62ddb1c7128c26627cc258
---
 drivers/staging/android/persistent_ram.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)
drivers/staging/android/persistent_ram.c +4 -4
index 3eb2fb4..e08f257 100644
@@ -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;
Signature · 1 line
1.7.3.2.146.gca209
#18 lore raw

PATCH 11/13 android: persistent_trace: ftrace into persistent_ram

In reply to John Stultz

From: Colin Cross <[email protected]>

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 <[email protected]>
CC Android Kernel Team <[email protected]>
Change-Id Ia6025ccc323599c7844e0783af0386d32ed7419e
---
 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
drivers/staging/android/Kconfig +14 -0
index 08a3b11..bc33ab9 100644
@@ -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
drivers/staging/android/Makefile +3 -0
index 9b6c9ed..35ffdfe 100644
@@ -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
drivers/staging/android/trace_persistent.c new file +242 -0

242 lines not on this page · raw message

Signature · 1 line
1.7.3.2.146.gca209
maintainer
#19 lore raw

Re: [PATCH 11/13] android: persistent_trace: ftrace into persistent_ram

Quoted 6 lines · John Stultz

From: Colin Cross <[email protected]>

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

#20 lore raw

Re: [PATCH 11/13] android: persistent_trace: ftrace into persistent_ram

Quoted 9 lines · Greg KH
Quoted 6 lines · John Stultz

From: Colin Cross <[email protected]>

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.

Quoted 6 lines

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

#21 lore raw

PATCH 12/13 android: staging: ram_console: fix crash in ram_console_late_init

In reply to John Stultz

From: Colin Cross <[email protected]>

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 <[email protected]>
CC Android Kernel Team <[email protected]>
Change-Id Idff0f690406cdb2fe977bab64a39dc8b40dd4566
---
 drivers/staging/android/ram_console.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)
drivers/staging/android/ram_console.c +3 -0
index 29d347e..d956b84 100644
@@ -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;
 
Signature · 1 line
1.7.3.2.146.gca209
#22 lore raw

PATCH 13/13 android: ram_console: honor dmesg_restrict

In reply to John Stultz

From: Nick Kralevich <[email protected]>

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 <[email protected]>
CC Android Kernel Team <[email protected]>
Change-Id I50ecb74012ef2ac0a3cff7325192634341fddae9
---
 drivers/staging/android/ram_console.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)
drivers/staging/android/ram_console.c +3 -0
index d956b84..b242be2 100644
@@ -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));
Signature · 1 line
1.7.3.2.146.gca209
maintainer
#23 lore raw

Re: [PATCH 13/13] android: ram_console: honor dmesg_restrict

Quoted 6 lines · John Stultz

From: Nick Kralevich <[email protected]>

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.

Quoted 7 lines

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

maintainer
#24 lore raw
In reply to John Stultz
Quoted 5 lines · John Stultz

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