aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorey Minyard <cminyard@mvista.com>2008-04-29 04:01:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-29 11:06:15 -0400
commit64959e2d47dead81c6e3ce4864d629d6375e07e2 (patch)
tree6287c1f07475b711258f5684b7013f4014b79093
parent73f2bdb975751eb11de0df1970710e6c40badc26 (diff)
ipmi: convert locked counters to atomics in the system interface
Atomics are faster and neater than locked counters. 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>
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c140
1 files changed, 66 insertions, 74 deletions
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 657034febdaf..286c042a0c66 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -120,6 +120,27 @@ static struct device_driver ipmi_driver =
120 .bus = &platform_bus_type 120 .bus = &platform_bus_type
121}; 121};
122 122
123
124/*
125 * Indexes into stats[] in smi_info below.
126 */
127
128#define SI_STAT_short_timeouts 0
129#define SI_STAT_long_timeouts 1
130#define SI_STAT_timeout_restarts 2
131#define SI_STAT_idles 3
132#define SI_STAT_interrupts 4
133#define SI_STAT_attentions 5
134#define SI_STAT_flag_fetches 6
135#define SI_STAT_hosed_count 7
136#define SI_STAT_complete_transactions 8
137#define SI_STAT_events 9
138#define SI_STAT_watchdog_pretimeouts 10
139#define SI_STAT_incoming_messages 11
140
141/* If you add a stat, you must update this value. */
142#define SI_NUM_STATS 12
143
123struct smi_info 144struct smi_info
124{ 145{
125 int intf_num; 146 int intf_num;
@@ -216,25 +237,18 @@ struct smi_info
216 unsigned char slave_addr; 237 unsigned char slave_addr;
217 238
218 /* Counters and things for the proc filesystem. */ 239 /* Counters and things for the proc filesystem. */
219 spinlock_t count_lock; 240 atomic_t stats[SI_NUM_STATS];
220 unsigned long short_timeouts;
221 unsigned long long_timeouts;
222 unsigned long timeout_restarts;
223 unsigned long idles;
224 unsigned long interrupts;
225 unsigned long attentions;
226 unsigned long flag_fetches;
227 unsigned long hosed_count;
228 unsigned long complete_transactions;
229 unsigned long events;
230 unsigned long watchdog_pretimeouts;
231 unsigned long incoming_messages;
232 241
233 struct task_struct *thread; 242 struct task_struct *thread;
234 243
235 struct list_head link; 244 struct list_head link;
236}; 245};
237 246
247#define smi_inc_stat(smi, stat) \
248 atomic_inc(&(smi)->stats[SI_STAT_ ## stat])
249#define smi_get_stat(smi, stat) \
250 ((unsigned int) atomic_read(&(smi)->stats[SI_STAT_ ## stat]))
251
238#define SI_MAX_PARMS 4 252#define SI_MAX_PARMS 4
239 253
240static int force_kipmid[SI_MAX_PARMS]; 254static int force_kipmid[SI_MAX_PARMS];
@@ -398,9 +412,7 @@ static void handle_flags(struct smi_info *smi_info)
398 retry: 412 retry:
399 if (smi_info->msg_flags & WDT_PRE_TIMEOUT_INT) { 413 if (smi_info->msg_flags & WDT_PRE_TIMEOUT_INT) {
400 /* Watchdog pre-timeout */ 414 /* Watchdog pre-timeout */
401 spin_lock(&smi_info->count_lock); 415 smi_inc_stat(smi_info, watchdog_pretimeouts);
402 smi_info->watchdog_pretimeouts++;
403 spin_unlock(&smi_info->count_lock);
404 416
405 start_clear_flags(smi_info); 417 start_clear_flags(smi_info);
406 smi_info->msg_flags &= ~WDT_PRE_TIMEOUT_INT; 418 smi_info->msg_flags &= ~WDT_PRE_TIMEOUT_INT;
@@ -545,9 +557,7 @@ static void handle_transaction_done(struct smi_info *smi_info)
545 smi_info->msg_flags &= ~EVENT_MSG_BUFFER_FULL; 557 smi_info->msg_flags &= ~EVENT_MSG_BUFFER_FULL;
546 handle_flags(smi_info); 558 handle_flags(smi_info);
547 } else { 559 } else {
548 spin_lock(&smi_info->count_lock); 560 smi_inc_stat(smi_info, events);
549 smi_info->events++;
550 spin_unlock(&smi_info->count_lock);
551 561
552 /* Do this before we deliver the message 562 /* Do this before we deliver the message
553 because delivering the message releases the 563 because delivering the message releases the
@@ -581,9 +591,7 @@ static void handle_transaction_done(struct smi_info *smi_info)
581 smi_info->msg_flags &= ~RECEIVE_MSG_AVAIL; 591 smi_info->msg_flags &= ~RECEIVE_MSG_AVAIL;
582 handle_flags(smi_info); 592 handle_flags(smi_info);
583 } else { 593 } else {
584 spin_lock(&smi_info->count_lock); 594 smi_inc_stat(smi_info, incoming_messages);
585 smi_info->incoming_messages++;
586 spin_unlock(&smi_info->count_lock);
587 595
588 /* Do this before we deliver the message 596 /* Do this before we deliver the message
589 because delivering the message releases the 597 because delivering the message releases the
@@ -700,18 +708,14 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info,
700 708
701 if (si_sm_result == SI_SM_TRANSACTION_COMPLETE) 709 if (si_sm_result == SI_SM_TRANSACTION_COMPLETE)
702 { 710 {
703 spin_lock(&smi_info->count_lock); 711 smi_inc_stat(smi_info, complete_transactions);
704 smi_info->complete_transactions++;
705 spin_unlock(&smi_info->count_lock);
706 712
707 handle_transaction_done(smi_info); 713 handle_transaction_done(smi_info);
708 si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0); 714 si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0);
709 } 715 }
710 else if (si_sm_result == SI_SM_HOSED) 716 else if (si_sm_result == SI_SM_HOSED)
711 { 717 {
712 spin_lock(&smi_info->count_lock); 718 smi_inc_stat(smi_info, hosed_count);
713 smi_info->hosed_count++;
714 spin_unlock(&smi_info->count_lock);
715 719
716 /* Do the before return_hosed_msg, because that 720 /* Do the before return_hosed_msg, because that
717 releases the lock. */ 721 releases the lock. */
@@ -733,9 +737,7 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info,
733 { 737 {
734 unsigned char msg[2]; 738 unsigned char msg[2];
735 739
736 spin_lock(&smi_info->count_lock); 740 smi_inc_stat(smi_info, attentions);
737 smi_info->attentions++;
738 spin_unlock(&smi_info->count_lock);
739 741
740 /* Got a attn, send down a get message flags to see 742 /* Got a attn, send down a get message flags to see
741 what's causing it. It would be better to handle 743 what's causing it. It would be better to handle
@@ -753,9 +755,7 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info,
753 755
754 /* If we are currently idle, try to start the next message. */ 756 /* If we are currently idle, try to start the next message. */
755 if (si_sm_result == SI_SM_IDLE) { 757 if (si_sm_result == SI_SM_IDLE) {
756 spin_lock(&smi_info->count_lock); 758 smi_inc_stat(smi_info, idles);
757 smi_info->idles++;
758 spin_unlock(&smi_info->count_lock);
759 759
760 si_sm_result = start_next_msg(smi_info); 760 si_sm_result = start_next_msg(smi_info);
761 if (si_sm_result != SI_SM_IDLE) 761 if (si_sm_result != SI_SM_IDLE)
@@ -945,23 +945,17 @@ static void smi_timeout(unsigned long data)
945 if ((smi_info->irq) && (!smi_info->interrupt_disabled)) { 945 if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
946 /* Running with interrupts, only do long timeouts. */ 946 /* Running with interrupts, only do long timeouts. */
947 smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; 947 smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
948 spin_lock_irqsave(&smi_info->count_lock, flags); 948 smi_inc_stat(smi_info, long_timeouts);
949 smi_info->long_timeouts++;
950 spin_unlock_irqrestore(&smi_info->count_lock, flags);
951 goto do_add_timer; 949 goto do_add_timer;
952 } 950 }
953 951
954 /* If the state machine asks for a short delay, then shorten 952 /* If the state machine asks for a short delay, then shorten
955 the timer timeout. */ 953 the timer timeout. */
956 if (smi_result == SI_SM_CALL_WITH_DELAY) { 954 if (smi_result == SI_SM_CALL_WITH_DELAY) {
957 spin_lock_irqsave(&smi_info->count_lock, flags); 955 smi_inc_stat(smi_info, short_timeouts);
958 smi_info->short_timeouts++;
959 spin_unlock_irqrestore(&smi_info->count_lock, flags);
960 smi_info->si_timer.expires = jiffies + 1; 956 smi_info->si_timer.expires = jiffies + 1;
961 } else { 957 } else {
962 spin_lock_irqsave(&smi_info->count_lock, flags); 958 smi_inc_stat(smi_info, long_timeouts);
963 smi_info->long_timeouts++;
964 spin_unlock_irqrestore(&smi_info->count_lock, flags);
965 smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; 959 smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
966 } 960 }
967 961
@@ -979,9 +973,7 @@ static irqreturn_t si_irq_handler(int irq, void *data)
979 973
980 spin_lock_irqsave(&(smi_info->si_lock), flags); 974 spin_lock_irqsave(&(smi_info->si_lock), flags);
981 975
982 spin_lock(&smi_info->count_lock); 976 smi_inc_stat(smi_info, interrupts);
983 smi_info->interrupts++;
984 spin_unlock(&smi_info->count_lock);
985 977
986#ifdef DEBUG_TIMING 978#ifdef DEBUG_TIMING
987 do_gettimeofday(&t); 979 do_gettimeofday(&t);
@@ -1765,9 +1757,7 @@ static u32 ipmi_acpi_gpe(void *context)
1765 1757
1766 spin_lock_irqsave(&(smi_info->si_lock), flags); 1758 spin_lock_irqsave(&(smi_info->si_lock), flags);
1767 1759
1768 spin_lock(&smi_info->count_lock); 1760 smi_inc_stat(smi_info, interrupts);
1769 smi_info->interrupts++;
1770 spin_unlock(&smi_info->count_lock);
1771 1761
1772#ifdef DEBUG_TIMING 1762#ifdef DEBUG_TIMING
1773 do_gettimeofday(&t); 1763 do_gettimeofday(&t);
@@ -2405,30 +2395,30 @@ static int stat_file_read_proc(char *page, char **start, off_t off,
2405 2395
2406 out += sprintf(out, "interrupts_enabled: %d\n", 2396 out += sprintf(out, "interrupts_enabled: %d\n",
2407 smi->irq && !smi->interrupt_disabled); 2397 smi->irq && !smi->interrupt_disabled);
2408 out += sprintf(out, "short_timeouts: %ld\n", 2398 out += sprintf(out, "short_timeouts: %u\n",
2409 smi->short_timeouts); 2399 smi_get_stat(smi, short_timeouts));
2410 out += sprintf(out, "long_timeouts: %ld\n", 2400 out += sprintf(out, "long_timeouts: %u\n",
2411 smi->long_timeouts); 2401 smi_get_stat(smi, long_timeouts));
2412 out += sprintf(out, "timeout_restarts: %ld\n", 2402 out += sprintf(out, "timeout_restarts: %u\n",
2413 smi->timeout_restarts); 2403 smi_get_stat(smi, timeout_restarts));
2414 out += sprintf(out, "idles: %ld\n", 2404 out += sprintf(out, "idles: %u\n",
2415 smi->idles); 2405 smi_get_stat(smi, idles));
2416 out += sprintf(out, "interrupts: %ld\n", 2406 out += sprintf(out, "interrupts: %u\n",
2417 smi->interrupts); 2407 smi_get_stat(smi, interrupts));
2418 out += sprintf(out, "attentions: %ld\n", 2408 out += sprintf(out, "attentions: %u\n",
2419 smi->attentions); 2409 smi_get_stat(smi, attentions));
2420 out += sprintf(out, "flag_fetches: %ld\n", 2410 out += sprintf(out, "flag_fetches: %u\n",
2421 smi->flag_fetches); 2411 smi_get_stat(smi, flag_fetches));
2422 out += sprintf(out, "hosed_count: %ld\n", 2412 out += sprintf(out, "hosed_count: %u\n",
2423 smi->hosed_count); 2413 smi_get_stat(smi, hosed_count));
2424 out += sprintf(out, "complete_transactions: %ld\n", 2414 out += sprintf(out, "complete_transactions: %u\n",
2425 smi->complete_transactions); 2415 smi_get_stat(smi, complete_transactions));
2426 out += sprintf(out, "events: %ld\n", 2416 out += sprintf(out, "events: %u\n",
2427 smi->events); 2417 smi_get_stat(smi, events));
2428 out += sprintf(out, "watchdog_pretimeouts: %ld\n", 2418 out += sprintf(out, "watchdog_pretimeouts: %u\n",
2429 smi->watchdog_pretimeouts); 2419 smi_get_stat(smi, watchdog_pretimeouts));
2430 out += sprintf(out, "incoming_messages: %ld\n", 2420 out += sprintf(out, "incoming_messages: %u\n",
2431 smi->incoming_messages); 2421 smi_get_stat(smi, incoming_messages));
2432 2422
2433 return out - page; 2423 return out - page;
2434} 2424}
@@ -2676,6 +2666,7 @@ static int is_new_interface(struct smi_info *info)
2676static int try_smi_init(struct smi_info *new_smi) 2666static int try_smi_init(struct smi_info *new_smi)
2677{ 2667{
2678 int rv; 2668 int rv;
2669 int i;
2679 2670
2680 if (new_smi->addr_source) { 2671 if (new_smi->addr_source) {
2681 printk(KERN_INFO "ipmi_si: Trying %s-specified %s state" 2672 printk(KERN_INFO "ipmi_si: Trying %s-specified %s state"
@@ -2738,7 +2729,6 @@ static int try_smi_init(struct smi_info *new_smi)
2738 2729
2739 spin_lock_init(&(new_smi->si_lock)); 2730 spin_lock_init(&(new_smi->si_lock));
2740 spin_lock_init(&(new_smi->msg_lock)); 2731 spin_lock_init(&(new_smi->msg_lock));
2741 spin_lock_init(&(new_smi->count_lock));
2742 2732
2743 /* Do low-level detection first. */ 2733 /* Do low-level detection first. */
2744 if (new_smi->handlers->detect(new_smi->si_sm)) { 2734 if (new_smi->handlers->detect(new_smi->si_sm)) {
@@ -2767,6 +2757,8 @@ static int try_smi_init(struct smi_info *new_smi)
2767 new_smi->curr_msg = NULL; 2757 new_smi->curr_msg = NULL;
2768 atomic_set(&new_smi->req_events, 0); 2758 atomic_set(&new_smi->req_events, 0);
2769 new_smi->run_to_completion = 0; 2759 new_smi->run_to_completion = 0;
2760 for (i = 0; i < SI_NUM_STATS; i++)
2761 atomic_set(&new_smi->stats[i], 0);
2770 2762
2771 new_smi->interrupt_disabled = 0; 2763 new_smi->interrupt_disabled = 0;
2772 atomic_set(&new_smi->stop_operation, 0); 2764 atomic_set(&new_smi->stop_operation, 0);