diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-12-10 17:42:22 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-12-10 17:42:22 -0500 |
| commit | 0bd0f1e6d40aa16c4d507b1fff27163a7e7711f5 (patch) | |
| tree | e4b54cc162edc66f0d530ac278ce786a4c57c114 /drivers | |
| parent | a80c47daa818ead2644917d72ff2a934dd64fd16 (diff) | |
| parent | ab5cdc31630c7596d81ca8fbe7d695f10666f39b (diff) | |
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma
Pull rdma fixes from Doug Ledford:
"Most are minor to important fixes.
There is one performance enhancement that I took on the grounds that
failing to check if other processes can run before running what's
intended to be a background, idle-time task is a bug, even though the
primary effect of the fix is to improve performance (and it was a very
simple patch)"
* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma:
IB/mlx5: Postpone remove_keys under knowledge of coming preemption
IB/mlx4: Use vmalloc for WR buffers when needed
IB/mlx4: Use correct order of variables in log message
iser-target: Remove explicit mlx4 work-around
mlx4: Expose correct max_sge_rd limit
IB/mad: Require CM send method for everything except ClassPortInfo
IB/cma: Add a missing rcu_read_unlock()
IB core: Fix ib_sg_to_pages()
IB/srp: Fix srp_map_sg_fr()
IB/srp: Fix indirect data buffer rkey endianness
IB/srp: Initialize dma_length in srp_map_idb
IB/srp: Fix possible send queue overflow
IB/srp: Fix a memory leak
IB/sa: Put netlink request into the request list before sending
IB/iser: use sector_div instead of do_div
IB/core: use RCU for uverbs id lookup
IB/qib: Minor fixes to qib per SFF 8636
IB/core: Fix user mode post wr corruption
IB/qib: Fix qib_mr structure
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/infiniband/core/cma.c | 5 | ||||
| -rw-r--r-- | drivers/infiniband/core/mad.c | 5 | ||||
| -rw-r--r-- | drivers/infiniband/core/sa_query.c | 32 | ||||
| -rw-r--r-- | drivers/infiniband/core/uverbs_cmd.c | 27 | ||||
| -rw-r--r-- | drivers/infiniband/core/verbs.c | 43 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mlx4/main.c | 2 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mlx4/qp.c | 19 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mlx4/srq.c | 11 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mlx5/mr.c | 14 | ||||
| -rw-r--r-- | drivers/infiniband/hw/qib/qib_qsfp.c | 4 | ||||
| -rw-r--r-- | drivers/infiniband/hw/qib/qib_verbs.h | 2 | ||||
| -rw-r--r-- | drivers/infiniband/ulp/iser/iser_verbs.c | 2 | ||||
| -rw-r--r-- | drivers/infiniband/ulp/isert/ib_isert.c | 13 | ||||
| -rw-r--r-- | drivers/infiniband/ulp/srp/ib_srp.c | 48 | ||||
| -rw-r--r-- | drivers/infiniband/ulp/srp/ib_srp.h | 5 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/cmd.c | 2 |
16 files changed, 132 insertions, 102 deletions
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 944cd90417bc..d2d5d004f16d 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
| @@ -1126,10 +1126,7 @@ static bool validate_ipv4_net_dev(struct net_device *net_dev, | |||
| 1126 | 1126 | ||
| 1127 | rcu_read_lock(); | 1127 | rcu_read_lock(); |
| 1128 | err = fib_lookup(dev_net(net_dev), &fl4, &res, 0); | 1128 | err = fib_lookup(dev_net(net_dev), &fl4, &res, 0); |
| 1129 | if (err) | 1129 | ret = err == 0 && FIB_RES_DEV(res) == net_dev; |
| 1130 | return false; | ||
| 1131 | |||
| 1132 | ret = FIB_RES_DEV(res) == net_dev; | ||
| 1133 | rcu_read_unlock(); | 1130 | rcu_read_unlock(); |
| 1134 | 1131 | ||
| 1135 | return ret; | 1132 | return ret; |
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 8d8af7a41a30..2281de122038 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c | |||
| @@ -1811,6 +1811,11 @@ static int validate_mad(const struct ib_mad_hdr *mad_hdr, | |||
| 1811 | if (qp_num == 0) | 1811 | if (qp_num == 0) |
| 1812 | valid = 1; | 1812 | valid = 1; |
| 1813 | } else { | 1813 | } else { |
| 1814 | /* CM attributes other than ClassPortInfo only use Send method */ | ||
| 1815 | if ((mad_hdr->mgmt_class == IB_MGMT_CLASS_CM) && | ||
| 1816 | (mad_hdr->attr_id != IB_MGMT_CLASSPORTINFO_ATTR_ID) && | ||
| 1817 | (mad_hdr->method != IB_MGMT_METHOD_SEND)) | ||
| 1818 | goto out; | ||
| 1814 | /* Filter GSI packets sent to QP0 */ | 1819 | /* Filter GSI packets sent to QP0 */ |
| 1815 | if (qp_num != 0) | 1820 | if (qp_num != 0) |
| 1816 | valid = 1; | 1821 | valid = 1; |
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 2aba774f835b..a95a32ba596e 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c | |||
| @@ -512,7 +512,7 @@ static int ib_nl_get_path_rec_attrs_len(ib_sa_comp_mask comp_mask) | |||
| 512 | return len; | 512 | return len; |
| 513 | } | 513 | } |
| 514 | 514 | ||
| 515 | static int ib_nl_send_msg(struct ib_sa_query *query) | 515 | static int ib_nl_send_msg(struct ib_sa_query *query, gfp_t gfp_mask) |
| 516 | { | 516 | { |
| 517 | struct sk_buff *skb = NULL; | 517 | struct sk_buff *skb = NULL; |
| 518 | struct nlmsghdr *nlh; | 518 | struct nlmsghdr *nlh; |
| @@ -526,7 +526,7 @@ static int ib_nl_send_msg(struct ib_sa_query *query) | |||
| 526 | if (len <= 0) | 526 | if (len <= 0) |
| 527 | return -EMSGSIZE; | 527 | return -EMSGSIZE; |
| 528 | 528 | ||
| 529 | skb = nlmsg_new(len, GFP_KERNEL); | 529 | skb = nlmsg_new(len, gfp_mask); |
| 530 | if (!skb) | 530 | if (!skb) |
| 531 | return -ENOMEM; | 531 | return -ENOMEM; |
| 532 | 532 | ||
| @@ -544,7 +544,7 @@ static int ib_nl_send_msg(struct ib_sa_query *query) | |||
| 544 | /* Repair the nlmsg header length */ | 544 | /* Repair the nlmsg header length */ |
| 545 | nlmsg_end(skb, nlh); | 545 | nlmsg_end(skb, nlh); |
| 546 | 546 | ||
| 547 | ret = ibnl_multicast(skb, nlh, RDMA_NL_GROUP_LS, GFP_KERNEL); | 547 | ret = ibnl_multicast(skb, nlh, RDMA_NL_GROUP_LS, gfp_mask); |
| 548 | if (!ret) | 548 | if (!ret) |
| 549 | ret = len; | 549 | ret = len; |
| 550 | else | 550 | else |
| @@ -553,7 +553,7 @@ static int ib_nl_send_msg(struct ib_sa_query *query) | |||
| 553 | return ret; | 553 | return ret; |
| 554 | } | 554 | } |
| 555 | 555 | ||
| 556 | static int ib_nl_make_request(struct ib_sa_query *query) | 556 | static int ib_nl_make_request(struct ib_sa_query *query, gfp_t gfp_mask) |
| 557 | { | 557 | { |
| 558 | unsigned long flags; | 558 | unsigned long flags; |
| 559 | unsigned long delay; | 559 | unsigned long delay; |
| @@ -562,25 +562,27 @@ static int ib_nl_make_request(struct ib_sa_query *query) | |||
| 562 | INIT_LIST_HEAD(&query->list); | 562 | INIT_LIST_HEAD(&query->list); |
| 563 | query->seq = (u32)atomic_inc_return(&ib_nl_sa_request_seq); | 563 | query->seq = (u32)atomic_inc_return(&ib_nl_sa_request_seq); |
| 564 | 564 | ||
| 565 | /* Put the request on the list first.*/ | ||
| 565 | spin_lock_irqsave(&ib_nl_request_lock, flags); | 566 | spin_lock_irqsave(&ib_nl_request_lock, flags); |
| 566 | ret = ib_nl_send_msg(query); | ||
| 567 | if (ret <= 0) { | ||
| 568 | ret = -EIO; | ||
| 569 | goto request_out; | ||
| 570 | } else { | ||
| 571 | ret = 0; | ||
| 572 | } | ||
| 573 | |||
| 574 | delay = msecs_to_jiffies(sa_local_svc_timeout_ms); | 567 | delay = msecs_to_jiffies(sa_local_svc_timeout_ms); |
| 575 | query->timeout = delay + jiffies; | 568 | query->timeout = delay + jiffies; |
| 576 | list_add_tail(&query->list, &ib_nl_request_list); | 569 | list_add_tail(&query->list, &ib_nl_request_list); |
| 577 | /* Start the timeout if this is the only request */ | 570 | /* Start the timeout if this is the only request */ |
| 578 | if (ib_nl_request_list.next == &query->list) | 571 | if (ib_nl_request_list.next == &query->list) |
| 579 | queue_delayed_work(ib_nl_wq, &ib_nl_timed_work, delay); | 572 | queue_delayed_work(ib_nl_wq, &ib_nl_timed_work, delay); |
| 580 | |||
| 581 | request_out: | ||
| 582 | spin_unlock_irqrestore(&ib_nl_request_lock, flags); | 573 | spin_unlock_irqrestore(&ib_nl_request_lock, flags); |
| 583 | 574 | ||
| 575 | ret = ib_nl_send_msg(query, gfp_mask); | ||
| 576 | if (ret <= 0) { | ||
| 577 | ret = -EIO; | ||
| 578 | /* Remove the request */ | ||
| 579 | spin_lock_irqsave(&ib_nl_request_lock, flags); | ||
| 580 | list_del(&query->list); | ||
| 581 | spin_unlock_irqrestore(&ib_nl_request_lock, flags); | ||
| 582 | } else { | ||
| 583 | ret = 0; | ||
| 584 | } | ||
| 585 | |||
| 584 | return ret; | 586 | return ret; |
| 585 | } | 587 | } |
| 586 | 588 | ||
| @@ -1108,7 +1110,7 @@ static int send_mad(struct ib_sa_query *query, int timeout_ms, gfp_t gfp_mask) | |||
| 1108 | 1110 | ||
| 1109 | if (query->flags & IB_SA_ENABLE_LOCAL_SERVICE) { | 1111 | if (query->flags & IB_SA_ENABLE_LOCAL_SERVICE) { |
| 1110 | if (!ibnl_chk_listeners(RDMA_NL_GROUP_LS)) { | 1112 | if (!ibnl_chk_listeners(RDMA_NL_GROUP_LS)) { |
| 1111 | if (!ib_nl_make_request(query)) | 1113 | if (!ib_nl_make_request(query, gfp_mask)) |
| 1112 | return id; | 1114 | return id; |
| 1113 | } | 1115 | } |
| 1114 | ib_sa_disable_local_svc(query); | 1116 | ib_sa_disable_local_svc(query); |
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 94816aeb95a0..1c02deab068f 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
| @@ -62,9 +62,11 @@ static struct uverbs_lock_class rule_lock_class = { .name = "RULE-uobj" }; | |||
| 62 | * The ib_uobject locking scheme is as follows: | 62 | * The ib_uobject locking scheme is as follows: |
| 63 | * | 63 | * |
| 64 | * - ib_uverbs_idr_lock protects the uverbs idrs themselves, so it | 64 | * - ib_uverbs_idr_lock protects the uverbs idrs themselves, so it |
| 65 | * needs to be held during all idr operations. When an object is | 65 | * needs to be held during all idr write operations. When an object is |
| 66 | * looked up, a reference must be taken on the object's kref before | 66 | * looked up, a reference must be taken on the object's kref before |
| 67 | * dropping this lock. | 67 | * dropping this lock. For read operations, the rcu_read_lock() |
| 68 | * and rcu_write_lock() but similarly the kref reference is grabbed | ||
| 69 | * before the rcu_read_unlock(). | ||
| 68 | * | 70 | * |
| 69 | * - Each object also has an rwsem. This rwsem must be held for | 71 | * - Each object also has an rwsem. This rwsem must be held for |
| 70 | * reading while an operation that uses the object is performed. | 72 | * reading while an operation that uses the object is performed. |
| @@ -96,7 +98,7 @@ static void init_uobj(struct ib_uobject *uobj, u64 user_handle, | |||
| 96 | 98 | ||
| 97 | static void release_uobj(struct kref *kref) | 99 | static void release_uobj(struct kref *kref) |
| 98 | { | 100 | { |
| 99 | kfree(container_of(kref, struct ib_uobject, ref)); | 101 | kfree_rcu(container_of(kref, struct ib_uobject, ref), rcu); |
| 100 | } | 102 | } |
| 101 | 103 | ||
| 102 | static void put_uobj(struct ib_uobject *uobj) | 104 | static void put_uobj(struct ib_uobject *uobj) |
| @@ -145,7 +147,7 @@ static struct ib_uobject *__idr_get_uobj(struct idr *idr, int id, | |||
| 145 | { | 147 | { |
| 146 | struct ib_uobject *uobj; | 148 | struct ib_uobject *uobj; |
| 147 | 149 | ||
| 148 | spin_lock(&ib_uverbs_idr_lock); | 150 | rcu_read_lock(); |
| 149 | uobj = idr_find(idr, id); | 151 | uobj = idr_find(idr, id); |
| 150 | if (uobj) { | 152 | if (uobj) { |
| 151 | if (uobj->context == context) | 153 | if (uobj->context == context) |
| @@ -153,7 +155,7 @@ static struct ib_uobject *__idr_get_uobj(struct idr *idr, int id, | |||
| 153 | else | 155 | else |
| 154 | uobj = NULL; | 156 | uobj = NULL; |
| 155 | } | 157 | } |
| 156 | spin_unlock(&ib_uverbs_idr_lock); | 158 | rcu_read_unlock(); |
| 157 | 159 | ||
| 158 | return uobj; | 160 | return uobj; |
| 159 | } | 161 | } |
| @@ -2446,6 +2448,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, | |||
| 2446 | int i, sg_ind; | 2448 | int i, sg_ind; |
| 2447 | int is_ud; | 2449 | int is_ud; |
| 2448 | ssize_t ret = -EINVAL; | 2450 | ssize_t ret = -EINVAL; |
| 2451 | size_t next_size; | ||
| 2449 | 2452 | ||
| 2450 | if (copy_from_user(&cmd, buf, sizeof cmd)) | 2453 | if (copy_from_user(&cmd, buf, sizeof cmd)) |
| 2451 | return -EFAULT; | 2454 | return -EFAULT; |
| @@ -2490,7 +2493,8 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, | |||
| 2490 | goto out_put; | 2493 | goto out_put; |
| 2491 | } | 2494 | } |
| 2492 | 2495 | ||
| 2493 | ud = alloc_wr(sizeof(*ud), user_wr->num_sge); | 2496 | next_size = sizeof(*ud); |
| 2497 | ud = alloc_wr(next_size, user_wr->num_sge); | ||
| 2494 | if (!ud) { | 2498 | if (!ud) { |
| 2495 | ret = -ENOMEM; | 2499 | ret = -ENOMEM; |
| 2496 | goto out_put; | 2500 | goto out_put; |
| @@ -2511,7 +2515,8 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, | |||
| 2511 | user_wr->opcode == IB_WR_RDMA_READ) { | 2515 | user_wr->opcode == IB_WR_RDMA_READ) { |
| 2512 | struct ib_rdma_wr *rdma; | 2516 | struct ib_rdma_wr *rdma; |
| 2513 | 2517 | ||
| 2514 | rdma = alloc_wr(sizeof(*rdma), user_wr->num_sge); | 2518 | next_size = sizeof(*rdma); |
| 2519 | rdma = alloc_wr(next_size, user_wr->num_sge); | ||
| 2515 | if (!rdma) { | 2520 | if (!rdma) { |
| 2516 | ret = -ENOMEM; | 2521 | ret = -ENOMEM; |
| 2517 | goto out_put; | 2522 | goto out_put; |
| @@ -2525,7 +2530,8 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, | |||
| 2525 | user_wr->opcode == IB_WR_ATOMIC_FETCH_AND_ADD) { | 2530 | user_wr->opcode == IB_WR_ATOMIC_FETCH_AND_ADD) { |
| 2526 | struct ib_atomic_wr *atomic; | 2531 | struct ib_atomic_wr *atomic; |
| 2527 | 2532 | ||
| 2528 | atomic = alloc_wr(sizeof(*atomic), user_wr->num_sge); | 2533 | next_size = sizeof(*atomic); |
| 2534 | atomic = alloc_wr(next_size, user_wr->num_sge); | ||
| 2529 | if (!atomic) { | 2535 | if (!atomic) { |
| 2530 | ret = -ENOMEM; | 2536 | ret = -ENOMEM; |
| 2531 | goto out_put; | 2537 | goto out_put; |
| @@ -2540,7 +2546,8 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, | |||
| 2540 | } else if (user_wr->opcode == IB_WR_SEND || | 2546 | } else if (user_wr->opcode == IB_WR_SEND || |
| 2541 | user_wr->opcode == IB_WR_SEND_WITH_IMM || | 2547 | user_wr->opcode == IB_WR_SEND_WITH_IMM || |
| 2542 | user_wr->opcode == IB_WR_SEND_WITH_INV) { | 2548 | user_wr->opcode == IB_WR_SEND_WITH_INV) { |
| 2543 | next = alloc_wr(sizeof(*next), user_wr->num_sge); | 2549 | next_size = sizeof(*next); |
| 2550 | next = alloc_wr(next_size, user_wr->num_sge); | ||
| 2544 | if (!next) { | 2551 | if (!next) { |
| 2545 | ret = -ENOMEM; | 2552 | ret = -ENOMEM; |
| 2546 | goto out_put; | 2553 | goto out_put; |
| @@ -2572,7 +2579,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, | |||
| 2572 | 2579 | ||
| 2573 | if (next->num_sge) { | 2580 | if (next->num_sge) { |
| 2574 | next->sg_list = (void *) next + | 2581 | next->sg_list = (void *) next + |
| 2575 | ALIGN(sizeof *next, sizeof (struct ib_sge)); | 2582 | ALIGN(next_size, sizeof(struct ib_sge)); |
| 2576 | if (copy_from_user(next->sg_list, | 2583 | if (copy_from_user(next->sg_list, |
| 2577 | buf + sizeof cmd + | 2584 | buf + sizeof cmd + |
| 2578 | cmd.wr_count * cmd.wqe_size + | 2585 | cmd.wr_count * cmd.wqe_size + |
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 043a60ee6836..545906dec26d 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c | |||
| @@ -1516,7 +1516,7 @@ EXPORT_SYMBOL(ib_map_mr_sg); | |||
| 1516 | * @sg_nents: number of entries in sg | 1516 | * @sg_nents: number of entries in sg |
| 1517 | * @set_page: driver page assignment function pointer | 1517 | * @set_page: driver page assignment function pointer |
| 1518 | * | 1518 | * |
| 1519 | * Core service helper for drivers to covert the largest | 1519 | * Core service helper for drivers to convert the largest |
| 1520 | * prefix of given sg list to a page vector. The sg list | 1520 | * prefix of given sg list to a page vector. The sg list |
| 1521 | * prefix converted is the prefix that meet the requirements | 1521 | * prefix converted is the prefix that meet the requirements |
| 1522 | * of ib_map_mr_sg. | 1522 | * of ib_map_mr_sg. |
| @@ -1533,7 +1533,7 @@ int ib_sg_to_pages(struct ib_mr *mr, | |||
| 1533 | u64 last_end_dma_addr = 0, last_page_addr = 0; | 1533 | u64 last_end_dma_addr = 0, last_page_addr = 0; |
| 1534 | unsigned int last_page_off = 0; | 1534 | unsigned int last_page_off = 0; |
| 1535 | u64 page_mask = ~((u64)mr->page_size - 1); | 1535 | u64 page_mask = ~((u64)mr->page_size - 1); |
| 1536 | int i; | 1536 | int i, ret; |
| 1537 | 1537 | ||
| 1538 | mr->iova = sg_dma_address(&sgl[0]); | 1538 | mr->iova = sg_dma_address(&sgl[0]); |
| 1539 | mr->length = 0; | 1539 | mr->length = 0; |
| @@ -1544,27 +1544,29 @@ int ib_sg_to_pages(struct ib_mr *mr, | |||
| 1544 | u64 end_dma_addr = dma_addr + dma_len; | 1544 | u64 end_dma_addr = dma_addr + dma_len; |
| 1545 | u64 page_addr = dma_addr & page_mask; | 1545 | u64 page_addr = dma_addr & page_mask; |
| 1546 | 1546 | ||
| 1547 | if (i && page_addr != dma_addr) { | 1547 | /* |
| 1548 | if (last_end_dma_addr != dma_addr) { | 1548 | * For the second and later elements, check whether either the |
| 1549 | /* gap */ | 1549 | * end of element i-1 or the start of element i is not aligned |
| 1550 | goto done; | 1550 | * on a page boundary. |
| 1551 | 1551 | */ | |
| 1552 | } else if (last_page_off + dma_len <= mr->page_size) { | 1552 | if (i && (last_page_off != 0 || page_addr != dma_addr)) { |
| 1553 | /* chunk this fragment with the last */ | 1553 | /* Stop mapping if there is a gap. */ |
| 1554 | mr->length += dma_len; | 1554 | if (last_end_dma_addr != dma_addr) |
| 1555 | last_end_dma_addr += dma_len; | 1555 | break; |
| 1556 | last_page_off += dma_len; | 1556 | |
| 1557 | continue; | 1557 | /* |
| 1558 | } else { | 1558 | * Coalesce this element with the last. If it is small |
| 1559 | /* map starting from the next page */ | 1559 | * enough just update mr->length. Otherwise start |
| 1560 | page_addr = last_page_addr + mr->page_size; | 1560 | * mapping from the next page. |
| 1561 | dma_len -= mr->page_size - last_page_off; | 1561 | */ |
| 1562 | } | 1562 | goto next_page; |
| 1563 | } | 1563 | } |
| 1564 | 1564 | ||
| 1565 | do { | 1565 | do { |
| 1566 | if (unlikely(set_page(mr, page_addr))) | 1566 | ret = set_page(mr, page_addr); |
| 1567 | goto done; | 1567 | if (unlikely(ret < 0)) |
| 1568 | return i ? : ret; | ||
| 1569 | next_page: | ||
| 1568 | page_addr += mr->page_size; | 1570 | page_addr += mr->page_size; |
| 1569 | } while (page_addr < end_dma_addr); | 1571 | } while (page_addr < end_dma_addr); |
| 1570 | 1572 | ||
| @@ -1574,7 +1576,6 @@ int ib_sg_to_pages(struct ib_mr *mr, | |||
| 1574 | last_page_off = end_dma_addr & ~page_mask; | 1576 | last_page_off = end_dma_addr & ~page_mask; |
| 1575 | } | 1577 | } |
| 1576 | 1578 | ||
| 1577 | done: | ||
| 1578 | return i; | 1579 | return i; |
| 1579 | } | 1580 | } |
| 1580 | EXPORT_SYMBOL(ib_sg_to_pages); | 1581 | EXPORT_SYMBOL(ib_sg_to_pages); |
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index f567160a4a56..97d6878f9938 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
| @@ -456,7 +456,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev, | |||
| 456 | props->max_qp_wr = dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE; | 456 | props->max_qp_wr = dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE; |
| 457 | props->max_sge = min(dev->dev->caps.max_sq_sg, | 457 | props->max_sge = min(dev->dev->caps.max_sq_sg, |
| 458 | dev->dev->caps.max_rq_sg); | 458 | dev->dev->caps.max_rq_sg); |
| 459 | props->max_sge_rd = props->max_sge; | 459 | props->max_sge_rd = MLX4_MAX_SGE_RD; |
| 460 | props->max_cq = dev->dev->quotas.cq; | 460 | props->max_cq = dev->dev->quotas.cq; |
| 461 | props->max_cqe = dev->dev->caps.max_cqes; | 461 | props->max_cqe = dev->dev->caps.max_cqes; |
| 462 | props->max_mr = dev->dev->quotas.mpt; | 462 | props->max_mr = dev->dev->quotas.mpt; |
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index a2e4ca56da44..13eaaf45288f 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/log2.h> | 34 | #include <linux/log2.h> |
| 35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
| 36 | #include <linux/netdevice.h> | 36 | #include <linux/netdevice.h> |
| 37 | #include <linux/vmalloc.h> | ||
| 37 | 38 | ||
| 38 | #include <rdma/ib_cache.h> | 39 | #include <rdma/ib_cache.h> |
| 39 | #include <rdma/ib_pack.h> | 40 | #include <rdma/ib_pack.h> |
| @@ -795,8 +796,14 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, | |||
| 795 | if (err) | 796 | if (err) |
| 796 | goto err_mtt; | 797 | goto err_mtt; |
| 797 | 798 | ||
| 798 | qp->sq.wrid = kmalloc(qp->sq.wqe_cnt * sizeof (u64), gfp); | 799 | qp->sq.wrid = kmalloc(qp->sq.wqe_cnt * sizeof(u64), gfp); |
| 799 | qp->rq.wrid = kmalloc(qp->rq.wqe_cnt * sizeof (u64), gfp); | 800 | if (!qp->sq.wrid) |
| 801 | qp->sq.wrid = __vmalloc(qp->sq.wqe_cnt * sizeof(u64), | ||
| 802 | gfp, PAGE_KERNEL); | ||
| 803 | qp->rq.wrid = kmalloc(qp->rq.wqe_cnt * sizeof(u64), gfp); | ||
| 804 | if (!qp->rq.wrid) | ||
| 805 | qp->rq.wrid = __vmalloc(qp->rq.wqe_cnt * sizeof(u64), | ||
| 806 | gfp, PAGE_KERNEL); | ||
| 800 | if (!qp->sq.wrid || !qp->rq.wrid) { | 807 | if (!qp->sq.wrid || !qp->rq.wrid) { |
| 801 | err = -ENOMEM; | 808 | err = -ENOMEM; |
| 802 | goto err_wrid; | 809 | goto err_wrid; |
| @@ -886,8 +893,8 @@ err_wrid: | |||
| 886 | if (qp_has_rq(init_attr)) | 893 | if (qp_has_rq(init_attr)) |
| 887 | mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), &qp->db); | 894 | mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), &qp->db); |
| 888 | } else { | 895 | } else { |
| 889 | kfree(qp->sq.wrid); | 896 | kvfree(qp->sq.wrid); |
| 890 | kfree(qp->rq.wrid); | 897 | kvfree(qp->rq.wrid); |
| 891 | } | 898 | } |
| 892 | 899 | ||
| 893 | err_mtt: | 900 | err_mtt: |
| @@ -1062,8 +1069,8 @@ static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp, | |||
| 1062 | &qp->db); | 1069 | &qp->db); |
| 1063 | ib_umem_release(qp->umem); | 1070 | ib_umem_release(qp->umem); |
| 1064 | } else { | 1071 | } else { |
| 1065 | kfree(qp->sq.wrid); | 1072 | kvfree(qp->sq.wrid); |
| 1066 | kfree(qp->rq.wrid); | 1073 | kvfree(qp->rq.wrid); |
| 1067 | if (qp->mlx4_ib_qp_type & (MLX4_IB_QPT_PROXY_SMI_OWNER | | 1074 | if (qp->mlx4_ib_qp_type & (MLX4_IB_QPT_PROXY_SMI_OWNER | |
| 1068 | MLX4_IB_QPT_PROXY_SMI | MLX4_IB_QPT_PROXY_GSI)) | 1075 | MLX4_IB_QPT_PROXY_SMI | MLX4_IB_QPT_PROXY_GSI)) |
| 1069 | free_proxy_bufs(&dev->ib_dev, qp); | 1076 | free_proxy_bufs(&dev->ib_dev, qp); |
diff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index dce5dfe3a70e..8d133c40fa0e 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/mlx4/qp.h> | 34 | #include <linux/mlx4/qp.h> |
| 35 | #include <linux/mlx4/srq.h> | 35 | #include <linux/mlx4/srq.h> |
| 36 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
| 37 | #include <linux/vmalloc.h> | ||
| 37 | 38 | ||
| 38 | #include "mlx4_ib.h" | 39 | #include "mlx4_ib.h" |
| 39 | #include "user.h" | 40 | #include "user.h" |
| @@ -172,8 +173,12 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd, | |||
| 172 | 173 | ||
| 173 | srq->wrid = kmalloc(srq->msrq.max * sizeof (u64), GFP_KERNEL); | 174 | srq->wrid = kmalloc(srq->msrq.max * sizeof (u64), GFP_KERNEL); |
| 174 | if (!srq->wrid) { | 175 | if (!srq->wrid) { |
| 175 | err = -ENOMEM; | 176 | srq->wrid = __vmalloc(srq->msrq.max * sizeof(u64), |
| 176 | goto err_mtt; | 177 | GFP_KERNEL, PAGE_KERNEL); |
| 178 | if (!srq->wrid) { | ||
| 179 | err = -ENOMEM; | ||
| 180 | goto err_mtt; | ||
| 181 | } | ||
| 177 | } | 182 | } |
| 178 | } | 183 | } |
| 179 | 184 | ||
| @@ -204,7 +209,7 @@ err_wrid: | |||
| 204 | if (pd->uobject) | 209 | if (pd->uobject) |
| 205 | mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), &srq->db); | 210 | mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), &srq->db); |
| 206 | else | 211 | else |
| 207 | kfree(srq->wrid); | 212 | kvfree(srq->wrid); |
| 208 | 213 | ||
| 209 | err_mtt: | 214 | err_mtt: |
| 210 | mlx4_mtt_cleanup(dev->dev, &srq->mtt); | 215 | mlx4_mtt_cleanup(dev->dev, &srq->mtt); |
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index ec8993a7b3be..6000f7aeede9 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c | |||
| @@ -381,7 +381,19 @@ static void __cache_work_func(struct mlx5_cache_ent *ent) | |||
| 381 | } | 381 | } |
| 382 | } | 382 | } |
| 383 | } else if (ent->cur > 2 * ent->limit) { | 383 | } else if (ent->cur > 2 * ent->limit) { |
| 384 | if (!someone_adding(cache) && | 384 | /* |
| 385 | * The remove_keys() logic is performed as garbage collection | ||
| 386 | * task. Such task is intended to be run when no other active | ||
| 387 | * processes are running. | ||
| 388 | * | ||
| 389 | * The need_resched() will return TRUE if there are user tasks | ||
| 390 | * to be activated in near future. | ||
| 391 | * | ||
| 392 | * In such case, we don't execute remove_keys() and postpone | ||
| 393 | * the garbage collection work to try to run in next cycle, | ||
| 394 | * in order to free CPU resources to other tasks. | ||
| 395 | */ | ||
| 396 | if (!need_resched() && !someone_adding(cache) && | ||
| 385 | time_after(jiffies, cache->last_add + 300 * HZ)) { | 397 | time_after(jiffies, cache->last_add + 300 * HZ)) { |
| 386 | remove_keys(dev, i, 1); | 398 | remove_keys(dev, i, 1); |
| 387 | if (ent->cur > ent->limit) | 399 | if (ent->cur > ent->limit) |
diff --git a/drivers/infiniband/hw/qib/qib_qsfp.c b/drivers/infiniband/hw/qib/qib_qsfp.c index 5e27f76805e2..4c7c3c84a741 100644 --- a/drivers/infiniband/hw/qib/qib_qsfp.c +++ b/drivers/infiniband/hw/qib/qib_qsfp.c | |||
| @@ -292,7 +292,7 @@ int qib_refresh_qsfp_cache(struct qib_pportdata *ppd, struct qib_qsfp_cache *cp) | |||
| 292 | qib_dev_porterr(ppd->dd, ppd->port, | 292 | qib_dev_porterr(ppd->dd, ppd->port, |
| 293 | "QSFP byte0 is 0x%02X, S/B 0x0C/D\n", peek[0]); | 293 | "QSFP byte0 is 0x%02X, S/B 0x0C/D\n", peek[0]); |
| 294 | 294 | ||
| 295 | if ((peek[2] & 2) == 0) { | 295 | if ((peek[2] & 4) == 0) { |
| 296 | /* | 296 | /* |
| 297 | * If cable is paged, rather than "flat memory", we need to | 297 | * If cable is paged, rather than "flat memory", we need to |
| 298 | * set the page to zero, Even if it already appears to be zero. | 298 | * set the page to zero, Even if it already appears to be zero. |
| @@ -538,7 +538,7 @@ int qib_qsfp_dump(struct qib_pportdata *ppd, char *buf, int len) | |||
| 538 | sofar += scnprintf(buf + sofar, len - sofar, "Date:%.*s\n", | 538 | sofar += scnprintf(buf + sofar, len - sofar, "Date:%.*s\n", |
| 539 | QSFP_DATE_LEN, cd.date); | 539 | QSFP_DATE_LEN, cd.date); |
| 540 | sofar += scnprintf(buf + sofar, len - sofar, "Lot:%.*s\n", | 540 | sofar += scnprintf(buf + sofar, len - sofar, "Lot:%.*s\n", |
| 541 | QSFP_LOT_LEN, cd.date); | 541 | QSFP_LOT_LEN, cd.lot); |
| 542 | 542 | ||
| 543 | while (bidx < QSFP_DEFAULT_HDR_CNT) { | 543 | while (bidx < QSFP_DEFAULT_HDR_CNT) { |
| 544 | int iidx; | 544 | int iidx; |
diff --git a/drivers/infiniband/hw/qib/qib_verbs.h b/drivers/infiniband/hw/qib/qib_verbs.h index 2baf5ad251ed..bc803f33d5f6 100644 --- a/drivers/infiniband/hw/qib/qib_verbs.h +++ b/drivers/infiniband/hw/qib/qib_verbs.h | |||
| @@ -329,9 +329,9 @@ struct qib_sge { | |||
| 329 | struct qib_mr { | 329 | struct qib_mr { |
| 330 | struct ib_mr ibmr; | 330 | struct ib_mr ibmr; |
| 331 | struct ib_umem *umem; | 331 | struct ib_umem *umem; |
| 332 | struct qib_mregion mr; /* must be last */ | ||
| 333 | u64 *pages; | 332 | u64 *pages; |
| 334 | u32 npages; | 333 | u32 npages; |
| 334 | struct qib_mregion mr; /* must be last */ | ||
| 335 | }; | 335 | }; |
| 336 | 336 | ||
| 337 | /* | 337 | /* |
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index a93070210109..42f4da620f2e 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c | |||
| @@ -1293,7 +1293,7 @@ u8 iser_check_task_pi_status(struct iscsi_iser_task *iser_task, | |||
| 1293 | if (mr_status.fail_status & IB_MR_CHECK_SIG_STATUS) { | 1293 | if (mr_status.fail_status & IB_MR_CHECK_SIG_STATUS) { |
| 1294 | sector_t sector_off = mr_status.sig_err.sig_err_offset; | 1294 | sector_t sector_off = mr_status.sig_err.sig_err_offset; |
| 1295 | 1295 | ||
| 1296 | do_div(sector_off, sector_size + 8); | 1296 | sector_div(sector_off, sector_size + 8); |
| 1297 | *sector = scsi_get_lba(iser_task->sc) + sector_off; | 1297 | *sector = scsi_get_lba(iser_task->sc) + sector_off; |
| 1298 | 1298 | ||
| 1299 | pr_err("PI error found type %d at sector %llx " | 1299 | pr_err("PI error found type %d at sector %llx " |
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index dfbbbb28090b..8a51c3b5d657 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c | |||
| @@ -157,16 +157,9 @@ isert_create_qp(struct isert_conn *isert_conn, | |||
| 157 | attr.recv_cq = comp->cq; | 157 | attr.recv_cq = comp->cq; |
| 158 | attr.cap.max_send_wr = ISERT_QP_MAX_REQ_DTOS; | 158 | attr.cap.max_send_wr = ISERT_QP_MAX_REQ_DTOS; |
| 159 | attr.cap.max_recv_wr = ISERT_QP_MAX_RECV_DTOS + 1; | 159 | attr.cap.max_recv_wr = ISERT_QP_MAX_RECV_DTOS + 1; |
| 160 | /* | 160 | attr.cap.max_send_sge = device->dev_attr.max_sge; |
| 161 | * FIXME: Use devattr.max_sge - 2 for max_send_sge as | 161 | isert_conn->max_sge = min(device->dev_attr.max_sge, |
| 162 | * work-around for RDMA_READs with ConnectX-2. | 162 | device->dev_attr.max_sge_rd); |
| 163 | * | ||
| 164 | * Also, still make sure to have at least two SGEs for | ||
| 165 | * outgoing control PDU responses. | ||
| 166 | */ | ||
| 167 | attr.cap.max_send_sge = max(2, device->dev_attr.max_sge - 2); | ||
| 168 | isert_conn->max_sge = attr.cap.max_send_sge; | ||
| 169 | |||
| 170 | attr.cap.max_recv_sge = 1; | 163 | attr.cap.max_recv_sge = 1; |
| 171 | attr.sq_sig_type = IB_SIGNAL_REQ_WR; | 164 | attr.sq_sig_type = IB_SIGNAL_REQ_WR; |
| 172 | attr.qp_type = IB_QPT_RC; | 165 | attr.qp_type = IB_QPT_RC; |
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 9909022dc6c3..3db9a659719b 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
| @@ -488,7 +488,7 @@ static int srp_create_ch_ib(struct srp_rdma_ch *ch) | |||
| 488 | struct ib_qp *qp; | 488 | struct ib_qp *qp; |
| 489 | struct ib_fmr_pool *fmr_pool = NULL; | 489 | struct ib_fmr_pool *fmr_pool = NULL; |
| 490 | struct srp_fr_pool *fr_pool = NULL; | 490 | struct srp_fr_pool *fr_pool = NULL; |
| 491 | const int m = 1 + dev->use_fast_reg; | 491 | const int m = dev->use_fast_reg ? 3 : 1; |
| 492 | struct ib_cq_init_attr cq_attr = {}; | 492 | struct ib_cq_init_attr cq_attr = {}; |
| 493 | int ret; | 493 | int ret; |
| 494 | 494 | ||
| @@ -994,16 +994,16 @@ static int srp_connect_ch(struct srp_rdma_ch *ch, bool multich) | |||
| 994 | 994 | ||
| 995 | ret = srp_lookup_path(ch); | 995 | ret = srp_lookup_path(ch); |
| 996 | if (ret) | 996 | if (ret) |
| 997 | return ret; | 997 | goto out; |
| 998 | 998 | ||
| 999 | while (1) { | 999 | while (1) { |
| 1000 | init_completion(&ch->done); | 1000 | init_completion(&ch->done); |
| 1001 | ret = srp_send_req(ch, multich); | 1001 | ret = srp_send_req(ch, multich); |
| 1002 | if (ret) | 1002 | if (ret) |
| 1003 | return ret; | 1003 | goto out; |
| 1004 | ret = wait_for_completion_interruptible(&ch->done); | 1004 | ret = wait_for_completion_interruptible(&ch->done); |
| 1005 | if (ret < 0) | 1005 | if (ret < 0) |
| 1006 | return ret; | 1006 | goto out; |
| 1007 | 1007 | ||
| 1008 | /* | 1008 | /* |
| 1009 | * The CM event handling code will set status to | 1009 | * The CM event handling code will set status to |
| @@ -1011,15 +1011,16 @@ static int srp_connect_ch(struct srp_rdma_ch *ch, bool multich) | |||
| 1011 | * back, or SRP_DLID_REDIRECT if we get a lid/qp | 1011 | * back, or SRP_DLID_REDIRECT if we get a lid/qp |
| 1012 | * redirect REJ back. | 1012 | * redirect REJ back. |
| 1013 | */ | 1013 | */ |
| 1014 | switch (ch->status) { | 1014 | ret = ch->status; |
| 1015 | switch (ret) { | ||
| 1015 | case 0: | 1016 | case 0: |
| 1016 | ch->connected = true; | 1017 | ch->connected = true; |
| 1017 | return 0; | 1018 | goto out; |
| 1018 | 1019 | ||
| 1019 | case SRP_PORT_REDIRECT: | 1020 | case SRP_PORT_REDIRECT: |
| 1020 | ret = srp_lookup_path(ch); | 1021 | ret = srp_lookup_path(ch); |
| 1021 | if (ret) | 1022 | if (ret) |
| 1022 | return ret; | 1023 | goto out; |
| 1023 | break; | 1024 | break; |
| 1024 | 1025 | ||
| 1025 | case SRP_DLID_REDIRECT: | 1026 | case SRP_DLID_REDIRECT: |
| @@ -1028,13 +1029,16 @@ static int srp_connect_ch(struct srp_rdma_ch *ch, bool multich) | |||
| 1028 | case SRP_STALE_CONN: | 1029 | case SRP_STALE_CONN: |
| 1029 | shost_printk(KERN_ERR, target->scsi_host, PFX | 1030 | shost_printk(KERN_ERR, target->scsi_host, PFX |
| 1030 | "giving up on stale connection\n"); | 1031 | "giving up on stale connection\n"); |
| 1031 | ch->status = -ECONNRESET; | 1032 | ret = -ECONNRESET; |
| 1032 | return ch->status; | 1033 | goto out; |
| 1033 | 1034 | ||
| 1034 | default: | 1035 | default: |
| 1035 | return ch->status; | 1036 | goto out; |
| 1036 | } | 1037 | } |
| 1037 | } | 1038 | } |
| 1039 | |||
| 1040 | out: | ||
| 1041 | return ret <= 0 ? ret : -ENODEV; | ||
| 1038 | } | 1042 | } |
| 1039 | 1043 | ||
| 1040 | static int srp_inv_rkey(struct srp_rdma_ch *ch, u32 rkey) | 1044 | static int srp_inv_rkey(struct srp_rdma_ch *ch, u32 rkey) |
| @@ -1309,7 +1313,7 @@ reset_state: | |||
| 1309 | } | 1313 | } |
| 1310 | 1314 | ||
| 1311 | static int srp_map_finish_fr(struct srp_map_state *state, | 1315 | static int srp_map_finish_fr(struct srp_map_state *state, |
| 1312 | struct srp_rdma_ch *ch) | 1316 | struct srp_rdma_ch *ch, int sg_nents) |
| 1313 | { | 1317 | { |
| 1314 | struct srp_target_port *target = ch->target; | 1318 | struct srp_target_port *target = ch->target; |
| 1315 | struct srp_device *dev = target->srp_host->srp_dev; | 1319 | struct srp_device *dev = target->srp_host->srp_dev; |
| @@ -1324,10 +1328,10 @@ static int srp_map_finish_fr(struct srp_map_state *state, | |||
| 1324 | 1328 | ||
| 1325 | WARN_ON_ONCE(!dev->use_fast_reg); | 1329 | WARN_ON_ONCE(!dev->use_fast_reg); |
| 1326 | 1330 | ||
| 1327 | if (state->sg_nents == 0) | 1331 | if (sg_nents == 0) |
| 1328 | return 0; | 1332 | return 0; |
| 1329 | 1333 | ||
| 1330 | if (state->sg_nents == 1 && target->global_mr) { | 1334 | if (sg_nents == 1 && target->global_mr) { |
| 1331 | srp_map_desc(state, sg_dma_address(state->sg), | 1335 | srp_map_desc(state, sg_dma_address(state->sg), |
| 1332 | sg_dma_len(state->sg), | 1336 | sg_dma_len(state->sg), |
| 1333 | target->global_mr->rkey); | 1337 | target->global_mr->rkey); |
| @@ -1341,8 +1345,7 @@ static int srp_map_finish_fr(struct srp_map_state *state, | |||
| 1341 | rkey = ib_inc_rkey(desc->mr->rkey); | 1345 | rkey = ib_inc_rkey(desc->mr->rkey); |
| 1342 | ib_update_fast_reg_key(desc->mr, rkey); | 1346 | ib_update_fast_reg_key(desc->mr, rkey); |
| 1343 | 1347 | ||
| 1344 | n = ib_map_mr_sg(desc->mr, state->sg, state->sg_nents, | 1348 | n = ib_map_mr_sg(desc->mr, state->sg, sg_nents, dev->mr_page_size); |
| 1345 | dev->mr_page_size); | ||
| 1346 | if (unlikely(n < 0)) | 1349 | if (unlikely(n < 0)) |
| 1347 | return n; | 1350 | return n; |
| 1348 | 1351 | ||
| @@ -1448,16 +1451,15 @@ static int srp_map_sg_fr(struct srp_map_state *state, struct srp_rdma_ch *ch, | |||
| 1448 | state->fr.next = req->fr_list; | 1451 | state->fr.next = req->fr_list; |
| 1449 | state->fr.end = req->fr_list + ch->target->cmd_sg_cnt; | 1452 | state->fr.end = req->fr_list + ch->target->cmd_sg_cnt; |
| 1450 | state->sg = scat; | 1453 | state->sg = scat; |
| 1451 | state->sg_nents = scsi_sg_count(req->scmnd); | ||
| 1452 | 1454 | ||
| 1453 | while (state->sg_nents) { | 1455 | while (count) { |
| 1454 | int i, n; | 1456 | int i, n; |
| 1455 | 1457 | ||
| 1456 | n = srp_map_finish_fr(state, ch); | 1458 | n = srp_map_finish_fr(state, ch, count); |
| 1457 | if (unlikely(n < 0)) | 1459 | if (unlikely(n < 0)) |
| 1458 | return n; | 1460 | return n; |
| 1459 | 1461 | ||
| 1460 | state->sg_nents -= n; | 1462 | count -= n; |
| 1461 | for (i = 0; i < n; i++) | 1463 | for (i = 0; i < n; i++) |
| 1462 | state->sg = sg_next(state->sg); | 1464 | state->sg = sg_next(state->sg); |
| 1463 | } | 1465 | } |
| @@ -1517,10 +1519,12 @@ static int srp_map_idb(struct srp_rdma_ch *ch, struct srp_request *req, | |||
| 1517 | 1519 | ||
| 1518 | if (dev->use_fast_reg) { | 1520 | if (dev->use_fast_reg) { |
| 1519 | state.sg = idb_sg; | 1521 | state.sg = idb_sg; |
| 1520 | state.sg_nents = 1; | ||
| 1521 | sg_set_buf(idb_sg, req->indirect_desc, idb_len); | 1522 | sg_set_buf(idb_sg, req->indirect_desc, idb_len); |
| 1522 | idb_sg->dma_address = req->indirect_dma_addr; /* hack! */ | 1523 | idb_sg->dma_address = req->indirect_dma_addr; /* hack! */ |
| 1523 | ret = srp_map_finish_fr(&state, ch); | 1524 | #ifdef CONFIG_NEED_SG_DMA_LENGTH |
| 1525 | idb_sg->dma_length = idb_sg->length; /* hack^2 */ | ||
| 1526 | #endif | ||
| 1527 | ret = srp_map_finish_fr(&state, ch, 1); | ||
| 1524 | if (ret < 0) | 1528 | if (ret < 0) |
| 1525 | return ret; | 1529 | return ret; |
| 1526 | } else if (dev->use_fmr) { | 1530 | } else if (dev->use_fmr) { |
| @@ -1655,7 +1659,7 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_rdma_ch *ch, | |||
| 1655 | return ret; | 1659 | return ret; |
| 1656 | req->nmdesc++; | 1660 | req->nmdesc++; |
| 1657 | } else { | 1661 | } else { |
| 1658 | idb_rkey = target->global_mr->rkey; | 1662 | idb_rkey = cpu_to_be32(target->global_mr->rkey); |
| 1659 | } | 1663 | } |
| 1660 | 1664 | ||
| 1661 | indirect_hdr->table_desc.va = cpu_to_be64(req->indirect_dma_addr); | 1665 | indirect_hdr->table_desc.va = cpu_to_be64(req->indirect_dma_addr); |
diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h index 87a2a919dc43..f6af531f9f32 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.h +++ b/drivers/infiniband/ulp/srp/ib_srp.h | |||
| @@ -300,10 +300,7 @@ struct srp_map_state { | |||
| 300 | dma_addr_t base_dma_addr; | 300 | dma_addr_t base_dma_addr; |
| 301 | u32 dma_len; | 301 | u32 dma_len; |
| 302 | u32 total_len; | 302 | u32 total_len; |
| 303 | union { | 303 | unsigned int npages; |
| 304 | unsigned int npages; | ||
| 305 | int sg_nents; | ||
| 306 | }; | ||
| 307 | unsigned int nmdesc; | 304 | unsigned int nmdesc; |
| 308 | unsigned int ndesc; | 305 | unsigned int ndesc; |
| 309 | }; | 306 | }; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 2177e56ed0be..d48d5793407d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c | |||
| @@ -1010,7 +1010,7 @@ static int mlx4_MAD_IFC_wrapper(struct mlx4_dev *dev, int slave, | |||
| 1010 | if (!(smp->mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED && | 1010 | if (!(smp->mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED && |
| 1011 | smp->method == IB_MGMT_METHOD_GET) || network_view) { | 1011 | smp->method == IB_MGMT_METHOD_GET) || network_view) { |
| 1012 | mlx4_err(dev, "Unprivileged slave %d is trying to execute a Subnet MGMT MAD, class 0x%x, method 0x%x, view=%s for attr 0x%x. Rejecting\n", | 1012 | mlx4_err(dev, "Unprivileged slave %d is trying to execute a Subnet MGMT MAD, class 0x%x, method 0x%x, view=%s for attr 0x%x. Rejecting\n", |
| 1013 | slave, smp->method, smp->mgmt_class, | 1013 | slave, smp->mgmt_class, smp->method, |
| 1014 | network_view ? "Network" : "Host", | 1014 | network_view ? "Network" : "Host", |
| 1015 | be16_to_cpu(smp->attr_id)); | 1015 | be16_to_cpu(smp->attr_id)); |
| 1016 | return -EPERM; | 1016 | return -EPERM; |
