aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/cache.c
diff options
context:
space:
mode:
authorParav Pandit <parav@mellanox.com>2018-06-05 01:40:17 -0400
committerJason Gunthorpe <jgg@mellanox.com>2018-06-18 13:09:05 -0400
commitbf399c2cadfa66d399d01d5a92a7bb0a112f1568 (patch)
tree4bec872b23a13d79c1b65083bd236fbe1f7fce3e /drivers/infiniband/core/cache.c
parentf4df9a7c34d8f9e84af73ce187bcdf6fea65c4cb (diff)
IB/core: Introduce GID attribute get, put and hold APIs
This patch introduces three APIs, rdma_get_gid_attr(), rdma_put_gid_attr(), and rdma_hold_gid_attr() which expose the reference counting for GID table entries to the entire stack. The kref counting is based on the struct ib_gid_attr pointer Later patches will convert more cache query function to return struct ib_gid_attrs. 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.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
index e569956c4e7a..d92525fb47c7 100644
--- a/drivers/infiniband/core/cache.c
+++ b/drivers/infiniband/core/cache.c
@@ -286,6 +286,11 @@ static void store_gid_entry(struct ib_gid_table *table,
286 write_unlock_irq(&table->rwlock); 286 write_unlock_irq(&table->rwlock);
287} 287}
288 288
289static void get_gid_entry(struct ib_gid_table_entry *entry)
290{
291 kref_get(&entry->kref);
292}
293
289static void put_gid_entry(struct ib_gid_table_entry *entry) 294static void put_gid_entry(struct ib_gid_table_entry *entry)
290{ 295{
291 kref_put(&entry->kref, schedule_free_gid); 296 kref_put(&entry->kref, schedule_free_gid);
@@ -1208,6 +1213,87 @@ int ib_get_cached_port_state(struct ib_device *device,
1208} 1213}
1209EXPORT_SYMBOL(ib_get_cached_port_state); 1214EXPORT_SYMBOL(ib_get_cached_port_state);
1210 1215
1216/**
1217 * rdma_get_gid_attr - Returns GID attributes for a port of a device
1218 * at a requested gid_index, if a valid GID entry exists.
1219 * @device: The device to query.
1220 * @port_num: The port number on the device where the GID value
1221 * is to be queried.
1222 * @index: Index of the GID table entry whose attributes are to
1223 * be queried.
1224 *
1225 * rdma_get_gid_attr() acquires reference count of gid attributes from the
1226 * cached GID table. Caller must invoke rdma_put_gid_attr() to release
1227 * reference to gid attribute regardless of link layer.
1228 *
1229 * Returns pointer to valid gid attribute or ERR_PTR for the appropriate error
1230 * code.
1231 */
1232const struct ib_gid_attr *
1233rdma_get_gid_attr(struct ib_device *device, u8 port_num, int index)
1234{
1235 const struct ib_gid_attr *attr = ERR_PTR(-EINVAL);
1236 struct ib_gid_table *table;
1237 unsigned long flags;
1238
1239 if (!rdma_is_port_valid(device, port_num))
1240 return ERR_PTR(-EINVAL);
1241
1242 table = rdma_gid_table(device, port_num);
1243 if (index < 0 || index >= table->sz)
1244 return ERR_PTR(-EINVAL);
1245
1246 read_lock_irqsave(&table->rwlock, flags);
1247 if (!is_gid_entry_valid(table->data_vec[index]))
1248 goto done;
1249
1250 get_gid_entry(table->data_vec[index]);
1251 attr = &table->data_vec[index]->attr;
1252done:
1253 read_unlock_irqrestore(&table->rwlock, flags);
1254 return attr;
1255}
1256EXPORT_SYMBOL(rdma_get_gid_attr);
1257
1258/**
1259 * rdma_put_gid_attr - Release reference to the GID attribute
1260 * @attr: Pointer to the GID attribute whose reference
1261 * needs to be released.
1262 *
1263 * rdma_put_gid_attr() must be used to release reference whose
1264 * reference is acquired using rdma_get_gid_attr() or any APIs
1265 * which returns a pointer to the ib_gid_attr regardless of link layer
1266 * of IB or RoCE.
1267 *
1268 */
1269void rdma_put_gid_attr(const struct ib_gid_attr *attr)
1270{
1271 struct ib_gid_table_entry *entry =
1272 container_of(attr, struct ib_gid_table_entry, attr);
1273
1274 put_gid_entry(entry);
1275}
1276EXPORT_SYMBOL(rdma_put_gid_attr);
1277
1278/**
1279 * rdma_hold_gid_attr - Get reference to existing GID attribute
1280 *
1281 * @attr: Pointer to the GID attribute whose reference
1282 * needs to be taken.
1283 *
1284 * Increase the reference count to a GID attribute to keep it from being
1285 * freed. Callers are required to already be holding a reference to attribute.
1286 *
1287 */
1288void rdma_hold_gid_attr(const struct ib_gid_attr *attr)
1289{
1290 struct ib_gid_table_entry *entry =
1291 container_of(attr, struct ib_gid_table_entry, attr);
1292
1293 get_gid_entry(entry);
1294}
1295EXPORT_SYMBOL(rdma_hold_gid_attr);
1296
1211static int config_non_roce_gid_cache(struct ib_device *device, 1297static int config_non_roce_gid_cache(struct ib_device *device,
1212 u8 port, int gid_tbl_len) 1298 u8 port, int gid_tbl_len)
1213{ 1299{