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

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