Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Corey Minyard and committed by
Linus Torvalds
64959e2d 73f2bdb9

+66 -74
+66 -74
drivers/char/ipmi/ipmi_si_intf.c
··· 120 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 + 123 144 struct smi_info 124 145 { 125 146 int intf_num; ··· 237 216 unsigned char slave_addr; 238 217 239 218 /* Counters and things for the proc filesystem. */ 240 - spinlock_t count_lock; 241 - unsigned long short_timeouts; 242 - unsigned long long_timeouts; 243 - unsigned long timeout_restarts; 244 - unsigned long idles; 245 - unsigned long interrupts; 246 - unsigned long attentions; 247 - unsigned long flag_fetches; 248 - unsigned long hosed_count; 249 - unsigned long complete_transactions; 250 - unsigned long events; 251 - unsigned long watchdog_pretimeouts; 252 - unsigned long incoming_messages; 219 + atomic_t stats[SI_NUM_STATS]; 253 220 254 221 struct task_struct *thread; 255 222 256 223 struct list_head link; 257 224 }; 225 + 226 + #define smi_inc_stat(smi, stat) \ 227 + atomic_inc(&(smi)->stats[SI_STAT_ ## stat]) 228 + #define smi_get_stat(smi, stat) \ 229 + ((unsigned int) atomic_read(&(smi)->stats[SI_STAT_ ## stat])) 258 230 259 231 #define SI_MAX_PARMS 4 260 232 ··· 412 398 retry: 413 399 if (smi_info->msg_flags & WDT_PRE_TIMEOUT_INT) { 414 400 /* Watchdog pre-timeout */ 415 - spin_lock(&smi_info->count_lock); 416 - smi_info->watchdog_pretimeouts++; 417 - spin_unlock(&smi_info->count_lock); 401 + smi_inc_stat(smi_info, watchdog_pretimeouts); 418 402 419 403 start_clear_flags(smi_info); 420 404 smi_info->msg_flags &= ~WDT_PRE_TIMEOUT_INT; ··· 557 545 smi_info->msg_flags &= ~EVENT_MSG_BUFFER_FULL; 558 546 handle_flags(smi_info); 559 547 } else { 560 - spin_lock(&smi_info->count_lock); 561 - smi_info->events++; 562 - spin_unlock(&smi_info->count_lock); 548 + smi_inc_stat(smi_info, events); 563 549 564 550 /* Do this before we deliver the message 565 551 because delivering the message releases the ··· 591 581 smi_info->msg_flags &= ~RECEIVE_MSG_AVAIL; 592 582 handle_flags(smi_info); 593 583 } else { 594 - spin_lock(&smi_info->count_lock); 595 - smi_info->incoming_messages++; 596 - spin_unlock(&smi_info->count_lock); 584 + smi_inc_stat(smi_info, incoming_messages); 597 585 598 586 /* Do this before we deliver the message 599 587 because delivering the message releases the ··· 708 700 709 701 if (si_sm_result == SI_SM_TRANSACTION_COMPLETE) 710 702 { 711 - spin_lock(&smi_info->count_lock); 712 - smi_info->complete_transactions++; 713 - spin_unlock(&smi_info->count_lock); 703 + smi_inc_stat(smi_info, complete_transactions); 714 704 715 705 handle_transaction_done(smi_info); 716 706 si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0); 717 707 } 718 708 else if (si_sm_result == SI_SM_HOSED) 719 709 { 720 - spin_lock(&smi_info->count_lock); 721 - smi_info->hosed_count++; 722 - spin_unlock(&smi_info->count_lock); 710 + smi_inc_stat(smi_info, hosed_count); 723 711 724 712 /* Do the before return_hosed_msg, because that 725 713 releases the lock. */ ··· 737 733 { 738 734 unsigned char msg[2]; 739 735 740 - spin_lock(&smi_info->count_lock); 741 - smi_info->attentions++; 742 - spin_unlock(&smi_info->count_lock); 736 + smi_inc_stat(smi_info, attentions); 743 737 744 738 /* Got a attn, send down a get message flags to see 745 739 what's causing it. It would be better to handle ··· 755 753 756 754 /* If we are currently idle, try to start the next message. */ 757 755 if (si_sm_result == SI_SM_IDLE) { 758 - spin_lock(&smi_info->count_lock); 759 - smi_info->idles++; 760 - spin_unlock(&smi_info->count_lock); 756 + smi_inc_stat(smi_info, idles); 761 757 762 758 si_sm_result = start_next_msg(smi_info); 763 759 if (si_sm_result != SI_SM_IDLE) ··· 945 945 if ((smi_info->irq) && (!smi_info->interrupt_disabled)) { 946 946 /* Running with interrupts, only do long timeouts. */ 947 947 smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; 948 - spin_lock_irqsave(&smi_info->count_lock, flags); 949 - smi_info->long_timeouts++; 950 - spin_unlock_irqrestore(&smi_info->count_lock, flags); 948 + smi_inc_stat(smi_info, long_timeouts); 951 949 goto do_add_timer; 952 950 } 953 951 954 952 /* If the state machine asks for a short delay, then shorten 955 953 the timer timeout. */ 956 954 if (smi_result == SI_SM_CALL_WITH_DELAY) { 957 - spin_lock_irqsave(&smi_info->count_lock, flags); 958 - smi_info->short_timeouts++; 959 - spin_unlock_irqrestore(&smi_info->count_lock, flags); 955 + smi_inc_stat(smi_info, short_timeouts); 960 956 smi_info->si_timer.expires = jiffies + 1; 961 957 } else { 962 - spin_lock_irqsave(&smi_info->count_lock, flags); 963 - smi_info->long_timeouts++; 964 - spin_unlock_irqrestore(&smi_info->count_lock, flags); 958 + smi_inc_stat(smi_info, long_timeouts); 965 959 smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; 966 960 } 967 961 ··· 973 979 974 980 spin_lock_irqsave(&(smi_info->si_lock), flags); 975 981 976 - spin_lock(&smi_info->count_lock); 977 - smi_info->interrupts++; 978 - spin_unlock(&smi_info->count_lock); 982 + smi_inc_stat(smi_info, interrupts); 979 983 980 984 #ifdef DEBUG_TIMING 981 985 do_gettimeofday(&t); ··· 1757 1765 1758 1766 spin_lock_irqsave(&(smi_info->si_lock), flags); 1759 1767 1760 - spin_lock(&smi_info->count_lock); 1761 - smi_info->interrupts++; 1762 - spin_unlock(&smi_info->count_lock); 1768 + smi_inc_stat(smi_info, interrupts); 1763 1769 1764 1770 #ifdef DEBUG_TIMING 1765 1771 do_gettimeofday(&t); ··· 2395 2405 2396 2406 out += sprintf(out, "interrupts_enabled: %d\n", 2397 2407 smi->irq && !smi->interrupt_disabled); 2398 - out += sprintf(out, "short_timeouts: %ld\n", 2399 - smi->short_timeouts); 2400 - out += sprintf(out, "long_timeouts: %ld\n", 2401 - smi->long_timeouts); 2402 - out += sprintf(out, "timeout_restarts: %ld\n", 2403 - smi->timeout_restarts); 2404 - out += sprintf(out, "idles: %ld\n", 2405 - smi->idles); 2406 - out += sprintf(out, "interrupts: %ld\n", 2407 - smi->interrupts); 2408 - out += sprintf(out, "attentions: %ld\n", 2409 - smi->attentions); 2410 - out += sprintf(out, "flag_fetches: %ld\n", 2411 - smi->flag_fetches); 2412 - out += sprintf(out, "hosed_count: %ld\n", 2413 - smi->hosed_count); 2414 - out += sprintf(out, "complete_transactions: %ld\n", 2415 - smi->complete_transactions); 2416 - out += sprintf(out, "events: %ld\n", 2417 - smi->events); 2418 - out += sprintf(out, "watchdog_pretimeouts: %ld\n", 2419 - smi->watchdog_pretimeouts); 2420 - out += sprintf(out, "incoming_messages: %ld\n", 2421 - smi->incoming_messages); 2408 + out += sprintf(out, "short_timeouts: %u\n", 2409 + smi_get_stat(smi, short_timeouts)); 2410 + out += sprintf(out, "long_timeouts: %u\n", 2411 + smi_get_stat(smi, long_timeouts)); 2412 + out += sprintf(out, "timeout_restarts: %u\n", 2413 + smi_get_stat(smi, timeout_restarts)); 2414 + out += sprintf(out, "idles: %u\n", 2415 + smi_get_stat(smi, idles)); 2416 + out += sprintf(out, "interrupts: %u\n", 2417 + smi_get_stat(smi, interrupts)); 2418 + out += sprintf(out, "attentions: %u\n", 2419 + smi_get_stat(smi, attentions)); 2420 + out += sprintf(out, "flag_fetches: %u\n", 2421 + smi_get_stat(smi, flag_fetches)); 2422 + out += sprintf(out, "hosed_count: %u\n", 2423 + smi_get_stat(smi, hosed_count)); 2424 + out += sprintf(out, "complete_transactions: %u\n", 2425 + smi_get_stat(smi, complete_transactions)); 2426 + out += sprintf(out, "events: %u\n", 2427 + smi_get_stat(smi, events)); 2428 + out += sprintf(out, "watchdog_pretimeouts: %u\n", 2429 + smi_get_stat(smi, watchdog_pretimeouts)); 2430 + out += sprintf(out, "incoming_messages: %u\n", 2431 + smi_get_stat(smi, incoming_messages)); 2422 2432 2423 2433 return out - page; 2424 2434 } ··· 2666 2676 static int try_smi_init(struct smi_info *new_smi) 2667 2677 { 2668 2678 int rv; 2679 + int i; 2669 2680 2670 2681 if (new_smi->addr_source) { 2671 2682 printk(KERN_INFO "ipmi_si: Trying %s-specified %s state" ··· 2729 2738 2730 2739 spin_lock_init(&(new_smi->si_lock)); 2731 2740 spin_lock_init(&(new_smi->msg_lock)); 2732 - spin_lock_init(&(new_smi->count_lock)); 2733 2741 2734 2742 /* Do low-level detection first. */ 2735 2743 if (new_smi->handlers->detect(new_smi->si_sm)) { ··· 2757 2767 new_smi->curr_msg = NULL; 2758 2768 atomic_set(&new_smi->req_events, 0); 2759 2769 new_smi->run_to_completion = 0; 2770 + for (i = 0; i < SI_NUM_STATS; i++) 2771 + atomic_set(&new_smi->stats[i], 0); 2760 2772 2761 2773 new_smi->interrupt_disabled = 0; 2762 2774 atomic_set(&new_smi->stop_operation, 0);