diff options
Diffstat (limited to 'drivers/net/netconsole.c')
| -rw-r--r-- | drivers/net/netconsole.c | 18 | 
1 files changed, 11 insertions, 7 deletions
| diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index adeee615dd19..c9a15925a1f7 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -310,6 +310,7 @@ static ssize_t store_enabled(struct netconsole_target *nt,  			     const char *buf,  			     size_t count)  { +	unsigned long flags;  	int enabled;  	int err; @@ -324,9 +325,7 @@ static ssize_t store_enabled(struct netconsole_target *nt,  		return -EINVAL;  	} -	mutex_lock(&nt->mutex);  	if (enabled) {	/* 1 */ -  		/*  		 * Skip netpoll_parse_options() -- all the attributes are  		 * already configured via configfs. Just print them out. @@ -334,19 +333,22 @@ static ssize_t store_enabled(struct netconsole_target *nt,  		netpoll_print_options(&nt->np);  		err = netpoll_setup(&nt->np); -		if (err) { -			mutex_unlock(&nt->mutex); +		if (err)  			return err; -		}  		printk(KERN_INFO "netconsole: network logging started\n"); -  	} else {	/* 0 */ +		/* We need to disable the netconsole before cleaning it up +		 * otherwise we might end up in write_msg() with +		 * nt->np.dev == NULL and nt->enabled == 1 +		 */ +		spin_lock_irqsave(&target_list_lock, flags); +		nt->enabled = 0; +		spin_unlock_irqrestore(&target_list_lock, flags);  		netpoll_cleanup(&nt->np);  	}  	nt->enabled = enabled; -	mutex_unlock(&nt->mutex);  	return strnlen(buf, count);  } @@ -563,8 +565,10 @@ static ssize_t netconsole_target_attr_store(struct config_item *item,  	struct netconsole_target_attr *na =  		container_of(attr, struct netconsole_target_attr, attr); +	mutex_lock(&nt->mutex);  	if (na->store)  		ret = na->store(nt, buf, count); +	mutex_unlock(&nt->mutex);  	return ret;  } |