Mailing List Archive

[PATCH 02/13] IB/ehca: includes
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

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 02/13] IB/ehca: includes [ In reply to ]
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

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 02/13] IB/ehca: includes [ In reply to ]
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 <><
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 02/13] IB/ehca: includes [ In reply to ]
> 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

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 02/13] IB/ehca: includes [ In reply to ]
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 <><
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [openib-general] [PATCH 02/13] IB/ehca: includes [ In reply to ]
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);

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/