On 4/24/2025 10:44 AM, Paul E. McKenney wrote:
> On Thu, Apr 24, 2025 at 09:54:14AM +0300, Dan Carpenter wrote:
>> On Wed, Apr 23, 2025 at 05:41:37PM -0700, Paul E. McKenney wrote:
>>> On Wed, Apr 23, 2025 at 10:19:56AM +0300, Dan Carpenter wrote:
>>>> On Wed, Apr 23, 2025 at 10:17:16AM +0300, Dan Carpenter wrote:
>>>>> Hello Joel Fernandes,
>>>>>
>>>>> Commit bd57ec707441 ("rcutorture: Perform more frequent testing of
>>>>> ->gpwrap") from Feb 16, 2025 (linux-next), leads to the following
>>>>> Smatch static checker warning:
>>>>>
>>>>>   kernel/rcu/rcutorture.c:4586 rcu_torture_init()
>>>>>   warn: missing error code 'firsterr'
>>>>>
>>>>> kernel/rcu/rcutorture.c
>>>>>     4576                 if (torture_init_error(firsterr))
>>>>>     4577                         goto unwind;
>>>>>     4578         }
>>>>>     4579         if (object_debug)
>>>>>     4580                 rcu_test_debug_objects();
>>>>>     4581         torture_init_end();
>>>>                    ^^^^^^^^^^^^^^^^^^^
>>>> Also:
>>>>
>>>> kernel/rcu/rcutorture.c:4591 rcu_torture_init() warn: double unlock 
>>>> 'global &fullstop_mutex' (orig line 4581)
>>>
>>> You lost me on this one.  This mutex is acquired by the earlier call to
>>> torture_init_begin(), but only if that function returns true.  If that
>>> function returns false, yes, it releases fullstop_mutex, but in that case
>>> rcu_torture_init() returns immediately, thus avoiding this invocation
>>> of torture_init_end().
>>>
>>> Or am I missing something subtle here?  Or missing something obvious,
>>> for that matter!  ;-)
>>>
>>
>> I explained it badly.  Joel's patch added a goto so now we call
>> torture_init_end() twice in a row.
>>
>>>                                                     Thanx, Paul
>>>
>>>>>     4582         if (cur_ops->gp_slow_register && 
>>>>> !WARN_ON_ONCE(!cur_ops->gp_slow_unregister))
>>>>>     4583                 cur_ops->gp_slow_register(&rcu_fwd_cb_nodelay);
>>>>>     4584 
>>>>>     4585         if (cur_ops->set_gpwrap_lag && rcu_gpwrap_lag_init())
>>>>> --> 4586                 goto unwind;
>>>>>
>>>>> set an error code?
>>
>> Here is the goto.
>>
>>>>>
>>>>>     4587 
>>>>>     4588         return 0;
>>>>>     4589 
>>>>>     4590 unwind:
>>>>>     4591         torture_init_end();
>>>>                    ^^^^^^^^^^^^^^^^^^^
>>
>> Here is the second torture_init_end().
> 
> Ah!  Thank you for persisting.  Over to you, Joel!

Oops, thanks for finding both the issues. I will move the torture_init_end()
further down and run some tests. At first look, that seems like the right thing
to do:

diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
index 92e2686a4795..bb9a8e718533 100644
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -4582,13 +4582,17 @@ rcu_torture_init(void)
        }
        if (object_debug)
                rcu_test_debug_objects();
-       torture_init_end();
+
        if (cur_ops->gp_slow_register &&
!WARN_ON_ONCE(!cur_ops->gp_slow_unregister))
                cur_ops->gp_slow_register(&rcu_fwd_cb_nodelay);

-       if (gpwrap_lag && cur_ops->set_gpwrap_lag && rcu_gpwrap_lag_init())
-               goto unwind;
+       if (gpwrap_lag && cur_ops->set_gpwrap_lag) {
+               firsterr = rcu_gpwrap_lag_init();
+               if (torture_init_error(firsterr))
+                       goto unwind;
+       }

+       torture_init_end();
        return 0;

 unwind:

Reply via email to