On 10/07/2020 15:23, Oliver O'Halloran wrote:
> Rework the PE allocation logic to allow allocating blocks of PEs rather
> than individually. We'll use this to allocate contigious blocks of PEs for
> the SR-IOVs.

The patch does not do just this, it also adds missing mutexes (which is
good) but still misses them in pnv_pci_sriov_disable() and
pnv_pci_ioda_pe_dump().




> 
> Signed-off-by: Oliver O'Halloran <ooh...@gmail.com>
> ---
>  arch/powerpc/platforms/powernv/pci-ioda.c | 41 ++++++++++++++++++-----
>  arch/powerpc/platforms/powernv/pci.h      |  2 +-
>  2 files changed, 34 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
> b/arch/powerpc/platforms/powernv/pci-ioda.c
> index 2d36a9ebf0e9..c9c25fb0783c 100644
> --- a/arch/powerpc/platforms/powernv/pci-ioda.c
> +++ b/arch/powerpc/platforms/powernv/pci-ioda.c
> @@ -145,23 +145,45 @@ static void pnv_ioda_reserve_pe(struct pnv_phb *phb, 
> int pe_no)
>               return;
>       }
>  
> +     mutex_lock(&phb->ioda.pe_alloc_mutex);
>       if (test_and_set_bit(pe_no, phb->ioda.pe_alloc))
>               pr_debug("%s: PE %x was reserved on PHB#%x\n",
>                        __func__, pe_no, phb->hose->global_number);
> +     mutex_unlock(&phb->ioda.pe_alloc_mutex);
>  
>       pnv_ioda_init_pe(phb, pe_no);
>  }
>  
> -struct pnv_ioda_pe *pnv_ioda_alloc_pe(struct pnv_phb *phb)
> +struct pnv_ioda_pe *pnv_ioda_alloc_pe(struct pnv_phb *phb, int count)
>  {
> -     long pe;
> +     struct pnv_ioda_pe *ret = NULL;
> +     int run = 0, pe, i;
>  
> +     mutex_lock(&phb->ioda.pe_alloc_mutex);
> +
> +     /* scan backwards for a run of @count cleared bits */
>       for (pe = phb->ioda.total_pe_num - 1; pe >= 0; pe--) {
> -             if (!test_and_set_bit(pe, phb->ioda.pe_alloc))
> -                     return pnv_ioda_init_pe(phb, pe);
> +             if (test_bit(pe, phb->ioda.pe_alloc)) {
> +                     run = 0;
> +                     continue;
> +             }
> +
> +             run++;
> +             if (run == count)
> +                     break;
>       }
> +     if (run != count)
> +             goto out;
>  
> -     return NULL;
> +     for (i = pe; i < pe + count; i++) {
> +             set_bit(i, phb->ioda.pe_alloc);
> +             pnv_ioda_init_pe(phb, i);
> +     }
> +     ret = &phb->ioda.pe_array[pe];
> +
> +out:
> +     mutex_unlock(&phb->ioda.pe_alloc_mutex);
> +     return ret;
>  }
>  
>  void pnv_ioda_free_pe(struct pnv_ioda_pe *pe)
> @@ -173,7 +195,10 @@ void pnv_ioda_free_pe(struct pnv_ioda_pe *pe)
>       WARN_ON(pe->npucomp); /* NPUs for nvlink are not supposed to be freed */
>       kfree(pe->npucomp);
>       memset(pe, 0, sizeof(struct pnv_ioda_pe));
> +
> +     mutex_lock(&phb->ioda.pe_alloc_mutex);
>       clear_bit(pe_num, phb->ioda.pe_alloc);
> +     mutex_unlock(&phb->ioda.pe_alloc_mutex);
>  }
>  
>  /* The default M64 BAR is shared by all PEs */
> @@ -976,7 +1001,7 @@ static struct pnv_ioda_pe *pnv_ioda_setup_dev_PE(struct 
> pci_dev *dev)
>       if (pdn->pe_number != IODA_INVALID_PE)
>               return NULL;
>  
> -     pe = pnv_ioda_alloc_pe(phb);
> +     pe = pnv_ioda_alloc_pe(phb, 1);
>       if (!pe) {
>               pr_warn("%s: Not enough PE# available, disabling device\n",
>                       pci_name(dev));
> @@ -1047,7 +1072,7 @@ static struct pnv_ioda_pe *pnv_ioda_setup_bus_PE(struct 
> pci_bus *bus, bool all)
>  
>       /* The PE number isn't pinned by M64 */
>       if (!pe)
> -             pe = pnv_ioda_alloc_pe(phb);
> +             pe = pnv_ioda_alloc_pe(phb, 1);
>  
>       if (!pe) {
>               pr_warn("%s: Not enough PE# available for PCI bus %04x:%02x\n",
> @@ -3065,7 +3090,7 @@ static void __init pnv_pci_init_ioda_phb(struct 
> device_node *np,
>               pnv_ioda_reserve_pe(phb, phb->ioda.root_pe_idx);
>       } else {
>               /* otherwise just allocate one */
> -             root_pe = pnv_ioda_alloc_pe(phb);
> +             root_pe = pnv_ioda_alloc_pe(phb, 1);
>               phb->ioda.root_pe_idx = root_pe->pe_number;
>       }
>  
> diff --git a/arch/powerpc/platforms/powernv/pci.h 
> b/arch/powerpc/platforms/powernv/pci.h
> index 58c97e60c3db..b4c9bdba7217 100644
> --- a/arch/powerpc/platforms/powernv/pci.h
> +++ b/arch/powerpc/platforms/powernv/pci.h
> @@ -223,7 +223,7 @@ int pnv_ioda_deconfigure_pe(struct pnv_phb *phb, struct 
> pnv_ioda_pe *pe);
>  void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe);
>  void pnv_pci_ioda2_release_pe_dma(struct pnv_ioda_pe *pe);
>  
> -struct pnv_ioda_pe *pnv_ioda_alloc_pe(struct pnv_phb *phb);
> +struct pnv_ioda_pe *pnv_ioda_alloc_pe(struct pnv_phb *phb, int count);
>  void pnv_ioda_free_pe(struct pnv_ioda_pe *pe);
>  
>  #ifdef CONFIG_PCI_IOV
> 

-- 
Alexey

Reply via email to