diff options
author | Hoang-Nam Nguyen <hnguyen@linux.vnet.ibm.com> | 2007-02-15 11:06:33 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2007-02-16 16:57:34 -0500 |
commit | 78d8d5f9ef8d6179e92b94481cfdfc45d396992f (patch) | |
tree | 55ee3cecd4c0d59f418b59870cec2ac33b1b70e7 /drivers/infiniband/hw/ehca/ehca_main.c | |
parent | 551fd6122d247d76124c4fdb6eb898cc8e3d74aa (diff) |
IB/ehca: Rework irq handler
Rework ehca interrupt handling to avoid/reduce missed irq events.
Signed-off-by: Hoang-Nam Nguyen <hnguyen@de.ibm.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/ehca/ehca_main.c')
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_main.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index 1155bcf48212..579053421472 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c | |||
@@ -52,7 +52,7 @@ | |||
52 | MODULE_LICENSE("Dual BSD/GPL"); | 52 | MODULE_LICENSE("Dual BSD/GPL"); |
53 | MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>"); | 53 | MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>"); |
54 | MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver"); | 54 | MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver"); |
55 | MODULE_VERSION("SVNEHCA_0020"); | 55 | MODULE_VERSION("SVNEHCA_0021"); |
56 | 56 | ||
57 | int ehca_open_aqp1 = 0; | 57 | int ehca_open_aqp1 = 0; |
58 | int ehca_debug_level = 0; | 58 | int ehca_debug_level = 0; |
@@ -432,8 +432,8 @@ static int ehca_destroy_aqp1(struct ehca_sport *sport) | |||
432 | 432 | ||
433 | static ssize_t ehca_show_debug_level(struct device_driver *ddp, char *buf) | 433 | static ssize_t ehca_show_debug_level(struct device_driver *ddp, char *buf) |
434 | { | 434 | { |
435 | return snprintf(buf, PAGE_SIZE, "%d\n", | 435 | return snprintf(buf, PAGE_SIZE, "%d\n", |
436 | ehca_debug_level); | 436 | ehca_debug_level); |
437 | } | 437 | } |
438 | 438 | ||
439 | static ssize_t ehca_store_debug_level(struct device_driver *ddp, | 439 | static ssize_t ehca_store_debug_level(struct device_driver *ddp, |
@@ -778,8 +778,24 @@ void ehca_poll_eqs(unsigned long data) | |||
778 | 778 | ||
779 | spin_lock(&shca_list_lock); | 779 | spin_lock(&shca_list_lock); |
780 | list_for_each_entry(shca, &shca_list, shca_list) { | 780 | list_for_each_entry(shca, &shca_list, shca_list) { |
781 | if (shca->eq.is_initialized) | 781 | if (shca->eq.is_initialized) { |
782 | ehca_tasklet_eq((unsigned long)(void*)shca); | 782 | /* call deadman proc only if eq ptr does not change */ |
783 | struct ehca_eq *eq = &shca->eq; | ||
784 | int max = 3; | ||
785 | volatile u64 q_ofs, q_ofs2; | ||
786 | u64 flags; | ||
787 | spin_lock_irqsave(&eq->spinlock, flags); | ||
788 | q_ofs = eq->ipz_queue.current_q_offset; | ||
789 | spin_unlock_irqrestore(&eq->spinlock, flags); | ||
790 | do { | ||
791 | spin_lock_irqsave(&eq->spinlock, flags); | ||
792 | q_ofs2 = eq->ipz_queue.current_q_offset; | ||
793 | spin_unlock_irqrestore(&eq->spinlock, flags); | ||
794 | max--; | ||
795 | } while (q_ofs == q_ofs2 && max > 0); | ||
796 | if (q_ofs == q_ofs2) | ||
797 | ehca_process_eq(shca, 0); | ||
798 | } | ||
783 | } | 799 | } |
784 | mod_timer(&poll_eqs_timer, jiffies + HZ); | 800 | mod_timer(&poll_eqs_timer, jiffies + HZ); |
785 | spin_unlock(&shca_list_lock); | 801 | spin_unlock(&shca_list_lock); |
@@ -790,7 +806,7 @@ int __init ehca_module_init(void) | |||
790 | int ret; | 806 | int ret; |
791 | 807 | ||
792 | printk(KERN_INFO "eHCA Infiniband Device Driver " | 808 | printk(KERN_INFO "eHCA Infiniband Device Driver " |
793 | "(Rel.: SVNEHCA_0020)\n"); | 809 | "(Rel.: SVNEHCA_0021)\n"); |
794 | idr_init(&ehca_qp_idr); | 810 | idr_init(&ehca_qp_idr); |
795 | idr_init(&ehca_cq_idr); | 811 | idr_init(&ehca_cq_idr); |
796 | spin_lock_init(&ehca_qp_idr_lock); | 812 | spin_lock_init(&ehca_qp_idr_lock); |