[PATCH 07/15] powerpc/powernv: Add support for the cxl kernel api on the real phb

Andrew Donnellan andrew.donnellan at au1.ibm.com
Tue Jul 12 20:39:13 AEST 2016


(reviewed late in the evening, apologies if I've missed something)

On 11/07/16 21:50, Ian Munsie wrote:
> From: Ian Munsie <imunsie at au1.ibm.com>
>
> This adds support for the peer model of the cxl kernel api to the
> PowerNV PHB, in which physical function 0 represents the cxl function on
> the card (an XSL in the case of the CX4), which other physical functions
> will use for memory access and interrupt services. It is referred to as
> the peer model as these functions are peers of one another, as opposed
> to the Virtual PHB model which forms a hierarchy.
>
> This patch exports APIs to enable the peer mode, check if a PCI device
> is attached to a PHB in this mode, and to set and get the peer AFU for
> this mode.
>
> The cxl driver will enable this mode for supported cards by calling
> pnv_cxl_enable_phb_kernel_api(). This will set a flag in the PHB to note
> that this mode is enabled, and switch out it's controller_ops for the
> cxl version.
>
> The cxl version of the controller_ops struct implements it's own
> versions of the enable_device_hook and release_device to handle
> refcounting on the peer AFU and to allocate a default context for the
> device.
>
> Once enabled, the cxl kernel API may not be disabled on a PHB. Currently
> there is no safe way to disable cxl mode short of a reboot, so until
> that changes there is no reason to support the disable path.
>
> Signed-off-by: Ian Munsie <imunsie at au1.ibm.com>

Some comments below - with those addressed:

Reviewed-by: Andrew Donnellan <andrew.donnellan at au1.ibm.com>

>
> ---
>
> V1->V2:
> 	- Add an explanation of the peer model to the commit message,
> 	  and a comment above the pnv_cxl_enable_device_hook function.

The comments are good!

> +/*
> + * Sets flags and switches the controller ops to enable the cxl kernel api.
> + * Original the cxl kernel API operated on a virtual PHB, but certain cards

Originally

> + * such as the Mellanox CX4 use a peer model instead and for these cards the
> + * cxl kernel api will operate on the real PHB.
> + */
> +int pnv_cxl_enable_phb_kernel_api(struct pci_controller *hose, bool enable)
> +{
> +	struct pnv_phb *phb = hose->private_data;
> +	struct module *cxl_module;
> +
> +	if (!enable) {
> +		/*
> +		 * Once cxl mode is enabled on the PHB, there is currently no
> +		 * known safe method to disable it again, and trying risks a
> +		 * checkstop. If we can find a way to safely disable cxl mode
> +		 * in the future we can revisit this, but for now the only sane
> +		 * thing to do is to refuse to disable cxl mode:
> +		 */
> +		return -EPERM;
> +	}
> +
> +	/*
> +	 * Hold a reference to the cxl module since several PHB operations now
> +	 * depend on it, and it would be insane to allow it to be removed so
> +	 * long as we are in this mode (and since we can't safely disable this
> +	 * mode once enabled...).
> +	 */
> +	mutex_lock(&module_mutex);
> +	cxl_module = find_module("cxl");
> +	if (cxl_module)
> +		__module_get(cxl_module);
> +	mutex_unlock(&module_mutex);
> +	if (!cxl_module)
> +		return -ENODEV;
> +
> +	phb->flags |= PNV_PHB_FLAG_CXL;
> +	hose->controller_ops = pnv_cxl_cx4_ioda_controller_ops;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(pnv_cxl_enable_phb_kernel_api);
> +
> +bool pnv_pci_on_cxl_phb(struct pci_dev *dev)
> +{
> +	struct pci_controller *hose = pci_bus_to_host(dev->bus);
> +	struct pnv_phb *phb = hose->private_data;
> +
> +	return !!(phb->flags & PNV_PHB_FLAG_CXL);
> +}
> +EXPORT_SYMBOL(pnv_pci_on_cxl_phb);

Should these two exports be _GPL as well?

> -static void pnv_pci_release_device(struct pci_dev *pdev)
> +void pnv_pci_release_device(struct pci_dev *pdev)

Why is this being unstatic-ified? I don't see us introducing any new 
uses of it.

>  {
>  	struct pci_controller *hose = pci_bus_to_host(pdev->bus);
>  	struct pnv_phb *phb = hose->private_data;
> @@ -3423,7 +3423,7 @@ static void pnv_pci_ioda_shutdown(struct pci_controller *hose)
>  		       OPAL_ASSERT_RESET);
>  }
>
> -static const struct pci_controller_ops pnv_pci_ioda_controller_ops = {
> +const struct pci_controller_ops pnv_pci_ioda_controller_ops = {

It looks like we don't currently use this - is this being unstatic-ised 
in view of allowing a switch back to regular mode in future?

>  extern struct pci_ops pnv_pci_ops;
> @@ -218,6 +222,8 @@ extern int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type);
>  extern void pnv_teardown_msi_irqs(struct pci_dev *pdev);
>  extern struct pnv_ioda_pe *pnv_ioda_get_pe(struct pci_dev *dev);
>  extern void pnv_set_msi_irq_chip(struct pnv_phb *phb, unsigned int virq);
> +extern bool pnv_pci_enable_device_hook(struct pci_dev *dev);
> +extern void pnv_pci_release_device(struct pci_dev *pdev);
>
>  extern void pe_level_printk(const struct pnv_ioda_pe *pe, const char *level,
>  			    const char *fmt, ...);
> @@ -238,4 +244,14 @@ extern long pnv_npu_unset_window(struct pnv_ioda_pe *npe, int num);
>  extern void pnv_npu_take_ownership(struct pnv_ioda_pe *npe);
>  extern void pnv_npu_release_ownership(struct pnv_ioda_pe *npe);
>
> +
> +/* cxl functions */
> +extern bool pnv_cxl_enable_device_hook(struct pci_dev *dev);
> +extern void pnv_cxl_disable_device(struct pci_dev *dev);
> +
> +
> +/* phb ops (cxl switches these when enabling the kernel api on the phb) */
> +extern const struct pci_controller_ops pnv_cxl_cx4_ioda_controller_ops;
> +extern const struct pci_controller_ops pnv_pci_ioda_controller_ops;

See applicable comments about static.

-- 
Andrew Donnellan              OzLabs, ADL Canberra
andrew.donnellan at au1.ibm.com  IBM Australia Limited



More information about the Linuxppc-dev mailing list