mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Neil Horman <nhorman@tuxdriver.com>
To: Mike Waychison <mikew@google.com>
Cc: simon.kagstrom@netinsight.net, davem@davemloft.net,
	"Matt Mackall" <mpm@selenic.com>,
	adurbin@google.com, linux-kernel@vger.kernel.org,
	chavey@google.com, "Greg KH" <greg@kroah.com>,
	netdev@vger.kernel.org, "Américo Wang" <xiyou.wangcong@gmail.com>,
	akpm@linux-foundation.org, linux-api@vger.kernel.org
Subject: Re: [PATCH v3 03/22] netconsole: Introduce 'enabled' state-machine
Date: Fri, 17 Dec 2010 15:52:38 -0500	[thread overview]
Message-ID: <20101217205238.GA8642@hmsreliant.think-freely.org> (raw)
In-Reply-To: <20101214212909.17022.96801.stgit@mike.mtv.corp.google.com>

On Tue, Dec 14, 2010 at 01:29:10PM -0800, Mike Waychison wrote:
> Representing the internal state within netconsole isn't really a boolean
> value, but rather a state machine with transitions.
> 
> This patch introduces 4 states that the netconsole multi-target can
> handle.  These states are:
> - NETPOLL_DISABLED:
>     The netpoll structure hasn't been setup.
> - NETPOLL_SETTINGUP:
>     The netpoll structure is being setup, and only whoever set this
>     state can transition out of it.  Must come from the NETPOLL_DISABLED
>     state.
> - NETPOLL_ENABLED:
>     The netpoll structure has been setup and we are good to emit
>     packets.
> - NETPOLL_CLEANING:
>     Somebody is queued to call netpoll_clean.  Whoever does so must
>     transition out of this state.  Must come from the NETPOLL_CLEANING
>     state.
> 
> The SETTINGUP state specifically targets the window where
> netpoll_setup() can take a while (for example, waiting on RTNL).
> During this window, we want to exclude console messages from being
> emitted to this netpoll target.  We also want to exclude any subsequent
> user thread that tries to simultaneously enable or disable the target.
> 
> The CLEANING state will be used in a subsequent patch to safely defer
> netpoll_cleanup to scheduled work in process context (to fix the
> deadlock that will occur whenever NETDEV_UNREGISTER is seen).
> 
> When introducing these new transition states, it no longer makes sense
> to 'disable' the target if the interface is going down, only when it is
> being removed completely (or deslaved).  In fact, prior to this change,
> we would leak a reference to the network device if an interface was
> brought down, the target removed, and netconsole unloaded.
> 
> Signed-off-by: Mike Waychison <mikew@google.com>
> Acked-by: Matt Mackall <mpm@selenic.com>
> ---
>  drivers/net/netconsole.c |   62 +++++++++++++++++++++++++++++-----------------
>  1 files changed, 39 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
> index 6e16888..288a025 100644
> --- a/drivers/net/netconsole.c
> +++ b/drivers/net/netconsole.c
> @@ -71,16 +71,24 @@ static LIST_HEAD(target_list);
>  /* This needs to be a spinlock because write_msg() cannot sleep */
>  static DEFINE_SPINLOCK(target_list_lock);
>  
> +#define NETPOLL_DISABLED	0
> +#define NETPOLL_SETTINGUP	1
> +#define NETPOLL_ENABLED		2
> +#define NETPOLL_CLEANING	3
> +
>  /**
>   * struct netconsole_target - Represents a configured netconsole target.
>   * @list:	Links this target into the target_list.
>   * @item:	Links us into the configfs subsystem hierarchy.
> - * @enabled:	On / off knob to enable / disable target.
> - *		Visible from userspace (read-write).
> - *		We maintain a strict 1:1 correspondence between this and
> - *		whether the corresponding netpoll is active or inactive.
> + * @np_state:	Enabled / Disabled / SettingUp / Cleaning
> + *		Visible from userspace (read-write) as "enabled".
> + *		We maintain a state machine here of the valid states.  Either a
> + *		target is enabled or disabled, but it may also be in a
> + *		transitional state whereby nobody is allowed to act on the
> + *		target other than whoever owns the transition.
> + *
>   *		Also, other parameters of a target may be modified at
> - *		runtime only when it is disabled (enabled == 0).
> + *		runtime only when it is disabled (np_state == NETPOLL_ENABLED).
>   * @np:		The netpoll structure for this target.
>   *		Contains the other userspace visible parameters:
>   *		dev_name	(read-write)
> @@ -96,7 +104,7 @@ struct netconsole_target {
>  #ifdef	CONFIG_NETCONSOLE_DYNAMIC
>  	struct config_item	item;
>  #endif
> -	int			enabled;
> +	int			np_state;
>  	struct netpoll		np;
>  };
>  
> @@ -189,7 +197,7 @@ static struct netconsole_target *alloc_param_target(char *target_config)
>  	if (err)
>  		goto fail;
>  
> -	nt->enabled = 1;
> +	nt->np_state = NETPOLL_ENABLED;
>  
>  	return nt;
>  
> @@ -275,7 +283,8 @@ static long strtol10_check_range(const char *cp, long min, long max)
>  
>  static ssize_t show_enabled(struct netconsole_target *nt, char *buf)
>  {
> -	return snprintf(buf, PAGE_SIZE, "%d\n", nt->enabled);
> +	return snprintf(buf, PAGE_SIZE, "%d\n",
> +			nt->np_state == NETPOLL_ENABLED);
>  }
>  
>  static ssize_t show_dev_name(struct netconsole_target *nt, char *buf)
> @@ -337,9 +346,12 @@ static ssize_t store_enabled(struct netconsole_target *nt,
>  
>  	if (enabled) {	/* 1 */
>  		spin_lock_irqsave(&target_list_lock, flags);
> -		if (nt->enabled)
> +		if (nt->np_state != NETPOLL_DISABLED)
>  			goto busy;
> -		spin_unlock_irqrestore(&target_list_lock, flags);
> +		else {
> +			nt->np_state = NETPOLL_SETTINGUP;
> +			spin_unlock_irqrestore(&target_list_lock, flags);
> +		}
>  
>  		/*
>  		 * Skip netpoll_parse_options() -- all the attributes are
> @@ -350,9 +362,9 @@ static ssize_t store_enabled(struct netconsole_target *nt,
>  		err = netpoll_setup(&nt->np);
>  		spin_lock_irqsave(&target_list_lock, flags);
>  		if (err)
> -			nt->enabled = 0;
> +			nt->np_state = NETPOLL_DISABLED;
>  		else
> -			nt->enabled = 1;
> +			nt->np_state = NETPOLL_ENABLED;
>  		spin_unlock_irqrestore(&target_list_lock, flags);
>  		if (err)
>  			return err;
> @@ -360,10 +372,17 @@ static ssize_t store_enabled(struct netconsole_target *nt,
>  		printk(KERN_INFO "netconsole: network logging started\n");
>  	} else {	/* 0 */
>  		spin_lock_irqsave(&target_list_lock, flags);
> -		nt->enabled = 0;
> +		if (nt->np_state == NETPOLL_ENABLED)
> +			nt->np_state = NETPOLL_CLEANING;
> +		else if (nt->np_state != NETPOLL_DISABLED)
> +			goto busy;
>  		spin_unlock_irqrestore(&target_list_lock, flags);
>  
>  		netpoll_cleanup(&nt->np);
> +
> +		spin_lock_irqsave(&target_list_lock, flags);
> +		nt->np_state = NETPOLL_DISABLED;
> +		spin_unlock_irqrestore(&target_list_lock, flags);
>  	}
>  
>  	return strnlen(buf, count);
> @@ -486,7 +505,7 @@ static ssize_t store_locked_##_name(struct netconsole_target *nt,	\
>  	unsigned long flags;						\
>  	ssize_t ret;							\
>  	spin_lock_irqsave(&target_list_lock, flags);			\
> -	if (nt->enabled) {						\
> +	if (nt->np_state != NETPOLL_DISABLED) {				\
>  		printk(KERN_ERR "netconsole: target (%s) is enabled, "	\
>  				"disable to update parameters\n",	\
>  				config_item_name(&nt->item));		\
> @@ -642,7 +661,7 @@ static void drop_netconsole_target(struct config_group *group,
>  	 * The target may have never been enabled, or was manually disabled
>  	 * before being removed so netpoll may have already been cleaned up.
>  	 */
> -	if (nt->enabled)
> +	if (nt->np_state == NETPOLL_ENABLED)
>  		netpoll_cleanup(&nt->np);
>  
>  	config_item_put(&nt->item);
> @@ -680,16 +699,17 @@ static int netconsole_netdev_event(struct notifier_block *this,
>  	struct net_device *dev = ptr;
>  
>  	if (!(event == NETDEV_CHANGENAME || event == NETDEV_UNREGISTER ||
> -	      event == NETDEV_BONDING_DESLAVE || event == NETDEV_GOING_DOWN))
> +	      event == NETDEV_BONDING_DESLAVE))
>  		goto done;
>  
>  	spin_lock_irqsave(&target_list_lock, flags);
>  	list_for_each_entry(nt, &target_list, list) {
> -		if (nt->np.dev == dev) {
> +		if (nt->np_state == NETPOLL_ENABLED && nt->np.dev == dev) {
>  			switch (event) {
>  			case NETDEV_CHANGENAME:
>  				strlcpy(nt->np.dev_name, dev->name, IFNAMSIZ);
>  				break;
> +			case NETDEV_BONDING_DESLAVE:
>  			case NETDEV_UNREGISTER:
I don't follow what you're doing here.  Previously NETDEV_BONDING_DESLAVE events
simply caused the netconsole interface to get deactivated, and now we're doing a
dev_put on the bonded interface bacause of the above move.  Given that
NETDEV_BONDING_DESLAVE events are generated when a slave leaves the bond, this
doesn't seem right, or am I missing something

Regards
Neil


  parent reply	other threads:[~2010-12-17 20:53 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-12-14 21:28 [PATCH v3 00/22] netoops support Mike Waychison
2010-12-14 21:28 ` [PATCH v3 01/22] netconsole: Remove unneeded reference counting Mike Waychison
2010-12-14 21:29 ` [PATCH v3 02/22] netconsole: Introduce locking over the netpoll fields Mike Waychison
2010-12-14 23:15   ` Michał Mirosław
2010-12-14 23:30     ` Mike Waychison
2010-12-14 21:29 ` [PATCH v3 03/22] netconsole: Introduce 'enabled' state-machine Mike Waychison
2010-12-14 23:21   ` Michał Mirosław
2010-12-14 23:33     ` Mike Waychison
2010-12-17 20:52   ` Neil Horman [this message]
2010-12-17 21:20     ` Mike Waychison
2010-12-14 21:29 ` [PATCH v3 04/22] netconsole: Call netpoll_cleanup() in process context Mike Waychison
2010-12-14 21:29 ` [PATCH v3 05/22] netconsole: Wrap the list and locking in a structure Mike Waychison
2010-12-14 21:29 ` [PATCH v3 06/22] netconsole: Push configfs_subsystem into netpoll_targets Mike Waychison
2010-12-14 21:29 ` [PATCH v3 07/22] netconsole: Move netdev_notifier " Mike Waychison
2010-12-14 21:29 ` [PATCH v3 08/22] netconsole: Split out netpoll_targets init/exit Mike Waychison
2010-12-14 21:29 ` [PATCH v3 09/22] netconsole: Add pointer to netpoll_targets Mike Waychison
2010-12-14 21:29 ` [PATCH v3 10/22] netconsole: Rename netconsole_target -> netpoll_target Mike Waychison
2010-12-14 21:29 ` [PATCH v3 11/22] netconsole: Abstract away the subsystem name Mike Waychison
2010-12-14 21:29 ` [PATCH v3 12/22] netconsole: Move setting of default ports Mike Waychison
2010-12-14 21:30 ` [PATCH v3 13/22] netpoll: Introduce netpoll_target configs Mike Waychison
2010-12-14 21:30 ` [PATCH v3 14/22] netpoll: Move target code into netpoll_targets.c Mike Waychison
2010-12-15  0:07   ` Mike Waychison
2010-12-14 21:30 ` [PATCH v3 15/22] Oops: Pass regs to oops_exit() Mike Waychison
2010-12-14 21:30 ` [PATCH v3 16/22] kmsg_dumper: Pass pt_regs along to dumpers Mike Waychison
2010-12-14 21:30 ` [PATCH v3 17/22] kmsg_dumper: Introduce a new 'SOFT' dump reason Mike Waychison
2010-12-14 21:30 ` [PATCH v3 18/22] sys-rq: Add option to soft dump Mike Waychison
2010-12-14 21:30 ` [PATCH v3 19/22] netoops: add core functionality Mike Waychison
2010-12-14 21:30 ` [PATCH v3 20/22] netoops: Add x86 specific bits to packet headers Mike Waychison
2010-12-14 21:30 ` [PATCH v3 21/22] netoops: Add user-programmable boot_id Mike Waychison
2010-12-14 21:42   ` Matt Mackall
2010-12-14 21:59     ` Mike Waychison
2010-12-14 22:06       ` Matt Mackall
2010-12-14 22:33         ` Mike Waychison
2010-12-14 22:47           ` Matt Mackall
2010-12-14 23:19             ` Mike Waychison
2010-12-15  2:16               ` Ted Ts'o
2010-12-14 21:30 ` [PATCH v3 22/22] netoops: Add a user programmable blob to the netoops packet Mike Waychison

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=20101217205238.GA8642@hmsreliant.think-freely.org \
    --to=nhorman@tuxdriver.com \
    --cc=adurbin@google.com \
    --cc=akpm@linux-foundation.org \
    --cc=chavey@google.com \
    --cc=davem@davemloft.net \
    --cc=greg@kroah.com \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mikew@google.com \
    --cc=mpm@selenic.com \
    --cc=netdev@vger.kernel.org \
    --cc=simon.kagstrom@netinsight.net \
    --cc=xiyou.wangcong@gmail.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®