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

Reply via email to