From patchwork Tue Apr 30 11:31:39 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gu Zheng X-Patchwork-Id: 240598 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40DC42C00AE for ; Tue, 30 Apr 2013 21:33:56 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760411Ab3D3Ldt (ORCPT ); Tue, 30 Apr 2013 07:33:49 -0400 Received: from cn.fujitsu.com ([222.73.24.84]:10027 "EHLO song.cn.fujitsu.com" rhost-flags-OK-FAIL-OK-OK) by vger.kernel.org with ESMTP id S1760421Ab3D3Ldf (ORCPT ); Tue, 30 Apr 2013 07:33:35 -0400 X-IronPort-AV: E=Sophos;i="4.87,581,1363104000"; d="scan'208,223";a="7159410" Received: from unknown (HELO tang.cn.fujitsu.com) ([10.167.250.3]) by song.cn.fujitsu.com with ESMTP; 30 Apr 2013 19:30:49 +0800 Received: from fnstmail02.fnst.cn.fujitsu.com (tang.cn.fujitsu.com [127.0.0.1]) by tang.cn.fujitsu.com (8.14.3/8.13.1) with ESMTP id r3UBXS4x029882; Tue, 30 Apr 2013 19:33:33 +0800 Received: from [10.167.233.218] ([10.167.233.218]) by fnstmail02.fnst.cn.fujitsu.com (Lotus Domino Release 8.5.3) with ESMTP id 2013043019314718-921410 ; Tue, 30 Apr 2013 19:31:47 +0800 Message-ID: <517FAB9B.6010005@cn.fujitsu.com> Date: Tue, 30 Apr 2013 19:31:39 +0800 From: Gu Zheng User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:7.0.1) Gecko/20110930 Thunderbird/7.0.1 MIME-Version: 1.0 To: Bjorn Helgaas , Yinghai Lu CC: "linux-pci@vger.kernel.org" , linux-kernel , Yasuaki Ishimatsu , Taku Izumi , tangchen , "'Lin Feng'" , Jiang Liu , guz.fnst@cn.fujitsu.com Subject: [PATCH v2 4/4] PCI: Check if the pci device get removed from pci tree already in remove_callback() References: <516FB647.5030203@cn.fujitsu.com> In-Reply-To: X-MIMETrack: Itemize by SMTP Server on mailserver/fnst(Release 8.5.3|September 15, 2011) at 2013/04/30 19:31:47, Serialize by Router on mailserver/fnst(Release 8.5.3|September 15, 2011) at 2013/04/30 19:31:51, Serialize complete at 2013/04/30 19:31:51 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From a870da3615988f53a8949e5f8c907b079162067b Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Tue, 30 Apr 2013 18:45:12 +0800 Subject: [PATCH v2 4/4] PCI: Check if the pci device get removed from pci tree already in remove_callback We found nested removing through: echo -n 1 > /sys/bus/pci/devices/0000\:10\:00.0/remove ; echo -n 1 > /sys/bus/pci/devices/0000\:1a\:01.0/remove will cause kernel crash as bus get freed. [ 418.946462] CPU 4 [ 418.968377] Pid: 512, comm: kworker/u:2 Tainted: G W 3.8.0 #2 FUJITSU-SV PRIMEQUEST 1800E/SB [ 419.081763] RIP: 0010:[] [] pci_bus_read_config_word+0x5e/0x90 [ 420.494137] Call Trace: [ 420.523326] [] ? remove_callback+0x1f/0x40 [ 420.591984] [] pci_pme_active+0x4b/0x1c0 [ 420.658545] [] pci_stop_bus_device+0x57/0xb0 [ 420.729259] [] pci_stop_and_remove_bus_device+0x16/0x30 [ 420.811392] [] remove_callback+0x2b/0x40 [ 420.877955] [] sysfs_schedule_callback_work+0x26/0x70 https://bugzilla.kernel.org/show_bug.cgi?id=54411 We have one patch that will let device hold bus ref to prevent it from being freed, but that will still generate warning. ------------[ cut here ]------------ WARNING: at lib/list_debug.c:53 __list_del_entry+0x63/0xd0() Hardware name: PRIMEQUEST 1800E list_del corruption, ffff8807d1b6c000->next is LIST_POISON1 (dead000000100100) Call Trace: [] warn_slowpath_common+0x7f/0xc0 [] warn_slowpath_fmt+0x46/0x50 [] __list_del_entry+0x63/0xd0 [] list_del+0x11/0x40 [] pci_destroy_dev+0x31/0xc0 [] pci_remove_bus_device+0x5b/0x70 [] pci_stop_and_remove_bus_device+0x1e/0x30 [] remove_callback+0x29/0x40 [] sysfs_schedule_callback_work+0x24/0x70 We can just check if the device get removed from pci tree already in the protection under pci_remove_rescan_mutex. Signed-off-by: Gu Zheng Signed-off-by: Yinghai Lu --- drivers/pci/pci-sysfs.c | 13 ++++++++++--- 1 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 5b4a9d9..18590c1 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -328,10 +328,17 @@ dev_rescan_store(struct device *dev, struct device_attribute *attr, static void remove_callback(struct device *dev) { - struct pci_dev *pdev = to_pci_dev(dev); - + struct pci_dev *pdev = to_pci_dev(dev), *tmp; + bool found = false; + struct pci_bus *bus = pdev->bus; mutex_lock(&pci_remove_rescan_mutex); - pci_stop_and_remove_bus_device(pdev); + list_for_each_entry(tmp, &bus->devices, bus_list) + if (tmp == pdev) { + found = true; + break; + } + if (found) + pci_stop_and_remove_bus_device(pdev); mutex_unlock(&pci_remove_rescan_mutex); }