Page MenuHomeFreeBSD

Remove LAGG_RLOCK() from lagg_get_counter.
AbandonedPublic

Authored by sbruno on Jun 14 2016, 3:12 PM.
Tags
None
Referenced Files
Unknown Object (File)
Mon, Nov 25, 9:51 AM
Unknown Object (File)
Mon, Nov 25, 9:51 AM
Unknown Object (File)
Mon, Nov 25, 9:40 AM
Unknown Object (File)
Sun, Nov 24, 9:00 AM
Unknown Object (File)
Oct 2 2024, 10:03 PM
Unknown Object (File)
Oct 2 2024, 1:27 PM
Unknown Object (File)
Oct 1 2024, 12:49 AM
Unknown Object (File)
Sep 29 2024, 1:59 AM

Details

Reviewers
None

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 4219
Build 4263: arc lint + arc unit

Event Timeline

sbruno retitled this revision from to Remove LAGG_RLOCK() from lagg_get_counter..
sbruno updated this object.
sbruno edited the test plan for this revision. (Show Details)

This definitely fixes the lagg related hangs I've had on a laptop when tearing down a lagg device.

The real issue seems like some LOR or recursive lock attempt

sys/net/if_lagg.c
1058

This sc_ports list could change without the lock

static int
lagg_port_destroy(struct lagg_port *lp, int rundelport)
{
        struct lagg_softc *sc = lp->lp_softc;
        struct lagg_port *lp_ptr, *lp0;
        struct lagg_llq *llq;
        struct ifnet *ifp = lp->lp_ifp;
        uint64_t *pval, vdiff;
        int i;

        LAGG_WLOCK_ASSERT(sc);

        if (rundelport)
                lagg_proto_delport(sc, lp);

        /*
         * Remove multicast addresses and interface flags from this port and
         * reset the MAC address, skip if the interface is being detached.
         */
        if (!lp->lp_detaching) {
                lagg_ether_cmdmulti(lp, 0);
                lagg_setflags(lp, 0);
                lagg_port_lladdr(lp, lp->lp_lladdr, LAGG_LLQTYPE_PHYS);
        }

        /* Restore interface */
        ifp->if_type = lp->lp_iftype;
        ifp->if_ioctl = lp->lp_ioctl;
        ifp->if_output = lp->lp_output;
        ifp->if_lagg = NULL;

        /* Update detached port counters */
        pval = lp->port_counters.val;
        for (i = 0; i < IFCOUNTERS; i++, pval++) {
                vdiff = ifp->if_get_counter(ifp, i) - *pval;

Note the WLOCK is asserted, then if_get_counter is called, which is really lagg_get_counter. So it does seem to be recursing on the lock.

if_get_counter is called, which is really lagg_get_counter.

I know nothing about lagg and am only making a guess here

All of the code I've identified came in rS272211 from D781. Ping @melifaro on this bug

After seeing the net@ post it is a clear LOR, the LAGG lock and IF_ADDR locks are taken in different orders. That's from Sr269492