diff options
Diffstat (limited to 'drivers/net/netconsole.c')
-rw-r--r-- | drivers/net/netconsole.c | 20 |
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, | |||
312 | const char *buf, | 312 | const char *buf, |
313 | size_t count) | 313 | size_t count) |
314 | { | 314 | { |
315 | unsigned long flags; | ||
315 | int enabled; | 316 | int enabled; |
316 | int err; | 317 | int err; |
317 | 318 | ||
@@ -326,9 +327,7 @@ static ssize_t store_enabled(struct netconsole_target *nt, | |||
326 | return -EINVAL; | 327 | return -EINVAL; |
327 | } | 328 | } |
328 | 329 | ||
329 | mutex_lock(&nt->mutex); | ||
330 | if (enabled) { /* 1 */ | 330 | if (enabled) { /* 1 */ |
331 | |||
332 | /* | 331 | /* |
333 | * Skip netpoll_parse_options() -- all the attributes are | 332 | * Skip netpoll_parse_options() -- all the attributes are |
334 | * already configured via configfs. Just print them out. | 333 | * already configured via configfs. Just print them out. |
@@ -336,19 +335,22 @@ static ssize_t store_enabled(struct netconsole_target *nt, | |||
336 | netpoll_print_options(&nt->np); | 335 | netpoll_print_options(&nt->np); |
337 | 336 | ||
338 | err = netpoll_setup(&nt->np); | 337 | err = netpoll_setup(&nt->np); |
339 | if (err) { | 338 | if (err) |
340 | mutex_unlock(&nt->mutex); | ||
341 | return err; | 339 | return err; |
342 | } | ||
343 | |||
344 | pr_info("network logging started\n"); | ||
345 | 340 | ||
341 | pr_info("netconsole: network logging started\n"); | ||
346 | } else { /* 0 */ | 342 | } else { /* 0 */ |
343 | /* We need to disable the netconsole before cleaning it up | ||
344 | * otherwise we might end up in write_msg() with | ||
345 | * nt->np.dev == NULL and nt->enabled == 1 | ||
346 | */ | ||
347 | spin_lock_irqsave(&target_list_lock, flags); | ||
348 | nt->enabled = 0; | ||
349 | spin_unlock_irqrestore(&target_list_lock, flags); | ||
347 | netpoll_cleanup(&nt->np); | 350 | netpoll_cleanup(&nt->np); |
348 | } | 351 | } |
349 | 352 | ||
350 | nt->enabled = enabled; | 353 | nt->enabled = enabled; |
351 | mutex_unlock(&nt->mutex); | ||
352 | 354 | ||
353 | return strnlen(buf, count); | 355 | return strnlen(buf, count); |
354 | } | 356 | } |
@@ -559,8 +561,10 @@ static ssize_t netconsole_target_attr_store(struct config_item *item, | |||
559 | struct netconsole_target_attr *na = | 561 | struct netconsole_target_attr *na = |
560 | container_of(attr, struct netconsole_target_attr, attr); | 562 | container_of(attr, struct netconsole_target_attr, attr); |
561 | 563 | ||
564 | mutex_lock(&nt->mutex); | ||
562 | if (na->store) | 565 | if (na->store) |
563 | ret = na->store(nt, buf, count); | 566 | ret = na->store(nt, buf, count); |
567 | mutex_unlock(&nt->mutex); | ||
564 | 568 | ||
565 | return ret; | 569 | return ret; |
566 | } | 570 | } |