On Tue, Mar 08, 2022 at 05:49:22PM +0100, Alexandr Nedvedicky wrote:
> Hello,
> 
> my original idea was to have a one mutex per pfsync queue.  however it creates
> things more complicated then necessary for queues, which keep pf(4) state.
> hrvoje@ hit some panics in this area recently. bluhm@ and I are still looking
> at those issues. However there is the first change in order to make code more
> simple: diff below merges the array of ->sc_mtx[] into a single mutex. 
> 
> OK ?

I have thrown it on my performance test machine with pfsync enabled.
No issues seen.
http://bluhm.genua.de/perform/results/2022-03-06T22%3A40%3A13Z/perform.html

OK bluhm@

> --------8<---------------8<---------------8<------------------8<--------
> 
> diff --git a/sys/net/if_pfsync.c b/sys/net/if_pfsync.c
> index edeb2209161..9a92fc4d21f 100644
> --- a/sys/net/if_pfsync.c
> +++ b/sys/net/if_pfsync.c
> @@ -212,7 +212,7 @@ struct pfsync_softc {
>       struct ip                sc_template;
>  
>       struct pf_state_queue    sc_qs[PFSYNC_S_COUNT];
> -     struct mutex             sc_mtx[PFSYNC_S_COUNT];
> +     struct mutex             sc_st_mtx;
>       size_t                   sc_len;
>  
>       struct pfsync_upd_reqs   sc_upd_req_list;
> @@ -324,13 +324,6 @@ pfsync_clone_create(struct if_clone *ifc, int unit)
>       struct pfsync_softc *sc;
>       struct ifnet *ifp;
>       int q;
> -     static const char *mtx_names[] = {
> -             "iack_mtx",
> -             "upd_c_mtx",
> -             "del_mtx",
> -             "ins_mtx",
> -             "upd_mtx",
> -             "" };
>  
>       if (unit != 0)
>               return (EINVAL);
> @@ -338,10 +331,9 @@ pfsync_clone_create(struct if_clone *ifc, int unit)
>       pfsync_sync_ok = 1;
>  
>       sc = malloc(sizeof(*pfsyncif), M_DEVBUF, M_WAITOK|M_ZERO);
> -     for (q = 0; q < PFSYNC_S_COUNT; q++) {
> +     for (q = 0; q < PFSYNC_S_COUNT; q++)
>               TAILQ_INIT(&sc->sc_qs[q]);
> -             mtx_init_flags(&sc->sc_mtx[q], IPL_SOFTNET, mtx_names[q], 0);
> -     }
> +     mtx_init_flags(&sc->sc_st_mtx, IPL_SOFTNET, "st_mtx", 0);
>  
>       pool_init(&sc->sc_pool, PFSYNC_PLSIZE, 0, IPL_SOFTNET, 0, "pfsync",
>           NULL);
> @@ -1585,9 +1577,7 @@ pfsync_grab_snapshot(struct pfsync_snapshot *sn, struct 
> pfsync_softc *sc)
>  
>       sn->sn_sc = sc;
>  
> -     for (q = 0; q < PFSYNC_S_COUNT; q++)
> -             mtx_enter(&sc->sc_mtx[q]);
> -
> +     mtx_enter(&sc->sc_st_mtx);
>       mtx_enter(&sc->sc_upd_req_mtx);
>       mtx_enter(&sc->sc_tdb_mtx);
>  
> @@ -1612,9 +1602,7 @@ pfsync_grab_snapshot(struct pfsync_snapshot *sn, struct 
> pfsync_softc *sc)
>  
>       mtx_leave(&sc->sc_tdb_mtx);
>       mtx_leave(&sc->sc_upd_req_mtx);
> -
> -     for (q = (PFSYNC_S_COUNT - 1); q >= 0; q--)
> -             mtx_leave(&sc->sc_mtx[q]);
> +     mtx_leave(&sc->sc_st_mtx);
>  }
>  
>  void
> @@ -2420,14 +2408,14 @@ pfsync_q_ins(struct pf_state *st, int q)
>               panic("pfsync pkt len is too low %zd", sc->sc_len);
>  #endif
>       do {
> -             mtx_enter(&sc->sc_mtx[q]);
> +             mtx_enter(&sc->sc_st_mtx);
>  
>               /*
>                * If two threads are competing to insert the same state, then
>                * there must be just single winner.
>                */
>               if (st->sync_state != PFSYNC_S_NONE) {
> -                     mtx_leave(&sc->sc_mtx[q]);
> +                     mtx_leave(&sc->sc_st_mtx);
>                       break;
>               }
>  
> @@ -2439,7 +2427,7 @@ pfsync_q_ins(struct pf_state *st, int q)
>               sc_len = atomic_add_long_nv(&sc->sc_len, nlen);
>               if (sc_len > sc->sc_if.if_mtu) {
>                       atomic_sub_long(&sc->sc_len, nlen);
> -                     mtx_leave(&sc->sc_mtx[q]);
> +                     mtx_leave(&sc->sc_st_mtx);
>                       pfsync_sendout();
>                       continue;
>               }
> @@ -2448,7 +2436,7 @@ pfsync_q_ins(struct pf_state *st, int q)
>  
>               TAILQ_INSERT_TAIL(&sc->sc_qs[q], st, sync_list);
>               st->sync_state = q;
> -             mtx_leave(&sc->sc_mtx[q]);
> +             mtx_leave(&sc->sc_st_mtx);
>       } while (0);
>  }
>  
> @@ -2456,18 +2444,19 @@ void
>  pfsync_q_del(struct pf_state *st)
>  {
>       struct pfsync_softc *sc = pfsyncif;
> -     int q = st->sync_state;
> +     int q;
>  
>       KASSERT(st->sync_state != PFSYNC_S_NONE);
>  
> -     mtx_enter(&sc->sc_mtx[q]);
> +     mtx_enter(&sc->sc_st_mtx);
> +     q = st->sync_state;
>       atomic_sub_long(&sc->sc_len, pfsync_qs[q].len);
>       TAILQ_REMOVE(&sc->sc_qs[q], st, sync_list);
>       if (TAILQ_EMPTY(&sc->sc_qs[q]))
>               atomic_sub_long(&sc->sc_len, sizeof (struct pfsync_subheader));
> -     mtx_leave(&sc->sc_mtx[q]);
> -
>       st->sync_state = PFSYNC_S_NONE;
> +     mtx_leave(&sc->sc_st_mtx);
> +
>       pf_state_unref(st);
>  }
>  

Reply via email to