Hello Hrvoje,

thank you for testing.
On Wed, May 11, 2022 at 10:40:28AM +0200, Hrvoje Popovski wrote:
> On 10.5.2022. 22:55, Alexander Bluhm wrote:
> > Yes.  It is similar.
> > 
> > I have read the whole mail thread and the final fix got commited.
> > But it looks incomplete, pf is still sleeping.
> > 
> > Hrvoje, can you run the tests again that triggered the panics a
> > year ago?
> 
> Hi,
> 
> year ago panics was triggered when veb or tpmr bridged traffic. I've
> tried that right now and I couldn't trigger that panics.
> If I put vport and route traffic over veb than I can trigger panic with
> or without vlans as child-iface for veb.
> For panic i need to have pf enabled and to run
> ifconfig veb destroy or ifconfig vlan destroy and sh netstart in loop.
> 
> 
> this is panic without vlans
> 
> ddb{4}> show all locks
> CPU 4:
> exclusive sched_lock &sched_lock r = 0 (0xffffffff824819c0)
> #0  witness_lock+0x311
> #1  sleep_setup+0xa5
> #2  rw_enter+0x211
> #3  pf_test+0xcf0
> #4  ip_output+0x6b7
> #5  ip_forward+0x2da
> #6  ip_input_if+0x353
> #7  ipv4_input+0x39
> #8  ether_input+0x3ad
> #9  vport_if_enqueue+0x19
> #10 veb_port_input+0x529

    I suspect we deal with broadcast and this time things start
    to go downhill here in veb_broadcast():

 875         smr_read_enter();
 876         SMR_TAILQ_FOREACH(tp, &sc->sc_ports.l_list, p_entry) {
 877                 if (rp == tp || (rp->p_protected & tp->p_protected)) {
 878                         /*
 879                          * don't let Ethernet packets hairpin or
 880                          * move between ports in the same protected
 881                          * domain(s).
 882                          */
 883                         continue;
 884                 }
 885 
 886                 ifp0 = tp->p_ifp0;
 887                 if (!ISSET(ifp0->if_flags, IFF_RUNNING)) {
 888                         /* don't waste time */
 889                         continue;
 890                 }
 891 
 892                 if (!ISSET(tp->p_bif_flags, IFBIF_DISCOVER) &&
 893                     !ISSET(m0->m_flags, M_BCAST | M_MCAST)) {
 894                         /* don't flood unknown unicast */
 895                         continue;
 896                 }
 897 
 898                 if (veb_rule_filter(tp, VEB_RULE_LIST_OUT, m0, src, dst))
 899                         continue;
 900 
 901                 m = m_dup_pkt(m0, max_linkhdr + ETHER_ALIGN, M_NOWAIT);
 902                 if (m == NULL) {
 903                         /* XXX count error? */
 904                         continue;
 905                 }
 906 
 907                 (*tp->p_enqueue)(ifp0, m); /* XXX count error */
 908         }
 909         smr_read_leave();

    the veb_broadcast() is being called from veb_port_input():
1082 
1083                 /* unknown unicast address */
1084         } else {
1085                 SET(m->m_flags, ETH64_IS_BROADCAST(dst) ? M_BCAST : 
M_MCAST);
1086         }
1087 
1088         veb_broadcast(sc, p, m, src, dst);
1089         return (NULL);

    I think I've spotted the place yesterday night in code, but could not
    figure out how to wire things up to trigger the panic. Fortunately you've
    managed to figure it out.

I think vport_if_enqueue() is a trap/land mine here. The function should really
be queueing a packet instead of dispatching it right away.


thanks and
regards
sashan

Reply via email to