On Thu, Apr 28, 2022 at 12:52:41AM +0300, Vitaliy Makkoveev wrote:
> On Thu, Apr 28, 2022 at 12:15:25AM +0300, Vitaliy Makkoveev wrote:
> > > On 27 Apr 2022, at 23:24, Kasak <ka...@kasakoff.net> wrote:
> [ skip ]
> > > I???m afraid your patch did not help, it crashed again after three hours 
> > 
> > Did it panic within ipsp_ids_gc() again?
> > 
> 
> I missed, ipsp_ids_lookup() bumps `id_refcount' on dead `ids'. I fixed
> my previous diff.

OK bluhm@

> Index: sys/netinet/ip_ipsp.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/ip_ipsp.c,v
> retrieving revision 1.269
> diff -u -p -r1.269 ip_ipsp.c
> --- sys/netinet/ip_ipsp.c     10 Mar 2022 15:21:08 -0000      1.269
> +++ sys/netinet/ip_ipsp.c     27 Apr 2022 21:40:58 -0000
> @@ -1205,7 +1205,7 @@ ipsp_ids_insert(struct ipsec_ids *ids)
>       found = RBT_INSERT(ipsec_ids_tree, &ipsec_ids_tree, ids);
>       if (found) {
>               /* if refcount was zero, then timeout is running */
> -             if (atomic_inc_int_nv(&found->id_refcount) == 1) {
> +             if ((++found->id_refcount) == 1) {
>                       LIST_REMOVE(found, id_gc_list);
>  
>                       if (LIST_EMPTY(&ipsp_ids_gc_list))
> @@ -1248,7 +1248,12 @@ ipsp_ids_lookup(u_int32_t ipsecflowinfo)
>  
>       mtx_enter(&ipsec_flows_mtx);
>       ids = RBT_FIND(ipsec_ids_flows, &ipsec_ids_flows, &key);
> -     atomic_inc_int(&ids->id_refcount);
> +     if (ids != NULL) {
> +             if (ids->id_refcount != 0)
> +                     ids->id_refcount++;
> +             else
> +                     ids = NULL;
> +     }
>       mtx_leave(&ipsec_flows_mtx);
>  
>       return ids;
> @@ -1290,6 +1295,8 @@ ipsp_ids_free(struct ipsec_ids *ids)
>       if (ids == NULL)
>               return;
>  
> +     mtx_enter(&ipsec_flows_mtx);
> +
>       /*
>        * If the refcount becomes zero, then a timeout is started. This
>        * timeout must be cancelled if refcount is increased from zero.
> @@ -1297,10 +1304,10 @@ ipsp_ids_free(struct ipsec_ids *ids)
>       DPRINTF("ids %p count %d", ids, ids->id_refcount);
>       KASSERT(ids->id_refcount > 0);
>  
> -     if (atomic_dec_int_nv(&ids->id_refcount) > 0)
> +     if ((--ids->id_refcount) > 0) {
> +             mtx_leave(&ipsec_flows_mtx);
>               return;
> -
> -     mtx_enter(&ipsec_flows_mtx);
> +     }
>  
>       /*
>        * Add second for the case ipsp_ids_gc() is already running and
> Index: sys/netinet/ip_ipsp.h
> ===================================================================
> RCS file: /cvs/src/sys/netinet/ip_ipsp.h,v
> retrieving revision 1.238
> diff -u -p -r1.238 ip_ipsp.h
> --- sys/netinet/ip_ipsp.h     21 Apr 2022 15:22:50 -0000      1.238
> +++ sys/netinet/ip_ipsp.h     27 Apr 2022 21:40:59 -0000
> @@ -241,7 +241,7 @@ struct ipsec_ids {
>       struct ipsec_id         *id_local;      /* [I] */
>       struct ipsec_id         *id_remote;     /* [I] */
>       u_int32_t               id_flow;        /* [I] */
> -     u_int                   id_refcount;    /* [a] */
> +     u_int                   id_refcount;    /* [F] */
>       u_int                   id_gc_ttl;      /* [F] */
>  };
>  RBT_HEAD(ipsec_ids_flows, ipsec_ids);

Reply via email to