[<prev] [next>] [day] [month] [year] [list]
Message-ID: <tencent_ADBE84293031AFCF8E409D87E2BE9B0FF507@qq.com>
Date: Wed, 30 Mar 2022 00:12:40 +0800
From: Chen Guanqiao <chen.chenchacha@...mail.com>
To: minyard@....org, openipmi-developer@...ts.sourceforge.net,
linux-kernel@...r.kernel.org
Cc: Chen Guanqiao <chen.chenchacha@...mail.com>
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 <chen.chenchacha@...mail.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
Powered by blists - more mailing lists