Merge ../linux-2.6-watchdog-mm
[firefly-linux-kernel-4.4.55.git] / drivers / infiniband / hw / ehca / ehca_main.c
index 024d511c4b58f3c64140d8d5d1a4b236cff6ddca..6574fbbaead5e8faf0f65d7e98ca3c75c4bede05 100644 (file)
@@ -40,6 +40,9 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifdef CONFIG_PPC_64K_PAGES
+#include <linux/slab.h>
+#endif
 #include "ehca_classes.h"
 #include "ehca_iverbs.h"
 #include "ehca_mrmw.h"
@@ -49,7 +52,7 @@
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>");
 MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver");
-MODULE_VERSION("SVNEHCA_0017");
+MODULE_VERSION("SVNEHCA_0019");
 
 int ehca_open_aqp1     = 0;
 int ehca_debug_level   = 0;
@@ -94,11 +97,31 @@ spinlock_t ehca_cq_idr_lock;
 DEFINE_IDR(ehca_qp_idr);
 DEFINE_IDR(ehca_cq_idr);
 
+
 static struct list_head shca_list; /* list of all registered ehcas */
 static spinlock_t shca_list_lock;
 
 static struct timer_list poll_eqs_timer;
 
+#ifdef CONFIG_PPC_64K_PAGES
+static struct kmem_cache *ctblk_cache = NULL;
+
+void *ehca_alloc_fw_ctrlblock(gfp_t flags)
+{
+       void *ret = kmem_cache_zalloc(ctblk_cache, flags);
+       if (!ret)
+               ehca_gen_err("Out of memory for ctblk");
+       return ret;
+}
+
+void ehca_free_fw_ctrlblock(void *ptr)
+{
+       if (ptr)
+               kmem_cache_free(ctblk_cache, ptr);
+
+}
+#endif
+
 static int ehca_create_slab_caches(void)
 {
        int ret;
@@ -133,6 +156,17 @@ static int ehca_create_slab_caches(void)
                goto create_slab_caches5;
        }
 
+#ifdef CONFIG_PPC_64K_PAGES
+       ctblk_cache = kmem_cache_create("ehca_cache_ctblk",
+                                       EHCA_PAGESIZE, H_CB_ALIGNMENT,
+                                       SLAB_HWCACHE_ALIGN,
+                                       NULL, NULL);
+       if (!ctblk_cache) {
+               ehca_gen_err("Cannot create ctblk SLAB cache.");
+               ehca_cleanup_mrmw_cache();
+               goto create_slab_caches5;
+       }
+#endif
        return 0;
 
 create_slab_caches5:
@@ -157,6 +191,10 @@ static void ehca_destroy_slab_caches(void)
        ehca_cleanup_qp_cache();
        ehca_cleanup_cq_cache();
        ehca_cleanup_pd_cache();
+#ifdef CONFIG_PPC_64K_PAGES
+       if (ctblk_cache)
+               kmem_cache_destroy(ctblk_cache);
+#endif
 }
 
 #define EHCA_HCAAVER  EHCA_BMASK_IBM(32,39)
@@ -168,7 +206,7 @@ int ehca_sense_attributes(struct ehca_shca *shca)
        u64 h_ret;
        struct hipz_query_hca *rblock;
 
-       rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+       rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
        if (!rblock) {
                ehca_gen_err("Cannot allocate rblock memory.");
                return -ENOMEM;
@@ -211,7 +249,7 @@ int ehca_sense_attributes(struct ehca_shca *shca)
        shca->sport[1].rate = IB_RATE_30_GBPS;
 
 num_ports1:
-       kfree(rblock);
+       ehca_free_fw_ctrlblock(rblock);
        return ret;
 }
 
@@ -220,7 +258,7 @@ static int init_node_guid(struct ehca_shca *shca)
        int ret = 0;
        struct hipz_query_hca *rblock;
 
-       rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+       rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
        if (!rblock) {
                ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
                return -ENOMEM;
@@ -235,7 +273,7 @@ static int init_node_guid(struct ehca_shca *shca)
        memcpy(&shca->ib_device.node_guid, &rblock->node_guid, sizeof(u64));
 
 init_node_guid1:
-       kfree(rblock);
+       ehca_free_fw_ctrlblock(rblock);
        return ret;
 }
 
@@ -431,7 +469,7 @@ static ssize_t  ehca_show_##name(struct device *dev,                       \
                                                                           \
        shca = dev->driver_data;                                           \
                                                                           \
-       rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);                      \
+       rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);                      \
        if (!rblock) {                                                     \
                dev_err(dev, "Can't allocate rblock memory.");             \
                return 0;                                                  \
@@ -439,12 +477,12 @@ static ssize_t  ehca_show_##name(struct device *dev,                       \
                                                                           \
        if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) { \
                dev_err(dev, "Can't query device properties");             \
-               kfree(rblock);                                             \
+               ehca_free_fw_ctrlblock(rblock);                            \
                return 0;                                                  \
        }                                                                  \
                                                                           \
        data = rblock->name;                                               \
-       kfree(rblock);                                                     \
+       ehca_free_fw_ctrlblock(rblock);                                    \
                                                                           \
        if ((strcmp(#name, "num_ports") == 0) && (ehca_nr_ports == 1))     \
                return snprintf(buf, 256, "1\n");                          \
@@ -752,7 +790,7 @@ int __init ehca_module_init(void)
        int ret;
 
        printk(KERN_INFO "eHCA Infiniband Device Driver "
-                        "(Rel.: SVNEHCA_0017)\n");
+                        "(Rel.: SVNEHCA_0019)\n");
        idr_init(&ehca_qp_idr);
        idr_init(&ehca_cq_idr);
        spin_lock_init(&ehca_qp_idr_lock);