--- mm/vmalloc.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) Index: linux-2.6/mm/vmalloc.c =================================================================== --- linux-2.6.orig/mm/vmalloc.c 2007-09-15 19:59:29.000000000 -0700 +++ linux-2.6/mm/vmalloc.c 2007-09-15 20:16:25.000000000 -0700 @@ -369,11 +369,29 @@ static void __vunmap(void *addr, int dea * * Must not be called in interrupt context. */ -void vfree(void *addr) +static void vfree_work(struct work_struct *w) { - BUG_ON(in_interrupt()); + void *addr = w; + __vunmap(addr, 1); } + +void vfree(void *addr) +{ + struct work_struct *w = addr; + + if (unlikely(in_interrupt())) { + /* + * The object is unused and we have at least a page + * at addr. So we can just use the area to put a work_struct + * there in order to defer the free until a time when + * interrupts are enabled. + */ + INIT_WORK(w, vfree_work); + schedule_work(w); + } else + vfree_work(w); +} EXPORT_SYMBOL(vfree); /**