From 8423e6b212a19d5f02232855dec73196297b5ee9 Mon Sep 17 00:00:00 2001 From: Karsten Keil Date: Fri, 4 May 2012 04:15:32 +0000 Subject: mISDN: L2 timeouts need to be queued as L2 event To be full preemptiv safe, we cannot handle a L2 timeout in the timer context itself, we should do all actions via the D-channel thread. Signed-off-by: Karsten Keil Signed-off-by: David S. Miller --- drivers/isdn/mISDN/tei.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers/isdn/mISDN/tei.c') diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c index 109276a0d1a0..be88728f1106 100644 --- a/drivers/isdn/mISDN/tei.c +++ b/drivers/isdn/mISDN/tei.c @@ -1294,7 +1294,7 @@ static int mgr_bcast(struct mISDNchannel *ch, struct sk_buff *skb) { struct manager *mgr = container_of(ch, struct manager, bcast); - struct mISDNhead *hh = mISDN_HEAD_P(skb); + struct mISDNhead *hhc, *hh = mISDN_HEAD_P(skb); struct sk_buff *cskb = NULL; struct layer2 *l2; u_long flags; @@ -1309,10 +1309,17 @@ mgr_bcast(struct mISDNchannel *ch, struct sk_buff *skb) skb = NULL; } else { if (!cskb) - cskb = skb_copy(skb, GFP_KERNEL); + cskb = skb_copy(skb, GFP_ATOMIC); } if (cskb) { - ret = l2->ch.send(&l2->ch, cskb); + hhc = mISDN_HEAD_P(cskb); + /* save original header behind normal header */ + hhc++; + *hhc = *hh; + hhc--; + hhc->prim = DL_INTERN_MSG; + hhc->id = l2->ch.nr; + ret = ch->st->own.recv(&ch->st->own, cskb); if (ret) { if (*debug & DEBUG_SEND_ERR) printk(KERN_DEBUG -- cgit v1.2.3