On Wed, May 11, 2022 at 10:29:57AM +0200, Claudio Jeker wrote:
> On Wed, May 11, 2022 at 09:58:09AM +0200, Alexandr Nedvedicky wrote:
> > Hello,
> > 
> > > 
> > > Can we limit the number of span ports per bridge to a small number so that
> > > the instead of a heap object for the SLIST a simple stack array of
> > > MAX_SPAN_PORTS pointers could be used?
> > > 
> > > Who needs more than a handfull of spanports per veb?
> > 
> >     I just to make sure I follow your idea...
> > 
> > > 
> > > > --------8<---------------8<---------------8<------------------8<--------
> > > > diff --git a/sys/net/if_veb.c b/sys/net/if_veb.c
> > > > index 2976cc200f1..a02dbac887f 100644
> > </snip>
> > > > +       struct veb_span_port *sp;
> > > > +       SLIST_HEAD(, veb_span_port) span_list;
> > 
> >     so the span_list, will be turned to array of references, right?
> > 
> > > >  
> > > > +       SLIST_INIT(&span_list)
> > > >         smr_read_enter();
> > > >         SMR_TAILQ_FOREACH(p, &sc->sc_spans.l_list, p_entry) {
> > > >                 ifp0 = p->p_ifp0;
> > > >                 if (!ISSET(ifp0->if_flags, IFF_RUNNING))
> > > >                         continue;
> > > >  
> > > > -               m = m_dup_pkt(m0, max_linkhdr + ETHER_ALIGN, M_NOWAIT);
> > > > -               if (m == NULL) {
> > > > -                       /* XXX count error */
> > > > -                       continue;
> > > > -               }
> > > > +               sp = pool_get(&span_port_pool, PR_NOWAIT);
> > > > +               if (sp == NULL)
> > > > +                       continue;       /* XXX count error */
> > > >  
> > > > -               if_enqueue(ifp0, m); /* XXX count error */
> > > > +               veb_eb_brport_take(p);
> > > > +               sp->sp_port = p;
> > > > +               SLIST_INSERT_HEAD(&span_list, sp, sp_entry);
> > 
> >     here we do instead of SLIST_INSERT_HEAD() something like:
> >     span_list[i++] = p;
> > 
> > > >         }
> > > >         smr_read_leave();
> > > > +
> > > > +       while (!SLIST_EMPTY(&span_list)) {
> > 
> >     and here instead of walking list we just walk through array.
> 
> Yes, this is my basic idea.
>  
> > is that somewhat correct? If so than I need some 'qualified' suggestion
> > for upper limit of span ports. I'm afraid my real life experience
> > with network switches is zero, so I don't feel like a right person.
> 
> I would suggest an upper limit of 8. For example it seems Cisco only
> supports 2 span sessions so 8 should be plenty.

Now looking at the original panic again I realized that the problem is
probably not veb_span() but actually veb_broadcast().
Both functions suffer from a similar issue that the smr block covers too
much.
For veb_broadcast the trick with the limit will not work. Using a service
task just for broadcast is also not a good option since it reorders packets.
 
> > another idea I'm toying with is to add a 'service task' to every switch
> > so the underlying `vport_if_enqueue()` will put packet to queue and
> > let task to dispatch to ifp associated with vport. Once packet
> > will be dispatched the task will drop the reference to port.
> 
> Need to look more into this but in general I dislike adding more queues
> and tasks. Such a setup would just synchronize everything back to a single
> thread.

-- 
:wq Claudio

Reply via email to