diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 4822aafe638bf2a5b9504d803150b9e80a029318..dcb21347c67044da535903f2f88ba36f2529f347 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -102,6 +102,7 @@ struct netconsole_target { struct config_item item; #endif int enabled; + struct mutex mutex; struct netpoll np; }; @@ -181,6 +182,7 @@ static struct netconsole_target *alloc_param_target(char *target_config) strlcpy(nt->np.dev_name, "eth0", IFNAMSIZ); nt->np.local_port = 6665; nt->np.remote_port = 6666; + mutex_init(&nt->mutex); memset(nt->np.remote_mac, 0xff, ETH_ALEN); /* Parse parameters and setup netpoll */ @@ -322,6 +324,7 @@ static ssize_t store_enabled(struct netconsole_target *nt, return -EINVAL; } + mutex_lock(&nt->mutex); if (enabled) { /* 1 */ /* @@ -331,8 +334,10 @@ static ssize_t store_enabled(struct netconsole_target *nt, netpoll_print_options(&nt->np); err = netpoll_setup(&nt->np); - if (err) + if (err) { + mutex_unlock(&nt->mutex); return err; + } printk(KERN_INFO "netconsole: network logging started\n"); @@ -341,6 +346,7 @@ static ssize_t store_enabled(struct netconsole_target *nt, } nt->enabled = enabled; + mutex_unlock(&nt->mutex); return strnlen(buf, count); } @@ -597,6 +603,7 @@ static struct config_item *make_netconsole_target(struct config_group *group, strlcpy(nt->np.dev_name, "eth0", IFNAMSIZ); nt->np.local_port = 6665; nt->np.remote_port = 6666; + mutex_init(&nt->mutex); memset(nt->np.remote_mac, 0xff, ETH_ALEN); /* Initialize the config_item member */ @@ -682,7 +689,11 @@ static int netconsole_netdev_event(struct notifier_block *this, * we might sleep in __netpoll_cleanup() */ spin_unlock_irqrestore(&target_list_lock, flags); + + mutex_lock(&nt->mutex); __netpoll_cleanup(&nt->np); + mutex_unlock(&nt->mutex); + spin_lock_irqsave(&target_list_lock, flags); dev_put(nt->np.dev); nt->np.dev = NULL;