The administrator sets the limit for the number of messages by modifying /sys/module/ipmi_msghandler/parameters/default_max_msgs.
Before create a message, count the number of outstanding messages, if the number reaches the limit, it will return a busy. Signed-off-by: Chen Guanqiao <chen.chencha...@foxmail.com> --- drivers/char/ipmi/ipmi_msghandler.c | 37 +++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 7886c8337368..80ab88702c5f 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -151,6 +151,12 @@ module_param(default_max_users, uint, 0644); MODULE_PARM_DESC(default_max_users, "The maximum number of users per interface"); +/* The default maximum number of outstanding messages per intf */ +static unsigned int default_max_messages = 100; +module_param(default_max_messages, uint, 0644); +MODULE_PARM_DESC(default_max_messages, + "The maximum number of outstanding messages per interface"); + /* Call every ~1000 ms. */ #define IPMI_TIMEOUT_TIME 1000 @@ -916,6 +922,30 @@ unsigned int ipmi_addr_length(int addr_type) } EXPORT_SYMBOL(ipmi_addr_length); +static void intf_msg_count(struct ipmi_smi *intf, + unsigned int *hp_count, unsigned int *count) +{ + struct ipmi_smi_msg *msg; + unsigned long flags; + int hp_msg_count = 0, msg_count = 0; + int run_to_completion = intf->run_to_completion; + + if (!run_to_completion) + spin_lock_irqsave(&intf->xmit_msgs_lock, flags); + if (!intf->in_shutdown) { + list_for_each_entry(msg, &intf->hp_xmit_msgs, link) + hp_msg_count++; + + list_for_each_entry(msg, &intf->xmit_msgs, link) + msg_count++; + } + if (!run_to_completion) + spin_unlock_irqrestore(&intf->xmit_msgs_lock, flags); + + *hp_count = hp_msg_count; + *count = msg_count; +} + static int deliver_response(struct ipmi_smi *intf, struct ipmi_recv_msg *msg) { int rv = 0; @@ -2299,6 +2329,7 @@ static int i_ipmi_request(struct ipmi_user *user, { struct ipmi_smi_msg *smi_msg; struct ipmi_recv_msg *recv_msg; + unsigned hp_msg_count, msg_count; int rv = 0; if (supplied_recv) @@ -2330,6 +2361,12 @@ static int i_ipmi_request(struct ipmi_user *user, goto out_err; } + intf_msg_count(intf, &hp_msg_count, &msg_count); + if ((hp_msg_count + msg_count) > default_max_messages) { + rv = -EBUSY; + goto out_err; + } + recv_msg->user = user; if (user) /* The put happens when the message is freed. */ -- 2.25.1 _______________________________________________ Openipmi-developer mailing list Openipmi-developer@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openipmi-developer