aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorStefan Roscher <stefan.roscher@de.ibm.com>2007-05-09 07:47:56 -0400
committerRoland Dreier <rolandd@cisco.com>2007-05-14 16:38:11 -0400
commit5d88278e3bdb6f2e4ed43306659e930ecd715f0c (patch)
tree60c856cf49531a23c0323a9146818932f62c6766 /drivers/infiniband
parent8f140b407f3be04e7202be9aa0cfef3006d14c9f (diff)
IB/ehca: Serialize hypervisor calls in ehca_register_mr()
Some pSeries hypervisor versions show a race condition in the allocate MR hCall. Serialize this call per adapter to circumvent this problem. Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/ehca/ehca_classes.h1
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c2
-rw-r--r--drivers/infiniband/hw/ehca/hcp_if.c13
3 files changed, 14 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index f64d42b08674..1d286d3cc2d5 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -277,6 +277,7 @@ void ehca_cleanup_mrmw_cache(void);
277 277
278extern spinlock_t ehca_qp_idr_lock; 278extern spinlock_t ehca_qp_idr_lock;
279extern spinlock_t ehca_cq_idr_lock; 279extern spinlock_t ehca_cq_idr_lock;
280extern spinlock_t hcall_lock;
280extern struct idr ehca_qp_idr; 281extern struct idr ehca_qp_idr;
281extern struct idr ehca_cq_idr; 282extern struct idr ehca_cq_idr;
282 283
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index fe90e7454560..b917cc130e48 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -98,6 +98,7 @@ MODULE_PARM_DESC(scaling_code,
98 98
99spinlock_t ehca_qp_idr_lock; 99spinlock_t ehca_qp_idr_lock;
100spinlock_t ehca_cq_idr_lock; 100spinlock_t ehca_cq_idr_lock;
101spinlock_t hcall_lock;
101DEFINE_IDR(ehca_qp_idr); 102DEFINE_IDR(ehca_qp_idr);
102DEFINE_IDR(ehca_cq_idr); 103DEFINE_IDR(ehca_cq_idr);
103 104
@@ -817,6 +818,7 @@ int __init ehca_module_init(void)
817 idr_init(&ehca_cq_idr); 818 idr_init(&ehca_cq_idr);
818 spin_lock_init(&ehca_qp_idr_lock); 819 spin_lock_init(&ehca_qp_idr_lock);
819 spin_lock_init(&ehca_cq_idr_lock); 820 spin_lock_init(&ehca_cq_idr_lock);
821 spin_lock_init(&hcall_lock);
820 822
821 INIT_LIST_HEAD(&shca_list); 823 INIT_LIST_HEAD(&shca_list);
822 spin_lock_init(&shca_list_lock); 824 spin_lock_init(&shca_list_lock);
diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c
index b564fcd3b282..7f0beec74f70 100644
--- a/drivers/infiniband/hw/ehca/hcp_if.c
+++ b/drivers/infiniband/hw/ehca/hcp_if.c
@@ -154,7 +154,8 @@ static long ehca_plpar_hcall9(unsigned long opcode,
154 unsigned long arg9) 154 unsigned long arg9)
155{ 155{
156 long ret; 156 long ret;
157 int i, sleep_msecs; 157 int i, sleep_msecs, lock_is_set = 0;
158 unsigned long flags;
158 159
159 ehca_gen_dbg("opcode=%lx arg1=%lx arg2=%lx arg3=%lx arg4=%lx " 160 ehca_gen_dbg("opcode=%lx arg1=%lx arg2=%lx arg3=%lx arg4=%lx "
160 "arg5=%lx arg6=%lx arg7=%lx arg8=%lx arg9=%lx", 161 "arg5=%lx arg6=%lx arg7=%lx arg8=%lx arg9=%lx",
@@ -162,10 +163,18 @@ static long ehca_plpar_hcall9(unsigned long opcode,
162 arg8, arg9); 163 arg8, arg9);
163 164
164 for (i = 0; i < 5; i++) { 165 for (i = 0; i < 5; i++) {
166 if ((opcode == H_ALLOC_RESOURCE) && (arg2 == 5)) {
167 spin_lock_irqsave(&hcall_lock, flags);
168 lock_is_set = 1;
169 }
170
165 ret = plpar_hcall9(opcode, outs, 171 ret = plpar_hcall9(opcode, outs,
166 arg1, arg2, arg3, arg4, arg5, 172 arg1, arg2, arg3, arg4, arg5,
167 arg6, arg7, arg8, arg9); 173 arg6, arg7, arg8, arg9);
168 174
175 if (lock_is_set)
176 spin_unlock_irqrestore(&hcall_lock, flags);
177
169 if (H_IS_LONG_BUSY(ret)) { 178 if (H_IS_LONG_BUSY(ret)) {
170 sleep_msecs = get_longbusy_msecs(ret); 179 sleep_msecs = get_longbusy_msecs(ret);
171 msleep_interruptible(sleep_msecs); 180 msleep_interruptible(sleep_msecs);
@@ -193,11 +202,11 @@ static long ehca_plpar_hcall9(unsigned long opcode,
193 opcode, ret, outs[0], outs[1], outs[2], outs[3], 202 opcode, ret, outs[0], outs[1], outs[2], outs[3],
194 outs[4], outs[5], outs[6], outs[7], outs[8]); 203 outs[4], outs[5], outs[6], outs[7], outs[8]);
195 return ret; 204 return ret;
196
197 } 205 }
198 206
199 return H_BUSY; 207 return H_BUSY;
200} 208}
209
201u64 hipz_h_alloc_resource_eq(const struct ipz_adapter_handle adapter_handle, 210u64 hipz_h_alloc_resource_eq(const struct ipz_adapter_handle adapter_handle,
202 struct ehca_pfeq *pfeq, 211 struct ehca_pfeq *pfeq,
203 const u32 neq_control, 212 const u32 neq_control,