Hi,
As to your question regarding the most generic fix: if there really is not enough ST-RAM (i.e. the available space is taken by the kernel and the ramdisk, after 'unpacking' the ramdisk to the buffer cache) we'd need to either make the ramdisk unpack go to non-DMA memory (no idea here; ideally the buffer cache should not have a preference for DMA memory in this case), or reserve a chunk of memory up front (tried that in a hackish way).
Slightly less hackish implementation of that hack attached. This (on top of my max_dma_address patch before) does solve the ramdisk related atafb problems without resorting to artificial RAM limits. Stephen, please try this patch. --- arch/m68k/atari/stram.c.pool.org 2007-12-31 21:50:45.000000000 +1300 +++ arch/m68k/atari/stram.c 2008-01-02 17:51:38.000000000 +1300 @@ -30,7 +30,7 @@ #include <asm/io.h> #include <asm/semaphore.h> -#undef DEBUG +#define DEBUG #ifdef DEBUG #define DPRINTK(fmt,args...) printk( fmt, ##args ) @@ -90,11 +90,15 @@ /* values for flags field */ #define BLOCK_FREE 0x01 /* free structure in the BLOCKs pool */ #define BLOCK_KMALLOCED 0x02 /* structure allocated by kmalloc() */ +#define BLOCK_POOL 0x04 /* block allocated from static pool */ #define BLOCK_GFP 0x08 /* block allocated with __get_dma_pages() */ /* list of allocated blocks */ static BLOCK *alloc_list; +static BLOCK *stram_free_list; +static unsigned long stram_pool, stram_pool_start, stram_pool_end; + /* We can't always use kmalloc() to allocate BLOCK structures, since * stram_alloc() can be called rather early. So we need some pool of * statically allocated structures. 20 of them is more than enough, so in most @@ -155,6 +159,10 @@ if (!kernel_in_stram) reserve_bootmem (0, PAGE_SIZE); + stram_pool = (unsigned long) alloc_bootmem_low(512*1024); + stram_pool_start = stram_pool; + stram_pool_end = stram_pool + 512*1024 - 1; + DPRINTK("atari_stram pool, start=%08lx, end=%08lx\n", stram_pool, stram_pool_end); } void atari_stram_mem_init_hook (void) @@ -162,6 +170,38 @@ mem_init_done = 1; } +/* find a region (by size) in the free list */ +static void *find_free_stram( long size ) +{ + BLOCK *p,*q,*r; + unsigned long item; + + q=NULL; + r=stram_free_list; + for( p = stram_free_list; p; p = p->next ) { + if (p->size >= size) { + q=p; + break; + } + r=p; + } + + /* remove from free list - FIXME, untested! */ + if (q) { + item = (unsigned long) q->start; + r->next = q->next; + return (void *) item; + } + /* take from pool */ + if ( (stram_pool_end - stram_pool) > size) { + item = stram_pool; + stram_pool += size; + return (void *) item; + } + + return( NULL ); +} + /* * This is main public interface: somehow allocate a ST-RAM block @@ -188,11 +228,17 @@ if (!mem_init_done) return alloc_bootmem_low(size); else { + if ((addr = find_free_stram(size)) != NULL) { + flags = BLOCK_POOL; + DPRINTK( "atari_stram_alloc: after mem_init, " + "find_free_Stram=%p\n", addr ); + } else { /* After mem_init(): can only resort to __get_dma_pages() */ - addr = (void *)__get_dma_pages(GFP_KERNEL, get_order(size)); - flags = BLOCK_GFP; + addr = (void *)__get_dma_pages(GFP_KERNEL, get_order(size)); + flags = BLOCK_GFP; + DPRINTK( "atari_stram_alloc: after mem_init, " "get_pages=%p\n", addr ); + } } if (addr) { - To unsubscribe from this list: send the line "unsubscribe linux-m68k" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html