#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>
static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void);
static int ipmi_init_msghandler(void);
-static int initialized = 0;
+static int initialized;
#ifdef CONFIG_PROC_FS
-static struct proc_dir_entry *proc_ipmi_root = NULL;
+static struct proc_dir_entry *proc_ipmi_root;
#endif /* CONFIG_PROC_FS */
/* Remain in auto-maintenance mode for this amount of time (in ms). */
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);
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);
kfree(entry);
rv = -ENOMEM;
} else {
- file->nlink = 1;
file->data = data;
file->read_proc = read_proc;
file->write_proc = write_proc;
bmc = container_of(ref, struct bmc_device, refcount);
remove_files(bmc);
- if (bmc->dev)
- platform_device_unregister(bmc->dev);
+ platform_device_unregister(bmc->dev);
kfree(bmc);
}
while (ipmi_find_bmc_prod_dev_id(&ipmidriver,
bmc->id.product_id,
- bmc->id.device_id))
- {
+ bmc->id.device_id)) {
if (!warn_printed) {
printk(KERN_WARNING PFX
"This machine has two different BMCs"
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);
}
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. */
/* 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]),
/* 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
}
#endif /* CONFIG_IPMI_PANIC_EVENT */
-static int has_panicked = 0;
+static int has_panicked;
static int panic_event(struct notifier_block *this,
unsigned long event,