On Tue, 2017-08-01 at 19:49 -0700, Stephen Hemminger wrote: > Split the TCP congestion ops structure into const and mutable portions. > Put the list pointers, key and a copy of the flags in new tcp_congestion_entry > structure.
... > -void tcp_unregister_congestion_control(struct tcp_congestion_ops *ca) > +void tcp_unregister_congestion_control(const struct tcp_congestion_ops *ca) > { > + struct tcp_congestion_entry *e; > + > spin_lock(&tcp_cong_list_lock); > - list_del_rcu(&ca->list); > + list_for_each_entry_rcu(e, &tcp_cong_list, list) { > + if (e->ops == ca) { > + list_del_rcu(&e->list); > + kfree_rcu(e, rcu); > + break; > + } > + } > spin_unlock(&tcp_cong_list_lock); > Since you switched to kfree_rcu(), you could remove the synchronize_rcu() from tcp_unregister_congestion_control() Otherwise, no need for kfree_rcu() and the rcu head added in struct tcp_congestion_entry : - You could do a kfree() after the synchronize_rcu(). Also, I am not convinced this would be a good move, since you added an extra structure which is not const anyway.