Skip to content

Commit

Permalink
Merge tag 'pci-v3.11-fixes-1' of git://git.kernel.org/pub/scm/linux/k…
Browse files Browse the repository at this point in the history
…ernel/git/helgaas/pci

Pull PCI fixes from Bjorn Helgaas:
 "Yinghai fixed a couple regressions: one resource assignment problem
  introduced in v3.10 that showed up with SR-IOV on powerpc, and another
  SR-IOV hot-remove issue related to refcounting changes we merged for
  v3.11.

  Yinghai is still working on another SR-IOV-related fix or two, which
  will be simpler if pciehp is non-modular, so I included the Kconfig
  changes now to get them in earlier.

  Finally, a minor fix for the ARM Marvell EBU host bridge driver that
  was merged for v3.11

  Hotplug:
      PCI: pciehp: Fix null pointer deref when hot-removing SR-IOV device
      PCI: hotplug: Convert to be builtin only, not modular
      PCI: pciehp: Convert pciehp to be builtin only, not modular

  Resource allocation:
      PCI: Retry allocation of only the resource type that failed

  ARM:
      PCI: mvebu: Disable prefetchable memory support in PCI-to-PCI bridge"

* tag 'pci-v3.11-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci:
  PCI: mvebu: Disable prefetchable memory support in PCI-to-PCI bridge
  PCI: Retry allocation of only the resource type that failed
  PCI: pciehp: Convert pciehp to be builtin only, not modular
  PCI: hotplug: Convert to be builtin only, not modular
  PCI: pciehp: Fix null pointer deref when hot-removing SR-IOV device
  • Loading branch information
Linus Torvalds committed Aug 2, 2013
2 parents 1fe0135 + 36dd1f3 commit aa8032b
Show file tree
Hide file tree
Showing 13 changed files with 87 additions and 44 deletions.
2 changes: 1 addition & 1 deletion arch/ia64/configs/generic_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ CONFIG_ACPI_FAN=m
CONFIG_ACPI_DOCK=y
CONFIG_ACPI_PROCESSOR=m
CONFIG_ACPI_CONTAINER=m
CONFIG_HOTPLUG_PCI=m
CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_ACPI=m
CONFIG_PACKET=y
CONFIG_UNIX=y
Expand Down
2 changes: 1 addition & 1 deletion arch/ia64/configs/gensparse_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ CONFIG_ACPI_BUTTON=m
CONFIG_ACPI_FAN=m
CONFIG_ACPI_PROCESSOR=m
CONFIG_ACPI_CONTAINER=m
CONFIG_HOTPLUG_PCI=m
CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_ACPI=m
CONFIG_PACKET=y
CONFIG_UNIX=y
Expand Down
2 changes: 1 addition & 1 deletion arch/ia64/configs/tiger_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ CONFIG_ACPI_BUTTON=m
CONFIG_ACPI_FAN=m
CONFIG_ACPI_PROCESSOR=m
CONFIG_ACPI_CONTAINER=m
CONFIG_HOTPLUG_PCI=m
CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_ACPI=m
CONFIG_PACKET=y
CONFIG_UNIX=y
Expand Down
2 changes: 1 addition & 1 deletion arch/ia64/configs/xen_domu_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ CONFIG_ACPI_BUTTON=m
CONFIG_ACPI_FAN=m
CONFIG_ACPI_PROCESSOR=m
CONFIG_ACPI_CONTAINER=m
CONFIG_HOTPLUG_PCI=m
CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_ACPI=m
CONFIG_PACKET=y
CONFIG_UNIX=y
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/configs/ppc64_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ CONFIG_SCHED_SMT=y
CONFIG_PPC_DENORMALISATION=y
CONFIG_PCCARD=y
CONFIG_ELECTRA_CF=y
CONFIG_HOTPLUG_PCI=m
CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_RPA=m
CONFIG_HOTPLUG_PCI_RPA_DLPAR=m
CONFIG_PACKET=y
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/configs/ppc64e_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ CONFIG_IRQ_ALL_CPUS=y
CONFIG_SPARSEMEM_MANUAL=y
CONFIG_PCI_MSI=y
CONFIG_PCCARD=y
CONFIG_HOTPLUG_PCI=m
CONFIG_HOTPLUG_PCI=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_XFRM_USER=m
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/configs/pseries_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ CONFIG_PPC_64K_PAGES=y
CONFIG_PPC_SUBPAGE_PROT=y
CONFIG_SCHED_SMT=y
CONFIG_PPC_DENORMALISATION=y
CONFIG_HOTPLUG_PCI=m
CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_RPA=m
CONFIG_HOTPLUG_PCI_RPA_DLPAR=m
CONFIG_PACKET=y
Expand Down
2 changes: 1 addition & 1 deletion arch/sh/configs/sh03_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ CONFIG_PREEMPT=y
CONFIG_CMDLINE_OVERWRITE=y
CONFIG_CMDLINE="console=ttySC1,115200 mem=64M root=/dev/nfs"
CONFIG_PCI=y
CONFIG_HOTPLUG_PCI=m
CONFIG_HOTPLUG_PCI=y
CONFIG_BINFMT_MISC=y
CONFIG_NET=y
CONFIG_PACKET=y
Expand Down
27 changes: 1 addition & 26 deletions drivers/pci/host/pci-mvebu.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,6 @@ struct mvebu_sw_pci_bridge {
u16 secondary_status;
u16 membase;
u16 memlimit;
u16 prefmembase;
u16 prefmemlimit;
u32 prefbaseupper;
u32 preflimitupper;
u16 iobaseupper;
u16 iolimitupper;
u8 cappointer;
Expand Down Expand Up @@ -419,15 +415,7 @@ static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port,
break;

case PCI_PREF_MEMORY_BASE:
*value = (bridge->prefmemlimit << 16 | bridge->prefmembase);
break;

case PCI_PREF_BASE_UPPER32:
*value = bridge->prefbaseupper;
break;

case PCI_PREF_LIMIT_UPPER32:
*value = bridge->preflimitupper;
*value = 0;
break;

case PCI_IO_BASE_UPPER16:
Expand Down Expand Up @@ -501,19 +489,6 @@ static int mvebu_sw_pci_bridge_write(struct mvebu_pcie_port *port,
mvebu_pcie_handle_membase_change(port);
break;

case PCI_PREF_MEMORY_BASE:
bridge->prefmembase = value & 0xffff;
bridge->prefmemlimit = value >> 16;
break;

case PCI_PREF_BASE_UPPER32:
bridge->prefbaseupper = value;
break;

case PCI_PREF_LIMIT_UPPER32:
bridge->preflimitupper = value;
break;

case PCI_IO_BASE_UPPER16:
bridge->iobaseupper = value & 0xffff;
bridge->iolimitupper = value >> 16;
Expand Down
5 changes: 1 addition & 4 deletions drivers/pci/hotplug/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,13 @@
#

menuconfig HOTPLUG_PCI
tristate "Support for PCI Hotplug"
bool "Support for PCI Hotplug"
depends on PCI && SYSFS
---help---
Say Y here if you have a motherboard with a PCI Hotplug controller.
This allows you to add and remove PCI cards while the machine is
powered up and running.

To compile this driver as a module, choose M here: the
module will be called pci_hotplug.

When in doubt, say N.

if HOTPLUG_PCI
Expand Down
9 changes: 8 additions & 1 deletion drivers/pci/hotplug/pciehp_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,14 @@ int pciehp_unconfigure_device(struct slot *p_slot)
if (ret)
presence = 0;

list_for_each_entry_safe(dev, temp, &parent->devices, bus_list) {
/*
* Stopping an SR-IOV PF device removes all the associated VFs,
* which will update the bus->devices list and confuse the
* iterator. Therefore, iterate in reverse so we remove the VFs
* first, then the PF. We do the same in pci_stop_bus_device().
*/
list_for_each_entry_safe_reverse(dev, temp, &parent->devices,
bus_list) {
pci_dev_get(dev);
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) {
pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl);
Expand Down
5 changes: 1 addition & 4 deletions drivers/pci/pcie/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,12 @@ config PCIEPORTBUS
# Include service Kconfig here
#
config HOTPLUG_PCI_PCIE
tristate "PCI Express Hotplug driver"
bool "PCI Express Hotplug driver"
depends on HOTPLUG_PCI && PCIEPORTBUS
help
Say Y here if you have a motherboard that supports PCI Express Native
Hotplug

To compile this driver as a module, choose M here: the
module will be called pciehp.

When in doubt, say N.

source "drivers/pci/pcie/aer/Kconfig"
Expand Down
69 changes: 68 additions & 1 deletion drivers/pci/setup-bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,47 @@ static void assign_requested_resources_sorted(struct list_head *head,
}
}

static unsigned long pci_fail_res_type_mask(struct list_head *fail_head)
{
struct pci_dev_resource *fail_res;
unsigned long mask = 0;

/* check failed type */
list_for_each_entry(fail_res, fail_head, list)
mask |= fail_res->flags;

/*
* one pref failed resource will set IORESOURCE_MEM,
* as we can allocate pref in non-pref range.
* Will release all assigned non-pref sibling resources
* according to that bit.
*/
return mask & (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH);
}

static bool pci_need_to_release(unsigned long mask, struct resource *res)
{
if (res->flags & IORESOURCE_IO)
return !!(mask & IORESOURCE_IO);

/* check pref at first */
if (res->flags & IORESOURCE_PREFETCH) {
if (mask & IORESOURCE_PREFETCH)
return true;
/* count pref if its parent is non-pref */
else if ((mask & IORESOURCE_MEM) &&
!(res->parent->flags & IORESOURCE_PREFETCH))
return true;
else
return false;
}

if (res->flags & IORESOURCE_MEM)
return !!(mask & IORESOURCE_MEM);

return false; /* should not get here */
}

static void __assign_resources_sorted(struct list_head *head,
struct list_head *realloc_head,
struct list_head *fail_head)
Expand All @@ -312,11 +353,24 @@ static void __assign_resources_sorted(struct list_head *head,
* if could do that, could get out early.
* if could not do that, we still try to assign requested at first,
* then try to reassign add_size for some resources.
*
* Separate three resource type checking if we need to release
* assigned resource after requested + add_size try.
* 1. if there is io port assign fail, will release assigned
* io port.
* 2. if there is pref mmio assign fail, release assigned
* pref mmio.
* if assigned pref mmio's parent is non-pref mmio and there
* is non-pref mmio assign fail, will release that assigned
* pref mmio.
* 3. if there is non-pref mmio assign fail or pref mmio
* assigned fail, will release assigned non-pref mmio.
*/
LIST_HEAD(save_head);
LIST_HEAD(local_fail_head);
struct pci_dev_resource *save_res;
struct pci_dev_resource *dev_res;
struct pci_dev_resource *dev_res, *tmp_res;
unsigned long fail_type;

/* Check if optional add_size is there */
if (!realloc_head || list_empty(realloc_head))
Expand Down Expand Up @@ -348,6 +402,19 @@ static void __assign_resources_sorted(struct list_head *head,
return;
}

/* check failed type */
fail_type = pci_fail_res_type_mask(&local_fail_head);
/* remove not need to be released assigned res from head list etc */
list_for_each_entry_safe(dev_res, tmp_res, head, list)
if (dev_res->res->parent &&
!pci_need_to_release(fail_type, dev_res->res)) {
/* remove it from realloc_head list */
remove_from_list(realloc_head, dev_res->res);
remove_from_list(&save_head, dev_res->res);
list_del(&dev_res->list);
kfree(dev_res);
}

free_list(&local_fail_head);
/* Release assigned resource */
list_for_each_entry(dev_res, head, list)
Expand Down

0 comments on commit aa8032b

Please sign in to comment.