Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 9 Apr 2012 13:06:30 -0400
From:      Andrew Boyer <aboyer@averesystems.com>
To:        Andrew Thompson <thompsa@FreeBSD.org>
Cc:        freebsd-net@freebsd.org, John Baldwin <jhb@freebsd.org>
Subject:   Re: LACP kernel panics: /* unlocking is safe here */
Message-ID:  <8B0D75C6-5918-4EFE-9929-4344D877B320@averesystems.com>
In-Reply-To: <CAFAOGNSbc05zLwWeatHRvmfWhCc1=UtCLFwmooHaoW1vBd4mwg@mail.gmail.com>
References:  <D02B1265-C1F4-4F6A-979D-E141565E813F@averesystems.com> <201204020835.00357.jhb@freebsd.org> <CAFAOGNSbc05zLwWeatHRvmfWhCc1=UtCLFwmooHaoW1vBd4mwg@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Makes sense to me.

-Andrew

On Apr 7, 2012, at 4:02 AM, Andrew Thompson wrote:

> On 3 April 2012 00:35, John Baldwin <jhb@freebsd.org> wrote:
>> On Friday, March 30, 2012 6:04:24 pm Andrew Boyer wrote:
>>> While investigating a LACP issue, I turned on LACP_DEBUG on a debug =
kernel.
>> In this configuration it's easy to panic the kernel - just run =
'ifconfig lagg0
>> laggproto lacp' on a lagg that's already in LACP mode and receiving =
LACP
>> messages.
>>>=20
>>> The problem is that lagg_lacp_detach() drops the lagg wlock (with =
the
>> comment in the title), which allows incoming LACP messages to get =
through
>> lagg_input() while the structure is being destroyed in lacp_detach().
>>>=20
>>> There's a very simple fix, but I don't know if it's the best way to =
fix it.
>> Resetting the protocol before calling sc_detach causes any further =
incoming
>> packets to be dropped until the lagg gets reconfigured.  Thoughts?
>>=20
>> This looks sensible.
>=20
> Changing the order also needs an additional check as LAGG_PROTO_NONE
> no longer means the detach is finished. If one ioctl sleeps then we
> may nullify all the pointers upon wake that have already been set by
> the other ioctl.
>=20
> Does this look ok?
>=20
> Index: if_lagg.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> --- if_lagg.c	(revision 233252)
> +++ if_lagg.c	(working copy)
> @@ -950,11 +950,11 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, =
caddr_t
> 			error =3D EPROTONOSUPPORT;
> 			break;
> 		}
> +		LAGG_WLOCK(sc);
> 		if (sc->sc_proto !=3D LAGG_PROTO_NONE) {
> -			LAGG_WLOCK(sc);
> +			/* Reset protocol first in case detach unlocks =
*/
> +			sc->sc_proto =3D LAGG_PROTO_NONE;
> 			error =3D sc->sc_detach(sc);
> -			/* Reset protocol and pointers */
> -			sc->sc_proto =3D LAGG_PROTO_NONE;
> 			sc->sc_detach =3D NULL;
> 			sc->sc_start =3D NULL;
> 			sc->sc_input =3D NULL;
> @@ -966,8 +966,11 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t
> 			sc->sc_lladdr =3D NULL;
> 			sc->sc_req =3D NULL;
> 			sc->sc_portreq =3D NULL;
> -			LAGG_WUNLOCK(sc);
> +		} else if (sc->sc_input !=3D NULL) {
> +			/* Still detaching */
> +			error =3D EBUSY;
> 		}
> +		LAGG_WUNLOCK(sc);
> 		if (error !=3D 0)
> 			break;
> 		for (int i =3D 0; i < (sizeof(lagg_protos) /

--------------------------------------------------
Andrew Boyer	aboyer@averesystems.com







Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?8B0D75C6-5918-4EFE-9929-4344D877B320>