diff -ur kernel-2.4.3/linux/arch/i386/kernel/irq.c kernel-2.4.3-works/linux/arch/i386/kernel/irq.c --- kernel-2.4.3/linux/arch/i386/kernel/irq.c Thu May 10 16:04:39 2001 +++ kernel-2.4.3-works/linux/arch/i386/kernel/irq.c Thu May 10 12:16:21 2001 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -576,7 +577,10 @@ irq_desc_t *desc = irq_desc + irq; struct irqaction * action; unsigned int status; + struct page_reservation *saved_irq_rsv; + saved_irq_rsv = current->page_reservations; + current->page_reservations = &irq_rsv; kstat.irqs[cpu][irq]++; spin_lock(&desc->lock); desc->handler->ack(irq); @@ -638,6 +642,7 @@ if (softirq_active(cpu) & softirq_mask(cpu)) do_softirq(); + current->page_reservations = saved_irq_rsv; return 1; } diff -ur kernel-2.4.3/linux/include/linux/mm/reservation.h kernel-2.4.3-works/linux/include/linux/mm/reservation.h --- kernel-2.4.3/linux/include/linux/mm/reservation.h Thu May 10 16:04:40 2001 +++ kernel-2.4.3-works/linux/include/linux/mm/reservation.h Thu May 10 12:16:21 2001 @@ -32,6 +32,8 @@ zone_t *zone; }; +extern struct page_reservation irq_rsv; + extern void init_page_reservation(struct page_reservation *rsv, int flags, int zone); extern void destroy_page_reservation(struct page_reservation *rsv); diff -ur kernel-2.4.3/linux/init/main.c kernel-2.4.3-works/linux/init/main.c --- kernel-2.4.3/linux/init/main.c Thu May 10 16:04:39 2001 +++ kernel-2.4.3-works/linux/init/main.c Thu May 10 12:16:21 2001 @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -655,6 +656,8 @@ #endif mempages = num_physpages; + if (reserve_pages(&irq_rsv, GFP_KERNEL, mempages >> 8)) + panic("unable to reserve memory.\n"); fork_init(mempages); proc_caches_init(); vfs_caches_init(mempages); diff -ur kernel-2.4.3/linux/mm/page_alloc.c kernel-2.4.3-works/linux/mm/page_alloc.c --- kernel-2.4.3/linux/mm/page_alloc.c Thu May 10 16:04:40 2001 +++ kernel-2.4.3-works/linux/mm/page_alloc.c Thu May 10 14:59:04 2001 @@ -20,6 +20,7 @@ #include #include +struct page_reservation irq_rsv; int nr_swap_pages; int nr_active_pages; int nr_inactive_dirty_pages; @@ -303,6 +304,8 @@ * We allocate if the number of free + inactive_clean * pages is above the watermark. */ + free_pages = z->free_pages - z->reserved_pages; + switch (limit) { default: case PAGES_MIN: @@ -312,7 +315,8 @@ water_mark = z->pages_low; rsv = current->page_reservations; if ((rsv->zone == z) && rsv->avail) { - water_mark += rsv->avail; +static int foo; if (foo++ < 5) printk("hit page reservation: %p\n", rsv); + free_pages += rsv->avail; } else rsv = NULL; break; @@ -323,8 +327,6 @@ water_mark = z->pages_high; } - free_pages = z->free_pages - z->reserved_pages; - if (free_pages + z->inactive_clean_pages > water_mark) { struct page *page = NULL; /* If possible, reclaim a page directly. */ @@ -467,7 +469,8 @@ * TODO: with memory reservations in place, much of the code * below is completely bogus. Clean this up! -ben */ - if (!order && current->page_reservations && !in_interrupt()) { + if (!order && current->page_reservations) { +static int foo; if (foo++ < 5) printk("trying reservation: %p\n", current->page_reservations); page = __alloc_pages_limit(zonelist, order, PAGES_RSV, direct_reclaim); if (page) goto out_success; @@ -1013,6 +1016,8 @@ } } build_zonelists(pgdat); + + init_page_reservation(&irq_rsv, RSV_MULTISHOT, ZONE_NORMAL); } void __init free_area_init(unsigned long *zones_size)