On Tue, Aug 25, 2020 at 12:45:43PM -0400, Stephen Smalley wrote: > On Tue, Aug 25, 2020 at 11:20 AM Ondrej Mosnacek <omosnace@xxxxxxxxxx> wrote: > > > > Instead of holding the RCU read lock the whole time while accessing the > > policy, add a simple refcount mechanism to track its lifetime. After > > this, the RCU read lock is held only for a brief time when fetching the > > policy pointer and incrementing the refcount. The policy struct is then > > guaranteed to stay alive until the refcount is decremented. > > > > Freeing of the policy remains the responsibility of the task that does > > the policy reload. In case the refcount drops to zero in a different > > task, the policy load task is notified via a completion. > > That's an interesting pattern. Is this approach used anywhere else in > the kernel? I didn't see any examples of it in the RCU documentation. The function txopt_get() in include/net/ipv6.h uses something quite similar. By convention, rcu_pointer_handoff() is (sometimes) used to indicate that the pointer is now protected by something other than RCU, as shown in that function. And grepping for rcu_pointer_handoff() can find you a few more. Thanx, Paul > > The advantage of this change is that the operations that access the > > policy can now do sleeping allocations, since they don't need to hold > > the RCU read lock anymore. This patch so far only leverages this in > > security_read_policy() for the vmalloc_user() allocation (although this > > function is always called under fsi->mutex and could just access the > > policy pointer directly). The conversion of affected GFP_ATOMIC > > allocations to GFP_KERNEL is left for a later patch, since auditing > > which code paths may still need GFP_ATOMIC is not very easy. > > Technically we don't need this patch for that purpose because > rcu_read_lock() isn't actually needed at all in > security_read_policy(), so I think we're better off just getting rid > of it there and letting it use rcu_dereference_check(..., 1) or > rcu_dereference_protected() instead.