Message ID | 1447806844.3729.57.camel@kernel.crashing.org |
---|---|
State | Accepted |
Headers | show |
Benjamin Herrenschmidt <benh@kernel.crashing.org> writes: > When doing an MSI EOI, we update the P and Q bits in the IVE. That causes > the corresponding cache line to be dirty in the L3 which will cause a > subsequent update by the PHB (upon recieving the next MSI) to get a few > retries until it gets flushed. > > We can improve the situation (and thus performance) by doing a dcbf > instruction to force a flush of the update we do in SW. > > Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> For some bizarre reason git (and /usr/bin/patch) told me the patch was corrupt, but never mind - applied by hand. Merged to update-2.1.1.1 as of 53def38 Merged to stable as of b96a20e merged to master as of 1cec33c
On Thu, 2015-11-19 at 17:25 +1100, Stewart Smith wrote: > Benjamin Herrenschmidt <benh@kernel.crashing.org> writes: > > When doing an MSI EOI, we update the P and Q bits in the IVE. That > > causes > > the corresponding cache line to be dirty in the L3 which will cause > > a > > subsequent update by the PHB (upon recieving the next MSI) to get a > > few > > retries until it gets flushed. > > > > We can improve the situation (and thus performance) by doing a dcbf > > instruction to force a flush of the update we do in SW. > > > > Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> > > For some bizarre reason git (and /usr/bin/patch) told me the patch > was corrupt, but never mind - applied by hand. Could be that I failed to set "Preformatted" in evo ... happens sometimes. > Merged to update-2.1.1.1 as of 53def38 > Merged to stable as of b96a20e > merged to master as of 1cec33c Thanks, Ben.
diff --git a/hw/phb3.c b/hw/phb3.c index 36e8c58..220740a 100644 --- a/hw/phb3.c +++ b/hw/phb3.c @@ -1045,7 +1045,7 @@ static int64_t phb3_map_pe_dma_window_real(struct phb *phb, return OPAL_SUCCESS; } -static void phb3_pci_msi_check_q(struct phb3 *p, uint32_t ive_num) +static bool phb3_pci_msi_check_q(struct phb3 *p, uint32_t ive_num) { uint64_t ive, ivc, ffi, state; uint8_t *q_byte; @@ -1067,7 +1067,7 @@ static void phb3_pci_msi_check_q(struct phb3 *p, uint32_t ive_num) /* Q still not set, bail out */ if (!(*q_byte & 0x1)) - return; + return false; } /* Lock FFI and send interrupt */ @@ -1076,7 +1076,7 @@ static void phb3_pci_msi_check_q(struct phb3 *p, uint32_t ive_num) if (!state) break; if (state == ~0ULL) /* PHB Fenced */ - return; + return false; } /* Clear Q bit and update IVC */ @@ -1092,6 +1092,16 @@ static void phb3_pci_msi_check_q(struct phb3 *p, uint32_t ive_num) */ ffi = SETFIELD(PHB_FFI_REQUEST_ISN, 0ul, ive_num) | PHB_FFI_LOCK_CLEAR; out_be64(p->regs + PHB_FFI_REQUEST, ffi); + + return true; +} + +static void phb3_pci_msi_flush_ive(struct phb3 *p, uint32_t ive_num) +{ + asm volatile("dcbf %0,%1" + : + : "b" (p->tbl_ivt), "r" (ive_num * IVT_TABLE_STRIDE * 8) + : "memory"); } static int64_t phb3_pci_msi_eoi(struct phb *phb, @@ -1127,6 +1137,8 @@ static int64_t phb3_pci_msi_eoi(struct phb *phb, /* Handle Q bit */ phb3_pci_msi_check_q(p, ive_num); + phb3_pci_msi_flush_ive(p, ive_num); + return OPAL_SUCCESS; } @@ -1637,8 +1649,10 @@ static int64_t phb3_msi_set_xive(void *data, * The OS should make sure the interrupt handler has * been installed already. */ - if (prio != 0xff) - phb3_pci_msi_check_q(p, ive_num); + if (prio != 0xff) { + if (phb3_pci_msi_check_q(p, ive_num)) + phb3_pci_msi_flush_ive(p, ive_num); + } return OPAL_SUCCESS; }
When doing an MSI EOI, we update the P and Q bits in the IVE. That causes the corresponding cache line to be dirty in the L3 which will cause a subsequent update by the PHB (upon recieving the next MSI) to get a few retries until it gets flushed. We can improve the situation (and thus performance) by doing a dcbf instruction to force a flush of the update we do in SW. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> ---