From d6dfd1310d3562698fd7c3c086f6c239f96394ac Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Fri, 31 Mar 2006 02:30:41 -0800 Subject: [PATCH] IPMI: convert from semaphores to mutexes Convert the remaining semaphores to mutexes in the IPMI driver. The watchdog was using a semaphore as a real semaphore (for IPC), so the conversion there required adding a completion. Signed-off-by: Corey Minyard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_watchdog.c | 53 ++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 23 deletions(-) (limited to 'drivers/char/ipmi/ipmi_watchdog.c') diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 2872c9575528..2d11ddd99e55 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -303,21 +304,22 @@ static int ipmi_heartbeat(void); static void panic_halt_ipmi_heartbeat(void); -/* We use a semaphore to make sure that only one thing can send a set +/* We use a mutex to make sure that only one thing can send a set timeout at one time, because we only have one copy of the data. - The semaphore is claimed when the set_timeout is sent and freed + The mutex is claimed when the set_timeout is sent and freed when both messages are free. */ static atomic_t set_timeout_tofree = ATOMIC_INIT(0); -static DECLARE_MUTEX(set_timeout_lock); +static DEFINE_MUTEX(set_timeout_lock); +static DECLARE_COMPLETION(set_timeout_wait); static void set_timeout_free_smi(struct ipmi_smi_msg *msg) { if (atomic_dec_and_test(&set_timeout_tofree)) - up(&set_timeout_lock); + complete(&set_timeout_wait); } static void set_timeout_free_recv(struct ipmi_recv_msg *msg) { if (atomic_dec_and_test(&set_timeout_tofree)) - up(&set_timeout_lock); + complete(&set_timeout_wait); } static struct ipmi_smi_msg set_timeout_smi_msg = { @@ -399,7 +401,7 @@ static int ipmi_set_timeout(int do_heartbeat) /* We can only send one of these at a time. */ - down(&set_timeout_lock); + mutex_lock(&set_timeout_lock); atomic_set(&set_timeout_tofree, 2); @@ -407,16 +409,21 @@ static int ipmi_set_timeout(int do_heartbeat) &set_timeout_recv_msg, &send_heartbeat_now); if (rv) { - up(&set_timeout_lock); - } else { - if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) - || ((send_heartbeat_now) - && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) - { - rv = ipmi_heartbeat(); - } + mutex_unlock(&set_timeout_lock); + goto out; + } + + wait_for_completion(&set_timeout_wait); + + if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) + || ((send_heartbeat_now) + && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) + { + rv = ipmi_heartbeat(); } + mutex_unlock(&set_timeout_lock); +out: return rv; } @@ -458,17 +465,17 @@ static void panic_halt_ipmi_set_timeout(void) The semaphore is claimed when the set_timeout is sent and freed when both messages are free. */ static atomic_t heartbeat_tofree = ATOMIC_INIT(0); -static DECLARE_MUTEX(heartbeat_lock); -static DECLARE_MUTEX_LOCKED(heartbeat_wait_lock); +static DEFINE_MUTEX(heartbeat_lock); +static DECLARE_COMPLETION(heartbeat_wait); static void heartbeat_free_smi(struct ipmi_smi_msg *msg) { if (atomic_dec_and_test(&heartbeat_tofree)) - up(&heartbeat_wait_lock); + complete(&heartbeat_wait); } static void heartbeat_free_recv(struct ipmi_recv_msg *msg) { if (atomic_dec_and_test(&heartbeat_tofree)) - up(&heartbeat_wait_lock); + complete(&heartbeat_wait); } static struct ipmi_smi_msg heartbeat_smi_msg = { @@ -511,14 +518,14 @@ static int ipmi_heartbeat(void) return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); } - down(&heartbeat_lock); + mutex_lock(&heartbeat_lock); atomic_set(&heartbeat_tofree, 2); /* Don't reset the timer if we have the timer turned off, that re-enables the watchdog. */ if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) { - up(&heartbeat_lock); + mutex_unlock(&heartbeat_lock); return 0; } @@ -539,14 +546,14 @@ static int ipmi_heartbeat(void) &heartbeat_recv_msg, 1); if (rv) { - up(&heartbeat_lock); + mutex_unlock(&heartbeat_lock); printk(KERN_WARNING PFX "heartbeat failure: %d\n", rv); return rv; } /* Wait for the heartbeat to be sent. */ - down(&heartbeat_wait_lock); + wait_for_completion(&heartbeat_wait); if (heartbeat_recv_msg.msg.data[0] != 0) { /* Got an error in the heartbeat response. It was already @@ -555,7 +562,7 @@ static int ipmi_heartbeat(void) rv = -EINVAL; } - up(&heartbeat_lock); + mutex_unlock(&heartbeat_lock); return rv; } -- cgit v1.2.3