On Sat, Feb 06, 2021 at 05:58:35PM +0300, Vitaliy Makkoveev wrote:
> I???m not sure it should be atomic. It seems groups require their own
> lock and this lock should be held while we perform if_addgroup() and
> if_delgroup().

I also think that atomic refcounting is not needed here.  But it
does no harm as adding interface groups is not performance critical.

Question is if we want to use refcnt_... API even if it does more
than required.  Or should we go with a self crafted ++ -- refcounting?

I think the API provides a nicer interface.

bluhm

> However if_creategroup() should set `ifg_refcnt??? to 1
> and carp(4) should not touch groups internals.
> 
> > 
> > Index: net/if.c
> > ===================================================================
> > RCS file: /data/mirror/openbsd/cvs/src/sys/net/if.c,v
> > retrieving revision 1.626
> > diff -u -p -r1.626 if.c
> > --- net/if.c        1 Feb 2021 07:43:33 -0000       1.626
> > +++ net/if.c        6 Feb 2021 12:16:20 -0000
> > @@ -2601,7 +2601,7 @@ if_creategroup(const char *groupname)
> >             return (NULL);
> > 
> >     strlcpy(ifg->ifg_group, groupname, sizeof(ifg->ifg_group));
> > -   ifg->ifg_refcnt = 0;
> > +   refcnt_init(&ifg->ifg_refcnt);
> >     ifg->ifg_carp_demoted = 0;
> >     TAILQ_INIT(&ifg->ifg_members);
> > #if NPF > 0
> > @@ -2642,13 +2642,17 @@ if_addgroup(struct ifnet *ifp, const cha
> >             if (!strcmp(ifg->ifg_group, groupname))
> >                     break;
> > 
> > -   if (ifg == NULL && (ifg = if_creategroup(groupname)) == NULL) {
> > +   if (ifg == NULL)
> > +           ifg = if_creategroup(groupname);
> > +   else
> > +           refcnt_take(&ifg->ifg_refcnt);
> > +
> > +   if (ifg == NULL) {
> >             free(ifgl, M_TEMP, sizeof(*ifgl));
> >             free(ifgm, M_TEMP, sizeof(*ifgm));
> >             return (ENOMEM);
> >     }
> > 
> > -   ifg->ifg_refcnt++;
> >     ifgl->ifgl_group = ifg;
> >     ifgm->ifgm_ifp = ifp;
> > 
> > @@ -2692,7 +2696,7 @@ if_delgroup(struct ifnet *ifp, const cha
> >     pfi_group_change(groupname);
> > #endif
> > 
> > -   if (--ifgl->ifgl_group->ifg_refcnt == 0) {
> > +   if (refcnt_rele(&ifgl->ifgl_group->ifg_refcnt)) {
> >             TAILQ_REMOVE(&ifg_head, ifgl->ifgl_group, ifg_next);
> > #if NPF > 0
> >             pfi_detach_ifgroup(ifgl->ifgl_group);
> > Index: net/if_var.h
> > ===================================================================
> > RCS file: /data/mirror/openbsd/cvs/src/sys/net/if_var.h,v
> > retrieving revision 1.112
> > diff -u -p -r1.112 if_var.h
> > --- net/if_var.h    29 Jul 2020 12:09:31 -0000      1.112
> > +++ net/if_var.h    6 Feb 2021 12:11:35 -0000
> > @@ -263,7 +263,7 @@ struct ifmaddr {
> > 
> > struct ifg_group {
> >     char                     ifg_group[IFNAMSIZ];
> > -   u_int                    ifg_refcnt;
> > +   struct refcnt            ifg_refcnt;
> >     caddr_t                  ifg_pf_kif;
> >     int                      ifg_carp_demoted;
> >     TAILQ_HEAD(, ifg_member) ifg_members;
> > Index: netinet/ip_carp.c
> > ===================================================================
> > RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_carp.c,v
> > retrieving revision 1.351
> > diff -u -p -r1.351 ip_carp.c
> > --- netinet/ip_carp.c       21 Jan 2021 13:18:07 -0000      1.351
> > +++ netinet/ip_carp.c       6 Feb 2021 12:11:35 -0000
> > @@ -786,10 +786,7 @@ carp_sysctl(int *name, u_int namelen, vo
> > void
> > carpattach(int n)
> > {
> > -   struct ifg_group        *ifg;
> > -
> > -   if ((ifg = if_creategroup("carp")) != NULL)
> > -           ifg->ifg_refcnt++;      /* keep around even if empty */
> > +   if_creategroup("carp");  /* keep around even if empty */
> >     if_clone_attach(&carp_cloner);
> >     carpcounters = counters_alloc(carps_ncounters);
> > }
> > 
> 

Reply via email to