Skip to content

Commit c4b4d54

Browse files
avihai1122jgunthorpe
authored andcommitted
RDMA/core: Introduce new GID table query API
Introduce rdma_query_gid_table which enables querying all the GID tables of a given device and copying the attributes of all valid GID entries to a provided buffer. This API provides a faster way to query a GID table using single call and will be used in libibverbs to improve current approach that requires multiple calls to open, close and read multiple sysfs files for a single GID table entry. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Avihai Horon <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 1c15b4f commit c4b4d54

File tree

3 files changed

+74
-3
lines changed

3 files changed

+74
-3
lines changed

drivers/infiniband/core/cache.c

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,6 +1247,67 @@ rdma_get_gid_attr(struct ib_device *device, u8 port_num, int index)
12471247
}
12481248
EXPORT_SYMBOL(rdma_get_gid_attr);
12491249

1250+
/**
1251+
* rdma_query_gid_table - Reads GID table entries of all the ports of a device up to max_entries.
1252+
* @device: The device to query.
1253+
* @entries: Entries where GID entries are returned.
1254+
* @max_entries: Maximum number of entries that can be returned.
1255+
* Entries array must be allocated to hold max_entries number of entries.
1256+
* @num_entries: Updated to the number of entries that were successfully read.
1257+
*
1258+
* Returns number of entries on success or appropriate error code.
1259+
*/
1260+
ssize_t rdma_query_gid_table(struct ib_device *device,
1261+
struct ib_uverbs_gid_entry *entries,
1262+
size_t max_entries)
1263+
{
1264+
const struct ib_gid_attr *gid_attr;
1265+
ssize_t num_entries = 0, ret;
1266+
struct ib_gid_table *table;
1267+
unsigned int port_num, i;
1268+
struct net_device *ndev;
1269+
unsigned long flags;
1270+
1271+
rdma_for_each_port(device, port_num) {
1272+
if (!rdma_ib_or_roce(device, port_num))
1273+
continue;
1274+
1275+
table = rdma_gid_table(device, port_num);
1276+
read_lock_irqsave(&table->rwlock, flags);
1277+
for (i = 0; i < table->sz; i++) {
1278+
if (!is_gid_entry_valid(table->data_vec[i]))
1279+
continue;
1280+
if (num_entries >= max_entries) {
1281+
ret = -EINVAL;
1282+
goto err;
1283+
}
1284+
1285+
gid_attr = &table->data_vec[i]->attr;
1286+
1287+
memcpy(&entries->gid, &gid_attr->gid,
1288+
sizeof(gid_attr->gid));
1289+
entries->gid_index = gid_attr->index;
1290+
entries->port_num = gid_attr->port_num;
1291+
entries->gid_type = gid_attr->gid_type;
1292+
ndev = rcu_dereference_protected(
1293+
gid_attr->ndev,
1294+
lockdep_is_held(&table->rwlock));
1295+
if (ndev)
1296+
entries->netdev_ifindex = ndev->ifindex;
1297+
1298+
num_entries++;
1299+
entries++;
1300+
}
1301+
read_unlock_irqrestore(&table->rwlock, flags);
1302+
}
1303+
1304+
return num_entries;
1305+
err:
1306+
read_unlock_irqrestore(&table->rwlock, flags);
1307+
return ret;
1308+
}
1309+
EXPORT_SYMBOL(rdma_query_gid_table);
1310+
12501311
/**
12511312
* rdma_put_gid_attr - Release reference to the GID attribute
12521313
* @attr: Pointer to the GID attribute whose reference
@@ -1303,7 +1364,7 @@ struct net_device *rdma_read_gid_attr_ndev_rcu(const struct ib_gid_attr *attr)
13031364
struct ib_gid_table_entry *entry =
13041365
container_of(attr, struct ib_gid_table_entry, attr);
13051366
struct ib_device *device = entry->attr.device;
1306-
struct net_device *ndev = ERR_PTR(-ENODEV);
1367+
struct net_device *ndev = ERR_PTR(-EINVAL);
13071368
u8 port_num = entry->attr.port_num;
13081369
struct ib_gid_table *table;
13091370
unsigned long flags;
@@ -1315,8 +1376,7 @@ struct net_device *rdma_read_gid_attr_ndev_rcu(const struct ib_gid_attr *attr)
13151376
valid = is_gid_entry_valid(table->data_vec[attr->index]);
13161377
if (valid) {
13171378
ndev = rcu_dereference(attr->ndev);
1318-
if (!ndev ||
1319-
(ndev && ((READ_ONCE(ndev->flags) & IFF_UP) == 0)))
1379+
if (!ndev)
13201380
ndev = ERR_PTR(-ENODEV);
13211381
}
13221382
read_unlock_irqrestore(&table->rwlock, flags);

include/rdma/ib_cache.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,5 +110,8 @@ const struct ib_gid_attr *rdma_get_gid_attr(struct ib_device *device,
110110
u8 port_num, int index);
111111
void rdma_put_gid_attr(const struct ib_gid_attr *attr);
112112
void rdma_hold_gid_attr(const struct ib_gid_attr *attr);
113+
ssize_t rdma_query_gid_table(struct ib_device *device,
114+
struct ib_uverbs_gid_entry *entries,
115+
size_t max_entries);
113116

114117
#endif /* _IB_CACHE_H */

include/uapi/rdma/ib_user_ioctl_verbs.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,4 +251,12 @@ enum rdma_driver_id {
251251
RDMA_DRIVER_SIW,
252252
};
253253

254+
struct ib_uverbs_gid_entry {
255+
__aligned_u64 gid[2];
256+
__u32 gid_index;
257+
__u32 port_num;
258+
__u32 gid_type;
259+
__u32 netdev_ifindex; /* It is 0 if there is no netdev associated with it */
260+
};
261+
254262
#endif

0 commit comments

Comments
 (0)