From patchwork Tue Aug 27 10:25:08 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Wang X-Patchwork-Id: 2850108 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 7B194BF546 for ; Tue, 27 Aug 2013 10:25:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A5F8C2053E for ; Tue, 27 Aug 2013 10:25:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 92520204FB for ; Tue, 27 Aug 2013 10:25:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753379Ab3H0KZL (ORCPT ); Tue, 27 Aug 2013 06:25:11 -0400 Received: from mail-lb0-f181.google.com ([209.85.217.181]:39017 "EHLO mail-lb0-f181.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753148Ab3H0KZK (ORCPT ); Tue, 27 Aug 2013 06:25:10 -0400 Received: by mail-lb0-f181.google.com with SMTP id u14so2368324lbd.40 for ; Tue, 27 Aug 2013 03:25:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=O14ubSTaoSdLm1ZHNTmt5J7DPRoie59pEEjtC2IkP0E=; b=mHVstcjJ7iH52dNiq2FIQzHPCc4GTN5/jUcHdz5vbLx0TY8+D64ADAC3ej1repIazx XTf+4q0q32tGE74GKgeUJUesWI08K4B3+TPXDdXd2u/QAZPuxhQQWJ2zXJgZiQZGM6Xz f9Z99N2rxgm1ZYmPRmgEyos+8ak8Y1wIs7XLFoFwXqODFQvp/vsT8nwbNjgisb+jbKqJ 6RyvoyFw8lglXrubNx0sAMlhoIWFk4RrH3ZxIV+QgFzr1NfcetixMtK97IFSnXXfnznT 5Tr+3zKFHpE0LObJ/X0pldXcTP9hKTRzGCQE1YQfWf+c01ZtoPGv1BqZHGkpSg5cxjXa 5nAA== MIME-Version: 1.0 X-Received: by 10.152.20.36 with SMTP id k4mr1245698lae.33.1377599108221; Tue, 27 Aug 2013 03:25:08 -0700 (PDT) Received: by 10.114.230.72 with HTTP; Tue, 27 Aug 2013 03:25:08 -0700 (PDT) In-Reply-To: <1376189294-32022-28-git-send-email-yinghai@kernel.org> References: <1376189294-32022-1-git-send-email-yinghai@kernel.org> <1376189294-32022-28-git-send-email-yinghai@kernel.org> Date: Tue, 27 Aug 2013 18:25:08 +0800 Message-ID: Subject: Re: [PATCH v4 27/28] PCI, x86, ACPI: Enable ioapic hotplug support with acpi host bridge. From: rui wang To: Yinghai Lu Cc: Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , Tony Luck , Bjorn Helgaas , "Rafael J. Wysocki" , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Spam-Status: No, score=-9.3 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On 8/11/13, Yinghai Lu wrote: > We need to have ioapic setup before normal pci drivers. > otherwise other pci driver can not setup irq. > > So we should not treat them as normal pci devices. > Also we will need to support ioapic hotplug without pci device around. > > We need to call ioapic add/remove during host-bridge add/remove. > > Signed-off-by: Yinghai Lu > --- > drivers/acpi/pci_root.c | 4 ++ > drivers/pci/ioapic.c | 147 > ++++++++++++++++++++++++++++++----------------- > include/linux/pci-acpi.h | 8 +++ > 3 files changed, 106 insertions(+), 53 deletions(-) > > diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c > index 5917839..7577175 100644 > --- a/drivers/acpi/pci_root.c > +++ b/drivers/acpi/pci_root.c > @@ -532,6 +532,8 @@ static int acpi_pci_root_add(struct acpi_device > *device, > pci_enable_bridges(root->bus); > } > > + acpi_pci_ioapic_add(root); > + > pci_bus_add_devices(root->bus); > return 1; > > @@ -546,6 +548,8 @@ static void acpi_pci_root_remove(struct acpi_device > *device) > > pci_stop_root_bus(root->bus); > > + acpi_pci_ioapic_remove(root); > + > device_set_run_wake(root->bus->bridge, false); > pci_acpi_remove_bus_pm_notifier(device); > > diff --git a/drivers/pci/ioapic.c b/drivers/pci/ioapic.c > index 7d6b157..60351b2 100644 > --- a/drivers/pci/ioapic.c > +++ b/drivers/pci/ioapic.c > @@ -22,101 +22,142 @@ > #include > #include > > -struct ioapic { > - acpi_handle handle; > +struct acpi_pci_ioapic { > + acpi_handle root_handle; > u32 gsi_base; > + struct pci_dev *pdev; > + struct list_head list; > }; > > -static int ioapic_probe(struct pci_dev *dev, const struct pci_device_id > *ent) > +static LIST_HEAD(ioapic_list); > +static DEFINE_MUTEX(ioapic_list_lock); > + > +static void handle_ioapic_add(acpi_handle handle, struct pci_dev **pdev, > + u32 *pgsi_base) > { > - acpi_handle handle; > acpi_status status; > unsigned long long gsb; > - struct ioapic *ioapic; > + struct pci_dev *dev; > + u32 gsi_base; > int ret; > char *type; > - struct resource *res; > + struct resource r; > + struct resource *res = &r; > + char objname[64]; > + struct acpi_buffer buffer = {sizeof(objname), objname}; > > - handle = DEVICE_ACPI_HANDLE(&dev->dev); > - if (!handle) > - return -EINVAL; > + *pdev = NULL; > + *pgsi_base = 0; > > status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb); > - if (ACPI_FAILURE(status)) > - return -EINVAL; > - > - /* > - * The previous code in acpiphp evaluated _MAT if _GSB failed, but > - * ACPI spec 4.0 sec 6.2.2 requires _GSB for hot-pluggable I/O APICs. > - */ > + if (ACPI_FAILURE(status) || !gsb) > + return; > > - ioapic = kzalloc(sizeof(*ioapic), GFP_KERNEL); > - if (!ioapic) > - return -ENOMEM; > + dev = acpi_get_pci_dev(handle); > + if (!dev) > + return; > > - ioapic->handle = handle; > - ioapic->gsi_base = (u32) gsb; > + acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); > > - if (dev->class == PCI_CLASS_SYSTEM_PIC_IOAPIC) > - type = "IOAPIC"; > - else > - type = "IOxAPIC"; > + gsi_base = gsb; > + type = "IOxAPIC"; > > ret = pci_enable_device(dev); > if (ret < 0) > - goto exit_free; > + goto exit_put; > > pci_set_master(dev); > > + if (dev->class == PCI_CLASS_SYSTEM_PIC_IOAPIC) > + type = "IOAPIC"; > + > if (pci_request_region(dev, 0, type)) > goto exit_disable; > > res = &dev->resource[0]; > - if (acpi_register_ioapic(ioapic->handle, res->start, ioapic->gsi_base)) > + > + if (acpi_register_ioapic(handle, res->start, gsi_base)) > goto exit_release; Here acpi_register_ioapic() fails for IOAPICs already described by the static MADT. So they won't be added to the ioapic_list. Subsequent hot-removal will also fail because they're not found by acpi_pci_ioapic_remove() on the ioapic_list. Here's what I used to fix it: From 2fff3297b4c71c88d92b04ba9ad0a8931b3e99b8 Mon Sep 17 00:00:00 2001 From: Rui Wang Date: Tue, 27 Aug 2013 11:23:43 -0400 Subject: [PATCH] Hotadd of IOAPICs described in static MADT For IOAPICs described in static MADT, we already called __mp_register_ioapic() in arch_early_irq_init(). During boot PCI root hotadd will call it again and will find it already registered, thus register_ioapic() won't add it to the ioapic_list. Subsequent hot-removal will also fail because it is not found on the ioapic_list. Signed-off-by: Rui Wang --- arch/x86/kernel/apic/io_apic.c | 4 +++- drivers/pci/ioapic.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) return; diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index fb9bf06..15ab9f1 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -3956,8 +3956,10 @@ int __mp_register_ioapic(int id, u32 address, u32 gsi_base, bool hotadd) /* already registered ? */ idx = __mp_find_ioapic(gsi_base); - if (idx >= 0) + if (idx >= 0) { + ret = -EEXIST; goto out; + } idx = find_first_zero_bit(ioapics_mask, MAX_IO_APICS); if (idx >= MAX_IO_APICS) { diff --git a/drivers/pci/ioapic.c b/drivers/pci/ioapic.c index 41f7c69..83b002b 100644 --- a/drivers/pci/ioapic.c +++ b/drivers/pci/ioapic.c @@ -126,7 +126,8 @@ static void handle_ioapic_add(acpi_handle handle, struct pci_dev **pdev, } } - if (acpi_register_ioapic(handle, res->start, gsi_base)) { + ret = acpi_register_ioapic(handle, res->start, gsi_base); + if (ret && ret != -EEXIST) { if (dev) goto exit_release;