From patchwork Wed Mar 19 12:32:05 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefano Stabellini X-Patchwork-Id: 26570 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 8349220534 for ; Wed, 19 Mar 2014 12:33:52 +0000 (UTC) Received: by mail-pa0-f70.google.com with SMTP id lj1sf22327974pab.1 for ; Wed, 19 Mar 2014 05:33:51 -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=naKPbLyLthy/hReCHbSKJtrSZhw5UcARF9v8SeEfN0k=; b=GI1O8jfOsSMOw0OKLAlZRdaCaLnS3Q2H02Q5mkua0aUIpXVIDwZdqO9p5gKNXGIjf+ eFWLKTEYjEa2xFwtb4yWO+Tsyw67XIqq5liGK0cu99Zcbz11nYmRcQ9Vzbd/cfOjXTz+ RPU5blYutPL884nURHwDjMXuWWYXqefXLTRLAsdehPy1aCtXMUxQuqh54F9edMJAz1cJ QjLJChZPfVD6Z8KocviIJGnnjf5zD6iuTlm69PSxccvWcnhmCpB/9D9K5Q1GzbEa+9ZB 2ugulyiuH59xWXWMI9/BYWqaU7Y7DpCYvZ9Eik2gXp0YBQNv6HEPczTp+4jKlHRs9Gqc wbgA== X-Gm-Message-State: ALoCoQn7L5XacadT7FvQoyBjObfr/r6BQ+wxtY+fY16QpASFq13LnnkIE4WLKRN1I6gFlZ9JkFgp X-Received: by 10.66.149.67 with SMTP id ty3mr14373186pab.27.1395232431668; Wed, 19 Mar 2014 05:33:51 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.34.36 with SMTP id k33ls34342qgk.20.gmail; Wed, 19 Mar 2014 05:33:51 -0700 (PDT) X-Received: by 10.52.189.33 with SMTP id gf1mr14535694vdc.26.1395232431465; Wed, 19 Mar 2014 05:33:51 -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 la9si2379725veb.38.2014.03.19.05.33.51 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 19 Mar 2014 05:33:51 -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 lh14so8987249vcb.34 for ; Wed, 19 Mar 2014 05:33:51 -0700 (PDT) X-Received: by 10.220.95.139 with SMTP id d11mr17071362vcn.21.1395232431365; Wed, 19 Mar 2014 05:33:51 -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.78.9 with SMTP id i9csp295214vck; Wed, 19 Mar 2014 05:33:50 -0700 (PDT) X-Received: by 10.224.60.71 with SMTP id o7mr43382610qah.38.1395232430413; Wed, 19 Mar 2014 05:33:50 -0700 (PDT) Received: from lists.xen.org (lists.xen.org. [50.57.142.19]) by mx.google.com with ESMTPS id f7si12677417qge.198.2014.03.19.05.33.50 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Wed, 19 Mar 2014 05:33:50 -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 1WQFfw-0007Zp-1e; Wed, 19 Mar 2014 12:32:52 +0000 Received: from mail6.bemta4.messagelabs.com ([85.158.143.247]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1WQFfm-0007Qg-6L for xen-devel@lists.xensource.com; Wed, 19 Mar 2014 12:32:42 +0000 Received: from [85.158.143.35:27062] by server-1.bemta-4.messagelabs.com id F1/65-09853-96E89235; Wed, 19 Mar 2014 12:32:41 +0000 X-Env-Sender: Stefano.Stabellini@citrix.com X-Msg-Ref: server-5.tower-21.messagelabs.com!1395232356!3212920!6 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 19211 invoked from network); 19 Mar 2014 12:32:40 -0000 Received: from smtp.citrix.com (HELO SMTP.CITRIX.COM) (66.165.176.89) by server-5.tower-21.messagelabs.com with RC4-SHA encrypted SMTP; 19 Mar 2014 12:32:40 -0000 X-IronPort-AV: E=Sophos;i="4.97,685,1389744000"; d="scan'208";a="112829432" Received: from accessns.citrite.net (HELO FTLPEX01CL03.citrite.net) ([10.9.154.239]) by FTLPIPO01.CITRIX.COM with ESMTP; 19 Mar 2014 12:32:37 +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, 19 Mar 2014 08:32:35 -0400 Received: from kaball.uk.xensource.com ([10.80.2.59]) by ukmail1.uk.xensource.com with esmtp (Exim 4.69) (envelope-from ) id 1WQFfa-0005Tm-QH; Wed, 19 Mar 2014 12:32:30 +0000 From: Stefano Stabellini To: Date: Wed, 19 Mar 2014 12:32:05 +0000 Message-ID: <1395232325-19226-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: MIA1 Cc: julien.grall@citrix.com, jtd@galois.com, Ian.Campbell@citrix.com, Stefano Stabellini Subject: [Xen-devel] [PATCH v4 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 v4: - in gic_events_need_delivery go through inflight_irqs and only consider enabled irqs. --- 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 bc9d66d..533964e 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); + } - 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) @@ -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.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 517128e..fe20fd2 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