From patchwork Wed Feb 26 18:39:56 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefano Stabellini X-Patchwork-Id: 25409 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pa0-f70.google.com (mail-pa0-f70.google.com [209.85.220.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id CBD2E203C4 for ; Wed, 26 Feb 2014 18:57:10 +0000 (UTC) Received: by mail-pa0-f70.google.com with SMTP id kx10sf2781563pab.5 for ; Wed, 26 Feb 2014 10:57:10 -0800 (PST) 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=rKzklCOBz3ZdEoIuf1zntE0AxwueeO/LtVDjHjo/1zk=; b=SwQutSd7UtV83ogu4agRn1KLjzdvKvKE+D92UFhVJGgTY3lmsYq6N/BAWdkhO7en0e 4sdQYjDsPWc+XgABif/TOxJ6/ImyLbXJ7JW0bBVwBN1nfnwAGEEqksJFXh9uRIhqDyMV MHPh4/nIk5oWCF8QmxyGhTCGsoSRVaYHzjFd720jevXvEU9gJtv6aOeyXkhTUAkuNgvR 1s0XV/3CodCqntp0JzDfgiQ5mASRaHALVQwYGoiWqn/bJthr/gkWUfI6dR432Q/DC/Bg xGx6GqIGOt7+BdZWWkO9ly7kVJpoO5Pq440a0JuUZ1DdVieXiELIwRWhaWtXoB7Y8TEP NH5g== X-Gm-Message-State: ALoCoQn1y7X3j0K2SlPsix854KsPrvip50Wa8Q7MoWkmYmvZIgS2ZLsVFlNG7HIf8JlJ02R2105G X-Received: by 10.66.253.9 with SMTP id zw9mr4482749pac.38.1393441030007; Wed, 26 Feb 2014 10:57:10 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.92.240 with SMTP id b103ls377127qge.57.gmail; Wed, 26 Feb 2014 10:57:09 -0800 (PST) X-Received: by 10.221.53.194 with SMTP id vr2mr395207vcb.41.1393441029833; Wed, 26 Feb 2014 10:57:09 -0800 (PST) Received: from mail-vc0-f181.google.com (mail-vc0-f181.google.com [209.85.220.181]) by mx.google.com with ESMTPS id sm10si463708vec.119.2014.02.26.10.57.09 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 26 Feb 2014 10:57:09 -0800 (PST) Received-SPF: neutral (google.com: 209.85.220.181 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.181; Received: by mail-vc0-f181.google.com with SMTP id lg15so1389970vcb.12 for ; Wed, 26 Feb 2014 10:57:09 -0800 (PST) X-Received: by 10.58.255.233 with SMTP id at9mr7188902ved.20.1393441029715; Wed, 26 Feb 2014 10:57:09 -0800 (PST) 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.174.196 with SMTP id u4csp47608vcz; Wed, 26 Feb 2014 10:57:09 -0800 (PST) X-Received: by 10.140.26.240 with SMTP id 103mr1546153qgv.92.1393441029243; Wed, 26 Feb 2014 10:57:09 -0800 (PST) Received: from lists.xen.org (lists.xen.org. [50.57.142.19]) by mx.google.com with ESMTPS id f2si1072668qaf.162.2014.02.26.10.57.08 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Wed, 26 Feb 2014 10:57:09 -0800 (PST) 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 1WIjdw-000132-SF; Wed, 26 Feb 2014 18:55:44 +0000 Received: from mail6.bemta4.messagelabs.com ([85.158.143.247]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1WIjdu-00012s-To for xen-devel@lists.xensource.com; Wed, 26 Feb 2014 18:55:43 +0000 Received: from [85.158.143.35:29490] by server-3.bemta-4.messagelabs.com id E4/1C-11539-EA83E035; Wed, 26 Feb 2014 18:55:42 +0000 X-Env-Sender: Stefano.Stabellini@citrix.com X-Msg-Ref: server-11.tower-21.messagelabs.com!1393440935!8548275!2 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.9.16; banners=-,-,- X-VirusChecked: Checked Received: (qmail 4663 invoked from network); 26 Feb 2014 18:55:41 -0000 Received: from smtp.citrix.com (HELO SMTP.CITRIX.COM) (66.165.176.89) by server-11.tower-21.messagelabs.com with RC4-SHA encrypted SMTP; 26 Feb 2014 18:55:41 -0000 X-IronPort-AV: E=Sophos;i="4.97,549,1389744000"; d="scan'208";a="106029919" Received: from accessns.citrite.net (HELO FTLPEX01CL03.citrite.net) ([10.9.154.239]) by FTLPIPO01.CITRIX.COM with ESMTP; 26 Feb 2014 18:55:35 +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.2.342.4; Wed, 26 Feb 2014 13:55:34 -0500 Received: from kaball.uk.xensource.com ([10.80.2.59]) by ukmail1.uk.xensource.com with esmtp (Exim 4.69) (envelope-from ) id 1WIjOm-0004S3-E2; Wed, 26 Feb 2014 18:40:04 +0000 From: Stefano Stabellini To: Date: Wed, 26 Feb 2014 18:39:56 +0000 Message-ID: <1393439997-26936-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, jtd@galois.com, Ian.Campbell@citrix.com, Stefano Stabellini Subject: [Xen-devel] [PATCH-4.5 v3 11/12] 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.181 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 --- xen/arch/arm/gic.c | 71 +++++++++++++++++++++++++++++++++++++----- xen/include/asm-arm/domain.h | 5 +-- xen/include/asm-arm/gic.h | 3 ++ 3 files changed, 70 insertions(+), 9 deletions(-) diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index 296d9a7..aaba8b0 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -709,6 +709,7 @@ static void _gic_clear_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) && @@ -723,6 +724,7 @@ static void _gic_clear_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 = nr_lrs; if ( test_bit(GIC_IRQ_GUEST_PENDING, &p->status) && test_bit(GIC_IRQ_GUEST_ENABLED, &p->status)) @@ -750,22 +752,47 @@ 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); + + p_r = list_entry(v->arch.vgic.inflight_irqs.prev, + typeof(*p_r), inflight); 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 ) + { + while ( !test_bit(GIC_IRQ_GUEST_VISIBLE, &p_r->status) || + test_bit(GIC_IRQ_GUEST_ACTIVE, &p_r->status) ) + { + p_r = list_entry(p_r->inflight.prev, typeof(*p_r), inflight); + if ( &p_r->inflight == p->inflight.next ) + goto out; + } + i = p_r->lr; + p_r->lr = nr_lrs; + 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->irq, p_r->priority); + } - spin_lock_irqsave(&v->arch.vgic.lock, flags); gic_set_lr(v, i, p->irq, GICH_LR_PENDING, p->priority); 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) @@ -779,8 +806,38 @@ 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); + + list_for_each_entry( p, &v->arch.vgic.lr_pending, lr_queue ) + { + if ( test_bit(GIC_IRQ_GUEST_ACTIVE, &p->status) ) + { + if ( p->priority < active_priority ) + active_priority = p->priority; + } else { + 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 7b636c8..86cb361 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_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; uint8_t lr; struct irq_desc *desc; /* only set it the irq corresponds to a physical 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