[PATCH 3/4 RFC] fsl/msi: Add MSI bank allocation for kernel owned devices

Bharat.Bhushan at freescale.com Bharat.Bhushan at freescale.com
Fri Mar 13 02:46:16 AEDT 2015



> -----Original Message-----
> From: Wood Scott-B07421
> Sent: Thursday, March 12, 2015 4:53 AM
> To: Bhushan Bharat-R65777
> Cc: linuxppc-dev at ozlabs.org
> Subject: Re: [PATCH 3/4 RFC] fsl/msi: Add MSI bank allocation for kernel
> owned devices
> 
> On Tue, 2015-03-03 at 10:47 +0530, Bharat Bhushan wrote:
> > With this patch a "context" can allocate a MSI bank and use the
> > allocated MSI-bank for the devices in that "context".
> >
> > kernel/host "context" is "NULL", So all devices owned by kernel will
> > share a MSI bank allocated with "context = NULL.
> >
> > This patch is in direction to have separate MSI bank for kernel
> > context and userspace/VM context. We do not want two software context
> > (kernel and VMs) to share a MSI bank for safe/reliable interrupts with
> > full isolation. Follow up patch will add interface to allocate a MSI
> > bank for userspace/VM context.
> >
> > NOTE: This RFC patch allows only one MSI bank to be allocated for
> > kernel context. Which seems to be sufficient to me. But if we see this
> > is limiting some real usecase scanerio then this limitation can be
> > removed
> >
> > One issue which still need to addressed is when to free kernel context
> > allocated MSI bank? Say all MSI capable devices are assigned to
> > VM/userspace then there is no need to have any MSI bank reserved for
> > kernel context.
> >
> > Signed-off-by: Bharat Bhushan <Bharat.Bhushan at freescale.com>
> > ---
> >  arch/powerpc/sysdev/fsl_msi.c | 88
> > ++++++++++++++++++++++++++++++++++++++-----
> >  arch/powerpc/sysdev/fsl_msi.h |  4 ++
> >  2 files changed, 83 insertions(+), 9 deletions(-)
> >
> > diff --git a/arch/powerpc/sysdev/fsl_msi.c
> > b/arch/powerpc/sysdev/fsl_msi.c index 32ba1e3..027aeeb 100644
> > --- a/arch/powerpc/sysdev/fsl_msi.c
> > +++ b/arch/powerpc/sysdev/fsl_msi.c
> > @@ -142,6 +142,79 @@ static void fsl_teardown_msi_irqs(struct pci_dev
> *pdev)
> >  	return;
> >  }
> >
> > +/*
> > + * Allocate a MSI Bank for the requested "context".
> > + * NULL "context" means that this request is to allocate
> > + * MSI bank for kernel owned devices. And currently we
> > + * assume that one MSI bank is sufficient for kernel.
> > + */
> > +static struct fsl_msi *fsl_msi_allocate_msi_bank(void *context) {
> > +	struct fsl_msi *msi_data;
> > +
> > +	/* Kernel context (NULL) can reserve only one msi bank */
> > +	if (!context) {
> > +		list_for_each_entry(msi_data, &msi_head, list) {
> > +			if ((msi_data->reserved == MSI_RESERVED) &&
> > +			    (msi_data->context == NULL))
> > +				return NULL;
> > +		}
> 
> Unnecessary parentheses
> 
> Is there any reason why the kernel bank needs to participate in this
> mechanism at all?  Set it aside at MSI driver init, and don't put it on
> the list.  I know you've previously said that you want to support configs
> where the kernel doesn't get any banks, but that can just be a boot
> option that tells the MSI code to not set aside a bank for the kernel.
> It would simplify the code.

I think we cannot completely remove the MSI bank from kernel practically. So I can make the kernel msi bank out of list.

> 
> With the patchset as is, how would one indicate whether kernel devices
> should get a bank?

For kernel owned device, in fsl_setup_msi_irqs() we check if there is a reserved MSI bank, if not then reserve a msi bank. If reserve fails then setup_msi_irq() fails. I think there is no fallback to Legacy interrupt.

>  Specifically, when the kernel does have an MSI-
> capable device but we'd prefer to use legacy interrupts to keep MSIs
> available to VFIO.

Do we want this?

> 
> > +	}
> > +
> > +	list_for_each_entry(msi_data, &msi_head, list) {
> > +		if (msi_data->reserved == MSI_FREE) {
> > +			msi_data->reserved = MSI_RESERVED;
> > +			msi_data->context = context;
> > +			return msi_data;
> > +		}
> > +	}
> 
> What prevents races from parallel callers?

Will add a lock.

> 
> > +/* FIXME: Assumption that host kernel will allocate only one MSI bank
> > +*/
> 
> It's not a FIXME if we think the limitation is not burdensome.

Ok

> 
> > + __attribute__ ((unused)) static int fsl_msi_free_msi_bank(void
> > + *context)
> 
> static int __maybe_unused fsl_msi_free_msi_bank(void *context)
> 
> Why are you adding this function then removing it in the next patch?

Will fix this

> 
> > +	/* If no MSI bank allocated for kernel owned device, allocate one
> */
> > +	msi_data = fsl_msi_allocate_msi_bank(NULL);
> > +	if (msi_data)
> > +		return msi_data;
> > +
> > +	return NULL;
> 
> return fsl_msi_allocate_msi_bank(NULL);

Ok

> 
> 
> > +}
> > +
> >  static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq,
> >  				struct msi_msg *msg,
> >  				struct fsl_msi *fsl_msi_data)
> > @@ -174,7 +247,7 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev,
> int nvec, int type)
> >  	struct pci_controller *hose = pci_bus_to_host(pdev->bus);
> >  	struct device_node *np;
> >  	phandle phandle = 0;
> > -	int rc, hwirq = -ENOMEM;
> > +	int rc = -ENODEV, hwirq = -ENOMEM;
> 
> Initialize rc when you detect the error instead of here (it'd be OK to
> initialize it to zero here, to mitigate potential uninitialized value
> bugs).

Ok

> 
> >  	unsigned int virq;
> >  	struct msi_desc *entry;
> >  	struct msi_msg msg;
> > @@ -231,15 +304,12 @@ static int fsl_setup_msi_irqs(struct pci_dev
> *pdev, int nvec, int type)
> >  		if (specific_msi_bank) {
> >  			hwirq = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1);
> >  		} else {
> > -			/*
> > -			 * Loop over all the MSI devices until we find one that
> has an
> > -			 * available interrupt.
> > -			 */
> > -			list_for_each_entry(msi_data, &msi_head, list) {
> > -				hwirq = msi_bitmap_alloc_hwirqs(&msi_data-
> >bitmap, 1);
> > -				if (hwirq >= 0)
> > -					break;
> > +			msi_data = fsl_msi_get_reserved_msi_bank(pdev);
> > +			if (!msi_data) {
> > +				dev_err(&pdev->dev, "No MSI Bank allocated\n");
> > +				goto out_free;
> 
> Is this really an error?  Seems like dev_info() would be more appropriate
> to indicate the absence of a resource where you can fall back to another
> option.

There is no fallback in fsl_setup_msi_irqs(), We have to error out from fsl_setup_msi_irqs(), no?

> 
> > diff --git a/arch/powerpc/sysdev/fsl_msi.h
> > b/arch/powerpc/sysdev/fsl_msi.h index 9b0ab84..c69702b 100644
> > --- a/arch/powerpc/sysdev/fsl_msi.h
> > +++ b/arch/powerpc/sysdev/fsl_msi.h
> > @@ -46,6 +46,10 @@ struct fsl_msi {
> >  	struct list_head list;          /* support multiple MSI banks */
> >
> >  	phandle phandle;
> > +#define MSI_FREE		0
> > +#define MSI_RESERVED		1
> > +        int reserved;
> > +        void *context;
> 
> Whitespace
> 
> How about just "bool reserved"?  Or if the kernel bank is kept off the
> list, just check context for NULL.

I will try to make kernel bank out of list and see how much this simplifies the code.

Thanks
-Bharat

> 
> -Scott
> 



More information about the Linuxppc-dev mailing list