From patchwork Wed Apr 2 15:01:46 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefano Stabellini X-Patchwork-Id: 27626 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pd0-f197.google.com (mail-pd0-f197.google.com [209.85.192.197]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id C4FD420341 for ; Wed, 2 Apr 2014 15:03:35 +0000 (UTC) Received: by mail-pd0-f197.google.com with SMTP id fp1sf999923pdb.8 for ; Wed, 02 Apr 2014 08:03:34 -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=hEtHJbR8iLWmVVdQXUky6Km2Wr1uP60smS8UVxdYE7k=; b=QVPt3Urk3fWWmTYuLEiolelPsEtSVfBHyqNGDeRHI1LmNIxeYII0JZH38iK1NaCdcz enICy15/y1o2q9hMG8XUZGcepVH3qoIYjK2Aoe4B2z1TtmDdP4dn8HkWz7gz4DzX0kfZ rQ4M0D+4ovLW74JI/rJdpXprXCmPP8btt505kJdqeVO3lmaK9kVZq5/3h9WQoDzcgUq3 BhkuV6FOTWI5MmvmVAPMxglOTOisR67ZoyiAgaJNB64ew2gAlBRUcBo1HJ11rWQ21q7U v3SsxTDNKNBS3+z/tm5Jm+UOYBYbmxND6T5jslZYty/Ct6EOCEE08ktw/JB1LMXltGY/ +u5g== X-Gm-Message-State: ALoCoQn4QCcs/ulvvVW8cXMs+37xCiSzM+5LLlMeW1oe/kGYYMJfg4iW+aelhdLGdvDUguak/T+4 X-Received: by 10.66.141.231 with SMTP id rr7mr9848675pab.47.1396451014900; Wed, 02 Apr 2014 08:03:34 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.86.85 with SMTP id o79ls388046qgd.12.gmail; Wed, 02 Apr 2014 08:03:34 -0700 (PDT) X-Received: by 10.52.160.98 with SMTP id xj2mr3670vdb.80.1396451014734; Wed, 02 Apr 2014 08:03:34 -0700 (PDT) Received: from mail-vc0-f175.google.com (mail-vc0-f175.google.com [209.85.220.175]) by mx.google.com with ESMTPS id sj4si591265vdc.174.2014.04.02.08.03.34 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 02 Apr 2014 08:03:34 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.220.175 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.175; Received: by mail-vc0-f175.google.com with SMTP id lh14so472159vcb.6 for ; Wed, 02 Apr 2014 08:03:34 -0700 (PDT) X-Received: by 10.52.166.18 with SMTP id zc18mr514505vdb.65.1396451014634; Wed, 02 Apr 2014 08:03:34 -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.12.8 with SMTP id v8csp330780vcv; Wed, 2 Apr 2014 08:03:34 -0700 (PDT) X-Received: by 10.224.69.193 with SMTP id a1mr1048211qaj.95.1396451012703; Wed, 02 Apr 2014 08:03:32 -0700 (PDT) Received: from lists.xen.org (lists.xen.org. [50.57.142.19]) by mx.google.com with ESMTPS id t96si911434qge.51.2014.04.02.08.03.31 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Wed, 02 Apr 2014 08:03:32 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of xen-devel-bounces@lists.xen.org designates 50.57.142.19 as permitted sender) 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 1WVMg6-0004zD-IP; Wed, 02 Apr 2014 15:02:10 +0000 Received: from mail6.bemta4.messagelabs.com ([85.158.143.247]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1WVMg3-0004ug-8C for xen-devel@lists.xensource.com; Wed, 02 Apr 2014 15:02:07 +0000 Received: from [85.158.143.35:20551] by server-1.bemta-4.messagelabs.com id 2F/52-09853-E662C335; Wed, 02 Apr 2014 15:02:06 +0000 X-Env-Sender: Stefano.Stabellini@citrix.com X-Msg-Ref: server-15.tower-21.messagelabs.com!1396450920!5795894!7 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.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 19812 invoked from network); 2 Apr 2014 15:02:05 -0000 Received: from smtp.citrix.com (HELO SMTP.CITRIX.COM) (66.165.176.89) by server-15.tower-21.messagelabs.com with RC4-SHA encrypted SMTP; 2 Apr 2014 15:02:05 -0000 X-IronPort-AV: E=Sophos;i="4.97,780,1389744000"; d="scan'208";a="117348325" Received: from accessns.citrite.net (HELO FTLPEX01CL02.citrite.net) ([10.9.154.239]) by FTLPIPO01.CITRIX.COM with ESMTP; 02 Apr 2014 15:02:01 +0000 Received: from ukmail1.uk.xensource.com (10.80.16.128) by smtprelay.citrix.com (10.13.107.79) with Microsoft SMTP Server id 14.2.342.4; Wed, 2 Apr 2014 11:01:58 -0400 Received: from kaball.uk.xensource.com ([10.80.2.59]) by ukmail1.uk.xensource.com with esmtp (Exim 4.69) (envelope-from ) id 1WVMfp-0003fd-DT; Wed, 02 Apr 2014 16:01:53 +0100 From: Stefano Stabellini To: Date: Wed, 2 Apr 2014 16:01:46 +0100 Message-ID: <1396450906-542-10-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 v6 10/10] 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=neutral (google.com: 209.85.220.175 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) 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. 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 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 | 77 ++++++++++++++++++++++++++++++++++++++---- xen/include/asm-arm/domain.h | 5 +-- xen/include/asm-arm/gic.h | 3 ++ 3 files changed, 76 insertions(+), 9 deletions(-) diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index 611990d..7faa0e9 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -721,6 +721,7 @@ static void gic_clear_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); /* HW interrupts cannot be ACTIVE and PENDING */ if ( p->desc == NULL && test_bit(GIC_IRQ_GUEST_ENABLED, &p->status) && @@ -735,6 +736,7 @@ static void gic_clear_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_PENDING, &p->status) && test_bit(GIC_IRQ_GUEST_ENABLED, &p->status)) @@ -763,22 +765,51 @@ void gic_clear_lrs(struct vcpu *v) static void gic_restore_pending_irqs(struct vcpu *v) { - int i; - struct pending_irq *p, *t; + int i = 0, lrs = nr_lrs; + struct pending_irq *p, *t, *p_r; unsigned long flags; + if ( list_empty(&v->arch.vgic.lr_pending) ) + return; + + spin_lock_irqsave(&v->arch.vgic.lock, flags); + 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; + if ( i >= nr_lrs ) + { + list_for_each_entry_reverse( p_r, + &v->arch.vgic.inflight_irqs, + inflight ) + { + if ( test_bit(GIC_IRQ_GUEST_VISIBLE, &p_r->status) && + !test_bit(GIC_IRQ_GUEST_ACTIVE, &p_r->status) ) + goto found; + if ( &p_r->inflight == p->inflight.next ) + goto out; + } + goto out; + +found: + i = p_r->lr; + p_r->lr = GIC_INVALID_LR; + set_bit(GIC_IRQ_GUEST_PENDING, &p_r->status); + clear_bit(GIC_IRQ_GUEST_VISIBLE, &p_r->status); + gic_add_to_lr_pending(v, p_r); + } - spin_lock_irqsave(&v->arch.vgic.lock, flags); gic_set_lr(i, p, GICH_LR_PENDING); list_del_init(&p->lr_queue); set_bit(i, &this_cpu(lr_mask)); - spin_unlock_irqrestore(&v->arch.vgic.lock, flags); + + lrs--; + if ( lrs == 0 ) + break; } +out: + spin_unlock_irqrestore(&v->arch.vgic.lock, flags); } void gic_clear_pending_irqs(struct vcpu *v) @@ -794,8 +825,40 @@ 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; + + 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; + } else if ( test_bit(GIC_IRQ_GUEST_ENABLED, &p->status) ) { + if ( p->priority < max_priority ) + max_priority = p->priority; + } + lrs--; + if ( lrs == 0 ) + break; + } + + spin_unlock_irqrestore(&v->arch.vgic.lock, flags); + + if ( max_priority < active_priority && + (max_priority >> 3) < 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 dcbeba1..696f36c 100644 --- a/xen/include/asm-arm/domain.h +++ b/xen/include/asm-arm/domain.h @@ -55,8 +55,9 @@ struct pending_irq * */ #define GIC_IRQ_GUEST_PENDING 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 5a9dc77..5d8f7f1 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