aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorey Minyard <cminyard@mvista.com>2009-04-21 15:24:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-21 16:41:48 -0400
commit25176ed670121e1e0aae5c8161713c332b786538 (patch)
treef022df5bce75f72994d59b43ff64d9a114fc5261
parent40112ae7504745799e75ef418057f0d2cb745050 (diff)
ipmi: fix statistics counting issues
Bela Lubkin noticed that the statistics for send IPMB and LAN commands in the IPMI driver could be incremented even if an error occurred. Move the increments to the proper place to avoid this. Also add some statistics for retransmissions that failed, and some little helper functions to neaten up the code a little. Signed-off-by: Corey Minyard <cminyard@mvista.com> Cc: Bela Lubkin <blubkin@vmware.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_msghandler.c73
1 files changed, 51 insertions, 22 deletions
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index e93fc8d22fb2..83c7477ba801 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -285,6 +285,11 @@ enum ipmi_stat_indexes {
285 /* Events that were received with the proper format. */ 285 /* Events that were received with the proper format. */
286 IPMI_STAT_events, 286 IPMI_STAT_events,
287 287
288 /* Retransmissions on IPMB that failed. */
289 IPMI_STAT_dropped_rexmit_ipmb_commands,
290
291 /* Retransmissions on LAN that failed. */
292 IPMI_STAT_dropped_rexmit_lan_commands,
288 293
289 /* This *must* remain last, add new values above this. */ 294 /* This *must* remain last, add new values above this. */
290 IPMI_NUM_STATS 295 IPMI_NUM_STATS
@@ -445,6 +450,20 @@ static DEFINE_MUTEX(smi_watchers_mutex);
445#define ipmi_get_stat(intf, stat) \ 450#define ipmi_get_stat(intf, stat) \
446 ((unsigned int) atomic_read(&(intf)->stats[IPMI_STAT_ ## stat])) 451 ((unsigned int) atomic_read(&(intf)->stats[IPMI_STAT_ ## stat]))
447 452
453static int is_lan_addr(struct ipmi_addr *addr)
454{
455 return addr->addr_type == IPMI_LAN_ADDR_TYPE;
456}
457
458static int is_ipmb_addr(struct ipmi_addr *addr)
459{
460 return addr->addr_type == IPMI_IPMB_ADDR_TYPE;
461}
462
463static int is_ipmb_bcast_addr(struct ipmi_addr *addr)
464{
465 return addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE;
466}
448 467
449static void free_recv_msg_list(struct list_head *q) 468static void free_recv_msg_list(struct list_head *q)
450{ 469{
@@ -601,8 +620,7 @@ ipmi_addr_equal(struct ipmi_addr *addr1, struct ipmi_addr *addr2)
601 return (smi_addr1->lun == smi_addr2->lun); 620 return (smi_addr1->lun == smi_addr2->lun);
602 } 621 }
603 622
604 if ((addr1->addr_type == IPMI_IPMB_ADDR_TYPE) 623 if (is_ipmb_addr(addr1) || is_ipmb_bcast_addr(addr1)) {
605 || (addr1->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) {
606 struct ipmi_ipmb_addr *ipmb_addr1 624 struct ipmi_ipmb_addr *ipmb_addr1
607 = (struct ipmi_ipmb_addr *) addr1; 625 = (struct ipmi_ipmb_addr *) addr1;
608 struct ipmi_ipmb_addr *ipmb_addr2 626 struct ipmi_ipmb_addr *ipmb_addr2
@@ -612,7 +630,7 @@ ipmi_addr_equal(struct ipmi_addr *addr1, struct ipmi_addr *addr2)
612 && (ipmb_addr1->lun == ipmb_addr2->lun)); 630 && (ipmb_addr1->lun == ipmb_addr2->lun));
613 } 631 }
614 632
615 if (addr1->addr_type == IPMI_LAN_ADDR_TYPE) { 633 if (is_lan_addr(addr1)) {
616 struct ipmi_lan_addr *lan_addr1 634 struct ipmi_lan_addr *lan_addr1
617 = (struct ipmi_lan_addr *) addr1; 635 = (struct ipmi_lan_addr *) addr1;
618 struct ipmi_lan_addr *lan_addr2 636 struct ipmi_lan_addr *lan_addr2
@@ -644,14 +662,13 @@ int ipmi_validate_addr(struct ipmi_addr *addr, int len)
644 || (addr->channel < 0)) 662 || (addr->channel < 0))
645 return -EINVAL; 663 return -EINVAL;
646 664
647 if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE) 665 if (is_ipmb_addr(addr) || is_ipmb_bcast_addr(addr)) {
648 || (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) {
649 if (len < sizeof(struct ipmi_ipmb_addr)) 666 if (len < sizeof(struct ipmi_ipmb_addr))
650 return -EINVAL; 667 return -EINVAL;
651 return 0; 668 return 0;
652 } 669 }
653 670
654 if (addr->addr_type == IPMI_LAN_ADDR_TYPE) { 671 if (is_lan_addr(addr)) {
655 if (len < sizeof(struct ipmi_lan_addr)) 672 if (len < sizeof(struct ipmi_lan_addr))
656 return -EINVAL; 673 return -EINVAL;
657 return 0; 674 return 0;
@@ -1503,8 +1520,7 @@ static int i_ipmi_request(ipmi_user_t user,
1503 memcpy(&(smi_msg->data[2]), msg->data, msg->data_len); 1520 memcpy(&(smi_msg->data[2]), msg->data, msg->data_len);
1504 smi_msg->data_size = msg->data_len + 2; 1521 smi_msg->data_size = msg->data_len + 2;
1505 ipmi_inc_stat(intf, sent_local_commands); 1522 ipmi_inc_stat(intf, sent_local_commands);
1506 } else if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE) 1523 } else if (is_ipmb_addr(addr) || is_ipmb_bcast_addr(addr)) {
1507 || (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) {
1508 struct ipmi_ipmb_addr *ipmb_addr; 1524 struct ipmi_ipmb_addr *ipmb_addr;
1509 unsigned char ipmb_seq; 1525 unsigned char ipmb_seq;
1510 long seqid; 1526 long seqid;
@@ -1583,8 +1599,6 @@ static int i_ipmi_request(ipmi_user_t user,
1583 1599
1584 spin_lock_irqsave(&(intf->seq_lock), flags); 1600 spin_lock_irqsave(&(intf->seq_lock), flags);
1585 1601
1586 ipmi_inc_stat(intf, sent_ipmb_commands);
1587
1588 /* 1602 /*
1589 * Create a sequence number with a 1 second 1603 * Create a sequence number with a 1 second
1590 * timeout and 4 retries. 1604 * timeout and 4 retries.
@@ -1606,6 +1620,8 @@ static int i_ipmi_request(ipmi_user_t user,
1606 goto out_err; 1620 goto out_err;
1607 } 1621 }
1608 1622
1623 ipmi_inc_stat(intf, sent_ipmb_commands);
1624
1609 /* 1625 /*
1610 * Store the sequence number in the message, 1626 * Store the sequence number in the message,
1611 * so that when the send message response 1627 * so that when the send message response
@@ -1635,7 +1651,7 @@ static int i_ipmi_request(ipmi_user_t user,
1635 */ 1651 */
1636 spin_unlock_irqrestore(&(intf->seq_lock), flags); 1652 spin_unlock_irqrestore(&(intf->seq_lock), flags);
1637 } 1653 }
1638 } else if (addr->addr_type == IPMI_LAN_ADDR_TYPE) { 1654 } else if (is_lan_addr(addr)) {
1639 struct ipmi_lan_addr *lan_addr; 1655 struct ipmi_lan_addr *lan_addr;
1640 unsigned char ipmb_seq; 1656 unsigned char ipmb_seq;
1641 long seqid; 1657 long seqid;
@@ -1696,8 +1712,6 @@ static int i_ipmi_request(ipmi_user_t user,
1696 1712
1697 spin_lock_irqsave(&(intf->seq_lock), flags); 1713 spin_lock_irqsave(&(intf->seq_lock), flags);
1698 1714
1699 ipmi_inc_stat(intf, sent_lan_commands);
1700
1701 /* 1715 /*
1702 * Create a sequence number with a 1 second 1716 * Create a sequence number with a 1 second
1703 * timeout and 4 retries. 1717 * timeout and 4 retries.
@@ -1719,6 +1733,8 @@ static int i_ipmi_request(ipmi_user_t user,
1719 goto out_err; 1733 goto out_err;
1720 } 1734 }
1721 1735
1736 ipmi_inc_stat(intf, sent_lan_commands);
1737
1722 /* 1738 /*
1723 * Store the sequence number in the message, 1739 * Store the sequence number in the message,
1724 * so that when the send message response 1740 * so that when the send message response
@@ -1937,6 +1953,10 @@ static int stat_file_read_proc(char *page, char **start, off_t off,
1937 ipmi_get_stat(intf, invalid_events)); 1953 ipmi_get_stat(intf, invalid_events));
1938 out += sprintf(out, "events: %u\n", 1954 out += sprintf(out, "events: %u\n",
1939 ipmi_get_stat(intf, events)); 1955 ipmi_get_stat(intf, events));
1956 out += sprintf(out, "failed rexmit LAN msgs: %u\n",
1957 ipmi_get_stat(intf, dropped_rexmit_lan_commands));
1958 out += sprintf(out, "failed rexmit IPMB msgs: %u\n",
1959 ipmi_get_stat(intf, dropped_rexmit_ipmb_commands));
1940 1960
1941 return (out - ((char *) page)); 1961 return (out - ((char *) page));
1942} 1962}
@@ -3730,7 +3750,7 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
3730 list_add_tail(&msg->link, timeouts); 3750 list_add_tail(&msg->link, timeouts);
3731 if (ent->broadcast) 3751 if (ent->broadcast)
3732 ipmi_inc_stat(intf, timed_out_ipmb_broadcasts); 3752 ipmi_inc_stat(intf, timed_out_ipmb_broadcasts);
3733 else if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE) 3753 else if (is_lan_addr(&ent->recv_msg->addr))
3734 ipmi_inc_stat(intf, timed_out_lan_commands); 3754 ipmi_inc_stat(intf, timed_out_lan_commands);
3735 else 3755 else
3736 ipmi_inc_stat(intf, timed_out_ipmb_commands); 3756 ipmi_inc_stat(intf, timed_out_ipmb_commands);
@@ -3744,15 +3764,17 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
3744 */ 3764 */
3745 ent->timeout = MAX_MSG_TIMEOUT; 3765 ent->timeout = MAX_MSG_TIMEOUT;
3746 ent->retries_left--; 3766 ent->retries_left--;
3747 if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE)
3748 ipmi_inc_stat(intf, retransmitted_lan_commands);
3749 else
3750 ipmi_inc_stat(intf, retransmitted_ipmb_commands);
3751
3752 smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot, 3767 smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot,
3753 ent->seqid); 3768 ent->seqid);
3754 if (!smi_msg) 3769 if (!smi_msg) {
3770 if (is_lan_addr(&ent->recv_msg->addr))
3771 ipmi_inc_stat(intf,
3772 dropped_rexmit_lan_commands);
3773 else
3774 ipmi_inc_stat(intf,
3775 dropped_rexmit_ipmb_commands);
3755 return; 3776 return;
3777 }
3756 3778
3757 spin_unlock_irqrestore(&intf->seq_lock, *flags); 3779 spin_unlock_irqrestore(&intf->seq_lock, *flags);
3758 3780
@@ -3764,10 +3786,17 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
3764 * resent. 3786 * resent.
3765 */ 3787 */
3766 handlers = intf->handlers; 3788 handlers = intf->handlers;
3767 if (handlers) 3789 if (handlers) {
3790 if (is_lan_addr(&ent->recv_msg->addr))
3791 ipmi_inc_stat(intf,
3792 retransmitted_lan_commands);
3793 else
3794 ipmi_inc_stat(intf,
3795 retransmitted_ipmb_commands);
3796
3768 intf->handlers->sender(intf->send_info, 3797 intf->handlers->sender(intf->send_info,
3769 smi_msg, 0); 3798 smi_msg, 0);
3770 else 3799 } else
3771 ipmi_free_smi_msg(smi_msg); 3800 ipmi_free_smi_msg(smi_msg);
3772 3801
3773 spin_lock_irqsave(&intf->seq_lock, *flags); 3802 spin_lock_irqsave(&intf->seq_lock, *flags);