From: Auger Eric <eric.auger@redhat.com> To: Thomas Gleixner <tglx@linutronix.de> Cc: eric.auger.pro@gmail.com, marc.zyngier@arm.com, christoffer.dall@linaro.org, andre.przywara@arm.com, robin.murphy@arm.com, alex.williamson@redhat.com, will.deacon@arm.com, joro@8bytes.org, jason@lakedaemon.net, linux-arm-kernel@lists.infradead.org, drjones@redhat.com, kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org, pbonzini@redhat.com, linux-kernel@vger.kernel.org, Bharat.Bhushan@freescale.com, pranav.sawargaonkar@gmail.com, p.fedin@samsung.com, iommu@lists.linux-foundation.org, Jean-Philippe.Brucker@arm.com, yehuday@marvell.com, Manish.Jaggi@caviumnetworks.com, robert.richter@caviumnetworks.com Subject: Re: [PATCH v11 09/10] genirq/msi: map/unmap the MSI doorbells on msi_domain_alloc/free_irqs Date: Mon, 25 Jul 2016 18:21:45 +0200 [thread overview] Message-ID: <75f5e846-6ca4-4178-e7aa-fed90e45e546@redhat.com> (raw) In-Reply-To: <alpine.DEB.2.11.1607201016060.3564@nanos> Hi Thomas, On 20/07/2016 11:04, Thomas Gleixner wrote: > On Tue, 19 Jul 2016, Eric Auger wrote: >> /** >> + * msi_handle_doorbell_mappings: in case the irq data corresponds to an >> + * MSI that requires iommu mapping, traverse the irq domain hierarchy >> + * to retrieve the doorbells to handle and iommu_map/unmap them according >> + * to @map boolean. >> + * >> + * @data: irq data handle >> + * @map: mapping if true, unmapping if false >> + */ > > > Please run that through the kernel doc generator. It does not work that way. > > The format is: > > /** > * function_name - Short function description > * @arg1: Description of arg1 > * @argument2: Description of argument2 > * > * Long explanation including documentation of the return values. > */ > >> +static int msi_handle_doorbell_mappings(struct irq_data *data, bool map) >> +{ >> + const struct irq_chip_msi_doorbell_info *dbinfo; >> + struct iommu_domain *domain; >> + struct irq_chip *chip; >> + struct device *dev; >> + dma_addr_t iova; >> + int ret = 0, cpu; >> + >> + while (data) { >> + dev = msi_desc_to_dev(irq_data_get_msi_desc(data)); >> + domain = iommu_msi_domain(dev); >> + if (domain) { >> + chip = irq_data_get_irq_chip(data); >> + if (chip->msi_doorbell_info) >> + break; >> + } >> + data = data->parent_data; >> + } > > Please split that out into a seperate function > > struct irq_data *msi_get_doorbell_info(data) > { > ..... > if (chip->msi_doorbell_info) > return chip->msi_get_doorbell_info(data); > } > return NULL; > } > > info = msi_get_doorbell_info(data); > ..... > >> + if (!data) >> + return 0; >> + >> + dbinfo = chip->msi_doorbell_info(data); >> + if (!dbinfo) >> + return -EINVAL; >> + >> + if (!dbinfo->doorbell_is_percpu) { >> + if (!map) { >> + iommu_msi_put_doorbell_iova(domain, >> + dbinfo->global_doorbell); >> + return 0; >> + } >> + return iommu_msi_get_doorbell_iova(domain, >> + dbinfo->global_doorbell, >> + dbinfo->size, dbinfo->prot, >> + &iova); >> + } > > You can spare an indentation level with a helper function > > if (!dbinfo->doorbell_is_percpu) > return msi_map_global_doorbell(domain, dbinfo); > >> + >> + /* percpu doorbells */ >> + for_each_possible_cpu(cpu) { >> + phys_addr_t __percpu *db_addr = >> + per_cpu_ptr(dbinfo->percpu_doorbells, cpu); >> + >> + if (!map) { >> + iommu_msi_put_doorbell_iova(domain, *db_addr); >> + } else { >> + >> + ret = iommu_msi_get_doorbell_iova(domain, *db_addr, >> + dbinfo->size, >> + dbinfo->prot, &iova); >> + if (ret) >> + return ret; >> + } >> + } > > Same here: > > for_each_possible_cpu(cpu) { > ret = msi_map_percpu_doorbell(domain, cpu); > if (ret) > return ret; > } > return 0; > > Hmm? > >> + >> + return 0; >> +} >> + >> +/** >> * msi_domain_alloc_irqs - Allocate interrupts from a MSI interrupt domain >> * @domain: The domain to allocate from >> * @dev: Pointer to device struct of the device for which the interrupts >> @@ -352,17 +423,29 @@ int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev, >> >> virq = __irq_domain_alloc_irqs(domain, virq, desc->nvec_used, >> dev_to_node(dev), &arg, false); >> - if (virq < 0) { >> - ret = -ENOSPC; >> - if (ops->handle_error) >> - ret = ops->handle_error(domain, desc, ret); >> - if (ops->msi_finish) >> - ops->msi_finish(&arg, ret); >> - return ret; >> - } >> + if (virq < 0) >> + goto error; >> >> for (i = 0; i < desc->nvec_used; i++) >> irq_set_msi_desc_off(virq, i, desc); >> + >> + for (i = 0; i < desc->nvec_used; i++) { >> + struct irq_data *d = irq_get_irq_data(virq + i); >> + >> + ret = msi_handle_doorbell_mappings(d, true); >> + if (ret) >> + break; >> + } >> + if (ret) { >> + for (; i >= 0; i--) { >> + struct irq_data *d = irq_get_irq_data(virq + i); >> + >> + msi_handle_doorbell_mappings(d, false); >> + } >> + irq_domain_free_irqs(virq, desc->nvec_used); >> + desc->irq = 0; >> + goto error; > > How is that supposed to work? You clear desc->irq and then you call > ops->handle_error. if I don't clear the desc->irq I enter an infinite loop in pci_enable_msix_range. This happens because msix_capability_init and pcie_enable_msix returns 1. In msix_capability_init, at out_avail: we enumerate the msi_desc which have a non zero irq, hence the returned value equal to 1. Currently the only handle_error ops I found, pci_msi_domain_handle_error does not use irq field so works although questionable. As for the irq_domain_free_irqs I think I can remove it since handled later. How do you advise to handle the above situation? Thanks Eric > > Why are you adding this extra stuff here? Look at the call sites of > msi_domain_alloc_irqs(). All of them use msi_domain_free_irqs() in case of > error. There is no reason why you can't do the same.... > >> /** >> @@ -396,6 +486,9 @@ void msi_domain_free_irqs(struct irq_domain *domain, struct device *dev) >> * entry. If that's the case, don't do anything. >> */ >> if (desc->irq) { >> + msi_handle_doorbell_mappings( >> + irq_get_irq_data(desc->irq), >> + false); >> irq_domain_free_irqs(desc->irq, desc->nvec_used); >> desc->irq = 0; > > Can you please restructure the code so it reads > > if (desc->irq) > continue; > > msi_handle_doorbell_mappings(irq_get_irq_data(desc->irq), > false); > irq_domain_free_irqs(desc->irq, desc->nvec_used); > desc->irq = 0; > > Just blindly whacking stuff into the 80 char limit is not helping readability. > > Thanks, > > tglx >
WARNING: multiple messages have this Message-ID (diff)
From: eric.auger@redhat.com (Auger Eric) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH v11 09/10] genirq/msi: map/unmap the MSI doorbells on msi_domain_alloc/free_irqs Date: Mon, 25 Jul 2016 18:21:45 +0200 [thread overview] Message-ID: <75f5e846-6ca4-4178-e7aa-fed90e45e546@redhat.com> (raw) In-Reply-To: <alpine.DEB.2.11.1607201016060.3564@nanos> Hi Thomas, On 20/07/2016 11:04, Thomas Gleixner wrote: > On Tue, 19 Jul 2016, Eric Auger wrote: >> /** >> + * msi_handle_doorbell_mappings: in case the irq data corresponds to an >> + * MSI that requires iommu mapping, traverse the irq domain hierarchy >> + * to retrieve the doorbells to handle and iommu_map/unmap them according >> + * to @map boolean. >> + * >> + * @data: irq data handle >> + * @map: mapping if true, unmapping if false >> + */ > > > Please run that through the kernel doc generator. It does not work that way. > > The format is: > > /** > * function_name - Short function description > * @arg1: Description of arg1 > * @argument2: Description of argument2 > * > * Long explanation including documentation of the return values. > */ > >> +static int msi_handle_doorbell_mappings(struct irq_data *data, bool map) >> +{ >> + const struct irq_chip_msi_doorbell_info *dbinfo; >> + struct iommu_domain *domain; >> + struct irq_chip *chip; >> + struct device *dev; >> + dma_addr_t iova; >> + int ret = 0, cpu; >> + >> + while (data) { >> + dev = msi_desc_to_dev(irq_data_get_msi_desc(data)); >> + domain = iommu_msi_domain(dev); >> + if (domain) { >> + chip = irq_data_get_irq_chip(data); >> + if (chip->msi_doorbell_info) >> + break; >> + } >> + data = data->parent_data; >> + } > > Please split that out into a seperate function > > struct irq_data *msi_get_doorbell_info(data) > { > ..... > if (chip->msi_doorbell_info) > return chip->msi_get_doorbell_info(data); > } > return NULL; > } > > info = msi_get_doorbell_info(data); > ..... > >> + if (!data) >> + return 0; >> + >> + dbinfo = chip->msi_doorbell_info(data); >> + if (!dbinfo) >> + return -EINVAL; >> + >> + if (!dbinfo->doorbell_is_percpu) { >> + if (!map) { >> + iommu_msi_put_doorbell_iova(domain, >> + dbinfo->global_doorbell); >> + return 0; >> + } >> + return iommu_msi_get_doorbell_iova(domain, >> + dbinfo->global_doorbell, >> + dbinfo->size, dbinfo->prot, >> + &iova); >> + } > > You can spare an indentation level with a helper function > > if (!dbinfo->doorbell_is_percpu) > return msi_map_global_doorbell(domain, dbinfo); > >> + >> + /* percpu doorbells */ >> + for_each_possible_cpu(cpu) { >> + phys_addr_t __percpu *db_addr = >> + per_cpu_ptr(dbinfo->percpu_doorbells, cpu); >> + >> + if (!map) { >> + iommu_msi_put_doorbell_iova(domain, *db_addr); >> + } else { >> + >> + ret = iommu_msi_get_doorbell_iova(domain, *db_addr, >> + dbinfo->size, >> + dbinfo->prot, &iova); >> + if (ret) >> + return ret; >> + } >> + } > > Same here: > > for_each_possible_cpu(cpu) { > ret = msi_map_percpu_doorbell(domain, cpu); > if (ret) > return ret; > } > return 0; > > Hmm? > >> + >> + return 0; >> +} >> + >> +/** >> * msi_domain_alloc_irqs - Allocate interrupts from a MSI interrupt domain >> * @domain: The domain to allocate from >> * @dev: Pointer to device struct of the device for which the interrupts >> @@ -352,17 +423,29 @@ int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev, >> >> virq = __irq_domain_alloc_irqs(domain, virq, desc->nvec_used, >> dev_to_node(dev), &arg, false); >> - if (virq < 0) { >> - ret = -ENOSPC; >> - if (ops->handle_error) >> - ret = ops->handle_error(domain, desc, ret); >> - if (ops->msi_finish) >> - ops->msi_finish(&arg, ret); >> - return ret; >> - } >> + if (virq < 0) >> + goto error; >> >> for (i = 0; i < desc->nvec_used; i++) >> irq_set_msi_desc_off(virq, i, desc); >> + >> + for (i = 0; i < desc->nvec_used; i++) { >> + struct irq_data *d = irq_get_irq_data(virq + i); >> + >> + ret = msi_handle_doorbell_mappings(d, true); >> + if (ret) >> + break; >> + } >> + if (ret) { >> + for (; i >= 0; i--) { >> + struct irq_data *d = irq_get_irq_data(virq + i); >> + >> + msi_handle_doorbell_mappings(d, false); >> + } >> + irq_domain_free_irqs(virq, desc->nvec_used); >> + desc->irq = 0; >> + goto error; > > How is that supposed to work? You clear desc->irq and then you call > ops->handle_error. if I don't clear the desc->irq I enter an infinite loop in pci_enable_msix_range. This happens because msix_capability_init and pcie_enable_msix returns 1. In msix_capability_init, at out_avail: we enumerate the msi_desc which have a non zero irq, hence the returned value equal to 1. Currently the only handle_error ops I found, pci_msi_domain_handle_error does not use irq field so works although questionable. As for the irq_domain_free_irqs I think I can remove it since handled later. How do you advise to handle the above situation? Thanks Eric > > Why are you adding this extra stuff here? Look at the call sites of > msi_domain_alloc_irqs(). All of them use msi_domain_free_irqs() in case of > error. There is no reason why you can't do the same.... > >> /** >> @@ -396,6 +486,9 @@ void msi_domain_free_irqs(struct irq_domain *domain, struct device *dev) >> * entry. If that's the case, don't do anything. >> */ >> if (desc->irq) { >> + msi_handle_doorbell_mappings( >> + irq_get_irq_data(desc->irq), >> + false); >> irq_domain_free_irqs(desc->irq, desc->nvec_used); >> desc->irq = 0; > > Can you please restructure the code so it reads > > if (desc->irq) > continue; > > msi_handle_doorbell_mappings(irq_get_irq_data(desc->irq), > false); > irq_domain_free_irqs(desc->irq, desc->nvec_used); > desc->irq = 0; > > Just blindly whacking stuff into the 80 char limit is not helping readability. > > Thanks, > > tglx >
next prev parent reply other threads:[~2016-07-25 16:21 UTC|newest] Thread overview: 81+ messages / expand[flat|nested] mbox.gz Atom feed top 2016-07-19 13:02 [PATCH v11 00/10] KVM PCIe/MSI passthrough on ARM/ARM64: kernel part 2/3: msi changes Eric Auger 2016-07-19 13:02 ` Eric Auger 2016-07-19 13:02 ` Eric Auger 2016-07-19 13:02 ` [PATCH v11 01/10] genirq/msi: export msi_get_domain_info Eric Auger 2016-07-19 13:02 ` Eric Auger 2016-07-19 13:02 ` Eric Auger 2016-07-19 13:02 ` [PATCH v11 02/10] genirq/msi: msi_compose wrapper Eric Auger 2016-07-19 13:02 ` Eric Auger 2016-07-19 13:02 ` Eric Auger 2016-07-19 13:02 ` [PATCH v11 03/10] genirq/irq: introduce msi_doorbell_info Eric Auger 2016-07-19 13:02 ` Eric Auger 2016-07-19 13:02 ` Eric Auger 2016-07-19 14:15 ` Thomas Gleixner 2016-07-19 14:15 ` Thomas Gleixner 2016-07-19 14:15 ` Thomas Gleixner 2016-07-19 13:02 ` [PATCH v11 04/10] genirq/msi-doorbell: allow MSI doorbell (un)registration Eric Auger 2016-07-19 13:02 ` Eric Auger 2016-07-19 14:22 ` Thomas Gleixner 2016-07-19 14:22 ` Thomas Gleixner 2016-07-19 14:22 ` Thomas Gleixner 2016-07-20 7:50 ` Auger Eric 2016-07-20 7:50 ` Auger Eric 2016-07-20 7:50 ` Auger Eric 2016-07-19 13:02 ` [PATCH v11 05/10] genirq/msi-doorbell: msi_doorbell_pages Eric Auger 2016-07-19 13:02 ` Eric Auger 2016-07-19 13:02 ` Eric Auger 2016-07-19 14:38 ` Thomas Gleixner 2016-07-19 14:38 ` Thomas Gleixner 2016-07-19 14:38 ` Thomas Gleixner 2016-07-20 7:50 ` Auger Eric 2016-07-20 7:50 ` Auger Eric 2016-07-20 7:50 ` Auger Eric 2016-07-21 13:38 ` Auger Eric 2016-07-21 13:38 ` Auger Eric 2016-07-19 13:02 ` [PATCH v11 06/10] genirq/msi-doorbell: msi_doorbell_safe Eric Auger 2016-07-19 13:02 ` Eric Auger 2016-07-20 8:12 ` Thomas Gleixner 2016-07-20 8:12 ` Thomas Gleixner 2016-07-20 8:12 ` Thomas Gleixner 2016-07-21 13:38 ` Auger Eric 2016-07-21 13:38 ` Auger Eric 2016-07-21 13:38 ` Auger Eric 2016-07-22 12:44 ` Thomas Gleixner 2016-07-22 12:44 ` Thomas Gleixner 2016-07-22 12:44 ` Thomas Gleixner 2016-07-22 14:08 ` Auger Eric 2016-07-22 14:08 ` Auger Eric 2016-07-19 13:02 ` [PATCH v11 07/10] irqchip/gicv2m: register the MSI global doorbell Eric Auger 2016-07-19 13:02 ` Eric Auger 2016-07-19 13:02 ` Eric Auger 2016-07-19 13:02 ` [PATCH v11 08/10] irqchip/gicv3-its: " Eric Auger 2016-07-19 13:02 ` Eric Auger 2016-07-19 13:02 ` Eric Auger 2016-07-19 13:02 ` [PATCH v11 09/10] genirq/msi: map/unmap the MSI doorbells on msi_domain_alloc/free_irqs Eric Auger 2016-07-19 13:02 ` Eric Auger 2016-07-19 13:02 ` Eric Auger 2016-07-20 9:04 ` Thomas Gleixner 2016-07-20 9:04 ` Thomas Gleixner 2016-07-20 9:04 ` Thomas Gleixner 2016-07-25 16:21 ` Auger Eric [this message] 2016-07-25 16:21 ` Auger Eric 2016-07-26 9:00 ` Thomas Gleixner 2016-07-26 9:00 ` Thomas Gleixner 2016-07-26 9:00 ` Thomas Gleixner 2016-07-26 9:54 ` Auger Eric 2016-07-26 9:54 ` Auger Eric 2016-07-26 9:54 ` Auger Eric 2016-07-26 11:01 ` Thomas Gleixner 2016-07-26 11:01 ` Thomas Gleixner 2016-07-19 13:02 ` [PATCH v11 10/10] genirq/msi: use the MSI doorbell's IOVA when requested Eric Auger 2016-07-19 13:02 ` Eric Auger 2016-07-19 13:02 ` Eric Auger 2016-07-20 9:09 ` Thomas Gleixner 2016-07-20 9:09 ` Thomas Gleixner 2016-07-25 16:31 ` Auger Eric 2016-07-25 16:31 ` Auger Eric 2016-07-25 16:31 ` Auger Eric 2016-07-26 9:04 ` Thomas Gleixner 2016-07-26 9:04 ` Thomas Gleixner 2016-07-26 10:02 ` Auger Eric 2016-07-26 10:02 ` Auger Eric
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=75f5e846-6ca4-4178-e7aa-fed90e45e546@redhat.com \ --to=eric.auger@redhat.com \ --cc=Bharat.Bhushan@freescale.com \ --cc=Jean-Philippe.Brucker@arm.com \ --cc=Manish.Jaggi@caviumnetworks.com \ --cc=alex.williamson@redhat.com \ --cc=andre.przywara@arm.com \ --cc=christoffer.dall@linaro.org \ --cc=drjones@redhat.com \ --cc=eric.auger.pro@gmail.com \ --cc=iommu@lists.linux-foundation.org \ --cc=jason@lakedaemon.net \ --cc=joro@8bytes.org \ --cc=kvm@vger.kernel.org \ --cc=kvmarm@lists.cs.columbia.edu \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=marc.zyngier@arm.com \ --cc=p.fedin@samsung.com \ --cc=pbonzini@redhat.com \ --cc=pranav.sawargaonkar@gmail.com \ --cc=robert.richter@caviumnetworks.com \ --cc=robin.murphy@arm.com \ --cc=tglx@linutronix.de \ --cc=will.deacon@arm.com \ --cc=yehuday@marvell.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.