aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/cache.c
diff options
context:
space:
mode:
authorParav Pandit <parav@mellanox.com>2018-09-05 05:54:25 -0400
committerJason Gunthorpe <jgg@mellanox.com>2018-09-12 18:32:17 -0400
commitd6b1764a8c5ac0ad3a66c6d11d24c4fe067fe933 (patch)
tree9b82b62906e476c9383f61e1c7cb929acb305dba /drivers/infiniband/core/cache.c
parent6aaecd38568557266ff7a5c3765c58322586e4ce (diff)
RDMA/core: Introduce rdma_read_gid_attr_ndev_rcu() to check GID attribute
Introduce an API rdma_read_gid_attr_ndev_rcu() to return GID attribute netdevice which is in UP state for accessing netdevice's fields such as net namespace and ifindex. This is useful for users who intent to access netdevice fields under rcu lock. Signed-off-by: Parav Pandit <parav@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Diffstat (limited to 'drivers/infiniband/core/cache.c')
-rw-r--r--drivers/infiniband/core/cache.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
index 0bee1f4b914e..8957d31d60ca 100644
--- a/drivers/infiniband/core/cache.c
+++ b/drivers/infiniband/core/cache.c
@@ -1252,6 +1252,39 @@ void rdma_hold_gid_attr(const struct ib_gid_attr *attr)
1252} 1252}
1253EXPORT_SYMBOL(rdma_hold_gid_attr); 1253EXPORT_SYMBOL(rdma_hold_gid_attr);
1254 1254
1255/**
1256 * rdma_read_gid_attr_ndev_rcu - Read GID attribute netdevice
1257 * which must be in UP state.
1258 *
1259 * @attr:Pointer to the GID attribute
1260 *
1261 * Returns pointer to netdevice if the netdevice was attached to GID and
1262 * netdevice is in UP state. Caller must hold RCU lock as this API
1263 * reads the netdev flags which can change while netdevice migrates to
1264 * different net namespace. Returns ERR_PTR with error code otherwise.
1265 *
1266 */
1267struct net_device *rdma_read_gid_attr_ndev_rcu(const struct ib_gid_attr *attr)
1268{
1269 struct ib_gid_table_entry *entry =
1270 container_of(attr, struct ib_gid_table_entry, attr);
1271 struct ib_device *device = entry->attr.device;
1272 struct net_device *ndev = ERR_PTR(-ENODEV);
1273 u8 port_num = entry->attr.port_num;
1274 struct ib_gid_table *table;
1275 unsigned long flags;
1276 bool valid;
1277
1278 table = rdma_gid_table(device, port_num);
1279
1280 read_lock_irqsave(&table->rwlock, flags);
1281 valid = is_gid_entry_valid(table->data_vec[attr->index]);
1282 if (valid && attr->ndev && (READ_ONCE(attr->ndev->flags) & IFF_UP))
1283 ndev = attr->ndev;
1284 read_unlock_irqrestore(&table->rwlock, flags);
1285 return ndev;
1286}
1287
1255static int config_non_roce_gid_cache(struct ib_device *device, 1288static int config_non_roce_gid_cache(struct ib_device *device,
1256 u8 port, int gid_tbl_len) 1289 u8 port, int gid_tbl_len)
1257{ 1290{