mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-11-07 04:36:52 -10:00
OFED: Various changes from Linux 4.11
This contains changes from the following Linux commits: 55efcfcd7776 RDMA/core: Fix incorrect structure packing for booleans aaaca121c7cf RDMA/core: add port state cache 9e2c3f1c7f3e RDMA/core: export ib_get_cached_port_state 93b1f29de71f RDMA/cma: resolve to first active ib port d43dbacfc063 IB/core: Change the type of an ib_dma_alloc_coherent() argument 6532c380bf40 IB/core: Remove ib_dma_*map_single_attrs() 0bbb3b7496ea IB/rxe, IB/rdmavt: Use dma_virt_ops instead of duplicating it f57e8ca50e23 IB/mad: Add port_num to error message 828f6fa65ce7 IB/umem: Release pid in error and ODP flow 19b752a19dce IB/cma: Allow port reuse for rdma_id 21d6454a392d RDMA/core: create struct ib_port_cache 25bf14d6f589 IB/core: Add implicit MR flag d9d0674c0f8a IB/umem: Indicate that process is being terminated d07d1d70ce1a IB/umem: Update on demand page (ODP) support a748d60df32e IB/mlx4: Take source GID by index from HW GID table 89052d784bc9 IB/cma: Add default RoCE TOS to CMA configfs 6df6b4a9ce43 IB/cma: Destination and source addr families must match On FreeBSD, the default RoCE TOS setting is available as per-port sysctls similar to the existing default RoCE mode sysctls. Tested by: Wafa Hamzah <[email protected]> (mlx5_ib) Tested by: John Baldwin <[email protected]> (iw_cxgbe) Sponsored by: Chelsio Communications
This commit is contained in:
1 parent
38d9ce1f58
commit
8d57de34d5
12 files changed
+410
-265
No files matched your search
@@ -2423,11 +2423,31 @@ static u8 sl_to_vl(struct mlx4_ib_dev *dev, u8 sl, int port_num)
|
||||
return vl;
|
||||
}
|
||||
|
||||
static int fill_gid_by_hw_index(struct mlx4_ib_dev *ibdev, u8 port_num,
|
||||
int index, union ib_gid *gid,
|
||||
enum ib_gid_type *gid_type)
|
||||
{
|
||||
struct mlx4_ib_iboe *iboe = &ibdev->iboe;
|
||||
struct mlx4_port_gid_table *port_gid_table;
|
||||
unsigned long flags;
|
||||
|
||||
port_gid_table = &iboe->gids[port_num - 1];
|
||||
spin_lock_irqsave(&iboe->lock, flags);
|
||||
memcpy(gid, &port_gid_table->gids[index].gid, sizeof(*gid));
|
||||
*gid_type = port_gid_table->gids[index].gid_type;
|
||||
spin_unlock_irqrestore(&iboe->lock, flags);
|
||||
if (!memcmp(gid, &zgid, sizeof(*gid)))
|
||||
return -ENOENT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MLX4_ROCEV2_QP1_SPORT 0xC000
|
||||
static int build_mlx_header(struct mlx4_ib_sqp *sqp, const struct ib_ud_wr *wr,
|
||||
void *wqe, unsigned *mlx_seg_len)
|
||||
{
|
||||
struct ib_device *ib_dev = sqp->qp.ibqp.device;
|
||||
struct mlx4_ib_dev *ibdev = to_mdev(ib_dev);
|
||||
struct mlx4_wqe_mlx_seg *mlx = wqe;
|
||||
struct mlx4_wqe_ctrl_seg *ctrl = wqe;
|
||||
struct mlx4_wqe_inline_seg *inl = wqe + sizeof *mlx;
|
||||
@@ -2453,8 +2473,7 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, const struct ib_ud_wr *wr,
|
||||
is_eth = rdma_port_get_link_layer(sqp->qp.ibqp.device, sqp->qp.port) == IB_LINK_LAYER_ETHERNET;
|
||||
is_grh = mlx4_ib_ah_grh_present(ah);
|
||||
if (is_eth) {
|
||||
struct ib_gid_attr gid_attr;
|
||||
|
||||
enum ib_gid_type gid_type;
|
||||
if (mlx4_is_mfunc(to_mdev(ib_dev)->dev)) {
|
||||
/* When multi-function is enabled, the ib_core gid
|
||||
* indexes don't necessarily match the hw ones, so
|
||||
@@ -2465,18 +2484,11 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, const struct ib_ud_wr *wr,
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
err = ib_get_cached_gid(ib_dev,
|
||||
be32_to_cpu(ah->av.ib.port_pd) >> 24,
|
||||
ah->av.ib.gid_index, &sgid,
|
||||
&gid_attr);
|
||||
err = fill_gid_by_hw_index(ibdev, sqp->qp.port,
|
||||
ah->av.ib.gid_index,
|
||||
&sgid, &gid_type);
|
||||
if (!err) {
|
||||
if (gid_attr.ndev)
|
||||
if_rele(gid_attr.ndev);
|
||||
if (!memcmp(&sgid, &zgid, sizeof(sgid)))
|
||||
err = -ENOENT;
|
||||
}
|
||||
if (!err) {
|
||||
is_udp = gid_attr.gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP;
|
||||
is_udp = gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP;
|
||||
if (is_udp) {
|
||||
if (ipv6_addr_v4mapped((struct in6_addr *)&sgid))
|
||||
ip_version = 4;
|
||||
@@ -2954,21 +2966,17 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr,
|
||||
|
||||
if (sqp->roce_v2_gsi) {
|
||||
struct mlx4_ib_ah *ah = to_mah(ud_wr(wr)->ah);
|
||||
struct ib_gid_attr gid_attr;
|
||||
enum ib_gid_type gid_type;
|
||||
union ib_gid gid;
|
||||
|
||||
if (!ib_get_cached_gid(ibqp->device,
|
||||
be32_to_cpu(ah->av.ib.port_pd) >> 24,
|
||||
ah->av.ib.gid_index, &gid,
|
||||
&gid_attr)) {
|
||||
if (gid_attr.ndev)
|
||||
if_rele(gid_attr.ndev);
|
||||
qp = (gid_attr.gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP) ?
|
||||
to_mqp(sqp->roce_v2_gsi) : qp;
|
||||
} else {
|
||||
if (!fill_gid_by_hw_index(mdev, sqp->qp.port,
|
||||
ah->av.ib.gid_index,
|
||||
&gid, &gid_type))
|
||||
qp = (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP) ?
|
||||
to_mqp(sqp->roce_v2_gsi) : qp;
|
||||
else
|
||||
pr_err("Failed to get gid at index %d. RoCEv2 will not work properly\n",
|
||||
ah->av.ib.gid_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,9 @@ int cma_get_default_gid_type(struct cma_device *cma_dev,
|
||||
int cma_set_default_gid_type(struct cma_device *cma_dev,
|
||||
unsigned int port,
|
||||
enum ib_gid_type default_gid_type);
|
||||
int cma_get_default_roce_tos(struct cma_device *cma_dev, unsigned int port);
|
||||
int cma_set_default_roce_tos(struct cma_device *a_dev, unsigned int port,
|
||||
u8 default_roce_tos);
|
||||
struct ib_device *cma_get_ib_dev(struct cma_device *cma_dev);
|
||||
|
||||
int ib_device_register_sysfs(struct ib_device *device,
|
||||
|
||||
@@ -332,13 +332,12 @@ static void make_default_gid(if_t dev, union ib_gid *gid)
|
||||
int ib_cache_gid_add(struct ib_device *ib_dev, u8 port,
|
||||
union ib_gid *gid, struct ib_gid_attr *attr)
|
||||
{
|
||||
struct ib_gid_table **ports_table = ib_dev->cache.gid_cache;
|
||||
struct ib_gid_table *table;
|
||||
int ix;
|
||||
int ret = 0;
|
||||
int empty;
|
||||
|
||||
table = ports_table[port - rdma_start_port(ib_dev)];
|
||||
table = ib_dev->cache.ports[port - rdma_start_port(ib_dev)].gid;
|
||||
|
||||
if (!memcmp(gid, &zgid, sizeof(*gid)))
|
||||
return -EINVAL;
|
||||
@@ -370,11 +369,10 @@ out_unlock:
|
||||
int ib_cache_gid_del(struct ib_device *ib_dev, u8 port,
|
||||
union ib_gid *gid, struct ib_gid_attr *attr)
|
||||
{
|
||||
struct ib_gid_table **ports_table = ib_dev->cache.gid_cache;
|
||||
struct ib_gid_table *table;
|
||||
int ix;
|
||||
|
||||
table = ports_table[port - rdma_start_port(ib_dev)];
|
||||
table = ib_dev->cache.ports[port - rdma_start_port(ib_dev)].gid;
|
||||
|
||||
mutex_lock(&table->lock);
|
||||
write_lock_irq(&table->rwlock);
|
||||
@@ -400,12 +398,11 @@ out_unlock:
|
||||
int ib_cache_gid_del_all_netdev_gids(struct ib_device *ib_dev, u8 port,
|
||||
if_t ndev)
|
||||
{
|
||||
struct ib_gid_table **ports_table = ib_dev->cache.gid_cache;
|
||||
struct ib_gid_table *table;
|
||||
int ix;
|
||||
bool deleted = false;
|
||||
|
||||
table = ports_table[port - rdma_start_port(ib_dev)];
|
||||
table = ib_dev->cache.ports[port - rdma_start_port(ib_dev)].gid;
|
||||
|
||||
mutex_lock(&table->lock);
|
||||
write_lock_irq(&table->rwlock);
|
||||
@@ -429,10 +426,9 @@ int ib_cache_gid_del_all_netdev_gids(struct ib_device *ib_dev, u8 port,
|
||||
static int __ib_cache_gid_get(struct ib_device *ib_dev, u8 port, int index,
|
||||
union ib_gid *gid, struct ib_gid_attr *attr)
|
||||
{
|
||||
struct ib_gid_table **ports_table = ib_dev->cache.gid_cache;
|
||||
struct ib_gid_table *table;
|
||||
|
||||
table = ports_table[port - rdma_start_port(ib_dev)];
|
||||
table = ib_dev->cache.ports[port - rdma_start_port(ib_dev)].gid;
|
||||
|
||||
if (index < 0 || index >= table->sz)
|
||||
return -EINVAL;
|
||||
@@ -461,14 +457,13 @@ static int _ib_cache_gid_table_find(struct ib_device *ib_dev,
|
||||
unsigned long mask,
|
||||
u8 *port, u16 *index)
|
||||
{
|
||||
struct ib_gid_table **ports_table = ib_dev->cache.gid_cache;
|
||||
struct ib_gid_table *table;
|
||||
u8 p;
|
||||
int local_index;
|
||||
unsigned long flags __writeonly;
|
||||
|
||||
for (p = 0; p < ib_dev->phys_port_cnt; p++) {
|
||||
table = ports_table[p];
|
||||
table = ib_dev->cache.ports[p].gid;
|
||||
read_lock_irqsave(&table->rwlock, flags);
|
||||
local_index = find_gid(table, gid, val, false, mask, NULL);
|
||||
if (local_index >= 0) {
|
||||
@@ -509,7 +504,6 @@ int ib_find_cached_gid_by_port(struct ib_device *ib_dev,
|
||||
u16 *index)
|
||||
{
|
||||
int local_index;
|
||||
struct ib_gid_table **ports_table = ib_dev->cache.gid_cache;
|
||||
struct ib_gid_table *table;
|
||||
unsigned long mask = GID_ATTR_FIND_MASK_GID |
|
||||
GID_ATTR_FIND_MASK_GID_TYPE;
|
||||
@@ -519,7 +513,7 @@ int ib_find_cached_gid_by_port(struct ib_device *ib_dev,
|
||||
if (!rdma_is_port_valid(ib_dev, port))
|
||||
return -ENOENT;
|
||||
|
||||
table = ports_table[port - rdma_start_port(ib_dev)];
|
||||
table = ib_dev->cache.ports[port - rdma_start_port(ib_dev)].gid;
|
||||
|
||||
if (ndev)
|
||||
mask |= GID_ATTR_FIND_MASK_NETDEV;
|
||||
@@ -567,22 +561,18 @@ static int ib_cache_gid_find_by_filter(struct ib_device *ib_dev,
|
||||
void *context,
|
||||
u16 *index)
|
||||
{
|
||||
struct ib_gid_table **ports_table = ib_dev->cache.gid_cache;
|
||||
struct ib_gid_table *table;
|
||||
unsigned int i;
|
||||
unsigned long flags __writeonly;
|
||||
bool found = false;
|
||||
|
||||
if (!ports_table)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!rdma_is_port_valid(ib_dev, port))
|
||||
return -EINVAL;
|
||||
|
||||
if (!rdma_protocol_roce(ib_dev, port))
|
||||
return -EPROTONOSUPPORT;
|
||||
|
||||
table = ports_table[port - rdma_start_port(ib_dev)];
|
||||
table = ib_dev->cache.ports[port - rdma_start_port(ib_dev)].gid;
|
||||
|
||||
read_lock_irqsave(&table->rwlock, flags);
|
||||
for (i = 0; i < table->sz; i++) {
|
||||
@@ -674,14 +664,13 @@ void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port,
|
||||
unsigned long gid_type_mask,
|
||||
enum ib_cache_gid_default_mode mode)
|
||||
{
|
||||
struct ib_gid_table **ports_table = ib_dev->cache.gid_cache;
|
||||
union ib_gid gid;
|
||||
struct ib_gid_attr gid_attr;
|
||||
struct ib_gid_attr zattr_type = zattr;
|
||||
struct ib_gid_table *table;
|
||||
unsigned int gid_type;
|
||||
|
||||
table = ports_table[port - rdma_start_port(ib_dev)];
|
||||
table = ib_dev->cache.ports[port - rdma_start_port(ib_dev)].gid;
|
||||
|
||||
make_default_gid(ndev, &gid);
|
||||
memset(&gid_attr, 0, sizeof(gid_attr));
|
||||
@@ -782,71 +771,64 @@ static int gid_table_reserve_default(struct ib_device *ib_dev, u8 port,
|
||||
static int _gid_table_setup_one(struct ib_device *ib_dev)
|
||||
{
|
||||
u8 port;
|
||||
struct ib_gid_table **table;
|
||||
struct ib_gid_table *table;
|
||||
int err = 0;
|
||||
|
||||
table = kcalloc(ib_dev->phys_port_cnt, sizeof(*table), GFP_KERNEL);
|
||||
if (!table)
|
||||
return -ENOMEM;
|
||||
|
||||
for (port = 0; port < ib_dev->phys_port_cnt; port++) {
|
||||
u8 rdma_port = port + rdma_start_port(ib_dev);
|
||||
|
||||
table[port] =
|
||||
table =
|
||||
alloc_gid_table(
|
||||
ib_dev->port_immutable[rdma_port].gid_tbl_len);
|
||||
if (!table[port]) {
|
||||
if (!table) {
|
||||
err = -ENOMEM;
|
||||
goto rollback_table_setup;
|
||||
}
|
||||
|
||||
err = gid_table_reserve_default(ib_dev,
|
||||
port + rdma_start_port(ib_dev),
|
||||
table[port]);
|
||||
table);
|
||||
if (err)
|
||||
goto rollback_table_setup;
|
||||
ib_dev->cache.ports[port].gid = table;
|
||||
}
|
||||
|
||||
ib_dev->cache.gid_cache = table;
|
||||
return 0;
|
||||
|
||||
rollback_table_setup:
|
||||
for (port = 0; port < ib_dev->phys_port_cnt; port++) {
|
||||
table = ib_dev->cache.ports[port].gid;
|
||||
|
||||
cleanup_gid_table_port(ib_dev, port + rdma_start_port(ib_dev),
|
||||
table[port]);
|
||||
release_gid_table(table[port]);
|
||||
table);
|
||||
release_gid_table(table);
|
||||
}
|
||||
|
||||
kfree(table);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void gid_table_release_one(struct ib_device *ib_dev)
|
||||
{
|
||||
struct ib_gid_table **table = ib_dev->cache.gid_cache;
|
||||
struct ib_gid_table *table;
|
||||
u8 port;
|
||||
|
||||
if (!table)
|
||||
return;
|
||||
|
||||
for (port = 0; port < ib_dev->phys_port_cnt; port++)
|
||||
release_gid_table(table[port]);
|
||||
|
||||
kfree(table);
|
||||
ib_dev->cache.gid_cache = NULL;
|
||||
for (port = 0; port < ib_dev->phys_port_cnt; port++) {
|
||||
table = ib_dev->cache.ports[port].gid;
|
||||
release_gid_table(table);
|
||||
ib_dev->cache.ports[port].gid = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void gid_table_cleanup_one(struct ib_device *ib_dev)
|
||||
{
|
||||
struct ib_gid_table **table = ib_dev->cache.gid_cache;
|
||||
struct ib_gid_table *table;
|
||||
u8 port;
|
||||
|
||||
if (!table)
|
||||
return;
|
||||
|
||||
for (port = 0; port < ib_dev->phys_port_cnt; port++)
|
||||
for (port = 0; port < ib_dev->phys_port_cnt; port++) {
|
||||
table = ib_dev->cache.ports[port].gid;
|
||||
cleanup_gid_table_port(ib_dev, port + rdma_start_port(ib_dev),
|
||||
table[port]);
|
||||
table);
|
||||
}
|
||||
}
|
||||
|
||||
static int gid_table_setup_one(struct ib_device *ib_dev)
|
||||
@@ -876,12 +858,12 @@ int ib_get_cached_gid(struct ib_device *device,
|
||||
{
|
||||
int res;
|
||||
unsigned long flags __writeonly;
|
||||
struct ib_gid_table **ports_table = device->cache.gid_cache;
|
||||
struct ib_gid_table *table = ports_table[port_num - rdma_start_port(device)];
|
||||
struct ib_gid_table *table;
|
||||
|
||||
if (!rdma_is_port_valid(device, port_num))
|
||||
return -EINVAL;
|
||||
|
||||
table = device->cache.ports[port_num - rdma_start_port(device)].gid;
|
||||
read_lock_irqsave(&table->rwlock, flags);
|
||||
res = __ib_cache_gid_get(device, port_num, index, gid, gid_attr);
|
||||
read_unlock_irqrestore(&table->rwlock, flags);
|
||||
@@ -933,7 +915,7 @@ int ib_get_cached_pkey(struct ib_device *device,
|
||||
|
||||
read_lock_irqsave(&device->cache.lock, flags);
|
||||
|
||||
cache = device->cache.pkey_cache[port_num - rdma_start_port(device)];
|
||||
cache = device->cache.ports[port_num - rdma_start_port(device)].pkey;
|
||||
|
||||
if (index < 0 || index >= cache->table_len)
|
||||
ret = -EINVAL;
|
||||
@@ -962,7 +944,7 @@ int ib_find_cached_pkey(struct ib_device *device,
|
||||
|
||||
read_lock_irqsave(&device->cache.lock, flags);
|
||||
|
||||
cache = device->cache.pkey_cache[port_num - rdma_start_port(device)];
|
||||
cache = device->cache.ports[port_num - rdma_start_port(device)].pkey;
|
||||
|
||||
*index = -1;
|
||||
|
||||
@@ -1002,7 +984,7 @@ int ib_find_exact_cached_pkey(struct ib_device *device,
|
||||
|
||||
read_lock_irqsave(&device->cache.lock, flags);
|
||||
|
||||
cache = device->cache.pkey_cache[port_num - rdma_start_port(device)];
|
||||
cache = device->cache.ports[port_num - rdma_start_port(device)].pkey;
|
||||
|
||||
*index = -1;
|
||||
|
||||
@@ -1030,13 +1012,32 @@ int ib_get_cached_lmc(struct ib_device *device,
|
||||
return -EINVAL;
|
||||
|
||||
read_lock_irqsave(&device->cache.lock, flags);
|
||||
*lmc = device->cache.lmc_cache[port_num - rdma_start_port(device)];
|
||||
*lmc = device->cache.ports[port_num - rdma_start_port(device)].lmc;
|
||||
read_unlock_irqrestore(&device->cache.lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(ib_get_cached_lmc);
|
||||
|
||||
int ib_get_cached_port_state(struct ib_device *device,
|
||||
u8 port_num,
|
||||
enum ib_port_state *port_state)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
if (!rdma_is_port_valid(device, port_num))
|
||||
return -EINVAL;
|
||||
|
||||
read_lock_irqsave(&device->cache.lock, flags);
|
||||
*port_state = device->cache.ports[port_num
|
||||
- rdma_start_port(device)].port_state;
|
||||
read_unlock_irqrestore(&device->cache.lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(ib_get_cached_port_state);
|
||||
|
||||
static void ib_cache_update(struct ib_device *device,
|
||||
u8 port)
|
||||
{
|
||||
@@ -1049,14 +1050,13 @@ static void ib_cache_update(struct ib_device *device,
|
||||
int i;
|
||||
int ret;
|
||||
struct ib_gid_table *table;
|
||||
struct ib_gid_table **ports_table = device->cache.gid_cache;
|
||||
bool use_roce_gid_table =
|
||||
rdma_cap_roce_gid_table(device, port);
|
||||
|
||||
if (!rdma_is_port_valid(device, port))
|
||||
return;
|
||||
|
||||
table = ports_table[port - rdma_start_port(device)];
|
||||
table = device->cache.ports[port - rdma_start_port(device)].gid;
|
||||
|
||||
tprops = kmalloc(sizeof *tprops, GFP_KERNEL);
|
||||
if (!tprops)
|
||||
@@ -1108,9 +1108,10 @@ static void ib_cache_update(struct ib_device *device,
|
||||
|
||||
write_lock_irq(&device->cache.lock);
|
||||
|
||||
old_pkey_cache = device->cache.pkey_cache[port - rdma_start_port(device)];
|
||||
old_pkey_cache = device->cache.ports[port -
|
||||
rdma_start_port(device)].pkey;
|
||||
|
||||
device->cache.pkey_cache[port - rdma_start_port(device)] = pkey_cache;
|
||||
device->cache.ports[port - rdma_start_port(device)].pkey = pkey_cache;
|
||||
if (!use_roce_gid_table) {
|
||||
write_lock(&table->rwlock);
|
||||
for (i = 0; i < gid_cache->table_len; i++) {
|
||||
@@ -1120,7 +1121,9 @@ static void ib_cache_update(struct ib_device *device,
|
||||
write_unlock(&table->rwlock);
|
||||
}
|
||||
|
||||
device->cache.lmc_cache[port - rdma_start_port(device)] = tprops->lmc;
|
||||
device->cache.ports[port - rdma_start_port(device)].lmc = tprops->lmc;
|
||||
device->cache.ports[port - rdma_start_port(device)].port_state =
|
||||
tprops->state;
|
||||
|
||||
write_unlock_irq(&device->cache.lock);
|
||||
|
||||
@@ -1173,22 +1176,17 @@ int ib_cache_setup_one(struct ib_device *device)
|
||||
|
||||
rwlock_init(&device->cache.lock);
|
||||
|
||||
device->cache.pkey_cache =
|
||||
kzalloc(sizeof *device->cache.pkey_cache *
|
||||
device->cache.ports =
|
||||
kzalloc(sizeof(*device->cache.ports) *
|
||||
(rdma_end_port(device) - rdma_start_port(device) + 1), GFP_KERNEL);
|
||||
device->cache.lmc_cache = kmalloc(sizeof *device->cache.lmc_cache *
|
||||
(rdma_end_port(device) -
|
||||
rdma_start_port(device) + 1),
|
||||
GFP_KERNEL);
|
||||
if (!device->cache.pkey_cache ||
|
||||
!device->cache.lmc_cache) {
|
||||
if (!device->cache.ports) {
|
||||
err = -ENOMEM;
|
||||
goto free;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = gid_table_setup_one(device);
|
||||
if (err)
|
||||
goto free;
|
||||
goto out;
|
||||
|
||||
for (p = 0; p <= rdma_end_port(device) - rdma_start_port(device); ++p)
|
||||
ib_cache_update(device, p + rdma_start_port(device));
|
||||
@@ -1203,9 +1201,7 @@ int ib_cache_setup_one(struct ib_device *device)
|
||||
|
||||
err:
|
||||
gid_table_cleanup_one(device);
|
||||
free:
|
||||
kfree(device->cache.pkey_cache);
|
||||
kfree(device->cache.lmc_cache);
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -1219,14 +1215,11 @@ void ib_cache_release_one(struct ib_device *device)
|
||||
* all the device's resources when the cache could no
|
||||
* longer be accessed.
|
||||
*/
|
||||
if (device->cache.pkey_cache)
|
||||
for (p = 0;
|
||||
p <= rdma_end_port(device) - rdma_start_port(device); ++p)
|
||||
kfree(device->cache.pkey_cache[p]);
|
||||
for (p = 0; p <= rdma_end_port(device) - rdma_start_port(device); ++p)
|
||||
kfree(device->cache.ports[p].pkey);
|
||||
|
||||
gid_table_release_one(device);
|
||||
kfree(device->cache.pkey_cache);
|
||||
kfree(device->cache.lmc_cache);
|
||||
kfree(device->cache.ports);
|
||||
}
|
||||
|
||||
void ib_cache_cleanup_one(struct ib_device *device)
|
||||
|
||||
@@ -223,6 +223,7 @@ struct cma_device {
|
||||
struct list_head id_list;
|
||||
struct sysctl_ctx_list sysctl_ctx;
|
||||
enum ib_gid_type *default_gid_type;
|
||||
u8 *default_roce_tos;
|
||||
};
|
||||
|
||||
struct rdma_bind_list {
|
||||
@@ -320,6 +321,25 @@ int cma_set_default_gid_type(struct cma_device *cma_dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cma_get_default_roce_tos(struct cma_device *cma_dev, unsigned int port)
|
||||
{
|
||||
if (!rdma_is_port_valid(cma_dev->device, port))
|
||||
return -EINVAL;
|
||||
|
||||
return cma_dev->default_roce_tos[port - rdma_start_port(cma_dev->device)];
|
||||
}
|
||||
|
||||
int cma_set_default_roce_tos(struct cma_device *cma_dev, unsigned int port,
|
||||
u8 default_roce_tos)
|
||||
{
|
||||
if (!rdma_is_port_valid(cma_dev->device, port))
|
||||
return -EINVAL;
|
||||
|
||||
cma_dev->default_roce_tos[port - rdma_start_port(cma_dev->device)] =
|
||||
default_roce_tos;
|
||||
|
||||
return 0;
|
||||
}
|
||||
struct ib_device *cma_get_ib_dev(struct cma_device *cma_dev)
|
||||
{
|
||||
return cma_dev->device;
|
||||
@@ -366,6 +386,7 @@ struct rdma_id_private {
|
||||
u32 options;
|
||||
u8 srq;
|
||||
u8 tos;
|
||||
u8 tos_set:1;
|
||||
u8 timeout_set:1;
|
||||
u8 reuseaddr;
|
||||
u8 afonly;
|
||||
@@ -734,6 +755,7 @@ static int cma_resolve_ib_dev(struct rdma_id_private *id_priv)
|
||||
union ib_gid gid, sgid, *dgid;
|
||||
u16 pkey, index;
|
||||
u8 p;
|
||||
enum ib_port_state port_state;
|
||||
int i;
|
||||
|
||||
cma_dev = NULL;
|
||||
@@ -749,6 +771,8 @@ static int cma_resolve_ib_dev(struct rdma_id_private *id_priv)
|
||||
if (ib_find_cached_pkey(cur_dev->device, p, pkey, &index))
|
||||
continue;
|
||||
|
||||
if (ib_get_cached_port_state(cur_dev->device, p, &port_state))
|
||||
continue;
|
||||
for (i = 0; !ib_get_cached_gid(cur_dev->device, p, i,
|
||||
&gid, NULL);
|
||||
i++) {
|
||||
@@ -760,7 +784,8 @@ static int cma_resolve_ib_dev(struct rdma_id_private *id_priv)
|
||||
}
|
||||
|
||||
if (!cma_dev && (gid.global.subnet_prefix ==
|
||||
dgid->global.subnet_prefix)) {
|
||||
dgid->global.subnet_prefix) &&
|
||||
port_state == IB_PORT_ACTIVE) {
|
||||
cma_dev = cur_dev;
|
||||
sgid = gid;
|
||||
id_priv->id.port_num = p;
|
||||
@@ -807,6 +832,7 @@ struct rdma_cm_id *rdma_create_id(struct vnet *net,
|
||||
id_priv->id.event_handler = event_handler;
|
||||
id_priv->id.ps = ps;
|
||||
id_priv->id.qp_type = qp_type;
|
||||
id_priv->tos_set = false;
|
||||
id_priv->timeout_set = false;
|
||||
spin_lock_init(&id_priv->lock);
|
||||
mutex_init(&id_priv->qp_mutex);
|
||||
@@ -2560,6 +2586,7 @@ void rdma_set_service_type(struct rdma_cm_id *id, int tos)
|
||||
|
||||
id_priv = container_of(id, struct rdma_id_private, id);
|
||||
id_priv->tos = (u8) tos;
|
||||
id_priv->tos_set = true;
|
||||
}
|
||||
EXPORT_SYMBOL(rdma_set_service_type);
|
||||
|
||||
@@ -2787,6 +2814,9 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
|
||||
struct cma_work *work;
|
||||
int ret;
|
||||
if_t ndev = NULL;
|
||||
u8 default_roce_tos = id_priv->cma_dev->default_roce_tos[id_priv->id.port_num -
|
||||
rdma_start_port(id_priv->cma_dev->device)];
|
||||
u8 tos = id_priv->tos_set ? id_priv->tos : default_roce_tos;
|
||||
|
||||
|
||||
work = kzalloc(sizeof *work, GFP_KERNEL);
|
||||
@@ -2846,8 +2876,8 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
|
||||
route->path_rec->reversible = 1;
|
||||
route->path_rec->pkey = cpu_to_be16(0xffff);
|
||||
route->path_rec->mtu_selector = IB_SA_EQ;
|
||||
route->path_rec->sl = iboe_tos_to_sl(ndev, id_priv->tos);
|
||||
route->path_rec->traffic_class = id_priv->tos;
|
||||
route->path_rec->sl = iboe_tos_to_sl(ndev, tos);
|
||||
route->path_rec->traffic_class = tos;
|
||||
route->path_rec->mtu = iboe_get_mtu(if_getmtu(ndev));
|
||||
route->path_rec->rate_selector = IB_SA_EQ;
|
||||
route->path_rec->rate = iboe_get_rate(ndev);
|
||||
@@ -3108,20 +3138,26 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
|
||||
int ret;
|
||||
|
||||
id_priv = container_of(id, struct rdma_id_private, id);
|
||||
memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr));
|
||||
if (id_priv->state == RDMA_CM_IDLE) {
|
||||
ret = cma_bind_addr(id, src_addr, dst_addr);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
memset(cma_dst_addr(id_priv), 0, rdma_addr_size(dst_addr));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (cma_family(id_priv) != dst_addr->sa_family)
|
||||
if (cma_family(id_priv) != dst_addr->sa_family) {
|
||||
memset(cma_dst_addr(id_priv), 0, rdma_addr_size(dst_addr));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY))
|
||||
if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY)) {
|
||||
memset(cma_dst_addr(id_priv), 0, rdma_addr_size(dst_addr));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
atomic_inc(&id_priv->refcount);
|
||||
memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr));
|
||||
if (cma_any_addr(vnet, dst_addr)) {
|
||||
ret = cma_resolve_loopback(id_priv);
|
||||
} else {
|
||||
@@ -3241,6 +3277,45 @@ err:
|
||||
return ret == -ENOSPC ? -EADDRNOTAVAIL : ret;
|
||||
}
|
||||
|
||||
static int cma_port_is_unique(struct rdma_bind_list *bind_list,
|
||||
struct rdma_id_private *id_priv)
|
||||
{
|
||||
struct rdma_id_private *cur_id;
|
||||
struct vnet *vnet = id_priv->id.route.addr.dev_addr.net;
|
||||
struct sockaddr *daddr = cma_dst_addr(id_priv);
|
||||
struct sockaddr *saddr = cma_src_addr(id_priv);
|
||||
__be16 dport = cma_port(daddr);
|
||||
|
||||
hlist_for_each_entry(cur_id, &bind_list->owners, node) {
|
||||
struct vnet *cur_vnet = cur_id->id.route.addr.dev_addr.net;
|
||||
struct sockaddr *cur_daddr = cma_dst_addr(cur_id);
|
||||
struct sockaddr *cur_saddr = cma_src_addr(cur_id);
|
||||
__be16 cur_dport = cma_port(cur_daddr);
|
||||
|
||||
if (id_priv == cur_id)
|
||||
continue;
|
||||
|
||||
/* different dest port -> unique */
|
||||
if (!cma_any_port(cur_daddr) &&
|
||||
(dport != cur_dport))
|
||||
continue;
|
||||
|
||||
/* different src address -> unique */
|
||||
if (!cma_any_addr(vnet, saddr) &&
|
||||
!cma_any_addr(cur_vnet, cur_saddr) &&
|
||||
cma_addr_cmp(saddr, cur_saddr))
|
||||
continue;
|
||||
|
||||
/* different dst address -> unique */
|
||||
if (!cma_any_addr(cur_vnet, cur_daddr) &&
|
||||
cma_addr_cmp(daddr, cur_daddr))
|
||||
continue;
|
||||
|
||||
return -EADDRNOTAVAIL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cma_alloc_any_port(enum rdma_port_space ps,
|
||||
struct rdma_id_private *id_priv)
|
||||
{
|
||||
@@ -3253,9 +3328,19 @@ static int cma_alloc_any_port(enum rdma_port_space ps,
|
||||
remaining = (high - low) + 1;
|
||||
rover = prandom_u32() % remaining + low;
|
||||
retry:
|
||||
if (last_used_port != rover &&
|
||||
!cma_ps_find(net, ps, (unsigned short)rover)) {
|
||||
int ret = cma_alloc_port(ps, id_priv, rover);
|
||||
if (last_used_port != rover) {
|
||||
struct rdma_bind_list *bind_list;
|
||||
int ret;
|
||||
|
||||
bind_list = cma_ps_find(net, ps, (unsigned short)rover);
|
||||
|
||||
if (!bind_list) {
|
||||
ret = cma_alloc_port(ps, id_priv, rover);
|
||||
} else {
|
||||
ret = cma_port_is_unique(bind_list, id_priv);
|
||||
if (!ret)
|
||||
cma_bind_port(bind_list, id_priv);
|
||||
}
|
||||
/*
|
||||
* Remember previously used port number in order to avoid
|
||||
* re-using same port immediately after it is closed.
|
||||
@@ -3495,6 +3580,7 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
|
||||
struct rdma_id_private *id_priv;
|
||||
struct vnet *vnet = id->route.addr.dev_addr.net;
|
||||
int ret;
|
||||
struct sockaddr *daddr;
|
||||
|
||||
if (addr->sa_family != AF_INET && addr->sa_family != AF_INET6 &&
|
||||
addr->sa_family != AF_IB)
|
||||
@@ -3534,6 +3620,9 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
|
||||
if (ret)
|
||||
goto err2;
|
||||
|
||||
daddr = cma_dst_addr(id_priv);
|
||||
daddr->sa_family = addr->sa_family;
|
||||
|
||||
return 0;
|
||||
err2:
|
||||
if (id_priv->cma_dev)
|
||||
@@ -4531,6 +4620,25 @@ done:
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
sysctl_cma_default_roce_tos(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct cma_device *cma_dev = arg1;
|
||||
const int port = arg2;
|
||||
int error;
|
||||
u8 tos;
|
||||
|
||||
tos = cma_get_default_roce_tos(cma_dev, port);
|
||||
|
||||
error = sysctl_handle_8(oidp, &tos, sizeof(tos), req);
|
||||
if (error != 0 || req->newptr == NULL)
|
||||
goto done;
|
||||
|
||||
error = -cma_set_default_roce_tos(cma_dev, port, tos);
|
||||
done:
|
||||
return (error);
|
||||
}
|
||||
|
||||
static void cma_add_one(struct ib_device *device)
|
||||
{
|
||||
struct cma_device *cma_dev;
|
||||
@@ -4547,10 +4655,15 @@ static void cma_add_one(struct ib_device *device)
|
||||
cma_dev->default_gid_type = kcalloc(device->phys_port_cnt,
|
||||
sizeof(*cma_dev->default_gid_type),
|
||||
GFP_KERNEL);
|
||||
if (!cma_dev->default_gid_type) {
|
||||
kfree(cma_dev);
|
||||
return;
|
||||
}
|
||||
if (!cma_dev->default_gid_type)
|
||||
goto free_cma_dev;
|
||||
|
||||
cma_dev->default_roce_tos = kcalloc(device->phys_port_cnt,
|
||||
sizeof(*cma_dev->default_roce_tos),
|
||||
GFP_KERNEL);
|
||||
if (!cma_dev->default_roce_tos)
|
||||
goto free_gid_type;
|
||||
|
||||
for (i = rdma_start_port(device); i <= rdma_end_port(device); i++) {
|
||||
unsigned long supported_gids;
|
||||
unsigned int default_gid_type;
|
||||
@@ -4569,6 +4682,7 @@ static void cma_add_one(struct ib_device *device)
|
||||
}
|
||||
cma_dev->default_gid_type[i - rdma_start_port(device)] =
|
||||
default_gid_type;
|
||||
cma_dev->default_roce_tos[i - rdma_start_port(device)] = 0;
|
||||
}
|
||||
|
||||
init_completion(&cma_dev->comp);
|
||||
@@ -4592,7 +4706,25 @@ static void cma_add_one(struct ib_device *device)
|
||||
OID_AUTO, buf, CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
cma_dev, i, &sysctl_cma_default_roce_mode, "A",
|
||||
"Default RoCE mode. Valid values: IB/RoCE v1 and RoCE v2");
|
||||
|
||||
snprintf(buf, sizeof(buf), "default_roce_tos_port%d", i);
|
||||
|
||||
(void) SYSCTL_ADD_PROC(&cma_dev->sysctl_ctx,
|
||||
SYSCTL_CHILDREN(device->ports_parent->parent->oidp),
|
||||
OID_AUTO, buf, CTLTYPE_U8 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
cma_dev, i, &sysctl_cma_default_roce_tos, "CU",
|
||||
"Default RoCE TOS. Valid values: 0-255");
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
free_gid_type:
|
||||
kfree(cma_dev->default_gid_type);
|
||||
|
||||
free_cma_dev:
|
||||
kfree(cma_dev);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int cma_remove_id_dev(struct rdma_id_private *id_priv)
|
||||
@@ -4662,6 +4794,7 @@ static void cma_remove_one(struct ib_device *device, void *client_data)
|
||||
|
||||
cma_process_remove(cma_dev);
|
||||
sysctl_ctx_free(&cma_dev->sysctl_ctx);
|
||||
kfree(cma_dev->default_roce_tos);
|
||||
kfree(cma_dev->default_gid_type);
|
||||
kfree(cma_dev);
|
||||
}
|
||||
|
||||
@@ -325,7 +325,9 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
|
||||
/* Validate device and port */
|
||||
port_priv = ib_get_mad_port(device, port_num);
|
||||
if (!port_priv) {
|
||||
dev_notice(&device->dev, "ib_register_mad_agent: Invalid port\n");
|
||||
dev_notice(&device->dev,
|
||||
"ib_register_mad_agent: Invalid port %d\n",
|
||||
port_num);
|
||||
ret = ERR_PTR(-ENODEV);
|
||||
goto error1;
|
||||
}
|
||||
|
||||
@@ -101,9 +101,6 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
|
||||
if (dmasync)
|
||||
dma_attrs |= DMA_ATTR_WRITE_BARRIER;
|
||||
|
||||
if (!size)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
/*
|
||||
* If the combination of the addr and size requested for this memory
|
||||
* region causes an integer overflow, return error.
|
||||
@@ -136,6 +133,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
|
||||
IB_ACCESS_REMOTE_ATOMIC | IB_ACCESS_MW_BIND));
|
||||
|
||||
if (access & IB_ACCESS_ON_DEMAND) {
|
||||
put_pid(umem->pid);
|
||||
ret = ib_umem_odp_get(context, umem);
|
||||
if (ret) {
|
||||
kfree(umem);
|
||||
@@ -148,6 +146,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
|
||||
|
||||
page_list = (struct page **) __get_free_page(GFP_KERNEL);
|
||||
if (!page_list) {
|
||||
put_pid(umem->pid);
|
||||
kfree(umem);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
@@ -240,6 +240,71 @@ static const struct mmu_notifier_ops ib_umem_notifiers = {
|
||||
.invalidate_range_end = ib_umem_notifier_invalidate_range_end,
|
||||
};
|
||||
|
||||
struct ib_umem *ib_alloc_odp_umem(struct ib_ucontext *context,
|
||||
unsigned long addr,
|
||||
size_t size)
|
||||
{
|
||||
struct ib_umem *umem;
|
||||
struct ib_umem_odp *odp_data;
|
||||
int pages = size >> PAGE_SHIFT;
|
||||
int ret;
|
||||
|
||||
umem = kzalloc(sizeof(*umem), GFP_KERNEL);
|
||||
if (!umem)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
umem->context = context;
|
||||
umem->length = size;
|
||||
umem->address = addr;
|
||||
umem->page_size = PAGE_SIZE;
|
||||
umem->writable = 1;
|
||||
|
||||
odp_data = kzalloc(sizeof(*odp_data), GFP_KERNEL);
|
||||
if (!odp_data) {
|
||||
ret = -ENOMEM;
|
||||
goto out_umem;
|
||||
}
|
||||
odp_data->umem = umem;
|
||||
|
||||
mutex_init(&odp_data->umem_mutex);
|
||||
init_completion(&odp_data->notifier_completion);
|
||||
|
||||
odp_data->page_list = vzalloc(pages * sizeof(*odp_data->page_list));
|
||||
if (!odp_data->page_list) {
|
||||
ret = -ENOMEM;
|
||||
goto out_odp_data;
|
||||
}
|
||||
|
||||
odp_data->dma_list = vzalloc(pages * sizeof(*odp_data->dma_list));
|
||||
if (!odp_data->dma_list) {
|
||||
ret = -ENOMEM;
|
||||
goto out_page_list;
|
||||
}
|
||||
|
||||
down_write(&context->umem_rwsem);
|
||||
context->odp_mrs_count++;
|
||||
rbt_ib_umem_insert(&odp_data->interval_tree, &context->umem_tree);
|
||||
if (likely(!atomic_read(&context->notifier_count)))
|
||||
odp_data->mn_counters_active = true;
|
||||
else
|
||||
list_add(&odp_data->no_private_counters,
|
||||
&context->no_private_counters);
|
||||
up_write(&context->umem_rwsem);
|
||||
|
||||
umem->odp_data = odp_data;
|
||||
|
||||
return umem;
|
||||
|
||||
out_page_list:
|
||||
vfree(odp_data->page_list);
|
||||
out_odp_data:
|
||||
kfree(odp_data);
|
||||
out_umem:
|
||||
kfree(umem);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
EXPORT_SYMBOL(ib_alloc_odp_umem);
|
||||
|
||||
int ib_umem_odp_get(struct ib_ucontext *context, struct ib_umem *umem)
|
||||
{
|
||||
int ret_val;
|
||||
@@ -270,18 +335,20 @@ int ib_umem_odp_get(struct ib_ucontext *context, struct ib_umem *umem)
|
||||
|
||||
init_completion(&umem->odp_data->notifier_completion);
|
||||
|
||||
umem->odp_data->page_list = vzalloc(ib_umem_num_pages(umem) *
|
||||
if (ib_umem_num_pages(umem)) {
|
||||
umem->odp_data->page_list = vzalloc(ib_umem_num_pages(umem) *
|
||||
sizeof(*umem->odp_data->page_list));
|
||||
if (!umem->odp_data->page_list) {
|
||||
ret_val = -ENOMEM;
|
||||
goto out_odp_data;
|
||||
}
|
||||
if (!umem->odp_data->page_list) {
|
||||
ret_val = -ENOMEM;
|
||||
goto out_odp_data;
|
||||
}
|
||||
|
||||
umem->odp_data->dma_list = vzalloc(ib_umem_num_pages(umem) *
|
||||
umem->odp_data->dma_list = vzalloc(ib_umem_num_pages(umem) *
|
||||
sizeof(*umem->odp_data->dma_list));
|
||||
if (!umem->odp_data->dma_list) {
|
||||
ret_val = -ENOMEM;
|
||||
goto out_page_list;
|
||||
if (!umem->odp_data->dma_list) {
|
||||
ret_val = -ENOMEM;
|
||||
goto out_page_list;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -464,6 +531,7 @@ static int ib_umem_odp_map_dma_single_page(
|
||||
}
|
||||
umem->odp_data->dma_list[page_index] = dma_addr | access_mask;
|
||||
umem->odp_data->page_list[page_index] = page;
|
||||
umem->npages++;
|
||||
stored_page = 1;
|
||||
} else if (umem->odp_data->page_list[page_index] == page) {
|
||||
umem->odp_data->dma_list[page_index] |= access_mask;
|
||||
@@ -503,7 +571,8 @@ out:
|
||||
* for failure.
|
||||
* An -EAGAIN error code is returned when a concurrent mmu notifier prevents
|
||||
* the function from completing its task.
|
||||
*
|
||||
* An -ENOENT error code indicates that userspace process is being terminated
|
||||
* and mm was already destroyed.
|
||||
* @umem: the umem to map and pin
|
||||
* @user_virt: the address from which we need to map.
|
||||
* @bcnt: the minimal number of bytes to pin and map. The mapping might be
|
||||
@@ -551,7 +620,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 user_virt, u64 bcnt,
|
||||
|
||||
owning_mm = get_task_mm(owning_process);
|
||||
if (owning_mm == NULL) {
|
||||
ret = -EINVAL;
|
||||
ret = -ENOENT;
|
||||
goto out_put_task;
|
||||
}
|
||||
|
||||
@@ -663,6 +732,7 @@ void ib_umem_odp_unmap_dma_pages(struct ib_umem *umem, u64 virt,
|
||||
put_page(page);
|
||||
umem->odp_data->page_list[idx] = NULL;
|
||||
umem->odp_data->dma_list[idx] = 0;
|
||||
umem->npages--;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&umem->odp_data->umem_mutex);
|
||||
|
||||
@@ -80,17 +80,32 @@ int rbt_ib_umem_for_each_in_range(struct rb_root *root,
|
||||
void *cookie)
|
||||
{
|
||||
int ret_val = 0;
|
||||
struct umem_odp_node *node;
|
||||
struct umem_odp_node *node, *next;
|
||||
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)) {
|
||||
for (node = rbt_ib_umem_iter_first(root, start, last - 1);
|
||||
node; node = next) {
|
||||
next = 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;
|
||||
}
|
||||
EXPORT_SYMBOL(rbt_ib_umem_for_each_in_range);
|
||||
|
||||
struct ib_umem_odp *rbt_ib_umem_lookup(struct rb_root *root,
|
||||
u64 addr, u64 length)
|
||||
{
|
||||
struct umem_odp_node *node;
|
||||
|
||||
node = rbt_ib_umem_iter_first(root, addr, addr + length - 1);
|
||||
if (node)
|
||||
return container_of(node, struct ib_umem_odp, interval_tree);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(rbt_ib_umem_lookup);
|
||||
@@ -167,4 +167,17 @@ int ib_get_cached_lmc(struct ib_device *device,
|
||||
u8 port_num,
|
||||
u8 *lmc);
|
||||
|
||||
/**
|
||||
* ib_get_cached_port_state - Returns a cached port state table entry
|
||||
* @device: The device to query.
|
||||
* @port_num: The port number of the device to query.
|
||||
* @port_state: port_state for the specified port for that device.
|
||||
*
|
||||
* ib_get_cached_port_state() fetches the specified port_state table entry stored in
|
||||
* the local software cache.
|
||||
*/
|
||||
int ib_get_cached_port_state(struct ib_device *device,
|
||||
u8 port_num,
|
||||
enum ib_port_state *port_active);
|
||||
|
||||
#endif /* _IB_CACHE_H */
|
||||
@@ -154,12 +154,12 @@ struct ib_sa_path_rec {
|
||||
union ib_gid sgid;
|
||||
__be16 dlid;
|
||||
__be16 slid;
|
||||
int raw_traffic;
|
||||
u8 raw_traffic;
|
||||
/* reserved */
|
||||
__be32 flow_label;
|
||||
u8 hop_limit;
|
||||
u8 traffic_class;
|
||||
int reversible;
|
||||
u8 reversible;
|
||||
u8 numb_path;
|
||||
__be16 pkey;
|
||||
__be16 qos_class;
|
||||
@@ -225,7 +225,7 @@ struct ib_sa_mcmember_rec {
|
||||
u8 hop_limit;
|
||||
u8 scope;
|
||||
u8 join_state;
|
||||
int proxy_join;
|
||||
u8 proxy_join;
|
||||
};
|
||||
|
||||
/* Service Record Component Mask Sec 15.2.5.14 Ver 1.1 */
|
||||
|
||||
@@ -82,11 +82,15 @@ struct ib_umem_odp {
|
||||
|
||||
struct completion notifier_completion;
|
||||
int dying;
|
||||
struct work_struct work;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
|
||||
|
||||
int ib_umem_odp_get(struct ib_ucontext *context, struct ib_umem *umem);
|
||||
struct ib_umem *ib_alloc_odp_umem(struct ib_ucontext *context,
|
||||
unsigned long addr,
|
||||
size_t size);
|
||||
|
||||
void ib_umem_odp_release(struct ib_umem *umem);
|
||||
|
||||
@@ -120,10 +124,12 @@ typedef int (*umem_call_back)(struct ib_umem *item, u64 start, u64 end,
|
||||
int rbt_ib_umem_for_each_in_range(struct rb_root *root, u64 start, u64 end,
|
||||
umem_call_back cb, void *cookie);
|
||||
|
||||
struct umem_odp_node *rbt_ib_umem_iter_first(struct rb_root *root,
|
||||
u64 start, u64 last);
|
||||
struct umem_odp_node *rbt_ib_umem_iter_next(struct umem_odp_node *node,
|
||||
u64 start, u64 last);
|
||||
/*
|
||||
* Find first region intersecting with address range.
|
||||
* Return NULL if not found
|
||||
*/
|
||||
struct ib_umem_odp *rbt_ib_umem_lookup(struct rb_root *root,
|
||||
u64 addr, u64 length);
|
||||
|
||||
static inline int ib_umem_mmu_notifier_retry(struct ib_umem *item,
|
||||
unsigned long mmu_seq)
|
||||
@@ -156,6 +162,13 @@ static inline int ib_umem_odp_get(struct ib_ucontext *context,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline struct ib_umem *ib_alloc_odp_umem(struct ib_ucontext *context,
|
||||
unsigned long addr,
|
||||
size_t size)
|
||||
{
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
static inline void ib_umem_odp_release(struct ib_umem *umem) {}
|
||||
|
||||
#endif /* CONFIG_INFINIBAND_ON_DEMAND_PAGING */
|
||||
|
||||
@@ -252,7 +252,8 @@ enum ib_atomic_cap {
|
||||
};
|
||||
|
||||
enum ib_odp_general_cap_bits {
|
||||
IB_ODP_SUPPORT = 1 << 0,
|
||||
IB_ODP_SUPPORT = 1 << 0,
|
||||
IB_ODP_SUPPORT_IMPLICIT = 1 << 1,
|
||||
};
|
||||
|
||||
enum ib_odp_transport_cap_bits {
|
||||
@@ -2005,59 +2006,17 @@ enum ib_mad_result {
|
||||
|
||||
#define IB_DEVICE_NAME_MAX 64
|
||||
|
||||
struct ib_port_cache {
|
||||
struct ib_pkey_cache *pkey;
|
||||
struct ib_gid_table *gid;
|
||||
u8 lmc;
|
||||
enum ib_port_state port_state;
|
||||
};
|
||||
|
||||
struct ib_cache {
|
||||
rwlock_t lock;
|
||||
struct ib_event_handler event_handler;
|
||||
struct ib_pkey_cache **pkey_cache;
|
||||
struct ib_gid_table **gid_cache;
|
||||
u8 *lmc_cache;
|
||||
};
|
||||
|
||||
struct ib_dma_mapping_ops {
|
||||
int (*mapping_error)(struct ib_device *dev,
|
||||
u64 dma_addr);
|
||||
u64 (*map_single)(struct ib_device *dev,
|
||||
void *ptr, size_t size,
|
||||
enum dma_data_direction direction);
|
||||
void (*unmap_single)(struct ib_device *dev,
|
||||
u64 addr, size_t size,
|
||||
enum dma_data_direction direction);
|
||||
u64 (*map_page)(struct ib_device *dev,
|
||||
struct page *page, unsigned long offset,
|
||||
size_t size,
|
||||
enum dma_data_direction direction);
|
||||
void (*unmap_page)(struct ib_device *dev,
|
||||
u64 addr, size_t size,
|
||||
enum dma_data_direction direction);
|
||||
int (*map_sg)(struct ib_device *dev,
|
||||
struct scatterlist *sg, int nents,
|
||||
enum dma_data_direction direction);
|
||||
void (*unmap_sg)(struct ib_device *dev,
|
||||
struct scatterlist *sg, int nents,
|
||||
enum dma_data_direction direction);
|
||||
int (*map_sg_attrs)(struct ib_device *dev,
|
||||
struct scatterlist *sg, int nents,
|
||||
enum dma_data_direction direction,
|
||||
unsigned long attrs);
|
||||
void (*unmap_sg_attrs)(struct ib_device *dev,
|
||||
struct scatterlist *sg, int nents,
|
||||
enum dma_data_direction direction,
|
||||
unsigned long attrs);
|
||||
void (*sync_single_for_cpu)(struct ib_device *dev,
|
||||
u64 dma_handle,
|
||||
size_t size,
|
||||
enum dma_data_direction dir);
|
||||
void (*sync_single_for_device)(struct ib_device *dev,
|
||||
u64 dma_handle,
|
||||
size_t size,
|
||||
enum dma_data_direction dir);
|
||||
void *(*alloc_coherent)(struct ib_device *dev,
|
||||
size_t size,
|
||||
u64 *dma_handle,
|
||||
gfp_t flag);
|
||||
void (*free_coherent)(struct ib_device *dev,
|
||||
size_t size, void *cpu_addr,
|
||||
u64 dma_handle);
|
||||
struct ib_port_cache *ports;
|
||||
};
|
||||
|
||||
struct iw_cm_verbs;
|
||||
@@ -2413,7 +2372,6 @@ struct ib_device {
|
||||
int (*read_counters)(struct ib_counters *counters,
|
||||
struct ib_counters_read_attr *counters_read_attr,
|
||||
struct uverbs_attr_bundle *attrs);
|
||||
struct ib_dma_mapping_ops *dma_ops;
|
||||
|
||||
struct module *owner;
|
||||
struct device dev;
|
||||
@@ -3531,8 +3489,6 @@ static inline int ib_req_ncomp_notif(struct ib_cq *cq, int wc_cnt)
|
||||
*/
|
||||
static inline int ib_dma_mapping_error(struct ib_device *dev, u64 dma_addr)
|
||||
{
|
||||
if (dev->dma_ops)
|
||||
return dev->dma_ops->mapping_error(dev, dma_addr);
|
||||
return dma_mapping_error(dev->dma_device, dma_addr);
|
||||
}
|
||||
|
||||
@@ -3547,8 +3503,6 @@ static inline u64 ib_dma_map_single(struct ib_device *dev,
|
||||
void *cpu_addr, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
if (dev->dma_ops)
|
||||
return dev->dma_ops->map_single(dev, cpu_addr, size, direction);
|
||||
return dma_map_single(dev->dma_device, cpu_addr, size, direction);
|
||||
}
|
||||
|
||||
@@ -3563,28 +3517,7 @@ static inline void ib_dma_unmap_single(struct ib_device *dev,
|
||||
u64 addr, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
if (dev->dma_ops)
|
||||
dev->dma_ops->unmap_single(dev, addr, size, direction);
|
||||
else
|
||||
dma_unmap_single(dev->dma_device, addr, size, direction);
|
||||
}
|
||||
|
||||
static inline u64 ib_dma_map_single_attrs(struct ib_device *dev,
|
||||
void *cpu_addr, size_t size,
|
||||
enum dma_data_direction direction,
|
||||
unsigned long dma_attrs)
|
||||
{
|
||||
return dma_map_single_attrs(dev->dma_device, cpu_addr, size,
|
||||
direction, dma_attrs);
|
||||
}
|
||||
|
||||
static inline void ib_dma_unmap_single_attrs(struct ib_device *dev,
|
||||
u64 addr, size_t size,
|
||||
enum dma_data_direction direction,
|
||||
unsigned long dma_attrs)
|
||||
{
|
||||
return dma_unmap_single_attrs(dev->dma_device, addr, size,
|
||||
direction, dma_attrs);
|
||||
dma_unmap_single(dev->dma_device, addr, size, direction);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3601,8 +3534,6 @@ static inline u64 ib_dma_map_page(struct ib_device *dev,
|
||||
size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
if (dev->dma_ops)
|
||||
return dev->dma_ops->map_page(dev, page, offset, size, direction);
|
||||
return dma_map_page(dev->dma_device, page, offset, size, direction);
|
||||
}
|
||||
|
||||
@@ -3617,10 +3548,7 @@ static inline void ib_dma_unmap_page(struct ib_device *dev,
|
||||
u64 addr, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
if (dev->dma_ops)
|
||||
dev->dma_ops->unmap_page(dev, addr, size, direction);
|
||||
else
|
||||
dma_unmap_page(dev->dma_device, addr, size, direction);
|
||||
dma_unmap_page(dev->dma_device, addr, size, direction);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3634,8 +3562,6 @@ static inline int ib_dma_map_sg(struct ib_device *dev,
|
||||
struct scatterlist *sg, int nents,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
if (dev->dma_ops)
|
||||
return dev->dma_ops->map_sg(dev, sg, nents, direction);
|
||||
return dma_map_sg(dev->dma_device, sg, nents, direction);
|
||||
}
|
||||
|
||||
@@ -3650,10 +3576,7 @@ static inline void ib_dma_unmap_sg(struct ib_device *dev,
|
||||
struct scatterlist *sg, int nents,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
if (dev->dma_ops)
|
||||
dev->dma_ops->unmap_sg(dev, sg, nents, direction);
|
||||
else
|
||||
dma_unmap_sg(dev->dma_device, sg, nents, direction);
|
||||
dma_unmap_sg(dev->dma_device, sg, nents, direction);
|
||||
}
|
||||
|
||||
static inline int ib_dma_map_sg_attrs(struct ib_device *dev,
|
||||
@@ -3661,12 +3584,8 @@ static inline int ib_dma_map_sg_attrs(struct ib_device *dev,
|
||||
enum dma_data_direction direction,
|
||||
unsigned long dma_attrs)
|
||||
{
|
||||
if (dev->dma_ops)
|
||||
return dev->dma_ops->map_sg_attrs(dev, sg, nents, direction,
|
||||
dma_attrs);
|
||||
else
|
||||
return dma_map_sg_attrs(dev->dma_device, sg, nents, direction,
|
||||
dma_attrs);
|
||||
return dma_map_sg_attrs(dev->dma_device, sg, nents, direction,
|
||||
dma_attrs);
|
||||
}
|
||||
|
||||
static inline void ib_dma_unmap_sg_attrs(struct ib_device *dev,
|
||||
@@ -3674,12 +3593,7 @@ static inline void ib_dma_unmap_sg_attrs(struct ib_device *dev,
|
||||
enum dma_data_direction direction,
|
||||
unsigned long dma_attrs)
|
||||
{
|
||||
if (dev->dma_ops)
|
||||
return dev->dma_ops->unmap_sg_attrs(dev, sg, nents, direction,
|
||||
dma_attrs);
|
||||
else
|
||||
dma_unmap_sg_attrs(dev->dma_device, sg, nents, direction,
|
||||
dma_attrs);
|
||||
dma_unmap_sg_attrs(dev->dma_device, sg, nents, direction, dma_attrs);
|
||||
}
|
||||
/**
|
||||
* ib_sg_dma_address - Return the DMA address from a scatter/gather entry
|
||||
@@ -3721,10 +3635,7 @@ static inline void ib_dma_sync_single_for_cpu(struct ib_device *dev,
|
||||
size_t size,
|
||||
enum dma_data_direction dir)
|
||||
{
|
||||
if (dev->dma_ops)
|
||||
dev->dma_ops->sync_single_for_cpu(dev, addr, size, dir);
|
||||
else
|
||||
dma_sync_single_for_cpu(dev->dma_device, addr, size, dir);
|
||||
dma_sync_single_for_cpu(dev->dma_device, addr, size, dir);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3739,10 +3650,7 @@ static inline void ib_dma_sync_single_for_device(struct ib_device *dev,
|
||||
size_t size,
|
||||
enum dma_data_direction dir)
|
||||
{
|
||||
if (dev->dma_ops)
|
||||
dev->dma_ops->sync_single_for_device(dev, addr, size, dir);
|
||||
else
|
||||
dma_sync_single_for_device(dev->dma_device, addr, size, dir);
|
||||
dma_sync_single_for_device(dev->dma_device, addr, size, dir);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3754,19 +3662,10 @@ static inline void ib_dma_sync_single_for_device(struct ib_device *dev,
|
||||
*/
|
||||
static inline void *ib_dma_alloc_coherent(struct ib_device *dev,
|
||||
size_t size,
|
||||
u64 *dma_handle,
|
||||
dma_addr_t *dma_handle,
|
||||
gfp_t flag)
|
||||
{
|
||||
if (dev->dma_ops)
|
||||
return dev->dma_ops->alloc_coherent(dev, size, dma_handle, flag);
|
||||
else {
|
||||
dma_addr_t handle;
|
||||
void *ret;
|
||||
|
||||
ret = dma_alloc_coherent(dev->dma_device, size, &handle, flag);
|
||||
*dma_handle = handle;
|
||||
return ret;
|
||||
}
|
||||
return dma_alloc_coherent(dev->dma_device, size, dma_handle, flag);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3778,12 +3677,9 @@ static inline void *ib_dma_alloc_coherent(struct ib_device *dev,
|
||||
*/
|
||||
static inline void ib_dma_free_coherent(struct ib_device *dev,
|
||||
size_t size, void *cpu_addr,
|
||||
u64 dma_handle)
|
||||
dma_addr_t dma_handle)
|
||||
{
|
||||
if (dev->dma_ops)
|
||||
dev->dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
|
||||
else
|
||||
dma_free_coherent(dev->dma_device, size, cpu_addr, dma_handle);
|
||||
dma_free_coherent(dev->dma_device, size, cpu_addr, dma_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user