Hello, On Tue, 30 May 2017, Sowmini Varadhan wrote:
> @@ -1650,6 +1689,7 @@ static int neigh_delete(struct sk_buff *skb, struct > nlmsghdr *nlh, > NEIGH_UPDATE_F_ADMIN, > NETLINK_CB(skb).portid); > neigh_release(neigh); > + neigh_remove_one(neigh, tbl); So, we do not hold reference to neigh while accessing its fields. I suspect we need to move the table lock from neigh_remove_one here, for example: + write_lock_bh(&tbl->lock); neigh_release(neigh); + neigh_remove_one(neigh, tbl); + write_unlock_bh(&tbl->lock); Otherwise, neigh_forced_gc can call neigh_destroy where neigh is freed (and replaced by another neigh entry) after RCU grace period (which can end prematurely if there are no running RCU read-side critical sections) and I'm not sure if our thread can be delayed, so that such pointer replacement can happen unnoticed by us. Another solution to cause faster removal would be to cancel the gc_work and to schedule it after 1 jiffie. It helps when many entries are deleted at once but the work prefers to just sleep when gc_thresh1 is not reached, so such solution is not good enough. Regards -- Julian Anastasov <j...@ssi.bg>