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

Re: [Xen-devel] [PATCH 1/2] IRQ: allocate CPU masks dynamically

To: Jan Beulich <JBeulich@xxxxxxxx>
Subject: Re: [Xen-devel] [PATCH 1/2] IRQ: allocate CPU masks dynamically
From: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
Date: Thu, 3 Nov 2011 15:43:22 +0000
Cc: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>, "Keir \(Xen.org\)" <keir@xxxxxxx>
Delivery-date: Thu, 03 Nov 2011 08:44:08 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <4EB2BE9E020000780005EC7F@xxxxxxxxxxxxxxxxxxxx>
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: <4EB2B2B5020000780005EBDD@xxxxxxxxxxxxxxxxxxxx> <4EB2A9F5.1060800@xxxxxxxxxx> <4EB2BE9E020000780005EC7F@xxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.23) Gecko/20110921 Lightning/1.0b2 Thunderbird/3.1.15
On 03/11/11 15:17, Jan Beulich wrote:
>>>> On 03.11.11 at 15:49, Andrew Cooper <andrew.cooper3@xxxxxxxxxx> wrote:
>> On 03/11/11 14:26, Jan Beulich wrote:
>>> IRQ: allocate CPU masks dynamically
>>>
>>> This includes delaying the initialization of dynamically created IRQs
>>> until their actual first use and some further elimination of uses of
>>> struct irq_cfg.
>>>
>>> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
>> Acked-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
>>
>> One query which may or may not affect the patch.  Would we get better
>> caching characteristics if all cpumasks were allocated in consecutive
>> memory, rather than having 3 individual allocs in arch_init_one_irq_desc ?
> That was what the first version of the patch did, rejected by Keir
> (and not liked too much by me either).
>
> Jan

My understanding of the objection was hiding the variables themselves as
an array in the code.

An alternative approach such as alloc'ing 3*sizeof(cpu mask) (cache
aligned) and assigning the relevant pointers to the current
cpumask_var_t's would be a suitable approach which causes the cpumasks
to be in contiguous memory, but not changing how they are referenced in
the code.

~Andrew

>>> --- a/xen/arch/ia64/linux-xen/irq_ia64.c
>>> +++ b/xen/arch/ia64/linux-xen/irq_ia64.c
>>> @@ -303,6 +303,9 @@ int __init request_irq_vector(unsigned i
>>>  void __init
>>>  init_IRQ (void)
>>>  {
>>> +#ifdef XEN
>>> +       BUG_ON(init_irq_data());
>>> +#endif
>>>         register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL);
>>>  #ifdef CONFIG_SMP
>>>         register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction);
>>> --- a/xen/arch/ia64/xen/irq.c
>>> +++ b/xen/arch/ia64/xen/irq.c
>>> @@ -74,17 +74,30 @@ unsigned int __ia64_local_vector_to_irq
>>>  /*
>>>   * Controller mappings for all interrupt sources:
>>>   */
>>> -irq_desc_t irq_desc[NR_IRQS] = {
>>> -       [0 ... NR_IRQS-1] = {
>>> -               .status = IRQ_DISABLED,
>>> -               .handler = &no_irq_type,
>>> -               .lock = SPIN_LOCK_UNLOCKED
>>> -               .arch = {
>>> -                       .vector = -1,
>>> -                       .cpu_mask = CPU_MASK_ALL,
>>> -               }
>>> +irq_desc_t irq_desc[NR_IRQS];
>>> +
>>> +int __init arch_init_one_irq_desc(struct irq_desc *desc)
>>> +{
>>> +       if (!alloc_cpumask_var(&desc->arch.cpu_mask))
>>> +               return -ENOMEM;
>>> +
>>> +       desc->arch.vector = -1;
>>> +       cpumask_setall(desc->arch.cpu_mask);
>>> +
>>> +       return 0;
>>> +}
>>> +
>>> +int __init init_irq_data(void)
>>> +{
>>> +       unsigned int irq;
>>> +
>>> +       for (irq = 0; irq < NR_IRQS; irq++) {
>>> +               struct irq_desc *desc = irq_to_desc(irq);
>>> +
>>> +               desc->irq = irq;
>>> +               init_one_irq_desc(desc);
>>>         }
>>> -};
>>> +}
>>>
>>>  void __do_IRQ_guest(int irq);
>>>
>>> --- a/xen/arch/x86/i8259.c
>>> +++ b/xen/arch/x86/i8259.c
>>> @@ -398,7 +398,7 @@ void __init init_IRQ(void)
>>>
>>>          desc->handler = &i8259A_irq_type;
>>>          per_cpu(vector_irq, cpu)[FIRST_LEGACY_VECTOR + irq] = irq;
>>> -        cpumask_copy(&desc->arch.cpu_mask, cpumask_of(cpu));
>>> +        cpumask_copy(desc->arch.cpu_mask, cpumask_of(cpu));
>>>          desc->arch.vector = FIRST_LEGACY_VECTOR + irq;
>>>      }
>>>
>>> --- a/xen/arch/x86/io_apic.c
>>> +++ b/xen/arch/x86/io_apic.c
>>> @@ -648,20 +648,21 @@ static int pin_2_irq(int idx, int apic,
>>>  void /*__init*/ setup_ioapic_dest(void)
>>>  {
>>>      int pin, ioapic, irq, irq_entry;
>>> -    struct irq_cfg *cfg;
>>>
>>>      if (skip_ioapic_setup)
>>>          return;
>>>
>>>      for (ioapic = 0; ioapic < nr_ioapics; ioapic++) {
>>>          for (pin = 0; pin < nr_ioapic_entries[ioapic]; pin++) {
>>> +            struct irq_desc *desc;
>>> +
>>>              irq_entry = find_irq_entry(ioapic, pin, mp_INT);
>>>              if (irq_entry == -1)
>>>                  continue;
>>>              irq = pin_2_irq(irq_entry, ioapic, pin);
>>> -            cfg = irq_cfg(irq);
>>> -            BUG_ON(cpus_empty(cfg->cpu_mask));
>>> -            set_ioapic_affinity_irq(irq_to_desc(irq), &cfg->cpu_mask);
>>> +            desc = irq_to_desc(irq);
>>> +            BUG_ON(cpumask_empty(desc->arch.cpu_mask));
>>> +            set_ioapic_affinity_irq(desc, desc->arch.cpu_mask);
>>>          }
>>>
>>>      }
>>> @@ -956,12 +957,12 @@ static void __init setup_IO_APIC_irqs(vo
>>>      struct IO_APIC_route_entry entry;
>>>      int apic, pin, idx, irq, first_notcon = 1, vector;
>>>      unsigned long flags;
>>> -    struct irq_cfg *cfg;
>>>
>>>      apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
>>>
>>>      for (apic = 0; apic < nr_ioapics; apic++) {
>>>          for (pin = 0; pin < nr_ioapic_entries[apic]; pin++) {
>>> +            struct irq_desc *desc;
>>>
>>>              /*
>>>               * add it to the IO-APIC irq-routing table:
>>> @@ -1016,9 +1017,9 @@ static void __init setup_IO_APIC_irqs(vo
>>>                  if (!apic && platform_legacy_irq(irq))
>>>                      disable_8259A_irq(irq_to_desc(irq));
>>>              }
>>> -            cfg = irq_cfg(irq);
>>> +            desc = irq_to_desc(irq);
>>>              SET_DEST(entry.dest.dest32, entry.dest.logical.logical_dest,
>>> -                     cpu_mask_to_apicid(&cfg->cpu_mask));
>>> +                     cpu_mask_to_apicid(desc->arch.cpu_mask));
>>>              spin_lock_irqsave(&ioapic_lock, flags);
>>>              __ioapic_write_entry(apic, pin, 0, entry);
>>>              set_native_irq_info(irq, TARGET_CPUS);
>>> @@ -2372,7 +2373,7 @@ int ioapic_guest_write(unsigned long phy
>>>      rte.vector = cfg->vector;
>>>
>>>      SET_DEST(rte.dest.dest32, rte.dest.logical.logical_dest,
>>> -             cpu_mask_to_apicid(&cfg->cpu_mask));
>>> +             cpu_mask_to_apicid(desc->arch.cpu_mask));
>>>
>>>      io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&rte) + 0));
>>>      io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&rte) + 1));
>>> --- a/xen/arch/x86/irq.c
>>> +++ b/xen/arch/x86/irq.c
>>> @@ -25,6 +25,7 @@
>>>  #include <public/physdev.h>
>>>
>>>  static void parse_irq_vector_map_param(char *s);
>>> +static int __assign_irq_vector(int irq, struct irq_desc *, const cpumask_t
>> *);
>>>  /* opt_noirqbalance: If true, software IRQ balancing/affinity is disabled.
>> */
>>>  bool_t __read_mostly opt_noirqbalance = 0;
>>> @@ -110,7 +111,7 @@ static int __init __bind_irq_vector(int
>>>  {
>>>      cpumask_t online_mask;
>>>      int cpu;
>>> -    struct irq_cfg *cfg = irq_cfg(irq);
>>> +    struct irq_desc *desc = irq_to_desc(irq);
>>>
>>>      BUG_ON((unsigned)irq >= nr_irqs);
>>>      BUG_ON((unsigned)vector >= NR_VECTORS);
>>> @@ -118,21 +119,22 @@ static int __init __bind_irq_vector(int
>>>      cpumask_and(&online_mask, cpu_mask, &cpu_online_map);
>>>      if (cpumask_empty(&online_mask))
>>>          return -EINVAL;
>>> -    if ((cfg->vector == vector) && cpumask_equal(&cfg->cpu_mask, 
>>> &online_mask))
>>> +    if ( (desc->arch.vector == vector) &&
>>> +         cpumask_equal(desc->arch.cpu_mask, &online_mask) )
>>>          return 0;
>>> -    if (cfg->vector != IRQ_VECTOR_UNASSIGNED)
>>> +    if ( desc->arch.vector != IRQ_VECTOR_UNASSIGNED )
>>>          return -EBUSY;
>>>      trace_irq_mask(TRC_HW_IRQ_BIND_VECTOR, irq, vector, &online_mask);
>>>      for_each_cpu_mask(cpu, online_mask)
>>>          per_cpu(vector_irq, cpu)[vector] = irq;
>>> -    cfg->vector = vector;
>>> -    cpumask_copy(&cfg->cpu_mask, &online_mask);
>>> -    if ( cfg->used_vectors )
>>> +    desc->arch.vector = vector;
>>> +    cpumask_copy(desc->arch.cpu_mask, &online_mask);
>>> +    if ( desc->arch.used_vectors )
>>>      {
>>> -        ASSERT(!test_bit(vector, cfg->used_vectors));
>>> -        set_bit(vector, cfg->used_vectors);
>>> +        ASSERT(!test_bit(vector, desc->arch.used_vectors));
>>> +        set_bit(vector, desc->arch.used_vectors);
>>>      }
>>> -    cfg->used = IRQ_USED;
>>> +    desc->arch.used = IRQ_USED;
>>>      if (IO_APIC_IRQ(irq))
>>>          irq_vector[irq] = vector;
>>>      return 0;
>>> @@ -166,14 +168,17 @@ int create_irq(void)
>>>  {
>>>      unsigned long flags;
>>>      int irq, ret;
>>> -    irq = -ENOSPC;
>>> +    struct irq_desc *desc;
>>>
>>>      spin_lock_irqsave(&vector_lock, flags);
>>>
>>>      irq = find_unassigned_irq();
>>>      if (irq < 0)
>>>           goto out;
>>> -    ret = __assign_irq_vector(irq, irq_cfg(irq), TARGET_CPUS);
>>> +    desc = irq_to_desc(irq);
>>> +    ret = init_one_irq_desc(desc);
>>> +    if (!ret)
>>> +        ret = __assign_irq_vector(irq, desc, TARGET_CPUS);
>>>      if (ret < 0)
>>>          irq = ret;
>>>  out:
>>> @@ -197,7 +202,7 @@ static void dynamic_irq_cleanup(unsigned
>>>      desc->msi_desc = NULL;
>>>      desc->handler = &no_irq_type;
>>>      desc->arch.used_vectors = NULL;
>>> -    cpumask_setall(&desc->affinity);
>>> +    cpumask_setall(desc->affinity);
>>>      spin_unlock_irqrestore(&desc->lock, flags);
>>>
>>>      /* Wait to make sure it's not being used on another CPU */
>>> @@ -211,38 +216,38 @@ static void __clear_irq_vector(int irq)
>>>  {
>>>      int cpu, vector, old_vector;
>>>      cpumask_t tmp_mask;
>>> -    struct irq_cfg *cfg = irq_cfg(irq);
>>> +    struct irq_desc *desc = irq_to_desc(irq);
>>>
>>> -    BUG_ON(!cfg->vector);
>>> +    BUG_ON(!desc->arch.vector);
>>>
>>> -    /* Always clear cfg->vector */
>>> -    vector = cfg->vector;
>>> -    cpumask_and(&tmp_mask, &cfg->cpu_mask, &cpu_online_map);
>>> +    /* Always clear desc->arch.vector */
>>> +    vector = desc->arch.vector;
>>> +    cpumask_and(&tmp_mask, desc->arch.cpu_mask, &cpu_online_map);
>>>
>>>      for_each_cpu_mask(cpu, tmp_mask) {
>>>          ASSERT( per_cpu(vector_irq, cpu)[vector] == irq );
>>>          per_cpu(vector_irq, cpu)[vector] = -1;
>>>      }
>>>
>>> -    cfg->vector = IRQ_VECTOR_UNASSIGNED;
>>> -    cpumask_clear(&cfg->cpu_mask);
>>> +    desc->arch.vector = IRQ_VECTOR_UNASSIGNED;
>>> +    cpumask_clear(desc->arch.cpu_mask);
>>>
>>> -    if ( cfg->used_vectors )
>>> +    if ( desc->arch.used_vectors )
>>>      {
>>> -        ASSERT(test_bit(vector, cfg->used_vectors));
>>> -        clear_bit(vector, cfg->used_vectors);
>>> +        ASSERT(test_bit(vector, desc->arch.used_vectors));
>>> +        clear_bit(vector, desc->arch.used_vectors);
>>>      }
>>>
>>> -    cfg->used = IRQ_UNUSED;
>>> +    desc->arch.used = IRQ_UNUSED;
>>>
>>>      trace_irq_mask(TRC_HW_IRQ_CLEAR_VECTOR, irq, vector, &tmp_mask);
>>>
>>> -    if (likely(!cfg->move_in_progress))
>>> +    if ( likely(!desc->arch.move_in_progress) )
>>>          return;
>>>
>>> -    /* If we were in motion, also clear cfg->old_vector */
>>> -    old_vector = cfg->old_vector;
>>> -    cpumask_and(&tmp_mask, &cfg->old_cpu_mask, &cpu_online_map);
>>> +    /* If we were in motion, also clear desc->arch.old_vector */
>>> +    old_vector = desc->arch.old_vector;
>>> +    cpumask_and(&tmp_mask, desc->arch.old_cpu_mask, &cpu_online_map);
>>>
>>>      for_each_cpu_mask(cpu, tmp_mask) {
>>>          ASSERT( per_cpu(vector_irq, cpu)[old_vector] == irq );
>>> @@ -250,16 +255,16 @@ static void __clear_irq_vector(int irq)
>>>          per_cpu(vector_irq, cpu)[old_vector] = -1;
>>>       }
>>>
>>> -    cfg->old_vector = IRQ_VECTOR_UNASSIGNED;
>>> -    cpumask_clear(&cfg->old_cpu_mask);
>>> +    desc->arch.old_vector = IRQ_VECTOR_UNASSIGNED;
>>> +    cpumask_clear(desc->arch.old_cpu_mask);
>>>
>>> -    if ( cfg->used_vectors )
>>> +    if ( desc->arch.used_vectors )
>>>      {
>>> -        ASSERT(test_bit(old_vector, cfg->used_vectors));
>>> -        clear_bit(old_vector, cfg->used_vectors);
>>> +        ASSERT(test_bit(old_vector, desc->arch.used_vectors));
>>> +        clear_bit(old_vector, desc->arch.used_vectors);
>>>      }
>>>
>>> -    cfg->move_in_progress = 0;
>>> +    desc->arch.move_in_progress = 0;
>>>  }
>>>
>>>  void clear_irq_vector(int irq)
>>> @@ -296,25 +301,28 @@ int irq_to_vector(int irq)
>>>      return vector;
>>>  }
>>>
>>> -static void __init init_one_irq_desc(struct irq_desc *desc)
>>> +int arch_init_one_irq_desc(struct irq_desc *desc)
>>>  {
>>> -    desc->status  = IRQ_DISABLED;
>>> -    desc->handler = &no_irq_type;
>>> -    desc->action  = NULL;
>>> -    desc->msi_desc = NULL;
>>> -    spin_lock_init(&desc->lock);
>>> -    cpumask_setall(&desc->affinity);
>>> -    INIT_LIST_HEAD(&desc->rl_link);
>>> -}
>>> +    if ( !zalloc_cpumask_var(&desc->arch.cpu_mask) )
>>> +        return -ENOMEM;
>>> +
>>> +    if ( !alloc_cpumask_var(&desc->arch.old_cpu_mask) )
>>> +    {
>>> +        free_cpumask_var(desc->arch.cpu_mask);
>>> +        return -ENOMEM;
>>> +    }
>>>
>>> -static void __init init_one_irq_cfg(struct irq_cfg *cfg)
>>> -{
>>> -    cfg->vector = IRQ_VECTOR_UNASSIGNED;
>>> -    cfg->old_vector = IRQ_VECTOR_UNASSIGNED;
>>> -    cpumask_clear(&cfg->cpu_mask);
>>> -    cpumask_clear(&cfg->old_cpu_mask);
>>> -    cfg->used_vectors = NULL;
>>> -    cfg->used = IRQ_UNUSED;
>>> +    if ( !alloc_cpumask_var(&desc->arch.pending_mask) )
>>> +    {
>>> +        free_cpumask_var(desc->arch.old_cpu_mask);
>>> +        free_cpumask_var(desc->arch.cpu_mask);
>>> +        return -ENOMEM;
>>> +    }
>>> +
>>> +    desc->arch.vector = IRQ_VECTOR_UNASSIGNED;
>>> +    desc->arch.old_vector = IRQ_VECTOR_UNASSIGNED;
>>> +
>>> +    return 0;
>>>  }
>>>
>>>  int __init init_irq_data(void)
>>> @@ -331,12 +339,13 @@ int __init init_irq_data(void)
>>>      if ( !irq_desc || !irq_vector )
>>>          return -ENOMEM;
>>>
>>> -    for (irq = 0; irq < nr_irqs; irq++) {
>>> +    for (irq = 0; irq < nr_irqs_gsi; irq++) {
>>>          desc = irq_to_desc(irq);
>>>          desc->irq = irq;
>>>          init_one_irq_desc(desc);
>>> -        init_one_irq_cfg(&desc->arch);
>>>      }
>>> +    for (; irq < nr_irqs; irq++)
>>> +        irq_to_desc(irq)->irq = irq;
>>>
>>>      /* Never allocate the hypercall vector or Linux/BSD fast-trap vector. 
>>> */
>>>      set_bit(LEGACY_SYSCALL_VECTOR, used_vectors);
>>> @@ -403,7 +412,8 @@ static vmask_t *irq_get_used_vector_mask
>>>      return ret;
>>>  }
>>>
>>> -int __assign_irq_vector(int irq, struct irq_cfg *cfg, const cpumask_t 
>>> *mask)
>>> +static int __assign_irq_vector(
>>> +    int irq, struct irq_desc *desc, const cpumask_t *mask)
>>>  {
>>>      /*
>>>       * NOTE! The local APIC isn't very good at handling
>>> @@ -426,13 +436,13 @@ int __assign_irq_vector(int irq, struct
>>>      old_vector = irq_to_vector(irq);
>>>      if (old_vector) {
>>>          cpumask_and(&tmp_mask, mask, &cpu_online_map);
>>> -        if (cpumask_intersects(&tmp_mask, &cfg->cpu_mask)) {
>>> -            cfg->vector = old_vector;
>>> +        if (cpumask_intersects(&tmp_mask, desc->arch.cpu_mask)) {
>>> +            desc->arch.vector = old_vector;
>>>              return 0;
>>>          }
>>>      }
>>>
>>> -    if ((cfg->move_in_progress) || cfg->move_cleanup_count)
>>> +    if ( desc->arch.move_in_progress || desc->arch.move_cleanup_count )
>>>          return -EAGAIN;
>>>
>>>      err = -ENOSPC;
>>> @@ -440,9 +450,9 @@ int __assign_irq_vector(int irq, struct
>>>      /* This is the only place normal IRQs are ever marked
>>>       * as "in use".  If they're not in use yet, check to see
>>>       * if we need to assign a global vector mask. */
>>> -    if ( cfg->used == IRQ_USED )
>>> +    if ( desc->arch.used == IRQ_USED )
>>>      {
>>> -        irq_used_vectors = cfg->used_vectors;
>>> +        irq_used_vectors = desc->arch.used_vectors;
>>>      }
>>>      else
>>>          irq_used_vectors = irq_get_used_vector_mask(irq);
>>> @@ -485,29 +495,29 @@ next:
>>>          current_offset = offset;
>>>          local_irq_save(flags);
>>>          if (old_vector) {
>>> -            cfg->move_in_progress = 1;
>>> -            cpumask_copy(&cfg->old_cpu_mask, &cfg->cpu_mask);
>>> -            cfg->old_vector = cfg->vector;
>>> +            desc->arch.move_in_progress = 1;
>>> +            cpumask_copy(desc->arch.old_cpu_mask, desc->arch.cpu_mask);
>>> +            desc->arch.old_vector = desc->arch.vector;
>>>          }
>>>          trace_irq_mask(TRC_HW_IRQ_ASSIGN_VECTOR, irq, vector, &tmp_mask);
>>>          for_each_cpu_mask(new_cpu, tmp_mask)
>>>              per_cpu(vector_irq, new_cpu)[vector] = irq;
>>> -        cfg->vector = vector;
>>> -        cpumask_copy(&cfg->cpu_mask, &tmp_mask);
>>> +        desc->arch.vector = vector;
>>> +        cpumask_copy(desc->arch.cpu_mask, &tmp_mask);
>>>
>>> -        cfg->used = IRQ_USED;
>>> -        ASSERT((cfg->used_vectors == NULL)
>>> -               || (cfg->used_vectors == irq_used_vectors));
>>> -        cfg->used_vectors = irq_used_vectors;
>>> +        desc->arch.used = IRQ_USED;
>>> +        ASSERT((desc->arch.used_vectors == NULL)
>>> +               || (desc->arch.used_vectors == irq_used_vectors));
>>> +        desc->arch.used_vectors = irq_used_vectors;
>>>
>>>          if (IO_APIC_IRQ(irq))
>>>              irq_vector[irq] = vector;
>>>
>>> -        if ( cfg->used_vectors )
>>> +        if ( desc->arch.used_vectors )
>>>          {
>>> -            ASSERT(!test_bit(vector, cfg->used_vectors));
>>> +            ASSERT(!test_bit(vector, desc->arch.used_vectors));
>>>
>>> -            set_bit(vector, cfg->used_vectors);
>>> +            set_bit(vector, desc->arch.used_vectors);
>>>          }
>>>
>>>          err = 0;
>>> @@ -521,16 +531,15 @@ int assign_irq_vector(int irq)
>>>  {
>>>      int ret;
>>>      unsigned long flags;
>>> -    struct irq_cfg *cfg = irq_cfg(irq);
>>>      struct irq_desc *desc = irq_to_desc(irq);
>>>
>>>      BUG_ON(irq >= nr_irqs || irq <0);
>>>
>>>      spin_lock_irqsave(&vector_lock, flags);
>>> -    ret = __assign_irq_vector(irq, cfg, TARGET_CPUS);
>>> +    ret = __assign_irq_vector(irq, desc, TARGET_CPUS);
>>>      if (!ret) {
>>> -        ret = cfg->vector;
>>> -        cpumask_copy(&desc->affinity, &cfg->cpu_mask);
>>> +        ret = desc->arch.vector;
>>> +        cpumask_copy(desc->affinity, desc->arch.cpu_mask);
>>>      }
>>>      spin_unlock_irqrestore(&vector_lock, flags);
>>>      return ret;
>>> @@ -543,15 +552,16 @@ int assign_irq_vector(int irq)
>>>  void __setup_vector_irq(int cpu)
>>>  {
>>>      int irq, vector;
>>> -    struct irq_cfg *cfg;
>>>
>>>      /* Clear vector_irq */
>>>      for (vector = 0; vector < NR_VECTORS; ++vector)
>>>          per_cpu(vector_irq, cpu)[vector] = -1;
>>>      /* Mark the inuse vectors */
>>>      for (irq = 0; irq < nr_irqs; ++irq) {
>>> -        cfg = irq_cfg(irq);
>>> -        if (!cpu_isset(cpu, cfg->cpu_mask))
>>> +        struct irq_desc *desc = irq_to_desc(irq);
>>> +
>>> +        if (!irq_desc_initialized(desc) ||
>>> +            !cpumask_test_cpu(cpu, desc->arch.cpu_mask))
>>>              continue;
>>>          vector = irq_to_vector(irq);
>>>          per_cpu(vector_irq, cpu)[vector] = irq;
>>> @@ -560,12 +570,14 @@ void __setup_vector_irq(int cpu)
>>>
>>>  void move_masked_irq(struct irq_desc *desc)
>>>  {
>>> +    cpumask_t *pending_mask = desc->arch.pending_mask;
>>> +
>>>      if (likely(!(desc->status & IRQ_MOVE_PENDING)))
>>>          return;
>>>
>>>      desc->status &= ~IRQ_MOVE_PENDING;
>>>
>>> -    if (unlikely(cpus_empty(desc->pending_mask)))
>>> +    if (unlikely(cpumask_empty(pending_mask)))
>>>          return;
>>>
>>>      if (!desc->handler->set_affinity)
>>> @@ -580,10 +592,10 @@ void move_masked_irq(struct irq_desc *de
>>>       *
>>>       * For correct operation this depends on the caller masking the irqs.
>>>       */
>>> -    if (likely(cpus_intersects(desc->pending_mask, cpu_online_map)))
>>> -        desc->handler->set_affinity(desc, &desc->pending_mask);
>>> +    if ( likely(cpumask_intersects(pending_mask, &cpu_online_map)) )
>>> +        desc->handler->set_affinity(desc, pending_mask);
>>>
>>> -    cpumask_clear(&desc->pending_mask);
>>> +    cpumask_clear(pending_mask);
>>>  }
>>>
>>>  void move_native_irq(struct irq_desc *desc)
>>> @@ -626,7 +638,8 @@ fastcall void smp_irq_move_cleanup_inter
>>>          if (!desc->arch.move_cleanup_count)
>>>              goto unlock;
>>>
>>> -        if (vector == desc->arch.vector && cpumask_test_cpu(me,
>> &desc->arch.cpu_mask))
>>> +        if ( vector == desc->arch.vector &&
>>> +             cpumask_test_cpu(me, desc->arch.cpu_mask) )
>>>              goto unlock;
>>>
>>>          irr = apic_read(APIC_IRR + (vector / 32 * 0x10));
>>> @@ -653,7 +666,7 @@ fastcall void smp_irq_move_cleanup_inter
>>>          if ( desc->arch.move_cleanup_count == 0 )
>>>          {
>>>              desc->arch.old_vector = IRQ_VECTOR_UNASSIGNED;
>>> -            cpumask_clear(&desc->arch.old_cpu_mask);
>>> +            cpumask_clear(desc->arch.old_cpu_mask);
>>>
>>>              if ( desc->arch.used_vectors )
>>>              {
>>> @@ -673,7 +686,7 @@ static void send_cleanup_vector(struct i
>>>  {
>>>      cpumask_t cleanup_mask;
>>>
>>> -    cpumask_and(&cleanup_mask, &desc->arch.old_cpu_mask, &cpu_online_map);
>>> +    cpumask_and(&cleanup_mask, desc->arch.old_cpu_mask, &cpu_online_map);
>>>      desc->arch.move_cleanup_count = cpumask_weight(&cleanup_mask);
>>>      genapic->send_IPI_mask(&cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR);
>>>
>>> @@ -690,7 +703,8 @@ void irq_complete_move(struct irq_desc *
>>>      vector = get_irq_regs()->entry_vector;
>>>      me = smp_processor_id();
>>>
>>> -    if (vector == desc->arch.vector && cpumask_test_cpu(me, 
>>> &desc->arch.cpu_mask))
>>> +    if ( vector == desc->arch.vector &&
>>> +         cpumask_test_cpu(me, desc->arch.cpu_mask) )
>>>          send_cleanup_vector(desc);
>>>  }
>>>
>>> @@ -708,15 +722,15 @@ unsigned int set_desc_affinity(struct ir
>>>
>>>      local_irq_save(flags);
>>>      lock_vector_lock();
>>> -    ret = __assign_irq_vector(irq, &desc->arch, mask);
>>> +    ret = __assign_irq_vector(irq, desc, mask);
>>>      unlock_vector_lock();
>>>      local_irq_restore(flags);
>>>
>>>      if (ret < 0)
>>>          return BAD_APICID;
>>>
>>> -    cpumask_copy(&desc->affinity, mask);
>>> -    cpumask_and(&dest_mask, mask, &desc->arch.cpu_mask);
>>> +    cpumask_copy(desc->affinity, mask);
>>> +    cpumask_and(&dest_mask, mask, desc->arch.cpu_mask);
>>>
>>>      return cpu_mask_to_apicid(&dest_mask);
>>>  }
>>> @@ -730,7 +744,7 @@ void irq_set_affinity(struct irq_desc *d
>>>      ASSERT(spin_is_locked(&desc->lock));
>>>      desc->status &= ~IRQ_MOVE_PENDING;
>>>      wmb();
>>> -    cpumask_copy(&desc->pending_mask, mask);
>>> +    cpumask_copy(desc->arch.pending_mask, mask);
>>>      wmb();
>>>      desc->status |= IRQ_MOVE_PENDING;
>>>  }
>>> @@ -1992,13 +2006,13 @@ static void dump_irqs(unsigned char key)
>>>
>>>          desc = irq_to_desc(irq);
>>>
>>> -        if ( !desc->handler || desc->handler == &no_irq_type )
>>> +        if ( !irq_desc_initialized(desc) || desc->handler == &no_irq_type )
>>>              continue;
>>>
>>>          spin_lock_irqsave(&desc->lock, flags);
>>>
>>>          cpumask_scnprintf(keyhandler_scratch, sizeof(keyhandler_scratch),
>>> -                          &desc->affinity);
>>> +                          desc->affinity);
>>>          printk("   IRQ:%4d affinity:%s vec:%02x type=%-15s"
>>>                 " status=%08x ",
>>>                 irq, keyhandler_scratch, desc->arch.vector,
>>> @@ -2073,10 +2087,12 @@ void fixup_irqs(void)
>>>              continue;
>>>
>>>          desc = irq_to_desc(irq);
>>> +        if ( !irq_desc_initialized(desc) )
>>> +            continue;
>>>
>>>          spin_lock(&desc->lock);
>>>
>>> -        cpumask_copy(&affinity, &desc->affinity);
>>> +        cpumask_copy(&affinity, desc->affinity);
>>>          if ( !desc->action || cpumask_subset(&affinity, &cpu_online_map) )
>>>          {
>>>              spin_unlock(&desc->lock);
>>> --- a/xen/arch/x86/msi.c
>>> +++ b/xen/arch/x86/msi.c
>>> @@ -125,13 +125,13 @@ void msi_compose_msg(struct irq_desc *de
>>>      unsigned dest;
>>>      int vector = desc->arch.vector;
>>>
>>> -    if ( cpumask_empty(&desc->arch.cpu_mask) ) {
>>> +    if ( cpumask_empty(desc->arch.cpu_mask) ) {
>>>          dprintk(XENLOG_ERR,"%s, compose msi message error!!\n", __func__);
>>>          return;
>>>      }
>>>
>>>      if ( vector ) {
>>> -        dest = cpu_mask_to_apicid(&desc->arch.cpu_mask);
>>> +        dest = cpu_mask_to_apicid(desc->arch.cpu_mask);
>>>
>>>          msg->address_hi = MSI_ADDR_BASE_HI;
>>>          msg->address_lo =
>>> --- a/xen/arch/x86/smpboot.c
>>> +++ b/xen/arch/x86/smpboot.c
>>> @@ -1011,7 +1011,7 @@ void __init smp_intr_init(void)
>>>          irq_vector[irq] = FIRST_HIPRIORITY_VECTOR + seridx + 1;
>>>          per_cpu(vector_irq, cpu)[FIRST_HIPRIORITY_VECTOR + seridx + 1] =
>> irq;
>>>          irq_to_desc(irq)->arch.vector = FIRST_HIPRIORITY_VECTOR + seridx + 
>>> 1;
>>> -        cpumask_copy(&irq_to_desc(irq)->arch.cpu_mask, &cpu_online_map);
>>> +        cpumask_copy(irq_to_desc(irq)->arch.cpu_mask, &cpu_online_map);
>>>      }
>>>
>>>      /* IPI for cleanuping vectors after irq move */
>>> --- a/xen/common/Makefile
>>> +++ b/xen/common/Makefile
>>> @@ -5,6 +5,7 @@ obj-y += domctl.o
>>>  obj-y += domain.o
>>>  obj-y += event_channel.o
>>>  obj-y += grant_table.o
>>> +obj-y += irq.o
>>>  obj-y += kernel.o
>>>  obj-y += keyhandler.o
>>>  obj-y += kexec.o
>>> --- /dev/null
>>> +++ a/xen/common/irq.c
>>> @@ -0,0 +1,28 @@
>>> +#include <xen/config.h>
>>> +#include <xen/irq.h>
>>> +
>>> +int init_one_irq_desc(struct irq_desc *desc)
>>> +{
>>> +    int err;
>>> +
>>> +    if (irq_desc_initialized(desc))
>>> +        return 0;
>>> +
>>> +    if ( !alloc_cpumask_var(&desc->affinity) )
>>> +        return -ENOMEM;
>>> +
>>> +    desc->status = IRQ_DISABLED;
>>> +    desc->handler = &no_irq_type;
>>> +    spin_lock_init(&desc->lock);
>>> +    cpumask_setall(desc->affinity);
>>> +    INIT_LIST_HEAD(&desc->rl_link);
>>> +
>>> +    err = arch_init_one_irq_desc(desc);
>>> +    if ( err )
>>> +    {
>>> +        free_cpumask_var(desc->affinity);
>>> +        desc->handler = NULL;
>>> +    }
>>> +
>>> +    return err;
>>> +}
>>> --- a/xen/drivers/passthrough/vtd/iommu.c
>>> +++ b/xen/drivers/passthrough/vtd/iommu.c
>>> @@ -1965,17 +1965,18 @@ static int init_vtd_hw(void)
>>>      struct iommu_flush *flush = NULL;
>>>      int ret;
>>>      unsigned long flags;
>>> -    struct irq_cfg *cfg;
>>>
>>>      /*
>>>       * Basic VT-d HW init: set VT-d interrupt, clear VT-d faults.
>>>       */
>>>      for_each_drhd_unit ( drhd )
>>>      {
>>> +        struct irq_desc *desc;
>>> +
>>>          iommu = drhd->iommu;
>>>
>>> -        cfg = irq_cfg(iommu->irq);
>>> -        dma_msi_set_affinity(irq_to_desc(iommu->irq), &cfg->cpu_mask);
>>> +        desc = irq_to_desc(iommu->irq);
>>> +        dma_msi_set_affinity(desc, desc->arch.cpu_mask);
>>>
>>>          clear_fault_bits(iommu);
>>>
>>> --- a/xen/include/asm-ia64/linux-xen/asm/irq.h
>>> +++ b/xen/include/asm-ia64/linux-xen/asm/irq.h
>>> @@ -18,8 +18,10 @@
>>>  struct irq_cfg {
>>>  #define arch_irq_desc irq_cfg
>>>          int  vector;
>>> -        cpumask_t cpu_mask;
>>> +        cpumask_var_t cpu_mask;
>>>  };
>>> +
>>> +int init_irq_data(void);
>>>  #endif
>>>
>>>  static __inline__ int
>>> --- a/xen/include/asm-x86/irq.h
>>> +++ b/xen/include/asm-x86/irq.h
>>> @@ -33,8 +33,9 @@ struct irq_cfg {
>>>  #define arch_irq_desc irq_cfg
>>>          s16 vector;                  /* vector itself is only 8 bits, */
>>>          s16 old_vector;              /* but we use -1 for unassigned  */
>>> -        cpumask_t cpu_mask;
>>> -        cpumask_t old_cpu_mask;
>>> +        cpumask_var_t cpu_mask;
>>> +        cpumask_var_t old_cpu_mask;
>>> +        cpumask_var_t pending_mask;
>>>          unsigned move_cleanup_count;
>>>          vmask_t *used_vectors;
>>>          u8 move_in_progress : 1;
>>> @@ -174,8 +175,6 @@ void __setup_vector_irq(int cpu);
>>>  void move_native_irq(struct irq_desc *);
>>>  void move_masked_irq(struct irq_desc *);
>>>
>>> -int __assign_irq_vector(int irq, struct irq_cfg *, const cpumask_t *);
>>> -
>>>  int bind_irq_vector(int irq, int vector, const cpumask_t *);
>>>
>>>  void irq_set_affinity(struct irq_desc *, const cpumask_t *mask);
>>> --- a/xen/include/xen/irq.h
>>> +++ b/xen/include/xen/irq.h
>>> @@ -76,8 +76,7 @@ typedef struct irq_desc {
>>>      int irq;
>>>      spinlock_t lock;
>>>      struct arch_irq_desc arch;
>>> -    cpumask_t affinity;
>>> -    cpumask_t pending_mask;  /* IRQ migration pending mask */
>>> +    cpumask_var_t affinity;
>>>
>>>      /* irq ratelimit */
>>>      s_time_t rl_quantum_start;
>>> @@ -85,6 +84,11 @@ typedef struct irq_desc {
>>>      struct list_head rl_link;
>>>  } __cacheline_aligned irq_desc_t;
>>>
>>> +int init_one_irq_desc(struct irq_desc *);
>>> +int arch_init_one_irq_desc(struct irq_desc *);
>>> +
>>> +#define irq_desc_initialized(desc) ((desc)->handler != NULL)
>>> +
>>>  #if defined(__ia64__)
>>>  extern irq_desc_t irq_desc[NR_VECTORS];
>>>
>>> @@ -153,7 +157,7 @@ extern irq_desc_t *pirq_spin_lock_irq_de
>>>
>>>  static inline void set_native_irq_info(unsigned int irq, const cpumask_t
>> *mask)
>>>  {
>>> -    cpumask_copy(&irq_desc[irq].affinity, mask);
>>> +    cpumask_copy(irq_to_desc(irq)->affinity, mask);
>>>  }
>>>
>>>  unsigned int set_desc_affinity(struct irq_desc *, const cpumask_t *);
>>>
>>>
>
>

-- 
Andrew Cooper - Dom0 Kernel Engineer, Citrix XenServer
T: +44 (0)1223 225 900, http://www.citrix.com


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