Re: [PATCH ovpn net v5 6/6] ovpn: defer key slot crypto freeing to workqueue

Sabrina Dubroca <[email protected]> Tue, 28 Jul 2026 12:44:40 +0200
Newsgroups gmane.network.openvpn.devel
Message-ID <amiIGDgDhnc8ntZ9@krikkit>
2026-07-08, 17:30:49 +0200, Ralf Lici wrote:
> On Wed, 08 Jul 2026 12:14:08 +0200, Sabrina Dubroca <[email protected]> wrote:
> > Am I making any sense? (it's quite possible I need another 3 cups of
> > coffee for this type of reasoning :))
> >
> 
> Yes, definitely it makes sense.
> 
> I went through the ovpn_wq producers:
> - ovpn->keepalive_work: disabled from ovpn_net_uninit before peers are
>   freed;
> - peer->keepalive_work: queued by the scanner, it holds a peer reference
>   and can indirectly hit the TCP deferred-delete path through TX
>   failure;
> - peer->tcp.defer_del_work: queued from TCP RX/TX error paths, each
>   successfully queued instance owns a peer reference and peer release
>   drops crypto state before dropping the netdev reference;
> - sock->tcp_tx_work: queued from TCP write_space, socket teardown
>   cancels it;
> - key-slot free work/rcu_work: queued from final key-slot put.
> 
> So after rtnl_link_unregister has returned, I don't see a peer-owned
> producer that can create new key-slot rcu_work without first holding a
> peer reference that would have kept unregister_netdevice waiting. Then

All those objects referencing each other make it really hard to reason
about correctness :/

> flush_workqueue waits for the remaining worker tails that may still be
> executing module text. After that, rcu_barrier forces pending rcu_work
> callbacks to queue their actual work, and destroy_workqueue drains that
> cleanup work before module text goes away.
> 
> So the ordering I'd use with queue_rcu_work is:
> 
>     ovpn_nl_unregister();
>     rtnl_link_unregister(&ovpn_link_ops);
>     flush_workqueue(ovpn_wq);
>     rcu_barrier();
>     destroy_workqueue(ovpn_wq);
> 
> Makes sense?
> 
> Avoiding work on deleted peers is nice cleanup, but I don't think the
> unload safety depends on it because the stronger invariant is that any
> peer-owned work that can queue more work either already owns a peer ref
> or takes one before queueing.
> 
> WDYT?

All this looks correct. Thanks.

-- 
Sabrina