aboutsummaryrefslogtreecommitdiff
path: root/drivers/isdn/mISDN
diff options
context:
space:
mode:
authorKarsten Keil <keil@b1-systems.de>2009-06-09 14:38:39 +0200
committerKarsten Keil <keil@b1-systems.de>2009-06-11 19:05:18 +0200
commit8164491dd628ffcac5d61267f747997689ee256c (patch)
tree146094cf95bb3a57708cb1f302c6cf5580c5a4ba /drivers/isdn/mISDN
parent395df11f5fa7fe852be28ccec8aaa15634386ad1 (diff)
mISDN: Do not disable IRQ in ph_data_ind()
This fix triggering the WARN_ON_ONCE(in_irq() || irqs_disabled()); in local_bh_enable(). Here is no need to grab this lock, this was wrong at all and may cause a deadlock and access to freed memory, since on a TEI remove the current listelement can be deleted under us. So this is clearly a case for list_for_each_entry_safe. Signed-off-by: Karsten Keil <keil@b1-systems.de>
Diffstat (limited to 'drivers/isdn/mISDN')
-rw-r--r--drivers/isdn/mISDN/tei.c7
1 files changed, 2 insertions, 5 deletions
diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c
index bfcdd97df95..e04bad6c5ba 100644
--- a/drivers/isdn/mISDN/tei.c
+++ b/drivers/isdn/mISDN/tei.c
@@ -862,8 +862,7 @@ static int
ph_data_ind(struct manager *mgr, struct sk_buff *skb)
{
int ret = -EINVAL;
- struct layer2 *l2;
- u_long flags;
+ struct layer2 *l2, *nl2;
u_char mt;
if (skb->len < 8) {
@@ -908,11 +907,9 @@ ph_data_ind(struct manager *mgr, struct sk_buff *skb)
new_tei_req(mgr, &skb->data[4]);
goto done;
}
- read_lock_irqsave(&mgr->lock, flags);
- list_for_each_entry(l2, &mgr->layer2, list) {
+ list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) {
tei_ph_data_ind(l2->tm, mt, &skb->data[4], skb->len - 4);
}
- read_unlock_irqrestore(&mgr->lock, flags);
done:
return ret;
}