From patchwork Mon Mar 31 16:02:37 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 27497 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qc0-f198.google.com (mail-qc0-f198.google.com [209.85.216.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 7E618202E0 for ; Mon, 31 Mar 2014 16:02:43 +0000 (UTC) Received: by mail-qc0-f198.google.com with SMTP id r5sf19348920qcx.5 for ; Mon, 31 Mar 2014 09:02:43 -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:message-id:date:from:user-agent :mime-version:to:cc:subject:references:in-reply-to:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe:content-type :content-transfer-encoding; bh=PGj8rSEdP3eP4pHHGGBDyllV1nYGOUubLNwl55EcTvU=; b=NRSxhXieMRsefdIt03c83w9gvd4AS9AXiIfNF0FPNZc858vYgGQk+jbFPLAP1d/3vU r4ilYBh6Pb7zGpQ3C7Et69S8lnFli26d0rbHXuFrLvhw7oOFtL7Pzm+DWiDvYqwR2nWL ZhQdaE+a3VwbIYtrNV1LSfGOfVozSDg+dIAZkEDSoGvgxA//uKdJ/d3G7gpIdsC5QADt w0UQFAtOqinsnKbPiVzJdPF0oG89YQMhZ1G537c5Qj8E7px2qve5GRc0uw6yIvN2uegV AtucWZhKYih09byUMX+C9LVuARhIfZUEX/vu05muyxH0ETfQyDNhLf3LG1trzd9fr0D8 m7qg== X-Gm-Message-State: ALoCoQlEHh8HEpL+pqWx7QGU+1Vw30To8dW0Ge2zUMfiRVIoLsNArKurRAfFH3bM92CtaCbuo2Vp X-Received: by 10.52.146.45 with SMTP id sz13mr9014138vdb.6.1396281763040; Mon, 31 Mar 2014 09:02:43 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.48.39 with SMTP id n36ls2518809qga.19.gmail; Mon, 31 Mar 2014 09:02:42 -0700 (PDT) X-Received: by 10.58.4.68 with SMTP id i4mr24432050vei.8.1396281762948; Mon, 31 Mar 2014 09:02:42 -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 fn10si3030919vdc.207.2014.03.31.09.02.42 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 31 Mar 2014 09:02:42 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.128.172 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.128.172; Received: by mail-ve0-f172.google.com with SMTP id jx11so8487432veb.3 for ; Mon, 31 Mar 2014 09:02:42 -0700 (PDT) X-Received: by 10.52.72.48 with SMTP id a16mr20102842vdv.19.1396281762866; Mon, 31 Mar 2014 09:02:42 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.12.8 with SMTP id v8csp154258vcv; Mon, 31 Mar 2014 09:02:42 -0700 (PDT) X-Received: by 10.180.189.169 with SMTP id gj9mr13441357wic.17.1396281761924; Mon, 31 Mar 2014 09:02:41 -0700 (PDT) Received: from mail-we0-f175.google.com (mail-we0-f175.google.com [74.125.82.175]) by mx.google.com with ESMTPS id c4si3668784wjb.13.2014.03.31.09.02.41 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 31 Mar 2014 09:02:41 -0700 (PDT) Received-SPF: neutral (google.com: 74.125.82.175 is neither permitted nor denied by best guess record for domain of julien.grall@linaro.org) client-ip=74.125.82.175; Received: by mail-we0-f175.google.com with SMTP id q58so4901356wes.6 for ; Mon, 31 Mar 2014 09:02:41 -0700 (PDT) X-Received: by 10.180.12.43 with SMTP id v11mr13307683wib.33.1396281760069; Mon, 31 Mar 2014 09:02:40 -0700 (PDT) Received: from [10.80.2.139] ([185.25.64.249]) by mx.google.com with ESMTPSA id 4sm33918150eeq.33.2014.03.31.09.02.39 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 31 Mar 2014 09:02:39 -0700 (PDT) Message-ID: <5339919D.7090801@linaro.org> Date: Mon, 31 Mar 2014 17:02:37 +0100 From: Julien Grall User-Agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/20131104 Icedove/17.0.10 MIME-Version: 1.0 To: Ian Campbell CC: xen-devel@lists.xenproject.org, Keir Fraser , patches@linaro.org, tim@xen.org, stefano.stabellini@citrix.com Subject: Re: [Xen-devel] [PATCH for-4.5 7/8] xen/irq: Handle multiple action per IRQ References: <1390581822-32624-1-git-send-email-julien.grall@linaro.org> <1390581822-32624-8-git-send-email-julien.grall@linaro.org> <1392810905.29739.19.camel@kazak.uk.xensource.com> <53398D84.3020901@linaro.org> <1396281181.8667.29.camel@kazak.uk.xensource.com> In-Reply-To: <1396281181.8667.29.camel@kazak.uk.xensource.com> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: julien.grall@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.128.172 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 Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , On 03/31/2014 04:53 PM, Ian Campbell wrote: > On Mon, 2014-03-31 at 16:45 +0100, Julien Grall wrote: >> On 02/19/2014 11:55 AM, Ian Campbell wrote: >>> On Fri, 2014-01-24 at 16:43 +0000, Julien Grall wrote: >>>> On ARM, it may happen (eg ARM SMMU) to setup multiple handler for the same >>>> interrupt. >>> >>> Mention here that you are therefore creating a linked list of actions >>> for each interrupt. >>> >>> If you use xen/list.h for this then you get a load of helpers and >>> iterators which would save you open coding them. >> >> I've tried to use xen/list.h. The amount of code it's basically the same >> and we I have to write open code to get the first element of the list > > Why? Can you post your WIP patch please for comparison. Because: - there is no helper to get the first element (__setup_irq) - I need to use 2 variables to search for an element in a list as there is no way to know after the end of the loop if we found or not an element. Below an incremental patch which change next field to a list (doesn't compile and not finished): diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index 7ea4da8..f4f5b71 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -545,36 +545,33 @@ void release_irq(unsigned int irq, const void *dev_id) { struct irq_desc *desc; unsigned long flags; - struct irqaction *action, **action_ptr; + struct irqaction *action, *next; desc = irq_to_desc(irq); spin_lock_irqsave(&desc->lock,flags); - desc->handler->shutdown(desc); - action = desc->action; - action_ptr = &desc->action; - for ( ;; ) + action = NULL; + list_for_each_entry(next, &desc->action, next) { - action = *action_ptr; - - if ( !action ) + if ( next->dev_id == dev_id ) { - printk(XENLOG_WARNING "Trying to free already-free IRQ %u\n", irq); - return; - } - - if ( action->dev_id == dev_id ) + action = next; break; + } + } - action_ptr = &action->next; + if ( !action ) + { + printk(XENLOG_WARNING "Trying to free already-free IRQ %u\n", irq); + return; } /* Found it - remove it from the action list */ - *action_ptr = action->next; + list_del_init(&action->next); /* If this was the list action, shut down the IRQ */ - if ( !desc->action ) + if ( list_empty(&desc->action) ) { desc->handler->shutdown(desc); desc->status &= ~IRQ_GUEST; @@ -592,12 +589,10 @@ void release_irq(unsigned int irq, const void *dev_id) static int __setup_irq(struct irq_desc *desc, struct irqaction *new, unsigned int irqflags) { - struct irqaction *action = desc->action; - ASSERT(new != NULL); /* Sanity check if the IRQ already have an action attached */ - if ( action != NULL ) + if ( !list_empty(&desc->action) ) { /* Check that IRQ is marked as shared */ if ( !(desc->status & IRQ_SHARED) || !(irqflags & IRQ_SHARED) ) @@ -610,8 +605,8 @@ static int __setup_irq(struct irq_desc *desc, struct irqaction *new, if ( irqflags & IRQ_SHARED ) desc->status |= IRQ_SHARED; - new->next = desc->action; - desc->action = new; + INIT_LIST_HEAD(&new->next); + list_add_tail(&new->next, &desc->action); dsb(sy); return 0; diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c index d6f3500..8a9ae3d 100644 --- a/xen/arch/arm/irq.c +++ b/xen/arch/arm/irq.c @@ -56,6 +56,7 @@ irq_desc_t *__irq_to_desc(int irq) int __init arch_init_one_irq_desc(struct irq_desc *desc) { desc->arch.type = DT_IRQ_TYPE_NONE; + INIT_LIST_HEAD(&desc->action); return 0; } @@ -151,7 +152,6 @@ int request_irq(unsigned int irq, void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq) { struct irq_desc *desc = irq_to_desc(irq); - struct irqaction *action = desc->action; /* TODO: perfc_incr(irqs); */ @@ -162,7 +162,7 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq) spin_lock(&desc->lock); desc->handler->ack(desc); - if ( action == NULL ) + if ( list_empty(&desc->action) ) { printk("Unknown %s %#3.3x\n", is_fiq ? "FIQ" : "IRQ", irq); @@ -171,6 +171,8 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq) if ( desc->status & IRQ_GUEST ) { + struct irqaction *action = list_entry(&desc->action, struct irqaction, + next); struct domain *d = action->dev_id; desc->handler->end(desc); @@ -194,16 +196,14 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq) desc->status |= IRQ_INPROGRESS; - action = desc->action; while ( desc->status & IRQ_PENDING ) { + struct irqaction *action, *next; + desc->status &= ~IRQ_PENDING; spin_unlock_irq(&desc->lock); - do - { + list_for_each_entry_safe(action, next, &desc->action, next) action->handler(irq, action->dev_id, regs); - action = action->next; - } while ( action ); spin_lock_irq(&desc->lock); } diff --git a/xen/include/xen/irq.h b/xen/include/xen/irq.h index 20548aa..a926554 100644 --- a/xen/include/xen/irq.h +++ b/xen/include/xen/irq.h @@ -17,7 +17,9 @@ struct irqaction { const char *name; void *dev_id; bool_t free_on_release; - struct irqaction *next; +#ifdef CONFIG_ARM + struct list_head next; +#endif }; /* @@ -73,7 +75,11 @@ typedef struct irq_desc { unsigned int status; /* IRQ status */ hw_irq_controller *handler; struct msi_desc *msi_desc; +#ifdef CONFIG_ARM + struct list_head action; /* IRQ action list */ +#else struct irqaction *action; /* IRQ action list */ +#endif int irq; spinlock_t lock; struct arch_irq_desc arch;