2022-03-29 19:08:12

by chenchacha

[permalink] [raw]
Subject: [PATCH v2 2/4] ipmi: msghandler: Add a limit for the number of messages

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 <[email protected]>
---
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