From patchwork Thu May 22 12:32:28 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefano Stabellini X-Patchwork-Id: 30624 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pb0-f69.google.com (mail-pb0-f69.google.com [209.85.160.69]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id BB10C20671 for ; Thu, 22 May 2014 12:53:28 +0000 (UTC) Received: by mail-pb0-f69.google.com with SMTP id uo5sf10774748pbc.4 for ; Thu, 22 May 2014 05:53:28 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:mime-version:cc:subject:precedence:list-id :list-unsubscribe:list-post:list-help:list-subscribe:sender :errors-to:x-original-sender:x-original-authentication-results :mailing-list:list-archive:content-type:content-transfer-encoding; bh=RpmA29vcy90CyZZbRPIoGnUH4OEeA4jVFIyAX+8za8I=; b=Ezpa9K3TsSIyEEBYjonmHK0aS4SKX8DRaJezGH3BMmK56j1zcPQYpo2osgahVfDLUK 8wGMlWDh2vY9DVetBtaPQs3BfThBreclWmlU+mOCrTrYV4AGJlH4K9Vxj78f9kIYDP3d aefY7vBaDHBsTY2e580rtxINycl8A2Ju5RmYifnWwmFTd/8K09viKDtE6Jyfcu9zsD1T j0hqN1TumHG72IbNUbdTM+2wZZXxP5Dxot0JE28XVWYH+jUaSe289ujn3hlnFjodlAlt N+kiXAgPT1a9ltBtKYXKa6/fS0R6TG+uv7lxABMUKg2b6ucUaGGQvtr9hA9LameQMdVZ Wedw== X-Gm-Message-State: ALoCoQnuTHYehrmRpP3x8PfWR6EZeKRDxIikcUA24smwD2HoxT3QPiyLWz5Sx7tZpu9zPfmKLHMM X-Received: by 10.68.195.9 with SMTP id ia9mr25421931pbc.7.1400763208073; Thu, 22 May 2014 05:53:28 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.101.247 with SMTP id u110ls1276512qge.79.gmail; Thu, 22 May 2014 05:53:27 -0700 (PDT) X-Received: by 10.52.253.130 with SMTP id aa2mr148695vdd.91.1400763207915; Thu, 22 May 2014 05:53:27 -0700 (PDT) Received: from mail-ve0-f172.google.com (mail-ve0-f172.google.com [209.85.128.172]) by mx.google.com with ESMTPS id wg9si4772602vcb.30.2014.05.22.05.53.27 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 22 May 2014 05:53:27 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.128.172 as permitted sender) client-ip=209.85.128.172; Received: by mail-ve0-f172.google.com with SMTP id oz11so4304532veb.31 for ; Thu, 22 May 2014 05:53:27 -0700 (PDT) X-Received: by 10.58.195.130 with SMTP id ie2mr15028718vec.3.1400763207827; Thu, 22 May 2014 05:53:27 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.221.72 with SMTP id ib8csp196158vcb; Thu, 22 May 2014 05:53:27 -0700 (PDT) X-Received: by 10.224.43.148 with SMTP id w20mr10936380qae.26.1400763207077; Thu, 22 May 2014 05:53:27 -0700 (PDT) Received: from lists.xen.org (lists.xen.org. [50.57.142.19]) by mx.google.com with ESMTPS id o1si5155461qah.35.2014.05.22.05.53.26 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 22 May 2014 05:53:27 -0700 (PDT) Received-SPF: none (google.com: xen-devel-bounces@lists.xen.org does not designate permitted sender hosts) client-ip=50.57.142.19; Received: from localhost ([127.0.0.1] helo=lists.xen.org) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1WnSTD-0006A3-Lk; Thu, 22 May 2014 12:51:39 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1WnSTB-00069Y-NV for xen-devel@lists.xensource.com; Thu, 22 May 2014 12:51:38 +0000 Received: from [85.158.137.68:64706] by server-11.bemta-3.messagelabs.com id 91/AA-19438-8D2FD735; Thu, 22 May 2014 12:51:36 +0000 X-Env-Sender: Stefano.Stabellini@citrix.com X-Msg-Ref: server-7.tower-31.messagelabs.com!1400763092!5530166!1 X-Originating-IP: [66.165.176.89] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni44OSA9PiAyMDMwMDc=\n X-StarScan-Received: X-StarScan-Version: 6.11.3; banners=-,-,- X-VirusChecked: Checked Received: (qmail 23516 invoked from network); 22 May 2014 12:51:35 -0000 Received: from smtp.citrix.com (HELO SMTP.CITRIX.COM) (66.165.176.89) by server-7.tower-31.messagelabs.com with RC4-SHA encrypted SMTP; 22 May 2014 12:51:35 -0000 X-IronPort-AV: E=Sophos;i="4.98,887,1392163200"; d="scan'208";a="134543503" Received: from accessns.citrite.net (HELO FTLPEX01CL03.citrite.net) ([10.9.154.239]) by FTLPIPO01.CITRIX.COM with ESMTP; 22 May 2014 12:51:32 +0000 Received: from ukmail1.uk.xensource.com (10.80.16.128) by smtprelay.citrix.com (10.13.107.80) with Microsoft SMTP Server id 14.3.181.6; Thu, 22 May 2014 08:51:31 -0400 Received: from kaball.uk.xensource.com ([10.80.2.59]) by ukmail1.uk.xensource.com with esmtp (Exim 4.69) (envelope-from ) id 1WnSBI-0003tn-Cf; Thu, 22 May 2014 13:33:08 +0100 From: Stefano Stabellini To: Date: Thu, 22 May 2014 13:32:28 +0100 Message-ID: <1400761950-25035-11-git-send-email-stefano.stabellini@eu.citrix.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: References: MIME-Version: 1.0 X-DLP: MIA2 Cc: julien.grall@citrix.com, Ian.Campbell@citrix.com, Stefano Stabellini Subject: [Xen-devel] [PATCH v8 11/13] xen/arm: gic_events_need_delivery and irq priorities X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: List-Unsubscribe: , List-Post: , List-Help: , List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: stefano.stabellini@eu.citrix.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.128.172 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Archive: gic_events_need_delivery should only return positive if an outstanding pending irq has an higher priority than the currently active irq and the priority mask. Introduce GIC_IRQ_GUEST_ACTIVE to track which ones are currently active in the guest. Rewrite the function by going through the priority ordered inflight and lr_queue lists. In gic_restore_pending_irqs replace lower priority pending (and not active) irqs in GICH_LRs with higher priority irqs if no more GICH_LRs are available. Signed-off-by: Stefano Stabellini --- Changes in v8: - in gic_restore_pending_irqs rename i to lr; - add in code comments in gic_restore_pending_irqs and gic_events_need_delivery; - add << 3 to mask_priority. Changes in v7: - fix locking for the list_empty case in gic_restore_pending_irqs; - add in code comment; - gic_events_need_delivery: break out of the loop as soon as we find the active irq as inflight_irqs is ordered by priority; - gic_events_need_delivery: break out of the loop if p->priority is lower than mask_priority as inflight_irqs is ordered by priority; - use find_next_zero_bit instead of find_first_zero_bit; - in gic_restore_pending_irqs remember the last position of the inner loop search and continue from there; - in gic_restore_pending_irqs use a priority check to get out of the inner loop. Changes in v5: - improve in code comments; - use list_for_each_entry_reverse instead of writing my own list walker. Changes in v4: - in gic_events_need_delivery go through inflight_irqs and only consider enabled irqs. --- xen/arch/arm/gic.c | 89 ++++++++++++++++++++++++++++++++++++++---- xen/include/asm-arm/domain.h | 5 ++- xen/include/asm-arm/gic.h | 3 ++ 3 files changed, 87 insertions(+), 10 deletions(-) diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index eb59f5a..de8dd1c 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -650,6 +650,7 @@ static void gic_update_one_lr(struct vcpu *v, int i) p = irq_to_pending(v, irq); if ( lr & GICH_LR_ACTIVE ) { + set_bit(GIC_IRQ_GUEST_ACTIVE, &p->status); if ( test_bit(GIC_IRQ_GUEST_ENABLED, &p->status) && test_and_clear_bit(GIC_IRQ_GUEST_QUEUED, &p->status) ) { @@ -673,6 +674,7 @@ static void gic_update_one_lr(struct vcpu *v, int i) if ( p->desc != NULL ) p->desc->status &= ~IRQ_INPROGRESS; clear_bit(GIC_IRQ_GUEST_VISIBLE, &p->status); + clear_bit(GIC_IRQ_GUEST_ACTIVE, &p->status); p->lr = GIC_INVALID_LR; if ( test_bit(GIC_IRQ_GUEST_ENABLED, &p->status) && test_bit(GIC_IRQ_GUEST_QUEUED, &p->status) ) @@ -703,20 +705,55 @@ void gic_clear_lrs(struct vcpu *v) static void gic_restore_pending_irqs(struct vcpu *v) { - int i; - struct pending_irq *p, *t; + int lr = 0, lrs = nr_lrs; + struct pending_irq *p, *t, *p_r; + struct list_head *inflight_r; unsigned long flags; spin_lock_irqsave(&v->arch.vgic.lock, flags); + + if ( list_empty(&v->arch.vgic.lr_pending) ) + goto out; + + inflight_r = &v->arch.vgic.inflight_irqs; list_for_each_entry_safe ( p, t, &v->arch.vgic.lr_pending, lr_queue ) { - i = find_first_zero_bit(&this_cpu(lr_mask), nr_lrs); - if ( i >= nr_lrs ) return; + lr = find_next_zero_bit(&this_cpu(lr_mask), nr_lrs, lr); + if ( lr >= nr_lrs ) + { + /* No more free LRs: find a lower priority irq to evict */ + list_for_each_entry_reverse( p_r, inflight_r, inflight ) + { + if ( p_r->priority == p->priority ) + goto out; + if ( test_bit(GIC_IRQ_GUEST_VISIBLE, &p_r->status) && + !test_bit(GIC_IRQ_GUEST_ACTIVE, &p_r->status) ) + goto found; + } + /* We didn't find a victim this time, and we won't next + * time, so quit */ + goto out; + +found: + lr = p_r->lr; + p_r->lr = GIC_INVALID_LR; + set_bit(GIC_IRQ_GUEST_QUEUED, &p_r->status); + clear_bit(GIC_IRQ_GUEST_VISIBLE, &p_r->status); + gic_add_to_lr_pending(v, p_r); + inflight_r = &p_r->inflight; + } - gic_set_lr(i, p, GICH_LR_PENDING); + gic_set_lr(lr, p, GICH_LR_PENDING); list_del_init(&p->lr_queue); - set_bit(i, &this_cpu(lr_mask)); + set_bit(lr, &this_cpu(lr_mask)); + + /* We can only evict nr_lrs entries */ + lrs--; + if ( lrs == 0 ) + break; } + +out: spin_unlock_irqrestore(&v->arch.vgic.lock, flags); } @@ -733,8 +770,44 @@ void gic_clear_pending_irqs(struct vcpu *v) int gic_events_need_delivery(void) { - return (!list_empty(¤t->arch.vgic.lr_pending) || - this_cpu(lr_mask)); + int mask_priority, lrs = nr_lrs; + int max_priority = 0xff, active_priority = 0xff; + struct vcpu *v = current; + struct pending_irq *p; + unsigned long flags; + + mask_priority = (GICH[GICH_VMCR] >> GICH_VMCR_PRIORITY_SHIFT) & GICH_VMCR_PRIORITY_MASK; + mask_priority = mask_priority << 3; + + spin_lock_irqsave(&v->arch.vgic.lock, flags); + + /* TODO: We order the guest irqs by priority, but we don't change + * the priority of host irqs. */ + list_for_each_entry( p, &v->arch.vgic.inflight_irqs, inflight ) + { + if ( test_bit(GIC_IRQ_GUEST_ACTIVE, &p->status) ) + { + if ( p->priority < active_priority ) + active_priority = p->priority; + break; + } else if ( test_bit(GIC_IRQ_GUEST_ENABLED, &p->status) ) { + if ( p->priority < max_priority ) + max_priority = p->priority; + } + if ( p->priority >= mask_priority ) + break; + lrs--; + if ( lrs == 0 ) + break; + } + + spin_unlock_irqrestore(&v->arch.vgic.lock, flags); + + if ( max_priority < active_priority && + max_priority < mask_priority ) + return 1; + else + return 0; } void gic_inject(void) diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h index 59ce196..d689675 100644 --- a/xen/include/asm-arm/domain.h +++ b/xen/include/asm-arm/domain.h @@ -56,8 +56,9 @@ struct pending_irq * */ #define GIC_IRQ_GUEST_QUEUED 0 -#define GIC_IRQ_GUEST_VISIBLE 1 -#define GIC_IRQ_GUEST_ENABLED 2 +#define GIC_IRQ_GUEST_ACTIVE 1 +#define GIC_IRQ_GUEST_VISIBLE 2 +#define GIC_IRQ_GUEST_ENABLED 3 unsigned long status; struct irq_desc *desc; /* only set it the irq corresponds to a physical irq */ int irq; diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h index 0c4c583..30e92cf 100644 --- a/xen/include/asm-arm/gic.h +++ b/xen/include/asm-arm/gic.h @@ -129,6 +129,9 @@ #define GICH_LR_CPUID_SHIFT 9 #define GICH_VTR_NRLRGS 0x3f +#define GICH_VMCR_PRIORITY_MASK 0x1f +#define GICH_VMCR_PRIORITY_SHIFT 27 + /* * The minimum GICC_BPR is required to be in the range 0-3. We set * GICC_BPR to 0 but we must expect that it might be 3. This means we