Re: push kernel lock inside ifioctl_get()
On Tue, Nov 08, 2022 at 08:31:16PM +0300, Vitaliy Makkoveev wrote: > No reason to keep kernel lock around if_clone_list() call. Yes, that is why I will remove it in the very next commit. This way there is one "move existing lock, make things clearer" and one "actually remove a lock for a specific code path" change.
Re: push kernel lock inside ifioctl_get()
No reason to keep kernel lock around if_clone_list() call. > On 8 Nov 2022, at 20:27, Klemens Nanni wrote: > > On Tue, Nov 08, 2022 at 08:04:16PM +0300, Vitaliy Makkoveev wrote: >> The `if_cloners’ list is immutable. You don't need kernel lock >> around if_clone_list() call. >> >>> case SIOCIFGCLONERS: >>> + KERNEL_LOCK(); >>> error = if_clone_list((struct if_clonereq *)data); >>> + KERNEL_UNLOCK(); >>> return (error); >> >> >> With this fix diff looks good for me. > > This is going the be first unlocking diff, I just want to clearly > separate setup churn (like this) from actual lock semantic changes. >
Re: push kernel lock inside ifioctl_get()
On Tue, Nov 08, 2022 at 04:47:23PM +, Martin Pieuchot wrote: > On 08/11/22(Tue) 15:28, Klemens Nanni wrote: > > After this mechanical move, I can unlock the individual SIOCG* in there. > > I'd suggest grabbing the KERNEL_LOCK() after NET_LOCK_SHARED(). > Otherwise you might spin for the first one then release it when going > to sleep. I can do that inside the first switch, but we must grab the net lock before if_unit() which is called before grabbing the shared net lock. I can shuffle this around if you really want, or I can simply move the existing kernel lock further down and keep it in the same order just like it is now already. > > > OK? > > > > Index: if.c > > === > > RCS file: /cvs/src/sys/net/if.c,v > > retrieving revision 1.667 > > diff -u -p -r1.667 if.c > > --- if.c8 Nov 2022 15:20:24 - 1.667 > > +++ if.c8 Nov 2022 15:26:07 - > > @@ -2426,33 +2426,43 @@ ifioctl_get(u_long cmd, caddr_t data) > > size_t bytesdone; > > const char *label; > > > > - KERNEL_LOCK(); > > - > > switch(cmd) { > > case SIOCGIFCONF: > > + KERNEL_LOCK(); > > NET_LOCK_SHARED(); > > error = ifconf(data); > > NET_UNLOCK_SHARED(); > > + KERNEL_UNLOCK(); > > return (error); > > case SIOCIFGCLONERS: > > + KERNEL_LOCK(); > > error = if_clone_list((struct if_clonereq *)data); > > + KERNEL_UNLOCK(); > > return (error); > > case SIOCGIFGMEMB: > > + KERNEL_LOCK(); > > NET_LOCK_SHARED(); > > error = if_getgroupmembers(data); > > NET_UNLOCK_SHARED(); > > + KERNEL_UNLOCK(); > > return (error); > > case SIOCGIFGATTR: > > + KERNEL_LOCK(); > > NET_LOCK_SHARED(); > > error = if_getgroupattribs(data); > > NET_UNLOCK_SHARED(); > > + KERNEL_UNLOCK(); > > return (error); > > case SIOCGIFGLIST: > > + KERNEL_LOCK(); > > NET_LOCK_SHARED(); > > error = if_getgrouplist(data); > > NET_UNLOCK_SHARED(); > > + KERNEL_UNLOCK(); > > return (error); > > } > > + > > + KERNEL_LOCK(); > > > > ifp = if_unit(ifr->ifr_name); > > if (ifp == NULL) { > > >
Re: push kernel lock inside ifioctl_get()
On Tue, Nov 08, 2022 at 08:04:16PM +0300, Vitaliy Makkoveev wrote: > The `if_cloners’ list is immutable. You don't need kernel lock > around if_clone_list() call. > > > case SIOCIFGCLONERS: > > + KERNEL_LOCK(); > > error = if_clone_list((struct if_clonereq *)data); > > + KERNEL_UNLOCK(); > > return (error); > > > With this fix diff looks good for me. This is going the be first unlocking diff, I just want to clearly separate setup churn (like this) from actual lock semantic changes.
Re: push kernel lock inside ifioctl_get()
The `if_cloners’ list is immutable. You don't need kernel lock around if_clone_list() call. > case SIOCIFGCLONERS: > + KERNEL_LOCK(); > error = if_clone_list((struct if_clonereq *)data); > + KERNEL_UNLOCK(); > return (error); With this fix diff looks good for me. > On 8 Nov 2022, at 18:28, Klemens Nanni wrote: > > After this mechanical move, I can unlock the individual SIOCG* in there. > > OK? > > Index: if.c > === > RCS file: /cvs/src/sys/net/if.c,v > retrieving revision 1.667 > diff -u -p -r1.667 if.c > --- if.c 8 Nov 2022 15:20:24 - 1.667 > +++ if.c 8 Nov 2022 15:26:07 - > @@ -2426,33 +2426,43 @@ ifioctl_get(u_long cmd, caddr_t data) > size_t bytesdone; > const char *label; > > - KERNEL_LOCK(); > - > switch(cmd) { > case SIOCGIFCONF: > + KERNEL_LOCK(); > NET_LOCK_SHARED(); > error = ifconf(data); > NET_UNLOCK_SHARED(); > + KERNEL_UNLOCK(); > return (error); > case SIOCIFGCLONERS: > + KERNEL_LOCK(); > error = if_clone_list((struct if_clonereq *)data); > + KERNEL_UNLOCK(); > return (error); > case SIOCGIFGMEMB: > + KERNEL_LOCK(); > NET_LOCK_SHARED(); > error = if_getgroupmembers(data); > NET_UNLOCK_SHARED(); > + KERNEL_UNLOCK(); > return (error); > case SIOCGIFGATTR: > + KERNEL_LOCK(); > NET_LOCK_SHARED(); > error = if_getgroupattribs(data); > NET_UNLOCK_SHARED(); > + KERNEL_UNLOCK(); > return (error); > case SIOCGIFGLIST: > + KERNEL_LOCK(); > NET_LOCK_SHARED(); > error = if_getgrouplist(data); > NET_UNLOCK_SHARED(); > + KERNEL_UNLOCK(); > return (error); > } > + > + KERNEL_LOCK(); > > ifp = if_unit(ifr->ifr_name); > if (ifp == NULL) { >
Re: push kernel lock inside ifioctl_get()
On 08/11/22(Tue) 15:28, Klemens Nanni wrote: > After this mechanical move, I can unlock the individual SIOCG* in there. I'd suggest grabbing the KERNEL_LOCK() after NET_LOCK_SHARED(). Otherwise you might spin for the first one then release it when going to sleep. > OK? > > Index: if.c > === > RCS file: /cvs/src/sys/net/if.c,v > retrieving revision 1.667 > diff -u -p -r1.667 if.c > --- if.c 8 Nov 2022 15:20:24 - 1.667 > +++ if.c 8 Nov 2022 15:26:07 - > @@ -2426,33 +2426,43 @@ ifioctl_get(u_long cmd, caddr_t data) > size_t bytesdone; > const char *label; > > - KERNEL_LOCK(); > - > switch(cmd) { > case SIOCGIFCONF: > + KERNEL_LOCK(); > NET_LOCK_SHARED(); > error = ifconf(data); > NET_UNLOCK_SHARED(); > + KERNEL_UNLOCK(); > return (error); > case SIOCIFGCLONERS: > + KERNEL_LOCK(); > error = if_clone_list((struct if_clonereq *)data); > + KERNEL_UNLOCK(); > return (error); > case SIOCGIFGMEMB: > + KERNEL_LOCK(); > NET_LOCK_SHARED(); > error = if_getgroupmembers(data); > NET_UNLOCK_SHARED(); > + KERNEL_UNLOCK(); > return (error); > case SIOCGIFGATTR: > + KERNEL_LOCK(); > NET_LOCK_SHARED(); > error = if_getgroupattribs(data); > NET_UNLOCK_SHARED(); > + KERNEL_UNLOCK(); > return (error); > case SIOCGIFGLIST: > + KERNEL_LOCK(); > NET_LOCK_SHARED(); > error = if_getgrouplist(data); > NET_UNLOCK_SHARED(); > + KERNEL_UNLOCK(); > return (error); > } > + > + KERNEL_LOCK(); > > ifp = if_unit(ifr->ifr_name); > if (ifp == NULL) { >
push kernel lock inside ifioctl_get()
After this mechanical move, I can unlock the individual SIOCG* in there. OK? Index: if.c === RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.667 diff -u -p -r1.667 if.c --- if.c8 Nov 2022 15:20:24 - 1.667 +++ if.c8 Nov 2022 15:26:07 - @@ -2426,33 +2426,43 @@ ifioctl_get(u_long cmd, caddr_t data) size_t bytesdone; const char *label; - KERNEL_LOCK(); - switch(cmd) { case SIOCGIFCONF: + KERNEL_LOCK(); NET_LOCK_SHARED(); error = ifconf(data); NET_UNLOCK_SHARED(); + KERNEL_UNLOCK(); return (error); case SIOCIFGCLONERS: + KERNEL_LOCK(); error = if_clone_list((struct if_clonereq *)data); + KERNEL_UNLOCK(); return (error); case SIOCGIFGMEMB: + KERNEL_LOCK(); NET_LOCK_SHARED(); error = if_getgroupmembers(data); NET_UNLOCK_SHARED(); + KERNEL_UNLOCK(); return (error); case SIOCGIFGATTR: + KERNEL_LOCK(); NET_LOCK_SHARED(); error = if_getgroupattribs(data); NET_UNLOCK_SHARED(); + KERNEL_UNLOCK(); return (error); case SIOCGIFGLIST: + KERNEL_LOCK(); NET_LOCK_SHARED(); error = if_getgrouplist(data); NET_UNLOCK_SHARED(); + KERNEL_UNLOCK(); return (error); } + + KERNEL_LOCK(); ifp = if_unit(ifr->ifr_name); if (ifp == NULL) {
push kernel lock into ifioctl_get()
Another mechanical diff without semantic changes to avoid churn in actual unlocking diffs. OK? Index: if.c === RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.666 diff -u -p -r1.666 if.c --- if.c8 Nov 2022 11:25:01 - 1.666 +++ if.c8 Nov 2022 13:53:27 - @@ -1979,9 +1979,7 @@ ifioctl(struct socket *so, u_long cmd, c case SIOCGIFRDOMAIN: case SIOCGIFGROUP: case SIOCGIFLLPRIO: - KERNEL_LOCK(); error = ifioctl_get(cmd, data); - KERNEL_UNLOCK(); return (error); } @@ -2428,6 +2426,8 @@ ifioctl_get(u_long cmd, caddr_t data) size_t bytesdone; const char *label; + KERNEL_LOCK(); + switch(cmd) { case SIOCGIFCONF: NET_LOCK_SHARED(); @@ -2455,8 +2455,10 @@ ifioctl_get(u_long cmd, caddr_t data) } ifp = if_unit(ifr->ifr_name); - if (ifp == NULL) + if (ifp == NULL) { + KERNEL_UNLOCK(); return (ENXIO); + } NET_LOCK_SHARED(); @@ -2527,6 +2529,8 @@ ifioctl_get(u_long cmd, caddr_t data) } NET_UNLOCK_SHARED(); + + KERNEL_UNLOCK(); if_put(ifp);