rcu.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Joel Fernandes <joel@joelfernandes.org>
To: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: rcu@vger.kernel.org, "Paul E. McKenney" <paulmck@kernel.org>,
	Josh Triplett <josh@joshtriplett.org>,
	Steven Rostedt <rostedt@goodmis.org>,
	Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
	Lai Jiangshan <jiangshanlai@gmail.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Mike Galbraith <efault@gmx.de>,
	urezki@gmail.com
Subject: Re: [PATCH 1/3] rcu: Use static initializer for krc.lock
Date: Thu, 16 Apr 2020 10:42:54 -0400	[thread overview]
Message-ID: <20200416144254.GC90777@google.com> (raw)
In-Reply-To: <20200415160034.662274-2-bigeasy@linutronix.de>

+Vlad

Hi Sebastian,

On Wed, Apr 15, 2020 at 06:00:32PM +0200, Sebastian Andrzej Siewior wrote:
> The per-CPU variable is initialized at runtime in
> kfree_rcu_batch_init(). This function is invoked before
> `rcu_scheduler_active' is set to `RCU_SCHEDULER_RUNNING'. After the
> initialisation, `->initialized' is to true.
> 
> The spin_lock is only acquired if `->initialized' is set to true. The
> worqueue item is only used if `rcu_scheduler_active' set to
> RCU_SCHEDULER_RUNNING' which happens after initialisation.
> 
> Use a static initializer for krc.lock and remove the runtime
> initialisation of the lock. Since the lock can now be always acquired,
> remove the `->initialized' check.
> The local_irq_save() is removed and raw_cpu_ptr() + spin_lock_irqsave()
> is used. The worst case scenario is that after raw_cpu_ptr() the code
> has been moved to another CPU. This is "okay" because the data strucure
> itself is protected with a lock.
> Add a warning in kfree_rcu_batch_init() to ensure that this function is
> invoked before `RCU_SCHEDULER_RUNNING' to ensure that the worker is not
> used earlier.
> 
> Reported-by: Mike Galbraith <efault@gmx.de>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> ---
>  kernel/rcu/tree.c | 22 +++++++---------------
>  1 file changed, 7 insertions(+), 15 deletions(-)
> 
> diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> index f288477ee1c26..5b0b63dd04b02 100644
> --- a/kernel/rcu/tree.c
> +++ b/kernel/rcu/tree.c
> @@ -2893,7 +2893,6 @@ struct kfree_rcu_cpu_work {
>   * @lock: Synchronize access to this structure
>   * @monitor_work: Promote @head to @head_free after KFREE_DRAIN_JIFFIES
>   * @monitor_todo: Tracks whether a @monitor_work delayed work is pending
> - * @initialized: The @lock and @rcu_work fields have been initialized
>   *
>   * This is a per-CPU structure.  The reason that it is not included in
>   * the rcu_data structure is to permit this code to be extracted from
> @@ -2908,12 +2907,13 @@ struct kfree_rcu_cpu {
>  	spinlock_t lock;
>  	struct delayed_work monitor_work;
>  	bool monitor_todo;
> -	bool initialized;
>  	// Number of objects for which GP not started
>  	int count;
>  };
>  
> -static DEFINE_PER_CPU(struct kfree_rcu_cpu, krc);
> +static DEFINE_PER_CPU(struct kfree_rcu_cpu, krc) = {
> +	.lock	= __SPIN_LOCK_UNLOCKED(krc.lock),
> +};
>  
>  static __always_inline void
>  debug_rcu_head_unqueue_bulk(struct rcu_head *head)
> @@ -3080,9 +3080,6 @@ kfree_call_rcu_add_ptr_to_bulk(struct kfree_rcu_cpu *krcp,
>  {
>  	struct kfree_rcu_bulk_data *bnode;
>  
> -	if (unlikely(!krcp->initialized))
> -		return false;
> -
>  	lockdep_assert_held(&krcp->lock);
>  
>  	/* Check if a new block is required. */
> @@ -3139,10 +3136,8 @@ void kfree_call_rcu(struct rcu_head *head, rcu_callback_t func)
>  	unsigned long flags;
>  	struct kfree_rcu_cpu *krcp;
>  
> -	local_irq_save(flags);	// For safely calling this_cpu_ptr().
> -	krcp = this_cpu_ptr(&krc);
> -	if (krcp->initialized)
> -		spin_lock(&krcp->lock);
> +	krcp = raw_cpu_ptr(&krc);
> +	spin_lock_irqsave(&krcp->lock, flags);

I agree with the patch, except for this bit. Would it be ok to split the
other parts of this patch into separate patch(es)?

For this part of the patch, I am wondering what is the value in it. For one,
we don't want migration between sampling the value of the pointer, and
actually using it. One reason at least is because we have certain resources
in the per-cpu structure that take advantage of cache locality (such as the
kfree_rcu_cpu::krw_arr array). In the common case, the callback would be
executed on the same CPU it is queued on. All of the access is local to the
CPU.

I know the work item can still be handled on other CPUs so we are not
strictly doing it in the worst case (however per my understanding, the work
item is executed in the same CPU most of the time).

Also on a slightly related note, could you share with me why this_cpu_ptr()
is unsafe to call in non-preemptible context, but raw_cpu_ptr() is ok? Just
curious on that.

thanks,

 - Joel


>  
>  	// Queue the object but don't yet schedule the batch.
>  	if (debug_rcu_head_queue(head)) {
> @@ -3172,9 +3167,7 @@ void kfree_call_rcu(struct rcu_head *head, rcu_callback_t func)
>  	}
>  
>  unlock_return:
> -	if (krcp->initialized)
> -		spin_unlock(&krcp->lock);
> -	local_irq_restore(flags);
> +	spin_unlock_irqrestore(&krcp->lock, flags);
>  }
>  EXPORT_SYMBOL_GPL(kfree_call_rcu);
>  
> @@ -4137,17 +4130,16 @@ static void __init kfree_rcu_batch_init(void)
>  	int cpu;
>  	int i;
>  
> +	WARN_ON(rcu_scheduler_active == RCU_SCHEDULER_RUNNING);
>  	for_each_possible_cpu(cpu) {
>  		struct kfree_rcu_cpu *krcp = per_cpu_ptr(&krc, cpu);
>  
> -		spin_lock_init(&krcp->lock);
>  		for (i = 0; i < KFREE_N_BATCHES; i++) {
>  			INIT_RCU_WORK(&krcp->krw_arr[i].rcu_work, kfree_rcu_work);
>  			krcp->krw_arr[i].krcp = krcp;
>  		}
>  
>  		INIT_DELAYED_WORK(&krcp->monitor_work, kfree_rcu_monitor);
> -		krcp->initialized = true;
>  	}
>  	if (register_shrinker(&kfree_rcu_shrinker))
>  		pr_err("Failed to register kfree_rcu() shrinker!\n");
> -- 
> 2.26.0
> 

  reply	other threads:[~2020-04-16 14:43 UTC|newest]

Thread overview: 85+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-15 16:00 [PATCH 0/3] rcu: Static initializer + misc Sebastian Andrzej Siewior
2020-04-15 16:00 ` [PATCH 1/3] rcu: Use static initializer for krc.lock Sebastian Andrzej Siewior
2020-04-16 14:42   ` Joel Fernandes [this message]
2020-04-16 15:01     ` Uladzislau Rezki
2020-04-16 15:20       ` Sebastian Andrzej Siewior
2020-04-16 15:38         ` Uladzislau Rezki
2020-04-16 15:46           ` Sebastian Andrzej Siewior
2020-04-16 16:01             ` Uladzislau Rezki
2020-04-16 16:11               ` Sebastian Andrzej Siewior
2020-04-16 16:18                 ` Uladzislau Rezki
2020-04-16 16:33                   ` Sebastian Andrzej Siewior
2020-04-16 17:29                     ` Paul E. McKenney
2020-04-16 18:23                       ` Sebastian Andrzej Siewior
2020-04-16 18:29                         ` Paul E. McKenney
2020-04-16 18:43                           ` Joel Fernandes
2020-04-16 20:56                             ` Sebastian Andrzej Siewior
2020-04-16 21:04                               ` Joel Fernandes
2020-04-16 21:07                                 ` Sebastian Andrzej Siewior
2020-04-16 18:40                     ` Steven Rostedt
2020-04-16 18:53                       ` Joel Fernandes
2020-04-16 19:24                         ` Steven Rostedt
2020-04-16 20:41                           ` Joel Fernandes
2020-04-16 21:05                       ` Sebastian Andrzej Siewior
2020-04-16 17:28         ` Paul E. McKenney
2020-04-16 15:18     ` Sebastian Andrzej Siewior
2020-04-16 18:41       ` Joel Fernandes
2020-04-16 18:59         ` Joel Fernandes
2020-04-16 19:26           ` Steven Rostedt
2020-04-16 19:53             ` Paul E. McKenney
2020-04-16 20:05               ` Uladzislau Rezki
2020-04-16 20:25                 ` Paul E. McKenney
2020-04-16 21:02                   ` Joel Fernandes
2020-04-16 21:18                   ` Uladzislau Rezki
2020-04-16 21:26                     ` Uladzislau Rezki
2020-04-16 21:28                   ` Sebastian Andrzej Siewior
2020-04-16 20:36             ` Joel Fernandes
2020-04-16 21:00               ` Paul E. McKenney
2020-04-16 21:34                 ` Sebastian Andrzej Siewior
2020-04-17  3:05                   ` Joel Fernandes
2020-04-17  8:47                     ` Uladzislau Rezki
2020-04-17 15:04                     ` Sebastian Andrzej Siewior
2020-04-17 18:26                       ` Joel Fernandes
2020-04-17 18:54                         ` Paul E. McKenney
2020-04-18 12:37                           ` Uladzislau Rezki
2020-04-19 14:58                             ` Paul E. McKenney
2020-04-20  0:27                               ` Joel Fernandes
2020-04-20  1:17                                 ` Joel Fernandes
2020-04-20  1:44                                   ` Paul E. McKenney
2020-04-20 12:13                                     ` Uladzislau Rezki
2020-04-20 12:36                                       ` joel
2020-04-20 13:00                                         ` Uladzislau Rezki
2020-04-20 13:26                                           ` Paul E. McKenney
2020-04-20 16:08                                             ` Uladzislau Rezki
2020-04-20 16:25                                               ` Paul E. McKenney
2020-04-20 16:29                                                 ` Uladzislau Rezki
2020-04-20 16:46                                                   ` Paul E. McKenney
2020-04-20 16:59                                                     ` Uladzislau Rezki
2020-04-20 17:21                                                       ` Paul E. McKenney
2020-04-20 17:40                                                         ` Uladzislau Rezki
2020-04-20 17:57                                                           ` Joel Fernandes
2020-04-20 18:13                                                             ` Paul E. McKenney
2020-04-20 17:59                                                           ` Paul E. McKenney
2020-04-20 19:06                                                             ` Uladzislau Rezki
2020-04-20 20:17                                                               ` Uladzislau Rezki
2020-04-20 22:16                                                                 ` Paul E. McKenney
2020-04-21  1:22                                                                 ` Steven Rostedt
2020-04-21  5:18                                                                   ` Uladzislau Rezki
2020-04-21 13:30                                                                     ` Steven Rostedt
2020-04-21 13:45                                                                       ` Uladzislau Rezki
2020-04-21 13:39                                                           ` Sebastian Andrzej Siewior
2020-04-21 15:41                                                             ` Paul E. McKenney
2020-04-21 17:05                                                               ` Sebastian Andrzej Siewior
2020-04-21 18:09                                                                 ` Paul E. McKenney
2020-04-22 11:13                                                                   ` Sebastian Andrzej Siewior
2020-04-22 13:33                                                                     ` Paul E. McKenney
2020-04-22 15:46                                                                       ` Sebastian Andrzej Siewior
2020-04-22 16:19                                                                         ` Paul E. McKenney
2020-04-22 16:35                                                                           ` Paul E. McKenney
2020-04-20  3:02                                   ` Mike Galbraith
2020-04-20 12:30                                     ` joel
2020-04-17 16:11                     ` Uladzislau Rezki
2020-04-19 12:15                     ` Uladzislau Rezki
2020-04-15 16:00 ` [PATCH 2/3] rcu: Use consistent locking around kfree_rcu_drain_unlock() Sebastian Andrzej Siewior
2020-04-15 16:00 ` [PATCH 3/3] rcu: Avoid using xchg() in kfree_call_rcu_add_ptr_to_bulk() Sebastian Andrzej Siewior
2020-04-20 15:23   ` Joel Fernandes

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=20200416144254.GC90777@google.com \
    --to=joel@joelfernandes.org \
    --cc=bigeasy@linutronix.de \
    --cc=efault@gmx.de \
    --cc=jiangshanlai@gmail.com \
    --cc=josh@joshtriplett.org \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=paulmck@kernel.org \
    --cc=rcu@vger.kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=tglx@linutronix.de \
    --cc=urezki@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;
as well as URLs for NNTP newsgroup(s).