--- ul-20021218/mm/page_alloc.c.~1~	2002-12-19 00:10:02.000000000 +0100
+++ ul-20021218/mm/page_alloc.c	2002-12-20 10:01:54.000000000 +0100
@@ -57,6 +57,33 @@ int vm_gfp_debug = 0;
 	|| ((zone) != page_zone(page))					\
 )
 
+static void FASTCALL(__free_pages_ok (struct page *page, unsigned int order));
+
+static spinlock_t free_pages_ok_no_irq_lock = SPIN_LOCK_UNLOCKED;
+struct page * free_pages_ok_no_irq_head;
+
+static void do_free_pages_ok_no_irq(void * arg)
+{
+	struct page * page, * __page;
+
+	spin_lock_irq(&free_pages_ok_no_irq_lock);
+
+	page = free_pages_ok_no_irq_head;
+	free_pages_ok_no_irq_head = NULL;
+
+	spin_unlock_irq(&free_pages_ok_no_irq_lock);
+
+	while (page) {
+		__page = page;
+		page = page->next_hash;
+		__free_pages_ok(__page, __page->index);
+	}
+}
+
+static struct tq_struct free_pages_ok_no_irq_task = {
+	.routine	= do_free_pages_ok_no_irq,
+};
+
 /*
  * Freeing function for a buddy system allocator.
  *
@@ -80,7 +107,6 @@ int vm_gfp_debug = 0;
  * -- wli
  */
 
-static void FASTCALL(__free_pages_ok (struct page *page, unsigned int order));
 static void __free_pages_ok (struct page *page, unsigned int order)
 {
 	unsigned long index, page_idx, mask, flags;
@@ -92,8 +118,20 @@ static void __free_pages_ok (struct page
 	 * a reference to a page in order to pin it for io. -ben
 	 */
 	if (PageLRU(page)) {
-		if (unlikely(in_interrupt()))
-			BUG();
+		if (unlikely(in_interrupt())) {
+			unsigned long flags;
+
+			spin_lock_irqsave(&free_pages_ok_no_irq_lock, flags);
+
+			page->next_hash = free_pages_ok_no_irq_head;
+			free_pages_ok_no_irq_head = page;
+			page->index = order;
+
+			spin_unlock_irqrestore(&free_pages_ok_no_irq_lock, flags);
+
+			schedule_task(&free_pages_ok_no_irq_task);
+			return;
+		}
 		lru_cache_del(page);
 	}