From owner-freebsd-arch@FreeBSD.ORG Fri Nov 4 12:52:37 2005 Return-Path: X-Original-To: arch@FreeBSD.org Delivered-To: freebsd-arch@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7C5D516A431 for ; Fri, 4 Nov 2005 12:52:37 +0000 (GMT) (envelope-from jhb@FreeBSD.org) Received: from speedfactory.net (mail5.speedfactory.net [66.23.216.218]) by mx1.FreeBSD.org (Postfix) with ESMTP id 086CF43D48 for ; Fri, 4 Nov 2005 12:52:36 +0000 (GMT) (envelope-from jhb@FreeBSD.org) Received: from server.baldwin.cx (unverified [66.23.211.162]) by speedfactory.net (SurgeMail 3.5b3) with ESMTP id 1360008 for ; Fri, 04 Nov 2005 07:54:32 -0500 Received: from zion.baldwin.cx (zion.baldwin.cx [192.168.0.7]) (authenticated bits=0) by server.baldwin.cx (8.13.1/8.13.1) with ESMTP id jA4CqVcw081545 for ; Fri, 4 Nov 2005 07:52:32 -0500 (EST) (envelope-from jhb@FreeBSD.org) From: John Baldwin To: arch@FreeBSD.org Date: Fri, 4 Nov 2005 07:52:29 -0500 User-Agent: KMail/1.8 MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Message-Id: <200511040752.29724.jhb@FreeBSD.org> X-Spam-Status: No, score=-2.8 required=4.2 tests=ALL_TRUSTED autolearn=failed version=3.0.2 X-Spam-Checker-Version: SpamAssassin 3.0.2 (2004-11-16) on server.baldwin.cx X-Server: High Performance Mail Server - http://surgemail.com r=100 Cc: Subject: ether_ifdetach() races round 3(?) X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 04 Nov 2005 12:52:37 -0000 I had another moment of inspiration regarding the ether_ifdetach() races=20 during my shower this morning. Maybe this will gives us a viable solution= =20 this time. The reason we are having races is that once we call foo_stop(), the driver= =20 state is out of sync with the ifnet state because IFF_UP is still set even= =20 though the driver effectively has marked the interface down. The obvious=20 solution to that is to have the ifnet code "officially" mark the driver dow= n=20 by clearing IFF_UP. This would result in foo_ioctl() calling foo_stop()=20 rather than foo_detach() calling it explicitly. I think this is actually=20 cleaner in that drivers already rely on the ifnet layer calling foo_init()= =20 and don't call foo_init() in foo_attach(). Moving foo_stop() out of=20 foo_detach() and into the ifnet layer would thus be more consistent. =20 foo_detach() would go from: if (device_is_attached(sc)) { FOO_LOCK(sc); foo_stop(sc); FOO_UNLOCK(sc); callout_drain(&sc->sc_stat_callout); ether_ifdetach(sc->sc_ifp); } to just: if (device_is_attached(sc)) { ether_ifdetach(sc->sc_ifp); callout_drain(&sc->sc_stat_callout); } The only question then is when should ether_ifdetach() mark the interface a= s=20 down, and this actually ends up nice as it lets us fix all the other races= =20 with BPF and userland ioctls. Basically, we should detach the ifnet from=20 userland so no more userland requests can come in, then tear down kernel=20 consumers such as BPF, and mark the interface down resulting in an ioctl()= =20 that clears IFF_UP and calls foo_stop(). =2D-=20 John Baldwin =A0<>< =A0http://www.FreeBSD.org/~jhb/ "Power Users Use the Power to Serve" =A0=3D =A0http://www.FreeBSD.org