Move rtzone handling code to net/route_ctl.c

After moving the route control plane code from net/route.c,
 all rtzone users ended up being in net/route_ctl.c.
Move uma(9) rtzone setup/teardown code to net/route_ctl.c as well
 to have everything in a single place.

While here, remove custom initializers from the zone.
It was added originally to avoid setup/teardown of costy per-cpu couters.
With these counters removed, the only remaining job was avoiding rte mutex
 setup/teardown. Mutex setup is relatively cheap. Additionally, this mutex
 will soon be removed. With that in mind, there is no sense in keeping
 custom zone callbacks.

Differential Revision:	https://reviews.freebsd.org/D26051
This commit is contained in:
Alexander V. Chernikov 2020-08-13 18:35:29 +00:00
parent a459638fc4
commit 6cbadc4234
5 changed files with 81 additions and 107 deletions

View File

@ -122,14 +122,10 @@ VNET_DEFINE(struct rib_head *, rt_tables);
#define V_rt_tables VNET(rt_tables)
VNET_DEFINE(uma_zone_t, rtzone); /* Routing table UMA zone. */
#define V_rtzone VNET(rtzone)
EVENTHANDLER_LIST_DEFINE(rt_addrmsg);
static int rt_ifdelroute(const struct rtentry *rt, const struct nhop_object *,
void *arg);
static void destroy_rtentry_epoch(epoch_context_t ctx);
static int rt_exportinfo(struct rtentry *rt, struct rt_addrinfo *info,
int flags);
@ -207,43 +203,6 @@ route_init(void)
}
SYSINIT(route_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, route_init, NULL);
static int
rtentry_zinit(void *mem, int size, int how)
{
struct rtentry *rt = mem;
RT_LOCK_INIT(rt);
return (0);
}
static void
rtentry_zfini(void *mem, int size)
{
struct rtentry *rt = mem;
RT_LOCK_DESTROY(rt);
}
static int
rtentry_ctor(void *mem, int size, void *arg, int how)
{
struct rtentry *rt = mem;
bzero(rt, offsetof(struct rtentry, rt_endzero));
rt->rt_chain = NULL;
return (0);
}
static void
rtentry_dtor(void *mem, int size, void *arg)
{
struct rtentry *rt = mem;
RT_UNLOCK_COND(rt);
}
static void
vnet_route_init(const void *unused __unused)
{
@ -255,9 +214,7 @@ vnet_route_init(const void *unused __unused)
V_rt_tables = malloc(rt_numfibs * (AF_MAX+1) *
sizeof(struct rib_head *), M_RTABLE, M_WAITOK|M_ZERO);
V_rtzone = uma_zcreate("rtentry", sizeof(struct rtentry),
rtentry_ctor, rtentry_dtor,
rtentry_zinit, rtentry_zfini, UMA_ALIGN_PTR, 0);
vnet_rtzone_init();
for (dom = domains; dom; dom = dom->dom_next) {
if (dom->dom_rtattach == NULL)
continue;
@ -314,7 +271,7 @@ vnet_route_uninit(const void *unused __unused)
epoch_drain_callbacks(net_epoch_preempt);
free(V_rt_tables, M_RTABLE);
uma_zdestroy(V_rtzone);
vnet_rtzone_destroy();
}
VNET_SYSUNINIT(vnet_route_uninit, SI_SUB_PROTO_DOMAIN, SI_ORDER_FIRST,
vnet_route_uninit, 0);
@ -405,55 +362,6 @@ sys_setfib(struct thread *td, struct setfib_args *uap)
return (0);
}
/*
* Remove a reference count from an rtentry.
* If the count gets low enough, take it out of the routing table
*/
void
rtfree(struct rtentry *rt)
{
KASSERT(rt != NULL,("%s: NULL rt", __func__));
RT_LOCK_ASSERT(rt);
RT_UNLOCK(rt);
epoch_call(net_epoch_preempt, destroy_rtentry_epoch,
&rt->rt_epoch_ctx);
}
static void
destroy_rtentry(struct rtentry *rt)
{
/*
* At this moment rnh, nh_control may be already freed.
* nhop interface may have been migrated to a different vnet.
* Use vnet stored in the nexthop to delete the entry.
*/
CURVNET_SET(nhop_get_vnet(rt->rt_nhop));
/* Unreference nexthop */
nhop_free(rt->rt_nhop);
uma_zfree(V_rtzone, rt);
CURVNET_RESTORE();
}
/*
* Epoch callback indicating rtentry is safe to destroy
*/
static void
destroy_rtentry_epoch(epoch_context_t ctx)
{
struct rtentry *rt;
rt = __containerof(ctx, struct rtentry, rt_epoch_ctx);
destroy_rtentry(rt);
}
/*
* Adds a temporal redirect entry to the routing table.
* @fibnum: fib number

View File

@ -387,16 +387,7 @@ int rtsock_routemsg_info(int, struct rt_addrinfo *, int);
struct sockaddr *rtsock_fix_netmask(const struct sockaddr *dst,
const struct sockaddr *smask, struct sockaddr_storage *dmask);
/*
* Note the following locking behavior:
*
* rtfree() and RTFREE_LOCKED() require a locked rtentry
*
* RTFREE() uses an unlocked entry.
*/
void rtfree(struct rtentry *);
void rtfree_func(struct rtentry *);
void rt_updatemtu(struct ifnet *);
void rt_flushifroutes_af(struct ifnet *, int);

View File

@ -87,6 +87,77 @@ static void rib_notify(struct rib_head *rnh, enum rib_subscription_type type,
static void destroy_subscription_epoch(epoch_context_t ctx);
/* Routing table UMA zone */
VNET_DEFINE_STATIC(uma_zone_t, rtzone);
#define V_rtzone VNET(rtzone)
void
vnet_rtzone_init()
{
V_rtzone = uma_zcreate("rtentry", sizeof(struct rtentry),
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
}
#ifdef VIMAGE
void
vnet_rtzone_destroy()
{
uma_zdestroy(V_rtzone);
}
#endif
static void
destroy_rtentry(struct rtentry *rt)
{
/*
* At this moment rnh, nh_control may be already freed.
* nhop interface may have been migrated to a different vnet.
* Use vnet stored in the nexthop to delete the entry.
*/
CURVNET_SET(nhop_get_vnet(rt->rt_nhop));
/* Unreference nexthop */
nhop_free(rt->rt_nhop);
uma_zfree(V_rtzone, rt);
CURVNET_RESTORE();
}
/*
* Epoch callback indicating rtentry is safe to destroy
*/
static void
destroy_rtentry_epoch(epoch_context_t ctx)
{
struct rtentry *rt;
rt = __containerof(ctx, struct rtentry, rt_epoch_ctx);
destroy_rtentry(rt);
}
/*
* Schedule rtentry deletion
*/
static void
rtfree(struct rtentry *rt)
{
KASSERT(rt != NULL, ("%s: NULL rt", __func__));
RT_LOCK_ASSERT(rt);
RT_UNLOCK(rt);
epoch_call(net_epoch_preempt, destroy_rtentry_epoch,
&rt->rt_epoch_ctx);
}
static struct rib_head *
get_rnh(uint32_t fibnum, const struct rt_addrinfo *info)
{
@ -173,12 +244,13 @@ add_route(struct rib_head *rnh, struct rt_addrinfo *info,
return (error);
}
rt = uma_zalloc(V_rtzone, M_NOWAIT);
rt = uma_zalloc(V_rtzone, M_NOWAIT | M_ZERO);
if (rt == NULL) {
ifa_free(info->rti_ifa);
nhop_free(nh);
return (ENOBUFS);
}
RT_LOCK_INIT(rt);
rt->rt_flags = RTF_UP | flags;
rt->rt_nhop = nh;
@ -219,6 +291,7 @@ add_route(struct rib_head *rnh, struct rt_addrinfo *info,
RIB_WUNLOCK(rnh);
nhop_free(nh);
RT_LOCK_DESTROY(rt);
uma_zfree(V_rtzone, rt);
return (EEXIST);
}
@ -286,6 +359,7 @@ add_route(struct rib_head *rnh, struct rt_addrinfo *info,
*/
if (rn == NULL) {
nhop_free(nh);
RT_LOCK_DESTROY(rt);
uma_zfree(V_rtzone, rt);
return (EEXIST);
}

View File

@ -237,4 +237,8 @@ void tmproutes_update(struct rib_head *rnh, struct rtentry *rt);
void tmproutes_init(struct rib_head *rh);
void tmproutes_destroy(struct rib_head *rh);
/* route_ctl.c */
void vnet_rtzone_init(void);
void vnet_rtzone_destroy(void);
#endif

View File

@ -72,9 +72,6 @@ void rib_init_subscriptions(struct rib_head *rnh);
void rib_destroy_subscriptions(struct rib_head *rnh);
/* route */
VNET_DECLARE(uma_zone_t, rtzone); /* Routing table UMA zone. */
#define V_rtzone VNET(rtzone)
struct rtentry *rt_unlinkrte(struct rib_head *rnh, struct rt_addrinfo *info,
int *perror);