aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/hpet.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2012-10-25 14:26:08 +0200
committerJan Beulich <jbeulich@suse.com>2012-10-25 14:26:08 +0200
commit2392dcbcdeb0b038faa523c0f57735c14aa2d60b (patch)
tree8a77cb7b445505eaade91873dd8462bb4d60e5f3 /xen/arch/x86/hpet.c
parent56760f0034771691a8e90f798abbafd99fe697f0 (diff)
downloadxen-2392dcbcdeb0b038faa523c0f57735c14aa2d60b.tar.gz
xen-2392dcbcdeb0b038faa523c0f57735c14aa2d60b.tar.bz2
xen-2392dcbcdeb0b038faa523c0f57735c14aa2d60b.zip
x86/HPET: cache MSI message last written
Rather than spending measurable amounts of time reading back the most recently written message, cache it in space previously unused, and thus accelerate the CPU's entering of the intended C-state. hpet_msi_read() ends up being unused after this change, but rather than removing the function, it's being marked "unused" in order - that way it can easily get used again should a new need for it arise. Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/arch/x86/hpet.c')
-rw-r--r--xen/arch/x86/hpet.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/xen/arch/x86/hpet.c b/xen/arch/x86/hpet.c
index 07028778c7..0157fddfc9 100644
--- a/xen/arch/x86/hpet.c
+++ b/xen/arch/x86/hpet.c
@@ -253,17 +253,19 @@ static void hpet_msi_mask(struct irq_desc *desc)
static void hpet_msi_write(struct hpet_event_channel *ch, struct msi_msg *msg)
{
+ ch->msi.msg = *msg;
if ( iommu_intremap )
iommu_update_ire_from_msi(&ch->msi, msg);
hpet_write32(msg->data, HPET_Tn_ROUTE(ch->idx));
hpet_write32(msg->address_lo, HPET_Tn_ROUTE(ch->idx) + 4);
}
-static void hpet_msi_read(struct hpet_event_channel *ch, struct msi_msg *msg)
+static void __maybe_unused
+hpet_msi_read(struct hpet_event_channel *ch, struct msi_msg *msg)
{
msg->data = hpet_read32(HPET_Tn_ROUTE(ch->idx));
msg->address_lo = hpet_read32(HPET_Tn_ROUTE(ch->idx) + 4);
- msg->address_hi = 0;
+ msg->address_hi = MSI_ADDR_BASE_HI;
if ( iommu_intremap )
iommu_read_msi_from_ire(&ch->msi, msg);
}
@@ -285,20 +287,19 @@ static void hpet_msi_ack(struct irq_desc *desc)
static void hpet_msi_set_affinity(struct irq_desc *desc, const cpumask_t *mask)
{
- struct msi_msg msg;
- unsigned int dest;
+ struct hpet_event_channel *ch = desc->action->dev_id;
+ struct msi_msg msg = ch->msi.msg;
- dest = set_desc_affinity(desc, mask);
- if (dest == BAD_APICID)
+ msg.dest32 = set_desc_affinity(desc, mask);
+ if ( msg.dest32 == BAD_APICID )
return;
- hpet_msi_read(desc->action->dev_id, &msg);
msg.data &= ~MSI_DATA_VECTOR_MASK;
msg.data |= MSI_DATA_VECTOR(desc->arch.vector);
msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
- msg.address_lo |= MSI_ADDR_DEST_ID(dest);
- msg.dest32 = dest;
- hpet_msi_write(desc->action->dev_id, &msg);
+ msg.address_lo |= MSI_ADDR_DEST_ID(msg.dest32);
+ if ( msg.data != ch->msi.msg.data || msg.dest32 != ch->msi.msg.dest32 )
+ hpet_msi_write(ch, &msg);
}
/*