From patchwork Tue Dec 18 00:45:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Michael S. Tsirkin" X-Patchwork-Id: 10734571 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D4C2013AD for ; Tue, 18 Dec 2018 00:45:46 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9C522204BF for ; Tue, 18 Dec 2018 00:45:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 900BD26E75; Tue, 18 Dec 2018 00:45:46 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1F2F4204BF for ; Tue, 18 Dec 2018 00:45:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726296AbeLRApp (ORCPT ); Mon, 17 Dec 2018 19:45:45 -0500 Received: from mx1.redhat.com ([209.132.183.28]:50278 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726276AbeLRApo (ORCPT ); Mon, 17 Dec 2018 19:45:44 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E5188C0BF2CB; Tue, 18 Dec 2018 00:45:43 +0000 (UTC) Received: from redhat.com (ovpn-120-67.rdu2.redhat.com [10.10.120.67]) by smtp.corp.redhat.com (Postfix) with SMTP id 2EF601001F45; Tue, 18 Dec 2018 00:45:42 +0000 (UTC) Date: Mon, 17 Dec 2018 19:45:41 -0500 From: "Michael S. Tsirkin" To: linux-kernel@vger.kernel.org Cc: xuyandong , stable@vger.kernel.org, Yinghai Lu , Jesse Barnes , Bjorn Helgaas , linux-pci@vger.kernel.org Subject: [PATCH v2] PCI: avoid bridge feature re-probing on hotplug Message-ID: <20181218004455.20186-1-mst@redhat.com> MIME-Version: 1.0 Content-Disposition: inline X-Mutt-Fcc: =sent X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Tue, 18 Dec 2018 00:45:44 +0000 (UTC) Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP commit 1f82de10d6b1 ("PCI/x86: don't assume prefetchable ranges are 64bit") added probing of bridge support for 64 bit memory each time bridge is re-enumerated. Unfortunately this probing is destructive if any device behind the bridge is in use at this time. This was observed in the field, see https://lists.gnu.org/archive/html/qemu-devel/2018-12/msg01711.html and specifically https://lists.gnu.org/archive/html/qemu-devel/2018-12/msg02082.html There's no real need to re-probe the bridge features as the registers in question never change - detect that using the memory flag being set (it's always set on the 1st pass since all PCI2PCI bridges support memory forwarding) and skip the probing. Thus, only the first call will perform the disruptive probing and sets the resource flags as required - which we can be reasonably sure happens before any devices have been configured. Avoiding repeated calls to pci_bridge_check_ranges might be even nicer. Unfortunately I couldn't come up with a clean way to do it without a major probing code refactoring. Reported-by: xuyandong Tested-by: xuyandong Cc: stable@vger.kernel.org Cc: Yinghai Lu Cc: Jesse Barnes Signed-off-by: Michael S. Tsirkin --- Please review and consider for stable. changes from v1: comment and commit log updates to address comments by Bjorn. drivers/pci/setup-bus.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index ed960436df5e..d5c25d465d97 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -741,6 +741,16 @@ static void pci_bridge_check_ranges(struct pci_bus *bus) struct resource *b_res; b_res = &bridge->resource[PCI_BRIDGE_RESOURCES]; + + /* + * Don't re-check after this was called once already: + * important since bridge might be in use. + * Note: this is only reliable because as per spec all PCI to PCI + * bridges support memory unconditionally so IORESOURCE_MEM is set. + */ + if (b_res[1].flags & IORESOURCE_MEM) + return; + b_res[1].flags |= IORESOURCE_MEM; pci_read_config_word(bridge, PCI_IO_BASE, &io);