Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband
authorLinus Torvalds <torvalds@g5.osdl.org>
Mon, 13 Nov 2006 17:52:04 +0000 (09:52 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 13 Nov 2006 17:52:04 +0000 (09:52 -0800)
* 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband:
  IB/mad: Fix race between cancel and receive completion
  RDMA/amso1100: Fix && typo
  RDMA/amso1100: Fix unitialized pseudo_netdev accessed in c2_register_device
  IB/ehca: Activate scaling code by default
  IB/ehca: Use named constant for max mtu
  IB/ehca: Assure 4K alignment for firmware control blocks

13 files changed:
drivers/infiniband/core/mad.c
drivers/infiniband/hw/amso1100/c2.c
drivers/infiniband/hw/amso1100/c2_provider.c
drivers/infiniband/hw/amso1100/c2_rnic.c
drivers/infiniband/hw/ehca/Kconfig
drivers/infiniband/hw/ehca/ehca_av.c
drivers/infiniband/hw/ehca/ehca_hca.c
drivers/infiniband/hw/ehca/ehca_irq.c
drivers/infiniband/hw/ehca/ehca_iverbs.h
drivers/infiniband/hw/ehca/ehca_main.c
drivers/infiniband/hw/ehca/ehca_mrmw.c
drivers/infiniband/hw/ehca/ehca_qp.c
drivers/infiniband/hw/ehca/hipz_hw.h

index 493f4c65c7a2b5acaa5ca753a08bf772772d70a2..a72bcea46ff634ce018f667fa21fdf9d8f322541 100644 (file)
@@ -1750,7 +1750,7 @@ ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv,
                     */
                    (is_direct(wc->recv_buf.mad->mad_hdr.mgmt_class) ||
                     rcv_has_same_gid(mad_agent_priv, wr, wc)))
-                       return wr;
+                       return (wr->status == IB_WC_SUCCESS) ? wr : NULL;
        }
 
        /*
index 9e7bd94b958ad528b28b0d06e2bd7f02e4855c76..27fe242ed4353bc33fdb76410c9dcc4fd6cb6b30 100644 (file)
@@ -1155,7 +1155,8 @@ static int __devinit c2_probe(struct pci_dev *pcidev,
                goto bail10;
        }
 
-       c2_register_device(c2dev);
+       if (c2_register_device(c2dev))
+               goto bail10;
 
        return 0;
 
index da98d9f714295062d7e46c5ccd9e03b6e9a93bb2..fef972752912f821a035bca8c03bbb4e18db6b90 100644 (file)
@@ -757,20 +757,17 @@ static struct net_device *c2_pseudo_netdev_init(struct c2_dev *c2dev)
 
 int c2_register_device(struct c2_dev *dev)
 {
-       int ret;
+       int ret = -ENOMEM;
        int i;
 
        /* Register pseudo network device */
        dev->pseudo_netdev = c2_pseudo_netdev_init(dev);
-       if (dev->pseudo_netdev) {
-               ret = register_netdev(dev->pseudo_netdev);
-               if (ret) {
-                       printk(KERN_ERR PFX
-                               "Unable to register netdev, ret = %d\n", ret);
-                       free_netdev(dev->pseudo_netdev);
-                       return ret;
-               }
-       }
+       if (!dev->pseudo_netdev)
+               goto out3;
+
+       ret = register_netdev(dev->pseudo_netdev);
+       if (ret)
+               goto out2;
 
        pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
        strlcpy(dev->ibdev.name, "amso%d", IB_DEVICE_NAME_MAX);
@@ -848,21 +845,25 @@ int c2_register_device(struct c2_dev *dev)
 
        ret = ib_register_device(&dev->ibdev);
        if (ret)
-               return ret;
+               goto out1;
 
        for (i = 0; i < ARRAY_SIZE(c2_class_attributes); ++i) {
                ret = class_device_create_file(&dev->ibdev.class_dev,
                                               c2_class_attributes[i]);
-               if (ret) {
-                       unregister_netdev(dev->pseudo_netdev);
-                       free_netdev(dev->pseudo_netdev);
-                       ib_unregister_device(&dev->ibdev);
-                       return ret;
-               }
+               if (ret)
+                       goto out0;
        }
+       goto out3;
 
-       pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
-       return 0;
+out0:
+       ib_unregister_device(&dev->ibdev);
+out1:
+       unregister_netdev(dev->pseudo_netdev);
+out2:
+       free_netdev(dev->pseudo_netdev);
+out3:
+       pr_debug("%s:%u ret=%d\n", __FUNCTION__, __LINE__, ret);
+       return ret;
 }
 
 void c2_unregister_device(struct c2_dev *dev)
index 21d9612a56ccd3e13654595b8e0f80a05a6547b4..623dc95f91df3e3e811bf05233ab572c3684233d 100644 (file)
@@ -157,8 +157,8 @@ static int c2_rnic_query(struct c2_dev *c2dev, struct ib_device_attr *props)
 
        props->fw_ver =
                ((u64)be32_to_cpu(reply->fw_ver_major) << 32) |
-               ((be32_to_cpu(reply->fw_ver_minor) && 0xFFFF) << 16) |
-               (be32_to_cpu(reply->fw_ver_patch) && 0xFFFF);
+               ((be32_to_cpu(reply->fw_ver_minor) & 0xFFFF) << 16) |
+               (be32_to_cpu(reply->fw_ver_patch) & 0xFFFF);
        memcpy(&props->sys_image_guid, c2dev->netdev->dev_addr, 6);
        props->max_mr_size         = 0xFFFFFFFF;
        props->page_size_cap       = ~(C2_MIN_PAGESIZE-1);
index 922389b643940f8d9dd11faae23ed82cf5714fd6..727b10d896868516e1776938ef5fdbafedd0cba7 100644 (file)
@@ -10,6 +10,7 @@ config INFINIBAND_EHCA
 config INFINIBAND_EHCA_SCALING
        bool "Scaling support (EXPERIMENTAL)"
        depends on IBMEBUS && INFINIBAND_EHCA && HOTPLUG_CPU && EXPERIMENTAL
+       default y
        ---help---
        eHCA scaling support schedules the CQ callbacks to different CPUs.
 
index 3bac197f90141d488f806f07100874afa5d7f491..214e2fdddeef0792572aaf0fcd333aa1ae94016b 100644 (file)
@@ -118,8 +118,7 @@ struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
                }
                memcpy(&av->av.grh.word_1, &gid, sizeof(gid));
        }
-       /* for the time being we use a hard coded PMTU of 2048 Bytes */
-       av->av.pmtu = 4;
+       av->av.pmtu = EHCA_MAX_MTU;
 
        /* dgid comes in grh.word_3 */
        memcpy(&av->av.grh.word_3, &ah_attr->grh.dgid,
@@ -193,7 +192,7 @@ int ehca_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
                memcpy(&new_ehca_av.grh.word_1, &gid, sizeof(gid));
        }
 
-       new_ehca_av.pmtu = 4; /* see also comment in create_ah() */
+       new_ehca_av.pmtu = EHCA_MAX_MTU;
 
        memcpy(&new_ehca_av.grh.word_3, &ah_attr->grh.dgid,
               sizeof(ah_attr->grh.dgid));
index 5eae6ac48425961df6166f34c2954789a59a7911..e1b618c5f685079cd1c9e8245225ee3993372902 100644 (file)
@@ -40,6 +40,7 @@
  */
 
 #include "ehca_tools.h"
+#include "ehca_iverbs.h"
 #include "hcp_if.h"
 
 int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
@@ -49,7 +50,7 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
                                              ib_device);
        struct hipz_query_hca *rblock;
 
-       rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+       rblock = ehca_alloc_fw_ctrlblock();
        if (!rblock) {
                ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
                return -ENOMEM;
@@ -96,7 +97,7 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
                = min_t(int, rblock->max_total_mcast_qp_attach, INT_MAX);
 
 query_device1:
-       kfree(rblock);
+       ehca_free_fw_ctrlblock(rblock);
 
        return ret;
 }
@@ -109,7 +110,7 @@ int ehca_query_port(struct ib_device *ibdev,
                                              ib_device);
        struct hipz_query_port *rblock;
 
-       rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+       rblock = ehca_alloc_fw_ctrlblock();
        if (!rblock) {
                ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
                return -ENOMEM;
@@ -162,7 +163,7 @@ int ehca_query_port(struct ib_device *ibdev,
        props->active_speed    = 0x1;
 
 query_port1:
-       kfree(rblock);
+       ehca_free_fw_ctrlblock(rblock);
 
        return ret;
 }
@@ -178,7 +179,7 @@ int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey)
                return -EINVAL;
        }
 
-       rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+       rblock = ehca_alloc_fw_ctrlblock();
        if (!rblock) {
                ehca_err(&shca->ib_device,  "Can't allocate rblock memory.");
                return -ENOMEM;
@@ -193,7 +194,7 @@ int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey)
        memcpy(pkey, &rblock->pkey_entries + index, sizeof(u16));
 
 query_pkey1:
-       kfree(rblock);
+       ehca_free_fw_ctrlblock(rblock);
 
        return ret;
 }
@@ -211,7 +212,7 @@ int ehca_query_gid(struct ib_device *ibdev, u8 port,
                return -EINVAL;
        }
 
-       rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+       rblock = ehca_alloc_fw_ctrlblock();
        if (!rblock) {
                ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
                return -ENOMEM;
@@ -227,7 +228,7 @@ int ehca_query_gid(struct ib_device *ibdev, u8 port,
        memcpy(&gid->raw[8], &rblock->guid_entries[index], sizeof(u64));
 
 query_gid1:
-       kfree(rblock);
+       ehca_free_fw_ctrlblock(rblock);
 
        return ret;
 }
index 048cc443d1e7ab863e01bc05b4968ade64652b1d..c3ea746e9045669852266ecb17baa2b7208c8c1c 100644 (file)
@@ -45,6 +45,7 @@
 #include "ehca_tools.h"
 #include "hcp_if.h"
 #include "hipz_fns.h"
+#include "ipz_pt_fn.h"
 
 #define EQE_COMPLETION_EVENT   EHCA_BMASK_IBM(1,1)
 #define EQE_CQ_QP_NUMBER       EHCA_BMASK_IBM(8,31)
@@ -137,38 +138,36 @@ int ehca_error_data(struct ehca_shca *shca, void *data,
        u64 *rblock;
        unsigned long block_count;
 
-       rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+       rblock = ehca_alloc_fw_ctrlblock();
        if (!rblock) {
                ehca_err(&shca->ib_device, "Cannot allocate rblock memory.");
                ret = -ENOMEM;
                goto error_data1;
        }
 
+       /* rblock must be 4K aligned and should be 4K large */
        ret = hipz_h_error_data(shca->ipz_hca_handle,
                                resource,
                                rblock,
                                &block_count);
 
-       if (ret == H_R_STATE) {
+       if (ret == H_R_STATE)
                ehca_err(&shca->ib_device,
                         "No error data is available: %lx.", resource);
-       }
        else if (ret == H_SUCCESS) {
                int length;
 
                length = EHCA_BMASK_GET(ERROR_DATA_LENGTH, rblock[0]);
 
-               if (length > PAGE_SIZE)
-                       length = PAGE_SIZE;
+               if (length > EHCA_PAGESIZE)
+                       length = EHCA_PAGESIZE;
 
                print_error_data(shca, data, rblock, length);
-       }
-       else {
+       } else
                ehca_err(&shca->ib_device,
                         "Error data could not be fetched: %lx", resource);
-       }
 
-       kfree(rblock);
+       ehca_free_fw_ctrlblock(rblock);
 
 error_data1:
        return ret;
index 319c39d47f3a93f961601708f401af17c9e41ddb..3720e3032cceed84e22a514280e36cbbcc030e62 100644 (file)
@@ -179,4 +179,12 @@ int ehca_mmap_register(u64 physical,void **mapped,
 
 int ehca_munmap(unsigned long addr, size_t len);
 
+#ifdef CONFIG_PPC_64K_PAGES
+void *ehca_alloc_fw_ctrlblock(void);
+void ehca_free_fw_ctrlblock(void *ptr);
+#else
+#define ehca_alloc_fw_ctrlblock() ((void *) get_zeroed_page(GFP_KERNEL))
+#define ehca_free_fw_ctrlblock(ptr) free_page((unsigned long)(ptr))
+#endif
+
 #endif
index 024d511c4b58f3c64140d8d5d1a4b236cff6ddca..01f5aa9cb56d1ba3e58b2667a50dcf4d78787de2 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_0018");
 
 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(void)
+{
+       void *ret = kmem_cache_zalloc(ctblk_cache, SLAB_KERNEL);
+       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();
        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();
        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();                                \
        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_0018)\n");
        idr_init(&ehca_qp_idr);
        idr_init(&ehca_cq_idr);
        spin_lock_init(&ehca_qp_idr_lock);
index 5ca65441e1da594dda6b1b94d91439038966a616..abce676c0ae0ec8a6dd8c824e6f75a7130d91fcf 100644 (file)
@@ -1013,7 +1013,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca,
        u32 i;
        u64 *kpage;
 
-       kpage = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+       kpage = ehca_alloc_fw_ctrlblock();
        if (!kpage) {
                ehca_err(&shca->ib_device, "kpage alloc failed");
                ret = -ENOMEM;
@@ -1092,7 +1092,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca,
 
 
 ehca_reg_mr_rpages_exit1:
-       kfree(kpage);
+       ehca_free_fw_ctrlblock(kpage);
 ehca_reg_mr_rpages_exit0:
        if (ret)
                ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p pginfo=%p "
@@ -1124,7 +1124,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca,
        ehca_mrmw_map_acl(acl, &hipz_acl);
        ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl);
 
-       kpage = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+       kpage = ehca_alloc_fw_ctrlblock();
        if (!kpage) {
                ehca_err(&shca->ib_device, "kpage alloc failed");
                ret = -ENOMEM;
@@ -1181,7 +1181,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca,
        }
 
 ehca_rereg_mr_rereg1_exit1:
-       kfree(kpage);
+       ehca_free_fw_ctrlblock(kpage);
 ehca_rereg_mr_rereg1_exit0:
        if ( ret && (ret != -EAGAIN) )
                ehca_err(&shca->ib_device, "ret=%x lkey=%x rkey=%x "
index 4394123cdbd745b1b3263b1bf06916be26fd67ad..cf3e50ee2d0628c2e0daf477791708479c0c9b75 100644 (file)
@@ -811,8 +811,8 @@ static int internal_modify_qp(struct ib_qp *ibqp,
        unsigned long spl_flags = 0;
 
        /* do query_qp to obtain current attr values */
-       mqpcb = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
-       if (mqpcb == NULL) {
+       mqpcb = ehca_alloc_fw_ctrlblock();
+       if (!mqpcb) {
                ehca_err(ibqp->device, "Could not get zeroed page for mqpcb "
                         "ehca_qp=%p qp_num=%x ", my_qp, ibqp->qp_num);
                return -ENOMEM;
@@ -1225,7 +1225,7 @@ modify_qp_exit2:
        }
 
 modify_qp_exit1:
-       kfree(mqpcb);
+       ehca_free_fw_ctrlblock(mqpcb);
 
        return ret;
 }
@@ -1277,7 +1277,7 @@ int ehca_query_qp(struct ib_qp *qp,
                return -EINVAL;
        }
 
-       qpcb = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL );
+       qpcb = ehca_alloc_fw_ctrlblock();
        if (!qpcb) {
                ehca_err(qp->device,"Out of memory for qpcb "
                         "ehca_qp=%p qp_num=%x", my_qp, qp->qp_num);
@@ -1401,7 +1401,7 @@ int ehca_query_qp(struct ib_qp *qp,
                ehca_dmp(qpcb, 4*70, "qp_num=%x", qp->qp_num);
 
 query_qp_exit1:
-       kfree(qpcb);
+       ehca_free_fw_ctrlblock(qpcb);
 
        return ret;
 }
index 3fc92b031c50c3fbbc9d691fe9072767956baed9..fad91368dc5a7893237c3acebbf5eefa443aad28 100644 (file)
@@ -45,6 +45,8 @@
 
 #include "ehca_tools.h"
 
+#define EHCA_MAX_MTU 4
+
 /* QP Table Entry Memory Map */
 struct hipz_qptemm {
        u64 qpx_hcr;