Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755943AbYCQXao (ORCPT ); Mon, 17 Mar 2008 19:30:44 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1752180AbYCQXah (ORCPT ); Mon, 17 Mar 2008 19:30:37 -0400 Received: from sovereign.computergmbh.de ([85.214.69.204]:53942 "EHLO sovereign.computergmbh.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752590AbYCQXah (ORCPT ); Mon, 17 Mar 2008 19:30:37 -0400 Date: Tue, 18 Mar 2008 00:30:35 +0100 (CET) From: Jan Engelhardt To: Linux Kernel Mailing List Subject: vfree with spin_lock_bh Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=UTF-8 Content-Transfer-Encoding: 8BIT Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1603 Lines: 56 Hi, while transforming some code with big allocations (like 120 KB) from kmalloc to vmalloc — virtual contiguity is sufficient — I hit a BUG_ON in mm/vmalloc.c a number of times: void vfree(const void *addr) { BUG_ON(in_interrupt()); __vunmap(addr, 1); } First I was thinking “how could iptables -F run in interrupt context?”, but apparently, it does seem to make a difference: ... spin_lock_bh(&a_local_spinlock); list_del_rcu(&node->list); printk(KERN_INFO "Interrupt? %lu\n", in_interrupt()); /* vfree not worky here */ spin_unlock_bh(&a_local_spinlock); printk(KERN_INFO "Interrupt? %lu\n", in_interrupt()); /* now possible */ vfree(node); ... and this gives (x86_32) Interrupt? 256 Interrupt? 0 So this may be a "property" of spinlocks, but it is a bit strange to me. Why should not I be able to call vfree() when I am, in fact, in user context (but with a bh spinlock held...). Do I perhaps need a non-bh spinlock? There's RCU going on on that linked list so I am not sure whether I could just call the normal spin_lock() function. Looking at the code of _spin_lock_bh in kernel/spinlock.c reveals that it is actually disabling preempt instead of being in an interrupt. Making an uneducated guess, would BUG_ON(in_interrupt() != 0 && in_interrupt() != 256) in vfree() be safe? thanks, Jan -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/