mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-08-18 02:22:47 -07:00
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
Pull rdma updates from Jason Gunthorpe:
"This has been a smaller cycle with many of the commits being smallish
code fixes and improvements across the drivers.
- Driver updates for bnxt_re, cxgb4, hfi1, hns, mlx5, nes, qedr, and
rxe
- Memory window support in hns
- mlx5 user API 'flow mutate/steering' allows accessing the full
packet mangling and matching machinery from user space
- Support inter-working with verbs API calls in the 'devx' mlx5 user
API, and provide options to use devx with less privilege
- Modernize the use of syfs and the device interface to use attribute
groups and cdev properly for uverbs, and clean up some of the core
code's device list management
- More progress on net namespaces for RDMA devices
- Consolidate driver BAR mmapping support into core code helpers and
rework how RDMA holds poitners to mm_struct for get_user_pages
cases
- First pass to use 'dev_name' instead of ib_device->name
- Device renaming for RDMA devices"
* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: (242 commits)
IB/mlx5: Add support for extended atomic operations
RDMA/core: Fix comment for hw stats init for port == 0
RDMA/core: Refactor ib_register_device() function
RDMA/core: Fix unwinding flow in case of error to register device
ib_srp: Remove WARN_ON in srp_terminate_io()
IB/mlx5: Allow scatter to CQE without global signaled WRs
IB/mlx5: Verify that driver supports user flags
IB/mlx5: Support scatter to CQE for DC transport type
RDMA/drivers: Use core provided API for registering device attributes
RDMA/core: Allow existing drivers to set one sysfs group per device
IB/rxe: Remove unnecessary enum values
RDMA/umad: Use kernel API to allocate umad indexes
RDMA/uverbs: Use kernel API to allocate uverbs indexes
RDMA/core: Increase total number of RDMA ports across all devices
IB/mlx4: Add port and TID to MAD debug print
IB/mlx4: Enable debug print of SMPs
RDMA/core: Rename ports_parent to ports_kobj
RDMA/core: Do not expose unsupported counters
IB/mlx4: Refer to the device kobject instead of ports_parent
RDMA/nldev: Allow IB device rename through RDMA netlink
...
This commit is contained in:
commit
da19a102ce
204 files changed
+7633
-5205
No files matched your search
@@ -91,6 +91,24 @@ Description:
|
||||
stacked (e.g: VLAN interfaces) but still have the same MAC
|
||||
address as their parent device.
|
||||
|
||||
What: /sys/class/net/<iface>/dev_port
|
||||
Date: February 2014
|
||||
KernelVersion: 3.15
|
||||
Contact: netdev@vger.kernel.org
|
||||
Description:
|
||||
Indicates the port number of this network device, formatted
|
||||
as a decimal value. Some NICs have multiple independent ports
|
||||
on the same PCI bus, device and function. This attribute allows
|
||||
userspace to distinguish the respective interfaces.
|
||||
|
||||
Note: some device drivers started to use 'dev_id' for this
|
||||
purpose since long before 3.15 and have not adopted the new
|
||||
attribute ever since. To query the port number, some tools look
|
||||
exclusively at 'dev_port', while others only consult 'dev_id'.
|
||||
If a network device has multiple client adapter ports as
|
||||
described in the previous paragraph and does not set this
|
||||
attribute to its port number, it's a kernel bug.
|
||||
|
||||
What: /sys/class/net/<iface>/dormant
|
||||
Date: March 2006
|
||||
KernelVersion: 2.6.17
|
||||
|
||||
@@ -26,6 +26,7 @@ config INFINIBAND_USER_MAD
|
||||
config INFINIBAND_USER_ACCESS
|
||||
tristate "InfiniBand userspace access (verbs and CM)"
|
||||
select ANON_INODES
|
||||
depends on MMU
|
||||
---help---
|
||||
Userspace InfiniBand access support. This enables the
|
||||
kernel side of userspace verbs and the userspace
|
||||
|
||||
+253
-155
File diff suppressed because it is too large.
Load diff
@@ -212,9 +212,8 @@ static void free_gid_entry_locked(struct ib_gid_table_entry *entry)
|
||||
u8 port_num = entry->attr.port_num;
|
||||
struct ib_gid_table *table = rdma_gid_table(device, port_num);
|
||||
|
||||
pr_debug("%s device=%s port=%d index=%d gid %pI6\n", __func__,
|
||||
device->name, port_num, entry->attr.index,
|
||||
entry->attr.gid.raw);
|
||||
dev_dbg(&device->dev, "%s port=%d index=%d gid %pI6\n", __func__,
|
||||
port_num, entry->attr.index, entry->attr.gid.raw);
|
||||
|
||||
if (rdma_cap_roce_gid_table(device, port_num) &&
|
||||
entry->state != GID_TABLE_ENTRY_INVALID)
|
||||
@@ -289,9 +288,9 @@ static void store_gid_entry(struct ib_gid_table *table,
|
||||
{
|
||||
entry->state = GID_TABLE_ENTRY_VALID;
|
||||
|
||||
pr_debug("%s device=%s port=%d index=%d gid %pI6\n", __func__,
|
||||
entry->attr.device->name, entry->attr.port_num,
|
||||
entry->attr.index, entry->attr.gid.raw);
|
||||
dev_dbg(&entry->attr.device->dev, "%s port=%d index=%d gid %pI6\n",
|
||||
__func__, entry->attr.port_num, entry->attr.index,
|
||||
entry->attr.gid.raw);
|
||||
|
||||
lockdep_assert_held(&table->lock);
|
||||
write_lock_irq(&table->rwlock);
|
||||
@@ -320,17 +319,16 @@ static int add_roce_gid(struct ib_gid_table_entry *entry)
|
||||
int ret;
|
||||
|
||||
if (!attr->ndev) {
|
||||
pr_err("%s NULL netdev device=%s port=%d index=%d\n",
|
||||
__func__, attr->device->name, attr->port_num,
|
||||
attr->index);
|
||||
dev_err(&attr->device->dev, "%s NULL netdev port=%d index=%d\n",
|
||||
__func__, attr->port_num, attr->index);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (rdma_cap_roce_gid_table(attr->device, attr->port_num)) {
|
||||
ret = attr->device->add_gid(attr, &entry->context);
|
||||
if (ret) {
|
||||
pr_err("%s GID add failed device=%s port=%d index=%d\n",
|
||||
__func__, attr->device->name, attr->port_num,
|
||||
attr->index);
|
||||
dev_err(&attr->device->dev,
|
||||
"%s GID add failed port=%d index=%d\n",
|
||||
__func__, attr->port_num, attr->index);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -353,9 +351,8 @@ static void del_gid(struct ib_device *ib_dev, u8 port,
|
||||
|
||||
lockdep_assert_held(&table->lock);
|
||||
|
||||
pr_debug("%s device=%s port=%d index=%d gid %pI6\n", __func__,
|
||||
ib_dev->name, port, ix,
|
||||
table->data_vec[ix]->attr.gid.raw);
|
||||
dev_dbg(&ib_dev->dev, "%s port=%d index=%d gid %pI6\n", __func__, port,
|
||||
ix, table->data_vec[ix]->attr.gid.raw);
|
||||
|
||||
write_lock_irq(&table->rwlock);
|
||||
entry = table->data_vec[ix];
|
||||
@@ -782,9 +779,9 @@ static void release_gid_table(struct ib_device *device, u8 port,
|
||||
if (is_gid_entry_free(table->data_vec[i]))
|
||||
continue;
|
||||
if (kref_read(&table->data_vec[i]->kref) > 1) {
|
||||
pr_err("GID entry ref leak for %s (index %d) ref=%d\n",
|
||||
device->name, i,
|
||||
kref_read(&table->data_vec[i]->kref));
|
||||
dev_err(&device->dev,
|
||||
"GID entry ref leak for index %d ref=%d\n", i,
|
||||
kref_read(&table->data_vec[i]->kref));
|
||||
leak = true;
|
||||
}
|
||||
}
|
||||
@@ -1252,6 +1249,39 @@ void rdma_hold_gid_attr(const struct ib_gid_attr *attr)
|
||||
}
|
||||
EXPORT_SYMBOL(rdma_hold_gid_attr);
|
||||
|
||||
/**
|
||||
* rdma_read_gid_attr_ndev_rcu - Read GID attribute netdevice
|
||||
* which must be in UP state.
|
||||
*
|
||||
* @attr:Pointer to the GID attribute
|
||||
*
|
||||
* Returns pointer to netdevice if the netdevice was attached to GID and
|
||||
* netdevice is in UP state. Caller must hold RCU lock as this API
|
||||
* reads the netdev flags which can change while netdevice migrates to
|
||||
* different net namespace. Returns ERR_PTR with error code otherwise.
|
||||
*
|
||||
*/
|
||||
struct net_device *rdma_read_gid_attr_ndev_rcu(const struct ib_gid_attr *attr)
|
||||
{
|
||||
struct ib_gid_table_entry *entry =
|
||||
container_of(attr, struct ib_gid_table_entry, attr);
|
||||
struct ib_device *device = entry->attr.device;
|
||||
struct net_device *ndev = ERR_PTR(-ENODEV);
|
||||
u8 port_num = entry->attr.port_num;
|
||||
struct ib_gid_table *table;
|
||||
unsigned long flags;
|
||||
bool valid;
|
||||
|
||||
table = rdma_gid_table(device, port_num);
|
||||
|
||||
read_lock_irqsave(&table->rwlock, flags);
|
||||
valid = is_gid_entry_valid(table->data_vec[attr->index]);
|
||||
if (valid && attr->ndev && (READ_ONCE(attr->ndev->flags) & IFF_UP))
|
||||
ndev = attr->ndev;
|
||||
read_unlock_irqrestore(&table->rwlock, flags);
|
||||
return ndev;
|
||||
}
|
||||
|
||||
static int config_non_roce_gid_cache(struct ib_device *device,
|
||||
u8 port, int gid_tbl_len)
|
||||
{
|
||||
@@ -1270,8 +1300,9 @@ static int config_non_roce_gid_cache(struct ib_device *device,
|
||||
continue;
|
||||
ret = device->query_gid(device, port, i, &gid_attr.gid);
|
||||
if (ret) {
|
||||
pr_warn("query_gid failed (%d) for %s (index %d)\n",
|
||||
ret, device->name, i);
|
||||
dev_warn(&device->dev,
|
||||
"query_gid failed (%d) for index %d\n", ret,
|
||||
i);
|
||||
goto err;
|
||||
}
|
||||
gid_attr.index = i;
|
||||
@@ -1300,8 +1331,7 @@ static void ib_cache_update(struct ib_device *device,
|
||||
|
||||
ret = ib_query_port(device, port, tprops);
|
||||
if (ret) {
|
||||
pr_warn("ib_query_port failed (%d) for %s\n",
|
||||
ret, device->name);
|
||||
dev_warn(&device->dev, "ib_query_port failed (%d)\n", ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -1323,8 +1353,9 @@ static void ib_cache_update(struct ib_device *device,
|
||||
for (i = 0; i < pkey_cache->table_len; ++i) {
|
||||
ret = ib_query_pkey(device, port, i, pkey_cache->table + i);
|
||||
if (ret) {
|
||||
pr_warn("ib_query_pkey failed (%d) for %s (index %d)\n",
|
||||
ret, device->name, i);
|
||||
dev_warn(&device->dev,
|
||||
"ib_query_pkey failed (%d) for index %d\n",
|
||||
ret, i);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3292,8 +3292,11 @@ static int cm_lap_handler(struct cm_work *work)
|
||||
if (ret)
|
||||
goto unlock;
|
||||
|
||||
cm_init_av_by_path(param->alternate_path, NULL, &cm_id_priv->alt_av,
|
||||
cm_id_priv);
|
||||
ret = cm_init_av_by_path(param->alternate_path, NULL,
|
||||
&cm_id_priv->alt_av, cm_id_priv);
|
||||
if (ret)
|
||||
goto unlock;
|
||||
|
||||
cm_id_priv->id.lap_state = IB_CM_LAP_RCVD;
|
||||
cm_id_priv->tid = lap_msg->hdr.tid;
|
||||
ret = atomic_inc_and_test(&cm_id_priv->work_count);
|
||||
@@ -4367,7 +4370,7 @@ static void cm_add_one(struct ib_device *ib_device)
|
||||
cm_dev->going_down = 0;
|
||||
cm_dev->device = device_create(&cm_class, &ib_device->dev,
|
||||
MKDEV(0, 0), NULL,
|
||||
"%s", ib_device->name);
|
||||
"%s", dev_name(&ib_device->dev));
|
||||
if (IS_ERR(cm_dev->device)) {
|
||||
kfree(cm_dev);
|
||||
return;
|
||||
|
||||
+180
-77
@@ -639,13 +639,21 @@ static void cma_bind_sgid_attr(struct rdma_id_private *id_priv,
|
||||
id_priv->id.route.addr.dev_addr.sgid_attr = sgid_attr;
|
||||
}
|
||||
|
||||
static int cma_acquire_dev(struct rdma_id_private *id_priv,
|
||||
const struct rdma_id_private *listen_id_priv)
|
||||
/**
|
||||
* cma_acquire_dev_by_src_ip - Acquire cma device, port, gid attribute
|
||||
* based on source ip address.
|
||||
* @id_priv: cm_id which should be bound to cma device
|
||||
*
|
||||
* cma_acquire_dev_by_src_ip() binds cm id to cma device, port and GID attribute
|
||||
* based on source IP address. It returns 0 on success or error code otherwise.
|
||||
* It is applicable to active and passive side cm_id.
|
||||
*/
|
||||
static int cma_acquire_dev_by_src_ip(struct rdma_id_private *id_priv)
|
||||
{
|
||||
struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr;
|
||||
const struct ib_gid_attr *sgid_attr;
|
||||
struct cma_device *cma_dev;
|
||||
union ib_gid gid, iboe_gid, *gidp;
|
||||
struct cma_device *cma_dev;
|
||||
enum ib_gid_type gid_type;
|
||||
int ret = -ENODEV;
|
||||
u8 port;
|
||||
@@ -654,41 +662,125 @@ static int cma_acquire_dev(struct rdma_id_private *id_priv,
|
||||
id_priv->id.ps == RDMA_PS_IPOIB)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&lock);
|
||||
rdma_ip2gid((struct sockaddr *)&id_priv->id.route.addr.src_addr,
|
||||
&iboe_gid);
|
||||
|
||||
memcpy(&gid, dev_addr->src_dev_addr +
|
||||
rdma_addr_gid_offset(dev_addr), sizeof gid);
|
||||
|
||||
if (listen_id_priv) {
|
||||
cma_dev = listen_id_priv->cma_dev;
|
||||
port = listen_id_priv->id.port_num;
|
||||
gidp = rdma_protocol_roce(cma_dev->device, port) ?
|
||||
&iboe_gid : &gid;
|
||||
gid_type = listen_id_priv->gid_type;
|
||||
sgid_attr = cma_validate_port(cma_dev->device, port,
|
||||
gid_type, gidp, id_priv);
|
||||
if (!IS_ERR(sgid_attr)) {
|
||||
id_priv->id.port_num = port;
|
||||
cma_bind_sgid_attr(id_priv, sgid_attr);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
rdma_addr_gid_offset(dev_addr), sizeof(gid));
|
||||
|
||||
mutex_lock(&lock);
|
||||
list_for_each_entry(cma_dev, &dev_list, list) {
|
||||
for (port = 1; port <= cma_dev->device->phys_port_cnt; ++port) {
|
||||
if (listen_id_priv &&
|
||||
listen_id_priv->cma_dev == cma_dev &&
|
||||
listen_id_priv->id.port_num == port)
|
||||
continue;
|
||||
|
||||
for (port = rdma_start_port(cma_dev->device);
|
||||
port <= rdma_end_port(cma_dev->device); port++) {
|
||||
gidp = rdma_protocol_roce(cma_dev->device, port) ?
|
||||
&iboe_gid : &gid;
|
||||
gid_type = cma_dev->default_gid_type[port - 1];
|
||||
sgid_attr = cma_validate_port(cma_dev->device, port,
|
||||
gid_type, gidp, id_priv);
|
||||
if (!IS_ERR(sgid_attr)) {
|
||||
id_priv->id.port_num = port;
|
||||
cma_bind_sgid_attr(id_priv, sgid_attr);
|
||||
cma_attach_to_dev(id_priv, cma_dev);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* cma_ib_acquire_dev - Acquire cma device, port and SGID attribute
|
||||
* @id_priv: cm id to bind to cma device
|
||||
* @listen_id_priv: listener cm id to match against
|
||||
* @req: Pointer to req structure containaining incoming
|
||||
* request information
|
||||
* cma_ib_acquire_dev() acquires cma device, port and SGID attribute when
|
||||
* rdma device matches for listen_id and incoming request. It also verifies
|
||||
* that a GID table entry is present for the source address.
|
||||
* Returns 0 on success, or returns error code otherwise.
|
||||
*/
|
||||
static int cma_ib_acquire_dev(struct rdma_id_private *id_priv,
|
||||
const struct rdma_id_private *listen_id_priv,
|
||||
struct cma_req_info *req)
|
||||
{
|
||||
struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr;
|
||||
const struct ib_gid_attr *sgid_attr;
|
||||
enum ib_gid_type gid_type;
|
||||
union ib_gid gid;
|
||||
|
||||
if (dev_addr->dev_type != ARPHRD_INFINIBAND &&
|
||||
id_priv->id.ps == RDMA_PS_IPOIB)
|
||||
return -EINVAL;
|
||||
|
||||
if (rdma_protocol_roce(req->device, req->port))
|
||||
rdma_ip2gid((struct sockaddr *)&id_priv->id.route.addr.src_addr,
|
||||
&gid);
|
||||
else
|
||||
memcpy(&gid, dev_addr->src_dev_addr +
|
||||
rdma_addr_gid_offset(dev_addr), sizeof(gid));
|
||||
|
||||
gid_type = listen_id_priv->cma_dev->default_gid_type[req->port - 1];
|
||||
sgid_attr = cma_validate_port(req->device, req->port,
|
||||
gid_type, &gid, id_priv);
|
||||
if (IS_ERR(sgid_attr))
|
||||
return PTR_ERR(sgid_attr);
|
||||
|
||||
id_priv->id.port_num = req->port;
|
||||
cma_bind_sgid_attr(id_priv, sgid_attr);
|
||||
/* Need to acquire lock to protect against reader
|
||||
* of cma_dev->id_list such as cma_netdev_callback() and
|
||||
* cma_process_remove().
|
||||
*/
|
||||
mutex_lock(&lock);
|
||||
cma_attach_to_dev(id_priv, listen_id_priv->cma_dev);
|
||||
mutex_unlock(&lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cma_iw_acquire_dev(struct rdma_id_private *id_priv,
|
||||
const struct rdma_id_private *listen_id_priv)
|
||||
{
|
||||
struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr;
|
||||
const struct ib_gid_attr *sgid_attr;
|
||||
struct cma_device *cma_dev;
|
||||
enum ib_gid_type gid_type;
|
||||
int ret = -ENODEV;
|
||||
union ib_gid gid;
|
||||
u8 port;
|
||||
|
||||
if (dev_addr->dev_type != ARPHRD_INFINIBAND &&
|
||||
id_priv->id.ps == RDMA_PS_IPOIB)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(&gid, dev_addr->src_dev_addr +
|
||||
rdma_addr_gid_offset(dev_addr), sizeof(gid));
|
||||
|
||||
mutex_lock(&lock);
|
||||
|
||||
cma_dev = listen_id_priv->cma_dev;
|
||||
port = listen_id_priv->id.port_num;
|
||||
gid_type = listen_id_priv->gid_type;
|
||||
sgid_attr = cma_validate_port(cma_dev->device, port,
|
||||
gid_type, &gid, id_priv);
|
||||
if (!IS_ERR(sgid_attr)) {
|
||||
id_priv->id.port_num = port;
|
||||
cma_bind_sgid_attr(id_priv, sgid_attr);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
list_for_each_entry(cma_dev, &dev_list, list) {
|
||||
for (port = 1; port <= cma_dev->device->phys_port_cnt; ++port) {
|
||||
if (listen_id_priv->cma_dev == cma_dev &&
|
||||
listen_id_priv->id.port_num == port)
|
||||
continue;
|
||||
|
||||
gid_type = cma_dev->default_gid_type[port - 1];
|
||||
sgid_attr = cma_validate_port(cma_dev->device, port,
|
||||
gid_type, &gid, id_priv);
|
||||
if (!IS_ERR(sgid_attr)) {
|
||||
id_priv->id.port_num = port;
|
||||
cma_bind_sgid_attr(id_priv, sgid_attr);
|
||||
@@ -785,10 +877,7 @@ struct rdma_cm_id *__rdma_create_id(struct net *net,
|
||||
if (!id_priv)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
if (caller)
|
||||
id_priv->res.kern_name = caller;
|
||||
else
|
||||
rdma_restrack_set_task(&id_priv->res, current);
|
||||
rdma_restrack_set_task(&id_priv->res, caller);
|
||||
id_priv->res.type = RDMA_RESTRACK_CM_ID;
|
||||
id_priv->state = RDMA_CM_IDLE;
|
||||
id_priv->id.context = context;
|
||||
@@ -1462,17 +1551,34 @@ static bool cma_protocol_roce(const struct rdma_cm_id *id)
|
||||
return rdma_protocol_roce(device, port_num);
|
||||
}
|
||||
|
||||
static bool cma_is_req_ipv6_ll(const struct cma_req_info *req)
|
||||
{
|
||||
const struct sockaddr *daddr =
|
||||
(const struct sockaddr *)&req->listen_addr_storage;
|
||||
const struct sockaddr_in6 *daddr6 = (const struct sockaddr_in6 *)daddr;
|
||||
|
||||
/* Returns true if the req is for IPv6 link local */
|
||||
return (daddr->sa_family == AF_INET6 &&
|
||||
(ipv6_addr_type(&daddr6->sin6_addr) & IPV6_ADDR_LINKLOCAL));
|
||||
}
|
||||
|
||||
static bool cma_match_net_dev(const struct rdma_cm_id *id,
|
||||
const struct net_device *net_dev,
|
||||
u8 port_num)
|
||||
const struct cma_req_info *req)
|
||||
{
|
||||
const struct rdma_addr *addr = &id->route.addr;
|
||||
|
||||
if (!net_dev)
|
||||
/* This request is an AF_IB request */
|
||||
return (!id->port_num || id->port_num == port_num) &&
|
||||
return (!id->port_num || id->port_num == req->port) &&
|
||||
(addr->src_addr.ss_family == AF_IB);
|
||||
|
||||
/*
|
||||
* If the request is not for IPv6 link local, allow matching
|
||||
* request to any netdevice of the one or multiport rdma device.
|
||||
*/
|
||||
if (!cma_is_req_ipv6_ll(req))
|
||||
return true;
|
||||
/*
|
||||
* Net namespaces must match, and if the listner is listening
|
||||
* on a specific netdevice than netdevice must match as well.
|
||||
@@ -1500,13 +1606,14 @@ static struct rdma_id_private *cma_find_listener(
|
||||
hlist_for_each_entry(id_priv, &bind_list->owners, node) {
|
||||
if (cma_match_private_data(id_priv, ib_event->private_data)) {
|
||||
if (id_priv->id.device == cm_id->device &&
|
||||
cma_match_net_dev(&id_priv->id, net_dev, req->port))
|
||||
cma_match_net_dev(&id_priv->id, net_dev, req))
|
||||
return id_priv;
|
||||
list_for_each_entry(id_priv_dev,
|
||||
&id_priv->listen_list,
|
||||
listen_list) {
|
||||
if (id_priv_dev->id.device == cm_id->device &&
|
||||
cma_match_net_dev(&id_priv_dev->id, net_dev, req->port))
|
||||
cma_match_net_dev(&id_priv_dev->id,
|
||||
net_dev, req))
|
||||
return id_priv_dev;
|
||||
}
|
||||
}
|
||||
@@ -1518,18 +1625,18 @@ static struct rdma_id_private *cma_find_listener(
|
||||
static struct rdma_id_private *
|
||||
cma_ib_id_from_event(struct ib_cm_id *cm_id,
|
||||
const struct ib_cm_event *ib_event,
|
||||
struct cma_req_info *req,
|
||||
struct net_device **net_dev)
|
||||
{
|
||||
struct cma_req_info req;
|
||||
struct rdma_bind_list *bind_list;
|
||||
struct rdma_id_private *id_priv;
|
||||
int err;
|
||||
|
||||
err = cma_save_req_info(ib_event, &req);
|
||||
err = cma_save_req_info(ib_event, req);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
|
||||
*net_dev = cma_get_net_dev(ib_event, &req);
|
||||
*net_dev = cma_get_net_dev(ib_event, req);
|
||||
if (IS_ERR(*net_dev)) {
|
||||
if (PTR_ERR(*net_dev) == -EAFNOSUPPORT) {
|
||||
/* Assuming the protocol is AF_IB */
|
||||
@@ -1567,17 +1674,17 @@ cma_ib_id_from_event(struct ib_cm_id *cm_id,
|
||||
}
|
||||
|
||||
if (!validate_net_dev(*net_dev,
|
||||
(struct sockaddr *)&req.listen_addr_storage,
|
||||
(struct sockaddr *)&req.src_addr_storage)) {
|
||||
(struct sockaddr *)&req->listen_addr_storage,
|
||||
(struct sockaddr *)&req->src_addr_storage)) {
|
||||
id_priv = ERR_PTR(-EHOSTUNREACH);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
bind_list = cma_ps_find(*net_dev ? dev_net(*net_dev) : &init_net,
|
||||
rdma_ps_from_service_id(req.service_id),
|
||||
cma_port_from_service_id(req.service_id));
|
||||
id_priv = cma_find_listener(bind_list, cm_id, ib_event, &req, *net_dev);
|
||||
rdma_ps_from_service_id(req->service_id),
|
||||
cma_port_from_service_id(req->service_id));
|
||||
id_priv = cma_find_listener(bind_list, cm_id, ib_event, req, *net_dev);
|
||||
err:
|
||||
rcu_read_unlock();
|
||||
if (IS_ERR(id_priv) && *net_dev) {
|
||||
@@ -1710,8 +1817,8 @@ void rdma_destroy_id(struct rdma_cm_id *id)
|
||||
mutex_lock(&id_priv->handler_mutex);
|
||||
mutex_unlock(&id_priv->handler_mutex);
|
||||
|
||||
rdma_restrack_del(&id_priv->res);
|
||||
if (id_priv->cma_dev) {
|
||||
rdma_restrack_del(&id_priv->res);
|
||||
if (rdma_cap_ib_cm(id_priv->id.device, 1)) {
|
||||
if (id_priv->cm_id.ib)
|
||||
ib_destroy_cm_id(id_priv->cm_id.ib);
|
||||
@@ -1902,7 +2009,7 @@ cma_ib_new_conn_id(const struct rdma_cm_id *listen_id,
|
||||
rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path;
|
||||
|
||||
if (net_dev) {
|
||||
rdma_copy_addr(&rt->addr.dev_addr, net_dev, NULL);
|
||||
rdma_copy_src_l2_addr(&rt->addr.dev_addr, net_dev);
|
||||
} else {
|
||||
if (!cma_protocol_roce(listen_id) &&
|
||||
cma_any_addr(cma_src_addr(id_priv))) {
|
||||
@@ -1952,7 +2059,7 @@ cma_ib_new_udp_id(const struct rdma_cm_id *listen_id,
|
||||
goto err;
|
||||
|
||||
if (net_dev) {
|
||||
rdma_copy_addr(&id->route.addr.dev_addr, net_dev, NULL);
|
||||
rdma_copy_src_l2_addr(&id->route.addr.dev_addr, net_dev);
|
||||
} else {
|
||||
if (!cma_any_addr(cma_src_addr(id_priv))) {
|
||||
ret = cma_translate_addr(cma_src_addr(id_priv),
|
||||
@@ -1999,11 +2106,12 @@ static int cma_ib_req_handler(struct ib_cm_id *cm_id,
|
||||
{
|
||||
struct rdma_id_private *listen_id, *conn_id = NULL;
|
||||
struct rdma_cm_event event = {};
|
||||
struct cma_req_info req = {};
|
||||
struct net_device *net_dev;
|
||||
u8 offset;
|
||||
int ret;
|
||||
|
||||
listen_id = cma_ib_id_from_event(cm_id, ib_event, &net_dev);
|
||||
listen_id = cma_ib_id_from_event(cm_id, ib_event, &req, &net_dev);
|
||||
if (IS_ERR(listen_id))
|
||||
return PTR_ERR(listen_id);
|
||||
|
||||
@@ -2036,7 +2144,7 @@ static int cma_ib_req_handler(struct ib_cm_id *cm_id,
|
||||
}
|
||||
|
||||
mutex_lock_nested(&conn_id->handler_mutex, SINGLE_DEPTH_NESTING);
|
||||
ret = cma_acquire_dev(conn_id, listen_id);
|
||||
ret = cma_ib_acquire_dev(conn_id, listen_id, &req);
|
||||
if (ret)
|
||||
goto err2;
|
||||
|
||||
@@ -2232,7 +2340,7 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = cma_acquire_dev(conn_id, listen_id);
|
||||
ret = cma_iw_acquire_dev(conn_id, listen_id);
|
||||
if (ret) {
|
||||
mutex_unlock(&conn_id->handler_mutex);
|
||||
rdma_destroy_id(new_cm_id);
|
||||
@@ -2354,8 +2462,8 @@ static void cma_listen_on_dev(struct rdma_id_private *id_priv,
|
||||
|
||||
ret = rdma_listen(id, id_priv->backlog);
|
||||
if (ret)
|
||||
pr_warn("RDMA CMA: cma_listen_on_dev, error %d, listening on device %s\n",
|
||||
ret, cma_dev->device->name);
|
||||
dev_warn(&cma_dev->device->dev,
|
||||
"RDMA CMA: cma_listen_on_dev, error %d\n", ret);
|
||||
}
|
||||
|
||||
static void cma_listen_on_all(struct rdma_id_private *id_priv)
|
||||
@@ -2402,8 +2510,8 @@ static void cma_query_handler(int status, struct sa_path_rec *path_rec,
|
||||
queue_work(cma_wq, &work->work);
|
||||
}
|
||||
|
||||
static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms,
|
||||
struct cma_work *work)
|
||||
static int cma_query_ib_route(struct rdma_id_private *id_priv,
|
||||
unsigned long timeout_ms, struct cma_work *work)
|
||||
{
|
||||
struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr;
|
||||
struct sa_path_rec path_rec;
|
||||
@@ -2521,7 +2629,8 @@ static void cma_init_resolve_addr_work(struct cma_work *work,
|
||||
work->event.event = RDMA_CM_EVENT_ADDR_RESOLVED;
|
||||
}
|
||||
|
||||
static int cma_resolve_ib_route(struct rdma_id_private *id_priv, int timeout_ms)
|
||||
static int cma_resolve_ib_route(struct rdma_id_private *id_priv,
|
||||
unsigned long timeout_ms)
|
||||
{
|
||||
struct rdma_route *route = &id_priv->id.route;
|
||||
struct cma_work *work;
|
||||
@@ -2643,7 +2752,7 @@ err:
|
||||
}
|
||||
EXPORT_SYMBOL(rdma_set_ib_path);
|
||||
|
||||
static int cma_resolve_iw_route(struct rdma_id_private *id_priv, int timeout_ms)
|
||||
static int cma_resolve_iw_route(struct rdma_id_private *id_priv)
|
||||
{
|
||||
struct cma_work *work;
|
||||
|
||||
@@ -2744,7 +2853,7 @@ err1:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rdma_resolve_route(struct rdma_cm_id *id, int timeout_ms)
|
||||
int rdma_resolve_route(struct rdma_cm_id *id, unsigned long timeout_ms)
|
||||
{
|
||||
struct rdma_id_private *id_priv;
|
||||
int ret;
|
||||
@@ -2759,7 +2868,7 @@ int rdma_resolve_route(struct rdma_cm_id *id, int timeout_ms)
|
||||
else if (rdma_protocol_roce(id->device, id->port_num))
|
||||
ret = cma_resolve_iboe_route(id_priv);
|
||||
else if (rdma_protocol_iwarp(id->device, id->port_num))
|
||||
ret = cma_resolve_iw_route(id_priv, timeout_ms);
|
||||
ret = cma_resolve_iw_route(id_priv);
|
||||
else
|
||||
ret = -ENOSYS;
|
||||
|
||||
@@ -2862,7 +2971,7 @@ static void addr_handler(int status, struct sockaddr *src_addr,
|
||||
|
||||
memcpy(cma_src_addr(id_priv), src_addr, rdma_addr_size(src_addr));
|
||||
if (!status && !id_priv->cma_dev) {
|
||||
status = cma_acquire_dev(id_priv, NULL);
|
||||
status = cma_acquire_dev_by_src_ip(id_priv);
|
||||
if (status)
|
||||
pr_debug_ratelimited("RDMA CM: ADDR_ERROR: failed to acquire device. status %d\n",
|
||||
status);
|
||||
@@ -2882,13 +2991,11 @@ static void addr_handler(int status, struct sockaddr *src_addr,
|
||||
if (id_priv->id.event_handler(&id_priv->id, &event)) {
|
||||
cma_exch(id_priv, RDMA_CM_DESTROYING);
|
||||
mutex_unlock(&id_priv->handler_mutex);
|
||||
cma_deref_id(id_priv);
|
||||
rdma_destroy_id(&id_priv->id);
|
||||
return;
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&id_priv->handler_mutex);
|
||||
cma_deref_id(id_priv);
|
||||
}
|
||||
|
||||
static int cma_resolve_loopback(struct rdma_id_private *id_priv)
|
||||
@@ -2966,7 +3073,7 @@ static int cma_bind_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
|
||||
}
|
||||
|
||||
int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
|
||||
const struct sockaddr *dst_addr, int timeout_ms)
|
||||
const struct sockaddr *dst_addr, unsigned long timeout_ms)
|
||||
{
|
||||
struct rdma_id_private *id_priv;
|
||||
int ret;
|
||||
@@ -2985,16 +3092,16 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr));
|
||||
atomic_inc(&id_priv->refcount);
|
||||
if (cma_any_addr(dst_addr)) {
|
||||
ret = cma_resolve_loopback(id_priv);
|
||||
} else {
|
||||
if (dst_addr->sa_family == AF_IB) {
|
||||
ret = cma_resolve_ib_addr(id_priv);
|
||||
} else {
|
||||
ret = rdma_resolve_ip(cma_src_addr(id_priv),
|
||||
dst_addr, &id->route.addr.dev_addr,
|
||||
timeout_ms, addr_handler, id_priv);
|
||||
ret = rdma_resolve_ip(cma_src_addr(id_priv), dst_addr,
|
||||
&id->route.addr.dev_addr,
|
||||
timeout_ms, addr_handler,
|
||||
false, id_priv);
|
||||
}
|
||||
}
|
||||
if (ret)
|
||||
@@ -3003,7 +3110,6 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
|
||||
return 0;
|
||||
err:
|
||||
cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY, RDMA_CM_ADDR_BOUND);
|
||||
cma_deref_id(id_priv);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(rdma_resolve_addr);
|
||||
@@ -3414,7 +3520,7 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
|
||||
if (ret)
|
||||
goto err1;
|
||||
|
||||
ret = cma_acquire_dev(id_priv, NULL);
|
||||
ret = cma_acquire_dev_by_src_ip(id_priv);
|
||||
if (ret)
|
||||
goto err1;
|
||||
}
|
||||
@@ -3439,10 +3545,9 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
|
||||
|
||||
return 0;
|
||||
err2:
|
||||
if (id_priv->cma_dev) {
|
||||
rdma_restrack_del(&id_priv->res);
|
||||
rdma_restrack_del(&id_priv->res);
|
||||
if (id_priv->cma_dev)
|
||||
cma_release_dev(id_priv);
|
||||
}
|
||||
err1:
|
||||
cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_IDLE);
|
||||
return ret;
|
||||
@@ -3839,10 +3944,7 @@ int __rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param,
|
||||
|
||||
id_priv = container_of(id, struct rdma_id_private, id);
|
||||
|
||||
if (caller)
|
||||
id_priv->res.kern_name = caller;
|
||||
else
|
||||
rdma_restrack_set_task(&id_priv->res, current);
|
||||
rdma_restrack_set_task(&id_priv->res, caller);
|
||||
|
||||
if (!cma_comp(id_priv, RDMA_CM_CONNECT))
|
||||
return -EINVAL;
|
||||
@@ -4087,9 +4189,10 @@ static int cma_join_ib_multicast(struct rdma_id_private *id_priv,
|
||||
(!ib_sa_sendonly_fullmem_support(&sa_client,
|
||||
id_priv->id.device,
|
||||
id_priv->id.port_num))) {
|
||||
pr_warn("RDMA CM: %s port %u Unable to multicast join\n"
|
||||
"RDMA CM: SM doesn't support Send Only Full Member option\n",
|
||||
id_priv->id.device->name, id_priv->id.port_num);
|
||||
dev_warn(
|
||||
&id_priv->id.device->dev,
|
||||
"RDMA CM: port %u Unable to multicast join: SM doesn't support Send Only Full Member option\n",
|
||||
id_priv->id.port_num);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ static struct cma_dev_port_group *to_dev_port_group(struct config_item *item)
|
||||
|
||||
static bool filter_by_name(struct ib_device *ib_dev, void *cookie)
|
||||
{
|
||||
return !strcmp(ib_dev->name, cookie);
|
||||
return !strcmp(dev_name(&ib_dev->dev), cookie);
|
||||
}
|
||||
|
||||
static int cma_configfs_params_get(struct config_item *item,
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
#include "mad_priv.h"
|
||||
|
||||
/* Total number of ports combined across all struct ib_devices's */
|
||||
#define RDMA_MAX_PORTS 1024
|
||||
#define RDMA_MAX_PORTS 8192
|
||||
|
||||
struct pkey_index_qp_list {
|
||||
struct list_head pkey_index_list;
|
||||
@@ -87,6 +87,7 @@ int ib_device_register_sysfs(struct ib_device *device,
|
||||
int (*port_callback)(struct ib_device *,
|
||||
u8, struct kobject *));
|
||||
void ib_device_unregister_sysfs(struct ib_device *device);
|
||||
int ib_device_rename(struct ib_device *ibdev, const char *name);
|
||||
|
||||
typedef void (*roce_netdev_callback)(struct ib_device *device, u8 port,
|
||||
struct net_device *idev, void *cookie);
|
||||
@@ -338,7 +339,14 @@ int rdma_resolve_ip_route(struct sockaddr *src_addr,
|
||||
|
||||
int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid,
|
||||
const union ib_gid *dgid,
|
||||
u8 *dmac, const struct net_device *ndev,
|
||||
u8 *dmac, const struct ib_gid_attr *sgid_attr,
|
||||
int *hoplimit);
|
||||
void rdma_copy_src_l2_addr(struct rdma_dev_addr *dev_addr,
|
||||
const struct net_device *dev);
|
||||
|
||||
struct sa_path_rec;
|
||||
int roce_resolve_route_from_path(struct sa_path_rec *rec,
|
||||
const struct ib_gid_attr *attr);
|
||||
|
||||
struct net_device *rdma_read_gid_attr_ndev_rcu(const struct ib_gid_attr *attr);
|
||||
#endif /* _CORE_PRIV_H */
|
||||
@@ -112,12 +112,12 @@ static void ib_cq_poll_work(struct work_struct *work)
|
||||
IB_POLL_BATCH);
|
||||
if (completed >= IB_POLL_BUDGET_WORKQUEUE ||
|
||||
ib_req_notify_cq(cq, IB_POLL_FLAGS) > 0)
|
||||
queue_work(ib_comp_wq, &cq->work);
|
||||
queue_work(cq->comp_wq, &cq->work);
|
||||
}
|
||||
|
||||
static void ib_cq_completion_workqueue(struct ib_cq *cq, void *private)
|
||||
{
|
||||
queue_work(ib_comp_wq, &cq->work);
|
||||
queue_work(cq->comp_wq, &cq->work);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,7 +161,7 @@ struct ib_cq *__ib_alloc_cq(struct ib_device *dev, void *private,
|
||||
goto out_destroy_cq;
|
||||
|
||||
cq->res.type = RDMA_RESTRACK_CQ;
|
||||
cq->res.kern_name = caller;
|
||||
rdma_restrack_set_task(&cq->res, caller);
|
||||
rdma_restrack_add(&cq->res);
|
||||
|
||||
switch (cq->poll_ctx) {
|
||||
@@ -175,9 +175,12 @@ struct ib_cq *__ib_alloc_cq(struct ib_device *dev, void *private,
|
||||
ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
|
||||
break;
|
||||
case IB_POLL_WORKQUEUE:
|
||||
case IB_POLL_UNBOUND_WORKQUEUE:
|
||||
cq->comp_handler = ib_cq_completion_workqueue;
|
||||
INIT_WORK(&cq->work, ib_cq_poll_work);
|
||||
ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
|
||||
cq->comp_wq = (cq->poll_ctx == IB_POLL_WORKQUEUE) ?
|
||||
ib_comp_wq : ib_comp_unbound_wq;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
@@ -213,6 +216,7 @@ void ib_free_cq(struct ib_cq *cq)
|
||||
irq_poll_disable(&cq->iop);
|
||||
break;
|
||||
case IB_POLL_WORKQUEUE:
|
||||
case IB_POLL_UNBOUND_WORKQUEUE:
|
||||
cancel_work_sync(&cq->work);
|
||||
break;
|
||||
default:
|
||||
|
||||
+177
-103
@@ -61,6 +61,7 @@ struct ib_client_data {
|
||||
};
|
||||
|
||||
struct workqueue_struct *ib_comp_wq;
|
||||
struct workqueue_struct *ib_comp_unbound_wq;
|
||||
struct workqueue_struct *ib_wq;
|
||||
EXPORT_SYMBOL_GPL(ib_wq);
|
||||
|
||||
@@ -122,8 +123,9 @@ static int ib_device_check_mandatory(struct ib_device *device)
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mandatory_table); ++i) {
|
||||
if (!*(void **) ((void *) device + mandatory_table[i].offset)) {
|
||||
pr_warn("Device %s is missing mandatory function %s\n",
|
||||
device->name, mandatory_table[i].name);
|
||||
dev_warn(&device->dev,
|
||||
"Device is missing mandatory function %s\n",
|
||||
mandatory_table[i].name);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
@@ -163,16 +165,40 @@ static struct ib_device *__ib_device_get_by_name(const char *name)
|
||||
struct ib_device *device;
|
||||
|
||||
list_for_each_entry(device, &device_list, core_list)
|
||||
if (!strncmp(name, device->name, IB_DEVICE_NAME_MAX))
|
||||
if (!strcmp(name, dev_name(&device->dev)))
|
||||
return device;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int alloc_name(char *name)
|
||||
int ib_device_rename(struct ib_device *ibdev, const char *name)
|
||||
{
|
||||
struct ib_device *device;
|
||||
int ret = 0;
|
||||
|
||||
if (!strcmp(name, dev_name(&ibdev->dev)))
|
||||
return ret;
|
||||
|
||||
mutex_lock(&device_mutex);
|
||||
list_for_each_entry(device, &device_list, core_list) {
|
||||
if (!strcmp(name, dev_name(&device->dev))) {
|
||||
ret = -EEXIST;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = device_rename(&ibdev->dev, name);
|
||||
if (ret)
|
||||
goto out;
|
||||
strlcpy(ibdev->name, name, IB_DEVICE_NAME_MAX);
|
||||
out:
|
||||
mutex_unlock(&device_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int alloc_name(struct ib_device *ibdev, const char *name)
|
||||
{
|
||||
unsigned long *inuse;
|
||||
char buf[IB_DEVICE_NAME_MAX];
|
||||
struct ib_device *device;
|
||||
int i;
|
||||
|
||||
@@ -181,24 +207,21 @@ static int alloc_name(char *name)
|
||||
return -ENOMEM;
|
||||
|
||||
list_for_each_entry(device, &device_list, core_list) {
|
||||
if (!sscanf(device->name, name, &i))
|
||||
char buf[IB_DEVICE_NAME_MAX];
|
||||
|
||||
if (sscanf(dev_name(&device->dev), name, &i) != 1)
|
||||
continue;
|
||||
if (i < 0 || i >= PAGE_SIZE * 8)
|
||||
continue;
|
||||
snprintf(buf, sizeof buf, name, i);
|
||||
if (!strncmp(buf, device->name, IB_DEVICE_NAME_MAX))
|
||||
if (!strcmp(buf, dev_name(&device->dev)))
|
||||
set_bit(i, inuse);
|
||||
}
|
||||
|
||||
i = find_first_zero_bit(inuse, PAGE_SIZE * 8);
|
||||
free_page((unsigned long) inuse);
|
||||
snprintf(buf, sizeof buf, name, i);
|
||||
|
||||
if (__ib_device_get_by_name(buf))
|
||||
return -ENFILE;
|
||||
|
||||
strlcpy(name, buf, IB_DEVICE_NAME_MAX);
|
||||
return 0;
|
||||
return dev_set_name(&ibdev->dev, name, i);
|
||||
}
|
||||
|
||||
static void ib_device_release(struct device *device)
|
||||
@@ -221,9 +244,7 @@ static void ib_device_release(struct device *device)
|
||||
static int ib_device_uevent(struct device *device,
|
||||
struct kobj_uevent_env *env)
|
||||
{
|
||||
struct ib_device *dev = container_of(device, struct ib_device, dev);
|
||||
|
||||
if (add_uevent_var(env, "NAME=%s", dev->name))
|
||||
if (add_uevent_var(env, "NAME=%s", dev_name(device)))
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
@@ -269,7 +290,7 @@ struct ib_device *ib_alloc_device(size_t size)
|
||||
|
||||
INIT_LIST_HEAD(&device->event_handler_list);
|
||||
spin_lock_init(&device->event_handler_lock);
|
||||
spin_lock_init(&device->client_data_lock);
|
||||
rwlock_init(&device->client_data_lock);
|
||||
INIT_LIST_HEAD(&device->client_data_list);
|
||||
INIT_LIST_HEAD(&device->port_list);
|
||||
|
||||
@@ -285,6 +306,7 @@ EXPORT_SYMBOL(ib_alloc_device);
|
||||
*/
|
||||
void ib_dealloc_device(struct ib_device *device)
|
||||
{
|
||||
WARN_ON(!list_empty(&device->client_data_list));
|
||||
WARN_ON(device->reg_state != IB_DEV_UNREGISTERED &&
|
||||
device->reg_state != IB_DEV_UNINITIALIZED);
|
||||
rdma_restrack_clean(&device->res);
|
||||
@@ -295,9 +317,8 @@ EXPORT_SYMBOL(ib_dealloc_device);
|
||||
static int add_client_context(struct ib_device *device, struct ib_client *client)
|
||||
{
|
||||
struct ib_client_data *context;
|
||||
unsigned long flags;
|
||||
|
||||
context = kmalloc(sizeof *context, GFP_KERNEL);
|
||||
context = kmalloc(sizeof(*context), GFP_KERNEL);
|
||||
if (!context)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -306,9 +327,9 @@ static int add_client_context(struct ib_device *device, struct ib_client *client
|
||||
context->going_down = false;
|
||||
|
||||
down_write(&lists_rwsem);
|
||||
spin_lock_irqsave(&device->client_data_lock, flags);
|
||||
write_lock_irq(&device->client_data_lock);
|
||||
list_add(&context->list, &device->client_data_list);
|
||||
spin_unlock_irqrestore(&device->client_data_lock, flags);
|
||||
write_unlock_irq(&device->client_data_lock);
|
||||
up_write(&lists_rwsem);
|
||||
|
||||
return 0;
|
||||
@@ -444,22 +465,8 @@ static u32 __dev_new_index(void)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ib_register_device - Register an IB device with IB core
|
||||
* @device:Device to register
|
||||
*
|
||||
* Low-level drivers use ib_register_device() to register their
|
||||
* devices with the IB core. All registered clients will receive a
|
||||
* callback for each device that is added. @device must be allocated
|
||||
* with ib_alloc_device().
|
||||
*/
|
||||
int ib_register_device(struct ib_device *device,
|
||||
int (*port_callback)(struct ib_device *,
|
||||
u8, struct kobject *))
|
||||
static void setup_dma_device(struct ib_device *device)
|
||||
{
|
||||
int ret;
|
||||
struct ib_client *client;
|
||||
struct ib_udata uhw = {.outlen = 0, .inlen = 0};
|
||||
struct device *parent = device->dev.parent;
|
||||
|
||||
WARN_ON_ONCE(device->dma_device);
|
||||
@@ -491,56 +498,113 @@ int ib_register_device(struct ib_device *device,
|
||||
WARN_ON_ONCE(!parent);
|
||||
device->dma_device = parent;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_lock(&device_mutex);
|
||||
static void cleanup_device(struct ib_device *device)
|
||||
{
|
||||
ib_cache_cleanup_one(device);
|
||||
ib_cache_release_one(device);
|
||||
kfree(device->port_pkey_list);
|
||||
kfree(device->port_immutable);
|
||||
}
|
||||
|
||||
if (strchr(device->name, '%')) {
|
||||
ret = alloc_name(device->name);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
static int setup_device(struct ib_device *device)
|
||||
{
|
||||
struct ib_udata uhw = {.outlen = 0, .inlen = 0};
|
||||
int ret;
|
||||
|
||||
if (ib_device_check_mandatory(device)) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
ret = ib_device_check_mandatory(device);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = read_port_immutable(device);
|
||||
if (ret) {
|
||||
pr_warn("Couldn't create per port immutable data %s\n",
|
||||
device->name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = setup_port_pkey_list(device);
|
||||
if (ret) {
|
||||
pr_warn("Couldn't create per port_pkey_list\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = ib_cache_setup_one(device);
|
||||
if (ret) {
|
||||
pr_warn("Couldn't set up InfiniBand P_Key/GID cache\n");
|
||||
goto port_cleanup;
|
||||
}
|
||||
|
||||
ret = ib_device_register_rdmacg(device);
|
||||
if (ret) {
|
||||
pr_warn("Couldn't register device with rdma cgroup\n");
|
||||
goto cache_cleanup;
|
||||
dev_warn(&device->dev,
|
||||
"Couldn't create per port immutable data\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
memset(&device->attrs, 0, sizeof(device->attrs));
|
||||
ret = device->query_device(device, &device->attrs, &uhw);
|
||||
if (ret) {
|
||||
pr_warn("Couldn't query the device attributes\n");
|
||||
goto cg_cleanup;
|
||||
dev_warn(&device->dev,
|
||||
"Couldn't query the device attributes\n");
|
||||
goto port_cleanup;
|
||||
}
|
||||
|
||||
ret = setup_port_pkey_list(device);
|
||||
if (ret) {
|
||||
dev_warn(&device->dev, "Couldn't create per port_pkey_list\n");
|
||||
goto port_cleanup;
|
||||
}
|
||||
|
||||
ret = ib_cache_setup_one(device);
|
||||
if (ret) {
|
||||
dev_warn(&device->dev,
|
||||
"Couldn't set up InfiniBand P_Key/GID cache\n");
|
||||
goto pkey_cleanup;
|
||||
}
|
||||
return 0;
|
||||
|
||||
pkey_cleanup:
|
||||
kfree(device->port_pkey_list);
|
||||
port_cleanup:
|
||||
kfree(device->port_immutable);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ib_register_device - Register an IB device with IB core
|
||||
* @device:Device to register
|
||||
*
|
||||
* Low-level drivers use ib_register_device() to register their
|
||||
* devices with the IB core. All registered clients will receive a
|
||||
* callback for each device that is added. @device must be allocated
|
||||
* with ib_alloc_device().
|
||||
*/
|
||||
int ib_register_device(struct ib_device *device, const char *name,
|
||||
int (*port_callback)(struct ib_device *, u8,
|
||||
struct kobject *))
|
||||
{
|
||||
int ret;
|
||||
struct ib_client *client;
|
||||
|
||||
setup_dma_device(device);
|
||||
|
||||
mutex_lock(&device_mutex);
|
||||
|
||||
if (strchr(name, '%')) {
|
||||
ret = alloc_name(device, name);
|
||||
if (ret)
|
||||
goto out;
|
||||
} else {
|
||||
ret = dev_set_name(&device->dev, name);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
if (__ib_device_get_by_name(dev_name(&device->dev))) {
|
||||
ret = -ENFILE;
|
||||
goto out;
|
||||
}
|
||||
strlcpy(device->name, dev_name(&device->dev), IB_DEVICE_NAME_MAX);
|
||||
|
||||
ret = setup_device(device);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
device->index = __dev_new_index();
|
||||
|
||||
ret = ib_device_register_rdmacg(device);
|
||||
if (ret) {
|
||||
dev_warn(&device->dev,
|
||||
"Couldn't register device with rdma cgroup\n");
|
||||
goto dev_cleanup;
|
||||
}
|
||||
|
||||
ret = ib_device_register_sysfs(device, port_callback);
|
||||
if (ret) {
|
||||
pr_warn("Couldn't register device %s with driver model\n",
|
||||
device->name);
|
||||
dev_warn(&device->dev,
|
||||
"Couldn't register device with driver model\n");
|
||||
goto cg_cleanup;
|
||||
}
|
||||
|
||||
@@ -550,7 +614,6 @@ int ib_register_device(struct ib_device *device,
|
||||
if (!add_client_context(device, client) && client->add)
|
||||
client->add(device);
|
||||
|
||||
device->index = __dev_new_index();
|
||||
down_write(&lists_rwsem);
|
||||
list_add_tail(&device->core_list, &device_list);
|
||||
up_write(&lists_rwsem);
|
||||
@@ -559,11 +622,8 @@ int ib_register_device(struct ib_device *device,
|
||||
|
||||
cg_cleanup:
|
||||
ib_device_unregister_rdmacg(device);
|
||||
cache_cleanup:
|
||||
ib_cache_cleanup_one(device);
|
||||
ib_cache_release_one(device);
|
||||
port_cleanup:
|
||||
kfree(device->port_immutable);
|
||||
dev_cleanup:
|
||||
cleanup_device(device);
|
||||
out:
|
||||
mutex_unlock(&device_mutex);
|
||||
return ret;
|
||||
@@ -585,21 +645,20 @@ void ib_unregister_device(struct ib_device *device)
|
||||
|
||||
down_write(&lists_rwsem);
|
||||
list_del(&device->core_list);
|
||||
spin_lock_irqsave(&device->client_data_lock, flags);
|
||||
list_for_each_entry_safe(context, tmp, &device->client_data_list, list)
|
||||
write_lock_irq(&device->client_data_lock);
|
||||
list_for_each_entry(context, &device->client_data_list, list)
|
||||
context->going_down = true;
|
||||
spin_unlock_irqrestore(&device->client_data_lock, flags);
|
||||
write_unlock_irq(&device->client_data_lock);
|
||||
downgrade_write(&lists_rwsem);
|
||||
|
||||
list_for_each_entry_safe(context, tmp, &device->client_data_list,
|
||||
list) {
|
||||
list_for_each_entry(context, &device->client_data_list, list) {
|
||||
if (context->client->remove)
|
||||
context->client->remove(device, context->data);
|
||||
}
|
||||
up_read(&lists_rwsem);
|
||||
|
||||
ib_device_unregister_rdmacg(device);
|
||||
ib_device_unregister_sysfs(device);
|
||||
ib_device_unregister_rdmacg(device);
|
||||
|
||||
mutex_unlock(&device_mutex);
|
||||
|
||||
@@ -609,10 +668,13 @@ void ib_unregister_device(struct ib_device *device)
|
||||
kfree(device->port_pkey_list);
|
||||
|
||||
down_write(&lists_rwsem);
|
||||
spin_lock_irqsave(&device->client_data_lock, flags);
|
||||
list_for_each_entry_safe(context, tmp, &device->client_data_list, list)
|
||||
write_lock_irqsave(&device->client_data_lock, flags);
|
||||
list_for_each_entry_safe(context, tmp, &device->client_data_list,
|
||||
list) {
|
||||
list_del(&context->list);
|
||||
kfree(context);
|
||||
spin_unlock_irqrestore(&device->client_data_lock, flags);
|
||||
}
|
||||
write_unlock_irqrestore(&device->client_data_lock, flags);
|
||||
up_write(&lists_rwsem);
|
||||
|
||||
device->reg_state = IB_DEV_UNREGISTERED;
|
||||
@@ -662,9 +724,8 @@ EXPORT_SYMBOL(ib_register_client);
|
||||
*/
|
||||
void ib_unregister_client(struct ib_client *client)
|
||||
{
|
||||
struct ib_client_data *context, *tmp;
|
||||
struct ib_client_data *context;
|
||||
struct ib_device *device;
|
||||
unsigned long flags;
|
||||
|
||||
mutex_lock(&device_mutex);
|
||||
|
||||
@@ -676,14 +737,14 @@ void ib_unregister_client(struct ib_client *client)
|
||||
struct ib_client_data *found_context = NULL;
|
||||
|
||||
down_write(&lists_rwsem);
|
||||
spin_lock_irqsave(&device->client_data_lock, flags);
|
||||
list_for_each_entry_safe(context, tmp, &device->client_data_list, list)
|
||||
write_lock_irq(&device->client_data_lock);
|
||||
list_for_each_entry(context, &device->client_data_list, list)
|
||||
if (context->client == client) {
|
||||
context->going_down = true;
|
||||
found_context = context;
|
||||
break;
|
||||
}
|
||||
spin_unlock_irqrestore(&device->client_data_lock, flags);
|
||||
write_unlock_irq(&device->client_data_lock);
|
||||
up_write(&lists_rwsem);
|
||||
|
||||
if (client->remove)
|
||||
@@ -691,17 +752,18 @@ void ib_unregister_client(struct ib_client *client)
|
||||
found_context->data : NULL);
|
||||
|
||||
if (!found_context) {
|
||||
pr_warn("No client context found for %s/%s\n",
|
||||
device->name, client->name);
|
||||
dev_warn(&device->dev,
|
||||
"No client context found for %s\n",
|
||||
client->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
down_write(&lists_rwsem);
|
||||
spin_lock_irqsave(&device->client_data_lock, flags);
|
||||
write_lock_irq(&device->client_data_lock);
|
||||
list_del(&found_context->list);
|
||||
kfree(found_context);
|
||||
spin_unlock_irqrestore(&device->client_data_lock, flags);
|
||||
write_unlock_irq(&device->client_data_lock);
|
||||
up_write(&lists_rwsem);
|
||||
kfree(found_context);
|
||||
}
|
||||
|
||||
mutex_unlock(&device_mutex);
|
||||
@@ -722,13 +784,13 @@ void *ib_get_client_data(struct ib_device *device, struct ib_client *client)
|
||||
void *ret = NULL;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&device->client_data_lock, flags);
|
||||
read_lock_irqsave(&device->client_data_lock, flags);
|
||||
list_for_each_entry(context, &device->client_data_list, list)
|
||||
if (context->client == client) {
|
||||
ret = context->data;
|
||||
break;
|
||||
}
|
||||
spin_unlock_irqrestore(&device->client_data_lock, flags);
|
||||
read_unlock_irqrestore(&device->client_data_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -749,18 +811,18 @@ void ib_set_client_data(struct ib_device *device, struct ib_client *client,
|
||||
struct ib_client_data *context;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&device->client_data_lock, flags);
|
||||
write_lock_irqsave(&device->client_data_lock, flags);
|
||||
list_for_each_entry(context, &device->client_data_list, list)
|
||||
if (context->client == client) {
|
||||
context->data = data;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pr_warn("No client context found for %s/%s\n",
|
||||
device->name, client->name);
|
||||
dev_warn(&device->dev, "No client context found for %s\n",
|
||||
client->name);
|
||||
|
||||
out:
|
||||
spin_unlock_irqrestore(&device->client_data_lock, flags);
|
||||
write_unlock_irqrestore(&device->client_data_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(ib_set_client_data);
|
||||
|
||||
@@ -1166,10 +1228,19 @@ static int __init ib_core_init(void)
|
||||
goto err;
|
||||
}
|
||||
|
||||
ib_comp_unbound_wq =
|
||||
alloc_workqueue("ib-comp-unb-wq",
|
||||
WQ_UNBOUND | WQ_HIGHPRI | WQ_MEM_RECLAIM |
|
||||
WQ_SYSFS, WQ_UNBOUND_MAX_ACTIVE);
|
||||
if (!ib_comp_unbound_wq) {
|
||||
ret = -ENOMEM;
|
||||
goto err_comp;
|
||||
}
|
||||
|
||||
ret = class_register(&ib_class);
|
||||
if (ret) {
|
||||
pr_warn("Couldn't create InfiniBand device class\n");
|
||||
goto err_comp;
|
||||
goto err_comp_unbound;
|
||||
}
|
||||
|
||||
ret = rdma_nl_init();
|
||||
@@ -1218,6 +1289,8 @@ err_ibnl:
|
||||
rdma_nl_exit();
|
||||
err_sysfs:
|
||||
class_unregister(&ib_class);
|
||||
err_comp_unbound:
|
||||
destroy_workqueue(ib_comp_unbound_wq);
|
||||
err_comp:
|
||||
destroy_workqueue(ib_comp_wq);
|
||||
err:
|
||||
@@ -1236,6 +1309,7 @@ static void __exit ib_core_cleanup(void)
|
||||
addr_cleanup();
|
||||
rdma_nl_exit();
|
||||
class_unregister(&ib_class);
|
||||
destroy_workqueue(ib_comp_unbound_wq);
|
||||
destroy_workqueue(ib_comp_wq);
|
||||
/* Make sure that any pending umem accounting work is done. */
|
||||
destroy_workqueue(ib_wq);
|
||||
|
||||
@@ -213,7 +213,7 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd,
|
||||
device = pd->device;
|
||||
if (!device->alloc_fmr || !device->dealloc_fmr ||
|
||||
!device->map_phys_fmr || !device->unmap_fmr) {
|
||||
pr_info(PFX "Device %s does not support FMRs\n", device->name);
|
||||
dev_info(&device->dev, "Device does not support FMRs\n");
|
||||
return ERR_PTR(-ENOSYS);
|
||||
}
|
||||
|
||||
@@ -257,7 +257,8 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd,
|
||||
atomic_set(&pool->flush_ser, 0);
|
||||
init_waitqueue_head(&pool->force_wait);
|
||||
|
||||
pool->worker = kthread_create_worker(0, "ib_fmr(%s)", device->name);
|
||||
pool->worker =
|
||||
kthread_create_worker(0, "ib_fmr(%s)", dev_name(&device->dev));
|
||||
if (IS_ERR(pool->worker)) {
|
||||
pr_warn(PFX "couldn't start cleanup kthread worker\n");
|
||||
ret = PTR_ERR(pool->worker);
|
||||
|
||||
@@ -509,7 +509,7 @@ static int iw_cm_map(struct iw_cm_id *cm_id, bool active)
|
||||
cm_id->m_local_addr = cm_id->local_addr;
|
||||
cm_id->m_remote_addr = cm_id->remote_addr;
|
||||
|
||||
memcpy(pm_reg_msg.dev_name, cm_id->device->name,
|
||||
memcpy(pm_reg_msg.dev_name, dev_name(&cm_id->device->dev),
|
||||
sizeof(pm_reg_msg.dev_name));
|
||||
memcpy(pm_reg_msg.if_name, cm_id->device->iwcm->ifname,
|
||||
sizeof(pm_reg_msg.if_name));
|
||||
|
||||
@@ -220,33 +220,37 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
|
||||
int ret2, qpn;
|
||||
u8 mgmt_class, vclass;
|
||||
|
||||
if ((qp_type == IB_QPT_SMI && !rdma_cap_ib_smi(device, port_num)) ||
|
||||
(qp_type == IB_QPT_GSI && !rdma_cap_ib_cm(device, port_num)))
|
||||
return ERR_PTR(-EPROTONOSUPPORT);
|
||||
|
||||
/* Validate parameters */
|
||||
qpn = get_spl_qp_index(qp_type);
|
||||
if (qpn == -1) {
|
||||
dev_notice(&device->dev,
|
||||
"ib_register_mad_agent: invalid QP Type %d\n",
|
||||
qp_type);
|
||||
dev_dbg_ratelimited(&device->dev, "%s: invalid QP Type %d\n",
|
||||
__func__, qp_type);
|
||||
goto error1;
|
||||
}
|
||||
|
||||
if (rmpp_version && rmpp_version != IB_MGMT_RMPP_VERSION) {
|
||||
dev_notice(&device->dev,
|
||||
"ib_register_mad_agent: invalid RMPP Version %u\n",
|
||||
rmpp_version);
|
||||
dev_dbg_ratelimited(&device->dev,
|
||||
"%s: invalid RMPP Version %u\n",
|
||||
__func__, rmpp_version);
|
||||
goto error1;
|
||||
}
|
||||
|
||||
/* Validate MAD registration request if supplied */
|
||||
if (mad_reg_req) {
|
||||
if (mad_reg_req->mgmt_class_version >= MAX_MGMT_VERSION) {
|
||||
dev_notice(&device->dev,
|
||||
"ib_register_mad_agent: invalid Class Version %u\n",
|
||||
mad_reg_req->mgmt_class_version);
|
||||
dev_dbg_ratelimited(&device->dev,
|
||||
"%s: invalid Class Version %u\n",
|
||||
__func__,
|
||||
mad_reg_req->mgmt_class_version);
|
||||
goto error1;
|
||||
}
|
||||
if (!recv_handler) {
|
||||
dev_notice(&device->dev,
|
||||
"ib_register_mad_agent: no recv_handler\n");
|
||||
dev_dbg_ratelimited(&device->dev,
|
||||
"%s: no recv_handler\n", __func__);
|
||||
goto error1;
|
||||
}
|
||||
if (mad_reg_req->mgmt_class >= MAX_MGMT_CLASS) {
|
||||
@@ -256,9 +260,9 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
|
||||
*/
|
||||
if (mad_reg_req->mgmt_class !=
|
||||
IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) {
|
||||
dev_notice(&device->dev,
|
||||
"ib_register_mad_agent: Invalid Mgmt Class 0x%x\n",
|
||||
mad_reg_req->mgmt_class);
|
||||
dev_dbg_ratelimited(&device->dev,
|
||||
"%s: Invalid Mgmt Class 0x%x\n",
|
||||
__func__, mad_reg_req->mgmt_class);
|
||||
goto error1;
|
||||
}
|
||||
} else if (mad_reg_req->mgmt_class == 0) {
|
||||
@@ -266,8 +270,9 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
|
||||
* Class 0 is reserved in IBA and is used for
|
||||
* aliasing of IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE
|
||||
*/
|
||||
dev_notice(&device->dev,
|
||||
"ib_register_mad_agent: Invalid Mgmt Class 0\n");
|
||||
dev_dbg_ratelimited(&device->dev,
|
||||
"%s: Invalid Mgmt Class 0\n",
|
||||
__func__);
|
||||
goto error1;
|
||||
} else if (is_vendor_class(mad_reg_req->mgmt_class)) {
|
||||
/*
|
||||
@@ -275,18 +280,19 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
|
||||
* ensure supplied OUI is not zero
|
||||
*/
|
||||
if (!is_vendor_oui(mad_reg_req->oui)) {
|
||||
dev_notice(&device->dev,
|
||||
"ib_register_mad_agent: No OUI specified for class 0x%x\n",
|
||||
mad_reg_req->mgmt_class);
|
||||
dev_dbg_ratelimited(&device->dev,
|
||||
"%s: No OUI specified for class 0x%x\n",
|
||||
__func__,
|
||||
mad_reg_req->mgmt_class);
|
||||
goto error1;
|
||||
}
|
||||
}
|
||||
/* Make sure class supplied is consistent with RMPP */
|
||||
if (!ib_is_mad_class_rmpp(mad_reg_req->mgmt_class)) {
|
||||
if (rmpp_version) {
|
||||
dev_notice(&device->dev,
|
||||
"ib_register_mad_agent: RMPP version for non-RMPP class 0x%x\n",
|
||||
mad_reg_req->mgmt_class);
|
||||
dev_dbg_ratelimited(&device->dev,
|
||||
"%s: RMPP version for non-RMPP class 0x%x\n",
|
||||
__func__, mad_reg_req->mgmt_class);
|
||||
goto error1;
|
||||
}
|
||||
}
|
||||
@@ -297,9 +303,9 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
|
||||
IB_MGMT_CLASS_SUBN_LID_ROUTED) &&
|
||||
(mad_reg_req->mgmt_class !=
|
||||
IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)) {
|
||||
dev_notice(&device->dev,
|
||||
"ib_register_mad_agent: Invalid SM QP type: class 0x%x\n",
|
||||
mad_reg_req->mgmt_class);
|
||||
dev_dbg_ratelimited(&device->dev,
|
||||
"%s: Invalid SM QP type: class 0x%x\n",
|
||||
__func__, mad_reg_req->mgmt_class);
|
||||
goto error1;
|
||||
}
|
||||
} else {
|
||||
@@ -307,9 +313,9 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
|
||||
IB_MGMT_CLASS_SUBN_LID_ROUTED) ||
|
||||
(mad_reg_req->mgmt_class ==
|
||||
IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)) {
|
||||
dev_notice(&device->dev,
|
||||
"ib_register_mad_agent: Invalid GS QP type: class 0x%x\n",
|
||||
mad_reg_req->mgmt_class);
|
||||
dev_dbg_ratelimited(&device->dev,
|
||||
"%s: Invalid GS QP type: class 0x%x\n",
|
||||
__func__, mad_reg_req->mgmt_class);
|
||||
goto error1;
|
||||
}
|
||||
}
|
||||
@@ -324,18 +330,18 @@ 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 %d\n",
|
||||
port_num);
|
||||
dev_dbg_ratelimited(&device->dev, "%s: Invalid port %d\n",
|
||||
__func__, port_num);
|
||||
ret = ERR_PTR(-ENODEV);
|
||||
goto error1;
|
||||
}
|
||||
|
||||
/* Verify the QP requested is supported. For example, Ethernet devices
|
||||
* will not have QP0 */
|
||||
/* Verify the QP requested is supported. For example, Ethernet devices
|
||||
* will not have QP0.
|
||||
*/
|
||||
if (!port_priv->qp_info[qpn].qp) {
|
||||
dev_notice(&device->dev,
|
||||
"ib_register_mad_agent: QP %d not supported\n", qpn);
|
||||
dev_dbg_ratelimited(&device->dev, "%s: QP %d not supported\n",
|
||||
__func__, qpn);
|
||||
ret = ERR_PTR(-EPROTONOSUPPORT);
|
||||
goto error1;
|
||||
}
|
||||
@@ -2408,7 +2414,7 @@ static void wait_for_response(struct ib_mad_send_wr_private *mad_send_wr)
|
||||
}
|
||||
|
||||
void ib_reset_mad_timeout(struct ib_mad_send_wr_private *mad_send_wr,
|
||||
int timeout_ms)
|
||||
unsigned long timeout_ms)
|
||||
{
|
||||
mad_send_wr->timeout = msecs_to_jiffies(timeout_ms);
|
||||
wait_for_response(mad_send_wr);
|
||||
@@ -3183,7 +3189,7 @@ static int ib_mad_port_open(struct ib_device *device,
|
||||
cq_size *= 2;
|
||||
|
||||
port_priv->cq = ib_alloc_cq(port_priv->device, port_priv, cq_size, 0,
|
||||
IB_POLL_WORKQUEUE);
|
||||
IB_POLL_UNBOUND_WORKQUEUE);
|
||||
if (IS_ERR(port_priv->cq)) {
|
||||
dev_err(&device->dev, "Couldn't create ib_mad CQ\n");
|
||||
ret = PTR_ERR(port_priv->cq);
|
||||
|
||||
@@ -221,6 +221,6 @@ void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr,
|
||||
void ib_mark_mad_done(struct ib_mad_send_wr_private *mad_send_wr);
|
||||
|
||||
void ib_reset_mad_timeout(struct ib_mad_send_wr_private *mad_send_wr,
|
||||
int timeout_ms);
|
||||
unsigned long timeout_ms);
|
||||
|
||||
#endif /* __IB_MAD_PRIV_H__ */
|
||||
@@ -47,9 +47,9 @@ static struct {
|
||||
const struct rdma_nl_cbs *cb_table;
|
||||
} rdma_nl_types[RDMA_NL_NUM_CLIENTS];
|
||||
|
||||
int rdma_nl_chk_listeners(unsigned int group)
|
||||
bool rdma_nl_chk_listeners(unsigned int group)
|
||||
{
|
||||
return (netlink_has_listeners(nls, group)) ? 0 : -1;
|
||||
return netlink_has_listeners(nls, group);
|
||||
}
|
||||
EXPORT_SYMBOL(rdma_nl_chk_listeners);
|
||||
|
||||
|
||||
@@ -179,7 +179,8 @@ static int fill_nldev_handle(struct sk_buff *msg, struct ib_device *device)
|
||||
{
|
||||
if (nla_put_u32(msg, RDMA_NLDEV_ATTR_DEV_INDEX, device->index))
|
||||
return -EMSGSIZE;
|
||||
if (nla_put_string(msg, RDMA_NLDEV_ATTR_DEV_NAME, device->name))
|
||||
if (nla_put_string(msg, RDMA_NLDEV_ATTR_DEV_NAME,
|
||||
dev_name(&device->dev)))
|
||||
return -EMSGSIZE;
|
||||
|
||||
return 0;
|
||||
@@ -645,6 +646,36 @@ err:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int nldev_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct nlattr *tb[RDMA_NLDEV_ATTR_MAX];
|
||||
struct ib_device *device;
|
||||
u32 index;
|
||||
int err;
|
||||
|
||||
err = nlmsg_parse(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1, nldev_policy,
|
||||
extack);
|
||||
if (err || !tb[RDMA_NLDEV_ATTR_DEV_INDEX])
|
||||
return -EINVAL;
|
||||
|
||||
index = nla_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
|
||||
device = ib_device_get_by_index(index);
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
if (tb[RDMA_NLDEV_ATTR_DEV_NAME]) {
|
||||
char name[IB_DEVICE_NAME_MAX] = {};
|
||||
|
||||
nla_strlcpy(name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
|
||||
IB_DEVICE_NAME_MAX);
|
||||
err = ib_device_rename(device, name);
|
||||
}
|
||||
|
||||
put_device(&device->dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int _nldev_get_dumpit(struct ib_device *device,
|
||||
struct sk_buff *skb,
|
||||
struct netlink_callback *cb,
|
||||
@@ -1077,6 +1108,10 @@ static const struct rdma_nl_cbs nldev_cb_table[RDMA_NLDEV_NUM_OPS] = {
|
||||
.doit = nldev_get_doit,
|
||||
.dump = nldev_get_dumpit,
|
||||
},
|
||||
[RDMA_NLDEV_CMD_SET] = {
|
||||
.doit = nldev_set_doit,
|
||||
.flags = RDMA_NL_ADMIN_PERM,
|
||||
},
|
||||
[RDMA_NLDEV_CMD_PORT_GET] = {
|
||||
.doit = nldev_port_get_doit,
|
||||
.dump = nldev_port_get_dumpit,
|
||||
|
||||
@@ -794,44 +794,6 @@ void uverbs_close_fd(struct file *f)
|
||||
uverbs_uobject_put(uobj);
|
||||
}
|
||||
|
||||
static void ufile_disassociate_ucontext(struct ib_ucontext *ibcontext)
|
||||
{
|
||||
struct ib_device *ib_dev = ibcontext->device;
|
||||
struct task_struct *owning_process = NULL;
|
||||
struct mm_struct *owning_mm = NULL;
|
||||
|
||||
owning_process = get_pid_task(ibcontext->tgid, PIDTYPE_PID);
|
||||
if (!owning_process)
|
||||
return;
|
||||
|
||||
owning_mm = get_task_mm(owning_process);
|
||||
if (!owning_mm) {
|
||||
pr_info("no mm, disassociate ucontext is pending task termination\n");
|
||||
while (1) {
|
||||
put_task_struct(owning_process);
|
||||
usleep_range(1000, 2000);
|
||||
owning_process = get_pid_task(ibcontext->tgid,
|
||||
PIDTYPE_PID);
|
||||
if (!owning_process ||
|
||||
owning_process->state == TASK_DEAD) {
|
||||
pr_info("disassociate ucontext done, task was terminated\n");
|
||||
/* in case task was dead need to release the
|
||||
* task struct.
|
||||
*/
|
||||
if (owning_process)
|
||||
put_task_struct(owning_process);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
down_write(&owning_mm->mmap_sem);
|
||||
ib_dev->disassociate_ucontext(ibcontext);
|
||||
up_write(&owning_mm->mmap_sem);
|
||||
mmput(owning_mm);
|
||||
put_task_struct(owning_process);
|
||||
}
|
||||
|
||||
/*
|
||||
* Drop the ucontext off the ufile and completely disconnect it from the
|
||||
* ib_device
|
||||
@@ -840,20 +802,28 @@ static void ufile_destroy_ucontext(struct ib_uverbs_file *ufile,
|
||||
enum rdma_remove_reason reason)
|
||||
{
|
||||
struct ib_ucontext *ucontext = ufile->ucontext;
|
||||
struct ib_device *ib_dev = ucontext->device;
|
||||
int ret;
|
||||
|
||||
if (reason == RDMA_REMOVE_DRIVER_REMOVE)
|
||||
ufile_disassociate_ucontext(ucontext);
|
||||
/*
|
||||
* If we are closing the FD then the user mmap VMAs must have
|
||||
* already been destroyed as they hold on to the filep, otherwise
|
||||
* they need to be zap'd.
|
||||
*/
|
||||
if (reason == RDMA_REMOVE_DRIVER_REMOVE) {
|
||||
uverbs_user_mmap_disassociate(ufile);
|
||||
if (ib_dev->disassociate_ucontext)
|
||||
ib_dev->disassociate_ucontext(ucontext);
|
||||
}
|
||||
|
||||
put_pid(ucontext->tgid);
|
||||
ib_rdmacg_uncharge(&ucontext->cg_obj, ucontext->device,
|
||||
ib_rdmacg_uncharge(&ucontext->cg_obj, ib_dev,
|
||||
RDMACG_RESOURCE_HCA_HANDLE);
|
||||
|
||||
/*
|
||||
* FIXME: Drivers are not permitted to fail dealloc_ucontext, remove
|
||||
* the error return.
|
||||
*/
|
||||
ret = ucontext->device->dealloc_ucontext(ucontext);
|
||||
ret = ib_dev->dealloc_ucontext(ucontext);
|
||||
WARN_ON(ret);
|
||||
|
||||
ufile->ucontext = NULL;
|
||||
|
||||
@@ -160,5 +160,6 @@ void uverbs_disassociate_api(struct uverbs_api *uapi);
|
||||
void uverbs_destroy_api(struct uverbs_api *uapi);
|
||||
void uapi_compute_bundle_size(struct uverbs_api_ioctl_method *method_elm,
|
||||
unsigned int num_attrs);
|
||||
void uverbs_user_mmap_disassociate(struct ib_uverbs_file *ufile);
|
||||
|
||||
#endif /* RDMA_CORE_H */
|
||||
@@ -50,8 +50,7 @@ void rdma_restrack_clean(struct rdma_restrack_root *res)
|
||||
|
||||
dev = container_of(res, struct ib_device, res);
|
||||
pr_err("restrack: %s", CUT_HERE);
|
||||
pr_err("restrack: BUG: RESTRACK detected leak of resources on %s\n",
|
||||
dev->name);
|
||||
dev_err(&dev->dev, "BUG: RESTRACK detected leak of resources\n");
|
||||
hash_for_each(res->hash, bkt, e, node) {
|
||||
if (rdma_is_kernel_res(e)) {
|
||||
owner = e->kern_name;
|
||||
@@ -156,6 +155,21 @@ static bool res_is_user(struct rdma_restrack_entry *res)
|
||||
}
|
||||
}
|
||||
|
||||
void rdma_restrack_set_task(struct rdma_restrack_entry *res,
|
||||
const char *caller)
|
||||
{
|
||||
if (caller) {
|
||||
res->kern_name = caller;
|
||||
return;
|
||||
}
|
||||
|
||||
if (res->task)
|
||||
put_task_struct(res->task);
|
||||
get_task_struct(current);
|
||||
res->task = current;
|
||||
}
|
||||
EXPORT_SYMBOL(rdma_restrack_set_task);
|
||||
|
||||
void rdma_restrack_add(struct rdma_restrack_entry *res)
|
||||
{
|
||||
struct ib_device *dev = res_to_dev(res);
|
||||
@@ -168,7 +182,7 @@ void rdma_restrack_add(struct rdma_restrack_entry *res)
|
||||
|
||||
if (res_is_user(res)) {
|
||||
if (!res->task)
|
||||
rdma_restrack_set_task(res, current);
|
||||
rdma_restrack_set_task(res, NULL);
|
||||
res->kern_name = NULL;
|
||||
} else {
|
||||
set_kern_name(res);
|
||||
@@ -209,7 +223,7 @@ void rdma_restrack_del(struct rdma_restrack_entry *res)
|
||||
struct ib_device *dev;
|
||||
|
||||
if (!res->valid)
|
||||
return;
|
||||
goto out;
|
||||
|
||||
dev = res_to_dev(res);
|
||||
if (!dev)
|
||||
@@ -222,8 +236,12 @@ void rdma_restrack_del(struct rdma_restrack_entry *res)
|
||||
down_write(&dev->res.rwsem);
|
||||
hash_del(&res->node);
|
||||
res->valid = false;
|
||||
if (res->task)
|
||||
put_task_struct(res->task);
|
||||
up_write(&dev->res.rwsem);
|
||||
|
||||
out:
|
||||
if (res->task) {
|
||||
put_task_struct(res->task);
|
||||
res->task = NULL;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(rdma_restrack_del);
|
||||
@@ -49,16 +49,14 @@ static inline void ib_sa_client_put(struct ib_sa_client *client)
|
||||
}
|
||||
|
||||
int ib_sa_mcmember_rec_query(struct ib_sa_client *client,
|
||||
struct ib_device *device, u8 port_num,
|
||||
u8 method,
|
||||
struct ib_device *device, u8 port_num, u8 method,
|
||||
struct ib_sa_mcmember_rec *rec,
|
||||
ib_sa_comp_mask comp_mask,
|
||||
int timeout_ms, gfp_t gfp_mask,
|
||||
unsigned long timeout_ms, gfp_t gfp_mask,
|
||||
void (*callback)(int status,
|
||||
struct ib_sa_mcmember_rec *resp,
|
||||
void *context),
|
||||
void *context,
|
||||
struct ib_sa_query **sa_query);
|
||||
void *context, struct ib_sa_query **sa_query);
|
||||
|
||||
int mcast_init(void);
|
||||
void mcast_cleanup(void);
|
||||
|
||||
Loaded 20 of 204 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user