* Re: [PATCH 02/13] IB/ehca: includes [not found] <OFED0915E4.3CED6795-ONC12571CE.0053ECB8-C12571CE.0055546A@LocalDomain> @ 2006-08-30 9:13 ` Hoang-Nam Nguyen 2006-08-30 9:43 ` Arnd Bergmann 0 siblings, 1 reply; 7+ messages in thread From: Hoang-Nam Nguyen @ 2006-08-30 9:13 UTC (permalink / raw) To: abergman, linux-kernel, linuxppc-dev, openib-general Cc: Christoph Raisch, Marcus Eder > Christoph Raisch wrote on 18.08.2006 17:35:54: > we'll change these EDEBs to a wrapper around dev_err, dev_dbg and > dev_warn as it's done in the mthca driver. > All EDEB_EN and EDEB_EX will be removed, that type of tracing can be > done if needed by kprobes. > There are a few cases where we won't get to a dev, for these few > places we'll use a simple wrapper around printk, as done in ipoib. We incorporated those changes throughout ehca code, which is accessible from Roland's git tree: git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband.git for-2.6.19 Further comments/suggestions are appreciated! Regards Hoang-Nam Nguyen ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 02/13] IB/ehca: includes 2006-08-30 9:13 ` [PATCH 02/13] IB/ehca: includes Hoang-Nam Nguyen @ 2006-08-30 9:43 ` Arnd Bergmann 2006-08-30 18:27 ` [openib-general] " Hoang-Nam Nguyen 0 siblings, 1 reply; 7+ messages in thread From: Arnd Bergmann @ 2006-08-30 9:43 UTC (permalink / raw) To: linuxppc-dev Cc: linux-kernel, openib-general, Christoph Raisch, Hoang-Nam Nguyen, Marcus Eder, abergman On Wednesday 30 August 2006 11:13, Hoang-Nam Nguyen wrote: > Further comments/suggestions are appreciated! There are a few places in the driver where you declare external variables (mostly ehca_module and ehca_debug_level) from C files instead of a header. This sometimes leads to bugs when a type changes and is therefore considered bad style. ehca_debug_level is already declared in a header so you should not need any other declaration. For ehca_module, the usage pattern is very uncommon. Declaring the structure in a header helps a bit, but I don't really see the need for this structure at all. Each member of the struct seems to be used mostly in a single file, so I would declare it statically in there. E.g. in drivers/infiniband/hw/ehca/ehca_pd.c, you can do static struct kmem_cache *ehca_pd_cache; int ehca_init_pd_cache(void) { ehca_pd_cache = kmem_cache_init("ehca_cache_pd", sizeof(struct ehca_pd), 0, SLAB_HWCACHE_ALIGN, NULL, NULL); if (!ehca_pd_cache) return -ENOMEM; return 0; } void ehca_cleanup_pd_cache(void) { if (ehca_pd_cache) kmem_cache_destroy(ehca_pd_cache); } Moreover, for some of your more heavily used caches, you may want to look into using constructor/destructor calls to speed up allocation. Arnd <>< ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [openib-general] [PATCH 02/13] IB/ehca: includes 2006-08-30 9:43 ` Arnd Bergmann @ 2006-08-30 18:27 ` Hoang-Nam Nguyen 0 siblings, 0 replies; 7+ messages in thread From: Hoang-Nam Nguyen @ 2006-08-30 18:27 UTC (permalink / raw) To: abergman Cc: linux-kernel, openib-general, linuxppc-dev, Christoph Raisch, Marcus Eder, openib-general-bounces, abergman Hi, > There are a few places in the driver where you declare > external variables (mostly ehca_module and ehca_debug_level) > from C files instead of a header. This sometimes leads > to bugs when a type changes and is therefore considered > bad style. Good point. See patch attached below. > Moreover, for some of your more heavily used caches, you may > want to look into using constructor/destructor calls to > speed up allocation. That makes sense. Will look into this for a later patch. Thanks! Nam Makefile | 1 ehca_av.c | 29 +++++++--- ehca_classes.h | 27 +++++---- ehca_cq.c | 27 +++++++-- ehca_eq.c | 14 ---- ehca_irq.c | 1 ehca_main.c | 164 ++++++++++++++++++++------------------------------------- ehca_mrmw.c | 45 +++++++++++---- ehca_pd.c | 25 +++++++- ehca_qp.c | 32 +++++++---- ehca_reqs.c | 2 ehca_sqp.c | 2 hcp_if.c | 1 hcp_phyp.h | 4 - ipz_pt_fn.c | 2 15 files changed, 198 insertions(+), 178 deletions(-) diff -Nurp infiniband/drivers/infiniband/hw/ehca/Makefile infiniband_work/drivers/infiniband/hw/ehca/Makefile --- infiniband/drivers/infiniband/hw/ehca/Makefile 2006-08-30 18:02:01.000000000 +0200 +++ infiniband_work/drivers/infiniband/hw/ehca/Makefile 2006-08-30 20:00:17.000000000 +0200 @@ -10,6 +10,7 @@ obj-$(CONFIG_INFINIBAND_EHCA) += ib_ehca.o + ib_ehca-objs = ehca_main.o ehca_hca.o ehca_mcast.o ehca_pd.o ehca_av.o ehca_eq.o \ ehca_cq.o ehca_qp.o ehca_sqp.o ehca_mrmw.o ehca_reqs.o ehca_irq.o \ ehca_uverbs.o ipz_pt_fn.o hcp_if.o hcp_phyp.o diff -Nurp infiniband/drivers/infiniband/hw/ehca/ehca_av.c infiniband_work/drivers/infiniband/hw/ehca/ehca_av.c --- infiniband/drivers/infiniband/hw/ehca/ehca_av.c 2006-08-30 18:02:01.000000000 +0200 +++ infiniband_work/drivers/infiniband/hw/ehca/ehca_av.c 2006-08-30 20:00:16.000000000 +0200 @@ -48,16 +48,16 @@ #include "ehca_iverbs.h" #include "hcp_if.h" +static struct kmem_cache *av_cache; + struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr) { - extern struct ehca_module ehca_module; - extern int ehca_static_rate; int ret; struct ehca_av *av; struct ehca_shca *shca = container_of(pd->device, struct ehca_shca, ib_device); - av = kmem_cache_alloc(ehca_module.cache_av, SLAB_KERNEL); + av = kmem_cache_alloc(av_cache, SLAB_KERNEL); if (!av) { ehca_err(pd->device, "Out of memory pd=%p ah_attr=%p", pd, ah_attr); @@ -128,7 +128,7 @@ struct ib_ah *ehca_create_ah(struct ib_p return &av->ib_ah; create_ah_exit1: - kmem_cache_free(ehca_module.cache_av, av); + kmem_cache_free(av_cache, av); return ERR_PTR(ret); } @@ -238,7 +238,6 @@ int ehca_query_ah(struct ib_ah *ah, stru int ehca_destroy_ah(struct ib_ah *ah) { - extern struct ehca_module ehca_module; struct ehca_pd *my_pd = container_of(ah->pd, struct ehca_pd, ib_pd); u32 cur_pid = current->tgid; @@ -249,8 +248,24 @@ int ehca_destroy_ah(struct ib_ah *ah) return -EINVAL; } - kmem_cache_free(ehca_module.cache_av, - container_of(ah, struct ehca_av, ib_ah)); + kmem_cache_free(av_cache, container_of(ah, struct ehca_av, ib_ah)); + + return 0; +} +int ehca_init_av_cache(void) +{ + av_cache = kmem_cache_create("ehca_cache_av", + sizeof(struct ehca_av), 0, + SLAB_HWCACHE_ALIGN, + NULL, NULL); + if (!av_cache) + return -ENOMEM; return 0; } + +void ehca_cleanup_av_cache(void) +{ + if (av_cache) + kmem_cache_destroy(av_cache); +} diff -Nurp infiniband/drivers/infiniband/hw/ehca/ehca_classes.h infiniband_work/drivers/infiniband/hw/ehca/ehca_classes.h --- infiniband/drivers/infiniband/hw/ehca/ehca_classes.h 2006-08-30 18:02:01.000000000 +0200 +++ infiniband_work/drivers/infiniband/hw/ehca/ehca_classes.h 2006-08-30 20:00:16.000000000 +0200 @@ -63,18 +63,6 @@ struct ehca_av; #include "ehca_irq.h" -struct ehca_module { - struct list_head shca_list; - spinlock_t shca_lock; - struct timer_list timer; - kmem_cache_t *cache_pd; - kmem_cache_t *cache_cq; - kmem_cache_t *cache_qp; - kmem_cache_t *cache_av; - kmem_cache_t *cache_mr; - kmem_cache_t *cache_mw; -}; - struct ehca_eq { u32 length; struct ipz_queue ipz_queue; @@ -274,11 +262,26 @@ int ehca_shca_delete(struct ehca_shca *m struct ehca_sport *ehca_sport_new(struct ehca_shca *anchor); +int ehca_init_pd_cache(void); +void ehca_cleanup_pd_cache(void); +int ehca_init_cq_cache(void); +void ehca_cleanup_cq_cache(void); +int ehca_init_qp_cache(void); +void ehca_cleanup_qp_cache(void); +int ehca_init_av_cache(void); +void ehca_cleanup_av_cache(void); +int ehca_init_mrmw_cache(void); +void ehca_cleanup_mrmw_cache(void); + extern spinlock_t ehca_qp_idr_lock; extern spinlock_t ehca_cq_idr_lock; extern struct idr ehca_qp_idr; extern struct idr ehca_cq_idr; +extern int ehca_static_rate; +extern int ehca_port_act_time; +extern int ehca_use_hp_mr; + struct ipzu_queue_resp { u64 queue; /* points to first queue entry */ u32 qe_size; /* queue entry size */ diff -Nurp infiniband/drivers/infiniband/hw/ehca/ehca_cq.c infiniband_work/drivers/infiniband/hw/ehca/ehca_cq.c --- infiniband/drivers/infiniband/hw/ehca/ehca_cq.c 2006-08-30 18:02:01.000000000 +0200 +++ infiniband_work/drivers/infiniband/hw/ehca/ehca_cq.c 2006-08-30 20:00:17.000000000 +0200 @@ -50,6 +50,8 @@ #include "ehca_irq.h" #include "hcp_if.h" +static struct kmem_cache *cq_cache; + int ehca_cq_assign_qp(struct ehca_cq *cq, struct ehca_qp *qp) { unsigned int qp_num = qp->real_qp_num; @@ -115,7 +117,6 @@ struct ib_cq *ehca_create_cq(struct ib_d struct ib_ucontext *context, struct ib_udata *udata) { - extern struct ehca_module ehca_module; static const u32 additional_cqe = 20; struct ib_cq *cq; struct ehca_cq *my_cq; @@ -133,7 +134,7 @@ struct ib_cq *ehca_create_cq(struct ib_d if (cqe >= 0xFFFFFFFF - 64 - additional_cqe) return ERR_PTR(-EINVAL); - my_cq = kmem_cache_alloc(ehca_module.cache_cq, SLAB_KERNEL); + my_cq = kmem_cache_alloc(cq_cache, SLAB_KERNEL); if (!my_cq) { ehca_err(device, "Out of memory for ehca_cq struct device=%p", device); @@ -324,14 +325,13 @@ create_cq_exit2: spin_unlock_irqrestore(&ehca_cq_idr_lock, flags); create_cq_exit1: - kmem_cache_free(ehca_module.cache_cq, my_cq); + kmem_cache_free(cq_cache, my_cq); return cq; } int ehca_destroy_cq(struct ib_cq *cq) { - extern struct ehca_module ehca_module; u64 h_ret; int ret; struct ehca_cq *my_cq = container_of(cq, struct ehca_cq, ib_cq); @@ -387,7 +387,7 @@ int ehca_destroy_cq(struct ib_cq *cq) return ehca2ib_return_code(h_ret); } ipz_queue_dtor(&my_cq->ipz_queue); - kmem_cache_free(ehca_module.cache_cq, my_cq); + kmem_cache_free(cq_cache, my_cq); return 0; } @@ -408,3 +408,20 @@ int ehca_resize_cq(struct ib_cq *cq, int return -EFAULT; } + +int ehca_init_cq_cache(void) +{ + cq_cache = kmem_cache_create("ehca_cache_cq", + sizeof(struct ehca_cq), 0, + SLAB_HWCACHE_ALIGN, + NULL, NULL); + if (!cq_cache) + return -ENOMEM; + return 0; +} + +void ehca_cleanup_cq_cache(void) +{ + if (cq_cache) + kmem_cache_destroy(cq_cache); +} diff -Nurp infiniband/drivers/infiniband/hw/ehca/ehca_eq.c infiniband_work/drivers/infiniband/hw/ehca/ehca_eq.c --- infiniband/drivers/infiniband/hw/ehca/ehca_eq.c 2006-08-30 18:02:01.000000000 +0200 +++ infiniband_work/drivers/infiniband/hw/ehca/ehca_eq.c 2006-08-30 20:00:16.000000000 +0200 @@ -163,20 +163,6 @@ void *ehca_poll_eq(struct ehca_shca *shc return eqe; } -void ehca_poll_eqs(unsigned long data) -{ - struct ehca_shca *shca; - struct ehca_module *module = (struct ehca_module*)data; - - spin_lock(&module->shca_lock); - list_for_each_entry(shca, &module->shca_list, shca_list) { - if (shca->eq.is_initialized) - ehca_tasklet_eq((unsigned long)(void*)shca); - } - mod_timer(&module->timer, jiffies + HZ); - spin_unlock(&module->shca_lock); -} - int ehca_destroy_eq(struct ehca_shca *shca, struct ehca_eq *eq) { unsigned long flags; diff -Nurp infiniband/drivers/infiniband/hw/ehca/ehca_irq.c infiniband_work/drivers/infiniband/hw/ehca/ehca_irq.c --- infiniband/drivers/infiniband/hw/ehca/ehca_irq.c 2006-08-30 18:02:01.000000000 +0200 +++ infiniband_work/drivers/infiniband/hw/ehca/ehca_irq.c 2006-08-30 20:00:16.000000000 +0200 @@ -427,7 +427,6 @@ void ehca_tasklet_eq(unsigned long data) /* TODO: better structure */ if (EHCA_BMASK_GET(EQE_COMPLETION_EVENT, eqe_value)) { - extern struct idr ehca_cq_idr; unsigned long flags; u32 token; struct ehca_cq *cq; diff -Nurp infiniband/drivers/infiniband/hw/ehca/ehca_main.c infiniband_work/drivers/infiniband/hw/ehca/ehca_main.c --- infiniband/drivers/infiniband/hw/ehca/ehca_main.c 2006-08-30 18:02:01.000000000 +0200 +++ infiniband_work/drivers/infiniband/hw/ehca/ehca_main.c 2006-08-30 20:01:34.000000000 +0200 @@ -4,6 +4,7 @@ * module start stop, hca detection * * Authors: Heiko J Schick <schickhj@de•ibm.com> + * Hoang-Nam Nguyen <hnguyen@de•ibm.com> * * Copyright (c) 2005 IBM Corporation * @@ -47,7 +48,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_0014"); +MODULE_VERSION("SVNEHCA_0015"); int ehca_open_aqp1 = 0; int ehca_debug_level = 0; @@ -92,129 +93,69 @@ spinlock_t ehca_cq_idr_lock; DEFINE_IDR(ehca_qp_idr); DEFINE_IDR(ehca_cq_idr); -struct ehca_module ehca_module; +static struct list_head shca_list; /* list of all registered ehcas */ +static spinlock_t shca_list_lock; -int ehca_create_slab_caches(struct ehca_module *ehca_module) +static struct timer_list poll_eqs_timer; + +static int ehca_create_slab_caches(void) { int ret; - ehca_module->cache_pd = - kmem_cache_create("ehca_cache_pd", - sizeof(struct ehca_pd), - 0, SLAB_HWCACHE_ALIGN, - NULL, NULL); - if (!ehca_module->cache_pd) { + ret = ehca_init_pd_cache(); + if (ret) { ehca_gen_err("Cannot create PD SLAB cache."); - ret = -ENOMEM; - goto create_slab_caches1; + return ret; } - ehca_module->cache_cq = - kmem_cache_create("ehca_cache_cq", - sizeof(struct ehca_cq), - 0, SLAB_HWCACHE_ALIGN, - NULL, NULL); - if (!ehca_module->cache_cq) { + ret = ehca_init_cq_cache(); + if (ret) { ehca_gen_err("Cannot create CQ SLAB cache."); - ret = -ENOMEM; goto create_slab_caches2; } - ehca_module->cache_qp = - kmem_cache_create("ehca_cache_qp", - sizeof(struct ehca_qp), - 0, SLAB_HWCACHE_ALIGN, - NULL, NULL); - if (!ehca_module->cache_qp) { + ret = ehca_init_qp_cache(); + if (ret) { ehca_gen_err("Cannot create QP SLAB cache."); - ret = -ENOMEM; goto create_slab_caches3; } - ehca_module->cache_av = - kmem_cache_create("ehca_cache_av", - sizeof(struct ehca_av), - 0, SLAB_HWCACHE_ALIGN, - NULL, NULL); - if (!ehca_module->cache_av) { + ret = ehca_init_av_cache(); + if (ret) { ehca_gen_err("Cannot create AV SLAB cache."); - ret = -ENOMEM; goto create_slab_caches4; } - ehca_module->cache_mw = - kmem_cache_create("ehca_cache_mw", - sizeof(struct ehca_mw), - 0, SLAB_HWCACHE_ALIGN, - NULL, NULL); - if (!ehca_module->cache_mw) { - ehca_gen_err("Cannot create MW SLAB cache."); - ret = -ENOMEM; + ret = ehca_init_mrmw_cache(); + if (ret) { + ehca_gen_err("Cannot create MR&MW SLAB cache."); goto create_slab_caches5; } - ehca_module->cache_mr = - kmem_cache_create("ehca_cache_mr", - sizeof(struct ehca_mr), - 0, SLAB_HWCACHE_ALIGN, - NULL, NULL); - if (!ehca_module->cache_mr) { - ehca_gen_err("Cannot create MR SLAB cache."); - ret = -ENOMEM; - goto create_slab_caches6; - } - return 0; -create_slab_caches6: - kmem_cache_destroy(ehca_module->cache_mw); - create_slab_caches5: - kmem_cache_destroy(ehca_module->cache_av); + ehca_cleanup_av_cache(); create_slab_caches4: - kmem_cache_destroy(ehca_module->cache_qp); + ehca_cleanup_qp_cache(); create_slab_caches3: - kmem_cache_destroy(ehca_module->cache_cq); + ehca_cleanup_cq_cache(); create_slab_caches2: - kmem_cache_destroy(ehca_module->cache_pd); - -create_slab_caches1: + ehca_cleanup_pd_cache(); return ret; } -int ehca_destroy_slab_caches(struct ehca_module *ehca_module) +static void ehca_destroy_slab_caches(void) { - int ret; - - ret = kmem_cache_destroy(ehca_module->cache_pd); - if (ret) - ehca_gen_err("Cannot destroy PD SLAB cache. ret=%x", ret); - - ret = kmem_cache_destroy(ehca_module->cache_cq); - if (ret) - ehca_gen_err("Cannot destroy CQ SLAB cache. ret=%x", ret); - - ret = kmem_cache_destroy(ehca_module->cache_qp); - if (ret) - ehca_gen_err("Cannot destroy QP SLAB cache. ret=%x", ret); - - ret = kmem_cache_destroy(ehca_module->cache_av); - if (ret) - ehca_gen_err("Cannot destroy AV SLAB cache. ret=%x", ret); - - ret = kmem_cache_destroy(ehca_module->cache_mw); - if (ret) - ehca_gen_err("Cannot destroy MW SLAB cache. ret=%x", ret); - - ret = kmem_cache_destroy(ehca_module->cache_mr); - if (ret) - ehca_gen_err("Cannot destroy MR SLAB cache. ret=%x", ret); - - return 0; + ehca_cleanup_mrmw_cache(); + ehca_cleanup_av_cache(); + ehca_cleanup_qp_cache(); + ehca_cleanup_cq_cache(); + ehca_cleanup_pd_cache(); } #define EHCA_HCAAVER EHCA_BMASK_IBM(32,39) @@ -682,9 +623,9 @@ static int __devinit ehca_probe(struct i ehca_create_device_sysfs(dev); - spin_lock(&ehca_module.shca_lock); - list_add(&shca->shca_list, &ehca_module.shca_list); - spin_unlock(&ehca_module.shca_lock); + spin_lock(&shca_list_lock); + list_add(&shca->shca_list, &shca_list); + spin_unlock(&shca_list_lock); return 0; @@ -767,9 +708,9 @@ static int __devexit ehca_remove(struct ib_dealloc_device(&shca->ib_device); - spin_lock(&ehca_module.shca_lock); + spin_lock(&shca_list_lock); list_del(&shca->shca_list); - spin_unlock(&ehca_module.shca_lock); + spin_unlock(&shca_list_lock); return ret; } @@ -790,26 +731,39 @@ static struct ibmebus_driver ehca_driver .remove = ehca_remove, }; +void ehca_poll_eqs(unsigned long data) +{ + struct ehca_shca *shca; + + spin_lock(&shca_list_lock); + list_for_each_entry(shca, &shca_list, shca_list) { + if (shca->eq.is_initialized) + ehca_tasklet_eq((unsigned long)(void*)shca); + } + mod_timer(&poll_eqs_timer, jiffies + HZ); + spin_unlock(&shca_list_lock); +} + int __init ehca_module_init(void) { int ret; printk(KERN_INFO "eHCA Infiniband Device Driver " - "(Rel.: SVNEHCA_0014)\n"); + "(Rel.: SVNEHCA_0015)\n"); idr_init(&ehca_qp_idr); idr_init(&ehca_cq_idr); spin_lock_init(&ehca_qp_idr_lock); spin_lock_init(&ehca_cq_idr_lock); - INIT_LIST_HEAD(&ehca_module.shca_list); - spin_lock_init(&ehca_module.shca_lock); + INIT_LIST_HEAD(&shca_list); + spin_lock_init(&shca_list_lock); if ((ret = ehca_create_comp_pool())) { ehca_gen_err("Cannot create comp pool."); return ret; } - if ((ret = ehca_create_slab_caches(&ehca_module))) { + if ((ret = ehca_create_slab_caches())) { ehca_gen_err("Cannot create SLAB caches"); ret = -ENOMEM; goto module_init1; @@ -827,17 +781,16 @@ int __init ehca_module_init(void) ehca_gen_err("WARNING!!!"); ehca_gen_err("It is possible to lose interrupts."); } else { - init_timer(&ehca_module.timer); - ehca_module.timer.function = ehca_poll_eqs; - ehca_module.timer.data = (unsigned long)&ehca_module; - ehca_module.timer.expires = jiffies + HZ; - add_timer(&ehca_module.timer); + init_timer(&poll_eqs_timer); + poll_eqs_timer.function = ehca_poll_eqs; + poll_eqs_timer.expires = jiffies + HZ; + add_timer(&poll_eqs_timer); } return 0; module_init2: - ehca_destroy_slab_caches(&ehca_module); + ehca_destroy_slab_caches(); module_init1: ehca_destroy_comp_pool(); @@ -847,13 +800,12 @@ module_init1: void __exit ehca_module_exit(void) { if (ehca_poll_all_eqs == 1) - del_timer_sync(&ehca_module.timer); + del_timer_sync(&poll_eqs_timer); ehca_remove_driver_sysfs(&ehca_driver); ibmebus_unregister_driver(&ehca_driver); - if (ehca_destroy_slab_caches(&ehca_module) != 0) - ehca_gen_err("Cannot destroy SLAB caches"); + ehca_destroy_slab_caches(); ehca_destroy_comp_pool(); diff -Nurp infiniband/drivers/infiniband/hw/ehca/ehca_mrmw.c infiniband_work/drivers/infiniband/hw/ehca/ehca_mrmw.c --- infiniband/drivers/infiniband/hw/ehca/ehca_mrmw.c 2006-08-30 18:02:01.000000000 +0200 +++ infiniband_work/drivers/infiniband/hw/ehca/ehca_mrmw.c 2006-08-30 20:00:16.000000000 +0200 @@ -46,14 +46,14 @@ #include "hcp_if.h" #include "hipz_hw.h" -extern int ehca_use_hp_mr; +static struct kmem_cache *mr_cache; +static struct kmem_cache *mw_cache; static struct ehca_mr *ehca_mr_new(void) { - extern struct ehca_module ehca_module; struct ehca_mr *me; - me = kmem_cache_alloc(ehca_module.cache_mr, SLAB_KERNEL); + me = kmem_cache_alloc(mr_cache, SLAB_KERNEL); if (me) { memset(me, 0, sizeof(struct ehca_mr)); spin_lock_init(&me->mrlock); @@ -65,17 +65,14 @@ static struct ehca_mr *ehca_mr_new(void) static void ehca_mr_delete(struct ehca_mr *me) { - extern struct ehca_module ehca_module; - - kmem_cache_free(ehca_module.cache_mr, me); + kmem_cache_free(mr_cache, me); } static struct ehca_mw *ehca_mw_new(void) { - extern struct ehca_module ehca_module; struct ehca_mw *me; - me = kmem_cache_alloc(ehca_module.cache_mw, SLAB_KERNEL); + me = kmem_cache_alloc(mw_cache, SLAB_KERNEL); if (me) { memset(me, 0, sizeof(struct ehca_mw)); spin_lock_init(&me->mwlock); @@ -87,9 +84,7 @@ static struct ehca_mw *ehca_mw_new(void) static void ehca_mw_delete(struct ehca_mw *me) { - extern struct ehca_module ehca_module; - - kmem_cache_free(ehca_module.cache_mw, me); + kmem_cache_free(mw_cache, me); } /*----------------------------------------------------------------------*/ @@ -2236,3 +2231,31 @@ void ehca_mr_deletenew(struct ehca_mr *m mr->nr_of_pages = 0; mr->pagearray = NULL; } /* end ehca_mr_deletenew() */ + +int ehca_init_mrmw_cache(void) +{ + mr_cache = kmem_cache_create("ehca_cache_mr", + sizeof(struct ehca_mr), 0, + SLAB_HWCACHE_ALIGN, + NULL, NULL); + if (!mr_cache) + return -ENOMEM; + mw_cache = kmem_cache_create("ehca_cache_mw", + sizeof(struct ehca_mw), 0, + SLAB_HWCACHE_ALIGN, + NULL, NULL); + if (!mw_cache) { + kmem_cache_destroy(mr_cache); + mr_cache = NULL; + return -ENOMEM; + } + return 0; +} + +void ehca_cleanup_mrmw_cache(void) +{ + if (mr_cache) + kmem_cache_destroy(mr_cache); + if (mw_cache) + kmem_cache_destroy(mw_cache); +} diff -Nurp infiniband/drivers/infiniband/hw/ehca/ehca_pd.c infiniband_work/drivers/infiniband/hw/ehca/ehca_pd.c --- infiniband/drivers/infiniband/hw/ehca/ehca_pd.c 2006-08-30 18:02:01.000000000 +0200 +++ infiniband_work/drivers/infiniband/hw/ehca/ehca_pd.c 2006-08-30 20:00:16.000000000 +0200 @@ -43,13 +43,14 @@ #include "ehca_tools.h" #include "ehca_iverbs.h" +static struct kmem_cache *pd_cache; + struct ib_pd *ehca_alloc_pd(struct ib_device *device, struct ib_ucontext *context, struct ib_udata *udata) { - extern struct ehca_module ehca_module; struct ehca_pd *pd; - pd = kmem_cache_alloc(ehca_module.cache_pd, SLAB_KERNEL); + pd = kmem_cache_alloc(pd_cache, SLAB_KERNEL); if (!pd) { ehca_err(device, "device=%p context=%p out of memory", device, context); @@ -79,7 +80,6 @@ struct ib_pd *ehca_alloc_pd(struct ib_de int ehca_dealloc_pd(struct ib_pd *pd) { - extern struct ehca_module ehca_module; u32 cur_pid = current->tgid; struct ehca_pd *my_pd = container_of(pd, struct ehca_pd, ib_pd); @@ -90,8 +90,25 @@ int ehca_dealloc_pd(struct ib_pd *pd) return -EINVAL; } - kmem_cache_free(ehca_module.cache_pd, + kmem_cache_free(pd_cache, container_of(pd, struct ehca_pd, ib_pd)); return 0; } + +int ehca_init_pd_cache(void) +{ + pd_cache = kmem_cache_create("ehca_cache_pd", + sizeof(struct ehca_pd), 0, + SLAB_HWCACHE_ALIGN, + NULL, NULL); + if (!pd_cache) + return -ENOMEM; + return 0; +} + +void ehca_cleanup_pd_cache(void) +{ + if (pd_cache) + kmem_cache_destroy(pd_cache); +} diff -Nurp infiniband/drivers/infiniband/hw/ehca/ehca_qp.c infiniband_work/drivers/infiniband/hw/ehca/ehca_qp.c --- infiniband/drivers/infiniband/hw/ehca/ehca_qp.c 2006-08-30 18:02:01.000000000 +0200 +++ infiniband_work/drivers/infiniband/hw/ehca/ehca_qp.c 2006-08-30 20:00:16.000000000 +0200 @@ -51,6 +51,8 @@ #include "hcp_if.h" #include "hipz_fns.h" +static struct kmem_cache *qp_cache; + /* * attributes not supported by query qp */ @@ -387,7 +389,6 @@ struct ib_qp *ehca_create_qp(struct ib_p struct ib_qp_init_attr *init_attr, struct ib_udata *udata) { - extern struct ehca_module ehca_module; static int da_rc_msg_size[]={ 128, 256, 512, 1024, 2048, 4096 }; static int da_ud_sq_msg_size[]={ 128, 384, 896, 1920, 3968 }; struct ehca_qp *my_qp; @@ -449,7 +450,7 @@ struct ib_qp *ehca_create_qp(struct ib_p if (pd->uobject && udata) context = pd->uobject->context; - my_qp = kmem_cache_alloc(ehca_module.cache_qp, SLAB_KERNEL); + my_qp = kmem_cache_alloc(qp_cache, SLAB_KERNEL); if (!my_qp) { ehca_err(pd->device, "pd=%p not enough memory to alloc qp", pd); return ERR_PTR(-ENOMEM); @@ -716,7 +717,7 @@ create_qp_exit1: spin_unlock_irqrestore(&ehca_qp_idr_lock, flags); create_qp_exit0: - kmem_cache_free(ehca_module.cache_qp, my_qp); + kmem_cache_free(qp_cache, my_qp); return ERR_PTR(ret); } @@ -728,7 +729,6 @@ create_qp_exit0: static int prepare_sqe_rts(struct ehca_qp *my_qp, struct ehca_shca *shca, int *bad_wqe_cnt) { - extern int ehca_debug_level; u64 h_ret; struct ipz_queue *squeue; void *bad_send_wqe_p, *bad_send_wqe_v; @@ -797,7 +797,6 @@ static int internal_modify_qp(struct ib_ struct ib_qp_attr *attr, int attr_mask, int smi_reset2init) { - extern int ehca_debug_level; enum ib_qp_state qp_cur_state, qp_new_state; int cnt, qp_attr_idx, ret = 0; enum ib_qp_statetrans statetrans; @@ -807,7 +806,7 @@ static int internal_modify_qp(struct ib_ container_of(ibqp->pd->device, struct ehca_shca, ib_device); u64 update_mask; u64 h_ret; - int bad_wqe_cnt; + int bad_wqe_cnt = 0; int squeue_locked = 0; unsigned long spl_flags = 0; @@ -1253,7 +1251,6 @@ int ehca_query_qp(struct ib_qp *qp, struct ib_qp_attr *qp_attr, int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr) { - extern int ehca_debug_level; struct ehca_qp *my_qp = container_of(qp, struct ehca_qp, ib_qp); struct ehca_pd *my_pd = container_of(my_qp->ib_qp.pd, struct ehca_pd, ib_pd); @@ -1410,7 +1407,6 @@ query_qp_exit1: int ehca_destroy_qp(struct ib_qp *ibqp) { - extern struct ehca_module ehca_module; struct ehca_qp *my_qp = container_of(ibqp, struct ehca_qp, ib_qp); struct ehca_shca *shca = container_of(ibqp->device, struct ehca_shca, ib_device); @@ -1488,6 +1484,23 @@ int ehca_destroy_qp(struct ib_qp *ibqp) ipz_queue_dtor(&my_qp->ipz_rqueue); ipz_queue_dtor(&my_qp->ipz_squeue); - kmem_cache_free(ehca_module.cache_qp, my_qp); + kmem_cache_free(qp_cache, my_qp); return 0; } + +int ehca_init_qp_cache(void) +{ + qp_cache = kmem_cache_create("ehca_cache_qp", + sizeof(struct ehca_qp), 0, + SLAB_HWCACHE_ALIGN, + NULL, NULL); + if (!qp_cache) + return -ENOMEM; + return 0; +} + +void ehca_cleanup_qp_cache(void) +{ + if (qp_cache) + kmem_cache_destroy(qp_cache); +} diff -Nurp infiniband/drivers/infiniband/hw/ehca/ehca_reqs.c infiniband_work/drivers/infiniband/hw/ehca/ehca_reqs.c --- infiniband/drivers/infiniband/hw/ehca/ehca_reqs.c 2006-08-30 18:02:01.000000000 +0200 +++ infiniband_work/drivers/infiniband/hw/ehca/ehca_reqs.c 2006-08-30 20:00:16.000000000 +0200 @@ -49,8 +49,6 @@ #include "hcp_if.h" #include "hipz_fns.h" -extern int ehca_debug_level; - static inline int ehca_write_rwqe(struct ipz_queue *ipz_rqueue, struct ehca_wqe *wqe_p, struct ib_recv_wr *recv_wr) diff -Nurp infiniband/drivers/infiniband/hw/ehca/ehca_sqp.c infiniband_work/drivers/infiniband/hw/ehca/ehca_sqp.c --- infiniband/drivers/infiniband/hw/ehca/ehca_sqp.c 2006-08-30 18:02:01.000000000 +0200 +++ infiniband_work/drivers/infiniband/hw/ehca/ehca_sqp.c 2006-08-30 20:00:16.000000000 +0200 @@ -49,8 +49,6 @@ #include "hcp_if.h" -extern int ehca_port_act_time; - /** * ehca_define_sqp - Defines special queue pair 1 (GSI QP). When special queue * pair is created successfully, the corresponding port gets active. diff -Nurp infiniband/drivers/infiniband/hw/ehca/hcp_if.c infiniband_work/drivers/infiniband/hw/ehca/hcp_if.c --- infiniband/drivers/infiniband/hw/ehca/hcp_if.c 2006-08-30 18:02:01.000000000 +0200 +++ infiniband_work/drivers/infiniband/hw/ehca/hcp_if.c 2006-08-30 20:00:17.000000000 +0200 @@ -410,7 +410,6 @@ u64 hipz_h_query_port(const struct ipz_a const u8 port_id, struct hipz_query_port *query_port_response_block) { - extern int ehca_debug_level; u64 ret; u64 dummy; u64 r_cb = virt_to_abs(query_port_response_block); diff -Nurp infiniband/drivers/infiniband/hw/ehca/hcp_phyp.h infiniband_work/drivers/infiniband/hw/ehca/hcp_phyp.h --- infiniband/drivers/infiniband/hw/ehca/hcp_phyp.h 2006-08-30 18:02:01.000000000 +0200 +++ infiniband_work/drivers/infiniband/hw/ehca/hcp_phyp.h 2006-08-30 20:00:16.000000000 +0200 @@ -69,13 +69,13 @@ struct h_galpas { static inline u64 hipz_galpa_load(struct h_galpa galpa, u32 offset) { u64 addr = galpa.fw_handle + offset; - return *(u64 *)addr; + return *(volatile u64 __force *)addr; } static inline void hipz_galpa_store(struct h_galpa galpa, u32 offset, u64 value) { u64 addr = galpa.fw_handle + offset; - *(u64 *)addr = value; + *(volatile u64 __force *)addr = value; } int hcp_galpas_ctor(struct h_galpas *galpas, diff -Nurp infiniband/drivers/infiniband/hw/ehca/ipz_pt_fn.c infiniband_work/drivers/infiniband/hw/ehca/ipz_pt_fn.c --- infiniband/drivers/infiniband/hw/ehca/ipz_pt_fn.c 2006-08-30 18:02:01.000000000 +0200 +++ infiniband_work/drivers/infiniband/hw/ehca/ipz_pt_fn.c 2006-08-30 20:00:16.000000000 +0200 @@ -41,8 +41,6 @@ #include "ehca_tools.h" #include "ipz_pt_fn.h" -extern int ehca_hwlevel; - void *ipz_qpageit_get_inc(struct ipz_queue *queue) { void *ret = ipz_qeit_get(queue); ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 01/13] IB/ehca: hca @ 2006-08-17 20:11 Roland Dreier 2006-08-17 20:11 ` [PATCH 02/13] IB/ehca: includes Roland Dreier 0 siblings, 1 reply; 7+ messages in thread From: Roland Dreier @ 2006-08-17 20:11 UTC (permalink / raw) To: openib-general, linux-kernel, linuxppc-dev; +Cc: RAISCH, HNGUYEN, MEDER drivers/infiniband/hw/ehca/ehca_hca.c | 282 +++++++++++++++++++++++++++++++ drivers/infiniband/hw/ehca/ehca_mcast.c | 200 ++++++++++++++++++++++ 2 files changed, 482 insertions(+), 0 deletions(-) diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c new file mode 100644 index 0000000..7a871b2 --- /dev/null +++ b/drivers/infiniband/hw/ehca/ehca_hca.c @@ -0,0 +1,282 @@ +/* + * IBM eServer eHCA Infiniband device driver for Linux on POWER + * + * HCA query functions + * + * Authors: Heiko J Schick <schickhj@de•ibm.com> + * Christoph Raisch <raisch@de•ibm.com> + * + * Copyright (c) 2005 IBM Corporation + * + * All rights reserved. + * + * This source code is distributed under a dual license of GPL v2.0 and OpenIB + * BSD. + * + * OpenIB BSD License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#undef DEB_PREFIX +#define DEB_PREFIX "shca" + +#include "ehca_tools.h" + +#include "hcp_if.h" + +int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) +{ + int ret = 0; + struct ehca_shca *shca; + struct hipz_query_hca *rblock; + + EDEB_EN(7, ""); + + memset(props, 0, sizeof(struct ib_device_attr)); + shca = container_of(ibdev, struct ehca_shca, ib_device); + + rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + if (!rblock) { + EDEB_ERR(4, "Can't allocate rblock memory."); + ret = -ENOMEM; + goto query_device0; + } + + if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) { + EDEB_ERR(4, "Can't query device properties"); + ret = -EINVAL; + goto query_device1; + } + props->fw_ver = rblock->hw_ver; + props->max_mr_size = rblock->max_mr_size; + props->vendor_id = rblock->vendor_id >> 8; + props->vendor_part_id = rblock->vendor_part_id >> 16; + props->hw_ver = rblock->hw_ver; + props->max_qp = min_t(int, rblock->max_qp, INT_MAX); + props->max_qp_wr = min_t(int, rblock->max_wqes_wq, INT_MAX); + props->max_sge = min_t(int, rblock->max_sge, INT_MAX); + props->max_sge_rd = min_t(int, rblock->max_sge_rd, INT_MAX); + props->max_cq = min_t(int, rblock->max_cq, INT_MAX); + props->max_cqe = min_t(int, rblock->max_cqe, INT_MAX); + props->max_mr = min_t(int, rblock->max_mr, INT_MAX); + props->max_mw = min_t(int, rblock->max_mw, INT_MAX); + props->max_pd = min_t(int, rblock->max_pd, INT_MAX); + props->max_ah = min_t(int, rblock->max_ah, INT_MAX); + props->max_fmr = min_t(int, rblock->max_mr, INT_MAX); + props->max_srq = 0; + props->max_srq_wr = 0; + props->max_srq_sge = 0; + props->max_pkeys = 16; + props->local_ca_ack_delay + = rblock->local_ca_ack_delay; + props->max_raw_ipv6_qp + = min_t(int, rblock->max_raw_ipv6_qp, INT_MAX); + props->max_raw_ethy_qp + = min_t(int, rblock->max_raw_ethy_qp, INT_MAX); + props->max_mcast_grp + = min_t(int, rblock->max_mcast_grp, INT_MAX); + props->max_mcast_qp_attach + = min_t(int, rblock->max_mcast_qp_attach, INT_MAX); + props->max_total_mcast_qp_attach + = min_t(int, rblock->max_total_mcast_qp_attach, INT_MAX); + +query_device1: + kfree(rblock); + +query_device0: + EDEB_EX(7, "ret=%x", ret); + + return ret; +} + +int ehca_query_port(struct ib_device *ibdev, + u8 port, struct ib_port_attr *props) +{ + int ret = 0; + struct ehca_shca *shca; + struct hipz_query_port *rblock; + + EDEB_EN(7, "port=%x", port); + + memset(props, 0, sizeof(struct ib_port_attr)); + shca = container_of(ibdev, struct ehca_shca, ib_device); + + rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + if (!rblock) { + EDEB_ERR(4, "Can't allocate rblock memory."); + ret = -ENOMEM; + goto query_port0; + } + + if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) { + EDEB_ERR(4, "Can't query port properties"); + ret = -EINVAL; + goto query_port1; + } + + props->state = rblock->state; + + switch (rblock->max_mtu) { + case 0x1: + props->active_mtu = props->max_mtu = IB_MTU_256; + break; + case 0x2: + props->active_mtu = props->max_mtu = IB_MTU_512; + break; + case 0x3: + props->active_mtu = props->max_mtu = IB_MTU_1024; + break; + case 0x4: + props->active_mtu = props->max_mtu = IB_MTU_2048; + break; + case 0x5: + props->active_mtu = props->max_mtu = IB_MTU_4096; + break; + default: + EDEB_ERR(4, "Unknown MTU size: %x.", rblock->max_mtu); + } + + props->gid_tbl_len = rblock->gid_tbl_len; + props->max_msg_sz = rblock->max_msg_sz; + props->bad_pkey_cntr = rblock->bad_pkey_cntr; + props->qkey_viol_cntr = rblock->qkey_viol_cntr; + props->pkey_tbl_len = rblock->pkey_tbl_len; + props->lid = rblock->lid; + props->sm_lid = rblock->sm_lid; + props->lmc = rblock->lmc; + props->sm_sl = rblock->sm_sl; + props->subnet_timeout = rblock->subnet_timeout; + props->init_type_reply = rblock->init_type_reply; + + props->active_width = IB_WIDTH_12X; + props->active_speed = 0x1; + +query_port1: + kfree(rblock); + +query_port0: + EDEB_EX(7, "ret=%x", ret); + + return ret; +} + +int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey) +{ + int ret = 0; + struct ehca_shca *shca; + struct hipz_query_port *rblock; + + EDEB_EN(7, "port=%x index=%x", port, index); + + if (index > 16) { + EDEB_ERR(4, "Invalid index: %x.", index); + ret = -EINVAL; + goto query_pkey0; + } + + shca = container_of(ibdev, struct ehca_shca, ib_device); + + rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + if (!rblock) { + EDEB_ERR(4, "Can't allocate rblock memory."); + ret = -ENOMEM; + goto query_pkey0; + } + + if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) { + EDEB_ERR(4, "Can't query port properties"); + ret = -EINVAL; + goto query_pkey1; + } + + memcpy(pkey, &rblock->pkey_entries + index, sizeof(u16)); + +query_pkey1: + kfree(rblock); + +query_pkey0: + EDEB_EX(7, "ret=%x", ret); + + return ret; +} + +int ehca_query_gid(struct ib_device *ibdev, u8 port, + int index, union ib_gid *gid) +{ + int ret = 0; + struct ehca_shca *shca; + struct hipz_query_port *rblock; + + EDEB_EN(7, "port=%x index=%x", port, index); + + if (index > 255) { + EDEB_ERR(4, "Invalid index: %x.", index); + ret = -EINVAL; + goto query_gid0; + } + + shca = container_of(ibdev, struct ehca_shca, ib_device); + + rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + if (!rblock) { + EDEB_ERR(4, "Can't allocate rblock memory."); + ret = -ENOMEM; + goto query_gid0; + } + + if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) { + EDEB_ERR(4, "Can't query port properties"); + ret = -EINVAL; + goto query_gid1; + } + + memcpy(&gid->raw[0], &rblock->gid_prefix, sizeof(u64)); + memcpy(&gid->raw[8], &rblock->guid_entries[index], sizeof(u64)); + +query_gid1: + kfree(rblock); + +query_gid0: + EDEB_EX(7, "ret=%x GID=%lx%lx", ret, + *(u64 *) & gid->raw[0], + *(u64 *) & gid->raw[8]); + + return ret; +} + +int ehca_modify_port(struct ib_device *ibdev, + u8 port, int port_modify_mask, + struct ib_port_modify *props) +{ + int ret = 0; + + EDEB_EN(7, "port=%x", port); + + /* Not implemented yet. */ + + EDEB_EX(7, "ret=%x", ret); + + return ret; +} diff --git a/drivers/infiniband/hw/ehca/ehca_mcast.c b/drivers/infiniband/hw/ehca/ehca_mcast.c new file mode 100644 index 0000000..5c5b024 --- /dev/null +++ b/drivers/infiniband/hw/ehca/ehca_mcast.c @@ -0,0 +1,200 @@ +/* + * IBM eServer eHCA Infiniband device driver for Linux on POWER + * + * mcast functions + * + * Authors: Khadija Souissi <souissik@de•ibm.com> + * Waleri Fomin <fomin@de•ibm.com> + * Reinhard Ernst <rernst@de•ibm.com> + * Hoang-Nam Nguyen <hnguyen@de•ibm.com> + * Heiko J Schick <schickhj@de•ibm.com> + * + * Copyright (c) 2005 IBM Corporation + * + * All rights reserved. + * + * This source code is distributed under a dual license of GPL v2.0 and OpenIB + * BSD. + * + * OpenIB BSD License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#define DEB_PREFIX "mcas" + +#include <linux/module.h> +#include <linux/err.h> +#include "ehca_classes.h" +#include "ehca_tools.h" +#include "ehca_qes.h" +#include "ehca_iverbs.h" + +#include "hcp_if.h" + +#define MAX_MC_LID 0xFFFE +#define MIN_MC_LID 0xC000 /* Multicast limits */ +#define EHCA_VALID_MULTICAST_GID(gid) ((gid)[0] == 0xFF) +#define EHCA_VALID_MULTICAST_LID(lid) (((lid) >= MIN_MC_LID) && ((lid) <= MAX_MC_LID)) + +int ehca_attach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) +{ + struct ehca_qp *my_qp = NULL; + struct ehca_shca *shca = NULL; + union ib_gid my_gid; + u64 subnet_prefix; + u64 interface_id; + u64 h_ret = H_SUCCESS; + int ret = 0; + + EHCA_CHECK_ADR(ibqp); + EHCA_CHECK_ADR(gid); + + my_qp = container_of(ibqp, struct ehca_qp, ib_qp); + + EHCA_CHECK_QP(my_qp); + if (ibqp->qp_type != IB_QPT_UD) { + EDEB_ERR(4, "invalid qp_type %x gid, ret=%x", + ibqp->qp_type, EINVAL); + return -EINVAL; + } + + shca = container_of(ibqp->pd->device, struct ehca_shca, ib_device); + EHCA_CHECK_ADR(shca); + + if (!(EHCA_VALID_MULTICAST_GID(gid->raw))) { + EDEB_ERR(4, "gid is not valid mulitcast gid ret=%x", + EINVAL); + return -EINVAL; + } else if ((lid < MIN_MC_LID) || (lid > MAX_MC_LID)) { + EDEB_ERR(4, "lid=%x is not valid mulitcast lid ret=%x", + lid, EINVAL); + return -EINVAL; + } + + memcpy(&my_gid.raw, gid->raw, sizeof(union ib_gid)); + + subnet_prefix = be64_to_cpu(my_gid.global.subnet_prefix); + interface_id = be64_to_cpu(my_gid.global.interface_id); + h_ret = hipz_h_attach_mcqp(shca->ipz_hca_handle, + my_qp->ipz_qp_handle, + my_qp->galpas.kernel, + lid, subnet_prefix, interface_id); + if (h_ret != H_SUCCESS) { + EDEB_ERR(4, + "ehca_qp=%p qp_num=%x hipz_h_attach_mcqp() failed " + "h_ret=%lx", my_qp, ibqp->qp_num, h_ret); + } + ret = ehca2ib_return_code(h_ret); + + EDEB_EX(7, "mcast attach ret=%x\n" + "ehca_qp=%p qp_num=%x lid=%x\n" + "my_gid= %x %x %x %x\n" + " %x %x %x %x\n" + " %x %x %x %x\n" + " %x %x %x %x\n", + ret, my_qp, ibqp->qp_num, lid, + my_gid.raw[0], my_gid.raw[1], + my_gid.raw[2], my_gid.raw[3], + my_gid.raw[4], my_gid.raw[5], + my_gid.raw[6], my_gid.raw[7], + my_gid.raw[8], my_gid.raw[9], + my_gid.raw[10], my_gid.raw[11], + my_gid.raw[12], my_gid.raw[13], + my_gid.raw[14], my_gid.raw[15]); + + return ret; +} + +int ehca_detach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) +{ + struct ehca_qp *my_qp = NULL; + struct ehca_shca *shca = NULL; + union ib_gid my_gid; + u64 subnet_prefix; + u64 interface_id; + u64 h_ret = H_SUCCESS; + int ret = 0; + + EHCA_CHECK_ADR(ibqp); + EHCA_CHECK_ADR(gid); + + my_qp = container_of(ibqp, struct ehca_qp, ib_qp); + + EHCA_CHECK_QP(my_qp); + if (ibqp->qp_type != IB_QPT_UD) { + EDEB_ERR(4, "invalid qp_type %x gid, ret=%x", + ibqp->qp_type, EINVAL); + return -EINVAL; + } + + shca = container_of(ibqp->pd->device, struct ehca_shca, ib_device); + EHCA_CHECK_ADR(shca); + + if (!(EHCA_VALID_MULTICAST_GID(gid->raw))) { + EDEB_ERR(4, "gid is not valid mulitcast gid ret=%x", + EINVAL); + return -EINVAL; + } else if ((lid < MIN_MC_LID) || (lid > MAX_MC_LID)) { + EDEB_ERR(4, "lid=%x is not valid mulitcast lid ret=%x", + lid, EINVAL); + return -EINVAL; + } + + EDEB_EN(7, "dgid=%p qp_numl=%x lid=%x", + gid, ibqp->qp_num, lid); + + memcpy(&my_gid.raw, gid->raw, sizeof(union ib_gid)); + + subnet_prefix = be64_to_cpu(my_gid.global.subnet_prefix); + interface_id = be64_to_cpu(my_gid.global.interface_id); + h_ret = hipz_h_detach_mcqp(shca->ipz_hca_handle, + my_qp->ipz_qp_handle, + my_qp->galpas.kernel, + lid, subnet_prefix, interface_id); + if (h_ret != H_SUCCESS) { + EDEB_ERR(4, + "ehca_qp=%p qp_num=%x hipz_h_detach_mcqp() failed " + "h_ret=%lx", my_qp, ibqp->qp_num, h_ret); + } + ret = ehca2ib_return_code(h_ret); + + EDEB_EX(7, "mcast detach ret=%x\n" + "ehca_qp=%p qp_num=%x lid=%x\n" + "my_gid= %x %x %x %x\n" + " %x %x %x %x\n" + " %x %x %x %x\n" + " %x %x %x %x\n", + ret, my_qp, ibqp->qp_num, lid, + my_gid.raw[0], my_gid.raw[1], + my_gid.raw[2], my_gid.raw[3], + my_gid.raw[4], my_gid.raw[5], + my_gid.raw[6], my_gid.raw[7], + my_gid.raw[8], my_gid.raw[9], + my_gid.raw[10], my_gid.raw[11], + my_gid.raw[12], my_gid.raw[13], + my_gid.raw[14], my_gid.raw[15]); + + return ret; +} -- 1.4.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 02/13] IB/ehca: includes 2006-08-17 20:11 [PATCH 01/13] IB/ehca: hca Roland Dreier @ 2006-08-17 20:11 ` Roland Dreier 2006-08-17 23:44 ` Arnd Bergmann 0 siblings, 1 reply; 7+ messages in thread From: Roland Dreier @ 2006-08-17 20:11 UTC (permalink / raw) To: openib-general, linux-kernel, linuxppc-dev; +Cc: RAISCH, HNGUYEN, MEDER drivers/infiniband/hw/ehca/ehca_iverbs.h | 181 +++++++++++++ drivers/infiniband/hw/ehca/ehca_tools.h | 417 ++++++++++++++++++++++++++++++ 2 files changed, 598 insertions(+), 0 deletions(-) diff --git a/drivers/infiniband/hw/ehca/ehca_iverbs.h b/drivers/infiniband/hw/ehca/ehca_iverbs.h new file mode 100644 index 0000000..bbdc437 --- /dev/null +++ b/drivers/infiniband/hw/ehca/ehca_iverbs.h @@ -0,0 +1,181 @@ +/* + * IBM eServer eHCA Infiniband device driver for Linux on POWER + * + * Function definitions for internal functions + * + * Authors: Heiko J Schick <schickhj@de•ibm.com> + * Dietmar Decker <ddecker@de•ibm.com> + * + * Copyright (c) 2005 IBM Corporation + * + * All rights reserved. + * + * This source code is distributed under a dual license of GPL v2.0 and OpenIB + * BSD. + * + * OpenIB BSD License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __EHCA_IVERBS_H__ +#define __EHCA_IVERBS_H__ + +#include "ehca_classes.h" + +int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props); + +int ehca_query_port(struct ib_device *ibdev, u8 port, + struct ib_port_attr *props); + +int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 * pkey); + +int ehca_query_gid(struct ib_device *ibdev, u8 port, int index, + union ib_gid *gid); + +int ehca_modify_port(struct ib_device *ibdev, u8 port, int port_modify_mask, + struct ib_port_modify *props); + +struct ib_pd *ehca_alloc_pd(struct ib_device *device, + struct ib_ucontext *context, + struct ib_udata *udata); + +int ehca_dealloc_pd(struct ib_pd *pd); + +struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr); + +int ehca_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr); + +int ehca_query_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr); + +int ehca_destroy_ah(struct ib_ah *ah); + +struct ib_mr *ehca_get_dma_mr(struct ib_pd *pd, int mr_access_flags); + +struct ib_mr *ehca_reg_phys_mr(struct ib_pd *pd, + struct ib_phys_buf *phys_buf_array, + int num_phys_buf, + int mr_access_flags, u64 *iova_start); + +struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, + struct ib_umem *region, + int mr_access_flags, struct ib_udata *udata); + +int ehca_rereg_phys_mr(struct ib_mr *mr, + int mr_rereg_mask, + struct ib_pd *pd, + struct ib_phys_buf *phys_buf_array, + int num_phys_buf, int mr_access_flags, u64 *iova_start); + +int ehca_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr); + +int ehca_dereg_mr(struct ib_mr *mr); + +struct ib_mw *ehca_alloc_mw(struct ib_pd *pd); + +int ehca_bind_mw(struct ib_qp *qp, struct ib_mw *mw, + struct ib_mw_bind *mw_bind); + +int ehca_dealloc_mw(struct ib_mw *mw); + +struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd, + int mr_access_flags, + struct ib_fmr_attr *fmr_attr); + +int ehca_map_phys_fmr(struct ib_fmr *fmr, + u64 *page_list, int list_len, u64 iova); + +int ehca_unmap_fmr(struct list_head *fmr_list); + +int ehca_dealloc_fmr(struct ib_fmr *fmr); + +enum ehca_eq_type { + EHCA_EQ = 0, /* Event Queue */ + EHCA_NEQ /* Notification Event Queue */ +}; + +int ehca_create_eq(struct ehca_shca *shca, struct ehca_eq *eq, + enum ehca_eq_type type, const u32 length); + +int ehca_destroy_eq(struct ehca_shca *shca, struct ehca_eq *eq); + +void *ehca_poll_eq(struct ehca_shca *shca, struct ehca_eq *eq); + + +struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, + struct ib_ucontext *context, + struct ib_udata *udata); + +int ehca_destroy_cq(struct ib_cq *cq); + +int ehca_resize_cq(struct ib_cq *cq, int cqe, struct ib_udata *udata); + +int ehca_poll_cq(struct ib_cq *cq, int num_entries, struct ib_wc *wc); + +int ehca_peek_cq(struct ib_cq *cq, int wc_cnt); + +int ehca_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify cq_notify); + +struct ib_qp *ehca_create_qp(struct ib_pd *pd, + struct ib_qp_init_attr *init_attr, + struct ib_udata *udata); + +int ehca_destroy_qp(struct ib_qp *qp); + +int ehca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask); + +int ehca_query_qp(struct ib_qp *qp, struct ib_qp_attr *qp_attr, + int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr); + +int ehca_post_send(struct ib_qp *qp, struct ib_send_wr *send_wr, + struct ib_send_wr **bad_send_wr); + +int ehca_post_recv(struct ib_qp *qp, struct ib_recv_wr *recv_wr, + struct ib_recv_wr **bad_recv_wr); + +u64 ehca_define_sqp(struct ehca_shca *shca, struct ehca_qp *ibqp, + struct ib_qp_init_attr *qp_init_attr); + +int ehca_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid); + +int ehca_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid); + +struct ib_ucontext *ehca_alloc_ucontext(struct ib_device *device, + struct ib_udata *udata); + +int ehca_dealloc_ucontext(struct ib_ucontext *context); + +int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma); + +void ehca_poll_eqs(unsigned long data); + +int ehca_mmap_nopage(u64 foffset,u64 length,void **mapped, + struct vm_area_struct **vma); + +int ehca_mmap_register(u64 physical,void **mapped, + struct vm_area_struct **vma); + +int ehca_munmap(unsigned long addr, size_t len); + +#endif diff --git a/drivers/infiniband/hw/ehca/ehca_tools.h b/drivers/infiniband/hw/ehca/ehca_tools.h new file mode 100644 index 0000000..783fbb3 --- /dev/null +++ b/drivers/infiniband/hw/ehca/ehca_tools.h @@ -0,0 +1,417 @@ +/* + * IBM eServer eHCA Infiniband device driver for Linux on POWER + * + * auxiliary functions + * + * Authors: Christoph Raisch <raisch@de•ibm.com> + * Hoang-Nam Nguyen <hnguyen@de•ibm.com> + * Khadija Souissi <souissik@de•ibm.com> + * Waleri Fomin <fomin@de•ibm.com> + * Heiko J Schick <schickhj@de•ibm.com> + * + * Copyright (c) 2005 IBM Corporation + * + * This source code is distributed under a dual license of GPL v2.0 and OpenIB + * BSD. + * + * OpenIB BSD License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef EHCA_TOOLS_H +#define EHCA_TOOLS_H + +#include <linux/kernel.h> +#include <linux/spinlock.h> +#include <linux/delay.h> +#include <linux/idr.h> +#include <linux/kthread.h> +#include <linux/mm.h> +#include <linux/mman.h> +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/vmalloc.h> +#include <linux/version.h> +#include <linux/notifier.h> +#include <linux/cpu.h> + +#include <asm/abs_addr.h> +#include <asm/ibmebus.h> +#include <asm/io.h> +#include <asm/pgtable.h> + +#define EHCA_EDEB_TRACE_MASK_SIZE 32 +extern u8 ehca_edeb_mask[EHCA_EDEB_TRACE_MASK_SIZE]; +#define EDEB_ID_TO_U32(str4) (str4[3] | (str4[2] << 8) | (str4[1] << 16) | \ + (str4[0] << 24)) + +static inline u64 ehca_edeb_filter(const u32 level, + const u32 id, const u32 line) +{ + u64 ret = 0; + u32 filenr = 0; + u32 filter_level = 9; + u32 dynamic_level = 0; + + /* + * This is code written for the gcc -O2 optimizer + * which should collapse to two single ints. + * Filter_level is the first level kicked out by + * compiler and means trace everything below 6. + */ + + if (id == EDEB_ID_TO_U32("ehav")) { + filenr = 0x01; + filter_level = 8; + } + if (id == EDEB_ID_TO_U32("clas")) { + filenr = 0x02; + filter_level = 8; + } + if (id == EDEB_ID_TO_U32("cqeq")) { + filenr = 0x03; + filter_level = 8; + } + if (id == EDEB_ID_TO_U32("shca")) { + filenr = 0x05; + filter_level = 8; + } + if (id == EDEB_ID_TO_U32("eirq")) { + filenr = 0x06; + filter_level = 8; + } + if (id == EDEB_ID_TO_U32("lMad")) { + filenr = 0x07; + filter_level = 8; + } + if (id == EDEB_ID_TO_U32("mcas")) { + filenr = 0x08; + filter_level = 8; + } + if (id == EDEB_ID_TO_U32("mrmw")) { + filenr = 0x09; + filter_level = 8; + } + if (id == EDEB_ID_TO_U32("vpd ")) { + filenr = 0x0a; + filter_level = 8; + } + if (id == EDEB_ID_TO_U32("e_qp")) { + filenr = 0x0b; + filter_level = 8; + } + if (id == EDEB_ID_TO_U32("uqes")) { + filenr = 0x0c; + filter_level = 8; + } + if (id == EDEB_ID_TO_U32("PHYP")) { + filenr = 0x0d; + filter_level = 8; + } + if (id == EDEB_ID_TO_U32("hcpi")) { + filenr = 0x0e; + filter_level = 8; + } + if (id == EDEB_ID_TO_U32("iptz")) { + filenr = 0x0f; + filter_level = 8; + } + if (id == EDEB_ID_TO_U32("spta")) { + filenr = 0x10; + filter_level = 8; + } + if (id == EDEB_ID_TO_U32("simp")) { + filenr = 0x11; + filter_level = 8; + } + if (id == EDEB_ID_TO_U32("reqs")) { + filenr = 0x12; + filter_level = 8; + } + + if ((filenr - 1) > sizeof(ehca_edeb_mask)) { + filenr = 0; + } + + if (filenr == 0) { + filter_level = 9; + } /* default */ + ret = filenr * 0x10000 + line; + if (filter_level <= level) { + return ret | 0x100000000L; /* this is the flag to not trace */ + } + dynamic_level = ehca_edeb_mask[filenr]; + if (likely(dynamic_level <= level)) { + ret = ret | 0x100000000L; + }; + return ret; +} + +#ifdef EHCA_USE_HCALL_KERNEL +#ifdef CONFIG_PPC_PSERIES + +#include <asm/paca.h> + +/* + * IS_EDEB_ON - Checks if debug is on for the given level. + */ +#define IS_EDEB_ON(level) \ +((ehca_edeb_filter(level, EDEB_ID_TO_U32(DEB_PREFIX), __LINE__) & \ + 0x100000000L) == 0) + +#define EDEB_P_GENERIC(level,idstring,format,args...) \ +do { \ + u64 ehca_edeb_filterresult = \ + ehca_edeb_filter(level, EDEB_ID_TO_U32(DEB_PREFIX), __LINE__);\ + if ((ehca_edeb_filterresult & 0x100000000L) == 0) \ + printk("PU%04x %08x:%s " idstring " "format "\n", \ + get_paca()->paca_index, (u32)(ehca_edeb_filterresult), \ + __func__, ##args); \ +} while (1 == 0) + +#elif REAL_HCALL + +#define EDEB_P_GENERIC(level,idstring,format,args...) \ +do { \ + u64 ehca_edeb_filterresult = \ + ehca_edeb_filter(level, EDEB_ID_TO_U32(DEB_PREFIX), __LINE__); \ + if ((ehca_edeb_filterresult & 0x100000000L) == 0) \ + printk("%08x:%s " idstring " "format "\n", \ + (u32)(ehca_edeb_filterresult), \ + __func__, ##args); \ +} while (1 == 0) + +#endif +#else + +#define IS_EDEB_ON(level) (1) + +#define EDEB_P_GENERIC(level,idstring,format,args...) \ +do { \ + printk("%s " idstring " "format "\n", \ + __func__, ##args); \ +} while (1 == 0) + +#endif + +/** + * EDEB - Trace output macro. + * @level: tracelevel + * @format: optional format string, use "" if not desired + * @args: printf like arguments for trace + */ +#define EDEB(level,format,args...) \ + EDEB_P_GENERIC(level,"",format,##args) +#define EDEB_ERR(level,format,args...) \ + EDEB_P_GENERIC(level,"HCAD_ERROR ",format,##args) +#define EDEB_EN(level,format,args...) \ + EDEB_P_GENERIC(level,">>>",format,##args) +#define EDEB_EX(level,format,args...) \ + EDEB_P_GENERIC(level,"<<<",format,##args) + +/** + * EDEB_DMP - macro to dump a memory block, whose length is n*8 bytes. + * Each line has the following layout: + * <format string> adr=X ofs=Y <8 bytes hex> <8 bytes hex> + */ +#define EDEB_DMP(level,adr,len,format,args...) \ + do { \ + unsigned int x; \ + unsigned int l = (unsigned int)(len); \ + unsigned char *deb = (unsigned char*)(adr); \ + for (x = 0; x < l; x += 16) { \ + EDEB(level, format " adr=%p ofs=%04x %016lx %016lx", \ + ##args, deb, x, \ + *((u64 *)&deb[0]), *((u64 *)&deb[8])); \ + deb += 16; \ + } \ + } while (0) + +/* define a bitmask, little endian version */ +#define EHCA_BMASK(pos,length) (((pos)<<16)+(length)) + +/* define a bitmask, the ibm way... */ +#define EHCA_BMASK_IBM(from,to) (((63-to)<<16)+((to)-(from)+1)) + +/* internal function, don't use */ +#define EHCA_BMASK_SHIFTPOS(mask) (((mask)>>16)&0xffff) + +/* internal function, don't use */ +#define EHCA_BMASK_MASK(mask) (0xffffffffffffffffULL >> ((64-(mask))&0xffff)) + +/** + * EHCA_BMASK_SET - return value shifted and masked by mask + * variable|=EHCA_BMASK_SET(MY_MASK,0x4711) ORs the bits in variable + * variable&=~EHCA_BMASK_SET(MY_MASK,-1) clears the bits from the mask + * in variable + */ +#define EHCA_BMASK_SET(mask,value) \ + ((EHCA_BMASK_MASK(mask) & ((u64)(value)))<<EHCA_BMASK_SHIFTPOS(mask)) + +/** + * EHCA_BMASK_GET - extract a parameter from value by mask + */ +#define EHCA_BMASK_GET(mask,value) \ + ( EHCA_BMASK_MASK(mask)& (((u64)(value))>>EHCA_BMASK_SHIFTPOS(mask))) + +#define PARANOIA_MODE +#ifdef PARANOIA_MODE + +#define EHCA_CHECK_ADR_P(adr) \ + if (unlikely(adr == 0)) { \ + EDEB_ERR(4, "adr=%p check failed line %i", adr, \ + __LINE__); \ + return ERR_PTR(-EFAULT); } + +#define EHCA_CHECK_ADR(adr) \ + if (unlikely(adr == 0)) { \ + EDEB_ERR(4, "adr=%p check failed line %i", adr, \ + __LINE__); \ + return -EFAULT; } + +#define EHCA_CHECK_DEVICE_P(device) \ + if (unlikely(device == 0)) { \ + EDEB_ERR(4, "device=%p check failed", device); \ + return ERR_PTR(-EFAULT); } + +#define EHCA_CHECK_DEVICE(device) \ + if (unlikely(device == 0)) { \ + EDEB_ERR(4, "device=%p check failed", device); \ + return -EFAULT; } + +#define EHCA_CHECK_PD(pd) \ + if (unlikely(pd == 0)) { \ + EDEB_ERR(4, "pd=%p check failed", pd); \ + return -EFAULT; } + +#define EHCA_CHECK_PD_P(pd) \ + if (unlikely(pd == 0)) { \ + EDEB_ERR(4, "pd=%p check failed", pd); \ + return ERR_PTR(-EFAULT); } + +#define EHCA_CHECK_AV(av) \ + if (unlikely(av == 0)) { \ + EDEB_ERR(4, "av=%p check failed", av); \ + return -EFAULT; } + +#define EHCA_CHECK_AV_P(av) \ + if (unlikely(av == 0)) { \ + EDEB_ERR(4, "av=%p check failed", av); \ + return ERR_PTR(-EFAULT); } + +#define EHCA_CHECK_CQ(cq) \ + if (unlikely(cq == 0)) { \ + EDEB_ERR(4, "cq=%p check failed", cq); \ + return -EFAULT; } + +#define EHCA_CHECK_CQ_P(cq) \ + if (unlikely(cq == 0)) { \ + EDEB_ERR(4, "cq=%p check failed", cq); \ + return ERR_PTR(-EFAULT); } + +#define EHCA_CHECK_EQ(eq) \ + if (unlikely(eq == 0)) { \ + EDEB_ERR(4, "eq=%p check failed", eq); \ + return -EFAULT; } + +#define EHCA_CHECK_EQ_P(eq) \ + if (unlikely(eq == 0)) { \ + EDEB_ERR(4, "eq=%p check failed", eq); \ + return ERR_PTR(-EFAULT); } + +#define EHCA_CHECK_QP(qp) \ + if (unlikely(qp == 0)) { \ + EDEB_ERR(4, "qp=%p check failed", qp); \ + return -EFAULT; } + +#define EHCA_CHECK_QP_P(qp) \ + if (unlikely(qp == 0)) { \ + EDEB_ERR(4, "qp=%p check failed", qp); \ + return ERR_PTR(-EFAULT); } + +#define EHCA_CHECK_MR(mr) \ + if (unlikely(mr == 0)) { \ + EDEB_ERR(4, "mr=%p check failed", mr); \ + return -EFAULT; } + +#define EHCA_CHECK_MR_P(mr) \ + if (unlikely(mr == 0)) { \ + EDEB_ERR(4, "mr=%p check failed", mr); \ + return ERR_PTR(-EFAULT); } + +#define EHCA_CHECK_MW(mw) \ + if (unlikely(mw == 0)) { \ + EDEB_ERR(4, "mw=%p check failed", mw); \ + return -EFAULT; } + +#define EHCA_CHECK_MW_P(mw) \ + if (unlikely(mw == 0)) { \ + EDEB_ERR(4, "mw=%p check failed", mw); \ + return ERR_PTR(-EFAULT); } + +#define EHCA_CHECK_FMR(fmr) \ + if (unlikely(fmr == 0)) { \ + EDEB_ERR(4, "fmr=%p check failed", fmr); \ + return -EFAULT; } + +#define EHCA_CHECK_FMR_P(fmr) \ + if (unlikely(fmr == 0)) { \ + EDEB_ERR(4, "fmr=%p check failed", fmr); \ + return ERR_PTR(-EFAULT); } + +#define EHCA_REGISTER_PD(device,pd) +#define EHCA_REGISTER_AV(pd,av) +#define EHCA_DEREGISTER_PD(PD) +#define EHCA_DEREGISTER_AV(av) +#else +#define EHCA_CHECK_DEVICE_P(device) + +#define EHCA_CHECK_PD(pd) +#define EHCA_REGISTER_PD(device,pd) +#define EHCA_DEREGISTER_PD(PD) +#endif + +static inline int ehca_adr_bad(void *adr) +{ + return !adr; +} + +/* Converts ehca to ib return code */ +static inline int ehca2ib_return_code(u64 ehca_rc) +{ + switch (ehca_rc) { + case H_SUCCESS: + return 0; + case H_BUSY: + return -EBUSY; + case H_NO_MEM: + return -ENOMEM; + default: + return -EINVAL; + } +} + +#endif /* EHCA_TOOLS_H */ -- 1.4.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 02/13] IB/ehca: includes 2006-08-17 20:11 ` [PATCH 02/13] IB/ehca: includes Roland Dreier @ 2006-08-17 23:44 ` Arnd Bergmann 2006-08-18 15:35 ` Christoph Raisch 0 siblings, 1 reply; 7+ messages in thread From: Arnd Bergmann @ 2006-08-17 23:44 UTC (permalink / raw) To: linuxppc-dev; +Cc: linux-kernel, openib-general, RAISCH, HNGUYEN, MEDER T24gVGh1cnNkYXkgMTcgQXVndXN0IDIwMDYgMjI6MTEsIFJvbGFuZCBEcmVpZXIgd3JvdGU6Cj4g KyAqIElTX0VERUJfT04gLSBDaGVja3MgaWYgZGVidWcgaXMgb24gZm9yIHRoZSBnaXZlbiBsZXZl bC4KPiArICovCj4gKyNkZWZpbmUgSVNfRURFQl9PTihsZXZlbCkgXAo+ICsoKGVoY2FfZWRlYl9m aWx0ZXIobGV2ZWwsIEVERUJfSURfVE9fVTMyKERFQl9QUkVGSVgpLCBfX0xJTkVfXykgJiBcCj4g KyCgMHgxMDAwMDAwMDBMKSA9PSAwKQo+ICsKPiArI2RlZmluZSBFREVCX1BfR0VORVJJQyhsZXZl bCxpZHN0cmluZyxmb3JtYXQsYXJncy4uLikgXAo+ICtkbyB7IFwKPiAroKCgoKCgoHU2NCBlaGNh X2VkZWJfZmlsdGVycmVzdWx0ID2goKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKBc Cj4gK6CgoKCgoKCgoKCgoKCgoGVoY2FfZWRlYl9maWx0ZXIobGV2ZWwsIEVERUJfSURfVE9fVTMy KERFQl9QUkVGSVgpLCBfX0xJTkVfXyk7XAo+ICugoKCgoKCgaWYgKChlaGNhX2VkZWJfZmlsdGVy cmVzdWx0ICYgMHgxMDAwMDAwMDBMKSA9PSAwKaCgoKCgoKCgoKCgoKCgoFwKPiAroKCgoKCgoKCg oKCgoKCgcHJpbnRrKCJQVSUwNHggJTA4eDolcyAiIGlkc3RyaW5nICIgImZvcm1hdCAiXG4iLKCg oKCgoKBcCj4gK6CgoKCgoKCgoKCgoKCgoCCgIKAgoCBnZXRfcGFjYSgpLT5wYWNhX2luZGV4LCAo dTMyKShlaGNhX2VkZWJfZmlsdGVycmVzdWx0KSwgXAo+ICugoKCgoKCgoKCgoKCgoKAgoCCgIKAg X19mdW5jX18sIKAjI2FyZ3MpO6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoFwKPiArfSB3 aGlsZSAoMSA9PSAwKQoKVGhlc2UgbWFjcm9zIGFyZSByZXNwb25zaWJsZSBmb3IgNjElIG9mIHRo ZSBvYmplY3QgY29kZSBzaXplIG9mIHlvdXIgbW9kdWxlLgpUaGlzIGlzIGNvbXBsZXRlbHkgaW5z YW5lLiBQbGVhc2UgZ2V0IHJpZCBvZiB0aGF0IGNyYXAgZW50aXJlbHkgYW5kIHJlcGxhY2UKaXQg d2l0aCBkZXZfaW5mby9kZXZfZGJnL2Rldl93YXJuIGNhbGxzIHdoZXJlIGFwcHJvcHJpYXRlIQoK CUFybmQgPD48Cg== ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 02/13] IB/ehca: includes 2006-08-17 23:44 ` Arnd Bergmann @ 2006-08-18 15:35 ` Christoph Raisch 2006-08-18 16:21 ` Arnd Bergmann 0 siblings, 1 reply; 7+ messages in thread From: Christoph Raisch @ 2006-08-18 15:35 UTC (permalink / raw) To: abergman Cc: linux-kernel, openib-general, linuxppc-dev, Hoang-Nam Nguyen, Marcus Eder abergman > > +#define EDEB_P_GENERIC(level,idstring,format,args...) \ > > These macros are responsible for 61% of the object code size of your module. > ...Please get rid of that crap entirely and replace > it with dev_info/dev_dbg/dev_warn calls where appropriate! > > Arnd <>< we'll change these EDEBs to a wrapper around dev_err, dev_dbg and dev_warn as it's done in the mthca driver. All EDEB_EN and EDEB_EX will be removed, that type of tracing can be done if needed by kprobes. There are a few cases where we won't get to a dev, for these few places we'll use a simple wrapper around printk, as done in ipoib. Hope that's the "official" way how to implement it in ib drivers. Gruss / Regards . . . Christoph R ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 02/13] IB/ehca: includes 2006-08-18 15:35 ` Christoph Raisch @ 2006-08-18 16:21 ` Arnd Bergmann 0 siblings, 0 replies; 7+ messages in thread From: Arnd Bergmann @ 2006-08-18 16:21 UTC (permalink / raw) To: linuxppc-dev Cc: Christoph Raisch, Hoang-Nam Nguyen, linux-kernel, openib-general, Marcus Eder On Friday 18 August 2006 17:35, Christoph Raisch wrote: > we'll change these EDEBs to a wrapper around dev_err, dev_dbg and dev_warn > as it's done in the mthca driver. > > ... > > Hope that's the "official" way how to implement it in ib drivers. I guess it would be even better to just use the dev_* macros directly instead of having your own wrapper. You can do that in both ehca and ehea. Arnd <>< ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2006-08-30 18:23 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <OFED0915E4.3CED6795-ONC12571CE.0053ECB8-C12571CE.0055546A@LocalDomain>
2006-08-30 9:13 ` [PATCH 02/13] IB/ehca: includes Hoang-Nam Nguyen
2006-08-30 9:43 ` Arnd Bergmann
2006-08-30 18:27 ` [openib-general] " Hoang-Nam Nguyen
2006-08-17 20:11 [PATCH 01/13] IB/ehca: hca Roland Dreier
2006-08-17 20:11 ` [PATCH 02/13] IB/ehca: includes Roland Dreier
2006-08-17 23:44 ` Arnd Bergmann
2006-08-18 15:35 ` Christoph Raisch
2006-08-18 16:21 ` Arnd Bergmann
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox