diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2012-07-16 06:42:39 -0400 |
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2012-08-13 11:01:08 -0400 |
| commit | 81942621bd6b70b1a1ac4692b3f8f3be65a91b44 (patch) | |
| tree | fe5155456b7677d30bbbb801fe280e3e98bed445 /drivers/infiniband | |
| parent | 62ab7072476ae1600e877cc62b43758e485f4f1e (diff) | |
infiniband: Ehca: Use hotplug thread infrastructure
Get rid of the hotplug notifiers and use the generic hotplug thread
infrastructure.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/r/20120716103948.775527032@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers/infiniband')
| -rw-r--r-- | drivers/infiniband/hw/ehca/ehca_irq.c | 250 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ehca/ehca_irq.h | 6 |
2 files changed, 92 insertions, 164 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c index 53589000fd07..4eeac40cd943 100644 --- a/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/drivers/infiniband/hw/ehca/ehca_irq.c | |||
| @@ -42,6 +42,7 @@ | |||
| 42 | */ | 42 | */ |
| 43 | 43 | ||
| 44 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
| 45 | #include <linux/smpboot.h> | ||
| 45 | 46 | ||
| 46 | #include "ehca_classes.h" | 47 | #include "ehca_classes.h" |
| 47 | #include "ehca_irq.h" | 48 | #include "ehca_irq.h" |
| @@ -652,7 +653,7 @@ void ehca_tasklet_eq(unsigned long data) | |||
| 652 | ehca_process_eq((struct ehca_shca*)data, 1); | 653 | ehca_process_eq((struct ehca_shca*)data, 1); |
| 653 | } | 654 | } |
| 654 | 655 | ||
| 655 | static inline int find_next_online_cpu(struct ehca_comp_pool *pool) | 656 | static int find_next_online_cpu(struct ehca_comp_pool *pool) |
| 656 | { | 657 | { |
| 657 | int cpu; | 658 | int cpu; |
| 658 | unsigned long flags; | 659 | unsigned long flags; |
| @@ -662,17 +663,20 @@ static inline int find_next_online_cpu(struct ehca_comp_pool *pool) | |||
| 662 | ehca_dmp(cpu_online_mask, cpumask_size(), ""); | 663 | ehca_dmp(cpu_online_mask, cpumask_size(), ""); |
| 663 | 664 | ||
| 664 | spin_lock_irqsave(&pool->last_cpu_lock, flags); | 665 | spin_lock_irqsave(&pool->last_cpu_lock, flags); |
| 665 | cpu = cpumask_next(pool->last_cpu, cpu_online_mask); | 666 | do { |
| 666 | if (cpu >= nr_cpu_ids) | 667 | cpu = cpumask_next(pool->last_cpu, cpu_online_mask); |
| 667 | cpu = cpumask_first(cpu_online_mask); | 668 | if (cpu >= nr_cpu_ids) |
| 668 | pool->last_cpu = cpu; | 669 | cpu = cpumask_first(cpu_online_mask); |
| 670 | pool->last_cpu = cpu; | ||
| 671 | } while (!per_cpu_ptr(pool->cpu_comp_tasks, cpu)->active) | ||
| 669 | spin_unlock_irqrestore(&pool->last_cpu_lock, flags); | 672 | spin_unlock_irqrestore(&pool->last_cpu_lock, flags); |
| 670 | 673 | ||
| 671 | return cpu; | 674 | return cpu; |
| 672 | } | 675 | } |
| 673 | 676 | ||
| 674 | static void __queue_comp_task(struct ehca_cq *__cq, | 677 | static void __queue_comp_task(struct ehca_cq *__cq, |
| 675 | struct ehca_cpu_comp_task *cct) | 678 | struct ehca_cpu_comp_task *cct, |
| 679 | struct task_struct *thread) | ||
| 676 | { | 680 | { |
| 677 | unsigned long flags; | 681 | unsigned long flags; |
| 678 | 682 | ||
| @@ -683,7 +687,7 @@ static void __queue_comp_task(struct ehca_cq *__cq, | |||
| 683 | __cq->nr_callbacks++; | 687 | __cq->nr_callbacks++; |
| 684 | list_add_tail(&__cq->entry, &cct->cq_list); | 688 | list_add_tail(&__cq->entry, &cct->cq_list); |
| 685 | cct->cq_jobs++; | 689 | cct->cq_jobs++; |
| 686 | wake_up(&cct->wait_queue); | 690 | wake_up_process(thread); |
| 687 | } else | 691 | } else |
| 688 | __cq->nr_callbacks++; | 692 | __cq->nr_callbacks++; |
| 689 | 693 | ||
| @@ -695,6 +699,7 @@ static void queue_comp_task(struct ehca_cq *__cq) | |||
| 695 | { | 699 | { |
| 696 | int cpu_id; | 700 | int cpu_id; |
| 697 | struct ehca_cpu_comp_task *cct; | 701 | struct ehca_cpu_comp_task *cct; |
| 702 | struct task_struct *thread; | ||
| 698 | int cq_jobs; | 703 | int cq_jobs; |
| 699 | unsigned long flags; | 704 | unsigned long flags; |
| 700 | 705 | ||
| @@ -702,7 +707,8 @@ static void queue_comp_task(struct ehca_cq *__cq) | |||
| 702 | BUG_ON(!cpu_online(cpu_id)); | 707 | BUG_ON(!cpu_online(cpu_id)); |
| 703 | 708 | ||
| 704 | cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu_id); | 709 | cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu_id); |
| 705 | BUG_ON(!cct); | 710 | thread = per_cpu_ptr(pool->cpu_comp_threads, cpu_id); |
| 711 | BUG_ON(!cct || !thread); | ||
| 706 | 712 | ||
| 707 | spin_lock_irqsave(&cct->task_lock, flags); | 713 | spin_lock_irqsave(&cct->task_lock, flags); |
| 708 | cq_jobs = cct->cq_jobs; | 714 | cq_jobs = cct->cq_jobs; |
| @@ -710,28 +716,25 @@ static void queue_comp_task(struct ehca_cq *__cq) | |||
| 710 | if (cq_jobs > 0) { | 716 | if (cq_jobs > 0) { |
| 711 | cpu_id = find_next_online_cpu(pool); | 717 | cpu_id = find_next_online_cpu(pool); |
| 712 | cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu_id); | 718 | cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu_id); |
| 713 | BUG_ON(!cct); | 719 | thread = per_cpu_ptr(pool->cpu_comp_threads, cpu_id); |
| 720 | BUG_ON(!cct || !thread); | ||
| 714 | } | 721 | } |
| 715 | 722 | __queue_comp_task(__cq, cct, thread); | |
| 716 | __queue_comp_task(__cq, cct); | ||
| 717 | } | 723 | } |
| 718 | 724 | ||
| 719 | static void run_comp_task(struct ehca_cpu_comp_task *cct) | 725 | static void run_comp_task(struct ehca_cpu_comp_task *cct) |
| 720 | { | 726 | { |
| 721 | struct ehca_cq *cq; | 727 | struct ehca_cq *cq; |
| 722 | unsigned long flags; | ||
| 723 | |||
| 724 | spin_lock_irqsave(&cct->task_lock, flags); | ||
| 725 | 728 | ||
| 726 | while (!list_empty(&cct->cq_list)) { | 729 | while (!list_empty(&cct->cq_list)) { |
| 727 | cq = list_entry(cct->cq_list.next, struct ehca_cq, entry); | 730 | cq = list_entry(cct->cq_list.next, struct ehca_cq, entry); |
| 728 | spin_unlock_irqrestore(&cct->task_lock, flags); | 731 | spin_unlock_irq(&cct->task_lock); |
| 729 | 732 | ||
| 730 | comp_event_callback(cq); | 733 | comp_event_callback(cq); |
| 731 | if (atomic_dec_and_test(&cq->nr_events)) | 734 | if (atomic_dec_and_test(&cq->nr_events)) |
| 732 | wake_up(&cq->wait_completion); | 735 | wake_up(&cq->wait_completion); |
| 733 | 736 | ||
| 734 | spin_lock_irqsave(&cct->task_lock, flags); | 737 | spin_lock_irq(&cct->task_lock); |
| 735 | spin_lock(&cq->task_lock); | 738 | spin_lock(&cq->task_lock); |
| 736 | cq->nr_callbacks--; | 739 | cq->nr_callbacks--; |
| 737 | if (!cq->nr_callbacks) { | 740 | if (!cq->nr_callbacks) { |
| @@ -740,159 +743,76 @@ static void run_comp_task(struct ehca_cpu_comp_task *cct) | |||
| 740 | } | 743 | } |
| 741 | spin_unlock(&cq->task_lock); | 744 | spin_unlock(&cq->task_lock); |
| 742 | } | 745 | } |
| 743 | |||
| 744 | spin_unlock_irqrestore(&cct->task_lock, flags); | ||
| 745 | } | 746 | } |
| 746 | 747 | ||
| 747 | static int comp_task(void *__cct) | 748 | static void comp_task_park(unsigned int cpu) |
| 748 | { | 749 | { |
| 749 | struct ehca_cpu_comp_task *cct = __cct; | 750 | struct ehca_cpu_comp_task *cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu); |
| 750 | int cql_empty; | 751 | struct ehca_cpu_comp_task *target; |
| 751 | DECLARE_WAITQUEUE(wait, current); | 752 | struct task_struct *thread; |
| 752 | 753 | struct ehca_cq *cq, *tmp; | |
| 753 | set_current_state(TASK_INTERRUPTIBLE); | 754 | LIST_HEAD(list); |
| 754 | while (!kthread_should_stop()) { | ||
| 755 | add_wait_queue(&cct->wait_queue, &wait); | ||
| 756 | |||
| 757 | spin_lock_irq(&cct->task_lock); | ||
| 758 | cql_empty = list_empty(&cct->cq_list); | ||
| 759 | spin_unlock_irq(&cct->task_lock); | ||
| 760 | if (cql_empty) | ||
| 761 | schedule(); | ||
| 762 | else | ||
| 763 | __set_current_state(TASK_RUNNING); | ||
| 764 | |||
| 765 | remove_wait_queue(&cct->wait_queue, &wait); | ||
| 766 | 755 | ||
| 767 | spin_lock_irq(&cct->task_lock); | 756 | spin_lock_irq(&cct->task_lock); |
| 768 | cql_empty = list_empty(&cct->cq_list); | 757 | cct->cq_jobs = 0; |
| 769 | spin_unlock_irq(&cct->task_lock); | 758 | cct->active = 0; |
| 770 | if (!cql_empty) | 759 | list_splice_init(&cct->cq_list, &list); |
| 771 | run_comp_task(__cct); | 760 | spin_unlock_irq(&cct->task_lock); |
| 772 | 761 | ||
| 773 | set_current_state(TASK_INTERRUPTIBLE); | 762 | cpu = find_next_online_cpu(pool); |
| 763 | target = per_cpu_ptr(pool->cpu_comp_tasks, cpu); | ||
| 764 | thread = per_cpu_ptr(pool->cpu_comp_threads, cpu); | ||
| 765 | spin_lock_irq(&target->task_lock); | ||
| 766 | list_for_each_entry_safe(cq, tmp, &list, entry) { | ||
| 767 | list_del(&cq->entry); | ||
| 768 | __queue_comp_task(cq, target, thread); | ||
| 774 | } | 769 | } |
| 775 | __set_current_state(TASK_RUNNING); | 770 | spin_unlock_irq(&target->task_lock); |
| 776 | |||
| 777 | return 0; | ||
| 778 | } | ||
| 779 | |||
| 780 | static struct task_struct *create_comp_task(struct ehca_comp_pool *pool, | ||
| 781 | int cpu) | ||
| 782 | { | ||
| 783 | struct ehca_cpu_comp_task *cct; | ||
| 784 | |||
| 785 | cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu); | ||
| 786 | spin_lock_init(&cct->task_lock); | ||
| 787 | INIT_LIST_HEAD(&cct->cq_list); | ||
| 788 | init_waitqueue_head(&cct->wait_queue); | ||
| 789 | cct->task = kthread_create_on_node(comp_task, cct, cpu_to_node(cpu), | ||
| 790 | "ehca_comp/%d", cpu); | ||
| 791 | |||
| 792 | return cct->task; | ||
| 793 | } | 771 | } |
| 794 | 772 | ||
| 795 | static void destroy_comp_task(struct ehca_comp_pool *pool, | 773 | static void comp_task_stop(unsigned int cpu, bool online) |
| 796 | int cpu) | ||
| 797 | { | 774 | { |
| 798 | struct ehca_cpu_comp_task *cct; | 775 | struct ehca_cpu_comp_task *cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu); |
| 799 | struct task_struct *task; | ||
| 800 | unsigned long flags_cct; | ||
| 801 | |||
| 802 | cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu); | ||
| 803 | |||
| 804 | spin_lock_irqsave(&cct->task_lock, flags_cct); | ||
| 805 | 776 | ||
| 806 | task = cct->task; | 777 | spin_lock_irq(&cct->task_lock); |
| 807 | cct->task = NULL; | ||
| 808 | cct->cq_jobs = 0; | 778 | cct->cq_jobs = 0; |
| 809 | 779 | cct->active = 0; | |
| 810 | spin_unlock_irqrestore(&cct->task_lock, flags_cct); | 780 | WARN_ON(!list_empty(&cct->cq_list)); |
| 811 | 781 | spin_unlock_irq(&cct->task_lock); | |
| 812 | if (task) | ||
| 813 | kthread_stop(task); | ||
| 814 | } | 782 | } |
| 815 | 783 | ||
| 816 | static void __cpuinit take_over_work(struct ehca_comp_pool *pool, int cpu) | 784 | static int comp_task_should_run(unsigned int cpu) |
| 817 | { | 785 | { |
| 818 | struct ehca_cpu_comp_task *cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu); | 786 | struct ehca_cpu_comp_task *cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu); |
| 819 | LIST_HEAD(list); | ||
| 820 | struct ehca_cq *cq; | ||
| 821 | unsigned long flags_cct; | ||
| 822 | |||
| 823 | spin_lock_irqsave(&cct->task_lock, flags_cct); | ||
| 824 | |||
| 825 | list_splice_init(&cct->cq_list, &list); | ||
| 826 | |||
| 827 | while (!list_empty(&list)) { | ||
| 828 | cq = list_entry(cct->cq_list.next, struct ehca_cq, entry); | ||
| 829 | |||
| 830 | list_del(&cq->entry); | ||
| 831 | __queue_comp_task(cq, this_cpu_ptr(pool->cpu_comp_tasks)); | ||
| 832 | } | ||
| 833 | |||
| 834 | spin_unlock_irqrestore(&cct->task_lock, flags_cct); | ||
| 835 | 787 | ||
| 788 | return cct->cq_jobs; | ||
| 836 | } | 789 | } |
| 837 | 790 | ||
| 838 | static int __cpuinit comp_pool_callback(struct notifier_block *nfb, | 791 | static int comp_task(unsigned int cpu) |
| 839 | unsigned long action, | ||
| 840 | void *hcpu) | ||
| 841 | { | 792 | { |
| 842 | unsigned int cpu = (unsigned long)hcpu; | 793 | struct ehca_cpu_comp_task *cct = this_cpu_ptr(pool->cpu_comp_tasks); |
| 843 | struct ehca_cpu_comp_task *cct; | 794 | int cql_empty; |
| 844 | 795 | ||
| 845 | switch (action) { | 796 | spin_lock_irq(&cct->task_lock); |
| 846 | case CPU_UP_PREPARE: | 797 | cql_empty = list_empty(&cct->cq_list); |
| 847 | case CPU_UP_PREPARE_FROZEN: | 798 | if (!cql_empty) { |
| 848 | ehca_gen_dbg("CPU: %x (CPU_PREPARE)", cpu); | 799 | __set_current_state(TASK_RUNNING); |
| 849 | if (!create_comp_task(pool, cpu)) { | 800 | run_comp_task(cct); |
| 850 | ehca_gen_err("Can't create comp_task for cpu: %x", cpu); | ||
| 851 | return notifier_from_errno(-ENOMEM); | ||
| 852 | } | ||
| 853 | break; | ||
| 854 | case CPU_UP_CANCELED: | ||
| 855 | case CPU_UP_CANCELED_FROZEN: | ||
| 856 | ehca_gen_dbg("CPU: %x (CPU_CANCELED)", cpu); | ||
| 857 | cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu); | ||
| 858 | kthread_bind(cct->task, cpumask_any(cpu_online_mask)); | ||
| 859 | destroy_comp_task(pool, cpu); | ||
| 860 | break; | ||
| 861 | case CPU_ONLINE: | ||
| 862 | case CPU_ONLINE_FROZEN: | ||
| 863 | ehca_gen_dbg("CPU: %x (CPU_ONLINE)", cpu); | ||
| 864 | cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu); | ||
| 865 | kthread_bind(cct->task, cpu); | ||
| 866 | wake_up_process(cct->task); | ||
| 867 | break; | ||
| 868 | case CPU_DOWN_PREPARE: | ||
| 869 | case CPU_DOWN_PREPARE_FROZEN: | ||
| 870 | ehca_gen_dbg("CPU: %x (CPU_DOWN_PREPARE)", cpu); | ||
| 871 | break; | ||
| 872 | case CPU_DOWN_FAILED: | ||
| 873 | case CPU_DOWN_FAILED_FROZEN: | ||
| 874 | ehca_gen_dbg("CPU: %x (CPU_DOWN_FAILED)", cpu); | ||
| 875 | break; | ||
| 876 | case CPU_DEAD: | ||
| 877 | case CPU_DEAD_FROZEN: | ||
| 878 | ehca_gen_dbg("CPU: %x (CPU_DEAD)", cpu); | ||
| 879 | destroy_comp_task(pool, cpu); | ||
| 880 | take_over_work(pool, cpu); | ||
| 881 | break; | ||
| 882 | } | 801 | } |
| 883 | 802 | spin_unlock_irq(&cct->task_lock); | |
| 884 | return NOTIFY_OK; | ||
| 885 | } | 803 | } |
| 886 | 804 | ||
| 887 | static struct notifier_block comp_pool_callback_nb __cpuinitdata = { | 805 | static struct smp_hotplug_thread comp_pool_threads = { |
| 888 | .notifier_call = comp_pool_callback, | 806 | .thread_should_run = comp_task_should_run, |
| 889 | .priority = 0, | 807 | .thread_fn = comp_task, |
| 808 | .thread_comm = "ehca_comp/%u", | ||
| 809 | .cleanup = comp_task_stop, | ||
| 810 | .park = comp_task_park, | ||
| 890 | }; | 811 | }; |
| 891 | 812 | ||
| 892 | int ehca_create_comp_pool(void) | 813 | int ehca_create_comp_pool(void) |
| 893 | { | 814 | { |
| 894 | int cpu; | 815 | int cpu, ret = -ENOMEM; |
| 895 | struct task_struct *task; | ||
| 896 | 816 | ||
| 897 | if (!ehca_scaling_code) | 817 | if (!ehca_scaling_code) |
| 898 | return 0; | 818 | return 0; |
| @@ -905,38 +825,46 @@ int ehca_create_comp_pool(void) | |||
| 905 | pool->last_cpu = cpumask_any(cpu_online_mask); | 825 | pool->last_cpu = cpumask_any(cpu_online_mask); |
| 906 | 826 | ||
| 907 | pool->cpu_comp_tasks = alloc_percpu(struct ehca_cpu_comp_task); | 827 | pool->cpu_comp_tasks = alloc_percpu(struct ehca_cpu_comp_task); |
| 908 | if (pool->cpu_comp_tasks == NULL) { | 828 | if (!pool->cpu_comp_tasks) |
| 909 | kfree(pool); | 829 | goto out_pool; |
| 910 | return -EINVAL; | ||
| 911 | } | ||
| 912 | 830 | ||
| 913 | for_each_online_cpu(cpu) { | 831 | pool->cpu_comp_threads = alloc_percpu(struct task_struct *); |
| 914 | task = create_comp_task(pool, cpu); | 832 | if (!pool->cpu_comp_threads) |
| 915 | if (task) { | 833 | goto out_tasks; |
| 916 | kthread_bind(task, cpu); | 834 | |
| 917 | wake_up_process(task); | 835 | for_each_present_cpu(cpu) { |
| 918 | } | 836 | struct ehca_cpu_comp_task *cct; |
| 837 | |||
| 838 | cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu); | ||
| 839 | spin_lock_init(&cct->task_lock); | ||
| 840 | INIT_LIST_HEAD(&cct->cq_list); | ||
| 919 | } | 841 | } |
| 920 | 842 | ||
| 921 | register_hotcpu_notifier(&comp_pool_callback_nb); | 843 | comp_pool_threads.store = pool->cpu_comp_threads; |
| 844 | ret = smpboot_register_percpu_thread(&comp_pool_threads); | ||
| 845 | if (ret) | ||
| 846 | goto out_threads; | ||
| 922 | 847 | ||
| 923 | printk(KERN_INFO "eHCA scaling code enabled\n"); | 848 | pr_info("eHCA scaling code enabled\n"); |
| 849 | return ret; | ||
| 924 | 850 | ||
| 925 | return 0; | 851 | out_threads: |
| 852 | free_percpu(pool->cpu_comp_threads); | ||
| 853 | out_tasks: | ||
| 854 | free_percpu(pool->cpu_comp_tasks); | ||
| 855 | out_pool: | ||
| 856 | kfree(pool); | ||
| 857 | return ret; | ||
| 926 | } | 858 | } |
| 927 | 859 | ||
| 928 | void ehca_destroy_comp_pool(void) | 860 | void ehca_destroy_comp_pool(void) |
| 929 | { | 861 | { |
| 930 | int i; | ||
| 931 | |||
| 932 | if (!ehca_scaling_code) | 862 | if (!ehca_scaling_code) |
| 933 | return; | 863 | return; |
| 934 | 864 | ||
| 935 | unregister_hotcpu_notifier(&comp_pool_callback_nb); | 865 | smpboot_unregister_percpu_thread(&comp_pool_threads); |
| 936 | |||
| 937 | for_each_online_cpu(i) | ||
| 938 | destroy_comp_task(pool, i); | ||
| 939 | 866 | ||
| 867 | free_percpu(pool->cpu_comp_threads); | ||
| 940 | free_percpu(pool->cpu_comp_tasks); | 868 | free_percpu(pool->cpu_comp_tasks); |
| 941 | kfree(pool); | 869 | kfree(pool); |
| 942 | } | 870 | } |
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.h b/drivers/infiniband/hw/ehca/ehca_irq.h index 3346cb06cea6..5370199f08c7 100644 --- a/drivers/infiniband/hw/ehca/ehca_irq.h +++ b/drivers/infiniband/hw/ehca/ehca_irq.h | |||
| @@ -58,15 +58,15 @@ void ehca_tasklet_eq(unsigned long data); | |||
| 58 | void ehca_process_eq(struct ehca_shca *shca, int is_irq); | 58 | void ehca_process_eq(struct ehca_shca *shca, int is_irq); |
| 59 | 59 | ||
| 60 | struct ehca_cpu_comp_task { | 60 | struct ehca_cpu_comp_task { |
| 61 | wait_queue_head_t wait_queue; | ||
| 62 | struct list_head cq_list; | 61 | struct list_head cq_list; |
| 63 | struct task_struct *task; | ||
| 64 | spinlock_t task_lock; | 62 | spinlock_t task_lock; |
| 65 | int cq_jobs; | 63 | int cq_jobs; |
| 64 | int active; | ||
| 66 | }; | 65 | }; |
| 67 | 66 | ||
| 68 | struct ehca_comp_pool { | 67 | struct ehca_comp_pool { |
| 69 | struct ehca_cpu_comp_task *cpu_comp_tasks; | 68 | struct ehca_cpu_comp_task __percpu *cpu_comp_tasks; |
| 69 | struct task_struct * __percpu *cpu_comp_threads; | ||
| 70 | int last_cpu; | 70 | int last_cpu; |
| 71 | spinlock_t last_cpu_lock; | 71 | spinlock_t last_cpu_lock; |
| 72 | }; | 72 | }; |
