Message ID | 20150219184103.GB13745@linux.vnet.ibm.com (mailing list archive) |
---|---|
State | Changes Requested |
Headers | show |
On 02/20/2015 05:41 AM, Nishanth Aravamudan wrote: > After d905c5df9aef ("PPC: POWERNV: move iommu_add_device earlier"), the > refcnt on the kobject backing the IOMMU group for a PCI device is > elevated by each call to pci_dma_dev_setup_pSeriesLP() (via > set_iommu_table_base_and_group). When we go to dlpar a multi-function > PCI device out: > > iommu_reconfig_notifier -> > iommu_free_table -> > iommu_group_put > BUG_ON(tbl->it_group) > > We trip this BUG_ON, because there are still references on the table, so > it is not freed. Fix this by also adding a bus notifier identical to > PowerNV for pSeries. Tested a remove -> add -> remove cycle without > issue where it always hit the BUG_ON without the changes. > > Fixes: d905c5df9aef ("PPC: POWERNV: move iommu_add_device earlier") > Signed-off-by: Nishanth Aravamudan <nacc@linux.vnet.ibm.com> > Cc: stable@kernel.org (3.13+) Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru> > diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c > index 1d3d52dc3ff3..f77fb02f4710 100644 > --- a/arch/powerpc/platforms/pseries/iommu.c > +++ b/arch/powerpc/platforms/pseries/iommu.c > @@ -1340,3 +1340,31 @@ static int __init disable_multitce(char *str) > } > > __setup("multitce=", disable_multitce); > + > +static int tce_iommu_bus_notifier(struct notifier_block *nb, > + unsigned long action, void *data) > +{ > + struct device *dev = data; > + > + switch (action) { > + case BUS_NOTIFY_ADD_DEVICE: > + return iommu_add_device(dev); > + case BUS_NOTIFY_DEL_DEVICE: > + if (dev->iommu_group) > + iommu_del_device(dev); > + return 0; > + default: > + return 0; > + } > +} > + > +static struct notifier_block tce_iommu_bus_nb = { > + .notifier_call = tce_iommu_bus_notifier, > +}; > + > +static int __init tce_iommu_bus_notifier_init(void) > +{ > + bus_register_notifier(&pci_bus_type, &tce_iommu_bus_nb); > + return 0; > +} > +machine_subsys_initcall_sync(pseries, tce_iommu_bus_notifier_init); >
On Thu, 2015-02-19 at 10:41 -0800, Nishanth Aravamudan wrote: > After d905c5df9aef ("PPC: POWERNV: move iommu_add_device earlier"), the > refcnt on the kobject backing the IOMMU group for a PCI device is > elevated by each call to pci_dma_dev_setup_pSeriesLP() (via > set_iommu_table_base_and_group). When we go to dlpar a multi-function > PCI device out: > > iommu_reconfig_notifier -> > iommu_free_table -> > iommu_group_put > BUG_ON(tbl->it_group) > > We trip this BUG_ON, because there are still references on the table, so > it is not freed. Fix this by also adding a bus notifier identical to > PowerNV for pSeries. Please put it somewhere common, arch/powerpc/kernel/iommu.c perhaps, and just add a second machine_init_call() for pseries. cheers
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 1d3d52dc3ff3..f77fb02f4710 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -1340,3 +1340,31 @@ static int __init disable_multitce(char *str) } __setup("multitce=", disable_multitce); + +static int tce_iommu_bus_notifier(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct device *dev = data; + + switch (action) { + case BUS_NOTIFY_ADD_DEVICE: + return iommu_add_device(dev); + case BUS_NOTIFY_DEL_DEVICE: + if (dev->iommu_group) + iommu_del_device(dev); + return 0; + default: + return 0; + } +} + +static struct notifier_block tce_iommu_bus_nb = { + .notifier_call = tce_iommu_bus_notifier, +}; + +static int __init tce_iommu_bus_notifier_init(void) +{ + bus_register_notifier(&pci_bus_type, &tce_iommu_bus_nb); + return 0; +} +machine_subsys_initcall_sync(pseries, tce_iommu_bus_notifier_init);
After d905c5df9aef ("PPC: POWERNV: move iommu_add_device earlier"), the refcnt on the kobject backing the IOMMU group for a PCI device is elevated by each call to pci_dma_dev_setup_pSeriesLP() (via set_iommu_table_base_and_group). When we go to dlpar a multi-function PCI device out: iommu_reconfig_notifier -> iommu_free_table -> iommu_group_put BUG_ON(tbl->it_group) We trip this BUG_ON, because there are still references on the table, so it is not freed. Fix this by also adding a bus notifier identical to PowerNV for pSeries. Tested a remove -> add -> remove cycle without issue where it always hit the BUG_ON without the changes. Fixes: d905c5df9aef ("PPC: POWERNV: move iommu_add_device earlier") Signed-off-by: Nishanth Aravamudan <nacc@linux.vnet.ibm.com> Cc: stable@kernel.org (3.13+)