aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/sn/kernel/xpc_channel.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64/sn/kernel/xpc_channel.c')
-rw-r--r--arch/ia64/sn/kernel/xpc_channel.c34
1 files changed, 14 insertions, 20 deletions
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c
index 0c0a68902409..8d950c778bb6 100644
--- a/arch/ia64/sn/kernel/xpc_channel.c
+++ b/arch/ia64/sn/kernel/xpc_channel.c
@@ -22,6 +22,8 @@
22#include <linux/cache.h> 22#include <linux/cache.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/mutex.h>
26#include <linux/completion.h>
25#include <asm/sn/bte.h> 27#include <asm/sn/bte.h>
26#include <asm/sn/sn_sal.h> 28#include <asm/sn/sn_sal.h>
27#include <asm/sn/xpc.h> 29#include <asm/sn/xpc.h>
@@ -56,8 +58,8 @@ xpc_initialize_channels(struct xpc_partition *part, partid_t partid)
56 atomic_set(&ch->n_to_notify, 0); 58 atomic_set(&ch->n_to_notify, 0);
57 59
58 spin_lock_init(&ch->lock); 60 spin_lock_init(&ch->lock);
59 sema_init(&ch->msg_to_pull_sema, 1); /* mutex */ 61 mutex_init(&ch->msg_to_pull_mutex);
60 sema_init(&ch->wdisconnect_sema, 0); /* event wait */ 62 init_completion(&ch->wdisconnect_wait);
61 63
62 atomic_set(&ch->n_on_msg_allocate_wq, 0); 64 atomic_set(&ch->n_on_msg_allocate_wq, 0);
63 init_waitqueue_head(&ch->msg_allocate_wq); 65 init_waitqueue_head(&ch->msg_allocate_wq);
@@ -534,7 +536,6 @@ static enum xpc_retval
534xpc_allocate_msgqueues(struct xpc_channel *ch) 536xpc_allocate_msgqueues(struct xpc_channel *ch)
535{ 537{
536 unsigned long irq_flags; 538 unsigned long irq_flags;
537 int i;
538 enum xpc_retval ret; 539 enum xpc_retval ret;
539 540
540 541
@@ -552,11 +553,6 @@ xpc_allocate_msgqueues(struct xpc_channel *ch)
552 return ret; 553 return ret;
553 } 554 }
554 555
555 for (i = 0; i < ch->local_nentries; i++) {
556 /* use a semaphore as an event wait queue */
557 sema_init(&ch->notify_queue[i].sema, 0);
558 }
559
560 spin_lock_irqsave(&ch->lock, irq_flags); 556 spin_lock_irqsave(&ch->lock, irq_flags);
561 ch->flags |= XPC_C_SETUP; 557 ch->flags |= XPC_C_SETUP;
562 spin_unlock_irqrestore(&ch->lock, irq_flags); 558 spin_unlock_irqrestore(&ch->lock, irq_flags);
@@ -799,10 +795,8 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
799 } 795 }
800 796
801 if (ch->flags & XPC_C_WDISCONNECT) { 797 if (ch->flags & XPC_C_WDISCONNECT) {
802 spin_unlock_irqrestore(&ch->lock, *irq_flags); 798 /* we won't lose the CPU since we're holding ch->lock */
803 up(&ch->wdisconnect_sema); 799 complete(&ch->wdisconnect_wait);
804 spin_lock_irqsave(&ch->lock, *irq_flags);
805
806 } else if (ch->delayed_IPI_flags) { 800 } else if (ch->delayed_IPI_flags) {
807 if (part->act_state != XPC_P_DEACTIVATING) { 801 if (part->act_state != XPC_P_DEACTIVATING) {
808 /* time to take action on any delayed IPI flags */ 802 /* time to take action on any delayed IPI flags */
@@ -1092,12 +1086,12 @@ xpc_connect_channel(struct xpc_channel *ch)
1092 struct xpc_registration *registration = &xpc_registrations[ch->number]; 1086 struct xpc_registration *registration = &xpc_registrations[ch->number];
1093 1087
1094 1088
1095 if (down_trylock(&registration->sema) != 0) { 1089 if (mutex_trylock(&registration->mutex) == 0) {
1096 return xpcRetry; 1090 return xpcRetry;
1097 } 1091 }
1098 1092
1099 if (!XPC_CHANNEL_REGISTERED(ch->number)) { 1093 if (!XPC_CHANNEL_REGISTERED(ch->number)) {
1100 up(&registration->sema); 1094 mutex_unlock(&registration->mutex);
1101 return xpcUnregistered; 1095 return xpcUnregistered;
1102 } 1096 }
1103 1097
@@ -1108,7 +1102,7 @@ xpc_connect_channel(struct xpc_channel *ch)
1108 1102
1109 if (ch->flags & XPC_C_DISCONNECTING) { 1103 if (ch->flags & XPC_C_DISCONNECTING) {
1110 spin_unlock_irqrestore(&ch->lock, irq_flags); 1104 spin_unlock_irqrestore(&ch->lock, irq_flags);
1111 up(&registration->sema); 1105 mutex_unlock(&registration->mutex);
1112 return ch->reason; 1106 return ch->reason;
1113 } 1107 }
1114 1108
@@ -1140,7 +1134,7 @@ xpc_connect_channel(struct xpc_channel *ch)
1140 * channel lock be locked and will unlock and relock 1134 * channel lock be locked and will unlock and relock
1141 * the channel lock as needed. 1135 * the channel lock as needed.
1142 */ 1136 */
1143 up(&registration->sema); 1137 mutex_unlock(&registration->mutex);
1144 XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes, 1138 XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes,
1145 &irq_flags); 1139 &irq_flags);
1146 spin_unlock_irqrestore(&ch->lock, irq_flags); 1140 spin_unlock_irqrestore(&ch->lock, irq_flags);
@@ -1155,7 +1149,7 @@ xpc_connect_channel(struct xpc_channel *ch)
1155 atomic_inc(&xpc_partitions[ch->partid].nchannels_active); 1149 atomic_inc(&xpc_partitions[ch->partid].nchannels_active);
1156 } 1150 }
1157 1151
1158 up(&registration->sema); 1152 mutex_unlock(&registration->mutex);
1159 1153
1160 1154
1161 /* initiate the connection */ 1155 /* initiate the connection */
@@ -2089,7 +2083,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
2089 enum xpc_retval ret; 2083 enum xpc_retval ret;
2090 2084
2091 2085
2092 if (down_interruptible(&ch->msg_to_pull_sema) != 0) { 2086 if (mutex_lock_interruptible(&ch->msg_to_pull_mutex) != 0) {
2093 /* we were interrupted by a signal */ 2087 /* we were interrupted by a signal */
2094 return NULL; 2088 return NULL;
2095 } 2089 }
@@ -2125,7 +2119,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
2125 2119
2126 XPC_DEACTIVATE_PARTITION(part, ret); 2120 XPC_DEACTIVATE_PARTITION(part, ret);
2127 2121
2128 up(&ch->msg_to_pull_sema); 2122 mutex_unlock(&ch->msg_to_pull_mutex);
2129 return NULL; 2123 return NULL;
2130 } 2124 }
2131 2125
@@ -2134,7 +2128,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
2134 ch->next_msg_to_pull += nmsgs; 2128 ch->next_msg_to_pull += nmsgs;
2135 } 2129 }
2136 2130
2137 up(&ch->msg_to_pull_sema); 2131 mutex_unlock(&ch->msg_to_pull_mutex);
2138 2132
2139 /* return the message we were looking for */ 2133 /* return the message we were looking for */
2140 msg_offset = (get % ch->remote_nentries) * ch->msg_size; 2134 msg_offset = (get % ch->remote_nentries) * ch->msg_size;