Hello,

On Fri, 8 Jul 2022 00:53:16 +0300
Vitaliy Makkoveev <[email protected]> wrote:
> The `pipex_list_mtx' mutex(9) protects global pipex(4) lists so it need
> to be taken while we perform this foreach loop.
> 
> The all sessions loop was reworked to make possible to drop the lock
> within. This is required because pipex_ppp_output() takes scheduler lock
> when performs ip_send().
>
> Index: sys/net/pipex.c
> ===================================================================
> RCS file: /cvs/src/sys/net/pipex.c,v
> retrieving revision 1.143
> diff -u -p -r1.143 pipex.c
> --- sys/net/pipex.c   2 Jul 2022 08:50:42 -0000       1.143
> +++ sys/net/pipex.c   7 Jul 2022 21:52:16 -0000
> @@ -842,20 +842,39 @@ pipex_ip_output(struct mbuf *m0, struct 
>  
>               m0->m_flags &= ~(M_BCAST|M_MCAST);
>  
> -             LIST_FOREACH(session_tmp, &pipex_session_list, session_list) {
> +             mtx_enter(&pipex_list_mtx);
> +
> +             session_tmp = LIST_FIRST(&pipex_session_list);
> +             while (session_tmp != NULL) {
> +                     struct pipex_session *session_save = NULL;
> +
>                       if (session_tmp->ownersc != session->ownersc)
> -                             continue;
> +                             goto next;
>                       if ((session->flags & (PIPEX_SFLAGS_IP_FORWARD |
>                           PIPEX_SFLAGS_IP6_FORWARD)) == 0)
> -                             continue;
> +                             goto next;
>                       m = m_copym(m0, 0, M_COPYALL, M_NOWAIT);
>                       if (m == NULL) {
>                               counters_inc(session->stat_counters,
>                                   pxc_oerrors);
> -                             continue;
> +                             goto next;
>                       }
> +
> +                     refcnt_take(&session->pxs_refcnt);

this "session" should be session_tmp?

Also, isn't it needed to take reference count on top of the block?

                session_ = LIST_FIRST(&pipex_session_list);
                while (session_tmp != NULL) {
                        refcnt_take(&session_tmp->pxs_refcnt);
                        
                        if (session_tmp->ownersc != session->ownersc)
                                goto next;
                        if ((session->flags & (PIPEX_SFLAGS_IP_FORWARD |
                            PIPEX_SFLAGS_IP6_FORWARD)) == 0)
                                goto next;
                        m = m_copym(m0, 0, M_COPYALL, M_NOWAIT);
                        if (m == NULL) {
                                counters_inc(session->stat_counters,
                                    pxc_oerrors);
                                goto next;
                        }

                        mtx_leave(&pipex_list_mtx);
                        pipex_ppp_output(m, session_tmp, PPP_IP);
                        mtx_enter(&pipex_list_mtx);
next:
                        session_save = session_tmp;
                        session_tmp = LIST_NEXT(session_tmp, session_list);
                        pipex_rele_session(session_save);
                }


> +                     mtx_leave(&pipex_list_mtx);
> +
>                       pipex_ppp_output(m, session_tmp, PPP_IP);
> +
> +                     mtx_enter(&pipex_list_mtx);
> +                     session_save = session_tmp;
> +next:
> +                     session_tmp = LIST_NEXT(session_tmp, session_list);
> +                     if (session_save != NULL)
> +                             pipex_rele_session(session_save);
>               }
> +
> +             mtx_leave(&pipex_list_mtx);
> +
>               m_freem(m0);
>       }
>  

Reply via email to