Re: 回复:回复:回复:回复:Re:

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Good diagram, thank you!

But that call to on_each_cpu() looks like this:

	on_each_cpu(rcu_barrier_func, NULL, 0, 1);

Doesn't that last parameter of "1" mean that on_each_cpu() cannot return
until after CPU 3's call to rcu_barrier_func() finishes?

							Thanx, Paul

On Fri, Oct 07, 2022 at 04:03:12PM +0800, 5486 wrote:
> 原始邮件
>                        
>                      
> 
> 发件人:"Paul E. McKenney"< paulmck@xxxxxxxxxx &gt;;
> 
> 发件时间:2022/10/7 2:43
> 
> 收件人:"5486"< 3164135486@xxxxxx &gt;;
> 
> 抄送人:"rcu"< rcu@xxxxxxxxxxxxxxx &gt;;
> 
> 主题:回复:回复:回复:Re:
> 
> 
> On Fri, Oct 07, 2022 at 12:55:49AM +0800, 5486 wrote:
> &gt; &gt;&nbsp;Note that the last argument to on_each_cpu() is "1", that is,
> &gt; &gt;&nbsp;on_each_cpu() does not return until rcu_barrier_func() has executed on
> &gt; &gt;&nbsp;all CPUs.
> &gt; o .
> &gt; 
> &gt; 
> &gt; 
> &gt; &gt;Can your scenario happen?
> &gt; 
> &gt; rcu_barrier_func&nbsp; execution is not enough,the goal is finish all the rcu callback functions.
> &gt; 
> &gt; so it can.
> 
> OK, then please show the sequence of calls to rcu_barrier_func() and
> rcu_barrier_callback() on their respective CPUs, along with their effects
> on rcu_barrier_cpu_count, in order to show exactly how this can happen.
> 
> 							Thanx, Paul
> 
> &gt; 原始邮件
> &gt;                        
> &gt;                      
> &gt; 
> &gt; 发件人:"Paul E. McKenney"< paulmck@xxxxxxxxxx &gt;;
> &gt; 
> &gt; 发件时间:2022/10/7 0:46
> &gt; 
> &gt; 收件人:"5486"< 3164135486@xxxxxx &gt;;
> &gt; 
> &gt; 抄送人:"rcu"< rcu@xxxxxxxxxxxxxxx &gt;;
> &gt; 
> &gt; 主题:回复:回复:Re:
> &gt; 
> &gt; 
> &gt; On Fri, Oct 07, 2022 at 12:38:56AM +0800, 5486 wrote:
> &gt; &gt; In fact suppose there are for cpuscpu0 cpu1 cpu2 cpu3
> &gt; &gt; 
> &gt; &gt; 
> &gt; &gt; the value of rcu_barrier_cpu_count may be
> &gt; &gt; 
> &gt; &gt; 
> &gt; &gt; 1 &nbsp;cpu0 2 -&gt; 1 cpu1 2 -&gt; 1 cpu2 2 -&gt; 1
> &gt; &gt; then on_each_cpu finished rcu_barrier_cpu_count decreased to be 0
> &gt; &gt; then complete(&amp;rcu_barrier_completion); rcu_barrier finished.but rcu_barrier_func of cpu3 may not&nbsp;have been executed.
> &gt; 
> &gt; Note that the last argument to on_each_cpu() is "1", that is,
> &gt; on_each_cpu() does not return until rcu_barrier_func() has executed on
> &gt; all CPUs.
> &gt; 
> &gt; Can your scenario happen?
> &gt; 
> &gt; 							Thanx, Paul
> &gt; 
> &gt; &gt; 原始邮件
> &gt; &gt;                        
> &gt; &gt;                      
> &gt; &gt; 
> &gt; &gt; 发件人:"Paul E. McKenney"< paulmck@xxxxxxxxxx &gt;;
> &gt; &gt; 
> &gt; &gt; 发件时间:2022/10/6 19:57
> &gt; &gt; 
> &gt; &gt; 收件人:"5486"< 3164135486@xxxxxx &gt;;
> &gt; &gt; 
> &gt; &gt; 抄送人:"rcu"< rcu@xxxxxxxxxxxxxxx &gt;;
> &gt; &gt; 
> &gt; &gt; 主题:回复:Re:
> &gt; &gt; 
> &gt; &gt; 
> &gt; &gt; On Thu, Oct 06, 2022 at 05:56:35PM +0800, 5486 wrote:
> &gt; &gt; &gt; My problem is &nbsp;some grace period can take very little time shorter than the one iteration of on_each_cpu itself。So the complete() can execute on one cpu before the last of all. &nbsp;
> &gt; &gt; 
> &gt; &gt; And that is the bug.  Very good!
> &gt; &gt; 
> &gt; &gt; &gt; but now 
> &gt; &gt; &gt; The key is on_each_cpu &nbsp;,it is really clever that on_each_cpu &nbsp;will prevent completion of any grace periods. Concealed Mechanism!
> &gt; &gt; &gt; Is it?
> &gt; &gt; &gt; In this ancient version code have &nbsp;real race-condition bugs .I will take some time to study to find it and reply to you.
> &gt; &gt; &gt; it is about on_each_cpu have not prohibit preemption? ,I did not cover more things related to the operationg system.
> &gt; &gt; 
> &gt; &gt; Suppose the code instead read as follows?
> &gt; &gt; 
> &gt; &gt; void rcu_barrier(void)
> &gt; &gt; {
> &gt; &gt; 	BUG_ON(in_interrupt());
> &gt; &gt; 	/* Take cpucontrol semaphore to protect against CPU hotplug */
> &gt; &gt; 	down(&amp;rcu_barrier_sema);
> &gt; &gt; 	init_completion(&amp;rcu_barrier_completion);
> &gt; &gt; 	atomic_set(&amp;rcu_barrier_cpu_count, 1);
> &gt; &gt; 	on_each_cpu(rcu_barrier_func, NULL, 0, 1);
> &gt; &gt; 	if (atomic_dec_and_test(&amp;rcu_barrier_cpu_count))
> &gt; &gt; 		complete(&amp;rcu_barrier_completion);
> &gt; &gt; 	wait_for_completion(&amp;rcu_barrier_completion);
> &gt; &gt; 	up(&amp;rcu_barrier_sema);
> &gt; &gt; }
> &gt; &gt; 
> &gt; &gt; Would that work?  Or are there additional bugs?
> &gt; &gt; 
> &gt; &gt; 							Thanx, Paul
> &gt; &gt; 
> &gt; &gt; &gt; Chao,Li
> &gt; &gt; &gt; 
> &gt; &gt; &gt;                        
> &gt; &gt; &gt; 原始邮件
> &gt; &gt; &gt;                        
> &gt; &gt; &gt;                      
> &gt; &gt; &gt; 
> &gt; &gt; &gt; 发件人:"Paul E. McKenney"< paulmck@xxxxxxxxxx &gt;;
> &gt; &gt; &gt; 
> &gt; &gt; &gt; 发件时间:2022/10/5 21:01
> &gt; &gt; &gt; 
> &gt; &gt; &gt; 收件人:"5486"< 3164135486@xxxxxx &gt;;
> &gt; &gt; &gt; 
> &gt; &gt; &gt; 抄送人:"rcu"< rcu@xxxxxxxxxxxxxxx &gt;;
> &gt; &gt; &gt; 
> &gt; &gt; &gt; 主题:Re: Dear Pualmack help i have a problem with rcu code
> &gt; &gt; &gt; 
> &gt; &gt; &gt; 
> &gt; &gt; &gt; On Tue, Oct 04, 2022 at 03:04:19AM +0800, 5486 wrote:
> &gt; &gt; &gt; &gt; Dear&nbsp;Pualmack i have problem.
> &gt; &gt; &gt; &gt; I have been reading the patch
> &gt; &gt; &gt; &gt; https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/kernel?id=ab4720ec76b756e1f8705e207a7b392b0453afd6
> &gt; &gt; &gt; &gt; 
> &gt; &gt; &gt; &gt; 
> &gt; &gt; &gt; &gt; 
> &gt; &gt; &gt; &gt; +	wait_for_completion(&amp;rcu_barrier_completion);
> &gt; &gt; &gt; &gt; 
> &gt; &gt; &gt; &gt; How this guarantees all completes to be done ?
> &gt; &gt; &gt; &gt; I learn one wait_for_completion corresponds to one&nbsp;x-&gt;done++ once a time
> &gt; &gt; &gt; 
> &gt; &gt; &gt; 2005!  That takes me back a bit!
> &gt; &gt; &gt; 
> &gt; &gt; &gt; Adding the rcu email list on CC to archive this and for others to
> &gt; &gt; &gt; weigh in.
> &gt; &gt; &gt; 
> &gt; &gt; &gt; The trick is that rcu_barrier_callback() is an RCU callback that executes
> &gt; &gt; &gt; on each CPU (see the on_each_cpu() in the rcu_barrier() function.)
> &gt; &gt; &gt; 
> &gt; &gt; &gt; This RCU callback function is queued using call_rcu(), which queues
> &gt; &gt; &gt; that callback at the end of the CPU's callback list.  Thus, all
> &gt; &gt; &gt; RCU callback functions that were already queued on that CPU will
> &gt; &gt; &gt; be invoked before rcu_barrier_callback() in invoked.
> &gt; &gt; &gt; 
> &gt; &gt; &gt; The rcu_barrier_callback() does an atomic_dec_and_test() operation on the
> &gt; &gt; &gt; rcu_barrier_cpu_count global variable, and only when this variable becomes
> &gt; &gt; &gt; zero does it invoke complete().  This atomic_dec_and_test() operation is
> &gt; &gt; &gt; fully ordered, and thus ensures that all the earlier atomic_dec_and_test()
> &gt; &gt; &gt; operations on this variable are globally seen to happen before the last
> &gt; &gt; &gt; such operation (the one that decrements rcu_barrier_cpu_count to zero).
> &gt; &gt; &gt; 
> &gt; &gt; &gt; This last rcu_barrier_callback() will then invoke complete().  This will
> &gt; &gt; &gt; ensure that the wakeup in wait_for_completion() happens only after all
> &gt; &gt; &gt; previously queued RCU callbacks are invoked.
> &gt; &gt; &gt; 
> &gt; &gt; &gt; Almost, anyway.
> &gt; &gt; &gt; 
> &gt; &gt; &gt; There are rare but real race-condition bugs in this ancient version
> &gt; &gt; &gt; of rcu_barrier().  Can you tell me what they are?
> &gt; &gt; &gt; 
> &gt; &gt; &gt; 							Thanx, Paul





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux