History

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma

Pull rdma fixes from Doug Ledford: - Various driver bug fixes in mlx5, mlx4, bnxt_re and qedr, ranging from bugs under load to bad error case handling - There in one largish patch fixing the locking in bnxt_re to avoid a machine hard lock situation - A few core bugs on error paths - A patch to reduce stack usage in the new CQ API - One mlx5 regression introduced in this merge window - There were new syzkaller scripts written for the RDMA subsystem and we are fixing issues found by the bot - One of the commits (aa0de36a40f4 “RDMA/mlx5: Fix integer overflow while resizing CQ”) is missing part of the commit log message and one of the SOB lines. The original patch was from Leon Romanovsky, and a cut-n-paste separator in the commit message confused patchworks which then put the end of message separator in the wrong place in the downloaded patch, and I didn’t notice in time. The patch made it into the official branch, and the only way to fix it in-place was to rebase. Given the pain that a rebase causes, and the fact that the patch has relevant tags for stable and syzkaller, a revert of the munged patch and a reapplication of the original patch with the log message intact was done. * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: (25 commits) RDMA/mlx5: Fix integer overflow while resizing CQ Revert "RDMA/mlx5: Fix integer overflow while resizing CQ" RDMA/ucma: Check that user doesn't overflow QP state RDMA/mlx5: Fix integer overflow while resizing CQ RDMA/ucma: Limit possible option size IB/core: Fix possible crash to access NULL netdev RDMA/bnxt_re: Avoid Hard lockup during error CQE processing RDMA/core: Reduce poll batch for direct cq polling IB/mlx5: Fix an error code in __mlx5_ib_modify_qp() IB/mlx5: When not in dual port RoCE mode, use provided port as native IB/mlx4: Include GID type when deleting GIDs from HW table under RoCE IB/mlx4: Fix corruption of RoCEv2 IPv4 GIDs RDMA/qedr: Fix iWARP write and send with immediate RDMA/qedr: Fix kernel panic when running fio over NFSoRDMA RDMA/qedr: Fix iWARP connect with port mapper RDMA/qedr: Fix ipv6 destination address resolution IB/core : Add null pointer check in addr_resolve RDMA/bnxt_re: Fix the ib_reg failure cleanup RDMA/bnxt_re: Fix incorrect DB offset calculation RDMA/bnxt_re: Unconditionly fence non wire memory operations ...

Linus Torvalds committed 8 years ago

Commit 2f64e702 parents b3337a6 28e909123 files · +192 −156Browse files

Unified · Split

23 files
  1. drivers/infiniband/core/addr.c +5 −10
  2. drivers/infiniband/core/cq.c +11 −10
  3. drivers/infiniband/core/device.c +4 −2
  4. drivers/infiniband/core/sa_query.c +3 −4
  5. drivers/infiniband/core/ucma.c +6 −0
  6. drivers/infiniband/hw/bnxt_re/ib_verbs.c +19 −7
  7. drivers/infiniband/hw/bnxt_re/ib_verbs.h +3 −0
  8. drivers/infiniband/hw/bnxt_re/main.c +11 −1
  9. drivers/infiniband/hw/bnxt_re/qplib_fp.c +24 −85
  10. drivers/infiniband/hw/bnxt_re/qplib_fp.h +12 −0
  11. drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +6 −3
  12. drivers/infiniband/hw/bnxt_re/qplib_rcfw.h +1 −0
  13. drivers/infiniband/hw/bnxt_re/qplib_sp.c +2 −1
  14. drivers/infiniband/hw/bnxt_re/roce_hsi.h +24 −1
  15. drivers/infiniband/hw/mlx4/cq.c +3 −1
  16. drivers/infiniband/hw/mlx4/main.c +7 −4
  17. drivers/infiniband/hw/mlx5/cq.c +8 −2
  18. drivers/infiniband/hw/mlx5/main.c +9 −12
  19. drivers/infiniband/hw/mlx5/mr.c +1 −1
  20. drivers/infiniband/hw/mlx5/qp.c +9 −2
  21. drivers/infiniband/hw/qedr/qedr_iw_cm.c +11 −8
  22. drivers/infiniband/hw/qedr/verbs.c +12 −1
  23. drivers/net/ethernet/mellanox/mlx5/core/health.c +1 −1
drivers/infiniband/core/addr.c+5−10
@@ -550,18 +550,13 @@ static int addr_resolve(struct sockaddr *src_in, · 549 unmodified lines
550 dst_release(dst);550 dst_release(dst);
551 }551 }
552 552
553 if (ndev->flags & IFF_LOOPBACK) {553 if (ndev) {
554 ret = rdma_translate_ip(dst_in, addr);554 if (ndev->flags & IFF_LOOPBACK)
555 /*555 ret = rdma_translate_ip(dst_in, addr);
556 * Put the loopback device and get the translated556 else
557 * device instead.557 addr->bound_dev_if = ndev->ifindex;
558 */
559 dev_put(ndev);558 dev_put(ndev);
560 ndev = dev_get_by_index(addr->net, addr->bound_dev_if);
561 } else {
562 addr->bound_dev_if = ndev->ifindex;
563 }559 }
564 dev_put(ndev);
565 560
566 return ret;561 return ret;
567}562}
drivers/infiniband/core/cq.c+11−10
@@ -17,6 +17,7 @@ · 16 unmodified lines
17 17
18/* # of WCs to poll for with a single call to ib_poll_cq */18/* # of WCs to poll for with a single call to ib_poll_cq */
19#define IB_POLL_BATCH 1619#define IB_POLL_BATCH 16
20#define IB_POLL_BATCH_DIRECT 8
20 21
21/* # of WCs to iterate over before yielding */22/* # of WCs to iterate over before yielding */
22#define IB_POLL_BUDGET_IRQ 25623#define IB_POLL_BUDGET_IRQ 256
@@ -25,18 +26,18 @@ · 2 unmodified lines
25#define IB_POLL_FLAGS \26#define IB_POLL_FLAGS \
26 (IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS)27 (IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS)
27 28
28static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *poll_wc)29static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *wcs,
30 int batch)
29{31{
30 int i, n, completed = 0;32 int i, n, completed = 0;
31 struct ib_wc *wcs = poll_wc ? : cq->wc;
32 33
33 /*34 /*
34 * budget might be (-1) if the caller does not35 * budget might be (-1) if the caller does not
35 * want to bound this call, thus we need unsigned36 * want to bound this call, thus we need unsigned
36 * minimum here.37 * minimum here.
37 */38 */
38 while ((n = ib_poll_cq(cq, min_t(u32, IB_POLL_BATCH,39 while ((n = ib_poll_cq(cq, min_t(u32, batch,
39 budget - completed), wcs)) > 0) {40 budget - completed), wcs)) > 0) {
40 for (i = 0; i < n; i++) {41 for (i = 0; i < n; i++) {
41 struct ib_wc *wc = &wcs[i];42 struct ib_wc *wc = &wcs[i];
42 43
@@ -48,8 +49,7 @@ static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *poll_wc) · 5 unmodified lines
48 49
49 completed += n;50 completed += n;
50 51
51 if (n != IB_POLL_BATCH ||52 if (n != batch || (budget != -1 && completed >= budget))
52 (budget != -1 && completed >= budget))
53 break;53 break;
54 }54 }
55 55
@@ -72,9 +72,9 @@ static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *poll_wc) · 16 unmodified lines
72 */72 */
73int ib_process_cq_direct(struct ib_cq *cq, int budget)73int ib_process_cq_direct(struct ib_cq *cq, int budget)
74{74{
75 struct ib_wc wcs[IB_POLL_BATCH];75 struct ib_wc wcs[IB_POLL_BATCH_DIRECT];
76 76
77 return __ib_process_cq(cq, budget, wcs);77 return __ib_process_cq(cq, budget, wcs, IB_POLL_BATCH_DIRECT);
78}78}
79EXPORT_SYMBOL(ib_process_cq_direct);79EXPORT_SYMBOL(ib_process_cq_direct);
80 80
@@ -88,7 +88,7 @@ static int ib_poll_handler(struct irq_poll *iop, int budget) · 7 unmodified lines
88 struct ib_cq *cq = container_of(iop, struct ib_cq, iop);88 struct ib_cq *cq = container_of(iop, struct ib_cq, iop);
89 int completed;89 int completed;
90 90
91 completed = __ib_process_cq(cq, budget, NULL);91 completed = __ib_process_cq(cq, budget, cq->wc, IB_POLL_BATCH);
92 if (completed < budget) {92 if (completed < budget) {
93 irq_poll_complete(&cq->iop);93 irq_poll_complete(&cq->iop);
94 if (ib_req_notify_cq(cq, IB_POLL_FLAGS) > 0)94 if (ib_req_notify_cq(cq, IB_POLL_FLAGS) > 0)
@@ -108,7 +108,8 @@ static void ib_cq_poll_work(struct work_struct *work) · 13 unmodified lines
108 struct ib_cq *cq = container_of(work, struct ib_cq, work);108 struct ib_cq *cq = container_of(work, struct ib_cq, work);
109 int completed;109 int completed;
110 110
111 completed = __ib_process_cq(cq, IB_POLL_BUDGET_WORKQUEUE, NULL);111 completed = __ib_process_cq(cq, IB_POLL_BUDGET_WORKQUEUE, cq->wc,
112 IB_POLL_BATCH);
112 if (completed >= IB_POLL_BUDGET_WORKQUEUE ||113 if (completed >= IB_POLL_BUDGET_WORKQUEUE ||
113 ib_req_notify_cq(cq, IB_POLL_FLAGS) > 0)114 ib_req_notify_cq(cq, IB_POLL_FLAGS) > 0)
114 queue_work(ib_comp_wq, &cq->work);115 queue_work(ib_comp_wq, &cq->work);
drivers/infiniband/core/device.c+4−2
@@ -536,14 +536,14 @@ int ib_register_device(struct ib_device *device, · 535 unmodified lines
536 ret = device->query_device(device, &device->attrs, &uhw);536 ret = device->query_device(device, &device->attrs, &uhw);
537 if (ret) {537 if (ret) {
538 pr_warn("Couldn't query the device attributes\n");538 pr_warn("Couldn't query the device attributes\n");
539 goto cache_cleanup;539 goto cg_cleanup;
540 }540 }
541 541
542 ret = ib_device_register_sysfs(device, port_callback);542 ret = ib_device_register_sysfs(device, port_callback);
543 if (ret) {543 if (ret) {
544 pr_warn("Couldn't register device %s with driver model\n",544 pr_warn("Couldn't register device %s with driver model\n",
545 device->name);545 device->name);
546 goto cache_cleanup;546 goto cg_cleanup;
547 }547 }
548 548
549 device->reg_state = IB_DEV_REGISTERED;549 device->reg_state = IB_DEV_REGISTERED;
@@ -559,6 +559,8 @@ int ib_register_device(struct ib_device *device, · 9 unmodified lines
559 mutex_unlock(&device_mutex);559 mutex_unlock(&device_mutex);
560 return 0;560 return 0;
561 561
562cg_cleanup:
563 ib_device_unregister_rdmacg(device);
562cache_cleanup:564cache_cleanup:
563 ib_cache_cleanup_one(device);565 ib_cache_cleanup_one(device);
564 ib_cache_release_one(device);566 ib_cache_release_one(device);
drivers/infiniband/core/sa_query.c+3−4
@@ -1291,10 +1291,9 @@ int ib_init_ah_attr_from_path(struct ib_device *device, u8 port_num, · 1290 unmodified lines
1291 1291
1292 resolved_dev = dev_get_by_index(dev_addr.net,1292 resolved_dev = dev_get_by_index(dev_addr.net,
1293 dev_addr.bound_dev_if);1293 dev_addr.bound_dev_if);
1294 if (resolved_dev->flags & IFF_LOOPBACK) {1294 if (!resolved_dev) {
1295 dev_put(resolved_dev);1295 dev_put(idev);
1296 resolved_dev = idev;1296 return -ENODEV;
1297 dev_hold(resolved_dev);
1298 }1297 }
1299 ndev = ib_get_ndev_from_path(rec);1298 ndev = ib_get_ndev_from_path(rec);
1300 rcu_read_lock();1299 rcu_read_lock();
drivers/infiniband/core/ucma.c+6−0
@@ -1149,6 +1149,9 @@ static ssize_t ucma_init_qp_attr(struct ucma_file *file, · 1148 unmodified lines
1149 if (copy_from_user(&cmd, inbuf, sizeof(cmd)))1149 if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
1150 return -EFAULT;1150 return -EFAULT;
1151 1151
1152 if (cmd.qp_state > IB_QPS_ERR)
1153 return -EINVAL;
1154
1152 ctx = ucma_get_ctx(file, cmd.id);1155 ctx = ucma_get_ctx(file, cmd.id);
1153 if (IS_ERR(ctx))1156 if (IS_ERR(ctx))
1154 return PTR_ERR(ctx);1157 return PTR_ERR(ctx);
@@ -1294,6 +1297,9 @@ static ssize_t ucma_set_option(struct ucma_file *file, const char __user *inbuf, · 139 unmodified lines
1294 if (IS_ERR(ctx))1297 if (IS_ERR(ctx))
1295 return PTR_ERR(ctx);1298 return PTR_ERR(ctx);
1296 1299
1300 if (unlikely(cmd.optval > KMALLOC_MAX_SIZE))
1301 return -EINVAL;
1302
1297 optval = memdup_user((void __user *) (unsigned long) cmd.optval,1303 optval = memdup_user((void __user *) (unsigned long) cmd.optval,
1298 cmd.optlen);1304 cmd.optlen);
1299 if (IS_ERR(optval)) {1305 if (IS_ERR(optval)) {
drivers/infiniband/hw/bnxt_re/ib_verbs.c+19−7
@@ -785,7 +785,7 @@ int bnxt_re_query_ah(struct ib_ah *ib_ah, struct rdma_ah_attr *ah_attr) · 784 unmodified lines
785 return 0;785 return 0;
786}786}
787 787
788static unsigned long bnxt_re_lock_cqs(struct bnxt_re_qp *qp)788unsigned long bnxt_re_lock_cqs(struct bnxt_re_qp *qp)
789 __acquires(&qp->scq->cq_lock) __acquires(&qp->rcq->cq_lock)789 __acquires(&qp->scq->cq_lock) __acquires(&qp->rcq->cq_lock)
790{790{
791 unsigned long flags;791 unsigned long flags;
@@ -799,8 +799,8 @@ static unsigned long bnxt_re_lock_cqs(struct bnxt_re_qp *qp) · 7 unmodified lines
799 return flags;799 return flags;
800}800}
801 801
802static void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp,802void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp,
803 unsigned long flags)803 unsigned long flags)
804 __releases(&qp->scq->cq_lock) __releases(&qp->rcq->cq_lock)804 __releases(&qp->scq->cq_lock) __releases(&qp->rcq->cq_lock)
805{805{
806 if (qp->rcq != qp->scq)806 if (qp->rcq != qp->scq)
@@ -1606,6 +1606,7 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr, · 799 unmodified lines
1606 int status;1606 int status;
1607 union ib_gid sgid;1607 union ib_gid sgid;
1608 struct ib_gid_attr sgid_attr;1608 struct ib_gid_attr sgid_attr;
1609 unsigned int flags;
1609 u8 nw_type;1610 u8 nw_type;
1610 1611
1611 qp->qplib_qp.modify_flags = 0;1612 qp->qplib_qp.modify_flags = 0;
@@ -1634,14 +1635,18 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr, · 22 unmodified lines
1634 dev_dbg(rdev_to_dev(rdev),1635 dev_dbg(rdev_to_dev(rdev),
1635 "Move QP = %p to flush list\n",1636 "Move QP = %p to flush list\n",
1636 qp);1637 qp);
1638 flags = bnxt_re_lock_cqs(qp);
1637 bnxt_qplib_add_flush_qp(&qp->qplib_qp);1639 bnxt_qplib_add_flush_qp(&qp->qplib_qp);
1640 bnxt_re_unlock_cqs(qp, flags);
1638 }1641 }
1639 if (!qp->sumem &&1642 if (!qp->sumem &&
1640 qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_RESET) {1643 qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_RESET) {
1641 dev_dbg(rdev_to_dev(rdev),1644 dev_dbg(rdev_to_dev(rdev),
1642 "Move QP = %p out of flush list\n",1645 "Move QP = %p out of flush list\n",
1643 qp);1646 qp);
1647 flags = bnxt_re_lock_cqs(qp);
1644 bnxt_qplib_clean_qp(&qp->qplib_qp);1648 bnxt_qplib_clean_qp(&qp->qplib_qp);
1649 bnxt_re_unlock_cqs(qp, flags);
1645 }1650 }
1646 }1651 }
1647 if (qp_attr_mask & IB_QP_EN_SQD_ASYNC_NOTIFY) {1652 if (qp_attr_mask & IB_QP_EN_SQD_ASYNC_NOTIFY) {
@@ -2227,10 +2232,13 @@ static int bnxt_re_build_inv_wqe(struct ib_send_wr *wr, · 579 unmodified lines
2227 wqe->type = BNXT_QPLIB_SWQE_TYPE_LOCAL_INV;2232 wqe->type = BNXT_QPLIB_SWQE_TYPE_LOCAL_INV;
2228 wqe->local_inv.inv_l_key = wr->ex.invalidate_rkey;2233 wqe->local_inv.inv_l_key = wr->ex.invalidate_rkey;
2229 2234
2235 /* Need unconditional fence for local invalidate
2236 * opcode to work as expected.
2237 */
2238 wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_UC_FENCE;
2239
2230 if (wr->send_flags & IB_SEND_SIGNALED)2240 if (wr->send_flags & IB_SEND_SIGNALED)
2231 wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_SIGNAL_COMP;2241 wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_SIGNAL_COMP;
2232 if (wr->send_flags & IB_SEND_FENCE)
2233 wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_UC_FENCE;
2234 if (wr->send_flags & IB_SEND_SOLICITED)2242 if (wr->send_flags & IB_SEND_SOLICITED)
2235 wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_SOLICIT_EVENT;2243 wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_SOLICIT_EVENT;
2236 2244
@@ -2251,8 +2259,12 @@ static int bnxt_re_build_reg_wqe(struct ib_reg_wr *wr, · 14 unmodified lines
2251 wqe->frmr.levels = qplib_frpl->hwq.level + 1;2259 wqe->frmr.levels = qplib_frpl->hwq.level + 1;
2252 wqe->type = BNXT_QPLIB_SWQE_TYPE_REG_MR;2260 wqe->type = BNXT_QPLIB_SWQE_TYPE_REG_MR;
2253 2261
2254 if (wr->wr.send_flags & IB_SEND_FENCE)2262 /* Need unconditional fence for reg_mr
2255 wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_UC_FENCE;2263 * opcode to function as expected.
2264 */
2265
2266 wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_UC_FENCE;
2267
2256 if (wr->wr.send_flags & IB_SEND_SIGNALED)2268 if (wr->wr.send_flags & IB_SEND_SIGNALED)
2257 wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_SIGNAL_COMP;2269 wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_SIGNAL_COMP;
2258 2270
drivers/infiniband/hw/bnxt_re/ib_verbs.h+3−0
@@ -222,4 +222,7 @@ struct ib_ucontext *bnxt_re_alloc_ucontext(struct ib_device *ibdev, · 221 unmodified lines
222 struct ib_udata *udata);222 struct ib_udata *udata);
223int bnxt_re_dealloc_ucontext(struct ib_ucontext *context);223int bnxt_re_dealloc_ucontext(struct ib_ucontext *context);
224int bnxt_re_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);224int bnxt_re_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);
225
226unsigned long bnxt_re_lock_cqs(struct bnxt_re_qp *qp);
227void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp, unsigned long flags);
225#endif /* __BNXT_RE_IB_VERBS_H__ */228#endif /* __BNXT_RE_IB_VERBS_H__ */
drivers/infiniband/hw/bnxt_re/main.c+11−1
@@ -730,6 +730,13 @@ static int bnxt_re_handle_qp_async_event(struct creq_qp_event *qp_event, · 729 unmodified lines
730 struct bnxt_re_qp *qp)730 struct bnxt_re_qp *qp)
731{731{
732 struct ib_event event;732 struct ib_event event;
733 unsigned int flags;
734
735 if (qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_ERR) {
736 flags = bnxt_re_lock_cqs(qp);
737 bnxt_qplib_add_flush_qp(&qp->qplib_qp);
738 bnxt_re_unlock_cqs(qp, flags);
739 }
733 740
734 memset(&event, 0, sizeof(event));741 memset(&event, 0, sizeof(event));
735 if (qp->qplib_qp.srq) {742 if (qp->qplib_qp.srq) {
@@ -1416,9 +1423,12 @@ static void bnxt_re_task(struct work_struct *work) · 680 unmodified lines
1416 switch (re_work->event) {1423 switch (re_work->event) {
1417 case NETDEV_REGISTER:1424 case NETDEV_REGISTER:
1418 rc = bnxt_re_ib_reg(rdev);1425 rc = bnxt_re_ib_reg(rdev);
1419 if (rc)1426 if (rc) {
1420 dev_err(rdev_to_dev(rdev),1427 dev_err(rdev_to_dev(rdev),
1421 "Failed to register with IB: %#x", rc);1428 "Failed to register with IB: %#x", rc);
1429 bnxt_re_remove_one(rdev);
1430 bnxt_re_dev_unreg(rdev);
1431 }
1422 break;1432 break;
1423 case NETDEV_UP:1433 case NETDEV_UP:
1424 bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1,1434 bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1,
drivers/infiniband/hw/bnxt_re/qplib_fp.c+24−85
@@ -88,75 +88,35 @@ static void __bnxt_qplib_add_flush_qp(struct bnxt_qplib_qp *qp) · 87 unmodified lines
88 }88 }
89}89}
90 90
91void bnxt_qplib_acquire_cq_locks(struct bnxt_qplib_qp *qp,91static void bnxt_qplib_acquire_cq_flush_locks(struct bnxt_qplib_qp *qp,
92 unsigned long *flags)92 unsigned long *flags)
93 __acquires(&qp->scq->hwq.lock) __acquires(&qp->rcq->hwq.lock)93 __acquires(&qp->scq->flush_lock) __acquires(&qp->rcq->flush_lock)
94{94{
95 spin_lock_irqsave(&qp->scq->hwq.lock, *flags);95 spin_lock_irqsave(&qp->scq->flush_lock, *flags);
96 if (qp->scq == qp->rcq)96 if (qp->scq == qp->rcq)
97 __acquire(&qp->rcq->hwq.lock);97 __acquire(&qp->rcq->flush_lock);
98 else98 else
99 spin_lock(&qp->rcq->hwq.lock);99 spin_lock(&qp->rcq->flush_lock);
100}100}
101 101
102void bnxt_qplib_release_cq_locks(struct bnxt_qplib_qp *qp,102static void bnxt_qplib_release_cq_flush_locks(struct bnxt_qplib_qp *qp,
103 unsigned long *flags)103 unsigned long *flags)
104 __releases(&qp->scq->hwq.lock) __releases(&qp->rcq->hwq.lock)104 __releases(&qp->scq->flush_lock) __releases(&qp->rcq->flush_lock)
105{105{
106 if (qp->scq == qp->rcq)106 if (qp->scq == qp->rcq)
107 __release(&qp->rcq->hwq.lock);107 __release(&qp->rcq->flush_lock);
108 else108 else
109 spin_unlock(&qp->rcq->hwq.lock);109 spin_unlock(&qp->rcq->flush_lock);
110 spin_unlock_irqrestore(&qp->scq->hwq.lock, *flags);110 spin_unlock_irqrestore(&qp->scq->flush_lock, *flags);
111}
112
113static struct bnxt_qplib_cq *bnxt_qplib_find_buddy_cq(struct bnxt_qplib_qp *qp,
114 struct bnxt_qplib_cq *cq)
115{
116 struct bnxt_qplib_cq *buddy_cq = NULL;
117
118 if (qp->scq == qp->rcq)
119 buddy_cq = NULL;
120 else if (qp->scq == cq)
121 buddy_cq = qp->rcq;
122 else
123 buddy_cq = qp->scq;
124 return buddy_cq;
125}
126
127static void bnxt_qplib_lock_buddy_cq(struct bnxt_qplib_qp *qp,
128 struct bnxt_qplib_cq *cq)
129 __acquires(&buddy_cq->hwq.lock)
130{
131 struct bnxt_qplib_cq *buddy_cq = NULL;
132
133 buddy_cq = bnxt_qplib_find_buddy_cq(qp, cq);
134 if (!buddy_cq)
135 __acquire(&cq->hwq.lock);
136 else
137 spin_lock(&buddy_cq->hwq.lock);
138}
139
140static void bnxt_qplib_unlock_buddy_cq(struct bnxt_qplib_qp *qp,
141 struct bnxt_qplib_cq *cq)
142 __releases(&buddy_cq->hwq.lock)
143{
144 struct bnxt_qplib_cq *buddy_cq = NULL;
145
146 buddy_cq = bnxt_qplib_find_buddy_cq(qp, cq);
147 if (!buddy_cq)
148 __release(&cq->hwq.lock);
149 else
150 spin_unlock(&buddy_cq->hwq.lock);
151}111}
152 112
153void bnxt_qplib_add_flush_qp(struct bnxt_qplib_qp *qp)113void bnxt_qplib_add_flush_qp(struct bnxt_qplib_qp *qp)
154{114{
155 unsigned long flags;115 unsigned long flags;
156 116
157 bnxt_qplib_acquire_cq_locks(qp, &flags);117 bnxt_qplib_acquire_cq_flush_locks(qp, &flags);
158 __bnxt_qplib_add_flush_qp(qp);118 __bnxt_qplib_add_flush_qp(qp);
159 bnxt_qplib_release_cq_locks(qp, &flags);119 bnxt_qplib_release_cq_flush_locks(qp, &flags);
160}120}
161 121
162static void __bnxt_qplib_del_flush_qp(struct bnxt_qplib_qp *qp)122static void __bnxt_qplib_del_flush_qp(struct bnxt_qplib_qp *qp)
@@ -177,7 +137,7 @@ void bnxt_qplib_clean_qp(struct bnxt_qplib_qp *qp) · 14 unmodified lines
177{137{
178 unsigned long flags;138 unsigned long flags;
179 139
180 bnxt_qplib_acquire_cq_locks(qp, &flags);140 bnxt_qplib_acquire_cq_flush_locks(qp, &flags);
181 __clean_cq(qp->scq, (u64)(unsigned long)qp);141 __clean_cq(qp->scq, (u64)(unsigned long)qp);
182 qp->sq.hwq.prod = 0;142 qp->sq.hwq.prod = 0;
183 qp->sq.hwq.cons = 0;143 qp->sq.hwq.cons = 0;
@@ -186,7 +146,7 @@ void bnxt_qplib_clean_qp(struct bnxt_qplib_qp *qp) · 2 unmodified lines
186 qp->rq.hwq.cons = 0;146 qp->rq.hwq.cons = 0;
187 147
188 __bnxt_qplib_del_flush_qp(qp);148 __bnxt_qplib_del_flush_qp(qp);
189 bnxt_qplib_release_cq_locks(qp, &flags);149 bnxt_qplib_release_cq_flush_locks(qp, &flags);
190}150}
191 151
192static void bnxt_qpn_cqn_sched_task(struct work_struct *work)152static void bnxt_qpn_cqn_sched_task(struct work_struct *work)
@@ -2107,9 +2067,6 @@ void bnxt_qplib_mark_qp_error(void *qp_handle) · 1914 unmodified lines
2107 /* Must block new posting of SQ and RQ */2067 /* Must block new posting of SQ and RQ */
2108 qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;2068 qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;
2109 bnxt_qplib_cancel_phantom_processing(qp);2069 bnxt_qplib_cancel_phantom_processing(qp);
2110
2111 /* Add qp to flush list of the CQ */
2112 __bnxt_qplib_add_flush_qp(qp);
2113}2070}
2114 2071
2115/* Note: SQE is valid from sw_sq_cons up to cqe_sq_cons (exclusive)2072/* Note: SQE is valid from sw_sq_cons up to cqe_sq_cons (exclusive)
@@ -2285,9 +2242,9 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq, · 169 unmodified lines
2285 sw_sq_cons, cqe->wr_id, cqe->status);2242 sw_sq_cons, cqe->wr_id, cqe->status);
2286 cqe++;2243 cqe++;
2287 (*budget)--;2244 (*budget)--;
2288 bnxt_qplib_lock_buddy_cq(qp, cq);
2289 bnxt_qplib_mark_qp_error(qp);2245 bnxt_qplib_mark_qp_error(qp);
2290 bnxt_qplib_unlock_buddy_cq(qp, cq);2246 /* Add qp to flush list of the CQ */
2247 bnxt_qplib_add_flush_qp(qp);
2291 } else {2248 } else {
2292 if (swq->flags & SQ_SEND_FLAGS_SIGNAL_COMP) {2249 if (swq->flags & SQ_SEND_FLAGS_SIGNAL_COMP) {
2293 /* Before we complete, do WA 9060 */2250 /* Before we complete, do WA 9060 */
@@ -2403,9 +2360,7 @@ static int bnxt_qplib_cq_process_res_rc(struct bnxt_qplib_cq *cq, · 109 unmodified lines
2403 if (hwcqe->status != CQ_RES_RC_STATUS_OK) {2360 if (hwcqe->status != CQ_RES_RC_STATUS_OK) {
2404 qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;2361 qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;
2405 /* Add qp to flush list of the CQ */2362 /* Add qp to flush list of the CQ */
2406 bnxt_qplib_lock_buddy_cq(qp, cq);2363 bnxt_qplib_add_flush_qp(qp);
2407 __bnxt_qplib_add_flush_qp(qp);
2408 bnxt_qplib_unlock_buddy_cq(qp, cq);
2409 }2364 }
2410 }2365 }
2411 2366
@@ -2489,9 +2444,7 @@ static int bnxt_qplib_cq_process_res_ud(struct bnxt_qplib_cq *cq, · 77 unmodified lines
2489 if (hwcqe->status != CQ_RES_RC_STATUS_OK) {2444 if (hwcqe->status != CQ_RES_RC_STATUS_OK) {
2490 qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;2445 qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;
2491 /* Add qp to flush list of the CQ */2446 /* Add qp to flush list of the CQ */
2492 bnxt_qplib_lock_buddy_cq(qp, cq);2447 bnxt_qplib_add_flush_qp(qp);
2493 __bnxt_qplib_add_flush_qp(qp);
2494 bnxt_qplib_unlock_buddy_cq(qp, cq);
2495 }2448 }
2496 }2449 }
2497done:2450done:
@@ -2501,11 +2454,9 @@ done: · 3 unmodified lines
2501bool bnxt_qplib_is_cq_empty(struct bnxt_qplib_cq *cq)2454bool bnxt_qplib_is_cq_empty(struct bnxt_qplib_cq *cq)
2502{2455{
2503 struct cq_base *hw_cqe, **hw_cqe_ptr;2456 struct cq_base *hw_cqe, **hw_cqe_ptr;
2504 unsigned long flags;
2505 u32 sw_cons, raw_cons;2457 u32 sw_cons, raw_cons;
2506 bool rc = true;2458 bool rc = true;
2507 2459
2508 spin_lock_irqsave(&cq->hwq.lock, flags);
2509 raw_cons = cq->hwq.cons;2460 raw_cons = cq->hwq.cons;
2510 sw_cons = HWQ_CMP(raw_cons, &cq->hwq);2461 sw_cons = HWQ_CMP(raw_cons, &cq->hwq);
2511 hw_cqe_ptr = (struct cq_base **)cq->hwq.pbl_ptr;2462 hw_cqe_ptr = (struct cq_base **)cq->hwq.pbl_ptr;
@@ -2513,7 +2464,6 @@ bool bnxt_qplib_is_cq_empty(struct bnxt_qplib_cq *cq) · 1 unmodified line
2513 2464
2514 /* Check for Valid bit. If the CQE is valid, return false */2465 /* Check for Valid bit. If the CQE is valid, return false */
2515 rc = !CQE_CMP_VALID(hw_cqe, raw_cons, cq->hwq.max_elements);2466 rc = !CQE_CMP_VALID(hw_cqe, raw_cons, cq->hwq.max_elements);
2516 spin_unlock_irqrestore(&cq->hwq.lock, flags);
2517 return rc;2467 return rc;
2518}2468}
2519 2469
@@ -2602,9 +2552,7 @@ static int bnxt_qplib_cq_process_res_raweth_qp1(struct bnxt_qplib_cq *cq, · 82 unmodified lines
2602 if (hwcqe->status != CQ_RES_RC_STATUS_OK) {2552 if (hwcqe->status != CQ_RES_RC_STATUS_OK) {
2603 qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;2553 qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;
2604 /* Add qp to flush list of the CQ */2554 /* Add qp to flush list of the CQ */
2605 bnxt_qplib_lock_buddy_cq(qp, cq);2555 bnxt_qplib_add_flush_qp(qp);
2606 __bnxt_qplib_add_flush_qp(qp);
2607 bnxt_qplib_unlock_buddy_cq(qp, cq);
2608 }2556 }
2609 }2557 }
2610 2558
@@ -2719,9 +2667,7 @@ do_rq: · 108 unmodified lines
2719 */2667 */
2720 2668
2721 /* Add qp to flush list of the CQ */2669 /* Add qp to flush list of the CQ */
2722 bnxt_qplib_lock_buddy_cq(qp, cq);2670 bnxt_qplib_add_flush_qp(qp);
2723 __bnxt_qplib_add_flush_qp(qp);
2724 bnxt_qplib_unlock_buddy_cq(qp, cq);
2725done:2671done:
2726 return rc;2672 return rc;
2727}2673}
@@ -2750,7 +2696,7 @@ int bnxt_qplib_process_flush_list(struct bnxt_qplib_cq *cq, · 22 unmodified lines
2750 u32 budget = num_cqes;2696 u32 budget = num_cqes;
2751 unsigned long flags;2697 unsigned long flags;
2752 2698
2753 spin_lock_irqsave(&cq->hwq.lock, flags);2699 spin_lock_irqsave(&cq->flush_lock, flags);
2754 list_for_each_entry(qp, &cq->sqf_head, sq_flush) {2700 list_for_each_entry(qp, &cq->sqf_head, sq_flush) {
2755 dev_dbg(&cq->hwq.pdev->dev,2701 dev_dbg(&cq->hwq.pdev->dev,
2756 "QPLIB: FP: Flushing SQ QP= %p",2702 "QPLIB: FP: Flushing SQ QP= %p",
@@ -2764,7 +2710,7 @@ int bnxt_qplib_process_flush_list(struct bnxt_qplib_cq *cq, · 7 unmodified lines
2764 qp);2710 qp);
2765 __flush_rq(&qp->rq, qp, &cqe, &budget);2711 __flush_rq(&qp->rq, qp, &cqe, &budget);
2766 }2712 }
2767 spin_unlock_irqrestore(&cq->hwq.lock, flags);2713 spin_unlock_irqrestore(&cq->flush_lock, flags);
2768 2714
2769 return num_cqes - budget;2715 return num_cqes - budget;
2770}2716}
@@ -2773,11 +2719,9 @@ int bnxt_qplib_poll_cq(struct bnxt_qplib_cq *cq, struct bnxt_qplib_cqe *cqe, · 2 unmodified lines
2773 int num_cqes, struct bnxt_qplib_qp **lib_qp)2719 int num_cqes, struct bnxt_qplib_qp **lib_qp)
2774{2720{
2775 struct cq_base *hw_cqe, **hw_cqe_ptr;2721 struct cq_base *hw_cqe, **hw_cqe_ptr;
2776 unsigned long flags;
2777 u32 sw_cons, raw_cons;2722 u32 sw_cons, raw_cons;
2778 int budget, rc = 0;2723 int budget, rc = 0;
2779 2724
2780 spin_lock_irqsave(&cq->hwq.lock, flags);
2781 raw_cons = cq->hwq.cons;2725 raw_cons = cq->hwq.cons;
2782 budget = num_cqes;2726 budget = num_cqes;
2783 2727
@@ -2853,20 +2797,15 @@ int bnxt_qplib_poll_cq(struct bnxt_qplib_cq *cq, struct bnxt_qplib_cqe *cqe, · 69 unmodified lines
2853 bnxt_qplib_arm_cq(cq, DBR_DBR_TYPE_CQ);2797 bnxt_qplib_arm_cq(cq, DBR_DBR_TYPE_CQ);
2854 }2798 }
2855exit:2799exit:
2856 spin_unlock_irqrestore(&cq->hwq.lock, flags);
2857 return num_cqes - budget;2800 return num_cqes - budget;
2858}2801}
2859 2802
2860void bnxt_qplib_req_notify_cq(struct bnxt_qplib_cq *cq, u32 arm_type)2803void bnxt_qplib_req_notify_cq(struct bnxt_qplib_cq *cq, u32 arm_type)
2861{2804{
2862 unsigned long flags;
2863
2864 spin_lock_irqsave(&cq->hwq.lock, flags);
2865 if (arm_type)2805 if (arm_type)
2866 bnxt_qplib_arm_cq(cq, arm_type);2806 bnxt_qplib_arm_cq(cq, arm_type);
2867 /* Using cq->arm_state variable to track whether to issue cq handler */2807 /* Using cq->arm_state variable to track whether to issue cq handler */
2868 atomic_set(&cq->arm_state, 1);2808 atomic_set(&cq->arm_state, 1);
2869 spin_unlock_irqrestore(&cq->hwq.lock, flags);
2870}2809}
2871 2810
2872void bnxt_qplib_flush_cqn_wq(struct bnxt_qplib_qp *qp)2811void bnxt_qplib_flush_cqn_wq(struct bnxt_qplib_qp *qp)
drivers/infiniband/hw/bnxt_re/qplib_fp.h+12−0
@@ -389,6 +389,18 @@ struct bnxt_qplib_cq { · 388 unmodified lines
389 struct list_head sqf_head, rqf_head;389 struct list_head sqf_head, rqf_head;
390 atomic_t arm_state;390 atomic_t arm_state;
391 spinlock_t compl_lock; /* synch CQ handlers */391 spinlock_t compl_lock; /* synch CQ handlers */
392/* Locking Notes:
393 * QP can move to error state from modify_qp, async error event or error
394 * CQE as part of poll_cq. When QP is moved to error state, it gets added
395 * to two flush lists, one each for SQ and RQ.
396 * Each flush list is protected by qplib_cq->flush_lock. Both scq and rcq
397 * flush_locks should be acquired when QP is moved to error. The control path
398 * operations(modify_qp and async error events) are synchronized with poll_cq
399 * using upper level CQ locks (bnxt_re_cq->cq_lock) of both SCQ and RCQ.
400 * The qplib_cq->flush_lock is required to synchronize two instances of poll_cq
401 * of the same QP while manipulating the flush list.
402 */
403 spinlock_t flush_lock; /* QP flush management */
392};404};
393 405
394#define BNXT_QPLIB_MAX_IRRQE_ENTRY_SIZE sizeof(struct xrrq_irrq)406#define BNXT_QPLIB_MAX_IRRQE_ENTRY_SIZE sizeof(struct xrrq_irrq)
drivers/infiniband/hw/bnxt_re/qplib_rcfw.c+6−3
@@ -305,9 +305,8 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw, · 304 unmodified lines
305 err_event->res_err_state_reason);305 err_event->res_err_state_reason);
306 if (!qp)306 if (!qp)
307 break;307 break;
308 bnxt_qplib_acquire_cq_locks(qp, &flags);
309 bnxt_qplib_mark_qp_error(qp);308 bnxt_qplib_mark_qp_error(qp);
310 bnxt_qplib_release_cq_locks(qp, &flags);309 rcfw->aeq_handler(rcfw, qp_event, qp);
311 break;310 break;
312 default:311 default:
313 /* Command Response */312 /* Command Response */
@@ -460,7 +459,11 @@ int bnxt_qplib_init_rcfw(struct bnxt_qplib_rcfw *rcfw, · 146 unmodified lines
460 int rc;459 int rc;
461 460
462 RCFW_CMD_PREP(req, INITIALIZE_FW, cmd_flags);461 RCFW_CMD_PREP(req, INITIALIZE_FW, cmd_flags);
463 462 /* Supply (log-base-2-of-host-page-size - base-page-shift)
463 * to bono to adjust the doorbell page sizes.
464 */
465 req.log2_dbr_pg_size = cpu_to_le16(PAGE_SHIFT -
466 RCFW_DBR_BASE_PAGE_SHIFT);
464 /*467 /*
465 * VFs need not setup the HW context area, PF468 * VFs need not setup the HW context area, PF
466 * shall setup this area for VF. Skipping the469 * shall setup this area for VF. Skipping the
drivers/infiniband/hw/bnxt_re/qplib_rcfw.h+1−0
@@ -49,6 +49,7 @@ · 48 unmodified lines
49#define RCFW_COMM_SIZE 0x10449#define RCFW_COMM_SIZE 0x104
50 50
51#define RCFW_DBR_PCI_BAR_REGION 251#define RCFW_DBR_PCI_BAR_REGION 2
52#define RCFW_DBR_BASE_PAGE_SHIFT 12
52 53
53#define RCFW_CMD_PREP(req, CMD, cmd_flags) \54#define RCFW_CMD_PREP(req, CMD, cmd_flags) \
54 do { \55 do { \
drivers/infiniband/hw/bnxt_re/qplib_sp.c+2−1
@@ -139,7 +139,8 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw, · 138 unmodified lines
139 attr->max_pkey = le32_to_cpu(sb->max_pkeys);139 attr->max_pkey = le32_to_cpu(sb->max_pkeys);
140 140
141 attr->max_inline_data = le32_to_cpu(sb->max_inline_data);141 attr->max_inline_data = le32_to_cpu(sb->max_inline_data);
142 attr->l2_db_size = (sb->l2_db_space_size + 1) * PAGE_SIZE;142 attr->l2_db_size = (sb->l2_db_space_size + 1) *
143 (0x01 << RCFW_DBR_BASE_PAGE_SHIFT);
143 attr->max_sgid = le32_to_cpu(sb->max_gid);144 attr->max_sgid = le32_to_cpu(sb->max_gid);
144 145
145 bnxt_qplib_query_version(rcfw, attr->fw_ver);146 bnxt_qplib_query_version(rcfw, attr->fw_ver);
drivers/infiniband/hw/bnxt_re/roce_hsi.h+24−1
@@ -1761,7 +1761,30 @@ struct cmdq_initialize_fw { · 1760 unmodified lines
1761 #define CMDQ_INITIALIZE_FW_TIM_PG_SIZE_PG_2M (0x3UL << 4)1761 #define CMDQ_INITIALIZE_FW_TIM_PG_SIZE_PG_2M (0x3UL << 4)
1762 #define CMDQ_INITIALIZE_FW_TIM_PG_SIZE_PG_8M (0x4UL << 4)1762 #define CMDQ_INITIALIZE_FW_TIM_PG_SIZE_PG_8M (0x4UL << 4)
1763 #define CMDQ_INITIALIZE_FW_TIM_PG_SIZE_PG_1G (0x5UL << 4)1763 #define CMDQ_INITIALIZE_FW_TIM_PG_SIZE_PG_1G (0x5UL << 4)
1764 __le16 reserved16;1764 /* This value is (log-base-2-of-DBR-page-size - 12).
1765 * 0 for 4KB. HW supported values are enumerated below.
1766 */
1767 __le16 log2_dbr_pg_size;
1768 #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_MASK 0xfUL
1769 #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_SFT 0
1770 #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_4K 0x0UL
1771 #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_8K 0x1UL
1772 #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_16K 0x2UL
1773 #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_32K 0x3UL
1774 #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_64K 0x4UL
1775 #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_128K 0x5UL
1776 #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_256K 0x6UL
1777 #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_512K 0x7UL
1778 #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_1M 0x8UL
1779 #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_2M 0x9UL
1780 #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_4M 0xaUL
1781 #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_8M 0xbUL
1782 #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_16M 0xcUL
1783 #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_32M 0xdUL
1784 #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_64M 0xeUL
1785 #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_128M 0xfUL
1786 #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_LAST \
1787 CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_128M
1765 __le64 qpc_page_dir;1788 __le64 qpc_page_dir;
1766 __le64 mrw_page_dir;1789 __le64 mrw_page_dir;
1767 __le64 srq_page_dir;1790 __le64 srq_page_dir;
drivers/infiniband/hw/mlx4/cq.c+3−1
@@ -601,6 +601,7 @@ static void use_tunnel_data(struct mlx4_ib_qp *qp, struct mlx4_ib_cq *cq, struct · 600 unmodified lines
601 wc->dlid_path_bits = 0;601 wc->dlid_path_bits = 0;
602 602
603 if (is_eth) {603 if (is_eth) {
604 wc->slid = 0;
604 wc->vlan_id = be16_to_cpu(hdr->tun.sl_vid);605 wc->vlan_id = be16_to_cpu(hdr->tun.sl_vid);
605 memcpy(&(wc->smac[0]), (char *)&hdr->tun.mac_31_0, 4);606 memcpy(&(wc->smac[0]), (char *)&hdr->tun.mac_31_0, 4);
606 memcpy(&(wc->smac[4]), (char *)&hdr->tun.slid_mac_47_32, 2);607 memcpy(&(wc->smac[4]), (char *)&hdr->tun.slid_mac_47_32, 2);
@@ -851,7 +852,6 @@ repoll: · 244 unmodified lines
851 }852 }
852 }853 }
853 854
854 wc->slid = be16_to_cpu(cqe->rlid);
855 g_mlpath_rqpn = be32_to_cpu(cqe->g_mlpath_rqpn);855 g_mlpath_rqpn = be32_to_cpu(cqe->g_mlpath_rqpn);
856 wc->src_qp = g_mlpath_rqpn & 0xffffff;856 wc->src_qp = g_mlpath_rqpn & 0xffffff;
857 wc->dlid_path_bits = (g_mlpath_rqpn >> 24) & 0x7f;857 wc->dlid_path_bits = (g_mlpath_rqpn >> 24) & 0x7f;
@@ -860,6 +860,7 @@ repoll: · 2 unmodified lines
860 wc->wc_flags |= mlx4_ib_ipoib_csum_ok(cqe->status,860 wc->wc_flags |= mlx4_ib_ipoib_csum_ok(cqe->status,
861 cqe->checksum) ? IB_WC_IP_CSUM_OK : 0;861 cqe->checksum) ? IB_WC_IP_CSUM_OK : 0;
862 if (is_eth) {862 if (is_eth) {
863 wc->slid = 0;
863 wc->sl = be16_to_cpu(cqe->sl_vid) >> 13;864 wc->sl = be16_to_cpu(cqe->sl_vid) >> 13;
864 if (be32_to_cpu(cqe->vlan_my_qpn) &865 if (be32_to_cpu(cqe->vlan_my_qpn) &
865 MLX4_CQE_CVLAN_PRESENT_MASK) {866 MLX4_CQE_CVLAN_PRESENT_MASK) {
@@ -871,6 +872,7 @@ repoll: · 5 unmodified lines
871 memcpy(wc->smac, cqe->smac, ETH_ALEN);872 memcpy(wc->smac, cqe->smac, ETH_ALEN);
872 wc->wc_flags |= (IB_WC_WITH_VLAN | IB_WC_WITH_SMAC);873 wc->wc_flags |= (IB_WC_WITH_VLAN | IB_WC_WITH_SMAC);
873 } else {874 } else {
875 wc->slid = be16_to_cpu(cqe->rlid);
874 wc->sl = be16_to_cpu(cqe->sl_vid) >> 12;876 wc->sl = be16_to_cpu(cqe->sl_vid) >> 12;
875 wc->vlan_id = 0xffff;877 wc->vlan_id = 0xffff;
876 }878 }
drivers/infiniband/hw/mlx4/main.c+7−4
@@ -219,8 +219,6 @@ static int mlx4_ib_update_gids_v1_v2(struct gid_entry *gids, · 218 unmodified lines
219 gid_tbl[i].version = 2;219 gid_tbl[i].version = 2;
220 if (!ipv6_addr_v4mapped((struct in6_addr *)&gids[i].gid))220 if (!ipv6_addr_v4mapped((struct in6_addr *)&gids[i].gid))
221 gid_tbl[i].type = 1;221 gid_tbl[i].type = 1;
222 else
223 memset(&gid_tbl[i].gid, 0, 12);
224 }222 }
225 }223 }
226 224
@@ -366,8 +364,13 @@ static int mlx4_ib_del_gid(struct ib_device *device, · 139 unmodified lines
366 if (!gids) {364 if (!gids) {
367 ret = -ENOMEM;365 ret = -ENOMEM;
368 } else {366 } else {
369 for (i = 0; i < MLX4_MAX_PORT_GIDS; i++)367 for (i = 0; i < MLX4_MAX_PORT_GIDS; i++) {
370 memcpy(&gids[i].gid, &port_gid_table->gids[i].gid, sizeof(union ib_gid));368 memcpy(&gids[i].gid,
369 &port_gid_table->gids[i].gid,
370 sizeof(union ib_gid));
371 gids[i].gid_type =
372 port_gid_table->gids[i].gid_type;
373 }
371 }374 }
372 }375 }
373 spin_unlock_bh(&iboe->lock);376 spin_unlock_bh(&iboe->lock);
drivers/infiniband/hw/mlx5/cq.c+8−2
@@ -226,7 +226,6 @@ static void handle_responder(struct ib_wc *wc, struct mlx5_cqe64 *cqe, · 225 unmodified lines
226 wc->ex.invalidate_rkey = be32_to_cpu(cqe->imm_inval_pkey);226 wc->ex.invalidate_rkey = be32_to_cpu(cqe->imm_inval_pkey);
227 break;227 break;
228 }228 }
229 wc->slid = be16_to_cpu(cqe->slid);
230 wc->src_qp = be32_to_cpu(cqe->flags_rqpn) & 0xffffff;229 wc->src_qp = be32_to_cpu(cqe->flags_rqpn) & 0xffffff;
231 wc->dlid_path_bits = cqe->ml_path;230 wc->dlid_path_bits = cqe->ml_path;
232 g = (be32_to_cpu(cqe->flags_rqpn) >> 28) & 3;231 g = (be32_to_cpu(cqe->flags_rqpn) >> 28) & 3;
@@ -241,10 +240,12 @@ static void handle_responder(struct ib_wc *wc, struct mlx5_cqe64 *cqe, · 8 unmodified lines
241 }240 }
242 241
243 if (ll != IB_LINK_LAYER_ETHERNET) {242 if (ll != IB_LINK_LAYER_ETHERNET) {
243 wc->slid = be16_to_cpu(cqe->slid);
244 wc->sl = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0xf;244 wc->sl = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0xf;
245 return;245 return;
246 }246 }
247 247
248 wc->slid = 0;
248 vlan_present = cqe->l4_l3_hdr_type & 0x1;249 vlan_present = cqe->l4_l3_hdr_type & 0x1;
249 roce_packet_type = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0x3;250 roce_packet_type = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0x3;
250 if (vlan_present) {251 if (vlan_present) {
@@ -1177,7 +1178,12 @@ static int resize_user(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq, · 926 unmodified lines
1177 if (ucmd.reserved0 || ucmd.reserved1)1178 if (ucmd.reserved0 || ucmd.reserved1)
1178 return -EINVAL;1179 return -EINVAL;
1179 1180
1180 umem = ib_umem_get(context, ucmd.buf_addr, entries * ucmd.cqe_size,1181 /* check multiplication overflow */
1182 if (ucmd.cqe_size && SIZE_MAX / ucmd.cqe_size <= entries - 1)
1183 return -EINVAL;
1184
1185 umem = ib_umem_get(context, ucmd.buf_addr,
1186 (size_t)ucmd.cqe_size * entries,
1181 IB_ACCESS_LOCAL_WRITE, 1);1187 IB_ACCESS_LOCAL_WRITE, 1);
1182 if (IS_ERR(umem)) {1188 if (IS_ERR(umem)) {
1183 err = PTR_ERR(umem);1189 err = PTR_ERR(umem);
drivers/infiniband/hw/mlx5/main.c+9−12
@@ -245,12 +245,16 @@ struct mlx5_core_dev *mlx5_ib_get_native_port_mdev(struct mlx5_ib_dev *ibdev, · 244 unmodified lines
245 struct mlx5_ib_multiport_info *mpi;245 struct mlx5_ib_multiport_info *mpi;
246 struct mlx5_ib_port *port;246 struct mlx5_ib_port *port;
247 247
248 if (!mlx5_core_mp_enabled(ibdev->mdev) ||
249 ll != IB_LINK_LAYER_ETHERNET) {
250 if (native_port_num)
251 *native_port_num = ib_port_num;
252 return ibdev->mdev;
253 }
254
248 if (native_port_num)255 if (native_port_num)
249 *native_port_num = 1;256 *native_port_num = 1;
250 257
251 if (!mlx5_core_mp_enabled(ibdev->mdev) || ll != IB_LINK_LAYER_ETHERNET)
252 return ibdev->mdev;
253
254 port = &ibdev->port[ib_port_num - 1];258 port = &ibdev->port[ib_port_num - 1];
255 if (!port)259 if (!port)
256 return NULL;260 return NULL;
@@ -3263,7 +3267,7 @@ static void mlx5_ib_handle_event(struct work_struct *_work) · 3006 unmodified lines
3263 struct mlx5_ib_dev *ibdev;3267 struct mlx5_ib_dev *ibdev;
3264 struct ib_event ibev;3268 struct ib_event ibev;
3265 bool fatal = false;3269 bool fatal = false;
3266 u8 port = 0;3270 u8 port = (u8)work->param;
3267 3271
3268 if (mlx5_core_is_mp_slave(work->dev)) {3272 if (mlx5_core_is_mp_slave(work->dev)) {
3269 ibdev = mlx5_ib_get_ibdev_from_mpi(work->context);3273 ibdev = mlx5_ib_get_ibdev_from_mpi(work->context);
@@ -3283,8 +3287,6 @@ static void mlx5_ib_handle_event(struct work_struct *_work) · 13 unmodified lines
3283 case MLX5_DEV_EVENT_PORT_UP:3287 case MLX5_DEV_EVENT_PORT_UP:
3284 case MLX5_DEV_EVENT_PORT_DOWN:3288 case MLX5_DEV_EVENT_PORT_DOWN:
3285 case MLX5_DEV_EVENT_PORT_INITIALIZED:3289 case MLX5_DEV_EVENT_PORT_INITIALIZED:
3286 port = (u8)work->param;
3287
3288 /* In RoCE, port up/down events are handled in3290 /* In RoCE, port up/down events are handled in
3289 * mlx5_netdev_event().3291 * mlx5_netdev_event().
3290 */3292 */
@@ -3298,24 +3300,19 @@ static void mlx5_ib_handle_event(struct work_struct *_work) · 7 unmodified lines
3298 3300
3299 case MLX5_DEV_EVENT_LID_CHANGE:3301 case MLX5_DEV_EVENT_LID_CHANGE:
3300 ibev.event = IB_EVENT_LID_CHANGE;3302 ibev.event = IB_EVENT_LID_CHANGE;
3301 port = (u8)work->param;
3302 break;3303 break;
3303 3304
3304 case MLX5_DEV_EVENT_PKEY_CHANGE:3305 case MLX5_DEV_EVENT_PKEY_CHANGE:
3305 ibev.event = IB_EVENT_PKEY_CHANGE;3306 ibev.event = IB_EVENT_PKEY_CHANGE;
3306 port = (u8)work->param;
3307
3308 schedule_work(&ibdev->devr.ports[port - 1].pkey_change_work);3307 schedule_work(&ibdev->devr.ports[port - 1].pkey_change_work);
3309 break;3308 break;
3310 3309
3311 case MLX5_DEV_EVENT_GUID_CHANGE:3310 case MLX5_DEV_EVENT_GUID_CHANGE:
3312 ibev.event = IB_EVENT_GID_CHANGE;3311 ibev.event = IB_EVENT_GID_CHANGE;
3313 port = (u8)work->param;
3314 break;3312 break;
3315 3313
3316 case MLX5_DEV_EVENT_CLIENT_REREG:3314 case MLX5_DEV_EVENT_CLIENT_REREG:
3317 ibev.event = IB_EVENT_CLIENT_REREGISTER;3315 ibev.event = IB_EVENT_CLIENT_REREGISTER;
3318 port = (u8)work->param;
3319 break;3316 break;
3320 case MLX5_DEV_EVENT_DELAY_DROP_TIMEOUT:3317 case MLX5_DEV_EVENT_DELAY_DROP_TIMEOUT:
3321 schedule_work(&ibdev->delay_drop.delay_drop_work);3318 schedule_work(&ibdev->delay_drop.delay_drop_work);
@@ -3327,7 +3324,7 @@ static void mlx5_ib_handle_event(struct work_struct *_work) · 5 unmodified lines
3327 ibev.device = &ibdev->ib_dev;3324 ibev.device = &ibdev->ib_dev;
3328 ibev.element.port_num = port;3325 ibev.element.port_num = port;
3329 3326
3330 if (port < 1 || port > ibdev->num_ports) {3327 if (!rdma_is_port_valid(&ibdev->ib_dev, port)) {
3331 mlx5_ib_warn(ibdev, "warning: event on port %d\n", port);3328 mlx5_ib_warn(ibdev, "warning: event on port %d\n", port);
3332 goto out;3329 goto out;
3333 }3330 }
drivers/infiniband/hw/mlx5/mr.c+1−1
@@ -1816,7 +1816,6 @@ mlx5_ib_sg_to_klms(struct mlx5_ib_mr *mr, · 1815 unmodified lines
1816 1816
1817 mr->ibmr.iova = sg_dma_address(sg) + sg_offset;1817 mr->ibmr.iova = sg_dma_address(sg) + sg_offset;
1818 mr->ibmr.length = 0;1818 mr->ibmr.length = 0;
1819 mr->ndescs = sg_nents;
1820 1819
1821 for_each_sg(sgl, sg, sg_nents, i) {1820 for_each_sg(sgl, sg, sg_nents, i) {
1822 if (unlikely(i >= mr->max_descs))1821 if (unlikely(i >= mr->max_descs))
@@ -1828,6 +1827,7 @@ mlx5_ib_sg_to_klms(struct mlx5_ib_mr *mr, · 5 unmodified lines
1828 1827
1829 sg_offset = 0;1828 sg_offset = 0;
1830 }1829 }
1830 mr->ndescs = i;
1831 1831
1832 if (sg_offset_p)1832 if (sg_offset_p)
1833 *sg_offset_p = sg_offset;1833 *sg_offset_p = sg_offset;
drivers/infiniband/hw/mlx5/qp.c+9−2
@@ -1584,6 +1584,7 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd, · 1583 unmodified lines
1584 u32 uidx = MLX5_IB_DEFAULT_UIDX;1584 u32 uidx = MLX5_IB_DEFAULT_UIDX;
1585 struct mlx5_ib_create_qp ucmd;1585 struct mlx5_ib_create_qp ucmd;
1586 struct mlx5_ib_qp_base *base;1586 struct mlx5_ib_qp_base *base;
1587 int mlx5_st;
1587 void *qpc;1588 void *qpc;
1588 u32 *in;1589 u32 *in;
1589 int err;1590 int err;
@@ -1592,6 +1593,10 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd, · 2 unmodified lines
1592 spin_lock_init(&qp->sq.lock);1593 spin_lock_init(&qp->sq.lock);
1593 spin_lock_init(&qp->rq.lock);1594 spin_lock_init(&qp->rq.lock);
1594 1595
1596 mlx5_st = to_mlx5_st(init_attr->qp_type);
1597 if (mlx5_st < 0)
1598 return -EINVAL;
1599
1595 if (init_attr->rwq_ind_tbl) {1600 if (init_attr->rwq_ind_tbl) {
1596 if (!udata)1601 if (!udata)
1597 return -ENOSYS;1602 return -ENOSYS;
@@ -1753,7 +1758,7 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd, · 155 unmodified lines
1753 1758
1754 qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);1759 qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
1755 1760
1756 MLX5_SET(qpc, qpc, st, to_mlx5_st(init_attr->qp_type));1761 MLX5_SET(qpc, qpc, st, mlx5_st);
1757 MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);1762 MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);
1758 1763
1759 if (init_attr->qp_type != MLX5_IB_QPT_REG_UMR)1764 if (init_attr->qp_type != MLX5_IB_QPT_REG_UMR)
@@ -3095,8 +3100,10 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp, · 1335 unmodified lines
3095 goto out;3100 goto out;
3096 3101
3097 if (mlx5_cur >= MLX5_QP_NUM_STATE || mlx5_new >= MLX5_QP_NUM_STATE ||3102 if (mlx5_cur >= MLX5_QP_NUM_STATE || mlx5_new >= MLX5_QP_NUM_STATE ||
3098 !optab[mlx5_cur][mlx5_new])3103 !optab[mlx5_cur][mlx5_new]) {
3104 err = -EINVAL;
3099 goto out;3105 goto out;
3106 }
3100 3107
3101 op = optab[mlx5_cur][mlx5_new];3108 op = optab[mlx5_cur][mlx5_new];
3102 optpar = ib_mask_to_mlx5_opt(attr_mask);3109 optpar = ib_mask_to_mlx5_opt(attr_mask);
drivers/infiniband/hw/qedr/qedr_iw_cm.c+11−8
@@ -458,8 +458,7 @@ qedr_addr6_resolve(struct qedr_dev *dev, · 457 unmodified lines
458 }458 }
459 return -EINVAL;459 return -EINVAL;
460 }460 }
461 neigh = dst_neigh_lookup(dst, &dst_in);461 neigh = dst_neigh_lookup(dst, &fl6.daddr);
462
463 if (neigh) {462 if (neigh) {
464 rcu_read_lock();463 rcu_read_lock();
465 if (neigh->nud_state & NUD_VALID) {464 if (neigh->nud_state & NUD_VALID) {
@@ -494,10 +493,14 @@ int qedr_iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) · 28 unmodified lines
494 493
495 qp = idr_find(&dev->qpidr, conn_param->qpn);494 qp = idr_find(&dev->qpidr, conn_param->qpn);
496 495
497 laddr = (struct sockaddr_in *)&cm_id->local_addr;496 laddr = (struct sockaddr_in *)&cm_id->m_local_addr;
498 raddr = (struct sockaddr_in *)&cm_id->remote_addr;497 raddr = (struct sockaddr_in *)&cm_id->m_remote_addr;
499 laddr6 = (struct sockaddr_in6 *)&cm_id->local_addr;498 laddr6 = (struct sockaddr_in6 *)&cm_id->m_local_addr;
500 raddr6 = (struct sockaddr_in6 *)&cm_id->remote_addr;499 raddr6 = (struct sockaddr_in6 *)&cm_id->m_remote_addr;
500
501 DP_DEBUG(dev, QEDR_MSG_IWARP, "MAPPED %d %d\n",
502 ntohs(((struct sockaddr_in *)&cm_id->remote_addr)->sin_port),
503 ntohs(raddr->sin_port));
501 504
502 DP_DEBUG(dev, QEDR_MSG_IWARP,505 DP_DEBUG(dev, QEDR_MSG_IWARP,
503 "Connect source address: %pISpc, remote address: %pISpc\n",506 "Connect source address: %pISpc, remote address: %pISpc\n",
@@ -599,8 +602,8 @@ int qedr_iw_create_listen(struct iw_cm_id *cm_id, int backlog) · 95 unmodified lines
599 int rc;602 int rc;
600 int i;603 int i;
601 604
602 laddr = (struct sockaddr_in *)&cm_id->local_addr;605 laddr = (struct sockaddr_in *)&cm_id->m_local_addr;
603 laddr6 = (struct sockaddr_in6 *)&cm_id->local_addr;606 laddr6 = (struct sockaddr_in6 *)&cm_id->m_local_addr;
604 607
605 DP_DEBUG(dev, QEDR_MSG_IWARP,608 DP_DEBUG(dev, QEDR_MSG_IWARP,
606 "Create Listener address: %pISpc\n", &cm_id->local_addr);609 "Create Listener address: %pISpc\n", &cm_id->local_addr);
drivers/infiniband/hw/qedr/verbs.c+12−1
@@ -3034,6 +3034,11 @@ static int __qedr_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, · 3033 unmodified lines
3034 3034
3035 switch (wr->opcode) {3035 switch (wr->opcode) {
3036 case IB_WR_SEND_WITH_IMM:3036 case IB_WR_SEND_WITH_IMM:
3037 if (unlikely(rdma_protocol_iwarp(&dev->ibdev, 1))) {
3038 rc = -EINVAL;
3039 *bad_wr = wr;
3040 break;
3041 }
3037 wqe->req_type = RDMA_SQ_REQ_TYPE_SEND_WITH_IMM;3042 wqe->req_type = RDMA_SQ_REQ_TYPE_SEND_WITH_IMM;
3038 swqe = (struct rdma_sq_send_wqe_1st *)wqe;3043 swqe = (struct rdma_sq_send_wqe_1st *)wqe;
3039 swqe->wqe_size = 2;3044 swqe->wqe_size = 2;
@@ -3075,6 +3080,11 @@ static int __qedr_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, · 35 unmodified lines
3075 break;3080 break;
3076 3081
3077 case IB_WR_RDMA_WRITE_WITH_IMM:3082 case IB_WR_RDMA_WRITE_WITH_IMM:
3083 if (unlikely(rdma_protocol_iwarp(&dev->ibdev, 1))) {
3084 rc = -EINVAL;
3085 *bad_wr = wr;
3086 break;
3087 }
3078 wqe->req_type = RDMA_SQ_REQ_TYPE_RDMA_WR_WITH_IMM;3088 wqe->req_type = RDMA_SQ_REQ_TYPE_RDMA_WR_WITH_IMM;
3079 rwqe = (struct rdma_sq_rdma_wqe_1st *)wqe;3089 rwqe = (struct rdma_sq_rdma_wqe_1st *)wqe;
3080 3090
@@ -3724,7 +3734,7 @@ int qedr_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) · 643 unmodified lines
3724{3734{
3725 struct qedr_dev *dev = get_qedr_dev(ibcq->device);3735 struct qedr_dev *dev = get_qedr_dev(ibcq->device);
3726 struct qedr_cq *cq = get_qedr_cq(ibcq);3736 struct qedr_cq *cq = get_qedr_cq(ibcq);
3727 union rdma_cqe *cqe = cq->latest_cqe;3737 union rdma_cqe *cqe;
3728 u32 old_cons, new_cons;3738 u32 old_cons, new_cons;
3729 unsigned long flags;3739 unsigned long flags;
3730 int update = 0;3740 int update = 0;
@@ -3741,6 +3751,7 @@ int qedr_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) · 10 unmodified lines
3741 return qedr_gsi_poll_cq(ibcq, num_entries, wc);3751 return qedr_gsi_poll_cq(ibcq, num_entries, wc);
3742 3752
3743 spin_lock_irqsave(&cq->cq_lock, flags);3753 spin_lock_irqsave(&cq->cq_lock, flags);
3754 cqe = cq->latest_cqe;
3744 old_cons = qed_chain_get_cons_idx_u32(&cq->pbl);3755 old_cons = qed_chain_get_cons_idx_u32(&cq->pbl);
3745 while (num_entries && is_valid_cqe(cq, cqe)) {3756 while (num_entries && is_valid_cqe(cq, cqe)) {
3746 struct qedr_qp *qp;3757 struct qedr_qp *qp;
drivers/net/ethernet/mellanox/mlx5/core/health.c+1−1
@@ -124,7 +124,7 @@ void mlx5_enter_error_state(struct mlx5_core_dev *dev, bool force) · 123 unmodified lines
124 trigger_cmd_completions(dev);124 trigger_cmd_completions(dev);
125 }125 }
126 126
127 mlx5_core_event(dev, MLX5_DEV_EVENT_SYS_ERROR, 0);127 mlx5_core_event(dev, MLX5_DEV_EVENT_SYS_ERROR, 1);
128 mlx5_core_err(dev, "end\n");128 mlx5_core_err(dev, "end\n");
129 129
130unlock:130unlock:

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t