Re: xfrm_state locking regression...
From: David Miller <davem@davemloft.net>
Date: 2008-09-09 00:09:14
From: Herbert Xu <herbert@gondor.apana.org.au> Date: Fri, 5 Sep 2008 21:55:07 +1000
quoted hunk ↗ jump to hunk
@@ -403,17 +408,23 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x) static void xfrm_state_gc_task(struct work_struct *data) { - struct xfrm_state *x; - struct hlist_node *entry, *tmp; - struct hlist_head gc_list; + struct xfrm_state *x, *tmp; + static LIST_HEAD(gc_list); + unsigned long completed; spin_lock_bh(&xfrm_state_gc_lock); - gc_list.first = xfrm_state_gc_list.first; - INIT_HLIST_HEAD(&xfrm_state_gc_list); + list_splice_tail_init(&xfrm_state_gc_list, &gc_list); spin_unlock_bh(&xfrm_state_gc_lock); - hlist_for_each_entry_safe(x, entry, tmp, &gc_list, bydst) + mutex_lock(&xfrm_cfg_mutex); + completed = xfrm_state_walk_completed; + mutex_unlock(&xfrm_cfg_mutex); + + list_for_each_entry_safe(x, tmp, &gc_list, gclist) { + if ((long)(x->lastused - completed) > 0) + break; xfrm_state_gc_destroy(x); + } wake_up(&km_waitq); }
What happens to all of the entries on the local gc_list which you will be skipping when you break out of that last loop? It looks like they will never get processed.