浏览代码

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>
Corey Minyard 16 年之前
父节点
当前提交
25176ed670
共有 1 个文件被更改,包括 51 次插入22 次删除
  1. 51 22
      drivers/char/ipmi/ipmi_msghandler.c

+ 51 - 22
drivers/char/ipmi/ipmi_msghandler.c

@@ -285,6 +285,11 @@ enum ipmi_stat_indexes {
 	/* Events that were received with the proper format. */
 	/* Events that were received with the proper format. */
 	IPMI_STAT_events,
 	IPMI_STAT_events,
 
 
+	/* Retransmissions on IPMB that failed. */
+	IPMI_STAT_dropped_rexmit_ipmb_commands,
+
+	/* Retransmissions on LAN that failed. */
+	IPMI_STAT_dropped_rexmit_lan_commands,
 
 
 	/* This *must* remain last, add new values above this. */
 	/* This *must* remain last, add new values above this. */
 	IPMI_NUM_STATS
 	IPMI_NUM_STATS
@@ -445,6 +450,20 @@ static DEFINE_MUTEX(smi_watchers_mutex);
 #define ipmi_get_stat(intf, stat) \
 #define ipmi_get_stat(intf, stat) \
 	((unsigned int) atomic_read(&(intf)->stats[IPMI_STAT_ ## stat]))
 	((unsigned int) atomic_read(&(intf)->stats[IPMI_STAT_ ## stat]))
 
 
+static int is_lan_addr(struct ipmi_addr *addr)
+{
+	return addr->addr_type == IPMI_LAN_ADDR_TYPE;
+}
+
+static int is_ipmb_addr(struct ipmi_addr *addr)
+{
+	return addr->addr_type == IPMI_IPMB_ADDR_TYPE;
+}
+
+static int is_ipmb_bcast_addr(struct ipmi_addr *addr)
+{
+	return addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE;
+}
 
 
 static void free_recv_msg_list(struct list_head *q)
 static void free_recv_msg_list(struct list_head *q)
 {
 {
@@ -601,8 +620,7 @@ ipmi_addr_equal(struct ipmi_addr *addr1, struct ipmi_addr *addr2)
 		return (smi_addr1->lun == smi_addr2->lun);
 		return (smi_addr1->lun == smi_addr2->lun);
 	}
 	}
 
 
-	if ((addr1->addr_type == IPMI_IPMB_ADDR_TYPE)
-	    || (addr1->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) {
+	if (is_ipmb_addr(addr1) || is_ipmb_bcast_addr(addr1)) {
 		struct ipmi_ipmb_addr *ipmb_addr1
 		struct ipmi_ipmb_addr *ipmb_addr1
 		    = (struct ipmi_ipmb_addr *) addr1;
 		    = (struct ipmi_ipmb_addr *) addr1;
 		struct ipmi_ipmb_addr *ipmb_addr2
 		struct ipmi_ipmb_addr *ipmb_addr2
@@ -612,7 +630,7 @@ ipmi_addr_equal(struct ipmi_addr *addr1, struct ipmi_addr *addr2)
 			&& (ipmb_addr1->lun == ipmb_addr2->lun));
 			&& (ipmb_addr1->lun == ipmb_addr2->lun));
 	}
 	}
 
 
-	if (addr1->addr_type == IPMI_LAN_ADDR_TYPE) {
+	if (is_lan_addr(addr1)) {
 		struct ipmi_lan_addr *lan_addr1
 		struct ipmi_lan_addr *lan_addr1
 			= (struct ipmi_lan_addr *) addr1;
 			= (struct ipmi_lan_addr *) addr1;
 		struct ipmi_lan_addr *lan_addr2
 		struct ipmi_lan_addr *lan_addr2
@@ -644,14 +662,13 @@ int ipmi_validate_addr(struct ipmi_addr *addr, int len)
 	    || (addr->channel < 0))
 	    || (addr->channel < 0))
 		return -EINVAL;
 		return -EINVAL;
 
 
-	if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE)
-	    || (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) {
+	if (is_ipmb_addr(addr) || is_ipmb_bcast_addr(addr)) {
 		if (len < sizeof(struct ipmi_ipmb_addr))
 		if (len < sizeof(struct ipmi_ipmb_addr))
 			return -EINVAL;
 			return -EINVAL;
 		return 0;
 		return 0;
 	}
 	}
 
 
-	if (addr->addr_type == IPMI_LAN_ADDR_TYPE) {
+	if (is_lan_addr(addr)) {
 		if (len < sizeof(struct ipmi_lan_addr))
 		if (len < sizeof(struct ipmi_lan_addr))
 			return -EINVAL;
 			return -EINVAL;
 		return 0;
 		return 0;
@@ -1503,8 +1520,7 @@ static int i_ipmi_request(ipmi_user_t          user,
 			memcpy(&(smi_msg->data[2]), msg->data, msg->data_len);
 			memcpy(&(smi_msg->data[2]), msg->data, msg->data_len);
 		smi_msg->data_size = msg->data_len + 2;
 		smi_msg->data_size = msg->data_len + 2;
 		ipmi_inc_stat(intf, sent_local_commands);
 		ipmi_inc_stat(intf, sent_local_commands);
-	} else if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE)
-		   || (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) {
+	} else if (is_ipmb_addr(addr) || is_ipmb_bcast_addr(addr)) {
 		struct ipmi_ipmb_addr *ipmb_addr;
 		struct ipmi_ipmb_addr *ipmb_addr;
 		unsigned char         ipmb_seq;
 		unsigned char         ipmb_seq;
 		long                  seqid;
 		long                  seqid;
@@ -1583,8 +1599,6 @@ static int i_ipmi_request(ipmi_user_t          user,
 
 
 			spin_lock_irqsave(&(intf->seq_lock), flags);
 			spin_lock_irqsave(&(intf->seq_lock), flags);
 
 
-			ipmi_inc_stat(intf, sent_ipmb_commands);
-
 			/*
 			/*
 			 * Create a sequence number with a 1 second
 			 * Create a sequence number with a 1 second
 			 * timeout and 4 retries.
 			 * timeout and 4 retries.
@@ -1606,6 +1620,8 @@ static int i_ipmi_request(ipmi_user_t          user,
 				goto out_err;
 				goto out_err;
 			}
 			}
 
 
+			ipmi_inc_stat(intf, sent_ipmb_commands);
+
 			/*
 			/*
 			 * Store the sequence number in the message,
 			 * Store the sequence number in the message,
 			 * so that when the send message response
 			 * so that when the send message response
@@ -1635,7 +1651,7 @@ static int i_ipmi_request(ipmi_user_t          user,
 			 */
 			 */
 			spin_unlock_irqrestore(&(intf->seq_lock), flags);
 			spin_unlock_irqrestore(&(intf->seq_lock), flags);
 		}
 		}
-	} else if (addr->addr_type == IPMI_LAN_ADDR_TYPE) {
+	} else if (is_lan_addr(addr)) {
 		struct ipmi_lan_addr  *lan_addr;
 		struct ipmi_lan_addr  *lan_addr;
 		unsigned char         ipmb_seq;
 		unsigned char         ipmb_seq;
 		long                  seqid;
 		long                  seqid;
@@ -1696,8 +1712,6 @@ static int i_ipmi_request(ipmi_user_t          user,
 
 
 			spin_lock_irqsave(&(intf->seq_lock), flags);
 			spin_lock_irqsave(&(intf->seq_lock), flags);
 
 
-			ipmi_inc_stat(intf, sent_lan_commands);
-
 			/*
 			/*
 			 * Create a sequence number with a 1 second
 			 * Create a sequence number with a 1 second
 			 * timeout and 4 retries.
 			 * timeout and 4 retries.
@@ -1719,6 +1733,8 @@ static int i_ipmi_request(ipmi_user_t          user,
 				goto out_err;
 				goto out_err;
 			}
 			}
 
 
+			ipmi_inc_stat(intf, sent_lan_commands);
+
 			/*
 			/*
 			 * Store the sequence number in the message,
 			 * Store the sequence number in the message,
 			 * so that when the send message response
 			 * so that when the send message response
@@ -1937,6 +1953,10 @@ static int stat_file_read_proc(char *page, char **start, off_t off,
 		       ipmi_get_stat(intf, invalid_events));
 		       ipmi_get_stat(intf, invalid_events));
 	out += sprintf(out, "events:                      %u\n",
 	out += sprintf(out, "events:                      %u\n",
 		       ipmi_get_stat(intf, events));
 		       ipmi_get_stat(intf, events));
+	out += sprintf(out, "failed rexmit LAN msgs:      %u\n",
+		       ipmi_get_stat(intf, dropped_rexmit_lan_commands));
+	out += sprintf(out, "failed rexmit IPMB msgs:     %u\n",
+		       ipmi_get_stat(intf, dropped_rexmit_ipmb_commands));
 
 
 	return (out - ((char *) page));
 	return (out - ((char *) page));
 }
 }
@@ -3730,7 +3750,7 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
 		list_add_tail(&msg->link, timeouts);
 		list_add_tail(&msg->link, timeouts);
 		if (ent->broadcast)
 		if (ent->broadcast)
 			ipmi_inc_stat(intf, timed_out_ipmb_broadcasts);
 			ipmi_inc_stat(intf, timed_out_ipmb_broadcasts);
-		else if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE)
+		else if (is_lan_addr(&ent->recv_msg->addr))
 			ipmi_inc_stat(intf, timed_out_lan_commands);
 			ipmi_inc_stat(intf, timed_out_lan_commands);
 		else
 		else
 			ipmi_inc_stat(intf, timed_out_ipmb_commands);
 			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,
 		 */
 		 */
 		ent->timeout = MAX_MSG_TIMEOUT;
 		ent->timeout = MAX_MSG_TIMEOUT;
 		ent->retries_left--;
 		ent->retries_left--;
-		if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE)
-			ipmi_inc_stat(intf, retransmitted_lan_commands);
-		else
-			ipmi_inc_stat(intf, retransmitted_ipmb_commands);
-
 		smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot,
 		smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot,
 					    ent->seqid);
 					    ent->seqid);
-		if (!smi_msg)
+		if (!smi_msg) {
+			if (is_lan_addr(&ent->recv_msg->addr))
+				ipmi_inc_stat(intf,
+					      dropped_rexmit_lan_commands);
+			else
+				ipmi_inc_stat(intf,
+					      dropped_rexmit_ipmb_commands);
 			return;
 			return;
+		}
 
 
 		spin_unlock_irqrestore(&intf->seq_lock, *flags);
 		spin_unlock_irqrestore(&intf->seq_lock, *flags);
 
 
@@ -3764,10 +3786,17 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
 		 * resent.
 		 * resent.
 		 */
 		 */
 		handlers = intf->handlers;
 		handlers = intf->handlers;
-		if (handlers)
+		if (handlers) {
+			if (is_lan_addr(&ent->recv_msg->addr))
+				ipmi_inc_stat(intf,
+					      retransmitted_lan_commands);
+			else
+				ipmi_inc_stat(intf,
+					      retransmitted_ipmb_commands);
+
 			intf->handlers->sender(intf->send_info,
 			intf->handlers->sender(intf->send_info,
 					       smi_msg, 0);
 					       smi_msg, 0);
-		else
+		} else
 			ipmi_free_smi_msg(smi_msg);
 			ipmi_free_smi_msg(smi_msg);
 
 
 		spin_lock_irqsave(&intf->seq_lock, *flags);
 		spin_lock_irqsave(&intf->seq_lock, *flags);