]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/infiniband/core/cache.c
[PATCH] IB/cm: drop REQ when out of memory
[linux-2.6-omap-h63xx.git] / drivers / infiniband / core / cache.c
index f014e639088ca13d923df980234b998244062983..e05ca2cdc73f44aafd3dd807906d073b33511463 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
+#include <linux/sched.h>       /* INIT_WORK, schedule_work(), flush_scheduled_work() */
 
 #include <rdma/ib_cache.h>
 
@@ -190,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)
 {
@@ -250,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);
@@ -301,10 +322,16 @@ static void ib_cache_setup_one(struct ib_device *device)
                kmalloc(sizeof *device->cache.pkey_cache *
                        (end_port(device) - start_port(device) + 1), GFP_KERNEL);
        device->cache.gid_cache =
-               kmalloc(sizeof *device->cache.pkey_cache *
+               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;
@@ -332,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)
@@ -348,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 = {