WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] Re: [PATCH] xen: do not clear and mask evtchns in __xen_evtc

To: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
Subject: [Xen-devel] Re: [PATCH] xen: do not clear and mask evtchns in __xen_evtchn_do_upcall
From: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
Date: Mon, 4 Apr 2011 13:17:39 -0400
Cc: Jeremy Fitzhardinge <Jeremy.Fitzhardinge@xxxxxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>, "linux-kernel@xxxxxxxxxxxxxxx" <linux-kernel@xxxxxxxxxxxxxxx>
Delivery-date: Mon, 04 Apr 2011 10:18:47 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <alpine.DEB.2.00.1104041521370.16492@kaball-desktop>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <alpine.DEB.2.00.1103291505090.16492@kaball-desktop> <20110330154630.GA17427@xxxxxxxxxxxx> <alpine.DEB.2.00.1104041521370.16492@kaball-desktop>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.5.20 (2009-06-14)
> I reworded this part of the commit message, see below updated patch.
> 

[looking]
.. snip..
> > Can you expand? As in for the GSI? Or for the MSI/MSI-X?
> 
> Linux on native would use handle_edge_irq for edge irqs and msis, and
> handle_fasteoi_irq for everything else.

What about per_cpu one?

.. snip ..

> > 
> > OK. You need a big comment about this in the code. Explain
> > why this is happening. B/c if you look at this from code
> > it seems like wrong thing to do for gsi's (as in you would
> > think handle_level_irq would the right choice).
> 
> Except handle_level_irq is not used anymore anywhere in the kernel, give
> a look at arch/x86/kernel/apic/io_apic.c:ioapic_register_intr.

'make_8259A_irq' ? But yeah, I don't think we will hit machines with
that architecture anymore.

> 
> Updated patch, rebased on 2.6.39-rc1 follows:
> 
> ---
> 
> 
> commit 6978531913b45abf3aff048475a2174a2cdaf288
> Author: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
> Date:   Tue Mar 29 14:15:06 2011 +0000
> 
>     xen: do not clear and mask evtchns in __xen_evtchn_do_upcall
>     
>     Change the irq handler of virqs and pirqs that don't need EOI (pirqs
>     that correspond to physical edge interrupts) to handle_edge_irq.
>     
>     Use handle_fasteoi_irq for pirqs that need eoi (they generally
>     correspond to level triggered irqs), no risk in loosing interrupts
>     because we have to EOI the irq anyway.
>     
>     This change has the following benefits:
>     
>     - it uses the very same handlers that Linux would use on native for the
>     same irqs (handle_edge_irq for edge irqs and msis, and
                                                   ^^^-'MSIs/MSI-Xs'
>     handle_fasteoi_irq for everything else);
>     
>     - it uses these handlers in the same way Linux would use them: it let
                                                                           ^- 
's'

>     Linux mask\unmask and ack the irq when Linux want to mask\unmask and ack
                                                       ^- 's'
>     the irq;
>     
>     See genericirq in the kernel docbook docs for more informations.

Say 'Documentation/DocBook/genericirq.tmpl'

[edit: The patch looks OK to me, but let me think about this some more over this
week and sketch out the flow].

>     
>     Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
> 
> diff --git a/drivers/xen/events.c b/drivers/xen/events.c
> index 036343b..186eb1e 100644
> --- a/drivers/xen/events.c
> +++ b/drivers/xen/events.c
> @@ -118,6 +118,8 @@ static DEFINE_PER_CPU(unsigned long 
> [NR_EVENT_CHANNELS/BITS_PER_LONG],
>  static struct irq_chip xen_dynamic_chip;
>  static struct irq_chip xen_percpu_chip;
>  static struct irq_chip xen_pirq_chip;
> +static void enable_dynirq(struct irq_data *data);
> +static void disable_dynirq(struct irq_data *data);
>  
>  /* Get info for IRQ */
>  static struct irq_info *info_for_irq(unsigned irq)
> @@ -473,16 +475,6 @@ static void xen_free_irq(unsigned irq)
>       irq_free_desc(irq);
>  }
>  
> -static void pirq_unmask_notify(int irq)
> -{
> -     struct physdev_eoi eoi = { .irq = pirq_from_irq(irq) };
> -
> -     if (unlikely(pirq_needs_eoi(irq))) {
> -             int rc = HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi);
> -             WARN_ON(rc);
> -     }
> -}
> -
>  static void pirq_query_unmask(int irq)
>  {
>       struct physdev_irq_status_query irq_status;
> @@ -506,6 +498,29 @@ static bool probing_irq(int irq)
>       return desc && desc->action == NULL;
>  }
>  
> +static void eoi_pirq(struct irq_data *data)
> +{
> +     int evtchn = evtchn_from_irq(data->irq);
> +     struct physdev_eoi eoi = { .irq = pirq_from_irq(data->irq) };
> +     int rc = 0;
> +
> +     irq_move_irq(data);
> +
> +     if (VALID_EVTCHN(evtchn))
> +             clear_evtchn(evtchn);
> +
> +     if (pirq_needs_eoi(data->irq)) {
> +             rc = HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi);
> +             WARN_ON(rc);
> +     }
> +}
> +
> +static void mask_ack_pirq(struct irq_data *data)
> +{
> +     disable_dynirq(data);
> +     eoi_pirq(data);
> +}
> + 
>  static unsigned int __startup_pirq(unsigned int irq)
>  {
>       struct evtchn_bind_pirq bind_pirq;
> @@ -539,7 +554,7 @@ static unsigned int __startup_pirq(unsigned int irq)
>  
>  out:
>       unmask_evtchn(evtchn);
> -     pirq_unmask_notify(irq);
> +     eoi_pirq(irq_get_irq_data(irq));
>  
>       return 0;
>  }
> @@ -572,27 +587,6 @@ static void shutdown_pirq(struct irq_data *data)
>       info->evtchn = 0;
>  }
>  
> -static void enable_pirq(struct irq_data *data)
> -{
> -     startup_pirq(data);
> -}
> -
> -static void disable_pirq(struct irq_data *data)
> -{
> -}
> -
> -static void ack_pirq(struct irq_data *data)
> -{
> -     int evtchn = evtchn_from_irq(data->irq);
> -
> -     irq_move_irq(data);
> -
> -     if (VALID_EVTCHN(evtchn)) {
> -             mask_evtchn(evtchn);
> -             clear_evtchn(evtchn);
> -     }
> -}
> -
>  static int find_irq_by_gsi(unsigned gsi)
>  {
>       struct irq_info *info;
> @@ -639,9 +633,6 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi,
>       if (irq < 0)
>               goto out;
>  
> -     irq_set_chip_and_handler_name(irq, &xen_pirq_chip, handle_level_irq,
> -                                   name);
> -
>       irq_op.irq = irq;
>       irq_op.vector = 0;
>  
> @@ -658,6 +649,19 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi,
>       xen_irq_info_pirq_init(irq, 0, pirq, gsi, irq_op.vector,
>                              shareable ? PIRQ_SHAREABLE : 0);
>  
> +     pirq_query_unmask(irq);
> +     /* we try to follow the same convention as Linux on native:
> +      * handle_edge_irq for edge irqs and handle_fasteoi_irq for level
> +      * irqs, see ioapic_register_intr (handle_level_irq is not used
> +      * anymore).
> +      */
> +     if (pirq_needs_eoi(irq))
> +             irq_set_chip_and_handler_name(irq, &xen_pirq_chip,
> +                             handle_fasteoi_irq, name);
> +     else
> +             irq_set_chip_and_handler_name(irq, &xen_pirq_chip,
> +                             handle_edge_irq, name);
> +
>  out:
>       spin_unlock(&irq_mapping_update_lock);
>  
> @@ -690,8 +694,8 @@ int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct 
> msi_desc *msidesc,
>       if (irq == -1)
>               goto out;
>  
> -     irq_set_chip_and_handler_name(irq, &xen_pirq_chip, handle_level_irq,
> -                                   name);
> +     irq_set_chip_and_handler_name(irq, &xen_pirq_chip, handle_edge_irq,
> +                     name);
>  
>       xen_irq_info_pirq_init(irq, 0, pirq, 0, vector, 0);
>       ret = irq_set_msi_desc(irq, msidesc);
> @@ -773,7 +777,7 @@ int bind_evtchn_to_irq(unsigned int evtchn)
>                       goto out;
>  
>               irq_set_chip_and_handler_name(irq, &xen_dynamic_chip,
> -                                           handle_fasteoi_irq, "event");
> +                                           handle_edge_irq, "event");
>  
>               xen_irq_info_evtchn_init(irq, evtchn);
>       }
> @@ -1181,9 +1185,6 @@ static void __xen_evtchn_do_upcall(void)
>                               port = (word_idx * BITS_PER_LONG) + bit_idx;
>                               irq = evtchn_to_irq[port];
>  
> -                             mask_evtchn(port);
> -                             clear_evtchn(port);
> -
>                               if (irq != -1) {
>                                       desc = irq_to_desc(irq);
>                                       if (desc)
> @@ -1339,12 +1340,18 @@ static void ack_dynirq(struct irq_data *data)
>  {
>       int evtchn = evtchn_from_irq(data->irq);
>  
> -     irq_move_masked_irq(data);
> +     irq_move_irq(data);
>  
>       if (VALID_EVTCHN(evtchn))
> -             unmask_evtchn(evtchn);
> +             clear_evtchn(evtchn);
>  }
>  
> +static void mask_ack_dynirq(struct irq_data *data)
> +{
> +     disable_dynirq(data);
> +     ack_dynirq(data);
> +}
> + 
>  static int retrigger_dynirq(struct irq_data *data)
>  {
>       int evtchn = evtchn_from_irq(data->irq);
> @@ -1533,11 +1540,12 @@ void xen_irq_resume(void)
>  static struct irq_chip xen_dynamic_chip __read_mostly = {
>       .name                   = "xen-dyn",
>  
> -     .irq_disable            = disable_dynirq,
>       .irq_mask               = disable_dynirq,
>       .irq_unmask             = enable_dynirq,
>  
> -     .irq_eoi                = ack_dynirq,
> +     .irq_ack                = ack_dynirq,
> +     .irq_mask_ack           = mask_ack_dynirq,
> +
>       .irq_set_affinity       = set_affinity_irq,
>       .irq_retrigger          = retrigger_dynirq,
>  };
> @@ -1548,13 +1556,12 @@ static struct irq_chip xen_pirq_chip __read_mostly = {
>       .irq_startup            = startup_pirq,
>       .irq_shutdown           = shutdown_pirq,
>  
> -     .irq_enable             = enable_pirq,
> -     .irq_unmask             = enable_pirq,
> -
> -     .irq_disable            = disable_pirq,
> -     .irq_mask               = disable_pirq,
> +     .irq_mask               = disable_dynirq,
> +     .irq_unmask             = enable_dynirq,
>  
> -     .irq_ack                = ack_pirq,
> +     .irq_ack                = eoi_pirq,
> +     .irq_eoi                = eoi_pirq,
> +     .irq_mask_ack           = mask_ack_pirq,
>  
>       .irq_set_affinity       = set_affinity_irq,
>  

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel