From: Tejun Heo <tj@kernel.org>
To: akpm@linux-foundation.org, davem@davemloft.net
Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
Tejun Heo <tj@kernel.org>
Subject: [PATCH 10/16] netconsole: introduce netconsole_mutex
Date: Thu, 16 Apr 2015 19:03:47 -0400 [thread overview]
Message-ID: <1429225433-11946-11-git-send-email-tj@kernel.org> (raw)
In-Reply-To: <1429225433-11946-1-git-send-email-tj@kernel.org>
console_lock protects the target_list itself and setting and clearing
of its ->enabled flag; however, nothing protects the overall
enable/disable operations which we'll need to make netconsole
management more dynamic for the scheduled reliable transmission
support. Also, an earlier patch introduced a small race window where
dynamic console disable may compete against asynchronous disable
kicked off from netdevice_notifier.
This patch adds netconsole_mutex which protects all target
create/destroy and enable/disable operations. It also replaces
netconsole_target->mutex used by dynamic consoles. The above
mentioned race is removed by this change.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: David Miller <davem@davemloft.net>
---
drivers/net/netconsole.c | 48 ++++++++++++++++++++++++++++--------------------
1 file changed, 28 insertions(+), 20 deletions(-)
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 57c02ab..f0ac9f6 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -75,10 +75,14 @@ __setup("netconsole=", option_setup);
/*
* Linked list of all configured targets. The list and each target's
- * enable/disable state are protected by console_lock.
+ * enable/disable state are protected by both netconsole_mutex and
+ * console_lock.
*/
static LIST_HEAD(target_list);
+/* protects target creation/destruction and enable/disable */
+static DEFINE_MUTEX(netconsole_mutex);
+
/**
* struct netconsole_target - Represents a configured netconsole target.
* @list: Links this target into the target_list.
@@ -106,7 +110,6 @@ struct netconsole_target {
#endif
bool enabled;
bool disable_scheduled;
- struct mutex mutex;
struct netpoll np;
};
@@ -184,7 +187,6 @@ static struct netconsole_target *alloc_netconsole_target(void)
strlcpy(nt->np.dev_name, "eth0", IFNAMSIZ);
nt->np.local_port = 6665;
nt->np.remote_port = 6666;
- mutex_init(&nt->mutex);
eth_broadcast_addr(nt->np.remote_mac);
return nt;
@@ -196,6 +198,8 @@ static struct netconsole_target *alloc_param_target(char *target_config)
int err = -ENOMEM;
struct netconsole_target *nt;
+ lockdep_assert_held(&netconsole_mutex);
+
nt = alloc_netconsole_target();
if (!nt)
goto fail;
@@ -573,10 +577,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);
+ mutex_lock(&netconsole_mutex);
if (na->store)
ret = na->store(nt, buf, count);
- mutex_unlock(&nt->mutex);
+ mutex_unlock(&netconsole_mutex);
return ret;
}
@@ -610,9 +614,11 @@ static struct config_item *make_netconsole_target(struct config_group *group,
config_item_init_type_name(&nt->item, name, &netconsole_target_type);
/* Adding, but it is disabled */
+ mutex_lock(&netconsole_mutex);
console_lock();
list_add(&nt->list, &target_list);
console_unlock();
+ mutex_unlock(&netconsole_mutex);
return &nt->item;
}
@@ -622,6 +628,7 @@ static void drop_netconsole_target(struct config_group *group,
{
struct netconsole_target *nt = to_target(item);
+ mutex_lock(&netconsole_mutex);
console_lock();
list_del(&nt->list);
console_unlock();
@@ -634,6 +641,7 @@ static void drop_netconsole_target(struct config_group *group,
netpoll_cleanup(&nt->np);
config_item_put(&nt->item);
+ mutex_unlock(&netconsole_mutex);
}
static struct configfs_group_operations netconsole_subsys_group_ops = {
@@ -662,6 +670,7 @@ static void netconsole_deferred_disable_work_fn(struct work_struct *work)
{
struct netconsole_target *nt, *to_disable;
+ mutex_lock(&netconsole_mutex);
repeat:
to_disable = NULL;
console_lock();
@@ -685,6 +694,8 @@ repeat:
netconsole_target_put(to_disable);
goto repeat;
}
+
+ mutex_unlock(&netconsole_mutex);
}
static DECLARE_WORK(netconsole_deferred_disable_work,
@@ -791,6 +802,8 @@ static int __init init_netconsole(void)
char *target_config;
char *input = config;
+ mutex_lock(&netconsole_mutex);
+
if (strnlen(input, MAX_PARAM_LENGTH)) {
while ((target_config = strsep(&input, ";"))) {
nt = alloc_param_target(target_config);
@@ -818,24 +831,21 @@ static int __init init_netconsole(void)
register_console(&netconsole);
pr_info("network logging started\n");
+ mutex_unlock(&netconsole_mutex);
return err;
undonotifier:
unregister_netdevice_notifier(&netconsole_netdev_notifier);
- cancel_work_sync(&netconsole_deferred_disable_work);
fail:
pr_err("cleaning up\n");
- /*
- * Remove all targets and destroy them (only targets created
- * from the boot/module option exist here). Skipping the console
- * lock is safe here.
- */
+ /* targets are already inactive, skipping the console lock is safe */
list_for_each_entry_safe(nt, tmp, &target_list, list) {
list_del(&nt->list);
free_param_target(nt);
}
-
+ mutex_unlock(&netconsole_mutex);
+ cancel_work_sync(&netconsole_deferred_disable_work);
return err;
}
@@ -843,22 +853,20 @@ static void __exit cleanup_netconsole(void)
{
struct netconsole_target *nt, *tmp;
+ mutex_lock(&netconsole_mutex);
+
unregister_console(&netconsole);
dynamic_netconsole_exit();
unregister_netdevice_notifier(&netconsole_netdev_notifier);
- cancel_work_sync(&netconsole_deferred_disable_work);
- /*
- * Targets created via configfs pin references on our module
- * and would first be rmdir(2)'ed from userspace. We reach
- * here only when they are already destroyed, and only those
- * created from the boot/module option are left, so remove and
- * destroy them. Skipping the console lock is safe here.
- */
+ /* targets are already inactive, skipping the console lock is safe */
list_for_each_entry_safe(nt, tmp, &target_list, list) {
list_del(&nt->list);
free_param_target(nt);
}
+
+ mutex_unlock(&netconsole_mutex);
+ cancel_work_sync(&netconsole_deferred_disable_work);
}
/*
--
2.1.0
next prev parent reply other threads:[~2015-04-16 23:07 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-04-16 23:03 [PATCHSET] printk, netconsole: implement reliable netconsole Tejun Heo
2015-04-16 23:03 ` [PATCH 01/16] printk: guard the amount written per line by devkmsg_read() Tejun Heo
2015-04-20 12:11 ` Petr Mladek
2015-04-20 12:33 ` Petr Mladek
2015-04-16 23:03 ` [PATCH 02/16] printk: factor out message formatting from devkmsg_read() Tejun Heo
2015-04-20 12:30 ` Petr Mladek
2015-04-16 23:03 ` [PATCH 03/16] printk: move LOG_NOCONS skipping into call_console_drivers() Tejun Heo
2015-04-20 12:50 ` Petr Mladek
2015-04-16 23:03 ` [PATCH 04/16] printk: implement support for extended console drivers Tejun Heo
2015-04-20 15:43 ` Petr Mladek
2015-04-21 10:03 ` Petr Mladek
2015-04-27 21:09 ` Tejun Heo
2015-04-28 9:42 ` Petr Mladek
2015-04-28 14:10 ` Tejun Heo
2015-04-28 14:24 ` Petr Mladek
2015-04-16 23:03 ` [PATCH 05/16] printk: implement log_seq_range() and ext_log_from_seq() Tejun Heo
2015-04-16 23:03 ` [PATCH 06/16] netconsole: make netconsole_target->enabled a bool Tejun Heo
2015-04-16 23:03 ` [PATCH 07/16] netconsole: factor out alloc_netconsole_target() Tejun Heo
2015-04-16 23:03 ` [PATCH 08/16] netconsole: punt disabling to workqueue from netdevice_notifier Tejun Heo
2015-04-16 23:03 ` [PATCH 09/16] netconsole: replace target_list_lock with console_lock Tejun Heo
2015-04-16 23:03 ` Tejun Heo [this message]
2015-04-16 23:03 ` [PATCH 11/16] netconsole: consolidate enable/disable and create/destroy paths Tejun Heo
2015-04-16 23:03 ` [PATCH 12/16] netconsole: implement extended console support Tejun Heo
2015-04-16 23:03 ` [PATCH 13/16] netconsole: implement retransmission support for extended consoles Tejun Heo
2015-04-16 23:03 ` [PATCH 14/16] netconsole: implement ack handling and emergency transmission Tejun Heo
2015-04-16 23:03 ` [PATCH 15/16] netconsole: implement netconsole receiver library Tejun Heo
2015-04-16 23:03 ` [PATCH 16/16] netconsole: update documentation for extended netconsole Tejun Heo
2015-04-17 15:35 ` [PATCHSET] printk, netconsole: implement reliable netconsole Tetsuo Handa
2015-04-17 16:28 ` Tejun Heo
2015-04-17 17:17 ` David Miller
2015-04-17 17:37 ` Tejun Heo
2015-04-17 17:43 ` Tetsuo Handa
2015-04-17 17:45 ` Tejun Heo
2015-04-17 18:03 ` Tetsuo Handa
2015-04-17 18:07 ` Tejun Heo
2015-04-17 18:20 ` Tetsuo Handa
2015-04-17 18:26 ` Tejun Heo
2015-04-18 13:09 ` Tetsuo Handa
2015-04-17 18:04 ` Tejun Heo
2015-04-17 18:55 ` David Miller
2015-04-17 19:52 ` Tejun Heo
2015-04-17 20:06 ` David Miller
2015-04-21 21:51 ` Stephen Hemminger
2015-04-19 7:25 ` Rob Landley
2015-04-20 12:00 ` David Laight
2015-04-20 12:00 ` David Laight
2015-04-20 14:33 ` Tejun Heo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1429225433-11946-11-git-send-email-tj@kernel.org \
--to=tj@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=davem@davemloft.net \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.