[IA64-SGI] sn2 mutex conversion
Migrate sn2 code to use mutex and completion events rather than semaphores. Signed-off-by: Jes Sorensen <jes@sgi.com> Acked-by: Dean Nelson <dcn@sgi.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
This commit is contained in:
@@ -10,6 +10,7 @@
|
|||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/timer.h>
|
#include <linux/timer.h>
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
#include <asm/mca.h>
|
#include <asm/mca.h>
|
||||||
#include <asm/sal.h>
|
#include <asm/sal.h>
|
||||||
#include <asm/sn/sn_sal.h>
|
#include <asm/sn/sn_sal.h>
|
||||||
@@ -27,7 +28,7 @@ void sn_init_cpei_timer(void);
|
|||||||
/* Printing oemdata from mca uses data that is not passed through SAL, it is
|
/* Printing oemdata from mca uses data that is not passed through SAL, it is
|
||||||
* global. Only one user at a time.
|
* global. Only one user at a time.
|
||||||
*/
|
*/
|
||||||
static DECLARE_MUTEX(sn_oemdata_mutex);
|
static DEFINE_MUTEX(sn_oemdata_mutex);
|
||||||
static u8 **sn_oemdata;
|
static u8 **sn_oemdata;
|
||||||
static u64 *sn_oemdata_size, sn_oemdata_bufsize;
|
static u64 *sn_oemdata_size, sn_oemdata_bufsize;
|
||||||
|
|
||||||
@@ -89,7 +90,7 @@ static int
|
|||||||
sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata,
|
sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata,
|
||||||
u64 * oemdata_size)
|
u64 * oemdata_size)
|
||||||
{
|
{
|
||||||
down(&sn_oemdata_mutex);
|
mutex_lock(&sn_oemdata_mutex);
|
||||||
sn_oemdata = oemdata;
|
sn_oemdata = oemdata;
|
||||||
sn_oemdata_size = oemdata_size;
|
sn_oemdata_size = oemdata_size;
|
||||||
sn_oemdata_bufsize = 0;
|
sn_oemdata_bufsize = 0;
|
||||||
@@ -107,7 +108,7 @@ sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata,
|
|||||||
*sn_oemdata_size = 0;
|
*sn_oemdata_size = 0;
|
||||||
ia64_sn_plat_specific_err_print(print_hook, (char *)sect_header);
|
ia64_sn_plat_specific_err_print(print_hook, (char *)sect_header);
|
||||||
}
|
}
|
||||||
up(&sn_oemdata_mutex);
|
mutex_unlock(&sn_oemdata_mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
#include <asm/sn/intr.h>
|
#include <asm/sn/intr.h>
|
||||||
#include <asm/sn/sn_sal.h>
|
#include <asm/sn/sn_sal.h>
|
||||||
#include <asm/sn/xp.h>
|
#include <asm/sn/xp.h>
|
||||||
@@ -136,13 +137,13 @@ xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
|
|||||||
|
|
||||||
registration = &xpc_registrations[ch_number];
|
registration = &xpc_registrations[ch_number];
|
||||||
|
|
||||||
if (down_interruptible(®istration->sema) != 0) {
|
if (mutex_lock_interruptible(®istration->mutex) != 0) {
|
||||||
return xpcInterrupted;
|
return xpcInterrupted;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if XPC_CHANNEL_REGISTERED(ch_number) */
|
/* if XPC_CHANNEL_REGISTERED(ch_number) */
|
||||||
if (registration->func != NULL) {
|
if (registration->func != NULL) {
|
||||||
up(®istration->sema);
|
mutex_unlock(®istration->mutex);
|
||||||
return xpcAlreadyRegistered;
|
return xpcAlreadyRegistered;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,7 +155,7 @@ xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
|
|||||||
registration->key = key;
|
registration->key = key;
|
||||||
registration->func = func;
|
registration->func = func;
|
||||||
|
|
||||||
up(®istration->sema);
|
mutex_unlock(®istration->mutex);
|
||||||
|
|
||||||
xpc_interface.connect(ch_number);
|
xpc_interface.connect(ch_number);
|
||||||
|
|
||||||
@@ -190,11 +191,11 @@ xpc_disconnect(int ch_number)
|
|||||||
* figured XPC's users will just turn around and call xpc_disconnect()
|
* figured XPC's users will just turn around and call xpc_disconnect()
|
||||||
* again anyways, so we might as well wait, if need be.
|
* again anyways, so we might as well wait, if need be.
|
||||||
*/
|
*/
|
||||||
down(®istration->sema);
|
mutex_lock(®istration->mutex);
|
||||||
|
|
||||||
/* if !XPC_CHANNEL_REGISTERED(ch_number) */
|
/* if !XPC_CHANNEL_REGISTERED(ch_number) */
|
||||||
if (registration->func == NULL) {
|
if (registration->func == NULL) {
|
||||||
up(®istration->sema);
|
mutex_unlock(®istration->mutex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,7 +209,7 @@ xpc_disconnect(int ch_number)
|
|||||||
|
|
||||||
xpc_interface.disconnect(ch_number);
|
xpc_interface.disconnect(ch_number);
|
||||||
|
|
||||||
up(®istration->sema);
|
mutex_unlock(®istration->mutex);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -250,9 +251,9 @@ xp_init(void)
|
|||||||
xp_nofault_PIOR_target = SH1_IPI_ACCESS;
|
xp_nofault_PIOR_target = SH1_IPI_ACCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize the connection registration semaphores */
|
/* initialize the connection registration mutex */
|
||||||
for (ch_number = 0; ch_number < XPC_NCHANNELS; ch_number++) {
|
for (ch_number = 0; ch_number < XPC_NCHANNELS; ch_number++) {
|
||||||
sema_init(&xpc_registrations[ch_number].sema, 1); /* mutex */
|
mutex_init(&xpc_registrations[ch_number].mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -22,6 +22,8 @@
|
|||||||
#include <linux/cache.h>
|
#include <linux/cache.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
#include <linux/completion.h>
|
||||||
#include <asm/sn/bte.h>
|
#include <asm/sn/bte.h>
|
||||||
#include <asm/sn/sn_sal.h>
|
#include <asm/sn/sn_sal.h>
|
||||||
#include <asm/sn/xpc.h>
|
#include <asm/sn/xpc.h>
|
||||||
@@ -56,8 +58,8 @@ xpc_initialize_channels(struct xpc_partition *part, partid_t partid)
|
|||||||
atomic_set(&ch->n_to_notify, 0);
|
atomic_set(&ch->n_to_notify, 0);
|
||||||
|
|
||||||
spin_lock_init(&ch->lock);
|
spin_lock_init(&ch->lock);
|
||||||
sema_init(&ch->msg_to_pull_sema, 1); /* mutex */
|
mutex_init(&ch->msg_to_pull_mutex);
|
||||||
sema_init(&ch->wdisconnect_sema, 0); /* event wait */
|
init_completion(&ch->wdisconnect_wait);
|
||||||
|
|
||||||
atomic_set(&ch->n_on_msg_allocate_wq, 0);
|
atomic_set(&ch->n_on_msg_allocate_wq, 0);
|
||||||
init_waitqueue_head(&ch->msg_allocate_wq);
|
init_waitqueue_head(&ch->msg_allocate_wq);
|
||||||
@@ -534,7 +536,6 @@ static enum xpc_retval
|
|||||||
xpc_allocate_msgqueues(struct xpc_channel *ch)
|
xpc_allocate_msgqueues(struct xpc_channel *ch)
|
||||||
{
|
{
|
||||||
unsigned long irq_flags;
|
unsigned long irq_flags;
|
||||||
int i;
|
|
||||||
enum xpc_retval ret;
|
enum xpc_retval ret;
|
||||||
|
|
||||||
|
|
||||||
@@ -552,11 +553,6 @@ xpc_allocate_msgqueues(struct xpc_channel *ch)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < ch->local_nentries; i++) {
|
|
||||||
/* use a semaphore as an event wait queue */
|
|
||||||
sema_init(&ch->notify_queue[i].sema, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock_irqsave(&ch->lock, irq_flags);
|
spin_lock_irqsave(&ch->lock, irq_flags);
|
||||||
ch->flags |= XPC_C_SETUP;
|
ch->flags |= XPC_C_SETUP;
|
||||||
spin_unlock_irqrestore(&ch->lock, irq_flags);
|
spin_unlock_irqrestore(&ch->lock, irq_flags);
|
||||||
@@ -799,10 +795,8 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ch->flags & XPC_C_WDISCONNECT) {
|
if (ch->flags & XPC_C_WDISCONNECT) {
|
||||||
spin_unlock_irqrestore(&ch->lock, *irq_flags);
|
/* we won't lose the CPU since we're holding ch->lock */
|
||||||
up(&ch->wdisconnect_sema);
|
complete(&ch->wdisconnect_wait);
|
||||||
spin_lock_irqsave(&ch->lock, *irq_flags);
|
|
||||||
|
|
||||||
} else if (ch->delayed_IPI_flags) {
|
} else if (ch->delayed_IPI_flags) {
|
||||||
if (part->act_state != XPC_P_DEACTIVATING) {
|
if (part->act_state != XPC_P_DEACTIVATING) {
|
||||||
/* time to take action on any delayed IPI flags */
|
/* time to take action on any delayed IPI flags */
|
||||||
@@ -1092,12 +1086,12 @@ xpc_connect_channel(struct xpc_channel *ch)
|
|||||||
struct xpc_registration *registration = &xpc_registrations[ch->number];
|
struct xpc_registration *registration = &xpc_registrations[ch->number];
|
||||||
|
|
||||||
|
|
||||||
if (down_trylock(®istration->sema) != 0) {
|
if (mutex_trylock(®istration->mutex) == 0) {
|
||||||
return xpcRetry;
|
return xpcRetry;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!XPC_CHANNEL_REGISTERED(ch->number)) {
|
if (!XPC_CHANNEL_REGISTERED(ch->number)) {
|
||||||
up(®istration->sema);
|
mutex_unlock(®istration->mutex);
|
||||||
return xpcUnregistered;
|
return xpcUnregistered;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1108,7 +1102,7 @@ xpc_connect_channel(struct xpc_channel *ch)
|
|||||||
|
|
||||||
if (ch->flags & XPC_C_DISCONNECTING) {
|
if (ch->flags & XPC_C_DISCONNECTING) {
|
||||||
spin_unlock_irqrestore(&ch->lock, irq_flags);
|
spin_unlock_irqrestore(&ch->lock, irq_flags);
|
||||||
up(®istration->sema);
|
mutex_unlock(®istration->mutex);
|
||||||
return ch->reason;
|
return ch->reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1140,7 +1134,7 @@ xpc_connect_channel(struct xpc_channel *ch)
|
|||||||
* channel lock be locked and will unlock and relock
|
* channel lock be locked and will unlock and relock
|
||||||
* the channel lock as needed.
|
* the channel lock as needed.
|
||||||
*/
|
*/
|
||||||
up(®istration->sema);
|
mutex_unlock(®istration->mutex);
|
||||||
XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes,
|
XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes,
|
||||||
&irq_flags);
|
&irq_flags);
|
||||||
spin_unlock_irqrestore(&ch->lock, irq_flags);
|
spin_unlock_irqrestore(&ch->lock, irq_flags);
|
||||||
@@ -1155,7 +1149,7 @@ xpc_connect_channel(struct xpc_channel *ch)
|
|||||||
atomic_inc(&xpc_partitions[ch->partid].nchannels_active);
|
atomic_inc(&xpc_partitions[ch->partid].nchannels_active);
|
||||||
}
|
}
|
||||||
|
|
||||||
up(®istration->sema);
|
mutex_unlock(®istration->mutex);
|
||||||
|
|
||||||
|
|
||||||
/* initiate the connection */
|
/* initiate the connection */
|
||||||
@@ -2089,7 +2083,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
|
|||||||
enum xpc_retval ret;
|
enum xpc_retval ret;
|
||||||
|
|
||||||
|
|
||||||
if (down_interruptible(&ch->msg_to_pull_sema) != 0) {
|
if (mutex_lock_interruptible(&ch->msg_to_pull_mutex) != 0) {
|
||||||
/* we were interrupted by a signal */
|
/* we were interrupted by a signal */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -2125,7 +2119,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
|
|||||||
|
|
||||||
XPC_DEACTIVATE_PARTITION(part, ret);
|
XPC_DEACTIVATE_PARTITION(part, ret);
|
||||||
|
|
||||||
up(&ch->msg_to_pull_sema);
|
mutex_unlock(&ch->msg_to_pull_mutex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2134,7 +2128,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
|
|||||||
ch->next_msg_to_pull += nmsgs;
|
ch->next_msg_to_pull += nmsgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
up(&ch->msg_to_pull_sema);
|
mutex_unlock(&ch->msg_to_pull_mutex);
|
||||||
|
|
||||||
/* return the message we were looking for */
|
/* return the message we were looking for */
|
||||||
msg_offset = (get % ch->remote_nentries) * ch->msg_size;
|
msg_offset = (get % ch->remote_nentries) * ch->msg_size;
|
||||||
|
@@ -55,6 +55,7 @@
|
|||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/reboot.h>
|
#include <linux/reboot.h>
|
||||||
|
#include <linux/completion.h>
|
||||||
#include <asm/sn/intr.h>
|
#include <asm/sn/intr.h>
|
||||||
#include <asm/sn/sn_sal.h>
|
#include <asm/sn/sn_sal.h>
|
||||||
#include <asm/kdebug.h>
|
#include <asm/kdebug.h>
|
||||||
@@ -177,10 +178,10 @@ static DECLARE_WAIT_QUEUE_HEAD(xpc_act_IRQ_wq);
|
|||||||
static unsigned long xpc_hb_check_timeout;
|
static unsigned long xpc_hb_check_timeout;
|
||||||
|
|
||||||
/* notification that the xpc_hb_checker thread has exited */
|
/* notification that the xpc_hb_checker thread has exited */
|
||||||
static DECLARE_MUTEX_LOCKED(xpc_hb_checker_exited);
|
static DECLARE_COMPLETION(xpc_hb_checker_exited);
|
||||||
|
|
||||||
/* notification that the xpc_discovery thread has exited */
|
/* notification that the xpc_discovery thread has exited */
|
||||||
static DECLARE_MUTEX_LOCKED(xpc_discovery_exited);
|
static DECLARE_COMPLETION(xpc_discovery_exited);
|
||||||
|
|
||||||
|
|
||||||
static struct timer_list xpc_hb_timer;
|
static struct timer_list xpc_hb_timer;
|
||||||
@@ -321,7 +322,7 @@ xpc_hb_checker(void *ignore)
|
|||||||
|
|
||||||
|
|
||||||
/* mark this thread as having exited */
|
/* mark this thread as having exited */
|
||||||
up(&xpc_hb_checker_exited);
|
complete(&xpc_hb_checker_exited);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,7 +342,7 @@ xpc_initiate_discovery(void *ignore)
|
|||||||
dev_dbg(xpc_part, "discovery thread is exiting\n");
|
dev_dbg(xpc_part, "discovery thread is exiting\n");
|
||||||
|
|
||||||
/* mark this thread as having exited */
|
/* mark this thread as having exited */
|
||||||
up(&xpc_discovery_exited);
|
complete(&xpc_discovery_exited);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -893,7 +894,7 @@ xpc_disconnect_wait(int ch_number)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) down(&ch->wdisconnect_sema);
|
wait_for_completion(&ch->wdisconnect_wait);
|
||||||
|
|
||||||
spin_lock_irqsave(&ch->lock, irq_flags);
|
spin_lock_irqsave(&ch->lock, irq_flags);
|
||||||
DBUG_ON(!(ch->flags & XPC_C_DISCONNECTED));
|
DBUG_ON(!(ch->flags & XPC_C_DISCONNECTED));
|
||||||
@@ -946,10 +947,10 @@ xpc_do_exit(enum xpc_retval reason)
|
|||||||
free_irq(SGI_XPC_ACTIVATE, NULL);
|
free_irq(SGI_XPC_ACTIVATE, NULL);
|
||||||
|
|
||||||
/* wait for the discovery thread to exit */
|
/* wait for the discovery thread to exit */
|
||||||
down(&xpc_discovery_exited);
|
wait_for_completion(&xpc_discovery_exited);
|
||||||
|
|
||||||
/* wait for the heartbeat checker thread to exit */
|
/* wait for the heartbeat checker thread to exit */
|
||||||
down(&xpc_hb_checker_exited);
|
wait_for_completion(&xpc_hb_checker_exited);
|
||||||
|
|
||||||
|
|
||||||
/* sleep for a 1/3 of a second or so */
|
/* sleep for a 1/3 of a second or so */
|
||||||
@@ -1367,7 +1368,7 @@ xpc_init(void)
|
|||||||
dev_err(xpc_part, "failed while forking discovery thread\n");
|
dev_err(xpc_part, "failed while forking discovery thread\n");
|
||||||
|
|
||||||
/* mark this new thread as a non-starter */
|
/* mark this new thread as a non-starter */
|
||||||
up(&xpc_discovery_exited);
|
complete(&xpc_discovery_exited);
|
||||||
|
|
||||||
xpc_do_exit(xpcUnloading);
|
xpc_do_exit(xpcUnloading);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include <linux/cache.h>
|
#include <linux/cache.h>
|
||||||
#include <linux/hardirq.h>
|
#include <linux/hardirq.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
#include <asm/sn/types.h>
|
#include <asm/sn/types.h>
|
||||||
#include <asm/sn/bte.h>
|
#include <asm/sn/bte.h>
|
||||||
|
|
||||||
@@ -359,7 +360,7 @@ typedef void (*xpc_notify_func)(enum xpc_retval reason, partid_t partid,
|
|||||||
* the channel.
|
* the channel.
|
||||||
*/
|
*/
|
||||||
struct xpc_registration {
|
struct xpc_registration {
|
||||||
struct semaphore sema;
|
struct mutex mutex;
|
||||||
xpc_channel_func func; /* function to call */
|
xpc_channel_func func; /* function to call */
|
||||||
void *key; /* pointer to user's key */
|
void *key; /* pointer to user's key */
|
||||||
u16 nentries; /* #of msg entries in local msg queue */
|
u16 nentries; /* #of msg entries in local msg queue */
|
||||||
|
@@ -19,6 +19,8 @@
|
|||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/sysctl.h>
|
#include <linux/sysctl.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
#include <linux/completion.h>
|
||||||
#include <asm/pgtable.h>
|
#include <asm/pgtable.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <asm/sn/bte.h>
|
#include <asm/sn/bte.h>
|
||||||
@@ -335,7 +337,6 @@ struct xpc_openclose_args {
|
|||||||
* and consumed by the intended recipient.
|
* and consumed by the intended recipient.
|
||||||
*/
|
*/
|
||||||
struct xpc_notify {
|
struct xpc_notify {
|
||||||
struct semaphore sema; /* notify semaphore */
|
|
||||||
volatile u8 type; /* type of notification */
|
volatile u8 type; /* type of notification */
|
||||||
|
|
||||||
/* the following two fields are only used if type == XPC_N_CALL */
|
/* the following two fields are only used if type == XPC_N_CALL */
|
||||||
@@ -465,8 +466,8 @@ struct xpc_channel {
|
|||||||
xpc_channel_func func; /* user's channel function */
|
xpc_channel_func func; /* user's channel function */
|
||||||
void *key; /* pointer to user's key */
|
void *key; /* pointer to user's key */
|
||||||
|
|
||||||
struct semaphore msg_to_pull_sema; /* next msg to pull serialization */
|
struct mutex msg_to_pull_mutex; /* next msg to pull serialization */
|
||||||
struct semaphore wdisconnect_sema; /* wait for channel disconnect */
|
struct completion wdisconnect_wait; /* wait for channel disconnect */
|
||||||
|
|
||||||
struct xpc_openclose_args *local_openclose_args; /* args passed on */
|
struct xpc_openclose_args *local_openclose_args; /* args passed on */
|
||||||
/* opening or closing of channel */
|
/* opening or closing of channel */
|
||||||
|
Reference in New Issue
Block a user