Re: [PATCH] Fix warning
Hi Bjorn, Did you have chance to look at this one? Regards, Tadeusz On 01/03/12 17:18, tadeusz.st...@intel.com wrote: > From: Tadeusz Struk > Date: Mon, 14 Feb 2011 14:38:18 + > Subject: [PATCH] Fixed warning > > This patch fixes the following warning. > # virsh start fedora16-64 > kernel: [ 133.324565] pci-stub :02:01.1: claimed by stub > kernel: [ 134.163769] pci-stub :02:01.1: enabling device ( -> 0002) > kernel: [ 164.282679] [ cut here ] > kernel: [ 164.282685] WARNING: at drivers/pci/search.c:46 > pci_find_upstream_pcie_bridge+0x87/0x9f() > kernel: [ 164.282687] Hardware name: SandyBridge Platform > kernel: [ 164.282689] Modules linked in: sha512_generic sha256_generic > icp_qa_al(O) nfs fscache auth_rpcgss nfs_acl mga drm ip6table_filter > ip6_tables ebtable_nat ebtables lockd ipt_MASQUERADE iptable_nat nf_nat > nf_conntrack_ipv4 nf_defrag_ipv4 xt_state nf_conntrack xt_CHECKSUM > iptable_mangle tun bridge stp llc sunrpc btrfs zlib_deflate libcrc32c > virtio_net kvm_intel kvm uinput matroxfb_base matroxfb_DAC1064 matroxfb_accel > matroxfb_Ti3026 matroxfb_g450 g450_pll matroxfb_misc e1000e iTCO_wdt > iTCO_vendor_support igb microcode i2c_i801 shpchp serio_raw i2c_core pcspkr > dca [last unloaded: scsi_wait_scan] > kernel: [ 164.282724] Pid: 1233, comm: qemu-kvm Tainted: G O 3.2.5 > #10 > kernel: [ 164.282726] Call Trace: > kernel: [ 164.282732] [] warn_slowpath_common+0x83/0x9b > kernel: [ 164.282735] [] warn_slowpath_null+0x1a/0x1c > kernel: [ 164.282737] [] > pci_find_upstream_pcie_bridge+0x87/0x9f > kernel: [ 164.282741] [] domain_context_mapping+0x50/0xe6 > kernel: [ 164.282744] [] domain_add_dev_info+0x44/0xe3 > kernel: [ 164.282747] [] > intel_iommu_attach_device+0x14f/0x15c > kernel: [ 164.282750] [] iommu_attach_device+0x1c/0x1e > kernel: [ 164.282764] [] kvm_assign_device+0x4a/0x114 > [kvm] > kernel: [ 164.282773] [] > kvm_vm_ioctl_assigned_device+0x434/0xb25 [kvm] > kernel: [ 164.282777] [] ? __do_fault+0x351/0x38b > kernel: [ 164.282781] [] ? arch_local_irq_save+0x15/0x1b > kernel: [ 164.282784] [] ? > _raw_spin_unlock_irqrestore+0x17/0x19 > kernel: [ 164.282787] [] ? pci_conf1_read+0xe1/0xee > kernel: [ 164.282794] [] kvm_vm_ioctl+0x377/0x3ac [kvm] > kernel: [ 164.282797] [] ? pci_read_config+0xa2/0x1bd > kernel: [ 164.282801] [] ? virt_to_head_page+0xe/0x31 > kernel: [ 164.282804] [] do_vfs_ioctl+0x45d/0x49e > kernel: [ 164.282808] [] ? fsnotify_access+0x5f/0x67 > kernel: [ 164.282811] [] sys_ioctl+0x56/0x7b > kernel: [ 164.282814] [] system_call_fastpath+0x16/0x1b > kernel: [ 164.282816] ---[ end trace 6a834ec5ac21cba8 ]--- > > Signed-off-by: Tadeusz Struk > > --- > drivers/pci/search.c |7 +-- > 1 files changed, 5 insertions(+), 2 deletions(-) > > diff --git a/drivers/pci/search.c b/drivers/pci/search.c > index 9d75dc8..7847c6b 100644 > --- a/drivers/pci/search.c > +++ b/drivers/pci/search.c > @@ -26,6 +26,7 @@ struct pci_dev * > pci_find_upstream_pcie_bridge(struct pci_dev *pdev) > { > struct pci_dev *tmp = NULL; > + struct pci_dev *vf = pdev; > > if (pci_is_pcie(pdev)) > return NULL; > @@ -40,8 +41,10 @@ pci_find_upstream_pcie_bridge(struct pci_dev *pdev) > } > /* PCI device should connect to a PCIe bridge */ > if (pdev->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) { > - /* Busted hardware? */ > - WARN_ON_ONCE(1); > + if (!vf->is_virtfn) { > + /* Busted hardware? */ > + WARN_ON_ONCE(1); > + } > return NULL; > } > return pdev; -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] PCI: Device specific reset function
On 13/03/12 02:42, Alex Williamson wrote: > On Mon, 2012-03-12 at 16:55 +0000, Tadeusz Struk wrote: >> I have a use case where I need to cleanup resource allocated for Virtual >> Functions after a guest OS that used it crashed. This cleanup needs to >> be done before the VF is being FLRed. The only possible way to do this >> seems to be by using pci_dev_specific_reset() function. >> This patch adds specific reset function to the pci_driver struct. >> >> Signed-off-by: Tadeusz Struk >> --- >> drivers/pci/quirks.c |4 >> include/linux/pci.h |1 + >> 2 files changed, 5 insertions(+), 0 deletions(-) >> >> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c >> index 6476547..13d224b 100644 >> --- a/drivers/pci/quirks.c >> +++ b/drivers/pci/quirks.c >> @@ -3081,8 +3081,12 @@ static const struct pci_dev_reset_methods >> pci_dev_reset_methods[] = { >> >> int pci_dev_specific_reset(struct pci_dev *dev, int probe) >> { >> +struct pci_driver *drv = dev->driver; >> const struct pci_dev_reset_methods *i; >> >> +if (drv && drv->reset) >> +return drv->reset(dev, probe); >> + > > Isn't this exactly what the below code is for (pci_dev_reset_methods)? > In the case of KVM device assignment, the device should be reset via > this path if the guest crashes, but it may or may not be attached to > pci-stub at the time. I assume you're not adding a reset handler to > pci-stub, so we'll pass through here and use FLR, violating the premise > of the patch. Thanks, > > Alex Hi, The reset handler supposed to be in the "real" driver not in the pci-stub. You are right, at this stage the VF can still be assigned to the pci-stub, which makes it useless in my case. I think the only option for me will be to go with the v2 of the patch. I'll do a bit more testing to make sure this is the case and resend the v2. Thanks, Tadeusz -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] PCI: Device specific reset function
I have a use case where I need to cleanup resource allocated for Virtual Functions after a guest OS that used it crashed. This cleanup needs to be done before the VF is being FLRed. The only possible way to do this seems to be by using pci_dev_specific_reset() function. This patch adds specific reset function to the pci_driver struct. Signed-off-by: Tadeusz Struk --- drivers/pci/quirks.c |4 include/linux/pci.h |1 + 2 files changed, 5 insertions(+), 0 deletions(-) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 6476547..13d224b 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3081,8 +3081,12 @@ static const struct pci_dev_reset_methods pci_dev_reset_methods[] = { int pci_dev_specific_reset(struct pci_dev *dev, int probe) { + struct pci_driver *drv = dev->driver; const struct pci_dev_reset_methods *i; + if (drv && drv->reset) + return drv->reset(dev, probe); + for (i = pci_dev_reset_methods; i->reset; i++) { if ((i->vendor == dev->vendor || i->vendor == (u16)PCI_ANY_ID) && diff --git a/include/linux/pci.h b/include/linux/pci.h index a16b1df..2ccd838 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -560,6 +560,7 @@ struct pci_driver { int (*resume_early) (struct pci_dev *dev); int (*resume) (struct pci_dev *dev); /* Device woken up */ void (*shutdown) (struct pci_dev *dev); + int (*reset) (struct pci_dev *dev, int probe); struct pci_error_handlers *err_handler; struct device_driverdriver; struct pci_dynids dynids; -- 1.7.7.6 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/1] PCI: Device specific reset function
Hi, I have a use case where I need to cleanup resource allocated for Virtual Functions after a guest OS that used it crashed. This cleanup needs to be done before the VF is being FLRed. The only possible way to do this seems to be by using pci_dev_specific_reset() function. Unfortunately this function only works for devices defined in a static table in the drivers/pci/quirks.c file. This patch changes it so that specific reset handler is part of pci_driver struct. drivers/pci/pci.h|1 + drivers/pci/quirks.c | 33 +++-- include/linux/pci.h |1 + 3 files changed, 29 insertions(+), 6 deletions(-) -- Intel Shannon Limited Registered in Ireland Registered Office: Collinstown Industrial Park, Leixlip, County Kildare Registered Number: 308263 Business address: Dromore House, East Park, Shannon, Co. Clare This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/1 v3] PCI: Device specific reset function
--- drivers/pci/pci.h|1 + drivers/pci/quirks.c | 33 +++-- include/linux/pci.h |1 + 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 1009a5e..4d10479 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -315,6 +315,7 @@ struct pci_dev_reset_methods { u16 vendor; u16 device; int (*reset)(struct pci_dev *dev, int probe); + struct list_head list; }; #ifdef CONFIG_PCI_QUIRKS diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 6476547..f423d2f 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3070,26 +3070,47 @@ static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe) } #define PCI_DEVICE_ID_INTEL_82599_SFP_VF 0x10ed - -static const struct pci_dev_reset_methods pci_dev_reset_methods[] = { +static struct pci_dev_reset_methods pci_dev_reset_methods[] = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF, -reset_intel_82599_sfp_virtfn }, + reset_intel_82599_sfp_virtfn }, { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, reset_intel_generic_dev }, - { 0 } }; +static LIST_HEAD(reset_list); + +void pci_dev_specific_reset_add(struct pci_dev_reset_methods *reset_method) +{ + INIT_LIST_HEAD(&reset_method->list); + list_add(&reset_method->list, &reset_list); +} + +static int __init pci_dev_specific_reset_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(pci_dev_reset_methods); i++) { + pci_dev_specific_reset_add(&pci_dev_reset_methods[i]); + } + return 0; +} + +late_initcall(pci_dev_specific_reset_init); + int pci_dev_specific_reset(struct pci_dev *dev, int probe) { const struct pci_dev_reset_methods *i; + struct pci_driver *drv = dev->driver; + + if (drv && drv->reset) + return drv->reset(dev, probe); - for (i = pci_dev_reset_methods; i->reset; i++) { + list_for_each_entry(i, &reset_list, list) { if ((i->vendor == dev->vendor || i->vendor == (u16)PCI_ANY_ID) && (i->device == dev->device || i->device == (u16)PCI_ANY_ID)) return i->reset(dev, probe); } - return -ENOTTY; } diff --git a/include/linux/pci.h b/include/linux/pci.h index a16b1df..a3a0bc5 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -560,6 +560,7 @@ struct pci_driver { int (*resume_early) (struct pci_dev *dev); int (*resume) (struct pci_dev *dev); /* Device woken up */ void (*shutdown) (struct pci_dev *dev); + int (*reset) (struct pci_dev *dev, int probe); /* Device specific reset */ struct pci_error_handlers *err_handler; struct device_driverdriver; struct pci_dynids dynids; -- 1.7.7.6 -- Intel Shannon Limited Registered in Ireland Registered Office: Collinstown Industrial Park, Leixlip, County Kildare Registered Number: 308263 Business address: Dromore House, East Park, Shannon, Co. Clare This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] Dynamically add and remove device specific reset functions
On 02/03/12 16:29, Bjorn Helgaas wrote: > Where do you plan to add calls to pci_dev_specific_reset_add()? In > drivers? Yes, I'm working on a driver for a device with SRIOV capability. I'll call it from there. > Did you consider adding a "reset" function pointer to struct > pci_driver? That might be more natural -- the reset function is right > with all the other code that knows about the device, and there's no > issue with looking up the correct reset function. > With this patch, we sort of have two different ways to map > vendor/device IDs to code: the usual pci_register_driver() approach, > and this one using reset_list. If pci_driver had a "reset" pointer, > that would be used most of the time. You might still need the > reset_list for generic things, e.g., the reset_intel_generic_dev() > function, but it would be a fallback. It might look something like: > > struct pci_driver *drv = dev->driver; > > if (drv && drv->reset) { > drv->reset(dev); > return; > } > > list_for_each_entry(i, &reset_list, list) { > ... > No, I didn't think about it. This is good idea, but for me the pci_dev_specific_reset() works fine. > In that case, you might not even need the ability to dynamically add > things to the list, since the only things to add would be "generic" > things that would be more static. > > Perhaps this approach was previously discussed and discarded; if so, I > missed it. > > Bjorn Do you want me to send another patch that fixes these minor issues you pointed out? Thanks for you comments. Tadeusz -- Intel Shannon Limited Registered in Ireland Registered Office: Collinstown Industrial Park, Leixlip, County Kildare Registered Number: 308263 Business address: Dromore House, East Park, Shannon, Co. Clare This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] Dynamically add and remove device specific reset functions
Hi, Reworked according to comments. I have a use case where I need to cleanup resource allocated for Virtual Functions after a guest OS that used it crashed. This cleanup needs to be done before the VF is being FLRed. The only possible way to do this seems to be by using pci_dev_specific_reset() function. Unfortunately this function only works for devices defined in a static table in the drivers/pci/quirks.c file. This patch changes it so that specific reset functions can be added and deleted dynamically. Signed-off-by: Tadeusz Struk --- drivers/pci/pci.h| 14 +++ drivers/pci/quirks.c | 61 + 2 files changed, 65 insertions(+), 10 deletions(-) diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 1009a5e..3e95df6 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -312,6 +312,7 @@ static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, extern void pci_enable_acs(struct pci_dev *dev); struct pci_dev_reset_methods { + struct list_head list; u16 vendor; u16 device; int (*reset)(struct pci_dev *dev, int probe); @@ -319,11 +320,24 @@ struct pci_dev_reset_methods { #ifdef CONFIG_PCI_QUIRKS extern int pci_dev_specific_reset(struct pci_dev *dev, int probe); +extern int pci_dev_specific_reset_add(struct pci_dev_reset_methods + *reset_method); +extern int pci_dev_specific_reset_remove(struct pci_dev_reset_methods + *reset_method); #else static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe) { return -ENOTTY; } +int pci_dev_specific_reset_add(struct pci_dev_reset_methods *reset_method) +{ + return 0; +} +int +pci_dev_specific_reset_remove(struct pci_dev_reset_methods *reset_method) +{ + return 0; +} #endif #endif /* DRIVERS_PCI_H */ diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 6476547..a0152fd 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3070,26 +3070,67 @@ static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe) } #define PCI_DEVICE_ID_INTEL_82599_SFP_VF 0x10ed - -static const struct pci_dev_reset_methods pci_dev_reset_methods[] = { - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF, -reset_intel_82599_sfp_virtfn }, - { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, +static struct pci_dev_reset_methods pci_dev_reset_methods[] = { + { {NULL, NULL}, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF, + reset_intel_82599_sfp_virtfn }, + { {NULL, NULL}, PCI_VENDOR_ID_INTEL, PCI_ANY_ID, reset_intel_generic_dev }, - { 0 } }; +static DEFINE_SPINLOCK(reset_list_lock); +static LIST_HEAD(reset_list); + +static int __init pci_dev_specific_reset_init(void) +{ + int i; + for (i = 0; i < ARRAY_SIZE(pci_dev_reset_methods); i++) { + pci_dev_specific_reset_add(&pci_dev_reset_methods[i]); + } + return 0; +} + +late_initcall(pci_dev_specific_reset_init); + +int pci_dev_specific_reset_add(struct pci_dev_reset_methods *reset_method) +{ + WARN_ON(!reset_method->reset); + INIT_LIST_HEAD(&reset_method->list); + spin_lock(&reset_list_lock); + list_add(&reset_method->list, &reset_list); + spin_unlock(&reset_list_lock); + return 0; +} +EXPORT_SYMBOL(pci_dev_specific_reset_add); + +int pci_dev_specific_reset_remove(struct pci_dev_reset_methods *reset_method) +{ + spin_lock(&reset_list_lock); + list_del(&reset_method->list); + spin_unlock(&reset_list_lock); + return 0; +} +EXPORT_SYMBOL(pci_dev_specific_reset_remove); + int pci_dev_specific_reset(struct pci_dev *dev, int probe) { const struct pci_dev_reset_methods *i; + spin_lock(&reset_list_lock); + list_for_each_entry(i, &reset_list, list) { + if (i->vendor == dev->vendor && + i->device == dev->device) { + spin_unlock(&reset_list_lock); + return i->reset(dev, probe); + } + } - for (i = pci_dev_reset_methods; i->reset; i++) { + list_for_each_entry(i, &reset_list, list) { if ((i->vendor == dev->vendor || i->vendor == (u16)PCI_ANY_ID) && - (i->device == dev->device || -i->device == (u16)PCI_ANY_ID)) +i->device == (u16)PCI_ANY_ID) { + spin_unlock(&reset_list_lock); return i->reset(dev, probe); + } } - + spin_unlock(&reset_list_lock); return -ENOTTY; } -- 1.7.7.6 -- Intel Shannon Limited Registered in Ireland Registe
[PATCH] Fix warning
>From 268c5427305d59c1f6f6c1ce8047f6e32a7edcac Mon Sep 17 00:00:00 2001 From: Tadeusz Struk Date: Mon, 14 Feb 2011 14:38:18 + Subject: [PATCH] Fixed warning This patch fixes the following warning. # virsh start fedora16-64 kernel: [ 133.324565] pci-stub :02:01.1: claimed by stub kernel: [ 134.163769] pci-stub :02:01.1: enabling device ( -> 0002) kernel: [ 164.282679] [ cut here ] kernel: [ 164.282685] WARNING: at drivers/pci/search.c:46 pci_find_upstream_pcie_bridge+0x87/0x9f() kernel: [ 164.282687] Hardware name: SandyBridge Platform kernel: [ 164.282689] Modules linked in: sha512_generic sha256_generic icp_qa_al(O) nfs fscache auth_rpcgss nfs_acl mga drm ip6table_filter ip6_tables ebtable_nat ebtables lockd ipt_MASQUERADE iptable_nat nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 xt_state nf_conntrack xt_CHECKSUM iptable_mangle tun bridge stp llc sunrpc btrfs zlib_deflate libcrc32c virtio_net kvm_intel kvm uinput matroxfb_base matroxfb_DAC1064 matroxfb_accel matroxfb_Ti3026 matroxfb_g450 g450_pll matroxfb_misc e1000e iTCO_wdt iTCO_vendor_support igb microcode i2c_i801 shpchp serio_raw i2c_core pcspkr dca [last unloaded: scsi_wait_scan] kernel: [ 164.282724] Pid: 1233, comm: qemu-kvm Tainted: G O 3.2.5 #10 kernel: [ 164.282726] Call Trace: kernel: [ 164.282732] [] warn_slowpath_common+0x83/0x9b kernel: [ 164.282735] [] warn_slowpath_null+0x1a/0x1c kernel: [ 164.282737] [] pci_find_upstream_pcie_bridge+0x87/0x9f kernel: [ 164.282741] [] domain_context_mapping+0x50/0xe6 kernel: [ 164.282744] [] domain_add_dev_info+0x44/0xe3 kernel: [ 164.282747] [] intel_iommu_attach_device+0x14f/0x15c kernel: [ 164.282750] [] iommu_attach_device+0x1c/0x1e kernel: [ 164.282764] [] kvm_assign_device+0x4a/0x114 [kvm] kernel: [ 164.282773] [] kvm_vm_ioctl_assigned_device+0x434/0xb25 [kvm] kernel: [ 164.282777] [] ? __do_fault+0x351/0x38b kernel: [ 164.282781] [] ? arch_local_irq_save+0x15/0x1b kernel: [ 164.282784] [] ? _raw_spin_unlock_irqrestore+0x17/0x19 kernel: [ 164.282787] [] ? pci_conf1_read+0xe1/0xee kernel: [ 164.282794] [] kvm_vm_ioctl+0x377/0x3ac [kvm] kernel: [ 164.282797] [] ? pci_read_config+0xa2/0x1bd kernel: [ 164.282801] [] ? virt_to_head_page+0xe/0x31 kernel: [ 164.282804] [] do_vfs_ioctl+0x45d/0x49e kernel: [ 164.282808] [] ? fsnotify_access+0x5f/0x67 kernel: [ 164.282811] [] sys_ioctl+0x56/0x7b kernel: [ 164.282814] [] system_call_fastpath+0x16/0x1b kernel: [ 164.282816] ---[ end trace 6a834ec5ac21cba8 ]--- Signed-off-by: Tadeusz Struk --- drivers/pci/search.c |7 +-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 9d75dc8..7847c6b 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c @@ -26,6 +26,7 @@ struct pci_dev * pci_find_upstream_pcie_bridge(struct pci_dev *pdev) { struct pci_dev *tmp = NULL; + struct pci_dev *vf = pdev; if (pci_is_pcie(pdev)) return NULL; @@ -40,8 +41,10 @@ pci_find_upstream_pcie_bridge(struct pci_dev *pdev) } /* PCI device should connect to a PCIe bridge */ if (pdev->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) { - /* Busted hardware? */ - WARN_ON_ONCE(1); + if (!vf->is_virtfn) { + /* Busted hardware? */ + WARN_ON_ONCE(1); + } return NULL; } return pdev; -- 1.7.7.6 -- Intel Shannon Limited Registered in Ireland Registered Office: Collinstown Industrial Park, Leixlip, County Kildare Registered Number: 308263 Business address: Dromore House, East Park, Shannon, Co. Clare This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Added functionality that allows dynamically add and remove device specific reset functions
>From b4cf24d5987475862de799c78773f13f25ed2af8 Mon Sep 17 00:00:00 2001 From: Tadeusz Struk Date: Tue, 17 Jan 2012 16:45:46 + Subject: [PATCH] Added functionality that allows dynamically add and remove device specific reset functions I have a use case where I need to cleanup resource allocated for Virtual Functions after a guest OS that used it crashed. This cleanup needs to be done before the VF is being FLRed. The only possible way to do this seems to be by using pci_dev_specific_reset() function. Unfortunately this function only works for devices defined in a static table in the drivers/pci/quirks.c file. This patch changes it so that specific reset functions can be added and deleted dynamically. Signed-off-by: Tadeusz Struk --- drivers/pci/pci.h| 19 ++- drivers/pci/quirks.c | 63 ++ 2 files changed, 71 insertions(+), 11 deletions(-) diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 1009a5e..10929d8 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -312,18 +312,35 @@ static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, extern void pci_enable_acs(struct pci_dev *dev); struct pci_dev_reset_methods { + struct list_head list; u16 vendor; u16 device; int (*reset)(struct pci_dev *dev, int probe); }; #ifdef CONFIG_PCI_QUIRKS -extern int pci_dev_specific_reset(struct pci_dev *dev, int probe); +extern int +pci_dev_specific_reset(struct pci_dev *dev, int probe); +extern int +pci_dev_specific_reset_add(const struct pci_dev_reset_methods *reset_method); +extern int +pci_dev_specific_reset_remove(const struct pci_dev_reset_methods *reset_method); + #else static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe) { return -ENOTTY; } +int +pci_dev_specific_reset_add(const struct pci_dev_reset_methods *reset_method) +{ + return 0; +} +int +pci_dev_specific_reset_remove(const struct pci_dev_reset_methods *reset_method) +{ + return 0; +} #endif #endif /* DRIVERS_PCI_H */ diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 6476547..963e527 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3070,26 +3070,69 @@ static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe) } #define PCI_DEVICE_ID_INTEL_82599_SFP_VF 0x10ed +static struct pci_dev_reset_methods intel_82599_sfp_vf_reset = { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82599_SFP_VF, + .reset = reset_intel_82599_sfp_virtfn, + .list = LIST_HEAD_INIT(intel_82599_sfp_vf_reset.list) +} ; -static const struct pci_dev_reset_methods pci_dev_reset_methods[] = { - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF, -reset_intel_82599_sfp_virtfn }, - { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, - reset_intel_generic_dev }, - { 0 } -}; +static struct pci_dev_reset_methods intel_generic_reset = { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_ANY_ID, + .reset = reset_intel_generic_dev, + .list = LIST_HEAD_INIT(intel_generic_reset.list) +} ; + +static DEFINE_SPINLOCK(reset_list_lock); +static LIST_HEAD(reset_list); + + +static int __init pci_dev_specific_reset_init(void) +{ + pci_dev_specific_reset_add(&intel_82599_sfp_vf_reset); + pci_dev_specific_reset_add(&intel_generic_reset); + return 0; +} + +late_initcall(pci_dev_specific_reset_init); + +int +pci_dev_specific_reset_add(const struct pci_dev_reset_methods *reset_method) +{ + if (reset_method && reset_method->reset) { + spin_lock(&reset_list_lock); + list_add((struct list_head *)&reset_method->list, +&reset_list); + spin_unlock(&reset_list_lock); + return 0; + } + return -EINVAL; +} +EXPORT_SYMBOL(pci_dev_specific_reset_add); + +int +pci_dev_specific_reset_remove(const struct pci_dev_reset_methods *reset_method) +{ + if (reset_method) { + spin_lock(&reset_list_lock); + list_del((struct list_head *)(&reset_method->list)); + spin_unlock(&reset_list_lock); + return 0; + } + return -EINVAL; +} +EXPORT_SYMBOL(pci_dev_specific_reset_remove); int pci_dev_specific_reset(struct pci_dev *dev, int probe) { const struct pci_dev_reset_methods *i; - - for (i = pci_dev_reset_methods; i->reset; i++) { + list_for_each_entry(i, &reset_list, list) { if ((i->vendor == dev->vendor || i->vendor == (u16)PCI_ANY_ID) && (i->device == dev->device || i->device == (u16)PCI_ANY_ID)) return i->reset(dev, probe); } - return -ENOTTY; } -- 1.7.7.6