The further approach, add a cleanup interface in sysfs. The administrator write
'1' to clean_msg, and ipmi clear the entire message queue.

Signed-off-by: Chen Guanqiao <chen.chencha...@foxmail.com>
---
 drivers/char/ipmi/ipmi_msghandler.c | 81 +++++++++++++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/drivers/char/ipmi/ipmi_msghandler.c 
b/drivers/char/ipmi/ipmi_msghandler.c
index a188dc7e7135..58f3e17ee6b2 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -46,6 +46,9 @@ static void handle_new_recv_msgs(struct ipmi_smi *intf);
 static void need_waiter(struct ipmi_smi *intf);
 static int handle_one_recv_msg(struct ipmi_smi *intf,
                               struct ipmi_smi_msg *msg);
+static void deliver_smi_err_response(struct ipmi_smi *intf,
+                                    struct ipmi_smi_msg *msg,
+                                    unsigned char err);

 static bool initialized;
 static bool drvregistered;
@@ -2809,6 +2812,70 @@ static void get_msg_count(unsigned int *hp_count, 
unsigned int *count)
        srcu_read_unlock(&ipmi_interfaces_srcu, index);
 }

+static void __cleanup_msgs_queue(struct ipmi_smi *intf)
+{
+       int i;
+       unsigned long flags;
+       int run_to_completion = intf->run_to_completion;
+
+       rcu_read_lock();
+       if (!run_to_completion)
+               spin_lock_irqsave(&intf->xmit_msgs_lock, flags);
+       if (!intf->in_shutdown) {
+               struct ipmi_smi_msg *msg;
+               struct list_head *entry = NULL;
+
+               while (!list_empty(&intf->xmit_msgs)) {
+                       if (!list_empty(&intf->hp_xmit_msgs))
+                               entry = intf->hp_xmit_msgs.next;
+                       else if (!list_empty(&intf->xmit_msgs))
+                               entry = intf->xmit_msgs.next;
+
+                       if (!entry)
+                               continue;
+
+                       list_del(entry);
+                       msg = list_entry(entry, struct ipmi_smi_msg, link);
+                       deliver_smi_err_response(intf, msg,
+                                                IPMI_ERR_UNSPECIFIED);
+               }
+       }
+       if (!run_to_completion)
+               spin_unlock_irqrestore(&intf->xmit_msgs_lock, flags);
+       rcu_read_unlock();
+
+       spin_lock_irqsave(&intf->seq_lock, flags);
+       for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) {
+               struct seq_table *ent = &intf->seq_table[i];
+               if (!ent->inuse)
+                       continue;
+               deliver_err_response(intf, ent->recv_msg, IPMI_ERR_UNSPECIFIED);
+       }
+       spin_unlock_irqrestore(&intf->seq_lock, flags);
+}
+
+static void cleanup_msgs_queue(void)
+{
+       struct ipmi_smi *intf;
+       int index;
+
+       index = srcu_read_lock(&ipmi_interfaces_srcu);
+       list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
+               struct bmc_device *bmc = intf->bmc;
+
+               kref_get(&intf->refcount);
+               mutex_lock(&intf->bmc_reg_mutex);
+               mutex_lock(&bmc->dyn_mutex);
+
+               __cleanup_msgs_queue(intf);
+
+               mutex_unlock(&bmc->dyn_mutex);
+               mutex_unlock(&intf->bmc_reg_mutex);
+               kref_put(&intf->refcount, intf_free);
+       }
+       srcu_read_unlock(&ipmi_interfaces_srcu, index);
+}
+
 static ssize_t device_id_show(struct device *dev,
                              struct device_attribute *attr,
                              char *buf)
@@ -2998,6 +3065,19 @@ static ssize_t msg_count_show(struct device *dev, struct 
device_attribute *attr,
 }
 static DEVICE_ATTR_ADMIN_RO(msg_count);

+static ssize_t clean_msgs_store(struct device *dev,
+                               struct device_attribute *attr,
+                               const char *buf, size_t count)
+{
+       if (!sysfs_streq(buf, "1"))
+               return -EINVAL;
+
+       cleanup_msgs_queue();
+
+       return count;
+}
+static DEVICE_ATTR_WO(clean_msgs);
+
 static struct attribute *bmc_dev_attrs[] = {
        &dev_attr_device_id.attr,
        &dev_attr_provides_device_sdrs.attr,
@@ -3011,6 +3091,7 @@ static struct attribute *bmc_dev_attrs[] = {
        &dev_attr_guid.attr,
        &dev_attr_user_count.attr,
        &dev_attr_msg_count.attr,
+       &dev_attr_clean_msgs.attr,
        NULL
 };

--
2.25.1



_______________________________________________
Openipmi-developer mailing list
Openipmi-developer@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openipmi-developer

Reply via email to