Embedded Linux development
 help / color / mirror / Atom feed
* [PATCH 02/14] Pramfs: File operations for directories
From: Marco @ 2009-06-13 13:21 UTC (permalink / raw)
  To: Linux FS Devel; +Cc: Linux Embedded, Linux Kernel, Daniel Walker

From: Marco Stornelli <marco.stornelli@gmail.com>

File operations for directories.

Signed-off-by: Marco Stornelli <marco.stornelli@gmail.com>
---

diff -uprN linux-2.6.30-orig/fs/pramfs/dir.c linux-2.6.30/fs/pramfs/dir.c
--- linux-2.6.30-orig/fs/pramfs/dir.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.30/fs/pramfs/dir.c	2009-06-13 12:51:46.000000000 +0200
@@ -0,0 +1,220 @@
+/*
+ * FILE NAME fs/pramfs/dir.c
+ *
+ * BRIEF DESCRIPTION
+ *
+ * File operations for directories.
+ *
+ * Copyright 2009 Marco Stornelli <marco.stornelli@gmail.com>
+ * Copyright 2003 Sony Corporation
+ * Copyright 2003 Matsushita Electric Industrial Co., Ltd.
+ * 2003-2004 (c) MontaVista Software, Inc. , Steve Longerbeam
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/fs.h>
+#include <linux/pagemap.h>
+#include "pram_fs.h"
+
+/*
+ *	Parent is locked.
+ */
+int pram_add_link(struct dentry *dentry, struct inode *inode)
+{
+	struct inode *dir = dentry->d_parent->d_inode;
+	struct pram_inode *pidir, *pi, *pitail = NULL;
+	off_t tail_ino, prev_ino;
+	unsigned long flags;
+
+	const char *name = dentry->d_name.name;
+	int namelen = dentry->d_name.len > PRAM_NAME_LEN ?
+		PRAM_NAME_LEN : dentry->d_name.len;
+
+	flags = 0;
+
+	pidir = pram_get_inode(dir->i_sb, dir->i_ino);
+	pi = pram_get_inode(dir->i_sb, inode->i_ino);
+
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+
+	tail_ino = pidir->i_type.dir.tail;
+	if (tail_ino != 0) {
+		pitail = pram_get_inode(dir->i_sb, tail_ino);
+		pram_lock_inode(pitail, flags);
+		pitail->i_d.d_next = inode->i_ino;
+		pram_unlock_inode(pitail, flags);
+
+		prev_ino = tail_ino;
+
+		pram_lock_inode(pidir, flags);
+		pidir->i_type.dir.tail = inode->i_ino;
+		pidir->i_mtime = dir->i_mtime.tv_sec;
+		pidir->i_ctime = dir->i_ctime.tv_sec;
+		pram_unlock_inode(pidir, flags);
+	} else {
+		/* the directory is empty */
+		prev_ino = 0;
+
+		pram_lock_inode(pidir, flags);
+		pidir->i_type.dir.head = pidir->i_type.dir.tail = inode->i_ino;
+		pidir->i_mtime = dir->i_mtime.tv_sec;
+		pidir->i_ctime = dir->i_ctime.tv_sec;
+		pram_unlock_inode(pidir, flags);
+	}
+
+
+	pram_lock_inode(pi, flags);
+	pi->i_d.d_prev = prev_ino;
+	pi->i_d.d_parent = dir->i_ino;
+	memcpy(pi->i_d.d_name, name, namelen);
+	pi->i_d.d_name[namelen] = '\0';
+	pram_unlock_inode(pi, flags);
+	return 0;
+}
+
+int pram_remove_link(struct inode *inode)
+{
+	struct super_block *sb = inode->i_sb;
+	struct pram_inode *prev = NULL;
+	struct pram_inode *next = NULL;
+	struct pram_inode *pidir, *pi;
+	unsigned long flags;
+
+	flags = 0;
+
+	pi = pram_get_inode(sb, inode->i_ino);
+	pidir = pram_get_inode(sb, pi->i_d.d_parent);
+	if (!pidir)
+		return -EACCES;
+
+	if (inode->i_ino == pidir->i_type.dir.head) {
+		/* first inode in directory */
+		next = pram_get_inode(sb, pi->i_d.d_next);
+
+		if (next) {
+			pram_lock_inode(next, flags);
+			next->i_d.d_prev = 0;
+			pram_unlock_inode(next, flags);
+
+			pram_lock_inode(pidir, flags);
+			pidir->i_type.dir.head = pi->i_d.d_next;
+		} else {
+			pram_lock_inode(pidir, flags);
+			pidir->i_type.dir.head = pidir->i_type.dir.tail = 0;
+		}
+		pram_unlock_inode(pidir, flags);
+	} else if (inode->i_ino == pidir->i_type.dir.tail) {
+		/* last inode in directory */
+		prev = pram_get_inode(sb, pi->i_d.d_prev);
+
+		pram_lock_inode(prev, flags);
+		prev->i_d.d_next = 0;
+		pram_unlock_inode(prev, flags);
+
+		pram_lock_inode(pidir, flags);
+		pidir->i_type.dir.tail = pi->i_d.d_prev;
+		pram_unlock_inode(pidir, flags);
+	} else {
+		/* somewhere in the middle */
+		prev = pram_get_inode(sb, pi->i_d.d_prev);
+		next = pram_get_inode(sb, pi->i_d.d_next);
+
+		if (prev && next) {
+			pram_lock_inode(prev, flags);
+			prev->i_d.d_next = pi->i_d.d_next;
+			pram_unlock_inode(prev, flags);
+
+			pram_lock_inode(next, flags);
+			next->i_d.d_prev = pi->i_d.d_prev;
+			pram_unlock_inode(next, flags);
+		}
+	}
+
+	pram_lock_inode(pi, flags);
+	pi->i_d.d_next = pi->i_d.d_prev = pi->i_d.d_parent = 0;
+	pram_unlock_inode(pi, flags);
+
+	return 0;
+}
+
+#define S_SHIFT 12
+static unsigned int dtype_by_mode[S_IFMT >> S_SHIFT] = {
+	[S_IFREG >> S_SHIFT]    DT_REG,
+	[S_IFDIR >> S_SHIFT]    DT_DIR,
+	[S_IFCHR >> S_SHIFT]    DT_CHR,
+	[S_IFBLK >> S_SHIFT]    DT_BLK,
+	[S_IFIFO >> S_SHIFT]    DT_FIFO,
+	[S_IFSOCK >> S_SHIFT]   DT_SOCK,
+	[S_IFLNK >> S_SHIFT]    DT_LNK,
+};
+
+static int
+pram_readdir(struct file *filp, void *dirent, filldir_t filldir)
+{
+	struct inode *inode = filp->f_dentry->d_inode;
+	struct super_block *sb = inode->i_sb;
+	struct pram_inode *pi;
+	int namelen, ret = 0;
+	char *name;
+	ino_t ino;
+
+	if (filp->f_pos >> 32)
+		return 0;
+
+	pi = pram_get_inode(sb, inode->i_ino);
+
+	switch ((unsigned long)filp->f_pos) {
+	case 0:
+		ret = filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR);
+		filp->f_pos++;
+		return ret;
+	case 1:
+		ret = filldir(dirent, "..", 2, 1, pi->i_d.d_parent, DT_DIR);
+		ino = pi->i_type.dir.head;
+		filp->f_pos = ino ? ino : 2;
+		return ret;
+	case 2:
+		ino = pi->i_type.dir.head;
+		if (ino) {
+			filp->f_pos = ino;
+			pi = pram_get_inode(sb, ino);
+			break;
+		} else {
+			/* the directory is empty */
+			filp->f_pos = 2;
+			return 0;
+		}
+	case 3:
+		return 0;
+	default:
+		ino = filp->f_pos;
+		pi = pram_get_inode(sb, ino);
+		break;
+	}
+
+	while (pi && !pi->i_links_count) {
+		ino = filp->f_pos = pi->i_d.d_next;
+		pi = pram_get_inode(sb, ino);
+	}
+
+	if (pi) {
+		name = pi->i_d.d_name;
+		namelen = strlen(name);
+
+		ret = filldir(dirent, name, namelen,
+			      filp->f_pos, ino,
+			      dtype_by_mode[(pi->i_mode & S_IFMT)>>S_SHIFT]);
+		filp->f_pos = pi->i_d.d_next ? pi->i_d.d_next : 3;
+	} else
+		filp->f_pos = 3;
+
+	return ret;
+}
+
+struct file_operations pram_dir_operations = {
+	.read 		= generic_read_dir,
+	.readdir	= pram_readdir,
+	.fsync		= simple_sync_file,	
+};


^ permalink raw reply

* [PATCH 01/14] Pramfs: Block operations
From: Marco @ 2009-06-13 13:20 UTC (permalink / raw)
  To: Linux FS Devel; +Cc: Linux Embedded, Linux Kernel, Daniel Walker

From: Marco Stornelli <marco.stornelli@gmail.com>

Block allocation and deallocation routines.

Signed-off-by: Marco Stornelli <marco.stornelli@gmail.com>
---

diff -uprN linux-2.6.30-orig/fs/pramfs/balloc.c
linux-2.6.30/fs/pramfs/balloc.c
--- linux-2.6.30-orig/fs/pramfs/balloc.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.30/fs/pramfs/balloc.c	2009-06-13 12:51:24.000000000 +0200
@@ -0,0 +1,157 @@
+/*
+ * FILE NAME fs/pramfs/balloc.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *
+ * The blocks allocation and deallocation routines.
+ *
+ * Copyright 2009 Marco Stornelli <marco.stornelli@gmail.com>
+ * Copyright 2003 Sony Corporation
+ * Copyright 2003 Matsushita Electric Industrial Co., Ltd.
+ * 2003-2004 (c) MontaVista Software, Inc. , Steve Longerbeam
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/fs.h>
+#include <linux/quotaops.h>
+#include <linux/bitops.h>
+#include "pram_fs.h"
+
+/*
+ * This just marks in-use the blocks that make up the bitmap.
+ * The bitmap must be writeable before calling.
+ */
+void pram_init_bitmap(struct super_block *sb)
+{
+	struct pram_super_block *ps = pram_get_super(sb);
+	u32 *bitmap = pram_get_bitmap(sb);
+	int blocks = ps->s_bitmap_blocks;
+
+	memset(bitmap, 0, blocks<<sb->s_blocksize_bits);
+
+	while (blocks >= 32) {
+		*bitmap++ = 0xffffffff;
+		blocks -= 32;
+	}
+
+	if (blocks)
+		*bitmap = (1<<blocks) - 1;
+}
+
+
+/* Free absolute blocknr */
+void pram_free_block(struct super_block *sb, int blocknr)
+{
+	struct pram_super_block *ps;
+	off_t bitmap_block;
+	int bitmap_bnr;
+	void *bitmap;
+	void *bp;
+	unsigned long flags;
+
+	flags = 0;
+
+	lock_super(sb);
+
+	bitmap = pram_get_bitmap(sb);
+	/*
+	 * find the block within the bitmap that contains the inuse bit
+	 * for the block we need to free. We need to unlock this bitmap
+	 * block to clear the inuse bit.
+	 */
+	bitmap_bnr = blocknr >> (3 + sb->s_blocksize_bits);
+	bitmap_block = pram_get_block_off(sb, bitmap_bnr);
+	bp = pram_get_block(sb, bitmap_block);
+
+	pram_lock_block(sb, bp, flags);
+	clear_bit(blocknr, bitmap); /* mark the block free */
+	pram_unlock_block(sb, bp, flags);
+
+	ps = pram_get_super(sb);
+	pram_lock_super(ps, flags);
+	if (blocknr < ps->s_free_blocknr_hint)
+		ps->s_free_blocknr_hint = blocknr;
+	ps->s_free_blocks_count++;
+	pram_unlock_super(ps, flags);
+
+	unlock_super(sb);
+}
+
+
+/*
+ * allocate a block and return it's absolute blocknr. Zeroes out the
+ * block if zero set.
+ */
+int pram_new_block(struct super_block *sb, int *blocknr, int zero)
+{
+	struct pram_super_block *ps;
+	off_t bitmap_block;
+	int bnr, bitmap_bnr, errval;
+	void *bitmap;
+	void *bp;
+	unsigned long flags;
+
+	flags = 0;
+
+	lock_super(sb);
+	ps = pram_get_super(sb);
+	bitmap = pram_get_bitmap(sb);
+
+	if (ps->s_free_blocks_count) {
+		/* find the oldest unused block */
+		bnr = find_next_zero_bit(bitmap,
+					 ps->s_blocks_count,
+					 ps->s_free_blocknr_hint);
+
+		if (bnr < ps->s_bitmap_blocks || bnr >= ps->s_blocks_count) {
+			pram_err("no free blocks found!\n");
+			errval = -ENOSPC;
+			goto fail;
+		}
+
+		pram_dbg("allocating blocknr %d\n", bnr);
+		pram_lock_super(ps, flags);
+		ps->s_free_blocks_count--;
+		ps->s_free_blocknr_hint =
+			(bnr < ps->s_blocks_count-1) ? bnr+1 : 0;
+		pram_unlock_super(ps, flags);
+	} else {
+		pram_err("all blocks allocated\n");
+		errval = -ENOSPC;
+		goto fail;
+	}
+
+	/*
+	 * find the block within the bitmap that contains the inuse bit
+	 * for the unused block we just found. We need to unlock it to
+	 * set the inuse bit.
+	 */
+	bitmap_bnr = bnr >> (3 + sb->s_blocksize_bits);
+	bitmap_block = pram_get_block_off(sb, bitmap_bnr);
+	bp = pram_get_block(sb, bitmap_block);
+
+	pram_lock_block(sb, bp, flags);
+	set_bit(bnr, bitmap); /* mark the new block in use */
+	pram_unlock_block(sb, bp, flags);
+
+	if (zero) {
+		bp = pram_get_block(sb, pram_get_block_off(sb, bnr));
+		pram_lock_block(sb, bp, flags);
+		memset(bp, 0, sb->s_blocksize);
+		pram_unlock_block(sb, bp, flags);
+	}
+
+	*blocknr = bnr;
+	errval = 0;
+ fail:
+	unlock_super(sb);
+	return errval;
+}
+
+unsigned long pram_count_free_blocks(struct super_block *sb)
+{
+	struct pram_super_block *ps = pram_get_super(sb);
+	return ps->s_free_blocks_count;
+}


^ permalink raw reply

* [PATCH 00/14] Pramfs: Persistent and protected ram filesystem
From: Marco @ 2009-06-13 13:20 UTC (permalink / raw)
  To: Linux FS Devel; +Cc: Linux Embedded, linux-kernel, Daniel Walker

This is a second attempt at mainlining Pramfs. The first attempt was
back in early 2004 by MontaVista. Since then the kernel code has almost
been completely rewritten. So my first item on the list was porting the
code on a recent kernel version. After that I added the XIP support.

Now some FAQs:

What is the goal of this filesystem?

Many embedded systems have a block of non-volatile RAM separate from
normal system memory, i.e. of which the kernel maintains no memory page
descriptors. For such systems it would be beneficial to mount a
fast read/write filesystem over this "I/O memory", for storing
frequently accessed data that must survive system reboots and power
cycles. An example usage might be system logs under /var/log, or a user
address book in a cell phone or PDA.

Why this kind of filesystem should be "mainlined"?

Linux traditionally had no support for a persistent, non-volatile
RAM-based filesystem, persistent meaning the filesystem survives a
system reboot or power cycle intact. The RAM-based filesystems such as
tmpfs and ramfs have no actual backing store but exist entirely in the
page and buffer caches, hence the filesystem disappears after a system
reboot or power cycle.

Are there any pending patents on this code?

NO, there aren't patents pending on this code. MontaVista had a pending
patent application but now it has abandoned this way. Daniel Walker can
confirm that.


Marco



^ permalink raw reply

* Re: [PATCH 1/2] MMC Agressive clocking framework v2
From: Linus Walleij @ 2009-06-13 12:45 UTC (permalink / raw)
  To: Pierre Ossman, linux-arm-kernel, Pierre Ossman
  Cc: linux-embedded, Linus Walleij
In-Reply-To: <63386a3d0906020536t5a3391f9r921959ba6d6dd96e@mail.gmail.com>

2009/6/2 Linus Walleij <linus.ml.walleij@gmail.com>:

> This patch modified the MMC core code to optionally call the
> set_ios() operation on the driver with the clock frequency set
> to 0 to gate the hardware block clock (and thus the MCI clock)

have you had a chance to look at this for the current merge
window Pierre?

Yours,
Linus Walleij

^ permalink raw reply

* Re: Kernel crashing and log buffers...
From: Russell King @ 2009-06-13 10:26 UTC (permalink / raw)
  To: Robin Getz
  Cc: Mike Frysinger, Greg Ungerer, Paul Mundt, Tim Bird, Wolfgang Denk,
	Grant Erickson, linux-embedded
In-Reply-To: <200906102126.40410.rgetz@blackfin.uclinux.org>

On Wed, Jun 10, 2009 at 09:26:40PM -0400, Robin Getz wrote:
> I would be interested in Paul and Russell - how have you solved this issue? 
> (Or do your kernel's never crash? :)

We haven't any dedicated solution to reading out the crash messages.

What we do have is a very basic platform specific serial IO implementation
which we call "low level debug" - it just provides a number of functions
(eg, printascii).  These functions are callable from assembly or C, and
can work whether the MMU is enabled or not.

People can enable the low level debug build option and patch into
kernel/printk.c to hook it up (or place printascii etc where-ever they
choose.)  It has the advantage that it is entirely synchronous from
every context.

Yes, it requires a little bit of effort on the part of the developer to
hook it up - so far no one has complained about the process of hooking
this facility up in their kernel.

You can use this to debug SMP bringup, but you risk having each CPU
stomping on each other's messages - so it's in no way perfect.

The other way I've seen people read out crash messages is using a
debugger to dump the kernel's log buffer directly.  That seems to work
as well as any other method, and has the advantage that it doesn't
require any kernel modifications.

-- 
Russell King
 Linux kernel    2.6 ARM Linux   - http://www.arm.linux.org.uk/
 maintainer of:

^ permalink raw reply

* Re: AT91SAM9G20 design and power (was and boot times)
From: Christian Gagneraud @ 2009-06-12 18:37 UTC (permalink / raw)
  To: Aras Vaichas; +Cc: linux-embedded
In-Reply-To: <ed62800906102043m723911d8t1968174201ba7fbb@mail.gmail.com>

Aras Vaichas wrote:
> Hi,
> 
> we're designing our next generation RFID reader and I'm planning on
> using the AT91SAM9G20 in the next design. We currently use the
> AT91RM9200.
> 
> Can I get some feedback from people with regards to general design
> configurations  that affect the boot time with respect to this CPU (or
> the AT91SAM9260)
> 
> Some questions are:
> 
> * what is your boot time? What is the time from power-on to kernel
> running, how long does the kernel take to run until init starts, and
> how long does init take?
> * what is your system hardware configuration? CPU+NAND, CPU+NOR+NAND,
> CPU+DATAFLASH+NAND?
> * do you boot everything from the NAND or do you use a combination of
> Dataflash/NOR and NAND?
> * do you use U-Boot, or a minimal custom bootloader that copies a
> kernel image from NAND to SDRAM and then executes it?
> * do you mount a small partition of the NAND to begin with and then
> mount the rest later?
> * do you have a monolithic kernel, or is it split into minimal with
> modules loaded from, say, JFFS2 on NAND?
> * are you using JFFS2 or UBIFS?
> 
> Any info is much appreciated, thank you!

Hi all,

I'm changing slightly the topic...

We are thinking about making our own board as well, but we are mainly 
concerned with power consumption.

Can anyone gives some feedback as well about power consumption of 
their board (or the main components) and as well about the current 
support for power management of the Linux kernel? What about suspend 
to RAM, frequency scaling, etc...?

Regards,
Chris

> 
> regards,
> 
> Aras Vaichas
> --
> To unsubscribe from this list: send the line "unsubscribe linux-embedded" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: AT91SAM9G20 design and boot times
From: Jean-Christophe PLAGNIOL-VILLARD @ 2009-06-12 14:06 UTC (permalink / raw)
  To: Nicolas Ferre; +Cc: Aras Vaichas, linux-embedded
In-Reply-To: <4A30FD17.7060508@atmel.com>

On 14:48 Thu 11 Jun     , Nicolas Ferre wrote:
> Hi,
> 
> Aras Vaichas :
> > Hi,
> > 
> > we're designing our next generation RFID reader and I'm planning on
> > using the AT91SAM9G20 in the next design. We currently use the
> > AT91RM9200.
> 
> Good choice ;-)
> 
> > Can I get some feedback from people with regards to general design
> > configurations  that affect the boot time with respect to this CPU (or
> > the AT91SAM9260)
> 
> I presume that you already know what are the configurations we are using
> at Linux4sam.org on our at91sam9g20ek board. Anyway, I answer your
> questions as it may also interest other readers.
> 
> > Some questions are:
> > 
> > * what is your boot time? What is the time from power-on to kernel
> > running, how long does the kernel take to run until init starts, and
> > how long does init take?
> 
> We have not tried to be clever on speeding up boot process but I guess
> that we can save time:
> - removing unneeded bootloader steps (remove u-boot for instance)
> - removing unused drivers
> - lower timeouts (Ethernet phy detection for example)
> - tailor rootfs exactly to your needs
> 
> That said, here are numbers from our not optimized demo
> (AT91Bootstrap+u-boot+linux+buildroot):
> - ~6s to Linux (can certainly be optimized)
> - ~+2s to init
> - ~+5s to login (here also)
I've done some test on 9263
with the following config
cpu+nor (u-boot+linux+busybox)
~4/5s to the prompt

if the boottime is critical I'll recommend you NOR + XIP

> 
> > * what is your system hardware configuration? CPU+NAND, CPU+NOR+NAND,
> > CPU+DATAFLASH+NAND?
> 
> CPU + NAND can lower your BOM
> 
> > * do you boot everything from the NAND or do you use a combination of
> > Dataflash/NOR and NAND?
I've test it on 9263
> 
> Both.
> 
> > * do you use U-Boot, or a minimal custom bootloader that copies a
> > kernel image from NAND to SDRAM and then executes it?
> 
> If boot time is a hot topic, choose AT91Bootstrap that directly loads Linux.
I disagree on this because you will loose a lot's of possibity as bootcount
DFU, store your kernel in your rootfs etc...

> 
> > * do you mount a small partition of the NAND to begin with and then
> > mount the rest later?
> 
I'll consider to switch to UBIFS
and use lzma compression (for the uImage) if no XIP

Best Regards,
J.

^ permalink raw reply

* Re: Kernel crashing and log buffers...
From: Wolfgang Denk @ 2009-06-12  5:33 UTC (permalink / raw)
  To: David VomLehn
  Cc: Grant Erickson, Robin Getz, Mike Frysinger, Greg Ungerer,
	Russell King, Paul Mundt, Tim Bird, linux-embedded,
	Hariprasad Nellitheertha
In-Reply-To: <20090612003302.GA23715@cuplxvomd02.corp.sa.net>

Dear David VomLehn,

In message <20090612003302.GA23715@cuplxvomd02.corp.sa.net> you wrote:
>
> > However, the value and what's being proposed here and what I and others
> > proposed--at least in the embedded kingdom--seems high and the features and
> > implementation needn't be mutually exclusive.
> 
> I agree. In this case, we have three different approaches to three different
> problems (bootloader buffers, continuous state logging, and in-kernel capture
> of logging). All are problems that need to be solved. Personally, I'd love
> to have the continuous state logging, though I don't need the bootloader
> buffer part.

Question is: do we need three different solutions, or can we come up
with one solution that covers all?

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
"If it ain't broke, don't fix it."                       - Bert Lantz

^ permalink raw reply

* Re: Kernel crashing and log buffers...
From: Robin Getz @ 2009-06-12  4:54 UTC (permalink / raw)
  To: David VomLehn
  Cc: Mike Frysinger, Greg Ungerer, Russell King, Paul Mundt, Tim Bird,
	Wolfgang Denk, Grant Erickson, linux-embedded
In-Reply-To: <20090612010707.GB23715@cuplxvomd02.corp.sa.net>

On Thu 11 Jun 2009 21:07, David VomLehn pondered:
> It may be helpful if you can say a bit more about
> the problem you are trying to solve.

Yeah, I guess defining the goals is a good place to start (and 
the hardest to come to agreement on).

 - early crash analysis - before the kernel has set up the console 
   or console drivers, (which happens after interrupts, caches, & 
   memory, are set up) crashes are pretty difficult to figure out. 
   Typically - the kernel crashes or hangs without any output on 
   the console.
   What the end users experiences is typically...
   "Starting Kernel at = xxxx"
   and nothing else. The valuable info (if any) is stuck in the 
   kernel's log buffer.

   earlyprintk helps with this, however - this assumes that the 
   kernel has set up the early_printk console properly. If there
   is a problem doing that (wrong driver compiled in, wrong pin 
   muxing, etc), then the info is still stuck (unseen) in the
   kernel's log buffer.

   - but is only to be supported on:
   Documentation/kernel-parameters.txt
       earlyprintk=    [X86-32,X86-64,SH,BLACKFIN]
                        earlyprintk=vga
                        earlyprintk=serial[,ttySn[,baudrate]]
                        earlyprintk=dbgp

   see:
   arch/x86/kernel/early_printk.c
   arch/sh/kernel/early_printk.c
   arch/blackfin/kernel/early_printk.c

   For giggles - put a panic() in your arch/*/kernel/setup.c:setup_arch()
   With earlyprintk - you still get to see what happened (if the 
   earlyprintk console is working OK).

   Problem:
    Even with earlyprintk - there are times when things not getting
    out of the system, and are stuck in the printk __log_buf.

   David's patch might help with this - as architectures could register, 
   and write all the prink data into a buffer in memory - where it could
   be read out by the bootloader, or future kernels - but it would need
   some tweaks to support early functionality (but I don't think much).

 - late crash analysis - Sometimes - even after the kernel is up
   and running properly - a device driver does a bad thing. 
   Normally - complete kernel dumps can come out a serial
   console, and you can you your favourite serial application
   to scroll back and determine what is going on.

   In many embedded devices - this is not a possibility, since
   all the serial ports are in use (Irda, Bluetooth, GPS, etc).

   In devices that are deployed in the field - this is not a
   possibility, since nothing is connected to the serial 
   console (if it exists) for logging.

   Even when there is no console device, or anything attached to the
   console device, everything is in the __log_buf.

   Problem:
   There doesn't appear (to me) to be anything in mainline to help 
   with this.

   David's patch might help with this - as architectures could register, 
   and write all the prink data into a buffer in memory - where it could
   be read out by the bootloader, or future kernels.

 - allowing board startup information (POST) created/output from
   the boot loader to be transfered to the standard/normal kernel
   log processing features (syslog/dmesg/etc).

   There doesn't appear (to me) to be anything in mainline to help 
   with this.
 
   David's patch could help with this - as architectures could register, 
   and if a magic number was in the start of the buffer, it could just
   strnlen the buffer, and then do a printk on it. The downside is it would
   not be at the start of the buffer - as Grant's and Wolfgang's suggestion.
   But I'm not sure this is a requirement???


Is there anything I'm missing?

^ permalink raw reply

* Re: Kernel crashing and log buffers...
From: David VomLehn @ 2009-06-12  1:07 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: Robin Getz, Greg Ungerer, Russell King, Paul Mundt, Tim Bird,
	Wolfgang Denk, Grant Erickson, linux-embedded
In-Reply-To: <8bd0f97a0906111627h128cc561y2bf4a0b2b30d7187@mail.gmail.com>

On Thu, Jun 11, 2009 at 07:27:16PM -0400, Mike Frysinger wrote:
> On Thu, Jun 11, 2009 at 13:53, David VomLehn wrote:
> > On Wed, Jun 10, 2009 at 09:26:40PM -0400, Robin Getz wrote:
...
> > Our kernel does crash, so we have to do this. I had submitted a patch a
> > while ago that tweaks emit_log_char, but this was bounced, reasonably,
> > because it would be interferring with the great majority of people who
> > are not interested in capturing log output. The suggestion was made that
> > we do this with a console driver. I've recently got a version working, as
> > a module, but I've only started testing of the version integrated into the
> > kernel tree.  Still, post early, post often, so I've appended a version
> > of the patch here to see if this seems to be the right direction.
> 
> i guess there's two distinct crash types: early and late.  your
> console driver seems like it should be able to handle the "late"
> variety ok (i.e. the kernel is up and running and at some point, it
> blows up).  but it doesnt address the early crashes which is what
> we're currently looking for (i.e. kernel crash occurs before the
> serial console is up and running).
> 
> i think extending this driver to include early printk support should
> address that ?

If you really want to see really early output, I don't think this will give
you more benefit than simply looking at log_buf through your favorite kernel
debugging tool. Which is something I do with some regularity, so I know that
it can be a bit of a pain. It may be helpful if you can say a bit more about
the problem you are trying to solve.

> -mike

David VomLehn

^ permalink raw reply

* Re: Kernel crashing and log buffers...
From: David VomLehn @ 2009-06-12  0:33 UTC (permalink / raw)
  To: Grant Erickson
  Cc: Robin Getz, Mike Frysinger, Greg Ungerer, Russell King,
	Paul Mundt, Tim Bird, Wolfgang Denk, linux-embedded,
	Hariprasad Nellitheertha
In-Reply-To: <C656DA04.1708D%gerickson@nuovations.com>

On Thu, Jun 11, 2009 at 03:57:56PM -0700, Grant Erickson wrote:
> On 6/11/09 11:52 AM, Robin Getz wrote:
> > On Thu 11 Jun 2009 13:53, David VomLehn pondered:
> >> On Wed, Jun 10, 2009 at 09:26:40PM -0400, Robin Getz wrote:
> >>> I would be interested in Paul and Russell - how have you solved this
> >>> issue? (Or do your kernel's never crash? :)
> >> 
> >> Our kernel does crash, so we have to do this. I had submitted a patch a
> >> while ago that tweaks emit_log_char, but this was bounced, reasonably,
> >> because it would be interferring with the great majority of people who
> >> are not interested in capturing log output. The suggestion was made that
> >> we do this with a console driver. I've recently got a version working,
> >> as a module, but I've only started testing of the version integrated
> >> into the kernel tree.  Still, post early, post often, so I've appended
> >> a version of the patch here to see if this seems to be the right
> >> direction. 
> > 
> > Yeah - it looks like n people have done this n ways.
> > 
> > I think even Andrew M had mentioned that he had done something in a past
> > embedded life.
> > 
> > I think what you have would do what I need it to do - I'm not so sure about
> > what Wolfgang/Grant had in mind (- since they wanted also to dump buffers
> > from the bootloader into the console for syslog processing)...
> 
> Regrettably, I have not had the time to follow-up on this since my last
> commentary in March:
> 
>     http://lkml.org/lkml/2009/3/31/293
> 
> However, from what I can glean of the discussion, you are correct that this
> does not precisely cover what Wolfgang (originally) or, later, I was working
> towards in that neither boot loader logs nor round-trip log buffering
> (bootloader to kernel and back again) are covered.
> 
> However, the value and what's being proposed here and what I and others
> proposed--at least in the embedded kingdom--seems high and the features and
> implementation needn't be mutually exclusive.

I agree. In this case, we have three different approaches to three different
problems (bootloader buffers, continuous state logging, and in-kernel capture
of logging). All are problems that need to be solved. Personally, I'd love
to have the continuous state logging, though I don't need the bootloader
buffer part.

> Grant

^ permalink raw reply

* Re: Kernel crashing and log buffers...
From: Mike Frysinger @ 2009-06-11 23:27 UTC (permalink / raw)
  To: David VomLehn
  Cc: Robin Getz, Greg Ungerer, Russell King, Paul Mundt, Tim Bird,
	Wolfgang Denk, Grant Erickson, linux-embedded
In-Reply-To: <20090611175303.GA10058@cuplxvomd02.corp.sa.net>

On Thu, Jun 11, 2009 at 13:53, David VomLehn wrote:
> On Wed, Jun 10, 2009 at 09:26:40PM -0400, Robin Getz wrote:
>> On 17 Oct 2007, after much discussion and debate, Mike added add two new
>> functions for reading the kernel log buffer (from kernel space).
>>
>> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=0b15d04af3dd996035d8fa81fc849d049171f9c3
>>
>> The intention was for them to be used by recovery/dump/debug code so the
>> kernel log can be easily retrieved/parsed by the bootloader (or another
>> kernel) in a crash scenario.
>>
>> I was going to push the arch specific recovery/dump/debug code that uses them
>> upstream (yeah, it has been a little while - but anyway...) it was removed
>> since then by Roel Kluin ...
>>
>> 21 Oct 2008:
>> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=acff181d3574244e651913df77332e897b88bff4
>>
>> Before I ask Andrew to add it back, I thought I would make sure it was still a
>> useful function, and did everything everyone wanted - and wasn't deemed
>> unnecessary by a feature/function that I wasn't aware of - like the next
>> thing...
>>
>> I saw the patch Grant sent recently - Add Alternative Log Buffer Support for
>> printk Messages (in Nov2008 to the embedded list, and Jan 2009 to lkml) - but
>> I couldn't find any followups - and it doesn't seem to be in Linus's tree.
>>
>> http://thread.gmane.org/gmane.linux.kernel.embedded/1358/focus=1373
>>
>> http://lkml.org/lkml/2009/1/21/250
>>
>> I can see the desire on Wolfgang & Grant's part - for not needing the copy
>> from/to - (you never have to worry about crashing "nicely" - the kernel
>> panics, but you still need to copy memory around - potentially causing all
>> kinds of secondary issues - and masking the real reason the crash occurred).
>>
>> But for the majority of the case - the copy from/to would work much better
>> than what we have in mainstream today...
>>
>>
>> I would be interested in Paul and Russell - how have you solved this issue?
>> (Or do your kernel's never crash? :)
>
> Our kernel does crash, so we have to do this. I had submitted a patch a
> while ago that tweaks emit_log_char, but this was bounced, reasonably,
> because it would be interferring with the great majority of people who
> are not interested in capturing log output. The suggestion was made that
> we do this with a console driver. I've recently got a version working, as
> a module, but I've only started testing of the version integrated into the
> kernel tree.  Still, post early, post often, so I've appended a version
> of the patch here to see if this seems to be the right direction.

i guess there's two distinct crash types: early and late.  your
console driver seems like it should be able to handle the "late"
variety ok (i.e. the kernel is up and running and at some point, it
blows up).  but it doesnt address the early crashes which is what
we're currently looking for (i.e. kernel crash occurs before the
serial console is up and running).

i think extending this driver to include early printk support should
address that ?
-mike

^ permalink raw reply

* Re: Kernel crashing and log buffers...
From: Grant Erickson @ 2009-06-11 22:57 UTC (permalink / raw)
  To: Robin Getz, David VomLehn
  Cc: Mike Frysinger, Greg Ungerer, Russell King, Paul Mundt, Tim Bird,
	Wolfgang Denk, linux-embedded, Hariprasad Nellitheertha
In-Reply-To: <200906111452.39210.rgetz@blackfin.uclinux.org>

On 6/11/09 11:52 AM, Robin Getz wrote:
> On Thu 11 Jun 2009 13:53, David VomLehn pondered:
>> On Wed, Jun 10, 2009 at 09:26:40PM -0400, Robin Getz wrote:
>>> I would be interested in Paul and Russell - how have you solved this
>>> issue? (Or do your kernel's never crash? :)
>> 
>> Our kernel does crash, so we have to do this. I had submitted a patch a
>> while ago that tweaks emit_log_char, but this was bounced, reasonably,
>> because it would be interferring with the great majority of people who
>> are not interested in capturing log output. The suggestion was made that
>> we do this with a console driver. I've recently got a version working,
>> as a module, but I've only started testing of the version integrated
>> into the kernel tree.  Still, post early, post often, so I've appended
>> a version of the patch here to see if this seems to be the right
>> direction. 
> 
> Yeah - it looks like n people have done this n ways.
> 
> I think even Andrew M had mentioned that he had done something in a past
> embedded life.
> 
> I think what you have would do what I need it to do - I'm not so sure about
> what Wolfgang/Grant had in mind (- since they wanted also to dump buffers
> from the bootloader into the console for syslog processing)...

Regrettably, I have not had the time to follow-up on this since my last
commentary in March:

    http://lkml.org/lkml/2009/3/31/293

However, from what I can glean of the discussion, you are correct that this
does not precisely cover what Wolfgang (originally) or, later, I was working
towards in that neither boot loader logs nor round-trip log buffering
(bootloader to kernel and back again) are covered.

However, the value and what's being proposed here and what I and others
proposed--at least in the embedded kingdom--seems high and the features and
implementation needn't be mutually exclusive.

Regards,

Grant


^ permalink raw reply

* Re: Kernel crashing and log buffers...
From: David VomLehn @ 2009-06-11 22:46 UTC (permalink / raw)
  To: Tim Bird
  Cc: Robin Getz, Mike Frysinger, Greg Ungerer, Russell King,
	Paul Mundt, Wolfgang Denk, Grant Erickson, linux-embedded
In-Reply-To: <4A314B81.7060401@am.sony.com>

On Thu, Jun 11, 2009 at 11:22:57AM -0700, Tim Bird wrote:
> David VomLehn wrote:
> > Our kernel does crash, so we have to do this. I had submitted a patch a
> > while ago that tweaks emit_log_char, but this was bounced, reasonably,
> > because it would be interferring with the great majority of people who
> > are not interested in capturing log output. The suggestion was made that
> > we do this with a console driver. I've recently got a version working, as
> > a module, but I've only started testing of the version integrated into the
> > kernel tree.  Still, post early, post often, so I've appended a version
> > of the patch here to see if this seems to be the right direction.
> > 
> > Regardless whether my particular patch seems like the right way to do this,
> > we do need to solve this problem for the embedded world. It is one of the
> > few areas where we have needs not shared by the rest of the kernel community.
> 
> In general, I like this approach to solve this problem.  I spend most of
> my time in the lab with prototype boards that use a serial console, so my
> terminal history has always been my crashdump repository. ;-)
> 
> This approach it unobtrusive to the rest of the log buffer system.  I never
> did like the patches that introduced other ways to hack into the log
> buffer.  The printk/log buffer code path is already convoluted enough,
> and I didn't like the idea of adding additional hooks.  this approach
> leverages an already existing hook.

The one thing that is missing over some other approaches is that log output
captured by this method will be filtered, just like all of the other consoles,
by the printk priority. It might be useful to have the ability to specify
the priority level for each console. So, you could have only KERN_CRIT and
above going to your serial console, but configure the logging console to
capture everything down to KERN_WARNING. This is a refinement, though, and I
didn't want to make things overly complex without a good feeling that it was
necessary.

> I don't have much comment on the code specifics, but I have one nit
> with the config help...
...
> > +	help
> > +	  This contains a pseudo-console to record and divert kernel console
> > +	  output, which is probably of most used to embedded systems. When
> should be "most use" (no 'd')

Thanks for picking the nit!

> Tim Bird

David VomLehn

^ permalink raw reply

* Re: Kernel crashing and log buffers...
From: David VomLehn @ 2009-06-11 19:35 UTC (permalink / raw)
  To: Robin Getz
  Cc: Mike Frysinger, Greg Ungerer, Russell King, Paul Mundt, Tim Bird,
	Wolfgang Denk, Grant Erickson, linux-embedded,
	Hariprasad Nellitheertha
In-Reply-To: <200906111452.39210.rgetz@blackfin.uclinux.org>

On Thu, Jun 11, 2009 at 02:52:38PM -0400, Robin Getz wrote:
> On Thu 11 Jun 2009 13:53, David VomLehn pondered:
> > On Wed, Jun 10, 2009 at 09:26:40PM -0400, Robin Getz wrote:
...
> > Our kernel does crash, so we have to do this. I had submitted a patch a
> > while ago that tweaks emit_log_char, but this was bounced, reasonably,
> > because it would be interferring with the great majority of people who
> > are not interested in capturing log output. The suggestion was made that
> > we do this with a console driver. I've recently got a version working,
> > as a module, but I've only started testing of the version integrated 
> > into the kernel tree.  Still, post early, post often, so I've appended 
> > a version of the patch here to see if this seems to be the right 
> > direction. 
> 
> Yeah - it looks like n people have done this n ways. 
> 
> I think even Andrew M had mentioned that he had done something in a past 
> embedded life.

It ain't hard, but I think we need a common implementation to go into the
kernel.

> I think what you have would do what I need it to do - I'm not so sure about 
> what Wolfgang/Grant had in mind (- since they wanted also to dump buffers 
> from the bootloader into the console for syslog processing)...

This is definitely different what what Wolfgang/Grant had in mind.

> > Regardless whether my particular patch seems like the right way to do
> > this, we do need to solve this problem for the embedded world. It is
> > one of the few areas where we have needs not shared by the rest of
> > the kernel community.
> 
> I'm not so sure - googling for things last night led me to this:
> 
> http://www.faqs.org/patents/app/20090044051
> EXTRACTING LOG AND TRACE BUFFERS IN THE EVENT OF SYSTEM CRASHES
> Hariprasad V. Nellitheertha  - Linux Technology Center, India Software Labs, 
> IBM India.
> 
> So - I think as Paul stated in a previous conversation - the high availability 
> needs of servers are similar to the high availability needs of embedded...

This is also different as it involves continuous logging of system state
rather than producing crash logs. The continuous logging is definitely of
wider interest. I did some work a couple of years ago to see what
it would take to specify the buffer for LTT FDR data, though this work was
dropped as lower priority, and I never got back to it.

> -Robin

David

^ permalink raw reply

* Re: Kernel crashing and log buffers...
From: Robin Getz @ 2009-06-11 18:52 UTC (permalink / raw)
  To: David VomLehn
  Cc: Mike Frysinger, Greg Ungerer, Russell King, Paul Mundt, Tim Bird,
	Wolfgang Denk, Grant Erickson, linux-embedded,
	Hariprasad Nellitheertha
In-Reply-To: <20090611175303.GA10058@cuplxvomd02.corp.sa.net>

On Thu 11 Jun 2009 13:53, David VomLehn pondered:
> On Wed, Jun 10, 2009 at 09:26:40PM -0400, Robin Getz wrote:
> > On 17 Oct 2007, after much discussion and debate, Mike added add 
> > two new functions for reading the kernel log buffer (from kernel space).
> > 
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=0b15d04af3dd996035d8fa81fc849d049171f9c3
> > 
> > The intention was for them to be used by recovery/dump/debug code
> > so the kernel log can be easily retrieved/parsed by the bootloader
> > (or another kernel) in a crash scenario.
> > 
> > I was going to push the arch specific recovery/dump/debug code 
> > that uses them upstream (yeah, it has been a little while - but 
> > anyway...) it was removed since then by Roel Kluin ...
> > 
> > 21 Oct 2008:
> > 
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=acff181d3574244e651913df77332e897b88bff4
> > 
> > Before I ask Andrew to add it back, I thought I would make sure it
> > was still a useful function, and did everything everyone wanted - 
> > and wasn't deemed unnecessary by a feature/function that I wasn't
> > aware of - like the next thing...
> > 
> > I saw the patch Grant sent recently - Add Alternative Log Buffer
> > Support for printk Messages (in Nov2008 to the embedded list, and 
> > Jan 2009 to lkml) - but I couldn't find any followups - and it 
> > doesn't seem to be in Linus's tree.
> > 
> > http://thread.gmane.org/gmane.linux.kernel.embedded/1358/focus=1373
> > 
> > http://lkml.org/lkml/2009/1/21/250
> > 
> > I can see the desire on Wolfgang & Grant's part - for not needing 
> > the copy from/to - (you never have to worry about crashing "nicely" - 
> > the kernel panics, but you still need to copy memory around - 
> > potentially causing all kinds of secondary issues - and masking the
> > real reason the crash occurred).
> > 
> > But for the majority of the case - the copy from/to would work much
> > better than what we have in mainstream today...
> > 
> > 
> > I would be interested in Paul and Russell - how have you solved this
> > issue? (Or do your kernel's never crash? :)
> 
> Our kernel does crash, so we have to do this. I had submitted a patch a
> while ago that tweaks emit_log_char, but this was bounced, reasonably,
> because it would be interferring with the great majority of people who
> are not interested in capturing log output. The suggestion was made that
> we do this with a console driver. I've recently got a version working,
> as a module, but I've only started testing of the version integrated 
> into the kernel tree.  Still, post early, post often, so I've appended 
> a version of the patch here to see if this seems to be the right 
> direction. 

Yeah - it looks like n people have done this n ways. 

I think even Andrew M had mentioned that he had done something in a past 
embedded life.

I think what you have would do what I need it to do - I'm not so sure about 
what Wolfgang/Grant had in mind (- since they wanted also to dump buffers 
from the bootloader into the console for syslog processing)...

> Regardless whether my particular patch seems like the right way to do
> this, we do need to solve this problem for the embedded world. It is
> one of the few areas where we have needs not shared by the rest of
> the kernel community.

I'm not so sure - googling for things last night led me to this:

http://www.faqs.org/patents/app/20090044051
EXTRACTING LOG AND TRACE BUFFERS IN THE EVENT OF SYSTEM CRASHES
Hariprasad V. Nellitheertha  - Linux Technology Center, India Software Labs, 
IBM India.

So - I think as Paul stated in a previous conversation - the high availability 
needs of servers are similar to the high availability needs of embedded...

Hari - did any of the work you did end up in mainline?

Thanks
-Robin

^ permalink raw reply

* Re: Kernel crashing and log buffers...
From: Tim Bird @ 2009-06-11 18:22 UTC (permalink / raw)
  To: David VomLehn
  Cc: Robin Getz, Mike Frysinger, Greg Ungerer, Russell King,
	Paul Mundt, Wolfgang Denk, Grant Erickson, linux-embedded
In-Reply-To: <20090611175303.GA10058@cuplxvomd02.corp.sa.net>

David VomLehn wrote:
> Our kernel does crash, so we have to do this. I had submitted a patch a
> while ago that tweaks emit_log_char, but this was bounced, reasonably,
> because it would be interferring with the great majority of people who
> are not interested in capturing log output. The suggestion was made that
> we do this with a console driver. I've recently got a version working, as
> a module, but I've only started testing of the version integrated into the
> kernel tree.  Still, post early, post often, so I've appended a version
> of the patch here to see if this seems to be the right direction.
> 
> Regardless whether my particular patch seems like the right way to do this,
> we do need to solve this problem for the embedded world. It is one of the
> few areas where we have needs not shared by the rest of the kernel community.

In general, I like this approach to solve this problem.  I spend most of
my time in the lab with prototype boards that use a serial console, so my
terminal history has always been my crashdump repository. ;-)

This approach it unobtrusive to the rest of the log buffer system.  I never
did like the patches that introduced other ways to hack into the log
buffer.  The printk/log buffer code path is already convoluted enough,
and I didn't like the idea of adding additional hooks.  this approach
leverages an already existing hook.

I don't have much comment on the code specifics, but I have one nit
with the config help...

> diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
> index 735bbe2..882ee57 100644
> --- a/drivers/char/Kconfig
> +++ b/drivers/char/Kconfig
> @@ -684,6 +684,20 @@ config HVCS
>  	  which will also be compiled when this driver is built as a
>  	  module.
>  
> +config CONSLOGGER
> +	tristate "Pseudo-console for capturing console output"
> +	depends on PRINTK
> +	default n
> +	help
> +	  This contains a pseudo-console to record and divert kernel console
> +	  output, which is probably of most used to embedded systems. When
should be "most use" (no 'd')

> +	  a system crashes, it can divert printk output for logging information
> +	  about the failure in some persistent location. Then the output from
> +	  any function that uses printk() to display information, such as
> +	  dump_stack() can be stored in the failure log. It also stores
> +	  console output in a circular buffer so that that last <n> messages
> +	  can be added to the failure log.
> +
>  config IBM_BSR
>  	tristate "IBM POWER Barrier Synchronization Register support"
>  	depends on PPC_PSERIES

=============================
Tim Bird
Architecture Group Chair, CE Linux Forum
Senior Staff Engineer, Sony Corporation of America
=============================

^ permalink raw reply

* Re: Kernel crashing and log buffers...
From: David VomLehn @ 2009-06-11 17:53 UTC (permalink / raw)
  To: Robin Getz
  Cc: Mike Frysinger, Greg Ungerer, Russell King, Paul Mundt, Tim Bird,
	Wolfgang Denk, Grant Erickson, linux-embedded
In-Reply-To: <200906102126.40410.rgetz@blackfin.uclinux.org>

On Wed, Jun 10, 2009 at 09:26:40PM -0400, Robin Getz wrote:
> On 17 Oct 2007, after much discussion and debate, Mike added add two new 
> functions for reading the kernel log buffer (from kernel space).
> 
> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=0b15d04af3dd996035d8fa81fc849d049171f9c3
> 
> The intention was for them to be used by recovery/dump/debug code so the 
> kernel log can be easily retrieved/parsed by the bootloader (or another 
> kernel) in a crash scenario.
> 
> I was going to push the arch specific recovery/dump/debug code that uses them 
> upstream (yeah, it has been a little while - but anyway...) it was removed 
> since then by Roel Kluin ...
> 
> 21 Oct 2008:
> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=acff181d3574244e651913df77332e897b88bff4
> 
> Before I ask Andrew to add it back, I thought I would make sure it was still a 
> useful function, and did everything everyone wanted - and wasn't deemed 
> unnecessary by a feature/function that I wasn't aware of - like the next 
> thing...
> 
> I saw the patch Grant sent recently - Add Alternative Log Buffer Support for 
> printk Messages (in Nov2008 to the embedded list, and Jan 2009 to lkml) - but 
> I couldn't find any followups - and it doesn't seem to be in Linus's tree.
> 
> http://thread.gmane.org/gmane.linux.kernel.embedded/1358/focus=1373
> 
> http://lkml.org/lkml/2009/1/21/250
> 
> I can see the desire on Wolfgang & Grant's part - for not needing the copy 
> from/to - (you never have to worry about crashing "nicely" - the kernel 
> panics, but you still need to copy memory around - potentially causing all 
> kinds of secondary issues - and masking the real reason the crash occurred).
> 
> But for the majority of the case - the copy from/to would work much better 
> than what we have in mainstream today...
> 
> 
> I would be interested in Paul and Russell - how have you solved this issue? 
> (Or do your kernel's never crash? :)

Our kernel does crash, so we have to do this. I had submitted a patch a
while ago that tweaks emit_log_char, but this was bounced, reasonably,
because it would be interferring with the great majority of people who
are not interested in capturing log output. The suggestion was made that
we do this with a console driver. I've recently got a version working, as
a module, but I've only started testing of the version integrated into the
kernel tree.  Still, post early, post often, so I've appended a version
of the patch here to see if this seems to be the right direction.

Regardless whether my particular patch seems like the right way to do this,
we do need to solve this problem for the embedded world. It is one of the
few areas where we have needs not shared by the rest of the kernel community.

> -Robin
------------------------------------ CUT HERE --------------------------------
Provide functions for capturing console output for storage. The primary user
is likely to be embedded systems that don't have the storage for core dumps
but do have a need to log kernel panic information for later evaluation. It
offers two main areas of functionality:

o	It can maintain a circular log of console output so that kernel log
	messages written before panic() was called can be retrieved to be
	added to the failure log.
o	A function can be registered to store output from printk() in a
	persistent location, such as a reserved location in RAM.  Then,
	printk() can be used either directly, to print state information, or
	indirectly, through standard functions like dump_stack() and
	show_regs().

During normal operation, we use the circular logging. When we crash, almost
the first thing we do is to switch to storing output. This goes in a memory
buffer that is preserved over reboots. We then write a detailed crash
report using printk() and functions that use printk(). We retrieve the last
n lines of the log before the crash and print it, so that gets captured
in the log, too.

Signed-off-by: David VomLehn <dvomlehn@cisco.com>
---
 drivers/char/Kconfig       |   14 +++
 drivers/char/Makefile      |    2 +
 drivers/char/conslogger.c  |  233 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/conslogger.h |   52 ++++++++++
 4 files changed, 301 insertions(+), 0 deletions(-)

diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 735bbe2..882ee57 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -684,6 +684,20 @@ config HVCS
 	  which will also be compiled when this driver is built as a
 	  module.
 
+config CONSLOGGER
+	tristate "Pseudo-console for capturing console output"
+	depends on PRINTK
+	default n
+	help
+	  This contains a pseudo-console to record and divert kernel console
+	  output, which is probably of most used to embedded systems. When
+	  a system crashes, it can divert printk output for logging information
+	  about the failure in some persistent location. Then the output from
+	  any function that uses printk() to display information, such as
+	  dump_stack() can be stored in the failure log. It also stores
+	  console output in a circular buffer so that that last <n> messages
+	  can be added to the failure log.
+
 config IBM_BSR
 	tristate "IBM POWER Barrier Synchronization Register support"
 	depends on PPC_PSERIES
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 9caf5b5..ca62934 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -111,6 +111,8 @@ obj-$(CONFIG_PS3_FLASH)		+= ps3flash.o
 obj-$(CONFIG_JS_RTC)		+= js-rtc.o
 js-rtc-y = rtc.o
 
+obj-$(CONFIG_CONSLOGGER)	+= conslogger.o
+
 # Files generated that shall be removed upon make clean
 clean-files := consolemap_deftbl.c defkeymap.c
 
diff --git a/drivers/char/conslogger.c b/drivers/char/conslogger.c
new file mode 100644
index 0000000..ad44dc8
--- /dev/null
+++ b/drivers/char/conslogger.c
@@ -0,0 +1,233 @@
+/*
+ *				conslogger.c
+ *
+ * Console log diversion
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:       David VomLehn
+ *
+ * This offers two functionalities. One is to continually record output from
+ * printk in a buffer for retrieval of history, while the second is to call
+ * a registered function so that printk output can be stored.
+ */
+
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/gfp.h>
+#include <linux/slab.h>
+#include <linux/compiler.h>		/* For barrier() */
+#include <linux/conslogger.h>
+
+/* Return a value for indexing into the conslog array */
+#define BUF_IDX(conslog, idx)	((idx) & (conslog)->mask)
+
+static void conslog_write(struct console *c, const char *p, unsigned n);
+
+/**
+ * conslog_register - create and register a logging console
+ * @order:	Power of two of the log buffer size
+ *
+ * Returns an ERR_VALUE on error or a pointer to a &struct conslog on success.
+ */
+struct conslog *conslog_register(unsigned order)
+{
+	struct conslog *conslog;
+
+	conslog = kmalloc(sizeof(*conslog), GFP_KERNEL);
+
+	if (conslog == NULL)
+		conslog = ERR_PTR(-ENOMEM);
+
+	else {
+		size_t	size;
+		char	*buf;
+
+		memset(conslog, 0, sizeof(*conslog));
+		size = 1 << order;
+		buf = kmalloc(size, GFP_KERNEL);
+
+		if (buf == NULL) {
+			kfree(conslog);
+			conslog = ERR_PTR(-ENOMEM);
+		}
+
+		else {
+			conslog->size = size;
+			conslog->buf = buf;
+			conslog->mask = conslog->size - 1;
+			conslog->state = CONSLOG_DISABLE;
+
+			/* Initialize the console part of the structure */
+			conslog->console.data = conslog;
+
+			strlcpy(conslog->console.name, "console_logger",
+				sizeof(conslog->console.name));
+			conslog->console.write = conslog_write;
+			conslog->console.flags = CON_ENABLED;
+			conslog->console.index = -1;
+			register_console(&conslog->console);
+		}
+	}
+
+	return conslog;
+}
+
+/**
+ * conslog_unregister - Unregister a console logger
+ * @conslog:	Value returned by conslog_register
+ */
+int conslog_unregister(struct conslog *conslog)
+{
+	int	ret;
+
+	ret = unregister_console(&conslog->console);
+
+	if (conslog->buf != NULL)
+		kfree(conslog->buf);
+
+	return ret;
+}
+
+/**
+ * conslog_record - enable or disable storage of console to circular buffer
+ * @conslog:	Pointer to &struct conslog returned by conslog_register()
+ * @record:	True if data should be stored in the circular buffer, false
+ *		to disable data storage.
+ */
+void conslog_record(struct conslog *conslog, bool record)
+{
+	conslog->state = record ? CONSLOG_RECORD : CONSLOG_DISABLE;
+}
+
+/**
+ * conslog_divert - define a function to call with console output
+ * @conslog:	Pointer to &struct conslog returned by conslog_register()
+ * @divert:	Pointer to the function to call
+ */
+void conslog_divert(struct conslog *conslog,
+	void (*divert)(const char *p, size_t n))
+{
+	conslog->divert = divert;
+	conslog->state = CONSLOG_DIVERT;
+}
+
+/**
+ * conslog_write - console write function
+ * @c:	Pointer to the &console structure
+ * @p:	Pointer to data to write
+ * @n:	Number of bytes to write
+ *
+ * Called with console write data, which it either stores in the buffer,
+ * passes to the diversion function, or just ignores.
+ */
+static void conslog_write(struct console *c, const char *p, unsigned n)
+{
+	struct conslog *conslog;
+	static bool busy;
+
+	if (busy)
+		return;
+
+	busy = true;
+	barrier();
+	conslog = c->data;
+
+	switch (conslog->state) {
+	case CONSLOG_RECORD:
+		while (n-- != 0) {
+			conslog->buf[BUF_IDX(conslog, conslog->idx)] = *p++;
+			conslog->idx++;
+			if (unlikely(conslog->idx == conslog->size))
+				conslog->wrapped = true;
+		}
+		break;
+
+	case CONSLOG_DIVERT:
+		conslog->divert(p, n);
+		break;
+
+	case CONSLOG_DISABLE:
+		break;
+	}
+	busy = false;
+	barrier();
+}
+
+/**
+ * conslog_last - extract the last @n lines from recorded data
+ * @conslog:	Pointer to the &struct consolog from which to extract lines
+ * @nlines:	Number of lines to extract
+ * @report:	Function to report lines
+ *
+ * It is best to call this with recording disabled, though this is not
+ * enforced. See conslog_record().
+ */
+void conslog_last(struct conslog *conslog, unsigned nlines,
+	void (*report)(const char *p, unsigned cnt))
+{
+	unsigned	i;
+	unsigned	newest;
+	unsigned	oldest;
+	unsigned	n;
+
+	if (nlines == 0)
+		return;
+
+	oldest = conslog->wrapped ? conslog->idx - conslog->size : 0;
+
+	/* Set newest to be the index of the character most recently added to
+	 * the buffer, but if the most recent line ends with a newline, skip
+	 * the newline. This makes things work correctly even if the last
+	 * line was incomplete. */
+	newest = conslog->idx - 1;
+	if (newest != oldest && conslog->buf[BUF_IDX(conslog, newest)] == '\n')
+		newest--;
+
+	/* Scan backwards for the requested number of lines */
+	for (i = newest, n = 0; n != nlines && i != oldest; i--) {
+		if (conslog->buf[BUF_IDX(conslog, i)] == '\n')
+			n++;
+	}
+
+	/* We may be part-way through a line, in which case we need to scan
+	 * forward until we find a newline. Then we skip that newline. */
+	while (i != newest && conslog->buf[BUF_IDX(conslog, i)] != '\n')
+		i++;
+	i++;
+
+	/* We have n lines, let's print them */
+	for (; n != 0; n--) {
+		size_t	start;
+
+		start = i;
+
+		/* Search until we find the end of the line or we reach the
+		 * end of data. */
+		while (i != newest && conslog->buf[BUF_IDX(conslog, i)] != '\n')
+			i++;
+
+		/* If we stopped because i equaled newest, we need to increment
+		 * once more to get the correct end. */
+		if (i == newest)
+			i++;
+
+		report(conslog->buf + BUF_IDX(conslog, start), i - start);
+		i++;			/* Skip the newline */
+	}
+}
+
diff --git a/include/linux/conslogger.h b/include/linux/conslogger.h
new file mode 100644
index 0000000..77bcb90
--- /dev/null
+++ b/include/linux/conslogger.h
@@ -0,0 +1,52 @@
+/*
+ *				conslog.h
+ *
+ * Definitions for using the console diverter
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:       David VomLehn
+ */
+
+#ifndef _INCLUDE_LINUX_CONSLOG_H_
+#define _INCLUDE_LINUX_CONSLOG_H_
+#include <linux/console.h>
+#include <linux/err.h>
+
+enum conslog_state {
+	CONSLOG_DISABLE, CONSLOG_RECORD, CONSLOG_DIVERT
+};
+
+struct conslog {
+	enum conslog_state state;
+	char		*buf;
+	unsigned	idx;
+	bool		wrapped;
+	size_t		mask;
+	size_t		size;
+	void		(*divert)(const char *p, size_t n);
+	struct console	console;
+};
+
+extern struct conslog *conslog_register(unsigned order);
+extern int conslog_unregister(struct conslog *conslog);
+extern void conslog_record(struct conslog *conslog, bool record);
+extern void conslog_divert(struct conslog *conslog,
+	void (*divert)(const char *p, size_t n));
+extern void conslog_last(struct conslog *conslog, unsigned nlines,
+	void (*report)(const char *p, unsigned cnt));
+#endif

^ permalink raw reply related

* Re: AT91SAM9G20 design and boot times
From: Robin Getz @ 2009-06-11 13:58 UTC (permalink / raw)
  To: Nicolas Ferre; +Cc: Aras Vaichas, linux-embedded
In-Reply-To: <4A30FD17.7060508@atmel.com>

On Thu 11 Jun 2009 08:48, Nicolas Ferre pondered:
> Aras Vaichas :
> > * what is your boot time? What is the time from power-on to kernel
> > running, how long does the kernel take to run until init starts, and
> > how long does init take?

[snip]

> That said, here are numbers from our not optimized demo
> (AT91Bootstrap+u-boot+linux+buildroot):
> - ~6s to Linux (can certainly be optimized)
> - ~+2s to init
> - ~+5s to login (here also)

Holy long boot times batman.

For a sub 1 second (973ms) boot (to userspace - end of the /etc/rc file), have 
a look at:

https://docs.blackfin.uclinux.org/doku.php?id=fast_boot_example

It also includes a 421ms for a minimal kernel.

No magic - just careful optimisation of the BootROM, U-Boot, and the kernel.

Some of the tricks we do are architecture independent, and should be able to 
be applied to any system. Your milage may vary - depending on your 
distribution, and your architecture.

-Robin

^ permalink raw reply

* Re: AT91SAM9G20 design and boot times
From: Nicolas Ferre @ 2009-06-11 12:48 UTC (permalink / raw)
  To: Aras Vaichas; +Cc: linux-embedded
In-Reply-To: <ed62800906102043m723911d8t1968174201ba7fbb@mail.gmail.com>

Hi,

Aras Vaichas :
> Hi,
> 
> we're designing our next generation RFID reader and I'm planning on
> using the AT91SAM9G20 in the next design. We currently use the
> AT91RM9200.

Good choice ;-)

> Can I get some feedback from people with regards to general design
> configurations  that affect the boot time with respect to this CPU (or
> the AT91SAM9260)

I presume that you already know what are the configurations we are using
at Linux4sam.org on our at91sam9g20ek board. Anyway, I answer your
questions as it may also interest other readers.

> Some questions are:
> 
> * what is your boot time? What is the time from power-on to kernel
> running, how long does the kernel take to run until init starts, and
> how long does init take?

We have not tried to be clever on speeding up boot process but I guess
that we can save time:
- removing unneeded bootloader steps (remove u-boot for instance)
- removing unused drivers
- lower timeouts (Ethernet phy detection for example)
- tailor rootfs exactly to your needs

That said, here are numbers from our not optimized demo
(AT91Bootstrap+u-boot+linux+buildroot):
- ~6s to Linux (can certainly be optimized)
- ~+2s to init
- ~+5s to login (here also)

> * what is your system hardware configuration? CPU+NAND, CPU+NOR+NAND,
> CPU+DATAFLASH+NAND?

CPU + NAND can lower your BOM

> * do you boot everything from the NAND or do you use a combination of
> Dataflash/NOR and NAND?

Both.

> * do you use U-Boot, or a minimal custom bootloader that copies a
> kernel image from NAND to SDRAM and then executes it?

If boot time is a hot topic, choose AT91Bootstrap that directly loads Linux.

> * do you mount a small partition of the NAND to begin with and then
> mount the rest later?

With JFFS2, I advice you to tailor your NAND partition for rootfs to the
minimum. You will then have room in another partition once your system
is up-n-running.

> * do you have a monolithic kernel, or is it split into minimal with
> modules loaded from, say, JFFS2 on NAND?

Monolithic kernel.

> * are you using JFFS2 or UBIFS?

JFFS2 for the moment. We will certainly consider moving to UBIFS.

Bye,
-- 
Nicolas Ferre

^ permalink raw reply

* AT91SAM9G20 design and boot times
From: Aras Vaichas @ 2009-06-11  3:43 UTC (permalink / raw)
  To: linux-embedded
In-Reply-To: <ed62800906102037q71f2a6bdq835793a1ac36c41b@mail.gmail.com>

Hi,

we're designing our next generation RFID reader and I'm planning on
using the AT91SAM9G20 in the next design. We currently use the
AT91RM9200.

Can I get some feedback from people with regards to general design
configurations  that affect the boot time with respect to this CPU (or
the AT91SAM9260)

Some questions are:

* what is your boot time? What is the time from power-on to kernel
running, how long does the kernel take to run until init starts, and
how long does init take?
* what is your system hardware configuration? CPU+NAND, CPU+NOR+NAND,
CPU+DATAFLASH+NAND?
* do you boot everything from the NAND or do you use a combination of
Dataflash/NOR and NAND?
* do you use U-Boot, or a minimal custom bootloader that copies a
kernel image from NAND to SDRAM and then executes it?
* do you mount a small partition of the NAND to begin with and then
mount the rest later?
* do you have a monolithic kernel, or is it split into minimal with
modules loaded from, say, JFFS2 on NAND?
* are you using JFFS2 or UBIFS?

Any info is much appreciated, thank you!

regards,

Aras Vaichas

^ permalink raw reply

* Kernel crashing and log buffers...
From: Robin Getz @ 2009-06-11  1:26 UTC (permalink / raw)
  To: Mike Frysinger, Greg Ungerer, Russell King, Paul Mundt, Tim Bird,
	Wolfgan
  Cc: linux-embedded

On 17 Oct 2007, after much discussion and debate, Mike added add two new 
functions for reading the kernel log buffer (from kernel space).

http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=0b15d04af3dd996035d8fa81fc849d049171f9c3

The intention was for them to be used by recovery/dump/debug code so the 
kernel log can be easily retrieved/parsed by the bootloader (or another 
kernel) in a crash scenario.

I was going to push the arch specific recovery/dump/debug code that uses them 
upstream (yeah, it has been a little while - but anyway...) it was removed 
since then by Roel Kluin ...

21 Oct 2008:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=acff181d3574244e651913df77332e897b88bff4

Before I ask Andrew to add it back, I thought I would make sure it was still a 
useful function, and did everything everyone wanted - and wasn't deemed 
unnecessary by a feature/function that I wasn't aware of - like the next 
thing...

I saw the patch Grant sent recently - Add Alternative Log Buffer Support for 
printk Messages (in Nov2008 to the embedded list, and Jan 2009 to lkml) - but 
I couldn't find any followups - and it doesn't seem to be in Linus's tree.

http://thread.gmane.org/gmane.linux.kernel.embedded/1358/focus=1373

http://lkml.org/lkml/2009/1/21/250

I can see the desire on Wolfgang & Grant's part - for not needing the copy 
from/to - (you never have to worry about crashing "nicely" - the kernel 
panics, but you still need to copy memory around - potentially causing all 
kinds of secondary issues - and masking the real reason the crash occurred).

But for the majority of the case - the copy from/to would work much better 
than what we have in mainstream today...


I would be interested in Paul and Russell - how have you solved this issue? 
(Or do your kernel's never crash? :)

Thanks
-Robin

^ permalink raw reply

* Re: Representing Embedded Architectures at the Kernel Summit
From: Kumar Gala @ 2009-06-10 23:13 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD
  Cc: Josh Boyer, James Bottomley, ksummit-2009-discuss, linux-arch,
	linux-embedded
In-Reply-To: <20090602222132.GK6399@game.jcrosoft.org>


On Jun 2, 2009, at 5:21 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:

> I'd like to propose AMP and kernel relocate
> as more and SoC will came with multiple core with or without the  
> same arch

I think AMP or at least the idea of the kernel communicating with  
other OSes on the same SoC in multi-core systems is interesting.

- k

^ permalink raw reply

* Re: Representing Embedded Architectures at the Kernel Summit
From: Kumar Gala @ 2009-06-10 23:08 UTC (permalink / raw)
  To: Josh Boyer
  Cc: James Bottomley, ksummit-2009-discuss, linux-arch, linux-embedded
In-Reply-To: <20090602172941.GL3095@hansolo.jdub.homelinux.org>


On Jun 2, 2009, at 12:29 PM, Josh Boyer wrote:

> Which leads me to suggest that it is at least worth having someone  
> with an
> embedded focus at KS to simply keep an eye out for impacts of  
> generic changes.
> "Feature parity" is something I often deal with in trying to keep  
> ppc4xx up to
> speed with the rest of the archs in the kernel.

I think this is an interesting topic by itself.  How to keep embedded  
(or non-x86) arch's up with features being developed that are core  
kernel.  For example, I know Roland would use 4xx to test his  
infiniband since it was non-coherent system.

- k

^ permalink raw reply

* Re: [Ksummit-2009-discuss] Representing Embedded Architectures at the Kernel Summit
From: Thomas Petazzoni @ 2009-06-10  9:42 UTC (permalink / raw)
  To: James Bottomley
  Cc: Catalin Marinas, ksummit-2009-discuss, linux-arch, linux-embedded
In-Reply-To: <1244045997.21423.303.camel@mulgrave.site>

Le Wed, 03 Jun 2009 12:19:57 -0400,
James Bottomley <James.Bottomley@HansenPartnership.com> a écrit :

> So ZONE_DMA and coherent memory allocation as represented by the
> coherent mask are really totally separate things.  The idea of
> ZONE_DMA was really that if you had an ISA device, allocations from
> ZONE_DMA would be able to access the allocated memory without
> bouncing.  Since ISA is really going away, this definition has been
> hijacked.  If your problem is just that you need memory allocated on
> a certain physical mask and neither GFP_DMA or GFP_DMA32 cut it for
> you, then we could revisit the kmalloc_mask() proposal again ... but
> the consensus last time was that no-one really had a compelling use
> case that couldn't be covered by GFP_DMA32.

Back a few years ago, I was working on a MIPS platform which had 256 MB
of RAM attached to the CPU memory controller and 128 MB attached to an
external memory controller. The layout of the memories was: 256 MB
CPU-attached memory first, and then the 128 MB
external-controller-attached memory.

Now, back to the DMA discussion: the Ethernet controller, which was
part of that external controller also driving the 128 MB bank of
memory, could only DMA to and from memory controlled by that same
controller (i.e only to the *top* 128 MB of the physical address
space). I'm by far not an mm expert, but as far as I could understand
the zone mechanism, it was not possible to describe such a
physical memory configuration where DMA-able memory is only at the top.

In the end, I ended up passing mem=..., managing manually a few
megabytes of memory at the top of the physical address space, and
hacking the Ethernet driver to copy back and forth the skb contents
between the main memory and the DMA-reserved memory.

So when Calatalin Marinas says « currently ZONE_DMA is assumed to be in
the bottom part of the memory which isn't always the case », I cannot
agree more.

Reference:
http://www.linux-mips.org/archives/linux-mips/2004-09/msg00152.html

Sincerly,

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers and embedded Linux development,
consulting, training and support.
http://free-electrons.com

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox