Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[sfrench/cifs-2.6.git] / net / decnet / dn_route.c
index 4b9518a0d2489494ed88b6808f95803cf1b543ad..bcbe548f8854e103146932c0a7006b1ba04f3bfd 100644 (file)
@@ -183,17 +183,6 @@ static __inline__ unsigned int dn_hash(__le16 src, __le16 dst)
        return dn_rt_hash_mask & (unsigned int)tmp;
 }
 
-static inline void dnrt_free(struct dn_route *rt)
-{
-       call_rcu_bh(&rt->dst.rcu_head, dst_rcu_free);
-}
-
-static inline void dnrt_drop(struct dn_route *rt)
-{
-       dst_release(&rt->dst);
-       call_rcu_bh(&rt->dst.rcu_head, dst_rcu_free);
-}
-
 static void dn_dst_check_expire(unsigned long dummy)
 {
        int i;
@@ -208,14 +197,15 @@ static void dn_dst_check_expire(unsigned long dummy)
                spin_lock(&dn_rt_hash_table[i].lock);
                while ((rt = rcu_dereference_protected(*rtp,
                                                lockdep_is_held(&dn_rt_hash_table[i].lock))) != NULL) {
-                       if (atomic_read(&rt->dst.__refcnt) ||
-                                       (now - rt->dst.lastuse) < expire) {
+                       if (atomic_read(&rt->dst.__refcnt) > 1 ||
+                           (now - rt->dst.lastuse) < expire) {
                                rtp = &rt->dst.dn_next;
                                continue;
                        }
                        *rtp = rt->dst.dn_next;
                        rt->dst.dn_next = NULL;
-                       dnrt_free(rt);
+                       dst_dev_put(&rt->dst);
+                       dst_release(&rt->dst);
                }
                spin_unlock(&dn_rt_hash_table[i].lock);
 
@@ -241,14 +231,15 @@ static int dn_dst_gc(struct dst_ops *ops)
 
                while ((rt = rcu_dereference_protected(*rtp,
                                                lockdep_is_held(&dn_rt_hash_table[i].lock))) != NULL) {
-                       if (atomic_read(&rt->dst.__refcnt) ||
-                                       (now - rt->dst.lastuse) < expire) {
+                       if (atomic_read(&rt->dst.__refcnt) > 1 ||
+                           (now - rt->dst.lastuse) < expire) {
                                rtp = &rt->dst.dn_next;
                                continue;
                        }
                        *rtp = rt->dst.dn_next;
                        rt->dst.dn_next = NULL;
-                       dnrt_drop(rt);
+                       dst_dev_put(&rt->dst);
+                       dst_release(&rt->dst);
                        break;
                }
                spin_unlock_bh(&dn_rt_hash_table[i].lock);
@@ -350,7 +341,7 @@ static int dn_insert_route(struct dn_route *rt, unsigned int hash, struct dn_rou
                        dst_use(&rth->dst, now);
                        spin_unlock_bh(&dn_rt_hash_table[hash].lock);
 
-                       dnrt_drop(rt);
+                       dst_release_immediate(&rt->dst);
                        *rp = rth;
                        return 0;
                }
@@ -380,7 +371,8 @@ static void dn_run_flush(unsigned long dummy)
                for(; rt; rt = next) {
                        next = rcu_dereference_raw(rt->dst.dn_next);
                        RCU_INIT_POINTER(rt->dst.dn_next, NULL);
-                       dst_free((struct dst_entry *)rt);
+                       dst_dev_put(&rt->dst);
+                       dst_release(&rt->dst);
                }
 
 nothing_to_declare:
@@ -1187,7 +1179,7 @@ make_route:
        if (dev_out->flags & IFF_LOOPBACK)
                flags |= RTCF_LOCAL;
 
-       rt = dst_alloc(&dn_dst_ops, dev_out, 1, DST_OBSOLETE_NONE, DST_HOST);
+       rt = dst_alloc(&dn_dst_ops, dev_out, 0, DST_OBSOLETE_NONE, DST_HOST);
        if (rt == NULL)
                goto e_nobufs;
 
@@ -1221,6 +1213,7 @@ make_route:
                goto e_neighbour;
 
        hash = dn_hash(rt->fld.saddr, rt->fld.daddr);
+       /* dn_insert_route() increments dst->__refcnt */
        dn_insert_route(rt, hash, (struct dn_route **)pprt);
 
 done:
@@ -1243,7 +1236,7 @@ e_nobufs:
        err = -ENOBUFS;
        goto done;
 e_neighbour:
-       dst_free(&rt->dst);
+       dst_release_immediate(&rt->dst);
        goto e_nobufs;
 }
 
@@ -1451,7 +1444,7 @@ static int dn_route_input_slow(struct sk_buff *skb)
        }
 
 make_route:
-       rt = dst_alloc(&dn_dst_ops, out_dev, 0, DST_OBSOLETE_NONE, DST_HOST);
+       rt = dst_alloc(&dn_dst_ops, out_dev, 1, DST_OBSOLETE_NONE, DST_HOST);
        if (rt == NULL)
                goto e_nobufs;
 
@@ -1497,6 +1490,7 @@ make_route:
                goto e_neighbour;
 
        hash = dn_hash(rt->fld.saddr, rt->fld.daddr);
+       /* dn_insert_route() increments dst->__refcnt */
        dn_insert_route(rt, hash, &rt);
        skb_dst_set(skb, &rt->dst);
 
@@ -1520,7 +1514,7 @@ e_nobufs:
        goto done;
 
 e_neighbour:
-       dst_free(&rt->dst);
+       dst_release_immediate(&rt->dst);
        goto done;
 }