You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'rdma-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband
Pull infiniband updates from Roland Dreier:
"Main batch of InfiniBand/RDMA changes for 3.19:
- On-demand paging support in core midlayer and mlx5 driver. This
lets userspace create non-pinned memory regions and have the
adapter HW trigger page faults.
- iSER and IPoIB updates and fixes.
- Low-level HW driver updates for cxgb4, mlx4 and ocrdma.
- Other miscellaneous fixes"
* tag 'rdma-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband: (56 commits)
IB/mlx5: Implement on demand paging by adding support for MMU notifiers
IB/mlx5: Add support for RDMA read/write responder page faults
IB/mlx5: Handle page faults
IB/mlx5: Page faults handling infrastructure
IB/mlx5: Add mlx5_ib_update_mtt to update page tables after creation
IB/mlx5: Changes in memory region creation to support on-demand paging
IB/mlx5: Implement the ODP capability query verb
mlx5_core: Add support for page faults events and low level handling
mlx5_core: Re-add MLX5_DEV_CAP_FLAG_ON_DMND_PG flag
IB/srp: Allow newline separator for connection string
IB/core: Implement support for MMU notifiers regarding on demand paging regions
IB/core: Add support for on demand paging regions
IB/core: Add flags for on demand paging support
IB/core: Add support for extended query device caps
IB/mlx5: Add function to read WQE from user-space
IB/core: Add umem function to read data from user-space
IB/core: Replace ib_umem's offset field with a full address
IB/mlx5: Enhance UMR support to allow partial page table update
IB/mlx5: Remove per-MR pas and dma pointers
RDMA/ocrdma: Always resolve destination mac from GRH for UD QPs
...
This commit is contained in:
@@ -38,6 +38,17 @@ config INFINIBAND_USER_MEM
|
|||||||
depends on INFINIBAND_USER_ACCESS != n
|
depends on INFINIBAND_USER_ACCESS != n
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config INFINIBAND_ON_DEMAND_PAGING
|
||||||
|
bool "InfiniBand on-demand paging support"
|
||||||
|
depends on INFINIBAND_USER_MEM
|
||||||
|
select MMU_NOTIFIER
|
||||||
|
default y
|
||||||
|
---help---
|
||||||
|
On demand paging support for the InfiniBand subsystem.
|
||||||
|
Together with driver support this allows registration of
|
||||||
|
memory regions without pinning their pages, fetching the
|
||||||
|
pages on demand instead.
|
||||||
|
|
||||||
config INFINIBAND_ADDR_TRANS
|
config INFINIBAND_ADDR_TRANS
|
||||||
bool
|
bool
|
||||||
depends on INFINIBAND
|
depends on INFINIBAND
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ obj-$(CONFIG_INFINIBAND_USER_ACCESS) += ib_uverbs.o ib_ucm.o \
|
|||||||
ib_core-y := packer.o ud_header.o verbs.o sysfs.o \
|
ib_core-y := packer.o ud_header.o verbs.o sysfs.o \
|
||||||
device.o fmr_pool.o cache.o netlink.o
|
device.o fmr_pool.o cache.o netlink.o
|
||||||
ib_core-$(CONFIG_INFINIBAND_USER_MEM) += umem.o
|
ib_core-$(CONFIG_INFINIBAND_USER_MEM) += umem.o
|
||||||
|
ib_core-$(CONFIG_INFINIBAND_ON_DEMAND_PAGING) += umem_odp.o umem_rbtree.o
|
||||||
|
|
||||||
ib_mad-y := mad.o smi.o agent.o mad_rmpp.o
|
ib_mad-y := mad.o smi.o agent.o mad_rmpp.o
|
||||||
|
|
||||||
|
|||||||
@@ -176,8 +176,8 @@ static void set_timeout(unsigned long time)
|
|||||||
unsigned long delay;
|
unsigned long delay;
|
||||||
|
|
||||||
delay = time - jiffies;
|
delay = time - jiffies;
|
||||||
if ((long)delay <= 0)
|
if ((long)delay < 0)
|
||||||
delay = 1;
|
delay = 0;
|
||||||
|
|
||||||
mod_delayed_work(addr_wq, &work, delay);
|
mod_delayed_work(addr_wq, &work, delay);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -525,17 +525,22 @@ static void join_handler(int status, struct ib_sa_mcmember_rec *rec,
|
|||||||
if (status)
|
if (status)
|
||||||
process_join_error(group, status);
|
process_join_error(group, status);
|
||||||
else {
|
else {
|
||||||
|
int mgids_changed, is_mgid0;
|
||||||
ib_find_pkey(group->port->dev->device, group->port->port_num,
|
ib_find_pkey(group->port->dev->device, group->port->port_num,
|
||||||
be16_to_cpu(rec->pkey), &pkey_index);
|
be16_to_cpu(rec->pkey), &pkey_index);
|
||||||
|
|
||||||
spin_lock_irq(&group->port->lock);
|
spin_lock_irq(&group->port->lock);
|
||||||
group->rec = *rec;
|
|
||||||
if (group->state == MCAST_BUSY &&
|
if (group->state == MCAST_BUSY &&
|
||||||
group->pkey_index == MCAST_INVALID_PKEY_INDEX)
|
group->pkey_index == MCAST_INVALID_PKEY_INDEX)
|
||||||
group->pkey_index = pkey_index;
|
group->pkey_index = pkey_index;
|
||||||
if (!memcmp(&mgid0, &group->rec.mgid, sizeof mgid0)) {
|
mgids_changed = memcmp(&rec->mgid, &group->rec.mgid,
|
||||||
|
sizeof(group->rec.mgid));
|
||||||
|
group->rec = *rec;
|
||||||
|
if (mgids_changed) {
|
||||||
rb_erase(&group->node, &group->port->table);
|
rb_erase(&group->node, &group->port->table);
|
||||||
mcast_insert(group->port, group, 1);
|
is_mgid0 = !memcmp(&mgid0, &group->rec.mgid,
|
||||||
|
sizeof(mgid0));
|
||||||
|
mcast_insert(group->port, group, is_mgid0);
|
||||||
}
|
}
|
||||||
spin_unlock_irq(&group->port->lock);
|
spin_unlock_irq(&group->port->lock);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
#include <linux/hugetlb.h>
|
#include <linux/hugetlb.h>
|
||||||
#include <linux/dma-attrs.h>
|
#include <linux/dma-attrs.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <rdma/ib_umem_odp.h>
|
||||||
|
|
||||||
#include "uverbs.h"
|
#include "uverbs.h"
|
||||||
|
|
||||||
@@ -69,6 +70,10 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* ib_umem_get - Pin and DMA map userspace memory.
|
* ib_umem_get - Pin and DMA map userspace memory.
|
||||||
|
*
|
||||||
|
* If access flags indicate ODP memory, avoid pinning. Instead, stores
|
||||||
|
* the mm for future page fault handling in conjunction with MMU notifiers.
|
||||||
|
*
|
||||||
* @context: userspace context to pin memory for
|
* @context: userspace context to pin memory for
|
||||||
* @addr: userspace virtual address to start at
|
* @addr: userspace virtual address to start at
|
||||||
* @size: length of region to pin
|
* @size: length of region to pin
|
||||||
@@ -103,17 +108,30 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
|
|||||||
|
|
||||||
umem->context = context;
|
umem->context = context;
|
||||||
umem->length = size;
|
umem->length = size;
|
||||||
umem->offset = addr & ~PAGE_MASK;
|
umem->address = addr;
|
||||||
umem->page_size = PAGE_SIZE;
|
umem->page_size = PAGE_SIZE;
|
||||||
umem->pid = get_task_pid(current, PIDTYPE_PID);
|
umem->pid = get_task_pid(current, PIDTYPE_PID);
|
||||||
/*
|
/*
|
||||||
* We ask for writable memory if any access flags other than
|
* We ask for writable memory if any of the following
|
||||||
* "remote read" are set. "Local write" and "remote write"
|
* access flags are set. "Local write" and "remote write"
|
||||||
* obviously require write access. "Remote atomic" can do
|
* obviously require write access. "Remote atomic" can do
|
||||||
* things like fetch and add, which will modify memory, and
|
* things like fetch and add, which will modify memory, and
|
||||||
* "MW bind" can change permissions by binding a window.
|
* "MW bind" can change permissions by binding a window.
|
||||||
*/
|
*/
|
||||||
umem->writable = !!(access & ~IB_ACCESS_REMOTE_READ);
|
umem->writable = !!(access &
|
||||||
|
(IB_ACCESS_LOCAL_WRITE | IB_ACCESS_REMOTE_WRITE |
|
||||||
|
IB_ACCESS_REMOTE_ATOMIC | IB_ACCESS_MW_BIND));
|
||||||
|
|
||||||
|
if (access & IB_ACCESS_ON_DEMAND) {
|
||||||
|
ret = ib_umem_odp_get(context, umem);
|
||||||
|
if (ret) {
|
||||||
|
kfree(umem);
|
||||||
|
return ERR_PTR(ret);
|
||||||
|
}
|
||||||
|
return umem;
|
||||||
|
}
|
||||||
|
|
||||||
|
umem->odp_data = NULL;
|
||||||
|
|
||||||
/* We assume the memory is from hugetlb until proved otherwise */
|
/* We assume the memory is from hugetlb until proved otherwise */
|
||||||
umem->hugetlb = 1;
|
umem->hugetlb = 1;
|
||||||
@@ -132,7 +150,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
|
|||||||
if (!vma_list)
|
if (!vma_list)
|
||||||
umem->hugetlb = 0;
|
umem->hugetlb = 0;
|
||||||
|
|
||||||
npages = PAGE_ALIGN(size + umem->offset) >> PAGE_SHIFT;
|
npages = ib_umem_num_pages(umem);
|
||||||
|
|
||||||
down_write(¤t->mm->mmap_sem);
|
down_write(¤t->mm->mmap_sem);
|
||||||
|
|
||||||
@@ -235,6 +253,11 @@ void ib_umem_release(struct ib_umem *umem)
|
|||||||
struct task_struct *task;
|
struct task_struct *task;
|
||||||
unsigned long diff;
|
unsigned long diff;
|
||||||
|
|
||||||
|
if (umem->odp_data) {
|
||||||
|
ib_umem_odp_release(umem);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
__ib_umem_release(umem->context->device, umem, 1);
|
__ib_umem_release(umem->context->device, umem, 1);
|
||||||
|
|
||||||
task = get_pid_task(umem->pid, PIDTYPE_PID);
|
task = get_pid_task(umem->pid, PIDTYPE_PID);
|
||||||
@@ -246,7 +269,7 @@ void ib_umem_release(struct ib_umem *umem)
|
|||||||
if (!mm)
|
if (!mm)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
diff = PAGE_ALIGN(umem->length + umem->offset) >> PAGE_SHIFT;
|
diff = ib_umem_num_pages(umem);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We may be called with the mm's mmap_sem already held. This
|
* We may be called with the mm's mmap_sem already held. This
|
||||||
@@ -283,6 +306,9 @@ int ib_umem_page_count(struct ib_umem *umem)
|
|||||||
int n;
|
int n;
|
||||||
struct scatterlist *sg;
|
struct scatterlist *sg;
|
||||||
|
|
||||||
|
if (umem->odp_data)
|
||||||
|
return ib_umem_num_pages(umem);
|
||||||
|
|
||||||
shift = ilog2(umem->page_size);
|
shift = ilog2(umem->page_size);
|
||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
@@ -292,3 +318,37 @@ int ib_umem_page_count(struct ib_umem *umem)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ib_umem_page_count);
|
EXPORT_SYMBOL(ib_umem_page_count);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy from the given ib_umem's pages to the given buffer.
|
||||||
|
*
|
||||||
|
* umem - the umem to copy from
|
||||||
|
* offset - offset to start copying from
|
||||||
|
* dst - destination buffer
|
||||||
|
* length - buffer length
|
||||||
|
*
|
||||||
|
* Returns 0 on success, or an error code.
|
||||||
|
*/
|
||||||
|
int ib_umem_copy_from(void *dst, struct ib_umem *umem, size_t offset,
|
||||||
|
size_t length)
|
||||||
|
{
|
||||||
|
size_t end = offset + length;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (offset > umem->length || length > umem->length - offset) {
|
||||||
|
pr_err("ib_umem_copy_from not in range. offset: %zd umem length: %zd end: %zd\n",
|
||||||
|
offset, umem->length, end);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = sg_pcopy_to_buffer(umem->sg_head.sgl, umem->nmap, dst, length,
|
||||||
|
offset + ib_umem_offset(umem));
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
else if (ret != length)
|
||||||
|
return -EINVAL;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(ib_umem_copy_from);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014 Mellanox Technologies. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is available to you under a choice of one of two
|
||||||
|
* licenses. You may choose to be licensed under the terms of the GNU
|
||||||
|
* General Public License (GPL) Version 2, available from the file
|
||||||
|
* COPYING in the main directory of this source tree, or the
|
||||||
|
* OpenIB.org BSD license below:
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or
|
||||||
|
* without modification, are permitted provided that the following
|
||||||
|
* conditions are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/interval_tree_generic.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <linux/gfp.h>
|
||||||
|
#include <rdma/ib_umem_odp.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ib_umem list keeps track of memory regions for which the HW
|
||||||
|
* device request to receive notification when the related memory
|
||||||
|
* mapping is changed.
|
||||||
|
*
|
||||||
|
* ib_umem_lock protects the list.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline u64 node_start(struct umem_odp_node *n)
|
||||||
|
{
|
||||||
|
struct ib_umem_odp *umem_odp =
|
||||||
|
container_of(n, struct ib_umem_odp, interval_tree);
|
||||||
|
|
||||||
|
return ib_umem_start(umem_odp->umem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note that the representation of the intervals in the interval tree
|
||||||
|
* considers the ending point as contained in the interval, while the
|
||||||
|
* function ib_umem_end returns the first address which is not contained
|
||||||
|
* in the umem.
|
||||||
|
*/
|
||||||
|
static inline u64 node_last(struct umem_odp_node *n)
|
||||||
|
{
|
||||||
|
struct ib_umem_odp *umem_odp =
|
||||||
|
container_of(n, struct ib_umem_odp, interval_tree);
|
||||||
|
|
||||||
|
return ib_umem_end(umem_odp->umem) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERVAL_TREE_DEFINE(struct umem_odp_node, rb, u64, __subtree_last,
|
||||||
|
node_start, node_last, , rbt_ib_umem)
|
||||||
|
|
||||||
|
/* @last is not a part of the interval. See comment for function
|
||||||
|
* node_last.
|
||||||
|
*/
|
||||||
|
int rbt_ib_umem_for_each_in_range(struct rb_root *root,
|
||||||
|
u64 start, u64 last,
|
||||||
|
umem_call_back cb,
|
||||||
|
void *cookie)
|
||||||
|
{
|
||||||
|
int ret_val = 0;
|
||||||
|
struct umem_odp_node *node;
|
||||||
|
struct ib_umem_odp *umem;
|
||||||
|
|
||||||
|
if (unlikely(start == last))
|
||||||
|
return ret_val;
|
||||||
|
|
||||||
|
for (node = rbt_ib_umem_iter_first(root, start, last - 1); node;
|
||||||
|
node = rbt_ib_umem_iter_next(node, start, last - 1)) {
|
||||||
|
umem = container_of(node, struct ib_umem_odp, interval_tree);
|
||||||
|
ret_val = cb(umem->umem, start, last, cookie) || ret_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret_val;
|
||||||
|
}
|
||||||
@@ -258,5 +258,6 @@ IB_UVERBS_DECLARE_CMD(close_xrcd);
|
|||||||
|
|
||||||
IB_UVERBS_DECLARE_EX_CMD(create_flow);
|
IB_UVERBS_DECLARE_EX_CMD(create_flow);
|
||||||
IB_UVERBS_DECLARE_EX_CMD(destroy_flow);
|
IB_UVERBS_DECLARE_EX_CMD(destroy_flow);
|
||||||
|
IB_UVERBS_DECLARE_EX_CMD(query_device);
|
||||||
|
|
||||||
#endif /* UVERBS_H */
|
#endif /* UVERBS_H */
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#include <linux/file.h>
|
#include <linux/file.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
|
|
||||||
@@ -288,6 +289,9 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
|
|||||||
struct ib_uverbs_get_context_resp resp;
|
struct ib_uverbs_get_context_resp resp;
|
||||||
struct ib_udata udata;
|
struct ib_udata udata;
|
||||||
struct ib_device *ibdev = file->device->ib_dev;
|
struct ib_device *ibdev = file->device->ib_dev;
|
||||||
|
#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
|
||||||
|
struct ib_device_attr dev_attr;
|
||||||
|
#endif
|
||||||
struct ib_ucontext *ucontext;
|
struct ib_ucontext *ucontext;
|
||||||
struct file *filp;
|
struct file *filp;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -325,8 +329,25 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
|
|||||||
INIT_LIST_HEAD(&ucontext->ah_list);
|
INIT_LIST_HEAD(&ucontext->ah_list);
|
||||||
INIT_LIST_HEAD(&ucontext->xrcd_list);
|
INIT_LIST_HEAD(&ucontext->xrcd_list);
|
||||||
INIT_LIST_HEAD(&ucontext->rule_list);
|
INIT_LIST_HEAD(&ucontext->rule_list);
|
||||||
|
rcu_read_lock();
|
||||||
|
ucontext->tgid = get_task_pid(current->group_leader, PIDTYPE_PID);
|
||||||
|
rcu_read_unlock();
|
||||||
ucontext->closing = 0;
|
ucontext->closing = 0;
|
||||||
|
|
||||||
|
#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
|
||||||
|
ucontext->umem_tree = RB_ROOT;
|
||||||
|
init_rwsem(&ucontext->umem_rwsem);
|
||||||
|
ucontext->odp_mrs_count = 0;
|
||||||
|
INIT_LIST_HEAD(&ucontext->no_private_counters);
|
||||||
|
|
||||||
|
ret = ib_query_device(ibdev, &dev_attr);
|
||||||
|
if (ret)
|
||||||
|
goto err_free;
|
||||||
|
if (!(dev_attr.device_cap_flags & IB_DEVICE_ON_DEMAND_PAGING))
|
||||||
|
ucontext->invalidate_range = NULL;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
resp.num_comp_vectors = file->device->num_comp_vectors;
|
resp.num_comp_vectors = file->device->num_comp_vectors;
|
||||||
|
|
||||||
ret = get_unused_fd_flags(O_CLOEXEC);
|
ret = get_unused_fd_flags(O_CLOEXEC);
|
||||||
@@ -371,6 +392,7 @@ err_fd:
|
|||||||
put_unused_fd(resp.async_fd);
|
put_unused_fd(resp.async_fd);
|
||||||
|
|
||||||
err_free:
|
err_free:
|
||||||
|
put_pid(ucontext->tgid);
|
||||||
ibdev->dealloc_ucontext(ucontext);
|
ibdev->dealloc_ucontext(ucontext);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
@@ -378,6 +400,52 @@ err:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void copy_query_dev_fields(struct ib_uverbs_file *file,
|
||||||
|
struct ib_uverbs_query_device_resp *resp,
|
||||||
|
struct ib_device_attr *attr)
|
||||||
|
{
|
||||||
|
resp->fw_ver = attr->fw_ver;
|
||||||
|
resp->node_guid = file->device->ib_dev->node_guid;
|
||||||
|
resp->sys_image_guid = attr->sys_image_guid;
|
||||||
|
resp->max_mr_size = attr->max_mr_size;
|
||||||
|
resp->page_size_cap = attr->page_size_cap;
|
||||||
|
resp->vendor_id = attr->vendor_id;
|
||||||
|
resp->vendor_part_id = attr->vendor_part_id;
|
||||||
|
resp->hw_ver = attr->hw_ver;
|
||||||
|
resp->max_qp = attr->max_qp;
|
||||||
|
resp->max_qp_wr = attr->max_qp_wr;
|
||||||
|
resp->device_cap_flags = attr->device_cap_flags;
|
||||||
|
resp->max_sge = attr->max_sge;
|
||||||
|
resp->max_sge_rd = attr->max_sge_rd;
|
||||||
|
resp->max_cq = attr->max_cq;
|
||||||
|
resp->max_cqe = attr->max_cqe;
|
||||||
|
resp->max_mr = attr->max_mr;
|
||||||
|
resp->max_pd = attr->max_pd;
|
||||||
|
resp->max_qp_rd_atom = attr->max_qp_rd_atom;
|
||||||
|
resp->max_ee_rd_atom = attr->max_ee_rd_atom;
|
||||||
|
resp->max_res_rd_atom = attr->max_res_rd_atom;
|
||||||
|
resp->max_qp_init_rd_atom = attr->max_qp_init_rd_atom;
|
||||||
|
resp->max_ee_init_rd_atom = attr->max_ee_init_rd_atom;
|
||||||
|
resp->atomic_cap = attr->atomic_cap;
|
||||||
|
resp->max_ee = attr->max_ee;
|
||||||
|
resp->max_rdd = attr->max_rdd;
|
||||||
|
resp->max_mw = attr->max_mw;
|
||||||
|
resp->max_raw_ipv6_qp = attr->max_raw_ipv6_qp;
|
||||||
|
resp->max_raw_ethy_qp = attr->max_raw_ethy_qp;
|
||||||
|
resp->max_mcast_grp = attr->max_mcast_grp;
|
||||||
|
resp->max_mcast_qp_attach = attr->max_mcast_qp_attach;
|
||||||
|
resp->max_total_mcast_qp_attach = attr->max_total_mcast_qp_attach;
|
||||||
|
resp->max_ah = attr->max_ah;
|
||||||
|
resp->max_fmr = attr->max_fmr;
|
||||||
|
resp->max_map_per_fmr = attr->max_map_per_fmr;
|
||||||
|
resp->max_srq = attr->max_srq;
|
||||||
|
resp->max_srq_wr = attr->max_srq_wr;
|
||||||
|
resp->max_srq_sge = attr->max_srq_sge;
|
||||||
|
resp->max_pkeys = attr->max_pkeys;
|
||||||
|
resp->local_ca_ack_delay = attr->local_ca_ack_delay;
|
||||||
|
resp->phys_port_cnt = file->device->ib_dev->phys_port_cnt;
|
||||||
|
}
|
||||||
|
|
||||||
ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file,
|
ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file,
|
||||||
const char __user *buf,
|
const char __user *buf,
|
||||||
int in_len, int out_len)
|
int in_len, int out_len)
|
||||||
@@ -398,47 +466,7 @@ ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file,
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
memset(&resp, 0, sizeof resp);
|
memset(&resp, 0, sizeof resp);
|
||||||
|
copy_query_dev_fields(file, &resp, &attr);
|
||||||
resp.fw_ver = attr.fw_ver;
|
|
||||||
resp.node_guid = file->device->ib_dev->node_guid;
|
|
||||||
resp.sys_image_guid = attr.sys_image_guid;
|
|
||||||
resp.max_mr_size = attr.max_mr_size;
|
|
||||||
resp.page_size_cap = attr.page_size_cap;
|
|
||||||
resp.vendor_id = attr.vendor_id;
|
|
||||||
resp.vendor_part_id = attr.vendor_part_id;
|
|
||||||
resp.hw_ver = attr.hw_ver;
|
|
||||||
resp.max_qp = attr.max_qp;
|
|
||||||
resp.max_qp_wr = attr.max_qp_wr;
|
|
||||||
resp.device_cap_flags = attr.device_cap_flags;
|
|
||||||
resp.max_sge = attr.max_sge;
|
|
||||||
resp.max_sge_rd = attr.max_sge_rd;
|
|
||||||
resp.max_cq = attr.max_cq;
|
|
||||||
resp.max_cqe = attr.max_cqe;
|
|
||||||
resp.max_mr = attr.max_mr;
|
|
||||||
resp.max_pd = attr.max_pd;
|
|
||||||
resp.max_qp_rd_atom = attr.max_qp_rd_atom;
|
|
||||||
resp.max_ee_rd_atom = attr.max_ee_rd_atom;
|
|
||||||
resp.max_res_rd_atom = attr.max_res_rd_atom;
|
|
||||||
resp.max_qp_init_rd_atom = attr.max_qp_init_rd_atom;
|
|
||||||
resp.max_ee_init_rd_atom = attr.max_ee_init_rd_atom;
|
|
||||||
resp.atomic_cap = attr.atomic_cap;
|
|
||||||
resp.max_ee = attr.max_ee;
|
|
||||||
resp.max_rdd = attr.max_rdd;
|
|
||||||
resp.max_mw = attr.max_mw;
|
|
||||||
resp.max_raw_ipv6_qp = attr.max_raw_ipv6_qp;
|
|
||||||
resp.max_raw_ethy_qp = attr.max_raw_ethy_qp;
|
|
||||||
resp.max_mcast_grp = attr.max_mcast_grp;
|
|
||||||
resp.max_mcast_qp_attach = attr.max_mcast_qp_attach;
|
|
||||||
resp.max_total_mcast_qp_attach = attr.max_total_mcast_qp_attach;
|
|
||||||
resp.max_ah = attr.max_ah;
|
|
||||||
resp.max_fmr = attr.max_fmr;
|
|
||||||
resp.max_map_per_fmr = attr.max_map_per_fmr;
|
|
||||||
resp.max_srq = attr.max_srq;
|
|
||||||
resp.max_srq_wr = attr.max_srq_wr;
|
|
||||||
resp.max_srq_sge = attr.max_srq_sge;
|
|
||||||
resp.max_pkeys = attr.max_pkeys;
|
|
||||||
resp.local_ca_ack_delay = attr.local_ca_ack_delay;
|
|
||||||
resp.phys_port_cnt = file->device->ib_dev->phys_port_cnt;
|
|
||||||
|
|
||||||
if (copy_to_user((void __user *) (unsigned long) cmd.response,
|
if (copy_to_user((void __user *) (unsigned long) cmd.response,
|
||||||
&resp, sizeof resp))
|
&resp, sizeof resp))
|
||||||
@@ -947,6 +975,18 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
|
|||||||
goto err_free;
|
goto err_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cmd.access_flags & IB_ACCESS_ON_DEMAND) {
|
||||||
|
struct ib_device_attr attr;
|
||||||
|
|
||||||
|
ret = ib_query_device(pd->device, &attr);
|
||||||
|
if (ret || !(attr.device_cap_flags &
|
||||||
|
IB_DEVICE_ON_DEMAND_PAGING)) {
|
||||||
|
pr_debug("ODP support not available\n");
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto err_put;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mr = pd->device->reg_user_mr(pd, cmd.start, cmd.length, cmd.hca_va,
|
mr = pd->device->reg_user_mr(pd, cmd.start, cmd.length, cmd.hca_va,
|
||||||
cmd.access_flags, &udata);
|
cmd.access_flags, &udata);
|
||||||
if (IS_ERR(mr)) {
|
if (IS_ERR(mr)) {
|
||||||
@@ -3253,3 +3293,52 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
|
|||||||
|
|
||||||
return ret ? ret : in_len;
|
return ret ? ret : in_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ib_uverbs_ex_query_device(struct ib_uverbs_file *file,
|
||||||
|
struct ib_udata *ucore,
|
||||||
|
struct ib_udata *uhw)
|
||||||
|
{
|
||||||
|
struct ib_uverbs_ex_query_device_resp resp;
|
||||||
|
struct ib_uverbs_ex_query_device cmd;
|
||||||
|
struct ib_device_attr attr;
|
||||||
|
struct ib_device *device;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
device = file->device->ib_dev;
|
||||||
|
if (ucore->inlen < sizeof(cmd))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
err = ib_copy_from_udata(&cmd, ucore, sizeof(cmd));
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (cmd.reserved)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
err = device->query_device(device, &attr);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
memset(&resp, 0, sizeof(resp));
|
||||||
|
copy_query_dev_fields(file, &resp.base, &attr);
|
||||||
|
resp.comp_mask = 0;
|
||||||
|
|
||||||
|
#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
|
||||||
|
if (cmd.comp_mask & IB_USER_VERBS_EX_QUERY_DEVICE_ODP) {
|
||||||
|
resp.odp_caps.general_caps = attr.odp_caps.general_caps;
|
||||||
|
resp.odp_caps.per_transport_caps.rc_odp_caps =
|
||||||
|
attr.odp_caps.per_transport_caps.rc_odp_caps;
|
||||||
|
resp.odp_caps.per_transport_caps.uc_odp_caps =
|
||||||
|
attr.odp_caps.per_transport_caps.uc_odp_caps;
|
||||||
|
resp.odp_caps.per_transport_caps.ud_odp_caps =
|
||||||
|
attr.odp_caps.per_transport_caps.ud_odp_caps;
|
||||||
|
resp.comp_mask |= IB_USER_VERBS_EX_QUERY_DEVICE_ODP;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
err = ib_copy_to_udata(ucore, &resp, sizeof(resp));
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -122,7 +122,8 @@ static int (*uverbs_ex_cmd_table[])(struct ib_uverbs_file *file,
|
|||||||
struct ib_udata *ucore,
|
struct ib_udata *ucore,
|
||||||
struct ib_udata *uhw) = {
|
struct ib_udata *uhw) = {
|
||||||
[IB_USER_VERBS_EX_CMD_CREATE_FLOW] = ib_uverbs_ex_create_flow,
|
[IB_USER_VERBS_EX_CMD_CREATE_FLOW] = ib_uverbs_ex_create_flow,
|
||||||
[IB_USER_VERBS_EX_CMD_DESTROY_FLOW] = ib_uverbs_ex_destroy_flow
|
[IB_USER_VERBS_EX_CMD_DESTROY_FLOW] = ib_uverbs_ex_destroy_flow,
|
||||||
|
[IB_USER_VERBS_EX_CMD_QUERY_DEVICE] = ib_uverbs_ex_query_device
|
||||||
};
|
};
|
||||||
|
|
||||||
static void ib_uverbs_add_one(struct ib_device *device);
|
static void ib_uverbs_add_one(struct ib_device *device);
|
||||||
@@ -296,6 +297,8 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
|
|||||||
kfree(uobj);
|
kfree(uobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
put_pid(context->tgid);
|
||||||
|
|
||||||
return context->device->dealloc_ucontext(context);
|
return context->device->dealloc_ucontext(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -879,7 +879,8 @@ int ib_resolve_eth_l2_attrs(struct ib_qp *qp,
|
|||||||
if (rdma_link_local_addr((struct in6_addr *)qp_attr->ah_attr.grh.dgid.raw)) {
|
if (rdma_link_local_addr((struct in6_addr *)qp_attr->ah_attr.grh.dgid.raw)) {
|
||||||
rdma_get_ll_mac((struct in6_addr *)qp_attr->ah_attr.grh.dgid.raw, qp_attr->ah_attr.dmac);
|
rdma_get_ll_mac((struct in6_addr *)qp_attr->ah_attr.grh.dgid.raw, qp_attr->ah_attr.dmac);
|
||||||
rdma_get_ll_mac((struct in6_addr *)sgid.raw, qp_attr->smac);
|
rdma_get_ll_mac((struct in6_addr *)sgid.raw, qp_attr->smac);
|
||||||
qp_attr->vlan_id = rdma_get_vlan_id(&sgid);
|
if (!(*qp_attr_mask & IB_QP_VID))
|
||||||
|
qp_attr->vlan_id = rdma_get_vlan_id(&sgid);
|
||||||
} else {
|
} else {
|
||||||
ret = rdma_addr_find_dmac_by_grh(&sgid, &qp_attr->ah_attr.grh.dgid,
|
ret = rdma_addr_find_dmac_by_grh(&sgid, &qp_attr->ah_attr.grh.dgid,
|
||||||
qp_attr->ah_attr.dmac, &qp_attr->vlan_id);
|
qp_attr->ah_attr.dmac, &qp_attr->vlan_id);
|
||||||
|
|||||||
@@ -476,7 +476,7 @@ static struct ib_mr *c2_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
|
|||||||
c2mr->umem->page_size,
|
c2mr->umem->page_size,
|
||||||
i,
|
i,
|
||||||
length,
|
length,
|
||||||
c2mr->umem->offset,
|
ib_umem_offset(c2mr->umem),
|
||||||
&kva,
|
&kva,
|
||||||
c2_convert_access(acc),
|
c2_convert_access(acc),
|
||||||
c2mr);
|
c2mr);
|
||||||
|
|||||||
@@ -1640,7 +1640,8 @@ static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb)
|
|||||||
__state_set(&ep->com, MPA_REQ_RCVD);
|
__state_set(&ep->com, MPA_REQ_RCVD);
|
||||||
|
|
||||||
/* drive upcall */
|
/* drive upcall */
|
||||||
mutex_lock(&ep->parent_ep->com.mutex);
|
mutex_lock_nested(&ep->parent_ep->com.mutex,
|
||||||
|
SINGLE_DEPTH_NESTING);
|
||||||
if (ep->parent_ep->com.state != DEAD) {
|
if (ep->parent_ep->com.state != DEAD) {
|
||||||
if (connect_request_upcall(ep))
|
if (connect_request_upcall(ep))
|
||||||
abort_connection(ep, skb, GFP_KERNEL);
|
abort_connection(ep, skb, GFP_KERNEL);
|
||||||
@@ -3126,6 +3127,8 @@ static int create_server6(struct c4iw_dev *dev, struct c4iw_listen_ep *ep)
|
|||||||
err = c4iw_wait_for_reply(&ep->com.dev->rdev,
|
err = c4iw_wait_for_reply(&ep->com.dev->rdev,
|
||||||
&ep->com.wr_wait,
|
&ep->com.wr_wait,
|
||||||
0, 0, __func__);
|
0, 0, __func__);
|
||||||
|
else if (err > 0)
|
||||||
|
err = net_xmit_errno(err);
|
||||||
if (err)
|
if (err)
|
||||||
pr_err("cxgb4_create_server6/filter failed err %d stid %d laddr %pI6 lport %d\n",
|
pr_err("cxgb4_create_server6/filter failed err %d stid %d laddr %pI6 lport %d\n",
|
||||||
err, ep->stid,
|
err, ep->stid,
|
||||||
@@ -3159,6 +3162,8 @@ static int create_server4(struct c4iw_dev *dev, struct c4iw_listen_ep *ep)
|
|||||||
err = c4iw_wait_for_reply(&ep->com.dev->rdev,
|
err = c4iw_wait_for_reply(&ep->com.dev->rdev,
|
||||||
&ep->com.wr_wait,
|
&ep->com.wr_wait,
|
||||||
0, 0, __func__);
|
0, 0, __func__);
|
||||||
|
else if (err > 0)
|
||||||
|
err = net_xmit_errno(err);
|
||||||
}
|
}
|
||||||
if (err)
|
if (err)
|
||||||
pr_err("cxgb4_create_server/filter failed err %d stid %d laddr %pI4 lport %d\n"
|
pr_err("cxgb4_create_server/filter failed err %d stid %d laddr %pI4 lport %d\n"
|
||||||
|
|||||||
@@ -670,7 +670,7 @@ static int ep_open(struct inode *inode, struct file *file)
|
|||||||
idr_for_each(&epd->devp->stid_idr, count_idrs, &count);
|
idr_for_each(&epd->devp->stid_idr, count_idrs, &count);
|
||||||
spin_unlock_irq(&epd->devp->lock);
|
spin_unlock_irq(&epd->devp->lock);
|
||||||
|
|
||||||
epd->bufsize = count * 160;
|
epd->bufsize = count * 240;
|
||||||
epd->buf = vmalloc(epd->bufsize);
|
epd->buf = vmalloc(epd->bufsize);
|
||||||
if (!epd->buf) {
|
if (!epd->buf) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
|||||||
@@ -50,6 +50,13 @@ static int inline_threshold = C4IW_INLINE_THRESHOLD;
|
|||||||
module_param(inline_threshold, int, 0644);
|
module_param(inline_threshold, int, 0644);
|
||||||
MODULE_PARM_DESC(inline_threshold, "inline vs dsgl threshold (default=128)");
|
MODULE_PARM_DESC(inline_threshold, "inline vs dsgl threshold (default=128)");
|
||||||
|
|
||||||
|
static int mr_exceeds_hw_limits(struct c4iw_dev *dev, u64 length)
|
||||||
|
{
|
||||||
|
return (is_t4(dev->rdev.lldi.adapter_type) ||
|
||||||
|
is_t5(dev->rdev.lldi.adapter_type)) &&
|
||||||
|
length >= 8*1024*1024*1024ULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int _c4iw_write_mem_dma_aligned(struct c4iw_rdev *rdev, u32 addr,
|
static int _c4iw_write_mem_dma_aligned(struct c4iw_rdev *rdev, u32 addr,
|
||||||
u32 len, dma_addr_t data, int wait)
|
u32 len, dma_addr_t data, int wait)
|
||||||
{
|
{
|
||||||
@@ -369,9 +376,11 @@ static int register_mem(struct c4iw_dev *rhp, struct c4iw_pd *php,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = write_tpt_entry(&rhp->rdev, 0, &stag, 1, mhp->attr.pdid,
|
ret = write_tpt_entry(&rhp->rdev, 0, &stag, 1, mhp->attr.pdid,
|
||||||
FW_RI_STAG_NSMR, mhp->attr.perms,
|
FW_RI_STAG_NSMR, mhp->attr.len ?
|
||||||
|
mhp->attr.perms : 0,
|
||||||
mhp->attr.mw_bind_enable, mhp->attr.zbva,
|
mhp->attr.mw_bind_enable, mhp->attr.zbva,
|
||||||
mhp->attr.va_fbo, mhp->attr.len, shift - 12,
|
mhp->attr.va_fbo, mhp->attr.len ?
|
||||||
|
mhp->attr.len : -1, shift - 12,
|
||||||
mhp->attr.pbl_size, mhp->attr.pbl_addr);
|
mhp->attr.pbl_size, mhp->attr.pbl_addr);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
@@ -536,6 +545,11 @@ int c4iw_reregister_phys_mem(struct ib_mr *mr, int mr_rereg_mask,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mr_exceeds_hw_limits(rhp, total_size)) {
|
||||||
|
kfree(page_list);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
ret = reregister_mem(rhp, php, &mh, shift, npages);
|
ret = reregister_mem(rhp, php, &mh, shift, npages);
|
||||||
kfree(page_list);
|
kfree(page_list);
|
||||||
if (ret)
|
if (ret)
|
||||||
@@ -596,6 +610,12 @@ struct ib_mr *c4iw_register_phys_mem(struct ib_pd *pd,
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
if (mr_exceeds_hw_limits(rhp, total_size)) {
|
||||||
|
kfree(page_list);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
ret = alloc_pbl(mhp, npages);
|
ret = alloc_pbl(mhp, npages);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
kfree(page_list);
|
kfree(page_list);
|
||||||
@@ -699,6 +719,10 @@ struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
|
|||||||
|
|
||||||
php = to_c4iw_pd(pd);
|
php = to_c4iw_pd(pd);
|
||||||
rhp = php->rhp;
|
rhp = php->rhp;
|
||||||
|
|
||||||
|
if (mr_exceeds_hw_limits(rhp, length))
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
mhp = kzalloc(sizeof(*mhp), GFP_KERNEL);
|
mhp = kzalloc(sizeof(*mhp), GFP_KERNEL);
|
||||||
if (!mhp)
|
if (!mhp)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|||||||
@@ -1538,9 +1538,9 @@ err:
|
|||||||
set_state(qhp, C4IW_QP_STATE_ERROR);
|
set_state(qhp, C4IW_QP_STATE_ERROR);
|
||||||
free = 1;
|
free = 1;
|
||||||
abort = 1;
|
abort = 1;
|
||||||
wake_up(&qhp->wait);
|
|
||||||
BUG_ON(!ep);
|
BUG_ON(!ep);
|
||||||
flush_qp(qhp);
|
flush_qp(qhp);
|
||||||
|
wake_up(&qhp->wait);
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&qhp->mutex);
|
mutex_unlock(&qhp->mutex);
|
||||||
|
|
||||||
|
|||||||
@@ -399,7 +399,7 @@ reg_user_mr_fallback:
|
|||||||
pginfo.num_kpages = num_kpages;
|
pginfo.num_kpages = num_kpages;
|
||||||
pginfo.num_hwpages = num_hwpages;
|
pginfo.num_hwpages = num_hwpages;
|
||||||
pginfo.u.usr.region = e_mr->umem;
|
pginfo.u.usr.region = e_mr->umem;
|
||||||
pginfo.next_hwpage = e_mr->umem->offset / hwpage_size;
|
pginfo.next_hwpage = ib_umem_offset(e_mr->umem) / hwpage_size;
|
||||||
pginfo.u.usr.next_sg = pginfo.u.usr.region->sg_head.sgl;
|
pginfo.u.usr.next_sg = pginfo.u.usr.region->sg_head.sgl;
|
||||||
ret = ehca_reg_mr(shca, e_mr, (u64 *)virt, length, mr_access_flags,
|
ret = ehca_reg_mr(shca, e_mr, (u64 *)virt, length, mr_access_flags,
|
||||||
e_pd, &pginfo, &e_mr->ib.ib_mr.lkey,
|
e_pd, &pginfo, &e_mr->ib.ib_mr.lkey,
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ struct ib_mr *ipath_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
|
|||||||
mr->mr.user_base = start;
|
mr->mr.user_base = start;
|
||||||
mr->mr.iova = virt_addr;
|
mr->mr.iova = virt_addr;
|
||||||
mr->mr.length = length;
|
mr->mr.length = length;
|
||||||
mr->mr.offset = umem->offset;
|
mr->mr.offset = ib_umem_offset(umem);
|
||||||
mr->mr.access_flags = mr_access_flags;
|
mr->mr.access_flags = mr_access_flags;
|
||||||
mr->mr.max_segs = n;
|
mr->mr.max_segs = n;
|
||||||
mr->umem = umem;
|
mr->umem = umem;
|
||||||
|
|||||||
@@ -223,7 +223,6 @@ int mlx4_ib_rereg_user_mr(struct ib_mr *mr, int flags,
|
|||||||
|
|
||||||
if (flags & IB_MR_REREG_TRANS) {
|
if (flags & IB_MR_REREG_TRANS) {
|
||||||
int shift;
|
int shift;
|
||||||
int err;
|
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
mlx4_mr_rereg_mem_cleanup(dev->dev, &mmr->mmr);
|
mlx4_mr_rereg_mem_cleanup(dev->dev, &mmr->mmr);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
obj-$(CONFIG_MLX5_INFINIBAND) += mlx5_ib.o
|
obj-$(CONFIG_MLX5_INFINIBAND) += mlx5_ib.o
|
||||||
|
|
||||||
mlx5_ib-y := main.o cq.o doorbell.o qp.o mem.o srq.o mr.o ah.o mad.o
|
mlx5_ib-y := main.o cq.o doorbell.o qp.o mem.o srq.o mr.o ah.o mad.o
|
||||||
|
mlx5_ib-$(CONFIG_INFINIBAND_ON_DEMAND_PAGING) += odp.o
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user