Use refcnt API for struct rtentry instead of hand-crafted atomic
authorbluhm <bluhm@openbsd.org>
Tue, 28 Jun 2022 10:01:13 +0000 (10:01 +0000)
committerbluhm <bluhm@openbsd.org>
Tue, 28 Jun 2022 10:01:13 +0000 (10:01 +0000)
operations.
OK mvs@

regress/sys/net/rtable/kern_compat.h
sys/net/route.c
sys/net/route.h
sys/net/rtable.c
sys/net/rtsock.c

index 6515fe3..874e726 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_compat.h,v 1.12 2021/04/13 08:21:12 claudio Exp $        */
+/*     $OpenBSD: kern_compat.h,v 1.13 2022/06/28 10:01:13 bluhm Exp $  */
 
 #ifndef _KERN_COMPAT_H_
 #define _KERN_COMPAT_H_
@@ -74,6 +74,8 @@ extern struct domain *domains[];
 #define rw_exit_write(rwl)
 #define rw_assert_wrlock(rwl)
 
+#define refcnt_read(cnt)       1
+
 #define SET(t, f)      ((t) |= (f))
 #define CLR(t, f)      ((t) &= ~(f))
 #define ISSET(t, f)    ((t) & (f))
index c9b83e8..bafadfd 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: route.c,v 1.411 2022/06/27 21:26:46 claudio Exp $     */
+/*     $OpenBSD: route.c,v 1.412 2022/06/28 10:01:13 bluhm Exp $       */
 /*     $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $      */
 
 /*
@@ -488,40 +488,34 @@ rt_putgwroute(struct rtentry *rt)
 void
 rtref(struct rtentry *rt)
 {
-       atomic_inc_int(&rt->rt_refcnt);
+       refcnt_take(&rt->rt_refcnt);
 }
 
 void
 rtfree(struct rtentry *rt)
 {
-       int              refcnt;
-
        if (rt == NULL)
                return;
 
-       refcnt = (int)atomic_dec_int_nv(&rt->rt_refcnt);
-       if (refcnt <= 0) {
-               KASSERT(!ISSET(rt->rt_flags, RTF_UP));
-               KASSERT(!RT_ROOT(rt));
-               atomic_dec_int(&rttrash);
-               if (refcnt < 0) {
-                       printf("rtfree: %p not freed (neg refs)\n", rt);
-                       return;
-               }
+       if (refcnt_rele(&rt->rt_refcnt) == 0)
+               return;
+
+       KASSERT(!ISSET(rt->rt_flags, RTF_UP));
+       KASSERT(!RT_ROOT(rt));
+       atomic_dec_int(&rttrash);
 
-               KERNEL_LOCK();
-               rt_timer_remove_all(rt);
-               ifafree(rt->rt_ifa);
-               rtlabel_unref(rt->rt_labelid);
+       KERNEL_LOCK();
+       rt_timer_remove_all(rt);
+       ifafree(rt->rt_ifa);
+       rtlabel_unref(rt->rt_labelid);
 #ifdef MPLS
-               rt_mpls_clear(rt);
+       rt_mpls_clear(rt);
 #endif
-               free(rt->rt_gateway, M_RTABLE, ROUNDUP(rt->rt_gateway->sa_len));
-               free(rt_key(rt), M_RTABLE, rt_key(rt)->sa_len);
-               KERNEL_UNLOCK();
+       free(rt->rt_gateway, M_RTABLE, ROUNDUP(rt->rt_gateway->sa_len));
+       free(rt_key(rt), M_RTABLE, rt_key(rt)->sa_len);
+       KERNEL_UNLOCK();
 
-               pool_put(&rtentry_pool, rt);
-       }
+       pool_put(&rtentry_pool, rt);
 }
 
 void
@@ -877,7 +871,7 @@ rtrequest(int req, struct rt_addrinfo *info, u_int8_t prio,
                        return (ENOBUFS);
                }
 
-               rt->rt_refcnt = 1;
+               refcnt_init(&rt->rt_refcnt);
                rt->rt_flags = info->rti_flags | RTF_UP;
                rt->rt_priority = prio; /* init routing priority */
                LIST_INIT(&rt->rt_timer);
@@ -1879,8 +1873,8 @@ db_show_rtentry(struct rtentry *rt, void *w, unsigned int id)
 {
        db_printf("rtentry=%p", rt);
 
-       db_printf(" flags=0x%x refcnt=%d use=%llu expire=%lld rtableid=%u\n",
-           rt->rt_flags, rt->rt_refcnt, rt->rt_use, rt->rt_expire, id);
+       db_printf(" flags=0x%x refcnt=%u use=%llu expire=%lld rtableid=%u\n",
+           rt->rt_flags, rt->rt_refcnt.r_refs, rt->rt_use, rt->rt_expire, id);
 
        db_printf(" key="); db_print_sa(rt_key(rt));
        db_printf(" plen=%d", rt_plen(rt));
index 5692206..2178e40 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: route.h,v 1.195 2022/06/27 21:26:46 claudio Exp $     */
+/*     $OpenBSD: route.h,v 1.196 2022/06/28 10:01:13 bluhm Exp $       */
 /*     $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $       */
 
 /*
@@ -121,7 +121,7 @@ struct rtentry {
        struct rt_kmetrics rt_rmx;      /* metrics used by rx'ing protocols */
        unsigned int     rt_ifidx;      /* the answer: interface to use */
        unsigned int     rt_flags;      /* up/down?, host/net */
-       int              rt_refcnt;     /* # held references */
+       struct refcnt    rt_refcnt;     /* # held references */
        int              rt_plen;       /* prefix length */
        uint16_t         rt_labelid;    /* route label ID */
        uint8_t          rt_priority;   /* routing priority to use */
index a28b3cf..6a5f022 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rtable.c,v 1.78 2022/06/27 17:15:35 bluhm Exp $ */
+/*     $OpenBSD: rtable.c,v 1.79 2022/06/28 10:01:13 bluhm Exp $ */
 
 /*
  * Copyright (c) 2014-2016 Martin Pieuchot
@@ -681,7 +681,7 @@ rtable_delete(unsigned int rtableid, struct sockaddr *dst,
                npaths++;
 
        if (npaths > 1) {
-               KASSERT(rt->rt_refcnt >= 1);
+               KASSERT(refcnt_read(&rt->rt_refcnt) >= 1);
                SRPL_REMOVE_LOCKED(&rt_rc, &an->an_rtlist, rt, rtentry,
                    rt_next);
 
@@ -695,7 +695,7 @@ rtable_delete(unsigned int rtableid, struct sockaddr *dst,
        if (art_delete(ar, an, addr, plen) == NULL)
                panic("art_delete failed to find node %p", an);
 
-       KASSERT(rt->rt_refcnt >= 1);
+       KASSERT(refcnt_read(&rt->rt_refcnt) >= 1);
        SRPL_REMOVE_LOCKED(&rt_rc, &an->an_rtlist, rt, rtentry, rt_next);
        art_put(an);
 
index 7b4e544..fde6ec7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rtsock.c,v 1.333 2022/06/27 21:26:46 claudio Exp $    */
+/*     $OpenBSD: rtsock.c,v 1.334 2022/06/28 10:01:13 bluhm Exp $      */
 /*     $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $  */
 
 /*
@@ -2003,7 +2003,7 @@ sysctl_dumpentry(struct rtentry *rt, void *v, unsigned int id)
                rtm->rtm_priority = rt->rt_priority & RTP_MASK;
                rtm_getmetrics(rt, &rtm->rtm_rmx);
                /* Do not account the routing table's reference. */
-               rtm->rtm_rmx.rmx_refcnt = rt->rt_refcnt - 1;
+               rtm->rtm_rmx.rmx_refcnt = refcnt_read(&rt->rt_refcnt) - 1;
                rtm->rtm_index = rt->rt_ifidx;
                rtm->rtm_addrs = info.rti_addrs;
                rtm->rtm_tableid = id;