diff options
authorThadeu Lima de Souza Cascardo2013-04-01 15:13:39 -0500
committerGreg Kroah-Hartman2013-05-11 15:53:58 -0500
commit1d3a7eb266a154bbb90da4c7a9b992c4a3d75c22 (patch)
parent7f9cc57937dfbe59c25f66e801bfecf5cb0de031 (diff)
RDMA/cxgb4: Fix SQ allocation when on-chip SQ is disabled
commit 5b0c275926b8149c555da874bb4ec258ea3292aa upstream. Commit c079c28714e4 ("RDMA/cxgb4: Fix error handling in create_qp()") broke SQ allocation. Instead of falling back to host allocation when on-chip allocation fails, it tries to allocate both. And when it does, and we try to free the address from the genpool using the host address, we hit a BUG and the system crashes as below. We create a new function that has the previous behavior and properly propagate the error, as intended. kernel BUG at /usr/src/packages/BUILD/kernel-ppc64-3.0.68/linux-3.0/lib/genalloc.c:340! Oops: Exception in kernel mode, sig: 5 [#1] SMP NR_CPUS=1024 NUMA pSeries Modules linked in: rdma_ucm rdma_cm ib_addr ib_cm iw_cm ib_sa ib_mad ib_uverbs iw_cxgb4 ib_core ip6t_LOG xt_tcpudp xt_pkttype ipt_LOG xt_limit ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_raw xt_NOTRACK ipt_REJECT xt_state iptable_raw iptable_filter ip6table_mangle nf_conntrack_netbios_ns nf_conntrack_broadcast nf_conntrack_ipv4 nf_conntrack nf_defrag_ipv4 ip_tables ip6table_filter ip6_tables x_tables fuse loop dm_mod ipv6 ipv6_lib sr_mod cdrom ibmveth(X) cxgb4 sg ext3 jbd mbcache sd_mod crc_t10dif scsi_dh_emc scsi_dh_hp_sw scsi_dh_alua scsi_dh_rdac scsi_dh ibmvscsic(X) scsi_transport_srp scsi_tgt scsi_mod Supported: Yes NIP: c00000000037d41c LR: d000000003913824 CTR: c00000000037d3b0 REGS: c0000001f350ae50 TRAP: 0700 Tainted: G X (3.0.68-0.9-ppc64) MSR: 8000000000029032 <EE,ME,CE,IR,DR> CR: 24042482 XER: 00000001 TASK = c0000001f6f2a840[3616] 'rping' THREAD: c0000001f3508000 CPU: 0 GPR00: c0000001f6e875c8 c0000001f350b0d0 c000000000fc9690 c0000001f6e875c0 GPR04: 00000000000c0000 0000000000010000 0000000000000000 c0000000009d482a GPR08: 000000006a170000 0000000000100000 c0000001f350b140 c0000001f6e875c8 GPR12: d000000003915dd0 c000000003f40000 000000003e3ecfa8 c0000001f350bea0 GPR16: c0000001f350bcd0 00000000003c0000 0000000000040100 c0000001f6e74a80 GPR20: d00000000399a898 c0000001f6e74ac8 c0000001fad91600 c0000001f6e74ab0 GPR24: c0000001f7d23f80 0000000000000000 0000000000000002 000000006a170000 GPR28: 000000000000000c c0000001f584c8d0 d000000003925180 c0000001f6e875c8 NIP [c00000000037d41c] .gen_pool_free+0x6c/0xf8 LR [d000000003913824] .c4iw_ocqp_pool_free+0x8c/0xd8 [iw_cxgb4] Call Trace: [c0000001f350b0d0] [c0000001f350b180] 0xc0000001f350b180 (unreliable) [c0000001f350b170] [d000000003913824] .c4iw_ocqp_pool_free+0x8c/0xd8 [iw_cxgb4] [c0000001f350b210] [d00000000390fd70] .dealloc_sq+0x90/0xb0 [iw_cxgb4] [c0000001f350b280] [d00000000390fe08] .destroy_qp+0x78/0xf8 [iw_cxgb4] [c0000001f350b310] [d000000003912738] .c4iw_destroy_qp+0x208/0x2d0 [iw_cxgb4] [c0000001f350b460] [d000000003861874] .ib_destroy_qp+0x5c/0x130 [ib_core] [c0000001f350b510] [d0000000039911bc] .ib_uverbs_cleanup_ucontext+0x174/0x4f8 [ib_uverbs] [c0000001f350b5f0] [d000000003991568] .ib_uverbs_close+0x28/0x70 [ib_uverbs] [c0000001f350b670] [c0000000001e7b2c] .__fput+0xdc/0x278 [c0000001f350b720] [c0000000001a9590] .remove_vma+0x68/0xd8 [c0000001f350b7b0] [c0000000001a9720] .exit_mmap+0x120/0x160 [c0000001f350b8d0] [c0000000000af330] .mmput+0x80/0x160 [c0000001f350b960] [c0000000000b5d0c] .exit_mm+0x1ac/0x1e8 [c0000001f350ba10] [c0000000000b8154] .do_exit+0x1b4/0x4b8 [c0000001f350bad0] [c0000000000b84b0] .do_group_exit+0x58/0xf8 [c0000001f350bb60] [c0000000000ce9f4] .get_signal_to_deliver+0x2f4/0x5d0 [c0000001f350bc60] [c000000000017ee4] .do_signal_pending+0x6c/0x3e0 [c0000001f350bdb0] [c0000000000182cc] .do_signal+0x74/0x78 [c0000001f350be30] [c000000000009e74] do_work+0x24/0x28 Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com> Cc: Emil Goode <emilgoode@gmail.com> Acked-by: Steve Wise <swise@opengridcomputing.com> Signed-off-by: Roland Dreier <roland@purestorage.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 files changed, 13 insertions, 12 deletions
diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c
index 05bfe53bff64..892cd872733c 100644
--- a/drivers/infiniband/hw/cxgb4/qp.c
+++ b/drivers/infiniband/hw/cxgb4/qp.c
@@ -100,6 +100,16 @@ static int alloc_host_sq(struct c4iw_rdev *rdev, struct t4_sq *sq)
100 return 0; 100 return 0;
101} 101}
102 102
103static int alloc_sq(struct c4iw_rdev *rdev, struct t4_sq *sq, int user)
105 int ret = -ENOSYS;
106 if (user)
107 ret = alloc_oc_sq(rdev, sq);
108 if (ret)
109 ret = alloc_host_sq(rdev, sq);
110 return ret;
103static int destroy_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, 113static int destroy_qp(struct c4iw_rdev *rdev, struct t4_wq *wq,
104 struct c4iw_dev_ucontext *uctx) 114 struct c4iw_dev_ucontext *uctx)
105{ 115{
@@ -168,18 +178,9 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq,
168 goto free_sw_rq; 178 goto free_sw_rq;
169 } 179 }
170 180
171 if (user) { 181 ret = alloc_sq(rdev, &wq->sq, user);
172 ret = alloc_oc_sq(rdev, &wq->sq); 182 if (ret)
173 if (ret) 183 goto free_hwaddr;
174 goto free_hwaddr;
176 ret = alloc_host_sq(rdev, &wq->sq);
177 if (ret)
178 goto free_sq;
179 } else
180 ret = alloc_host_sq(rdev, &wq->sq);
181 if (ret)
182 goto free_hwaddr;
183 memset(wq->sq.queue, 0, wq->sq.memsize); 184 memset(wq->sq.queue, 0, wq->sq.memsize);
184 dma_unmap_addr_set(&wq->sq, mapping, wq->sq.dma_addr); 185 dma_unmap_addr_set(&wq->sq, mapping, wq->sq.dma_addr);
185 186