[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 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

>> --- 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 *);
>>
>>




_______________________________________________
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®.