summaryrefslogtreecommitdiff
path: root/drivers/net/netconsole.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/netconsole.c')
-rw-r--r--drivers/net/netconsole.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index a8ef4c4b94be..ba2f5e710af1 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -312,6 +312,7 @@ static ssize_t store_enabled(struct netconsole_target *nt,
const char *buf,
size_t count)
{
+ unsigned long flags;
int enabled;
int err;
@@ -326,9 +327,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.
@@ -336,19 +335,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;
- }
-
- pr_info("network logging started\n");
+ pr_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);
}
@@ -559,8 +561,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;
}