Module Name: src Committed By: ozaki-r Date: Tue Feb 21 03:58:24 UTC 2017
Modified Files: src/sys/netinet: if_arp.c if_inarp.h src/sys/netinet6: nd6_nbr.c Log Message: Replace malloc for DAD with kmem and move them out of the lock for DAD To generate a diff of this commit: cvs rdiff -u -r1.242 -r1.243 src/sys/netinet/if_arp.c cvs rdiff -u -r1.50 -r1.51 src/sys/netinet/if_inarp.h cvs rdiff -u -r1.136 -r1.137 src/sys/netinet6/nd6_nbr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/netinet/if_arp.c diff -u src/sys/netinet/if_arp.c:1.242 src/sys/netinet/if_arp.c:1.243 --- src/sys/netinet/if_arp.c:1.242 Sat Feb 11 15:37:30 2017 +++ src/sys/netinet/if_arp.c Tue Feb 21 03:58:23 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: if_arp.c,v 1.242 2017/02/11 15:37:30 roy Exp $ */ +/* $NetBSD: if_arp.c,v 1.243 2017/02/21 03:58:23 ozaki-r Exp $ */ /*- * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc. @@ -68,7 +68,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.242 2017/02/11 15:37:30 roy Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.243 2017/02/21 03:58:23 ozaki-r Exp $"); #ifdef _KERNEL_OPT #include "opt_ddb.h" @@ -84,7 +84,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1 #include <sys/param.h> #include <sys/systm.h> #include <sys/callout.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/mbuf.h> #include <sys/socket.h> #include <sys/time.h> @@ -1515,7 +1515,6 @@ struct dadq { int dad_arp_acount; /* # of announcements */ struct callout dad_timer_ch; }; -MALLOC_JUSTDEFINE(M_IPARP, "ARP DAD", "ARP DAD Structure"); static struct dadq_head dadq; static int dad_init = 0; @@ -1613,14 +1612,17 @@ arp_dad_start(struct ifaddr *ifa) if (!(ifa->ifa_ifp->if_flags & IFF_UP)) return; + dp = kmem_intr_alloc(sizeof(*dp), KM_NOSLEEP); + mutex_enter(&arp_dad_lock); if (arp_dad_find(ifa) != NULL) { mutex_exit(&arp_dad_lock); /* DAD already in progress */ + if (dp != NULL) + kmem_intr_free(dp, sizeof(*dp)); return; } - dp = malloc(sizeof(*dp), M_IPARP, M_NOWAIT); if (dp == NULL) { mutex_exit(&arp_dad_lock); log(LOG_ERR, "%s: memory allocation failed for %s(%s)\n", @@ -1628,13 +1630,12 @@ arp_dad_start(struct ifaddr *ifa) ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); return; } - memset(dp, 0, sizeof(*dp)); - callout_init(&dp->dad_timer_ch, CALLOUT_MPSAFE); /* * Send ARP packet for DAD, ip_dad_count times. * Note that we must delay the first transmission. */ + callout_init(&dp->dad_timer_ch, CALLOUT_MPSAFE); dp->dad_ifa = ifa; ifaref(ifa); /* just for safety */ dp->dad_count = ip_dad_count; @@ -1675,8 +1676,7 @@ arp_dad_stop(struct ifaddr *ifa) arp_dad_stoptimer(dp); - free(dp, M_IPARP); - dp = NULL; + kmem_intr_free(dp, sizeof(*dp)); ifafree(ifa); } @@ -1686,6 +1686,7 @@ arp_dad_timer(struct ifaddr *ifa) struct in_ifaddr *ia = (struct in_ifaddr *)ifa; struct dadq *dp; char ipbuf[INET_ADDRSTRLEN]; + bool need_free = false; #ifndef NET_MPSAFE mutex_enter(softnet_lock); @@ -1723,9 +1724,7 @@ arp_dad_timer(struct ifaddr *ifa) if_name(ifa->ifa_ifp)); TAILQ_REMOVE(&dadq, dp, dad_list); - free(dp, M_IPARP); - dp = NULL; - ifafree(ifa); + need_free = true; goto done; } @@ -1774,12 +1773,15 @@ announce: } TAILQ_REMOVE(&dadq, dp, dad_list); - free(dp, M_IPARP); - dp = NULL; - ifafree(ifa); - + need_free = true; done: mutex_exit(&arp_dad_lock); + + if (need_free) { + kmem_intr_free(dp, sizeof(*dp)); + ifafree(ifa); + } + #ifndef NET_MPSAFE KERNEL_UNLOCK_ONE(NULL); mutex_exit(softnet_lock); Index: src/sys/netinet/if_inarp.h diff -u src/sys/netinet/if_inarp.h:1.50 src/sys/netinet/if_inarp.h:1.51 --- src/sys/netinet/if_inarp.h:1.50 Tue Oct 11 12:32:30 2016 +++ src/sys/netinet/if_inarp.h Tue Feb 21 03:58:24 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: if_inarp.h,v 1.50 2016/10/11 12:32:30 roy Exp $ */ +/* $NetBSD: if_inarp.h,v 1.51 2017/02/21 03:58:24 ozaki-r Exp $ */ /* * Copyright (c) 1982, 1986, 1993 @@ -69,9 +69,6 @@ struct sockaddr_inarp { #define RATE_LIMIT_INTERVAL 60 #define DEFEND_INTERVAL 10 -#include <sys/malloc.h> -MALLOC_DECLARE(M_IPARP); - extern struct ifqueue arpintrq; void arp_ifinit(struct ifnet *, struct ifaddr *); void arp_rtrequest(int, struct rtentry *, const struct rt_addrinfo *); Index: src/sys/netinet6/nd6_nbr.c diff -u src/sys/netinet6/nd6_nbr.c:1.136 src/sys/netinet6/nd6_nbr.c:1.137 --- src/sys/netinet6/nd6_nbr.c:1.136 Mon Jan 16 15:44:47 2017 +++ src/sys/netinet6/nd6_nbr.c Tue Feb 21 03:58:24 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: nd6_nbr.c,v 1.136 2017/01/16 15:44:47 christos Exp $ */ +/* $NetBSD: nd6_nbr.c,v 1.137 2017/02/21 03:58:24 ozaki-r Exp $ */ /* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */ /* @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.136 2017/01/16 15:44:47 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.137 2017/02/21 03:58:24 ozaki-r Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -40,7 +40,7 @@ __KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v #include <sys/param.h> #include <sys/systm.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/mbuf.h> #include <sys/socket.h> #include <sys/socketvar.h> @@ -1154,14 +1154,17 @@ nd6_dad_start(struct ifaddr *ifa, int xt if (!(ifa->ifa_ifp->if_flags & IFF_UP)) return; + dp = kmem_intr_alloc(sizeof(*dp), KM_NOSLEEP); + mutex_enter(&nd6_dad_lock); if (nd6_dad_find(ifa) != NULL) { mutex_exit(&nd6_dad_lock); /* DAD already in progress */ + if (dp != NULL) + kmem_intr_free(dp, sizeof(*dp)); return; } - dp = malloc(sizeof(*dp), M_IP6NDP, M_NOWAIT); if (dp == NULL) { mutex_exit(&nd6_dad_lock); log(LOG_ERR, "nd6_dad_start: memory allocation failed for " @@ -1170,8 +1173,6 @@ nd6_dad_start(struct ifaddr *ifa, int xt ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); return; } - memset(dp, 0, sizeof(*dp)); - callout_init(&dp->dad_timer_ch, CALLOUT_MPSAFE); /* * Send NS packet for DAD, ip6_dad_count times. @@ -1179,6 +1180,7 @@ nd6_dad_start(struct ifaddr *ifa, int xt * first packet to be sent from the interface after interface * (re)initialization. */ + callout_init(&dp->dad_timer_ch, CALLOUT_MPSAFE); dp->dad_ifa = ifa; ifaref(ifa); /* just for safety */ dp->dad_count = ip6_dad_count; @@ -1223,8 +1225,7 @@ nd6_dad_stop(struct ifaddr *ifa) nd6_dad_stoptimer(dp); - free(dp, M_IP6NDP); - dp = NULL; + kmem_intr_free(dp, sizeof(*dp)); ifafree(ifa); } @@ -1235,6 +1236,7 @@ nd6_dad_timer(struct ifaddr *ifa) struct dadq *dp; int duplicate = 0; char ip6buf[INET6_ADDRSTRLEN]; + bool need_free = false; #ifndef NET_MPSAFE mutex_enter(softnet_lock); @@ -1273,9 +1275,7 @@ nd6_dad_timer(struct ifaddr *ifa) if_name(ifa->ifa_ifp)); TAILQ_REMOVE(&dadq, dp, dad_list); - free(dp, M_IP6NDP); - dp = NULL; - ifafree(ifa); + need_free = true; goto done; } @@ -1322,15 +1322,18 @@ nd6_dad_timer(struct ifaddr *ifa) IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr)); TAILQ_REMOVE(&dadq, dp, dad_list); - free(dp, M_IP6NDP); - dp = NULL; - ifafree(ifa); + need_free = true; } } - done: mutex_exit(&nd6_dad_lock); + if (need_free) { + kmem_intr_free(dp, sizeof(*dp)); + ifafree(ifa); + ifa = NULL; + } + if (duplicate) nd6_dad_duplicated(ifa); @@ -1413,8 +1416,7 @@ nd6_dad_duplicated(struct ifaddr *ifa) TAILQ_REMOVE(&dadq, dp, dad_list); mutex_exit(&nd6_dad_lock); - free(dp, M_IP6NDP); - dp = NULL; + kmem_intr_free(dp, sizeof(*dp)); ifafree(ifa); }