2007-02-07 13:41:06

by Martyn Welch

[permalink] [raw]
Subject: alloc_bootmem - Kernel panic

Hi Everyone,

First I'd like to appologise if my query is glaringly obvious. I'm
reasonable new to this, but every that I have read (including the Linux
Device Drivers book) seems to suggest that what I am doing should
work...

I am attempting to allocate a large buffer for DMA transfers in a driver
I am working on. I understand that the kernel normally will not allocate
block of coherent memory larger than 128KB, the suggested solution seems
to be to compile the driver into the kernel and allocate memory at boot
using alloc_bootmem. When attempting this I receive a kernel panic:

=========================================

Loading driver.
bootmem alloc of 4096 bytes failed!
Kernel panic - not syncing: Out of memory

=========================================
This is using:

kernel version 2.6.20
gcc version 4.1.1 20070105 (Red Hat 4.1.1-51)

The config is based on the default i386 config + one extra option to
cause my driver to be compiled in.

The offending code is listed below,

Thank you for any help in advance,

Martyn

=========================================

#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/bootmem.h>

void *buffer;

static int __init universeII_init(void)
{
printk(KERN_INFO "Loading driver.\n");

buffer = alloc_bootmem(PAGE_SIZE);

return 0;

}


static void __exit universeII_exit(void)
{
if (buffer != NULL) {
free_bootmem((unsigned long)buffer, PAGE_SIZE);
}
printk(KERN_INFO "Driver removed.\n");
}


MODULE_DESCRIPTION("alloc_bootmem_x Test");
MODULE_AUTHOR("Martyn Welch <[email protected]>");
MODULE_LICENSE("GPL");

/** Register initilisation function */
module_init(universeII_init);
/** Register cleanup function */
module_exit(universeII_exit);


________________________________________________________________________
This e-mail has been scanned for all viruses by Star.The service is powered by MessageLabs.
________________________________________________________________________


2007-02-07 16:47:23

by Martyn Welch

[permalink] [raw]
Subject: RE: alloc_bootmem - Kernel panic

Hi Asgard,

Thank you for your reply.

> I don't sure, that linux performs to allocate bootmem after kernel already booted.
> As I know, bootmem allocator "destroyed" when kernel initializes buddy allocator.
> Indeed you can look at arch/i385/mm/init.c, mem_init routine.
> kernel passes all bootmem pages to buddy system, so bootmem allocator can't be used after it.

That explains why I can't use alloc_bootmem. It'd assumed that do_initcalls and hence functions labelled with module_init() were called early enough, mainly because LDD3 suggests using alloc_bootmem. It seems the vt driver uses console_init() instead, which is called much earlier.

Which leads me to the question: what is the best method to reserve a large (~4MB) coherent buffer for DMA transfers?

Is there any way of using alloc_bootmem from a driver (compiled into the kernel) without delving further into kernel code?

Martyn

________________________________________________________________________
This e-mail has been scanned for all viruses by Star.The service is powered by MessageLabs.
________________________________________________________________________

2007-02-07 18:24:26

by Dan Kruchinin

[permalink] [raw]
Subject: Re: alloc_bootmem - Kernel panic

On 2/7/07, Martyn Welch <[email protected]> wrote:
>
> Which leads me to the question: what is the best method to reserve a large (~4MB) coherent buffer for DMA transfers?
>

May be you should to use alloc_pages with __GFP_DMA flag, and then use
page_address to get address of first allocated page.

> Is there any way of using alloc_bootmem from a driver (compiled into the kernel) without delving further into kernel code?

yes, i think:

-> (~/devel/learn/src/kernels/linux-2.6.19)
[asgard@midgard]$ find drivers/ -name "*" | xargs grep alloc_bootmem
drivers/char/vt.c: vc_cons[currcons].d = vc =
alloc_bootmem(sizeof(struct vc_data));
drivers/char/vt.c: vc->vc_screenbuf = (unsigned short
*)alloc_bootmem(vc->vc_screenbuf_size);
Binary file drivers/char/vt.o matches
Binary file drivers/char/built-in.o matches
Binary file drivers/firmware/dmi_scan.o matches
Binary file drivers/firmware/built-in.o matches
drivers/macintosh/smu.c: smu = alloc_bootmem(sizeof(struct smu_device));
drivers/s390/char/con3215.c: req = (struct raw3215_req *)
alloc_bootmem_low(sizeof(struct raw3215_req));
drivers/s390/char/con3215.c: alloc_bootmem_low(sizeof(struct
raw3215_info));
drivers/s390/char/con3215.c: raw->buffer = (char *)
alloc_bootmem_low(RAW3215_BUFFER_SIZE);
drivers/s390/char/con3215.c: raw->inbuf = (char *)
alloc_bootmem_low(RAW3215_INBUF_SIZE);
drivers/s390/char/con3270.c: condev = (struct con3270 *)
alloc_bootmem_low(sizeof(struct con3270));
drivers/s390/char/con3270.c: condev->read = raw3270_request_alloc_bootmem(0);
drivers/s390/char/con3270.c:
raw3270_request_alloc_bootmem(CON3270_OUTPUT_BUFFER_SIZE);
drivers/s390/char/con3270.c: condev->kreset =
raw3270_request_alloc_bootmem(1);
drivers/s390/char/con3270.c: cbuf = (void *)
alloc_bootmem_low_pages(PAGE_SIZE);
drivers/s390/char/raw3270.c:raw3270_request_alloc_bootmem(size_t size)
drivers/s390/char/raw3270.c: rq = alloc_bootmem_low(sizeof(struct raw3270));
drivers/s390/char/raw3270.c: rq->buffer = alloc_bootmem_low(size);
drivers/s390/char/raw3270.c: rp = (struct raw3270 *)
alloc_bootmem_low(sizeof(struct raw3270));
drivers/s390/char/raw3270.c: ascebc = (char *) alloc_bootmem(256);
drivers/s390/char/raw3270.h:struct raw3270_request
*raw3270_request_alloc_bootmem(size_t size);
drivers/s390/char/sclp_con.c: page = alloc_bootmem_low_pages(PAGE_SIZE);
drivers/s390/char/sclp_vt220.c: page =
alloc_bootmem_low_pages(PAGE_SIZE);
drivers/serial/cpm_uart/cpm_uart_cpm2.c: mem_addr = alloc_bootmem(memsz);
drivers/video/console/vgacon.c: vgacon_scrollback =
alloc_bootmem(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE
Binary file drivers/video/console/vgacon.o matches
Binary file drivers/video/console/built-in.o matches
Binary file drivers/video/built-in.o matches
Binary file drivers/built-in.o matches

> Martyn
>
> ________________________________________________________________________
> This e-mail has been scanned for all viruses by Star.The service is powered by MessageLabs.
> ________________________________________________________________________
>