On Wed, 30 Aug 2006 03:21:26 +0400
Alexey Kuznetsov <[EMAIL PROTECTED]> wrote:

> Hello!
> 
> > This should not be any more racy than the existing code.
> 
> Existing code is not racy.

Race 1: w/o RCU
                                        Cpu 0: is in neigh_lookup
                                                gets read_lock()
                                                finds entry
                                                ++refcount to 2
                                                updates it
        Cpu 1: is in forced_gc()
                waits at write_lock()
                                                releases read_lock()
                                                drops ref count to 1.
                sees ref count is 1
                deletes it

Race 1: w RCU
                                        Cpu 0: is in __neigh_lookup
                                                updates it
        Cpu 1: is in forced_gc()
                                                leaves refcount=1
                sees ref count is 1
                deletes it


> 
> Critical place is interpretation of refcnt==1. Current code assumes,
> that when refcnt=1 and entry is in hash table, nobody can take this
> entry (table is locked). So, it can be unlinked from the table.
> 
> See? __neigh_lookup()/__neigh_lookup_errno() _MUST_ return alive
> and hashed entry. And will stay hashed until the reference is held.
> Or until neigh entry is forced for destruction by device going down,
> in this case referring dst entries will die as well.

Why must it be hashed, it could always get zapped just after the update.

> If dst cache grabs an entry, which is purged from table because for some
> time it had refcnt==1, you got a valid dst entry referring to dead
> neighbour entry.

Hmm.. Since this is a slow path, grabbing the write_lock on the neighbour
entry would block the gc from zapping it.

in __neigh_lookup()
                neigh_hold();
                write_lock(&n->lock);
                if (n->dead) {
                        write_unlock()
                        neigh_release()
                        goto rescan;
                }

                write_unlock()





-- 
Stephen Hemminger <[EMAIL PROTECTED]>
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to