On Mon, May 12, 2003 at 01:58:21PM +0200, Sven Niese wrote:
Hallo,
gibt es mittlerweile eine Lösung für das Problem? Der Thread dazu begann am 27.03. Bei mir tritt selbiges auch auf, 'sleep 5' verhindert zwar, dass das System hängt, nach jedem Verbindungsabbau muss ich aber den ipppd neustarten (siehe auch die Mail von Tim Fischer, 16.04.2003 19:08). Ich nutze übrigens auch T-Online!?
System: Pentium 150, 32 MB RAM Elsa ML PCF-Pro k_deflt-2.4.19-174 i4l-base-2003.2.14-1 i4l-isdnlog-2002.11.5-0
OK, es gibt einen workaround (sleep zwischen auflegen und interface abbauen), der aber scheinbar manchmal andere Probleme triggert (ipppd laeuft weiter). Der endgültige Fix ist nur im kernel möglich, der Patch ist hier: diff -ur linux-2.4.20.SuSE.org/net/core/dev.c linux-2.4.20.SuSE/net/core/dev.c --- linux-2.4.20.SuSE.org/net/core/dev.c 2003-03-17 16:51:15.000000000 +0100 +++ linux-2.4.20.SuSE/net/core/dev.c 2003-04-29 19:00:22.000000000 +0200 @@ -620,16 +620,61 @@ struct dev_tq { struct tq_struct tq; + struct timer_list timer; struct net_device *dev; int event; -}; +}; + +static char *NetEvtStr[16] = { + "0000", + "up", + "down", + "reboot", + "change", + "register", + "unregister", + "change mtu", + "change addr", + "going down", + "change name", + "000B", + "000C", + "000D", + "000E", + "000F" +}; + +static void netdev_event_timer_callback(unsigned long data) +{ + struct dev_tq *tq = (struct dev_tq *) data; + + if (schedule_task(&tq->tq) == 0) { + printk(KERN_WARNING "%s: task for event %s scheduled with delay\n", + __FUNCTION__, NetEvtStr[0xf & tq->event]); + tq->timer.expires = jiffies + 1; + add_timer(&tq->timer); + } +} static void netdev_event_callback(void *data) { - struct dev_tq *tq = (struct dev_tq *) data; - rtnl_shlock(); - notifier_call_chain(&netdev_chain, tq->event, tq->dev); - rtnl_shunlock(); + struct dev_tq *tq = (struct dev_tq *) data; + + if (0 == rtnl_shlock_nowait()) { + notifier_call_chain(&netdev_chain, tq->event, tq->dev); + rtnl_shunlock(); + } else { + if (tq->dev->deadbeaf) { + printk(KERN_WARNING "%s: task for event %s canceled for device shutdown\n", + __FUNCTION__, NetEvtStr[0xf & tq->event]); + } else { + tq->timer.function = netdev_event_timer_callback; + tq->timer.data = (unsigned long)tq; + tq->timer.expires = jiffies + 1; + add_timer(&tq->timer); + return; + } + } dev_put(tq->dev); kfree(tq); } @@ -656,9 +701,12 @@ tq->tq.routine = netdev_event_callback; tq->tq.data = tq; if (schedule_task(&tq->tq) == 0) { - printk(KERN_WARNING __FUNCTION__ - ": task for event %x not scheduled\n", event); - dev_put(dev); + printk(KERN_WARNING "%s: task for event %s scheduled with delay\n", + __FUNCTION__, NetEvtStr[0xf & tq->event]); + tq->timer.function = netdev_event_timer_callback; + tq->timer.data = (unsigned long)tq; + tq->timer.expires = jiffies + 1; + add_timer(&tq->timer); } } -- Karsten Keil SuSE Labs ISDN development