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] [day] [month] [year] [list]
Date:   Tue, 22 Mar 2022 13:30:29 +0100
From:   Frederic Weisbecker <frederic@...nel.org>
To:     Zqiang <qiang1.zhang@...el.com>
Cc:     paulmck@...nel.org, rcu@...r.kernel.org,
        linux-kernel@...r.kernel.org
Subject: Re: [PATCH v3 1/2] rcu: Call rcu_nocb_rdp_deoffload() directly after
 rcuog/op kthreads spawn failed

On Fri, Mar 18, 2022 at 04:07:18PM +0800, Zqiang wrote:
> @@ -1009,10 +1015,33 @@ static long rcu_nocb_rdp_deoffload(void *arg)
>  	 */
>  	rcu_segcblist_set_flags(cblist, SEGCBLIST_RCU_CORE);
>  	invoke_rcu_core();
> -	ret = rdp_offload_toggle(rdp, false, flags);
> -	swait_event_exclusive(rdp->nocb_state_wq,
> -			      !rcu_segcblist_test_flags(cblist, SEGCBLIST_KTHREAD_CB |
> -							SEGCBLIST_KTHREAD_GP));
> +	wake_gp = rdp_offload_toggle(rdp, false, flags);
> +
> +	mutex_lock(&rdp_gp->nocb_gp_kthread_mutex);
> +	if (rdp_gp->nocb_gp_kthread) {
> +		if (wake_gp)
> +			wake_up_process(rdp_gp->nocb_gp_kthread);
> +
> +		if (rdp->nocb_cb_kthread) {
> +			condition = SEGCBLIST_KTHREAD_CB | SEGCBLIST_KTHREAD_GP;
> +		} else {
> +			/*
> +			 *If rcuop kthread spawn failed, direct remove SEGCBLIST_KTHREAD_CB
> +			 *just wait SEGCBLIST_KTHREAD_GP to be cleared.
> +			 */
> +			condition = SEGCBLIST_KTHREAD_GP;
> +			rcu_segcblist_clear_flags(&rdp->cblist,
> SEGCBLIST_KTHREAD_CB);

You may be running concurrently againt nocb_gp_wait() ->
nocb_gp_update_state_deoffloading() -> rcu_segcblist_clear_flags(cblist,
SEGCBLIST_KTHREAD_GP)

So you need to protect the flags clear with rcu_nocb lock.




> +		}
> +		swait_event_exclusive(rdp->nocb_state_wq,
> +					!rcu_segcblist_test_flags(cblist, condition));
> +	} else {
> +		rcu_nocb_lock_irqsave(rdp, flags);
> +		rcu_segcblist_clear_flags(&rdp->cblist,
> +				SEGCBLIST_KTHREAD_CB | SEGCBLIST_KTHREAD_GP);
> +		rcu_nocb_unlock_irqrestore(rdp, flags);

Like you're doing here.

Thanks!

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ