Message ID | 20191120012859.23300-18-oohall@gmail.com (mailing list archive) |
---|---|
State | RFC |
Headers | show |
Series | [Very,RFC,01/46] powerpc/eeh: Don't attempt to restore VF config space after reset | expand |
Context | Check | Description |
---|---|---|
snowpatch_ozlabs/apply_patch | warning | Failed to apply on branch powerpc/merge (784eee1cc44801366d4f197e0ade7739ee8e1e83) |
snowpatch_ozlabs/apply_patch | warning | Failed to apply on branch powerpc/next (0695f8bca93ea0c57f0e8e21b4b4db70183b3d1c) |
snowpatch_ozlabs/apply_patch | warning | Failed to apply on branch linus/master (c74386d50fbaf4a54fd3fe560f1abc709c0cff4b) |
snowpatch_ozlabs/apply_patch | warning | Failed to apply on branch powerpc/fixes (7d6475051fb3d9339c5c760ed9883bc0a9048b21) |
snowpatch_ozlabs/apply_patch | warning | Failed to apply on branch linux-next (5d1131b4d61e52e5702e0fa4bcbec81ac7d6ef52) |
snowpatch_ozlabs/apply_patch | fail | Failed to apply to any branch |
On 20/11/2019 12:28, Oliver O'Halloran wrote: > To get away from using pci_dn we need a way to find the edev for a given > bdfn. The easiest way to do this is to find the ioda_pe for that BDFN in > the PHB's reverse mapping table and scan the device list of the > corresponding eeh_pe. > > Is this slow? Yeah probably. Is it slower than the existing "traverse the > pdn tree" method? Probably not. > > Signed-off-by: Oliver O'Halloran <oohall@gmail.com> > --- > arch/powerpc/platforms/powernv/eeh-powernv.c | 31 ++++++++++++++++++++ > arch/powerpc/platforms/powernv/pci.h | 2 ++ > 2 files changed, 33 insertions(+) > > diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c > index f58fe6bda46e..a974822c5097 100644 > --- a/arch/powerpc/platforms/powernv/eeh-powernv.c > +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c > @@ -278,6 +278,37 @@ int pnv_eeh_post_init(void) > return ret; > } > > +struct eeh_dev *pnv_eeh_find_edev(struct pnv_phb *phb, u16 bdfn) > +{ > + struct pnv_ioda_pe *ioda_pe; > + struct eeh_dev *tmp, *edev; > + struct eeh_pe *pe; > + > + /* EEH not enabled ? */ > + if (!(phb->flags & PNV_PHB_FLAG_EEH)) > + return NULL; > + > + /* Fish the EEH PE from the IODA PE */ > + ioda_pe = __pnv_ioda_get_pe(phb, bdfn); > + if (!ioda_pe) > + return NULL; > + > + /* > + * FIXME: Doing a tree-traversal followed by a list traversal > + * on every config access is dumb. Not much dumber than the pci_dn > + * tree traversal we did before, but still quite dumb. Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru> Although I would reduce the comment above to "FIXME: replace 3 traversals with something better". > + */ > + pe = eeh_pe_get(phb->hose, ioda_pe->pe_number, 0); > + if (!pe) > + return NULL; > + > + eeh_pe_for_each_dev(pe, edev, tmp) > + if (edev->bdfn == bdfn) > + return edev; > + > + return NULL; > +} > + > static inline bool pnv_eeh_cfg_blocked(struct eeh_dev *edev) > { > if (!edev || !edev->pe) > diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h > index 3c33a0c91a69..a343f3c8e65c 100644 > --- a/arch/powerpc/platforms/powernv/pci.h > +++ b/arch/powerpc/platforms/powernv/pci.h > @@ -196,6 +196,8 @@ extern void pnv_set_msi_irq_chip(struct pnv_phb *phb, unsigned int virq); > extern unsigned long pnv_pci_ioda2_get_table_size(__u32 page_shift, > __u64 window_size, __u32 levels); > extern int pnv_eeh_post_init(void); > +struct eeh_dev; > +struct eeh_dev *pnv_eeh_find_edev(struct pnv_phb *phb, u16 bdfn); > > __printf(3, 4) > extern void pe_level_printk(const struct pnv_ioda_pe *pe, const char *level, >
diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index f58fe6bda46e..a974822c5097 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -278,6 +278,37 @@ int pnv_eeh_post_init(void) return ret; } +struct eeh_dev *pnv_eeh_find_edev(struct pnv_phb *phb, u16 bdfn) +{ + struct pnv_ioda_pe *ioda_pe; + struct eeh_dev *tmp, *edev; + struct eeh_pe *pe; + + /* EEH not enabled ? */ + if (!(phb->flags & PNV_PHB_FLAG_EEH)) + return NULL; + + /* Fish the EEH PE from the IODA PE */ + ioda_pe = __pnv_ioda_get_pe(phb, bdfn); + if (!ioda_pe) + return NULL; + + /* + * FIXME: Doing a tree-traversal followed by a list traversal + * on every config access is dumb. Not much dumber than the pci_dn + * tree traversal we did before, but still quite dumb. + */ + pe = eeh_pe_get(phb->hose, ioda_pe->pe_number, 0); + if (!pe) + return NULL; + + eeh_pe_for_each_dev(pe, edev, tmp) + if (edev->bdfn == bdfn) + return edev; + + return NULL; +} + static inline bool pnv_eeh_cfg_blocked(struct eeh_dev *edev) { if (!edev || !edev->pe) diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index 3c33a0c91a69..a343f3c8e65c 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h @@ -196,6 +196,8 @@ extern void pnv_set_msi_irq_chip(struct pnv_phb *phb, unsigned int virq); extern unsigned long pnv_pci_ioda2_get_table_size(__u32 page_shift, __u64 window_size, __u32 levels); extern int pnv_eeh_post_init(void); +struct eeh_dev; +struct eeh_dev *pnv_eeh_find_edev(struct pnv_phb *phb, u16 bdfn); __printf(3, 4) extern void pe_level_printk(const struct pnv_ioda_pe *pe, const char *level,
To get away from using pci_dn we need a way to find the edev for a given bdfn. The easiest way to do this is to find the ioda_pe for that BDFN in the PHB's reverse mapping table and scan the device list of the corresponding eeh_pe. Is this slow? Yeah probably. Is it slower than the existing "traverse the pdn tree" method? Probably not. Signed-off-by: Oliver O'Halloran <oohall@gmail.com> --- arch/powerpc/platforms/powernv/eeh-powernv.c | 31 ++++++++++++++++++++ arch/powerpc/platforms/powernv/pci.h | 2 ++ 2 files changed, 33 insertions(+)