[Skiboot] [PATCH] hw/phb3: Flush cache line after updating P/Q bits
Benjamin Herrenschmidt
benh at kernel.crashing.org
Wed Nov 18 11:34:04 AEDT 2015
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 at kernel.crashing.org>
---
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;
}
More information about the Skiboot
mailing list