diff options
author | Parav Pandit <parav@mellanox.com> | 2018-06-05 01:40:17 -0400 |
---|---|---|
committer | Jason Gunthorpe <jgg@mellanox.com> | 2018-06-18 13:09:05 -0400 |
commit | bf399c2cadfa66d399d01d5a92a7bb0a112f1568 (patch) | |
tree | 4bec872b23a13d79c1b65083bd236fbe1f7fce3e /drivers/infiniband/core/cache.c | |
parent | f4df9a7c34d8f9e84af73ce187bcdf6fea65c4cb (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.c | 86 |
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 | ||
289 | static void get_gid_entry(struct ib_gid_table_entry *entry) | ||
290 | { | ||
291 | kref_get(&entry->kref); | ||
292 | } | ||
293 | |||
289 | static void put_gid_entry(struct ib_gid_table_entry *entry) | 294 | static 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 | } |
1209 | EXPORT_SYMBOL(ib_get_cached_port_state); | 1214 | EXPORT_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 | */ | ||
1232 | const struct ib_gid_attr * | ||
1233 | rdma_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; | ||
1252 | done: | ||
1253 | read_unlock_irqrestore(&table->rwlock, flags); | ||
1254 | return attr; | ||
1255 | } | ||
1256 | EXPORT_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 | */ | ||
1269 | void 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 | } | ||
1276 | EXPORT_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 | */ | ||
1288 | void 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 | } | ||
1295 | EXPORT_SYMBOL(rdma_hold_gid_attr); | ||
1296 | |||
1211 | static int config_non_roce_gid_cache(struct ib_device *device, | 1297 | static 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 | { |