summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/core/cache.c30
-rw-r--r--include/rdma/ib_cache.h13
-rw-r--r--include/rdma/ib_verbs.h1
3 files changed, 43 insertions, 1 deletions
diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
index 50364c0b090c..e05ca2cdc73f 100644
--- a/drivers/infiniband/core/cache.c
+++ b/drivers/infiniband/core/cache.c
@@ -191,6 +191,24 @@ int ib_find_cached_pkey(struct ib_device *device,
}
EXPORT_SYMBOL(ib_find_cached_pkey);
+int ib_get_cached_lmc(struct ib_device *device,
+ u8 port_num,
+ u8 *lmc)
+{
+ unsigned long flags;
+ int ret = 0;
+
+ if (port_num < start_port(device) || port_num > end_port(device))
+ return -EINVAL;
+
+ read_lock_irqsave(&device->cache.lock, flags);
+ *lmc = device->cache.lmc_cache[port_num - start_port(device)];
+ read_unlock_irqrestore(&device->cache.lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(ib_get_cached_lmc);
+
static void ib_cache_update(struct ib_device *device,
u8 port)
{
@@ -251,6 +269,8 @@ static void ib_cache_update(struct ib_device *device,
device->cache.pkey_cache[port - start_port(device)] = pkey_cache;
device->cache.gid_cache [port - start_port(device)] = gid_cache;
+ device->cache.lmc_cache[port - start_port(device)] = tprops->lmc;
+
write_unlock_irq(&device->cache.lock);
kfree(old_pkey_cache);
@@ -305,7 +325,13 @@ static void ib_cache_setup_one(struct ib_device *device)
kmalloc(sizeof *device->cache.gid_cache *
(end_port(device) - start_port(device) + 1), GFP_KERNEL);
- if (!device->cache.pkey_cache || !device->cache.gid_cache) {
+ device->cache.lmc_cache = kmalloc(sizeof *device->cache.lmc_cache *
+ (end_port(device) -
+ start_port(device) + 1),
+ GFP_KERNEL);
+
+ if (!device->cache.pkey_cache || !device->cache.gid_cache ||
+ !device->cache.lmc_cache) {
printk(KERN_WARNING "Couldn't allocate cache "
"for %s\n", device->name);
goto err;
@@ -333,6 +359,7 @@ err_cache:
err:
kfree(device->cache.pkey_cache);
kfree(device->cache.gid_cache);
+ kfree(device->cache.lmc_cache);
}
static void ib_cache_cleanup_one(struct ib_device *device)
@@ -349,6 +376,7 @@ static void ib_cache_cleanup_one(struct ib_device *device)
kfree(device->cache.pkey_cache);
kfree(device->cache.gid_cache);
+ kfree(device->cache.lmc_cache);
}
static struct ib_client cache_client = {
diff --git a/include/rdma/ib_cache.h b/include/rdma/ib_cache.h
index 5bf9834f7dca..f179d233ffc3 100644
--- a/include/rdma/ib_cache.h
+++ b/include/rdma/ib_cache.h
@@ -102,4 +102,17 @@ int ib_find_cached_pkey(struct ib_device *device,
u16 pkey,
u16 *index);
+/**
+ * ib_get_cached_lmc - Returns a cached lmc table entry
+ * @device: The device to query.
+ * @port_num: The port number of the device to query.
+ * @lmc: The lmc value for the specified port for that device.
+ *
+ * ib_get_cached_lmc() fetches the specified lmc table entry stored in
+ * the local software cache.
+ */
+int ib_get_cached_lmc(struct ib_device *device,
+ u8 port_num,
+ u8 *lmc);
+
#endif /* _IB_CACHE_H */
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 6bbf1b364400..aeb4fcd86a9e 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -827,6 +827,7 @@ struct ib_cache {
struct ib_event_handler event_handler;
struct ib_pkey_cache **pkey_cache;
struct ib_gid_cache **gid_cache;
+ u8 *lmc_cache;
};
struct ib_device {