From: Ian Campbell <ian.campbell@citrix.com>
To: Julien Grall <julien.grall@citrix.com>, xen-devel@lists.xenproject.org
Cc: Vijaya.Kumar@caviumnetworks.com, stefano.stabellini@citrix.com,
manish.jaggi@caviumnetworks.com, vijay.kilari@gmail.com
Subject: Re: [PATCH v1 5/8] xen/arm: vgic: Optimize the way to store GICD_IPRIORITYR in the rank
Date: Mon, 28 Sep 2015 11:50:58 +0100 [thread overview]
Message-ID: <1443437458.25250.262.camel@citrix.com> (raw)
In-Reply-To: <1443192698-16163-6-git-send-email-julien.grall@citrix.com>
On Fri, 2015-09-25 at 15:51 +0100, Julien Grall wrote:
> Xen is currently directly storing the value of register GICD_IPRIORITYR
"of the GICD_... register"
> in the rank. This makes emulation of the register access very simple
> but makes the code to get the priority for a given IRQ more complex.
>
> While the priority of an IRQ is retrieved everytime an IRQ is injected
"every time".
> to the guest, the access to register occurs less often.
>
> So the data structure should be optimized for the most common case
> rather than the inverse.
>
> This patch introduces the usage of an array to store the priority for
> every interrupt in the rank. This will make the code to get the priority
> very quick. The emulation code will now have to generate the
> GICD_PRIORITYR
> register for read access and split it to store in a convenient way.
>
> Signed-off-by: Julien Grall <julien.grall@citrix.com>
> ---
>
> The real reason is I'd like to drop vgic_byte_* helpers in favors of more
> generic access helper. Although it would make the code to retrieve the
> priority more complex. So reworking the way to get the priority was the
> best solution.
>
> Changes in v2:
> - Patch added
> ---
> xen/arch/arm/vgic-v2.c | 24 ++++++++++++++----------
> xen/arch/arm/vgic-v3.c | 27 ++++++++++++++++-----------
> xen/arch/arm/vgic.c | 46
> ++++++++++++++++++++++++++++++++++++++++++++++
> xen/include/asm-arm/vgic.h | 18 +++++++++++++++++-
> 4 files changed, 93 insertions(+), 22 deletions(-)
>
> diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c
> index 47f9da9..23d1982 100644
> --- a/xen/arch/arm/vgic-v2.c
> +++ b/xen/arch/arm/vgic-v2.c
> @@ -139,8 +139,8 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
> if ( rank == NULL) goto read_as_zero;
>
> vgic_lock_rank(v, rank, flags);
> - *r = rank->ipriority[REG_RANK_INDEX(8, gicd_reg - GICD_IPRIORITYR,
> - DABT_WORD)];
> + /* Recreate the IPRIORITYR register */
> + *r = vgic_generate_ipriorityr(rank, gicd_reg - GICD_IPRIORITYR);
> if ( dabt.size == DABT_BYTE )
> *r = vgic_byte_read(*r, gicd_reg);
> vgic_unlock_rank(v, rank, flags);
> @@ -400,18 +400,25 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
> }
>
> case GICD_IPRIORITYR ... GICD_IPRIORITYRN:
> + {
> + uint32_t ipriorityr;
> +
> if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
> rank = vgic_rank_offset(v, 8, gicd_reg - GICD_IPRIORITYR, DABT_WORD);
> if ( rank == NULL) goto write_ignore;
> vgic_lock_rank(v, rank, flags);
> if ( dabt.size == DABT_WORD )
> - rank->ipriority[REG_RANK_INDEX(8, gicd_reg - GICD_IPRIORITYR,
> - DABT_WORD)] = r;
> + ipriorityr = r;
> else
> - vgic_byte_write(&rank->ipriority[REG_RANK_INDEX(8,
> - gicd_reg - GICD_IPRIORITYR, DABT_WORD)], r, gicd_reg);
> + {
> + ipriorityr = vgic_generate_ipriorityr(rank,
> + gicd_reg - GICD_IPRIORITYR);
> + vgic_byte_write(&ipriorityr, r, gicd_reg);
> + }
> + vgic_store_ipriorityr(rank, gicd_reg - GICD_IPRIORITYR, ipriorityr);
> vgic_unlock_rank(v, rank, flags);
> return 1;
> + }
>
> case GICD_ICFGR: /* SGIs */
> goto write_ignore_32;
> @@ -516,14 +523,11 @@ static struct vcpu *vgic_v2_get_target_vcpu(struct vcpu *v, unsigned int irq)
>
> static int vgic_v2_get_irq_priority(struct vcpu *v, unsigned int irq)
> {
> - int priority;
> struct vgic_irq_rank *rank = vgic_rank_irq(v, irq);
>
> ASSERT(spin_is_locked(&rank->lock));
> - priority = vgic_byte_read(rank->ipriority[REG_RANK_INDEX(8,
> - irq, DABT_WORD)], irq & 0x3);
>
> - return priority;
> + return rank->priority[irq & INTERRUPT_RANK_MASK];
> }
>
> static int vgic_v2_vcpu_init(struct vcpu *v)
> diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
> index c013200..2787507 100644
> --- a/xen/arch/arm/vgic-v3.c
> +++ b/xen/arch/arm/vgic-v3.c
> @@ -430,18 +430,26 @@ static int __vgic_v3_distr_common_mmio_write(const char *name, struct vcpu *v,
> return 0;
>
> case GICD_IPRIORITYR ... GICD_IPRIORITYRN:
> + {
> + uint32_t ipriorityr;
> +
> if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
> rank = vgic_rank_offset(v, 8, reg - GICD_IPRIORITYR, DABT_WORD);
> - if ( rank == NULL ) goto write_ignore;
> + if ( rank == NULL) goto write_ignore;
> +
> vgic_lock_rank(v, rank, flags);
> if ( dabt.size == DABT_WORD )
> - rank->ipriority[REG_RANK_INDEX(8, reg - GICD_IPRIORITYR,
> - DABT_WORD)] = r;
> + ipriorityr = r;
> else
> - vgic_byte_write(&rank->ipriority[REG_RANK_INDEX(8,
> - reg - GICD_IPRIORITYR, DABT_WORD)], r, reg);
> + {
> + ipriorityr = vgic_generate_ipriorityr(rank, reg - GICD_IPRIORITYR);
> + vgic_byte_write(&ipriorityr, r, reg);
> + }
> + vgic_store_ipriorityr(rank, reg - GICD_IPRIORITYR, ipriorityr);
Given the underlying change to the datastructure I think you should instead
supply a helper to set the priority of a given IRQ and use that for the
DABT_BYTE case.
For the DABT_WORD case your existing store helper would become 4 calls to
the byte helper.
That would be better than generating the full 32-bit value, masking in the
updated byte and then deconstructing the word again.
> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> index a6835a8..50ad360 100644
> --- a/xen/arch/arm/vgic.c
> +++ b/xen/arch/arm/vgic.c
> @@ -61,6 +61,52 @@ struct vgic_irq_rank *vgic_rank_irq(struct vcpu *v, unsigned int irq)
> return vgic_get_rank(v, rank);
> }
>
> +#define NR_PRIORITY_PER_REG 4U
> +#define NR_BIT_PER_PRIORITY 8U
> +
> +/*
> + * Generate the associated IPRIORITYR register based on an offset in the rank.
> + * Note the offset will be round down to match a real HW register.
"rounded".
> struct vgic_irq_rank {
> spinlock_t lock; /* Covers access to all other members of this struct */
> uint32_t ienable;
> uint32_t icfg[2];
> - uint32_t ipriority[8];
> +
> + /*
> + * It's more convenient to store one priority per interrupt than
> + * the register IPRIORITYR itself
> + */
> + uint8_t priority[32];
Does:
union {
uint32_t ipriorityr[8];
uint8_t priority[32];
}
Get us the best of both worlds, or are we stymied by endianess?
Ian.
next prev parent reply other threads:[~2015-09-28 10:51 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-25 14:51 [PATCH v1 0/8] xen/arm: vgic: Support 32-bit access for 64-bit register Julien Grall
2015-09-25 14:51 ` [PATCH v1 1/8] xen/arm: io: remove mmio_check_t typedef Julien Grall
2015-09-25 16:33 ` Ian Campbell
2015-09-25 14:51 ` [PATCH v1 2/8] xen/arm: io: Extend write/read handler to pass the register in parameter Julien Grall
2015-09-25 16:36 ` Ian Campbell
2015-09-28 16:35 ` Julien Grall
2015-09-29 10:51 ` Ian Campbell
2015-09-29 11:00 ` Julien Grall
2015-09-29 11:09 ` Ian Campbell
2015-09-25 14:51 ` [PATCH v1 3/8] xen/arm: Support sign-extension for every read access Julien Grall
2015-09-25 16:44 ` Ian Campbell
2015-09-28 16:42 ` Julien Grall
2015-09-29 11:01 ` Ian Campbell
2015-09-29 11:07 ` Julien Grall
2015-09-28 18:22 ` Julien Grall
2015-09-29 11:03 ` Ian Campbell
2015-09-29 11:13 ` Julien Grall
2015-09-29 13:13 ` Ian Campbell
2015-09-29 13:16 ` Julien Grall
2015-09-25 14:51 ` [PATCH v1 4/8] xen/arm: vgic: ctlr stores a 32-bit hardware register so use uint32_t Julien Grall
2015-09-25 16:45 ` Ian Campbell
2015-09-25 14:51 ` [PATCH v1 5/8] xen/arm: vgic: Optimize the way to store GICD_IPRIORITYR in the rank Julien Grall
2015-09-28 10:50 ` Ian Campbell [this message]
2015-09-28 17:10 ` Julien Grall
2015-09-29 10:56 ` Ian Campbell
2015-09-28 10:52 ` Ian Campbell
2015-09-28 16:43 ` Julien Grall
2015-09-25 14:51 ` [PATCH v1 6/8] xen/arm: vgic: Optimize the way to store the target vCPU " Julien Grall
2015-09-29 13:07 ` Ian Campbell
2015-09-29 13:36 ` Julien Grall
2015-09-29 14:23 ` Ian Campbell
2015-09-30 18:11 ` Julien Grall
2015-10-01 8:30 ` Ian Campbell
2015-09-25 14:51 ` [PATCH v1 7/8] xen/arm: vgic: Introduce helpers to read/write/clear/set vGIC register Julien Grall
2015-09-29 13:23 ` Ian Campbell
2015-09-29 13:48 ` Julien Grall
2015-09-29 14:24 ` Ian Campbell
2015-10-02 9:36 ` Julien Grall
2015-09-25 14:51 ` [PATCH v1 8/8] xen/arm: vgic-v3: Support 32-bit access for 64-bit registers Julien Grall
2015-09-29 13:27 ` Ian Campbell
-- strict thread matches above, loose matches on Subject: below --
2015-09-25 14:50 [PATCH v1 0/8] xen/arm: vgic: Support 32-bit access for 64-bit register Julien Grall
2015-09-25 14:51 ` [PATCH v1 5/8] xen/arm: vgic: Optimize the way to store GICD_IPRIORITYR in the rank Julien Grall
2015-09-25 14:51 ` Julien Grall
2015-09-25 14:51 ` Julien Grall
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=1443437458.25250.262.camel@citrix.com \
--to=ian.campbell@citrix.com \
--cc=Vijaya.Kumar@caviumnetworks.com \
--cc=julien.grall@citrix.com \
--cc=manish.jaggi@caviumnetworks.com \
--cc=stefano.stabellini@citrix.com \
--cc=vijay.kilari@gmail.com \
--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.