Re: nd6 less kernel lock

2023-05-03 Thread Klemens Nanni
On Wed, May 03, 2023 at 12:22:16AM +0200, Alexander Bluhm wrote:
> Hi,
> 
> Some checks in nd6_resolve() do not require kernel lock.  The analog
> code for ARP has been unlocked in if_ether.c revision 1.250 since
> 2022/06/27 20:47:10.

Same diff here, thought I sent/committed that already.
OK kn if you want to go ahead, else I'll take an OK ;)

Soon (tm) the kernel lock will be replaced with the new nd6 mutex.

> 
> ok?
> 
> bluhm
> 
> Index: netinet6/nd6.c
> ===
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/nd6.c,v
> retrieving revision 1.273
> diff -u -p -r1.273 nd6.c
> --- netinet6/nd6.c2 May 2023 06:06:13 -   1.273
> +++ netinet6/nd6.c2 May 2023 18:44:23 -
> @@ -1260,15 +1260,12 @@ nd6_resolve(struct ifnet *ifp, struct rt
>   return (0);
>   }
>  
> - /* XXXSMP there is a MP race in nd6_resolve() */
> - KERNEL_LOCK();
>   uptime = getuptime();
>   rt = rt_getll(rt0);
>  
>   if (ISSET(rt->rt_flags, RTF_REJECT) &&
>   (rt->rt_expire == 0 || rt->rt_expire > uptime)) {
>   m_freem(m);
> - KERNEL_UNLOCK();
>   return (rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
>   }
>  
> @@ -1291,6 +1288,11 @@ nd6_resolve(struct ifnet *ifp, struct rt
>   goto bad;
>   }
>  
> + KERNEL_LOCK();
> + if (!ISSET(rt->rt_flags, RTF_LLINFO)) {
> + KERNEL_UNLOCK();
> + goto bad;
> + }
>   ln = (struct llinfo_nd6 *)rt->rt_llinfo;
>   KASSERT(ln != NULL);
>  
> @@ -1321,6 +1323,8 @@ nd6_resolve(struct ifnet *ifp, struct rt
>* send the packet.
>*/
>   if (ln->ln_state > ND6_LLINFO_INCOMPLETE) {
> + KERNEL_UNLOCK();
> +
>   sdl = satosdl(rt->rt_gateway);
>   if (sdl->sdl_alen != ETHER_ADDR_LEN) {
>   char addr[INET6_ADDRSTRLEN];
> @@ -1332,7 +1336,6 @@ nd6_resolve(struct ifnet *ifp, struct rt
>   }
>  
>   bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
> - KERNEL_UNLOCK();
>   return (0);
>   }
>  
> @@ -1374,7 +1377,6 @@ nd6_resolve(struct ifnet *ifp, struct rt
>  
>  bad:
>   m_freem(m);
> - KERNEL_UNLOCK();
>   return (EINVAL);
>  }
>  
> 



nd6 less kernel lock

2023-05-02 Thread Alexander Bluhm
Hi,

Some checks in nd6_resolve() do not require kernel lock.  The analog
code for ARP has been unlocked in if_ether.c revision 1.250 since
2022/06/27 20:47:10.

ok?

bluhm

Index: netinet6/nd6.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/nd6.c,v
retrieving revision 1.273
diff -u -p -r1.273 nd6.c
--- netinet6/nd6.c  2 May 2023 06:06:13 -   1.273
+++ netinet6/nd6.c  2 May 2023 18:44:23 -
@@ -1260,15 +1260,12 @@ nd6_resolve(struct ifnet *ifp, struct rt
return (0);
}
 
-   /* XXXSMP there is a MP race in nd6_resolve() */
-   KERNEL_LOCK();
uptime = getuptime();
rt = rt_getll(rt0);
 
if (ISSET(rt->rt_flags, RTF_REJECT) &&
(rt->rt_expire == 0 || rt->rt_expire > uptime)) {
m_freem(m);
-   KERNEL_UNLOCK();
return (rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
}
 
@@ -1291,6 +1288,11 @@ nd6_resolve(struct ifnet *ifp, struct rt
goto bad;
}
 
+   KERNEL_LOCK();
+   if (!ISSET(rt->rt_flags, RTF_LLINFO)) {
+   KERNEL_UNLOCK();
+   goto bad;
+   }
ln = (struct llinfo_nd6 *)rt->rt_llinfo;
KASSERT(ln != NULL);
 
@@ -1321,6 +1323,8 @@ nd6_resolve(struct ifnet *ifp, struct rt
 * send the packet.
 */
if (ln->ln_state > ND6_LLINFO_INCOMPLETE) {
+   KERNEL_UNLOCK();
+
sdl = satosdl(rt->rt_gateway);
if (sdl->sdl_alen != ETHER_ADDR_LEN) {
char addr[INET6_ADDRSTRLEN];
@@ -1332,7 +1336,6 @@ nd6_resolve(struct ifnet *ifp, struct rt
}
 
bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
-   KERNEL_UNLOCK();
return (0);
}
 
@@ -1374,7 +1377,6 @@ nd6_resolve(struct ifnet *ifp, struct rt
 
 bad:
m_freem(m);
-   KERNEL_UNLOCK();
return (EINVAL);
 }