Skip to content

Commit ac93bd0

Browse files
committed
ipmi: Fix some counter issues
Counters would not be pegged properly on some errors. Have deliver_response() return an error so the counters can be incremented properly. Signed-off-by: Corey Minyard <[email protected]>
1 parent a567b62 commit ac93bd0

File tree

1 file changed

+45
-31
lines changed

1 file changed

+45
-31
lines changed

drivers/char/ipmi/ipmi_msghandler.c

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -886,18 +886,17 @@ unsigned int ipmi_addr_length(int addr_type)
886886
}
887887
EXPORT_SYMBOL(ipmi_addr_length);
888888

889-
static void deliver_response(struct ipmi_recv_msg *msg)
889+
static int deliver_response(struct ipmi_smi *intf, struct ipmi_recv_msg *msg)
890890
{
891-
if (!msg->user) {
892-
struct ipmi_smi *intf = msg->user_msg_data;
891+
int rv = 0;
893892

893+
if (!msg->user) {
894894
/* Special handling for NULL users. */
895895
if (intf->null_user_handler) {
896896
intf->null_user_handler(intf, msg);
897-
ipmi_inc_stat(intf, handled_local_responses);
898897
} else {
899898
/* No handler, so give up. */
900-
ipmi_inc_stat(intf, unhandled_local_responses);
899+
rv = -EINVAL;
901900
}
902901
ipmi_free_recv_msg(msg);
903902
} else if (!oops_in_progress) {
@@ -910,17 +909,28 @@ static void deliver_response(struct ipmi_recv_msg *msg)
910909
struct ipmi_user *user = msg->user;
911910
user->handler->ipmi_recv_hndl(msg, user->handler_data);
912911
}
912+
913+
return rv;
913914
}
914915

915-
static void
916-
deliver_err_response(struct ipmi_recv_msg *msg, int err)
916+
static void deliver_local_response(struct ipmi_smi *intf,
917+
struct ipmi_recv_msg *msg)
918+
{
919+
if (deliver_response(intf, msg))
920+
ipmi_inc_stat(intf, unhandled_local_responses);
921+
else
922+
ipmi_inc_stat(intf, handled_local_responses);
923+
}
924+
925+
static void deliver_err_response(struct ipmi_smi *intf,
926+
struct ipmi_recv_msg *msg, int err)
917927
{
918928
msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
919929
msg->msg_data[0] = err;
920930
msg->msg.netfn |= 1; /* Convert to a response. */
921931
msg->msg.data_len = 1;
922932
msg->msg.data = msg->msg_data;
923-
deliver_response(msg);
933+
deliver_local_response(intf, msg);
924934
}
925935

926936
/*
@@ -1071,7 +1081,7 @@ static int intf_err_seq(struct ipmi_smi *intf,
10711081
spin_unlock_irqrestore(&intf->seq_lock, flags);
10721082

10731083
if (msg)
1074-
deliver_err_response(msg, err);
1084+
deliver_err_response(intf, msg, err);
10751085

10761086
return rv;
10771087
}
@@ -1443,7 +1453,7 @@ int ipmi_set_gets_events(struct ipmi_user *user, bool val)
14431453
list_for_each_entry_safe(msg, msg2, &msgs, link) {
14441454
msg->user = user;
14451455
kref_get(&user->refcount);
1446-
deliver_response(msg);
1456+
deliver_local_response(intf, msg);
14471457
}
14481458

14491459
spin_lock_irqsave(&intf->events_lock, flags);
@@ -3614,7 +3624,7 @@ static void cleanup_smi_msgs(struct ipmi_smi *intf)
36143624
ent = &intf->seq_table[i];
36153625
if (!ent->inuse)
36163626
continue;
3617-
deliver_err_response(ent->recv_msg, IPMI_ERR_UNSPECIFIED);
3627+
deliver_err_response(intf, ent->recv_msg, IPMI_ERR_UNSPECIFIED);
36183628
}
36193629
}
36203630

@@ -3719,8 +3729,10 @@ static int handle_ipmb_get_msg_rsp(struct ipmi_smi *intf,
37193729
recv_msg->msg.data = recv_msg->msg_data;
37203730
recv_msg->msg.data_len = msg->rsp_size - 10;
37213731
recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
3722-
ipmi_inc_stat(intf, handled_ipmb_responses);
3723-
deliver_response(recv_msg);
3732+
if (deliver_response(intf, recv_msg))
3733+
ipmi_inc_stat(intf, unhandled_ipmb_responses);
3734+
else
3735+
ipmi_inc_stat(intf, handled_ipmb_responses);
37243736

37253737
return 0;
37263738
}
@@ -3793,9 +3805,6 @@ static int handle_ipmb_get_msg_cmd(struct ipmi_smi *intf,
37933805
}
37943806
rcu_read_unlock();
37953807
} else {
3796-
/* Deliver the message to the user. */
3797-
ipmi_inc_stat(intf, handled_commands);
3798-
37993808
recv_msg = ipmi_alloc_recv_msg();
38003809
if (!recv_msg) {
38013810
/*
@@ -3831,7 +3840,10 @@ static int handle_ipmb_get_msg_cmd(struct ipmi_smi *intf,
38313840
recv_msg->msg.data_len = msg->rsp_size - 10;
38323841
memcpy(recv_msg->msg_data, &msg->rsp[9],
38333842
msg->rsp_size - 10);
3834-
deliver_response(recv_msg);
3843+
if (deliver_response(intf, recv_msg))
3844+
ipmi_inc_stat(intf, unhandled_commands);
3845+
else
3846+
ipmi_inc_stat(intf, handled_commands);
38353847
}
38363848
}
38373849

@@ -3897,8 +3909,10 @@ static int handle_lan_get_msg_rsp(struct ipmi_smi *intf,
38973909
recv_msg->msg.data = recv_msg->msg_data;
38983910
recv_msg->msg.data_len = msg->rsp_size - 12;
38993911
recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
3900-
ipmi_inc_stat(intf, handled_lan_responses);
3901-
deliver_response(recv_msg);
3912+
if (deliver_response(intf, recv_msg))
3913+
ipmi_inc_stat(intf, unhandled_lan_responses);
3914+
else
3915+
ipmi_inc_stat(intf, handled_lan_responses);
39023916

39033917
return 0;
39043918
}
@@ -3949,9 +3963,6 @@ static int handle_lan_get_msg_cmd(struct ipmi_smi *intf,
39493963
*/
39503964
rv = 0;
39513965
} else {
3952-
/* Deliver the message to the user. */
3953-
ipmi_inc_stat(intf, handled_commands);
3954-
39553966
recv_msg = ipmi_alloc_recv_msg();
39563967
if (!recv_msg) {
39573968
/*
@@ -3989,7 +4000,10 @@ static int handle_lan_get_msg_cmd(struct ipmi_smi *intf,
39894000
recv_msg->msg.data_len = msg->rsp_size - 12;
39904001
memcpy(recv_msg->msg_data, &msg->rsp[11],
39914002
msg->rsp_size - 12);
3992-
deliver_response(recv_msg);
4003+
if (deliver_response(intf, recv_msg))
4004+
ipmi_inc_stat(intf, unhandled_commands);
4005+
else
4006+
ipmi_inc_stat(intf, handled_commands);
39934007
}
39944008
}
39954009

@@ -4057,9 +4071,6 @@ static int handle_oem_get_msg_cmd(struct ipmi_smi *intf,
40574071

40584072
rv = 0;
40594073
} else {
4060-
/* Deliver the message to the user. */
4061-
ipmi_inc_stat(intf, handled_commands);
4062-
40634074
recv_msg = ipmi_alloc_recv_msg();
40644075
if (!recv_msg) {
40654076
/*
@@ -4096,7 +4107,10 @@ static int handle_oem_get_msg_cmd(struct ipmi_smi *intf,
40964107
recv_msg->msg.data_len = msg->rsp_size - 4;
40974108
memcpy(recv_msg->msg_data, &msg->rsp[4],
40984109
msg->rsp_size - 4);
4099-
deliver_response(recv_msg);
4110+
if (deliver_response(intf, recv_msg))
4111+
ipmi_inc_stat(intf, unhandled_commands);
4112+
else
4113+
ipmi_inc_stat(intf, handled_commands);
41004114
}
41014115
}
41024116

@@ -4187,7 +4201,7 @@ static int handle_read_event_rsp(struct ipmi_smi *intf,
41874201
/* Now deliver all the messages. */
41884202
list_for_each_entry_safe(recv_msg, recv_msg2, &msgs, link) {
41894203
list_del(&recv_msg->link);
4190-
deliver_response(recv_msg);
4204+
deliver_local_response(intf, recv_msg);
41914205
}
41924206
} else if (intf->waiting_events_count < MAX_EVENTS_IN_QUEUE) {
41934207
/*
@@ -4259,7 +4273,7 @@ static int handle_bmc_rsp(struct ipmi_smi *intf,
42594273
memcpy(recv_msg->msg_data, &msg->rsp[2], msg->rsp_size - 2);
42604274
recv_msg->msg.data = recv_msg->msg_data;
42614275
recv_msg->msg.data_len = msg->rsp_size - 2;
4262-
deliver_response(recv_msg);
4276+
deliver_local_response(intf, recv_msg);
42634277
}
42644278

42654279
return 0;
@@ -4336,7 +4350,7 @@ static int handle_one_recv_msg(struct ipmi_smi *intf,
43364350
recv_msg->msg.data = recv_msg->msg_data;
43374351
recv_msg->msg.data_len = 1;
43384352
recv_msg->msg_data[0] = msg->rsp[2];
4339-
deliver_response(recv_msg);
4353+
deliver_local_response(intf, recv_msg);
43404354
} else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2))
43414355
&& (msg->rsp[1] == IPMI_GET_MSG_CMD)) {
43424356
struct ipmi_channel *chans;
@@ -4761,7 +4775,7 @@ static unsigned int ipmi_timeout_handler(struct ipmi_smi *intf,
47614775
spin_unlock_irqrestore(&intf->seq_lock, flags);
47624776

47634777
list_for_each_entry_safe(msg, msg2, &timeouts, link)
4764-
deliver_err_response(msg, IPMI_TIMEOUT_COMPLETION_CODE);
4778+
deliver_err_response(intf, msg, IPMI_TIMEOUT_COMPLETION_CODE);
47654779

47664780
/*
47674781
* Maintenance mode handling. Check the timeout

0 commit comments

Comments
 (0)