Re: Oops after register_netdev() failure in 2.6.3-bk5

From: Pavel Roskin
Date: Tue Feb 24 2004 - 16:37:27 EST


On Tue, 24 Feb 2004 viro@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx wrote:

> I have an even better model for you:
>
> dev = alloc_netdev(<whatever>);
> netif_carrier_off(dev);
> free_netdev(dev);
>
> That leaves a scheduled work (by linkwatch_fire_event()) with pointer to
> freed dev.
>
> *NOTE*: dev_hold() provides protection only to devices that had been
> registered. So netif_carrier_off() is safe for those (dev_hold() will
> hold unregister_netdev() from from finishing and since the caller of
> unregister_netdev() is still holding a reference, device won't go away).

I'm impressed by your quick analysis. Thank you!

> IOW, Don't Do It, Then. netif_carrier_off() is not safe for devices
> that are not registered.

I won't do it for now. In the long term, I believe it's a legitimate
approach to register a network device with carrier off and set it to on
only if the carrier has been detected by the hardware.

Maybe linkwatch_fire_event() should do nothing in certain situations?
Following patch fixes the crash. I didn't put much thought into the
patch, perhaps it could be improved.

==================================
--- net/core/link_watch.c
+++ net/core/link_watch.c
@@ -102,6 +102,9 @@ static void linkwatch_event(void *dummy)

void linkwatch_fire_event(struct net_device *dev)
{
+ if (dev->reg_state == NETREG_UNINITIALIZED)
+ return;
+
if (!test_and_set_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state)) {
unsigned long flags;
struct lw_event *event;
==================================

--
Regards,
Pavel Roskin
-
To unsubscribe from this list: send the line "unsubscribe linux-net" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html