diff options
author | Matthew Garrett <mjg@redhat.com> | 2010-05-26 17:43:48 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-27 12:12:49 -0400 |
commit | ea4078ca1a7a3a198e519c2a7a2ed6126e40b130 (patch) | |
tree | 8b53cbda0032c2eb5eac6f2c0bad563d2217bfdc /drivers/char | |
parent | 754d453185275951d39792865927ec494fa1ebd8 (diff) |
ipmi: reduce polling when interrupts are available
If we're not currently in the middle of a transaction, and if we have
interrupts, there's no real reason to poll the controller more frequently
than the core IPMI code does. Set the interrupt_disabled flag
appropriately as the interrupt state changes, and make the timeout code
reset itself only if the transaction is incomplete or we have no
interrupts.
Signed-off-by: Matthew Garrett <mjg@redhat.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 5b7bf7d22494..c8d68cf68598 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -454,6 +454,9 @@ static inline void disable_si_irq(struct smi_info *smi_info) | |||
454 | if ((smi_info->irq) && (!smi_info->interrupt_disabled)) { | 454 | if ((smi_info->irq) && (!smi_info->interrupt_disabled)) { |
455 | start_disable_irq(smi_info); | 455 | start_disable_irq(smi_info); |
456 | smi_info->interrupt_disabled = 1; | 456 | smi_info->interrupt_disabled = 1; |
457 | if (!atomic_read(&smi_info->stop_operation)) | ||
458 | mod_timer(&smi_info->si_timer, | ||
459 | jiffies + SI_TIMEOUT_JIFFIES); | ||
457 | } | 460 | } |
458 | } | 461 | } |
459 | 462 | ||
@@ -706,6 +709,8 @@ static void handle_transaction_done(struct smi_info *smi_info) | |||
706 | printk(KERN_WARNING | 709 | printk(KERN_WARNING |
707 | "ipmi_si: Could not enable interrupts" | 710 | "ipmi_si: Could not enable interrupts" |
708 | ", failed set, using polled mode.\n"); | 711 | ", failed set, using polled mode.\n"); |
712 | } else { | ||
713 | smi_info->interrupt_disabled = 0; | ||
709 | } | 714 | } |
710 | smi_info->si_state = SI_NORMAL; | 715 | smi_info->si_state = SI_NORMAL; |
711 | break; | 716 | break; |
@@ -886,6 +891,8 @@ static void sender(void *send_info, | |||
886 | printk("**Enqueue: %d.%9.9d\n", t.tv_sec, t.tv_usec); | 891 | printk("**Enqueue: %d.%9.9d\n", t.tv_sec, t.tv_usec); |
887 | #endif | 892 | #endif |
888 | 893 | ||
894 | mod_timer(&smi_info->si_timer, jiffies + SI_TIMEOUT_JIFFIES); | ||
895 | |||
889 | if (smi_info->run_to_completion) { | 896 | if (smi_info->run_to_completion) { |
890 | /* | 897 | /* |
891 | * If we are running to completion, then throw it in | 898 | * If we are running to completion, then throw it in |
@@ -1086,7 +1093,8 @@ static void smi_timeout(unsigned long data) | |||
1086 | } | 1093 | } |
1087 | 1094 | ||
1088 | do_add_timer: | 1095 | do_add_timer: |
1089 | add_timer(&(smi_info->si_timer)); | 1096 | if ((smi_result != SI_SM_IDLE) || smi_info->interrupt_disabled) |
1097 | add_timer(&(smi_info->si_timer)); | ||
1090 | } | 1098 | } |
1091 | 1099 | ||
1092 | static irqreturn_t si_irq_handler(int irq, void *data) | 1100 | static irqreturn_t si_irq_handler(int irq, void *data) |
@@ -3117,7 +3125,7 @@ static int try_smi_init(struct smi_info *new_smi) | |||
3117 | for (i = 0; i < SI_NUM_STATS; i++) | 3125 | for (i = 0; i < SI_NUM_STATS; i++) |
3118 | atomic_set(&new_smi->stats[i], 0); | 3126 | atomic_set(&new_smi->stats[i], 0); |
3119 | 3127 | ||
3120 | new_smi->interrupt_disabled = 0; | 3128 | new_smi->interrupt_disabled = 1; |
3121 | atomic_set(&new_smi->stop_operation, 0); | 3129 | atomic_set(&new_smi->stop_operation, 0); |
3122 | new_smi->intf_num = smi_num; | 3130 | new_smi->intf_num = smi_num; |
3123 | smi_num++; | 3131 | smi_num++; |