On Tue, 2023-04-04 at 10:37 +0800, Ping-Ke Shih wrote: > On Mon, 2023-04-03 at 13:32 +0300, Kalle Valo wrote: > > I would expect that there's polling if you are waiting something from > > hardware, or maybe when implementing a spin lock, but not when waiting > > for another kernel thread. This just doesn't feel right but I don't have > > time to propose a good alternative either, sorry. > > > > I have found a solution that uses an owner variable with a spin lock > to determine which side to free completion object. Simply show two use > cases below: > > Use case 1: (normal case; free completion object by work 1) > work 1 work 2 > wait > (spin_lock) > complete > check & set owner --> owner = work1 > (spin_unlock) > wait ok > (spin_lock) > check & check owner --> free by work 1 > (spin_unlock) > free completion > > > Use case 2: (timeout case; free completion object by work 2) > work 1 work 2 > wait > wait timeout > (spin_lock) > check & set owner --> owner = work 2 > (spin_unlock) > (spin_lock) > completion > check & set owner --> free by work 2 > (spin_unlock) > free completion > > I will apply this by v5. > We have a better idea that use kfree_rcu() to free completion, so no need spin_lock(). Then, the use cases become below, and I have sent this change by v6. Use case 1: (normal case) work 1 work 2 (rcu_assign_pointer(wait)) wait (rcu_read_lock) wait = rcu_dereference(); if (wait) --> wait != NULL complete (rcu_read_unlock) wait ok (rcu_assign_pointer(NULL)) kfree_rcu(completion) Use case 2: (timeout case) work 1 work 2 (rcu_assign_pointer(wait)) wait wait timeout (rcu_assign_pointer(NULL)) kfree_rcu(completion) (rcu_read_lock) wait = rcu_dereference(); if (wait) --> wait == NULL complete (rcu_read_unlock) Ping-Ke