On Tue, Dec 01, 2020 at 03:37, Vladimir Oltean <olte...@gmail.com> wrote: > On Mon, Nov 30, 2020 at 03:06:08PM +0100, Tobias Waldekranz wrote: >> +static void dsa_lag_release(struct kref *refcount) >> +{ >> + struct dsa_lag *lag = container_of(refcount, struct dsa_lag, refcount); >> + >> + rcu_assign_pointer(lag->dev, NULL); >> + synchronize_rcu(); >> + memset(lag, 0, sizeof(*lag)); >> +} > > What difference does it make if lag->dev is set to NULL right away or > after a grace period? Squeezing one last packet from that bonding interface? > Pointer updates are atomic operations on all architectures that the > kernel supports, and, as long as you use WRITE_ONCE and READ_ONCE memory > barriers, there should be no reason for RCU protection that I can see. > And unlike typical uses of RCU, you do not free lag->dev, because you do > not own lag->dev. Instead, the bonding interface pointed to by lag->dev > is going to be freed (in case of a deletion using ip link) after an RCU > grace period anyway. And the receive data path is under an RCU read-side > critical section anyway. So even if you set lag->dev to NULL using > WRITE_ONCE, the existing in-flight readers from the RX data path that > had called dsa_lag_dev_by_id() will still hold a reference to a valid > bonding interface.
I completely agree with your analysis. I will remove all the RCU primitives in v3. Thank you.