Hi List,
This is a patch for fixing the following problem-
if the application executes IPMICTL_SET_GETS_EVENTS_CMD and does
not execute IPMICTL_RECEIVE_MSG(_TRUNC), ie does not read
the message from the queue, which frees the
memory occupied by the messages in the queue, leads to
the infinite growth of the message queue and getting OOM
killing invoked.
Thanks
Amit Chaudhary.
This patch fixes the problem that occur if the
application executes IPMICTL_SET_GETS_EVENTS_CMD and does
not execute IPMICTL_RECEIVE_MSG(_TRUNC), ie does not read
the message from the queue, the receive operation frees the
memory occupied by the messages in the queue. This leads to
the infinite growth of the message queue and getting OOM
killing invoked.
Signed-off-by: Amit Chaudhary <[EMAIL PROTECTED]>
Index: linux-2.6.26/drivers/char/ipmi/ipmi_devintf.c
===================================================================
--- linux-2.6.26.orig/drivers/char/ipmi/ipmi_devintf.c
+++ linux-2.6.26/drivers/char/ipmi/ipmi_devintf.c
@@ -44,6 +44,9 @@
#include <linux/device.h>
#include <linux/compat.h>
+#define MAX_RECV_MSGS_QUEUE 100
+#define PRFX "IPMI device interface: "
+
struct ipmi_file_private
{
ipmi_user_t user;
@@ -55,6 +58,10 @@ struct ipmi_file_private
struct mutex recv_mutex;
int default_retries;
unsigned int default_retry_time_ms;
+ /* limit the queue at recv_msgs_count */
+ unsigned int recv_msgs_count;
+ unsigned char recv_msgs_printed;
+
};
static void file_receive_handler(struct ipmi_recv_msg *msg,
@@ -66,14 +73,33 @@ static void file_receive_handler(struct
spin_lock_irqsave(&(priv->recv_msg_lock), flags);
+ if (priv->recv_msgs_count >= MAX_RECV_MSGS_QUEUE) {
+ ipmi_free_recv_msg(msg);
+ if (!priv->recv_msgs_printed) {
+ printk(KERN_WARNING PRFX "Recieve message queue is full"
+ " now, discarding incoming message(s).\n");
+ priv->recv_msgs_printed = 1;
+ }
+
+ goto out_unlock;
+ }
+
+ if (priv->recv_msgs_printed) {
+ printk(KERN_WARNING PRFX "Recieve message queue no longer full."
+ "\n");
+ priv->recv_msgs_printed = 0;
+ }
+
was_empty = list_empty(&(priv->recv_msgs));
list_add_tail(&(msg->link), &(priv->recv_msgs));
+ priv->recv_msgs_count++;
if (was_empty) {
wake_up_interruptible(&priv->wait);
kill_fasync(&priv->fasync_queue, SIGIO, POLL_IN);
}
+out_unlock:
spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
}
@@ -144,6 +170,10 @@ static int ipmi_open(struct inode *inode
priv->default_retries = -1;
priv->default_retry_time_ms = 0;
+ /* message queue overrun handling*/
+ priv->recv_msgs_count = 0;
+ priv->recv_msgs_printed = 0;
+
return 0;
}
@@ -302,6 +332,7 @@ static int ipmi_ioctl(struct inode *ino
entry = priv->recv_msgs.next;
msg = list_entry(entry, struct ipmi_recv_msg, link);
list_del(entry);
+ priv->recv_msgs_count--;
spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
addr_len = ipmi_addr_length(msg->addr.addr_type);
@@ -358,6 +389,7 @@ static int ipmi_ioctl(struct inode *ino
the head of the queue. */
spin_lock_irqsave(&(priv->recv_msg_lock), flags);
list_add(entry, &(priv->recv_msgs));
+ priv->recv_msgs_count++;
spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
mutex_unlock(&priv->recv_mutex);
break;
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Openipmi-developer mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openipmi-developer