From: Johannes Weiner <hannes@saeurebad.de>
To: Jan Engelhardt <jengelh@computergmbh.de>
Cc: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: vfree with spin_lock_bh
Date: Tue, 18 Mar 2008 12:21:39 +0100 [thread overview]
Message-ID: <87wso0wa4c.fsf@saeurebad.de> (raw)
In-Reply-To: <Pine.LNX.4.64.0803180019470.18817@fbirervta.pbzchgretzou.qr> (Jan Engelhardt's message of "Tue, 18 Mar 2008 00:30:35 +0100 (CET)")
Hi Jan,
Jan Engelhardt <jengelh@computergmbh.de> writes:
> 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...).
in_interrupt() checks for both, hard- and softirqs. Since
spin_lock_bh() disables softirq's you have to be as fast as possible to
avoid softirq latency.
> 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.
Perhaps a call_rcu() which vfree()s the node? But I am just guessing
wildly here.
> 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)
That's basically a lacky in_irq(). The 256 you see here is
1<<SOFTIRQ_SHIFT but softirq disabling can be nested and you can not
check for 256 directly.
> in vfree() be safe?
Can not judge that.
Hannes
prev parent reply other threads:[~2008-03-18 11:24 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-03-17 23:30 vfree with spin_lock_bh Jan Engelhardt
2008-03-18 11:21 ` Johannes Weiner [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87wso0wa4c.fsf@saeurebad.de \
--to=hannes@saeurebad.de \
--cc=jengelh@computergmbh.de \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox