diff options
Diffstat (limited to 'kernel/irq/manage.c')
-rw-r--r-- | kernel/irq/manage.c | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 4c69326aa773..e49a288fa479 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -616,6 +616,22 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, | |||
616 | return ret; | 616 | return ret; |
617 | } | 617 | } |
618 | 618 | ||
619 | #ifdef CONFIG_HARDIRQS_SW_RESEND | ||
620 | int irq_set_parent(int irq, int parent_irq) | ||
621 | { | ||
622 | unsigned long flags; | ||
623 | struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0); | ||
624 | |||
625 | if (!desc) | ||
626 | return -EINVAL; | ||
627 | |||
628 | desc->parent_irq = parent_irq; | ||
629 | |||
630 | irq_put_desc_unlock(desc, flags); | ||
631 | return 0; | ||
632 | } | ||
633 | #endif | ||
634 | |||
619 | /* | 635 | /* |
620 | * Default primary interrupt handler for threaded interrupts. Is | 636 | * Default primary interrupt handler for threaded interrupts. Is |
621 | * assigned as primary handler when request_threaded_irq is called | 637 | * assigned as primary handler when request_threaded_irq is called |
@@ -716,6 +732,7 @@ static void | |||
716 | irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action) | 732 | irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action) |
717 | { | 733 | { |
718 | cpumask_var_t mask; | 734 | cpumask_var_t mask; |
735 | bool valid = true; | ||
719 | 736 | ||
720 | if (!test_and_clear_bit(IRQTF_AFFINITY, &action->thread_flags)) | 737 | if (!test_and_clear_bit(IRQTF_AFFINITY, &action->thread_flags)) |
721 | return; | 738 | return; |
@@ -730,10 +747,18 @@ irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action) | |||
730 | } | 747 | } |
731 | 748 | ||
732 | raw_spin_lock_irq(&desc->lock); | 749 | raw_spin_lock_irq(&desc->lock); |
733 | cpumask_copy(mask, desc->irq_data.affinity); | 750 | /* |
751 | * This code is triggered unconditionally. Check the affinity | ||
752 | * mask pointer. For CPU_MASK_OFFSTACK=n this is optimized out. | ||
753 | */ | ||
754 | if (desc->irq_data.affinity) | ||
755 | cpumask_copy(mask, desc->irq_data.affinity); | ||
756 | else | ||
757 | valid = false; | ||
734 | raw_spin_unlock_irq(&desc->lock); | 758 | raw_spin_unlock_irq(&desc->lock); |
735 | 759 | ||
736 | set_cpus_allowed_ptr(current, mask); | 760 | if (valid) |
761 | set_cpus_allowed_ptr(current, mask); | ||
737 | free_cpumask_var(mask); | 762 | free_cpumask_var(mask); |
738 | } | 763 | } |
739 | #else | 764 | #else |
@@ -793,7 +818,7 @@ static void irq_thread_dtor(struct callback_head *unused) | |||
793 | action = kthread_data(tsk); | 818 | action = kthread_data(tsk); |
794 | 819 | ||
795 | pr_err("exiting task \"%s\" (%d) is an active IRQ thread (irq %d)\n", | 820 | pr_err("exiting task \"%s\" (%d) is an active IRQ thread (irq %d)\n", |
796 | tsk->comm ? tsk->comm : "", tsk->pid, action->irq); | 821 | tsk->comm, tsk->pid, action->irq); |
797 | 822 | ||
798 | 823 | ||
799 | desc = irq_to_desc(action->irq); | 824 | desc = irq_to_desc(action->irq); |
@@ -833,6 +858,8 @@ static int irq_thread(void *data) | |||
833 | init_task_work(&on_exit_work, irq_thread_dtor); | 858 | init_task_work(&on_exit_work, irq_thread_dtor); |
834 | task_work_add(current, &on_exit_work, false); | 859 | task_work_add(current, &on_exit_work, false); |
835 | 860 | ||
861 | irq_thread_check_affinity(desc, action); | ||
862 | |||
836 | while (!irq_wait_for_interrupt(action)) { | 863 | while (!irq_wait_for_interrupt(action)) { |
837 | irqreturn_t action_ret; | 864 | irqreturn_t action_ret; |
838 | 865 | ||
@@ -936,6 +963,16 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
936 | */ | 963 | */ |
937 | get_task_struct(t); | 964 | get_task_struct(t); |
938 | new->thread = t; | 965 | new->thread = t; |
966 | /* | ||
967 | * Tell the thread to set its affinity. This is | ||
968 | * important for shared interrupt handlers as we do | ||
969 | * not invoke setup_affinity() for the secondary | ||
970 | * handlers as everything is already set up. Even for | ||
971 | * interrupts marked with IRQF_NO_BALANCE this is | ||
972 | * correct as we want the thread to move to the cpu(s) | ||
973 | * on which the requesting code placed the interrupt. | ||
974 | */ | ||
975 | set_bit(IRQTF_AFFINITY, &new->thread_flags); | ||
939 | } | 976 | } |
940 | 977 | ||
941 | if (!alloc_cpumask_var(&mask, GFP_KERNEL)) { | 978 | if (!alloc_cpumask_var(&mask, GFP_KERNEL)) { |