From 7bfa74bbb6da2894de8ba5b246100daec36c42e0 Mon Sep 17 00:00:00 2001 From: bluhm Date: Tue, 28 Jun 2022 10:01:13 +0000 Subject: [PATCH] Use refcnt API for struct rtentry instead of hand-crafted atomic operations. OK mvs@ --- regress/sys/net/rtable/kern_compat.h | 4 ++- sys/net/route.c | 46 ++++++++++++---------------- sys/net/route.h | 4 +-- sys/net/rtable.c | 6 ++-- sys/net/rtsock.c | 4 +-- 5 files changed, 30 insertions(+), 34 deletions(-) diff --git a/regress/sys/net/rtable/kern_compat.h b/regress/sys/net/rtable/kern_compat.h index 6515fe389f6..874e726de65 100644 --- a/regress/sys/net/rtable/kern_compat.h +++ b/regress/sys/net/rtable/kern_compat.h @@ -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)) diff --git a/sys/net/route.c b/sys/net/route.c index c9b83e892ba..bafadfd9e7c 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -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)); diff --git a/sys/net/route.h b/sys/net/route.h index 5692206e606..2178e401731 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -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 */ diff --git a/sys/net/rtable.c b/sys/net/rtable.c index a28b3cfe13b..6a5f022bef2 100644 --- a/sys/net/rtable.c +++ b/sys/net/rtable.c @@ -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); diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 7b4e544fced..fde6ec78565 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -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; -- 2.20.1