Re: xfrm_state locking regression...
From: Timo Teräs <hidden>
Date: 2008-09-21 15:21:32
Timo Teräs wrote:
Herbert Xu wrote:quoted
On Mon, Sep 08, 2008 at 05:25:13PM -0700, David Miller wrote: I've avoided the memory barrier by simply extending the mutexed section in the GC to cover the list splicing. Here's the updated patch: ipsec: Use RCU-like construct for saved state within a walk Now that we save states within a walk we need synchronisation so that the list the saved state is on doesn't disappear from under us. As it stands this is done by keeping the state on the list which is bad because it gets in the way of the management of the state life-cycle. An alternative is to make our own pseudo-RCU system where we use counters to indicate which state can't be freed immediately as it may be referenced by an ongoing walk when that resumes.Does not this logic fail if: 1. completed = ongoing 2. 1st walk started and iterator kept (a->lastused = ongoing, ongoing++) 3. 2nd walk started and iterator kept (b->lastused = ongoing, ongoing++) 4. 2nd walk finished (completed++) 5. gc triggered: a gets deleted since a->lastused == completed 6. 1st walk continued but freed memory accessed as a was deleted Though currently it does not affect, since xfrm_state_hold/_put are still called when keeping the iterator, so the entries won't actually get garbage collected anyway. So the completed/ongoing counting is basically useless. Or am I missing something?
Obviously I missed the fact that it prevents deletion of the entries which the iterator held list node might still point to. But the flaw still exists: the entries which interator->next points can be deleted if there is a walking that takes a long time and meanwhile we get walks that complete fast.
Wouldn't it be enough to do the list_del_rcu on delete? And just keep reference as previously?
So if we do list_del_rcu() on delete, could we also xfrm_state_hold() the entry pointed to by that list entry. And then on GC we could xfrm_state_put() the next entry. - Timo