lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20200922001015.GO29330@paulmck-ThinkPad-P72>
Date:   Mon, 21 Sep 2020 17:10:15 -0700
From:   "Paul E. McKenney" <paulmck@...nel.org>
To:     Frederic Weisbecker <frederic@...nel.org>
Cc:     LKML <linux-kernel@...r.kernel.org>,
        Steven Rostedt <rostedt@...dmis.org>,
        Mathieu Desnoyers <mathieu.desnoyers@...icios.com>,
        Lai Jiangshan <jiangshanlai@...il.com>,
        Joel Fernandes <joel@...lfernandes.org>,
        Josh Triplett <josh@...htriplett.org>
Subject: Re: [RFC PATCH 05/12] rcu: De-offloading GP kthread

On Mon, Sep 21, 2020 at 02:43:44PM +0200, Frederic Weisbecker wrote:
> In order to de-offload the callbacks processing of an rdp, we must clear
> SEGCBLIST_OFFLOAD and notify the GP kthread so that it clears its own
> bit flag and ignore the target rdp from its loop. The CB kthread
> is also notified the same way. Whoever acknowledges and clears its
> own bit last must notify the de-offloading worker so that it can resume
> the de-offloading while being sure that callbacks won't be handled
> remotely anymore.
> 
> Inspired-by: Paul E. McKenney <paulmck@...nel.org>
> Signed-off-by: Frederic Weisbecker <frederic@...nel.org>
> Cc: Paul E. McKenney <paulmck@...nel.org>
> Cc: Josh Triplett <josh@...htriplett.org>
> Cc: Steven Rostedt <rostedt@...dmis.org>
> Cc: Mathieu Desnoyers <mathieu.desnoyers@...icios.com>
> Cc: Lai Jiangshan <jiangshanlai@...il.com>
> Cc: Joel Fernandes <joel@...lfernandes.org>
> ---
>  kernel/rcu/tree_plugin.h | 53 ++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 51 insertions(+), 2 deletions(-)
> 
> diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
> index 3ea43c75c7a3..e4e7e7c4bfb6 100644
> --- a/kernel/rcu/tree_plugin.h
> +++ b/kernel/rcu/tree_plugin.h
> @@ -1900,6 +1900,33 @@ static void do_nocb_bypass_wakeup_timer(struct timer_list *t)
>  	__call_rcu_nocb_wake(rdp, true, flags);
>  }
>  
> +static inline bool nocb_gp_enabled_cb(struct rcu_data *rdp)
> +{
> +	u8 flags = SEGCBLIST_OFFLOADED | SEGCBLIST_KTHREAD_GP;
> +
> +	return rcu_segcblist_test_flags(&rdp->cblist, flags);
> +}
> +
> +static inline bool nocb_gp_update_state(struct rcu_data *rdp, bool *needwake_state)
> +{
> +	struct rcu_segcblist *cblist = &rdp->cblist;
> +
> +	if (rcu_segcblist_test_flags(cblist, SEGCBLIST_OFFLOADED)) {
> +		return true;
> +	} else {
> +		/*
> +		 * De-offloading. Clear our flag and notify the de-offload worker.
> +		 * We will ignore this rdp until it ever gets re-offloaded.
> +		 */
> +		WARN_ON_ONCE(!rcu_segcblist_test_flags(cblist, SEGCBLIST_KTHREAD_GP));
> +		rcu_segcblist_clear_flags(cblist, SEGCBLIST_KTHREAD_GP);
> +		if (!rcu_segcblist_test_flags(cblist, SEGCBLIST_KTHREAD_CB))
> +			*needwake_state = true;
> +		return false;
> +	}
> +}
> +
> +
>  /*
>   * No-CBs GP kthreads come here to wait for additional callbacks to show up
>   * or for grace periods to end.
> @@ -1927,8 +1954,17 @@ static void nocb_gp_wait(struct rcu_data *my_rdp)
>  	 * and the global grace-period kthread are awakened if needed.
>  	 */
>  	for (rdp = my_rdp; rdp; rdp = rdp->nocb_next_cb_rdp) {
> +		bool needwake_state = false;
> +		if (!nocb_gp_enabled_cb(rdp))
> +			continue;
>  		trace_rcu_nocb_wake(rcu_state.name, rdp->cpu, TPS("Check"));
>  		rcu_nocb_lock_irqsave(rdp, flags);
> +		if (!nocb_gp_update_state(rdp, &needwake_state)) {
> +			rcu_nocb_unlock_irqrestore(rdp, flags);
> +			if (needwake_state)
> +				swake_up_one(&rdp->nocb_state_wq);
> +			continue;
> +		}
>  		bypass_ncbs = rcu_cblist_n_cbs(&rdp->nocb_bypass);
>  		if (bypass_ncbs &&
>  		    (time_after(j, READ_ONCE(rdp->nocb_bypass_first) + 1) ||
> @@ -2194,7 +2230,8 @@ static void __rcu_nocb_rdp_deoffload(struct rcu_data *rdp)
>  	unsigned long flags;
>  	struct rcu_node *rnp = rdp->mynode;
>  	struct rcu_segcblist *cblist = &rdp->cblist;
> -	bool wake_cb = false;
> +	struct rcu_data *rdp_gp = rdp->nocb_gp_rdp;
> +	bool wake_cb = false, wake_gp = false;
>  
>  	printk("De-offloading %d\n", rdp->cpu);
>  
> @@ -2212,8 +2249,19 @@ static void __rcu_nocb_rdp_deoffload(struct rcu_data *rdp)
>  	if (wake_cb)
>  		swake_up_one(&rdp->nocb_cb_wq);
>  
> +	raw_spin_lock_irqsave(&rdp_gp->nocb_gp_lock, flags);
> +	if (rdp_gp->nocb_gp_sleep) {
> +		rdp_gp->nocb_gp_sleep = false;
> +		wake_gp = true;
> +	}
> +	raw_spin_unlock_irqrestore(&rdp_gp->nocb_gp_lock, flags);
> +
> +	if (wake_gp)
> +		wake_up_process(rdp_gp->nocb_gp_kthread);
> +
>  	swait_event_exclusive(rdp->nocb_state_wq,
> -			      !rcu_segcblist_test_flags(cblist, SEGCBLIST_KTHREAD_CB));
> +			      !rcu_segcblist_test_flags(cblist, SEGCBLIST_KTHREAD_CB |
> +							SEGCBLIST_KTHREAD_GP));
>  }
>  
>  static long rcu_nocb_rdp_deoffload(void *arg)
> @@ -2292,6 +2340,7 @@ void __init rcu_init_nohz(void)
>  			rcu_segcblist_init(&rdp->cblist);
>  		rcu_segcblist_offload(&rdp->cblist, true);
>  		rcu_segcblist_set_flags(&rdp->cblist, SEGCBLIST_KTHREAD_CB);
> +		rcu_segcblist_set_flags(&rdp->cblist, SEGCBLIST_KTHREAD_GP);

OK, I will bite at this nit...

Why not "SEGCBLIST_KTHREAD_CB | SEGCBLIST_KTHREAD_GP"?

							Thanx, Paul

>  	}
>  	rcu_organize_nocb_kthreads();
>  }
> -- 
> 2.28.0
> 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ