]> err.no Git - linux-2.6/blobdiff - drivers/char/ipmi/ipmi_msghandler.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6
[linux-2.6] / drivers / char / ipmi / ipmi_msghandler.c
index 4e4691a538901b7b728950edefcb33c5475abc56..b5df7e61aeb2aa4b7282733d357a24dee06b887a 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <asm/system.h>
-#include <linux/sched.h>
 #include <linux/poll.h>
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
@@ -406,13 +405,14 @@ static void clean_up_interface_data(ipmi_smi_t intf)
        free_smi_msg_list(&intf->waiting_msgs);
        free_recv_msg_list(&intf->waiting_events);
 
-       /* Wholesale remove all the entries from the list in the
-        * interface and wait for RCU to know that none are in use. */
+       /*
+        * Wholesale remove all the entries from the list in the
+        * interface and wait for RCU to know that none are in use.
+        */
        mutex_lock(&intf->cmd_rcvrs_mutex);
-       list_add_rcu(&list, &intf->cmd_rcvrs);
-       list_del_rcu(&intf->cmd_rcvrs);
+       INIT_LIST_HEAD(&list);
+       list_splice_init_rcu(&intf->cmd_rcvrs, &list, synchronize_rcu);
        mutex_unlock(&intf->cmd_rcvrs_mutex);
-       synchronize_rcu();
 
        list_for_each_entry_safe(rcvr, rcvr2, &list, link)
                kfree(rcvr);
@@ -451,7 +451,7 @@ int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher)
        mutex_lock(&ipmi_interfaces_mutex);
 
        /* Build a list of things to deliver. */
-       list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
+       list_for_each_entry(intf, &ipmi_interfaces, link) {
                if (intf->intf_num == -1)
                        continue;
                e = kmalloc(sizeof(*e), GFP_KERNEL);
@@ -1886,7 +1886,6 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
                kfree(entry);
                rv = -ENOMEM;
        } else {
-               file->nlink = 1;
                file->data = data;
                file->read_proc = read_proc;
                file->write_proc = write_proc;
@@ -2172,52 +2171,42 @@ static int create_files(struct bmc_device *bmc)
        int err;
 
        bmc->device_id_attr.attr.name = "device_id";
-       bmc->device_id_attr.attr.owner = THIS_MODULE;
        bmc->device_id_attr.attr.mode = S_IRUGO;
        bmc->device_id_attr.show = device_id_show;
 
        bmc->provides_dev_sdrs_attr.attr.name = "provides_device_sdrs";
-       bmc->provides_dev_sdrs_attr.attr.owner = THIS_MODULE;
        bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO;
        bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show;
 
        bmc->revision_attr.attr.name = "revision";
-       bmc->revision_attr.attr.owner = THIS_MODULE;
        bmc->revision_attr.attr.mode = S_IRUGO;
        bmc->revision_attr.show = revision_show;
 
        bmc->firmware_rev_attr.attr.name = "firmware_revision";
-       bmc->firmware_rev_attr.attr.owner = THIS_MODULE;
        bmc->firmware_rev_attr.attr.mode = S_IRUGO;
        bmc->firmware_rev_attr.show = firmware_rev_show;
 
        bmc->version_attr.attr.name = "ipmi_version";
-       bmc->version_attr.attr.owner = THIS_MODULE;
        bmc->version_attr.attr.mode = S_IRUGO;
        bmc->version_attr.show = ipmi_version_show;
 
        bmc->add_dev_support_attr.attr.name = "additional_device_support";
-       bmc->add_dev_support_attr.attr.owner = THIS_MODULE;
        bmc->add_dev_support_attr.attr.mode = S_IRUGO;
        bmc->add_dev_support_attr.show = add_dev_support_show;
 
        bmc->manufacturer_id_attr.attr.name = "manufacturer_id";
-       bmc->manufacturer_id_attr.attr.owner = THIS_MODULE;
        bmc->manufacturer_id_attr.attr.mode = S_IRUGO;
        bmc->manufacturer_id_attr.show = manufacturer_id_show;
 
        bmc->product_id_attr.attr.name = "product_id";
-       bmc->product_id_attr.attr.owner = THIS_MODULE;
        bmc->product_id_attr.attr.mode = S_IRUGO;
        bmc->product_id_attr.show = product_id_show;
 
        bmc->guid_attr.attr.name = "guid";
-       bmc->guid_attr.attr.owner = THIS_MODULE;
        bmc->guid_attr.attr.mode = S_IRUGO;
        bmc->guid_attr.show = guid_show;
 
        bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision";
-       bmc->aux_firmware_rev_attr.attr.owner = THIS_MODULE;
        bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO;
        bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show;
 
@@ -2760,9 +2749,15 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
                synchronize_rcu();
                kref_put(&intf->refcount, intf_free);
        } else {
-               /* After this point the interface is legal to use. */
+               /*
+                * Keep memory order straight for RCU readers.  Make
+                * sure everything else is committed to memory before
+                * setting intf_num to mark the interface valid.
+                */
+               smp_wmb();
                intf->intf_num = i;
                mutex_unlock(&ipmi_interfaces_mutex);
+               /* After this point the interface is legal to use. */
                call_smi_watchers(i, intf->si_dev);
                mutex_unlock(&smi_watchers_mutex);
        }
@@ -3649,8 +3644,6 @@ static void ipmi_timeout_handler(long timeout_period)
        unsigned long        flags;
        int                  i;
 
-       INIT_LIST_HEAD(&timeouts);
-
        rcu_read_lock();
        list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
                /* See if any waiting messages need to be processed. */
@@ -3671,6 +3664,7 @@ static void ipmi_timeout_handler(long timeout_period)
                /* Go through the seq table and find any messages that
                   have timed out, putting them in the timeouts
                   list. */
+               INIT_LIST_HEAD(&timeouts);
                spin_lock_irqsave(&intf->seq_lock, flags);
                for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++)
                        check_msg_timeout(intf, &(intf->seq_table[i]),
@@ -3924,6 +3918,14 @@ static void send_panic_events(char *str)
                        /* Interface was not ready yet. */
                        continue;
 
+               /*
+                * intf_num is used as an marker to tell if the
+                * interface is valid.  Thus we need a read barrier to
+                * make sure data fetched before checking intf_num
+                * won't be used.
+                */
+               smp_rmb();
+
                /* First job here is to figure out where to send the
                   OEM events.  There's no way in IPMI to send OEM
                   events using an event send command, so we have to