From owner-freebsd-stable@FreeBSD.ORG Mon Oct 18 21:12:24 2010 Return-Path: Delivered-To: freebsd-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CBF87106564A for ; Mon, 18 Oct 2010 21:12:23 +0000 (UTC) (envelope-from mdf356@gmail.com) Received: from mail-iw0-f182.google.com (mail-iw0-f182.google.com [209.85.214.182]) by mx1.freebsd.org (Postfix) with ESMTP id 8B5388FC0C for ; Mon, 18 Oct 2010 21:12:23 +0000 (UTC) Received: by iwn36 with SMTP id 36so112359iwn.13 for ; Mon, 18 Oct 2010 14:12:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:sender:received:date :x-google-sender-auth:message-id:subject:from:to:content-type; bh=L52WBcv6monsXdkWV35jrsV1nsnloSRCbgqNHvGE7cA=; b=WNVxirdHoGDuOsy39+zP4gmWC96I1DQg5FTsGZ1M5wd8U4Rfjczc/C0HZQdryDvgiN z6cg4Iw+qF4EIcmz7cFR0g0w68EHtfm7/19qgHMLPzhLrUT3AcNYT4p3VJ9ow4GKmGeb MZdh+6otC1HMguYV1k6uSIi1L2qtSm2pas5Lk= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:sender:date:x-google-sender-auth:message-id:subject :from:to:content-type; b=guK6CGVrBWEkvHL31v9Jie9x4kAAL1Bgoyx7euPhPIxy37B6k6uDvkr1NdFNhK4804 Dl7oT2j3KqRmcfuYPgg5bW4JIFyKUKkZs07fB+NPHbD0RpE9LK0BCfJEFws6G9QQMvqj qc9n26B9dS0HlqO0vIHYkW9IJqXcYUyU5js2I= MIME-Version: 1.0 Received: by 10.231.191.6 with SMTP id dk6mr3897764ibb.51.1287434525829; Mon, 18 Oct 2010 13:42:05 -0700 (PDT) Sender: mdf356@gmail.com Received: by 10.231.142.76 with HTTP; Mon, 18 Oct 2010 13:42:05 -0700 (PDT) Date: Mon, 18 Oct 2010 13:42:05 -0700 X-Google-Sender-Auth: D3gyKIYpfgoyNhOHL_M7t3yERy8 Message-ID: From: mdf@FreeBSD.org To: freebsd-stable@freebsd.org Content-Type: text/plain; charset=ISO-8859-1 Subject: kldunload usb panic X-BeenThere: freebsd-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Production branch of FreeBSD source code List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 18 Oct 2010 21:12:24 -0000 When we moved to FreeBSD 7 from 6, issuing a kldunload for usb devices started causing a kernel panic is a USB device was still plugged in (like a keyboard). The kldunload is done as part of an rc.d script that unloads usb since it's not generally needed by our product unless we mounted the root volume from a USB stick. The order doesn't matter much, but doing: kldunload ucom kldunload umass kldunload usb panics with this stack: panic @ time 1287356740.252, thread 0xffffff0016bd64a0: Fatal trap 12: page fault while in kernel mode cpuid = 2 Stack: -------------------------------------------------- kernel:trap_fatal+0xac kernel:trap_pfault+0x24c kernel:trap+0x3d9 kernel:pmap_kextract+0x70 kernel:free+0xcd usb.ko:usb_disconnect_port+0xbd usb.ko:uhub_detach+0xd2 kernel:device_detach+0xb3 kernel:device_delete_child+0x98 kernel:device_delete_child+0x66 usb.ko:uhci_pci_detach+0xac kernel:device_detach+0xb3 kernel:devclass_delete_driver+0xde kernel:driver_module_handler+0x11c kernel:module_unload+0x41 kernel:linker_file_unload+0x19a kernel:kern_kldunload+0x10a kernel:isi_syscall+0x98 kernel:ia32_syscall+0x1cd -------------------------------------------------- cpuid = 2; apic id = 12 fault virtual address = 0xffff80403037b7a8 fault code = supervisor read data, page not present stack pointer = 0x10:0xffffff8bfe2d0450 frame pointer = 0x10:0xffffff8bfe2d0470 code segment = base 0x0, limit 0xfffff, type 0x1b = DPL 0, pres 1, long 1, def32 0, gran 1 processor eflags = interrupt enabled, resume, IOPL = 0 The problem is that device_delete_child will recursively call device_delete_child before calling device_detach(). When device_detach resolves to uhub_detach, it attempts to call usb_disconnect_port() which will iterate over the subdevs array. Each of the pointers of the subdevs array is pointing into already-free'd storage; the free(9) came from the recursive call to device_delete_child(). In this case the code is trying to dereference 0xdeadc0dedeadc0de since this is INVARIANTS with the malloc poisoning on free(9). So questions: (1) is there a simple fix, like defining a devclass_t for the port device, and having it do a detach method cleanup instead of uhub_detach()? I wasn't sure what to put in for the match method, though. (2) reorder the device_detach() with the recursive device_delete_child() loop in device_delete_child()? This makes me pretty nervous as I don't know what else may break, possibly subtly. (3) just don't kldunload? I assume this doesn't happen in stable/8 and later due to the USB stack rewrite, but I haven't actually checked. Thanks, matthew