From owner-freebsd-bugs@FreeBSD.ORG Wed Jan 28 22:35:27 2004 Return-Path: Delivered-To: freebsd-bugs@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 84CB216A4CE; Wed, 28 Jan 2004 22:35:27 -0800 (PST) Received: from feith1.FEITH.COM (feith1.FEITH.COM [192.251.93.1]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7147E43D31; Wed, 28 Jan 2004 22:35:26 -0800 (PST) (envelope-from john@feith.com) Received: from jwlab.FEITH.COM (jwlab.FEITH.COM [192.251.93.16]) by feith1.FEITH.COM (8.12.10+Sun/8.12.9) with ESMTP id i0T6ZPAL014199; Thu, 29 Jan 2004 01:35:25 -0500 (EST) Received: (from john@localhost) by jwlab.FEITH.COM (8.11.7+Sun/8.11.7) id i0T6ZO224579; Thu, 29 Jan 2004 01:35:24 -0500 (EST) Date: Thu, 29 Jan 2004 01:35:24 -0500 (EST) From: John Wehle Message-Id: <200401290635.i0T6ZO224579@jwlab.FEITH.COM> To: bugs@freebsd.org Content-Type: text X-Scanned-By: MIMEDefang 2.39 X-Archived: cashew.FEITH.COM cc: current@freebsd.org Subject: nasty device_delete_child interaction X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 29 Jan 2004 06:35:27 -0000 device_delete_child works by starting with the grandchildren working back towards the immediate child. Several drivers (i.e. if_xl.c, if_wx.c, iicbb.c) have code similar to: xxx_attach() { ... sc->child_dev = device_add_child ... } xxx_detach() { bus_generic_detach (); if (sc->child_dev) device_delete_child ... } The problem is using device_delete_child on one of these drivers causes the grandchild to be freed twice. When device_delete_child is called for xxx, it recurses since xxx has a child. The grandchild is detached and deleted. xxx_detach is then called which calls device_delete_child for the grandchild a second time causing a panic. It seems to me that any driver which calls device_delete_child as part of detaching must also implement something like: xxx_child_detached() { if (child == sc->child_dev) sc->child_dev = NULL; } xxx_detach() { /* * Remember the child so we can delete it (bus_generic_detach * indirectly zeroes sc->child_dev). */ child = sc->child_dev; bus_generic_detach(); if (child) device_delete_child ... } or am I missing something? -- John ------------------------------------------------------------------------- | Feith Systems | Voice: 1-215-646-8000 | Email: john@feith.com | | John Wehle | Fax: 1-215-540-5495 | | -------------------------------------------------------------------------