All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrii Anisov <andrii.anisov@gmail.com>
Cc: xen-devel@lists.xenproject.org,
	Julien Grall <julien.grall@arm.com>,
	Stefano Stabellini <sstabellini@kernel.org>,
	Andrii Anisov <andrii_anisov@epam.com>
Subject: [RFC 15/16] hack: move gicv2 LRs reads and writes out of spinlocks
Date: Wed, 28 Nov 2018 23:32:10 +0200	[thread overview]
Message-ID: <1543440731-21947-16-git-send-email-andrii.anisov@gmail.com> (raw)
In-Reply-To: <1543440731-21947-1-git-send-email-andrii.anisov@gmail.com>

From: Andrii Anisov <andrii_anisov@epam.com>

Use values cached in `struct vcpu` for guest IRQs processing.
This also reduces LR stores and restores on VCPU switch.

Signed-off-by: Andrii Anisov <andrii_anisov@epam.com>
---
 xen/arch/arm/gic-v2.c     | 56 +++++++++++++++++++++++++++++++----------------
 xen/arch/arm/gic-vgic.c   |  8 +++++--
 xen/include/asm-arm/gic.h |  5 ++++-
 3 files changed, 47 insertions(+), 22 deletions(-)

diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
index 25147bd..a2eb0a7 100644
--- a/xen/arch/arm/gic-v2.c
+++ b/xen/arch/arm/gic-v2.c
@@ -176,31 +176,18 @@ static unsigned int gicv2_cpu_mask(const cpumask_t *cpumask)
 
 static void gicv2_save_state(struct vcpu *v)
 {
-    int i;
-
-    /* No need for spinlocks here because interrupts are disabled around
-     * this call and it only accesses struct vcpu fields that cannot be
-     * accessed simultaneously by another pCPU.
-     */
-    for ( i = 0; i < gicv2_info.nr_lrs; i++ )
-        v->arch.gic.v2.lr[i] = readl_gich(GICH_LR + i * 4);
-
     v->arch.gic.v2.apr = readl_gich(GICH_APR);
     v->arch.gic.v2.vmcr = readl_gich(GICH_VMCR);
     /* Disable until next VCPU scheduled */
     writel_gich(0, GICH_HCR);
 }
 
-static void gicv2_restore_state(const struct vcpu *v)
+static void gicv2_restore_state(struct vcpu *v)
 {
-    int i;
-
-    for ( i = 0; i < gicv2_info.nr_lrs; i++ )
-        writel_gich(v->arch.gic.v2.lr[i], GICH_LR + i * 4);
-
     writel_gich(v->arch.gic.v2.apr, GICH_APR);
     writel_gich(v->arch.gic.v2.vmcr, GICH_VMCR);
     writel_gich(GICH_HCR_EN, GICH_HCR);
+    v->arch.gic.v2.lr_update_mask = (1 << gic_hw_ops->info->nr_lrs) - 1;
 }
 
 static void gicv2_dump_state(const struct vcpu *v)
@@ -493,6 +480,7 @@ static void gicv2_disable_interface(void)
 static void gicv2_update_lr(int lr, unsigned int virq, uint8_t priority,
                             unsigned int hw_irq, unsigned int state)
 {
+    struct vcpu *v = current;
     uint32_t lr_reg;
 
     BUG_ON(lr >= gicv2_info.nr_lrs);
@@ -507,19 +495,23 @@ static void gicv2_update_lr(int lr, unsigned int virq, uint8_t priority,
         lr_reg |= GICH_V2_LR_HW | ((hw_irq & GICH_V2_LR_PHYSICAL_MASK )
                                    << GICH_V2_LR_PHYSICAL_SHIFT);
 
-    writel_gich(lr_reg, GICH_LR + lr * 4);
+    v->arch.gic.v2.lr[lr] = lr_reg;
+    v->arch.gic.v2.lr_update_mask |= 1<<lr;
 }
 
 static void gicv2_clear_lr(int lr)
 {
-    writel_gich(0, GICH_LR + lr * 4);
+    struct vcpu *v = current;
+
+    v->arch.gic.v2.lr[lr] = 0;
+    v->arch.gic.v2.lr_update_mask |= 1<<lr;
 }
 
 static void gicv2_read_lr(int lr, struct gic_lr *lr_reg)
 {
     uint32_t lrv;
 
-    lrv          = readl_gich(GICH_LR + lr * 4);
+    lrv = current->arch.gic.v2.lr[lr];
     lr_reg->virq = (lrv >> GICH_V2_LR_VIRTUAL_SHIFT) & GICH_V2_LR_VIRTUAL_MASK;
     lr_reg->priority = (lrv >> GICH_V2_LR_PRIORITY_SHIFT) & GICH_V2_LR_PRIORITY_MASK;
     lr_reg->pending = lrv & GICH_V2_LR_PENDING;
@@ -546,6 +538,7 @@ static void gicv2_read_lr(int lr, struct gic_lr *lr_reg)
 static void gicv2_write_lr(int lr, const struct gic_lr *lr_reg)
 {
     uint32_t lrv = 0;
+    struct vcpu *v = current;
 
     lrv = (((lr_reg->virq & GICH_V2_LR_VIRTUAL_MASK) << GICH_V2_LR_VIRTUAL_SHIFT)   |
           ((uint32_t)(lr_reg->priority & GICH_V2_LR_PRIORITY_MASK)
@@ -574,7 +567,30 @@ static void gicv2_write_lr(int lr, const struct gic_lr *lr_reg)
         lrv |= (uint32_t)lr_reg->virt.source << GICH_V2_LR_CPUID_SHIFT;
     }
 
-    writel_gich(lrv, GICH_LR + lr * 4);
+    v->arch.gic.v2.lr[lr] = lrv;
+    v->arch.gic.v2.lr_update_mask |= 1<<lr;
+}
+
+static void gicv2_fetch_lrs(struct vcpu *v)
+{
+    int i;
+
+    for ( i = 0; i < gicv2_info.nr_lrs; i++ )
+        if ( this_cpu(lr_mask) & 1<<i )
+            v->arch.gic.v2.lr[i] = readl_gich(GICH_LR + i * 4);
+        else
+            v->arch.gic.v2.lr[i] = 0;
+}
+
+static void gicv2_push_lrs(struct vcpu *v)
+{
+    int i;
+    uint64_t mask = v->arch.gic.v2.lr_update_mask;
+
+    for ( i = 0; i < gicv2_info.nr_lrs; i++ )
+        if ( mask & 1<<i )
+            writel_gich(v->arch.gic.v2.lr[i], GICH_LR + i * 4);
+    v->arch.gic.v2.lr_update_mask = 0;
 }
 
 static void gicv2_hcr_status(uint32_t flag, bool status)
@@ -1360,6 +1376,8 @@ const static struct gic_hw_operations gicv2_ops = {
     .map_hwdom_extra_mappings = gicv2_map_hwdown_extra_mappings,
     .iomem_deny_access   = gicv2_iomem_deny_access,
     .do_LPI              = gicv2_do_LPI,
+    .fetch_lrs           = gicv2_fetch_lrs,
+    .push_lrs            = gicv2_push_lrs,
 };
 
 /* Set up the GIC */
diff --git a/xen/arch/arm/gic-vgic.c b/xen/arch/arm/gic-vgic.c
index e511f91..86c8ae2 100644
--- a/xen/arch/arm/gic-vgic.c
+++ b/xen/arch/arm/gic-vgic.c
@@ -277,6 +277,7 @@ void vgic_sync_from_lrs(struct vcpu *v)
         return;
 
     gic_hw_ops->update_hcr_status(GICH_HCR_UIE, false);
+    gic_hw_ops->fetch_lrs(v);
 
     spin_lock(&v->arch.vgic.lock);
 
@@ -403,11 +404,14 @@ int vgic_vcpu_pending_irq(struct vcpu *v)
 
 void vgic_sync_to_lrs(void)
 {
+    struct vcpu *v = current;
     ASSERT(!local_irq_is_enabled());
 
-    gic_restore_pending_irqs(current);
+    gic_restore_pending_irqs(v);
 
-    if ( !list_empty(&current->arch.vgic.lr_pending) && lr_all_full() )
+    gic_hw_ops->push_lrs(v);
+
+    if ( !list_empty(&v->arch.vgic.lr_pending) && lr_all_full() )
         gic_hw_ops->update_hcr_status(GICH_HCR_UIE, true);
 }
 
diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
index 3d7394d..add2566 100644
--- a/xen/include/asm-arm/gic.h
+++ b/xen/include/asm-arm/gic.h
@@ -187,6 +187,7 @@ struct gic_v2 {
     uint32_t vmcr;
     uint32_t apr;
     uint32_t lr[64];
+    uint64_t lr_update_mask;
 };
 
 /*
@@ -323,7 +324,7 @@ struct gic_hw_operations {
     /* Save GIC registers */
     void (*save_state)(struct vcpu *);
     /* Restore GIC registers */
-    void (*restore_state)(const struct vcpu *);
+    void (*restore_state)(struct vcpu *);
     /* Dump GIC LR register information */
     void (*dump_state)(const struct vcpu *);
 
@@ -384,6 +385,8 @@ struct gic_hw_operations {
     int (*iomem_deny_access)(const struct domain *d);
     /* Handle LPIs, which require special handling */
     void (*do_LPI)(unsigned int lpi);
+    void (*fetch_lrs) (struct vcpu *v);
+    void (*push_lrs) (struct vcpu *v);
 };
 
 extern const struct gic_hw_operations *gic_hw_ops;
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  parent reply	other threads:[~2018-11-28 21:32 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1543440731-21947-1-git-send-email-andrii.anisov@gmail.com>
2018-11-28 21:31 ` [RFC 01/16] xen/arm: Re-enable interrupt later in the trap path Andrii Anisov
2018-11-28 22:00   ` Julien Grall
2019-07-30 17:34     ` [Xen-devel] " Andrii Anisov
2019-07-30 20:46       ` Julien Grall
2018-11-28 21:31 ` [RFC 02/16] hack: drop GIC v3 support Andrii Anisov
2018-11-29 12:08   ` Andre Przywara
2018-11-28 21:31 ` [RFC 03/16] vgic: move pause_flags check out of vgic spinlock Andrii Anisov
2018-11-28 22:02   ` Julien Grall
2018-11-28 21:31 ` [RFC 04/16] vgic: move irq_to_pending out of lock Andrii Anisov
2018-11-29 11:07   ` Julien Grall
2018-11-28 21:32 ` [RFC 05/16] gic-vgic: Drop an excessive clear_lrs Andrii Anisov
2018-12-11 14:33   ` Julien Grall
2018-12-12 11:01     ` Andrii Anisov
2018-12-12 11:55       ` Julien Grall
2018-11-28 21:32 ` [RFC 06/16] gic: drop interrupts enabling on interrupts processing Andrii Anisov
2018-11-28 22:06   ` Julien Grall
2018-12-12 12:10     ` Julien Grall
2018-11-28 21:32 ` [RFC 07/16] gic-vgic:vgic: do not keep disabled IRQs in any of queues Andrii Anisov
2018-11-28 21:32 ` [RFC 08/16] gic: separate ppi processing Andrii Anisov
2018-12-12 12:37   ` Andrii Anisov
2018-12-12 12:46     ` Julien Grall
2018-12-12 12:52       ` Andrii Anisov
2018-12-12 13:46         ` Julien Grall
2018-11-28 21:32 ` [RFC 09/16] gic-vgic:vgic: avoid excessive conversions Andrii Anisov
2018-11-29 10:23   ` Julien Grall
2018-11-28 21:32 ` [RFC 10/16] gic:vgic:gic-vgic: introduce non-atomic bitops Andrii Anisov
2018-11-29 12:14   ` Andre Przywara
2018-11-29 16:07     ` Julien Grall
2018-12-03 12:33     ` Andrii Anisov
2018-12-03 12:58       ` Julien Grall
2018-12-03 13:05         ` Andrii Anisov
2018-12-03 13:08           ` Julien Grall
2018-12-03 16:37       ` Andre Przywara
2018-11-28 21:32 ` [RFC 11/16] irq: skip action avalability check for guest's IRQ Andrii Anisov
2018-12-11 14:48   ` Julien Grall
2018-12-12 11:30     ` Andrii Anisov
2018-12-12 11:59       ` Julien Grall
2018-12-12 13:51         ` Andrii Anisov
2018-12-12 14:49           ` Julien Grall
2018-12-12 14:58             ` Andrii Anisov
2018-12-12 15:08               ` Julien Grall
2018-12-12 15:57                 ` Andrii Anisov
2018-11-28 21:32 ` [RFC 12/16] gic-v2: Write HCR only on change Andrii Anisov
2018-11-29 16:36   ` Julien Grall
2018-11-28 21:32 ` [RFC 13/16] gic-vgic: skip irqs locking Andrii Anisov
2018-12-12 12:07   ` Julien Grall
2018-12-12 12:35     ` Andrii Anisov
2018-12-12 12:44       ` Julien Grall
2018-12-12 12:47         ` Andrii Anisov
2018-11-28 21:32 ` [RFC 14/16] hack: arm/domain: simplify context restore from idle vcpu Andrii Anisov
2018-11-29 15:53   ` Julien Grall
2018-11-29 16:00   ` Wei Liu
2018-11-28 21:32 ` Andrii Anisov [this message]
2018-11-28 21:58   ` [RFC 15/16] hack: move gicv2 LRs reads and writes out of spinlocks Julien Grall
2018-11-28 21:32 ` [RFC 16/16] gic: vgic: align frequently accessed data by cache line size Andrii Anisov
2018-11-29 16:24   ` Julien Grall
2018-11-29  7:40 ` [RFC 00/16] Old GIC (gic-vgic) optimizations for GICV2 Andrii Anisov
2018-11-29 11:00   ` Julien Grall
2018-11-29 12:07   ` Andre Przywara

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=1543440731-21947-16-git-send-email-andrii.anisov@gmail.com \
    --to=andrii.anisov@gmail.com \
    --cc=andrii_anisov@epam.com \
    --cc=julien.grall@arm.com \
    --cc=sstabellini@kernel.org \
    --cc=xen-devel@lists.xenproject.org \
    /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: link
Be 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.