Claudio Jeker(cje...@diehard.n-r-g.com) on 2019.06.25 11:13:55 +0200:
> In bgpd there are a few objects that use reference counts to keep track on
> how many things point to them. Those are struct pt_entry, rde_aspath,
> rde_communities, and nexthop. The way this reference counting is done and
> especially the cleanup is a bit different everywhere. This diff is making
> them more similar by calling all functions _ref and _unref also the _unref
> function will remove the element once the last reference is dropped.
> There are still some internal differences but all in all for the callers
> this makes the code look a lot more similar.
> 
> OK?

ok

> -- 
> :wq Claudio
> 
> Index: rde.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
> retrieving revision 1.474
> diff -u -p -r1.474 rde.c
> --- rde.c     25 Jun 2019 09:04:42 -0000      1.474
> +++ rde.c     25 Jun 2019 09:05:27 -0000
> @@ -1353,7 +1353,7 @@ rde_update_dispatch(struct imsg *imsg)
>               }
>  
>               /* unlock the previously locked nexthop, it is no longer used */
> -             (void)nexthop_put(state.nexthop);
> +             nexthop_unref(state.nexthop);
>               state.nexthop = NULL;
>               if ((pos = rde_get_mp_nexthop(mpp, mplen, aid, &state)) == -1) {
>                       log_peer_warnx(&peer->conf, "bad nlri nexthop");
> @@ -1653,7 +1653,7 @@ bad_flags:
>                           op, len);
>                       return (-1);
>               }
> -             nexthop_put(state->nexthop);    /* just to be sure */
> +             nexthop_unref(state->nexthop);  /* just to be sure */
>               state->nexthop = nexthop_get(&nexthop);
>               break;
>       case ATTR_MED:
> @@ -2015,7 +2015,7 @@ rde_get_mp_nexthop(u_char *data, u_int16
>               return (-1);
>       }
>  
> -     nexthop_put(state->nexthop);    /* just to be sure */
> +     nexthop_unref(state->nexthop);  /* just to be sure */
>       state->nexthop = nexthop_get(&nexthop);
>  
>       /* ignore reserved (old SNPA) field as per RFC4760 */
> Index: rde.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v
> retrieving revision 1.218
> diff -u -p -r1.218 rde.h
> --- rde.h     24 Jun 2019 06:39:49 -0000      1.218
> +++ rde.h     25 Jun 2019 09:05:27 -0000
> @@ -423,7 +423,7 @@ void       communities_copy(struct rde_commun
>  void  communities_clean(struct rde_community *);
>  
>  static inline struct rde_community *
> -communities_get(struct rde_community *comm)
> +communities_ref(struct rde_community *comm)
>  {
>       if (comm->refcnt == 0)
>               fatalx("%s: not-referenced community", __func__);
> @@ -433,12 +433,12 @@ communities_get(struct rde_community *co
>  }
>  
>  static inline void
> -communities_put(struct rde_community *comm)
> +communities_unref(struct rde_community *comm)
>  {
>       if (comm == NULL)
>               return;
>       rdemem.comm_refs--;
> -     if (--comm->refcnt == 1)
> +     if (--comm->refcnt == 1)        /* last ref is hold internally */
>               communities_unlink(comm);
>  }
>  
> @@ -460,11 +460,15 @@ int              rde_filter_equal(struct filter_hea
>  void          rde_filter_calc_skip_steps(struct filter_head *);
>  
>  /* rde_prefix.c */
> -static inline int
> -pt_empty(struct pt_entry *pt)
> -{
> -     return (pt->refcnt == 0);
> -}
> +void  pt_init(void);
> +void  pt_shutdown(void);
> +void  pt_getaddr(struct pt_entry *, struct bgpd_addr *);
> +struct pt_entry      *pt_fill(struct bgpd_addr *, int);
> +struct pt_entry      *pt_get(struct bgpd_addr *, int);
> +struct pt_entry *pt_add(struct bgpd_addr *, int);
> +void  pt_remove(struct pt_entry *);
> +struct pt_entry      *pt_lookup(struct bgpd_addr *);
> +int   pt_prefix_cmp(const struct pt_entry *, const struct pt_entry *);
>  
>  static inline struct pt_entry *
>  pt_ref(struct pt_entry *pt)
> @@ -475,25 +479,15 @@ pt_ref(struct pt_entry *pt)
>       return pt;
>  }
>  
> -static inline int
> +static inline void
>  pt_unref(struct pt_entry *pt)
>  {
>       if (pt->refcnt == 0)
>               fatalx("pt_unref: underflow");
> -     --pt->refcnt;
> -     return pt_empty(pt);
> +     if (--pt->refcnt == 0)
> +             pt_remove(pt);
>  }
>  
> -void  pt_init(void);
> -void  pt_shutdown(void);
> -void  pt_getaddr(struct pt_entry *, struct bgpd_addr *);
> -struct pt_entry      *pt_fill(struct bgpd_addr *, int);
> -struct pt_entry      *pt_get(struct bgpd_addr *, int);
> -struct pt_entry *pt_add(struct bgpd_addr *, int);
> -void  pt_remove(struct pt_entry *);
> -struct pt_entry      *pt_lookup(struct bgpd_addr *);
> -int   pt_prefix_cmp(const struct pt_entry *, const struct pt_entry *);
> -
>  /* rde_rib.c */
>  extern u_int16_t      rib_size;
>  extern struct rib_desc       *ribs;
> @@ -608,7 +602,7 @@ void               nexthop_unlink(struct prefix *);
>  void          nexthop_update(struct kroute_nexthop *);
>  struct nexthop       *nexthop_get(struct bgpd_addr *);
>  struct nexthop       *nexthop_ref(struct nexthop *);
> -int           nexthop_put(struct nexthop *);
> +int           nexthop_unref(struct nexthop *);
>  int           nexthop_compare(struct nexthop *, struct nexthop *);
>  
>  /* rde_update.c */
> Index: rde_filter.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/rde_filter.c,v
> retrieving revision 1.120
> diff -u -p -r1.120 rde_filter.c
> --- rde_filter.c      22 Jun 2019 05:44:05 -0000      1.120
> +++ rde_filter.c      25 Jun 2019 09:05:27 -0000
> @@ -444,7 +444,7 @@ rde_filterstate_clean(struct filterstate
>  {
>       path_clean(&state->aspath);
>       communities_clean(&state->communities);
> -     nexthop_put(state->nexthop);
> +     nexthop_unref(state->nexthop);
>       state->nexthop = NULL;
>  }
>  
> @@ -481,7 +481,7 @@ filterset_free(struct filter_set_head *s
>                       pftable_unref(s->action.id);
>               else if (s->type == ACTION_SET_NEXTHOP &&
>                   bgpd_process == PROC_RDE)
> -                     nexthop_put(s->action.nh);
> +                     nexthop_unref(s->action.nh);
>               free(s);
>       }
>  }
> Index: rde_prefix.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/rde_prefix.c,v
> retrieving revision 1.38
> diff -u -p -r1.38 rde_prefix.c
> --- rde_prefix.c      15 Feb 2019 09:55:21 -0000      1.38
> +++ rde_prefix.c      25 Jun 2019 09:05:27 -0000
> @@ -188,7 +188,7 @@ pt_add(struct bgpd_addr *prefix, int pre
>  void
>  pt_remove(struct pt_entry *pte)
>  {
> -     if (!pt_empty(pte))
> +     if (pte->refcnt != 0)
>               fatalx("pt_remove: entry still holds references");
>  
>       if (RB_REMOVE(pt_tree, &pttable, pte) == NULL)
> Index: rde_rib.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/rde_rib.c,v
> retrieving revision 1.195
> diff -u -p -r1.195 rde_rib.c
> --- rde_rib.c 22 Jun 2019 05:44:05 -0000      1.195
> +++ rde_rib.c 25 Jun 2019 09:05:27 -0000
> @@ -62,11 +62,11 @@ struct rib_context {
>  };
>  LIST_HEAD(, rib_context) rib_dumps = LIST_HEAD_INITIALIZER(rib_dumps);
>  
> -static int    prefix_add(struct bgpd_addr *, int, struct rib *,
> +static int   prefix_add(struct bgpd_addr *, int, struct rib *,
>                   struct rde_peer *, struct rde_aspath *,
>                   struct rde_community *, struct nexthop *,
>                   u_int8_t, u_int8_t);
> -static int    prefix_move(struct prefix *, struct rde_peer *,
> +static int   prefix_move(struct prefix *, struct rde_peer *,
>                   struct rde_aspath *, struct rde_community *,
>                   struct nexthop *, u_int8_t, u_int8_t);
>  
> @@ -326,8 +326,7 @@ rib_remove(struct rib_entry *re)
>               /* entry is locked, don't free it. */
>               return;
>  
> -     if (pt_unref(re->prefix))
> -             pt_remove(re->prefix);
> +     pt_unref(re->prefix);
>  
>       if (RB_REMOVE(rib_tree, rib_tree(re_rib(re)), re) == NULL)
>               log_warnx("rib_remove: remove failed.");
> @@ -501,12 +500,6 @@ SIPHASH_KEY pathtablekey;
>  
>  #define      PATH_HASH(x)    &pathtable.path_hashtbl[x & 
> pathtable.path_hashmask]
>  
> -static inline int
> -path_empty(struct rde_aspath *asp)
> -{
> -     return (asp == NULL || asp->refcnt <= 0);
> -}
> -
>  static inline struct rde_aspath *
>  path_ref(struct rde_aspath *asp)
>  {
> @@ -521,10 +514,14 @@ path_ref(struct rde_aspath *asp)
>  static inline void
>  path_unref(struct rde_aspath *asp)
>  {
> +     if (asp == NULL)
> +             return;
>       if ((asp->flags & F_ATTR_LINKED) == 0)
>               fatalx("%s: unlinked object", __func__);
>       asp->refcnt--;
>       rdemem.path_refs--;
> +     if (asp->refcnt <= 0)
> +             path_unlink(asp);
>  }
>  
>  void
> @@ -765,8 +762,8 @@ path_unlink(struct rde_aspath *asp)
>               return;
>  
>       /* make sure no reference is hold for this rde_aspath */
> -     if (!path_empty(asp))
> -             fatalx("%s: still has prefixes", __func__);
> +     if (asp->refcnt != 0)
> +             fatalx("%s: still holds references", __func__);
>  
>       LIST_REMOVE(asp, path_l);
>       asp->flags &= ~F_ATTR_LINKED;
> @@ -938,7 +935,7 @@ prefix_move(struct prefix *p, struct rde
>       np = prefix_alloc();
>       /* add reference to new AS path and communities */
>       np->aspath = path_ref(asp);
> -     np->communities = communities_get(comm);
> +     np->communities = communities_ref(comm);
>       np->peer = peer;
>       np->pt = p->pt; /* skip refcnt update since ref is moved */
>       np->re = p->re;
> @@ -970,10 +967,9 @@ prefix_move(struct prefix *p, struct rde
>  
>       /* destroy all references to other objects and free the old prefix */
>       nexthop_unlink(p);
> -     nexthop_put(p->nexthop);
> -     communities_put(p->communities);
> -     if (oasp)
> -             path_unref(oasp);
> +     nexthop_unref(p->nexthop);
> +     communities_unref(p->communities);
> +     path_unref(oasp);
>       p->communities = NULL;
>       p->nexthop = NULL;
>       p->aspath = NULL;
> @@ -982,10 +978,6 @@ prefix_move(struct prefix *p, struct rde
>       p->pt = NULL;
>       prefix_free(p);
>  
> -     /* destroy old path if empty */
> -     if (path_empty(oasp))
> -             path_unlink(oasp);
> -
>       return (0);
>  }
>  
> @@ -1061,28 +1053,22 @@ prefix_withdraw(struct rib *rib, struct 
>      struct bgpd_addr *prefix, int prefixlen)
>  {
>       struct prefix           *p;
> -     struct rde_aspath       *asp;
>  
>       p = prefix_get(rib, peer, prefix, prefixlen);
>       if (p == NULL)          /* Got a dummy withdrawn request. */
>               return (0);
>  
>       /* unlink from aspath ...*/
> -     asp = p->aspath;
> -     if (asp != NULL) {
> -             path_unref(asp);
> -             p->aspath = NULL;
> -             if (path_empty(asp))
> -                     path_unlink(asp);
> -     }
> +     path_unref(p->aspath);
> +     p->aspath = NULL;
>  
>       /* ... communities ... */
> -     communities_put(p->communities);
> +     communities_unref(p->communities);
>       p->communities = NULL;
>  
>       /* ... and nexthop but keep the re link */
>       nexthop_unlink(p);
> -     nexthop_put(p->nexthop);
> +     nexthop_unref(p->nexthop);
>       p->nexthop = NULL;
>       p->nhflags = 0;
>       /* re link still exists */
> @@ -1271,14 +1257,8 @@ prefix_updateall(struct prefix *p, enum 
>  void
>  prefix_destroy(struct prefix *p)
>  {
> -     struct rde_aspath       *asp;
> -
> -     asp = prefix_aspath(p);
>       prefix_unlink(p);
>       prefix_free(p);
> -
> -     if (path_empty(asp))
> -             path_unlink(asp);
>  }
>  
>  /*
> @@ -1290,7 +1270,7 @@ prefix_link(struct prefix *p, struct rib
>      struct nexthop *nexthop, u_int8_t nhflags, u_int8_t vstate)
>  {
>       p->aspath = path_ref(asp);
> -     p->communities = communities_get(comm);
> +     p->communities = communities_ref(comm);
>       p->peer = peer;
>       p->pt = pt_ref(re->prefix);
>       p->re = re;
> @@ -1321,12 +1301,10 @@ prefix_unlink(struct prefix *p)
>  
>       /* destroy all references to other objects */
>       nexthop_unlink(p);
> -     nexthop_put(p->nexthop);
> -     communities_put(p->communities);
> -     if (p->aspath)
> -             path_unref(p->aspath);
> -     if (pt_unref(p->pt))
> -             pt_remove(p->pt);
> +     nexthop_unref(p->nexthop);
> +     communities_unref(p->communities);
> +     path_unref(p->aspath);
> +     pt_unref(p->pt);
>       p->communities = NULL;
>       p->nexthop = NULL;
>       p->aspath = NULL;
> @@ -1418,7 +1396,7 @@ nexthop_shutdown(void)
>                   nh != NULL; nh = nnh) {
>                       nnh = LIST_NEXT(nh, nexthop_l);
>                       nh->state = NEXTHOP_UNREACH;
> -                     (void)nexthop_put(nh);
> +                     nexthop_unref(nh);
>               }
>               if (!LIST_EMPTY(&nexthoptable.nexthop_hashtbl[i])) {
>                       nh = LIST_FIRST(&nexthoptable.nexthop_hashtbl[i]);
> @@ -1481,7 +1459,7 @@ nexthop_update(struct kroute_nexthop *ms
>       nh->oldstate = nh->state;
>       if (nh->oldstate == NEXTHOP_LOOKUP)
>               /* drop reference which was hold during the lookup */
> -             if (nexthop_put(nh))
> +             if (nexthop_unref(nh))
>                       return;         /* nh lost last ref, no work left */
>  
>       if (nh->next_prefix) {
> @@ -1546,7 +1524,7 @@ nexthop_modify(struct nexthop *setnh, en
>                */
>               if (aid != setnh->exit_nexthop.aid)
>                       break;
> -             nexthop_put(*nexthop);
> +             nexthop_unref(*nexthop);
>               *nexthop = nexthop_ref(setnh);
>               *flags = 0;
>               break;
> @@ -1617,11 +1595,10 @@ nexthop_ref(struct nexthop *nexthop)
>  }
>  
>  int
> -nexthop_put(struct nexthop *nh)
> +nexthop_unref(struct nexthop *nh)
>  {
>       if (nh == NULL)
>               return (0);
> -
>       if (--nh->refcnt > 0)
>               return (0);
>  
> 

Reply via email to