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 <linux/kernel_stat.h>
 #include <linux/irq.h>
 #include <linux/proc_fs.h>
+#include <linux/mm/reservation.h>
 
 #include <asm/atomic.h>
 #include <asm/io.h>
@@ -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 <linux/iobuf.h>
 #include <linux/bootmem.h>
 #include <linux/tty.h>
+#include <linux/mm/reservation.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -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 <linux/slab.h>
 #include <linux/mm/reservation.h>
 
+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)