[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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



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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.