<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=us-ascii">
<META content="MSHTML 6.00.2900.3243" name=GENERATOR></HEAD>
<BODY>
<DIV><FONT face=Arial size=2><SPAN class=399095408-23062008>Investigation of
INSUFFICIENT_MEMORY failures on our stress tests brought us to
"revelation", that VirtualAlloc function, used for implementation of
posix_memalign, is a very "greedy" one: it allocates at least 64KB
memory.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN class=399095408-23062008>As far as we usually
ask one page, it is 16 times more than necessary.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN
class=399095408-23062008></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=399095408-23062008>Presented
below a patch, which implements posix_memalign with (ultimately) HeapAlloc
functions.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN class=399095408-23062008>The patch was tested
and worked OK.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN
class=399095408-23062008></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=399095408-23062008>An important nuance,
that was revealed during testing is as follows:</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN class=399095408-23062008>A system function,
which releases the resources of an exiting process, damages in some way the work
of MmSecureVirtualMemory function, which we use today to secure <SPAN
class=399095408-23062008>CQ\QP\SRQ circular buffers and user
buffers.</SPAN></SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN class=399095408-23062008>If an application
gets killed or exits without releasing the resources, IBBUS catches this event,
starts its cascading destroy of resources and crashes on
MmUnsecureVirtualMemory.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN class=399095408-23062008>Putting
MmUnsecureVirtualMemory in try-except block saves from the crash, but an
async thread, releasing QPs, freezes on MmUnsecureVirtualMemory, which fails to
get some mutex.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN class=399095408-23062008>As far as there is
no real reason to secure circular buffers, i've solved the problem by
skipping securing for IB objects.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN class=399095408-23062008>User buffers are
still secured while memory registration.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN
class=399095408-23062008></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=399095408-23062008>Therefore the patch
contains 3 kinds of changes:</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN class=399095408-23062008>1) new
implementation of posix_memalign and all related to that;</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN class=399095408-23062008>2) try-except block
around MmUnsecureVirtualMemory;</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN class=399095408-23062008>3) new parameter in
ib_umem_get and mthca_reg_virt_mr for skipping memory securing and all related
to it;</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>Index:
hw/mlx4/kernel/bus/core/l2w_umem.c<BR>===================================================================<BR>---
hw/mlx4/kernel/bus/core/l2w_umem.c (revision 1294)<BR>+++
hw/mlx4/kernel/bus/core/l2w_umem.c (working copy)<BR>@@ -9,8 +9,20
@@<BR> void ib_umem_release(struct ib_umem
*p_ib_umem)<BR> {<BR> MLX4_ENTER(MLX4_DBG_MEMORY);<BR>- if
(p_ib_umem->secure_handle)<BR>- MmUnsecureVirtualMemory(
p_ib_umem->secure_handle );<BR>+ if (p_ib_umem->secure_handle)
{<BR>+ __try {<BR>+ MmUnsecureVirtualMemory(
p_ib_umem->secure_handle );<BR>+ p_ib_umem->secure_handle
= NULL;<BR>+ }<BR>+ __except (EXCEPTION_EXECUTE_HANDLER)
{<BR>+ NTSTATUS Status =
GetExceptionCode();<BR>+ UNUSED_PARAM_WOWPP(Status);<BR>+ MLX4_PRINT(TRACE_LEVEL_ERROR
,MLX4_DBG_MEMORY ,<BR>+ ("Exception 0x%x on
MmUnsecureVirtualMemory(), addr %I64x, size %I64x, seg_num %d, nr_pages %d\n",
<BR>+ Status, p_ib_umem->iobuf.va,
(u64)p_ib_umem->iobuf.size,
<BR>+ p_ib_umem->iobuf.seg_num,
p_ib_umem->iobuf.nr_pages ));<BR>+ }<BR>+ }<BR> if
(p_ib_umem->iobuf_used)<BR> iobuf_deregister_with_cash(&p_ib_umem->iobuf);<BR> kfree(p_ib_umem);<BR>@@
-26,7 +38,7 @@<BR> * @access: IB_ACCESS_xxx flags for memory being
pinned<BR> */<BR> struct ib_umem *ib_umem_get(struct ib_ucontext
*context, u64 addr,<BR>- size_t size, enum
ib_access_flags access)<BR>+ size_t size,
enum ib_access_flags access, boolean_t secure)<BR> {<BR> int
err;<BR> struct ib_umem *p_ib_umem;<BR>@@ -52,7 +64,7
@@<BR> // TODO: map the memory for
DMA<BR> <BR> // secure memory<BR>- if
(!context)<BR>+ if (!context || !secure)<BR> goto
done;<BR> __try {<BR> p_ib_umem->secure_handle =
MmSecureVirtualMemory ( <BR>Index:
hw/mlx4/kernel/bus/ib/cq.c<BR>===================================================================<BR>---
hw/mlx4/kernel/bus/ib/cq.c (revision 1294)<BR>+++
hw/mlx4/kernel/bus/ib/cq.c (working copy)<BR>@@ -142,7 +142,7
@@<BR> }<BR> <BR> cq->umem =
ib_umem_get(context, ucmd.buf_addr,
buf_size,<BR>-
IB_ACCESS_LOCAL_WRITE);<BR>+
IB_ACCESS_LOCAL_WRITE, FALSE);<BR> if (IS_ERR(cq->umem))
{<BR> err =
PTR_ERR(cq->umem);<BR> goto err_cq;<BR>Index:
hw/mlx4/kernel/bus/ib/doorbell.c<BR>===================================================================<BR>---
hw/mlx4/kernel/bus/ib/doorbell.c (revision 1294)<BR>+++
hw/mlx4/kernel/bus/ib/doorbell.c (working copy)<BR>@@ -182,7 +182,7
@@<BR> page->user_virt = virt &
(u64)PAGE_MASK;<BR> page->refcnt =
0;<BR> page->umem =
ib_umem_get(&context->ibucontext, virt &
(u64)PAGE_MASK,<BR>-
PAGE_SIZE, 0);<BR>+
PAGE_SIZE, 0, FALSE);<BR> if (IS_ERR(page->umem))
{<BR> err =
PTR_ERR(page->umem);<BR> kfree(page);<BR>Index:
hw/mlx4/kernel/bus/ib/mr.c<BR>===================================================================<BR>---
hw/mlx4/kernel/bus/ib/mr.c (revision 1294)<BR>+++
hw/mlx4/kernel/bus/ib/mr.c (working copy)<BR>@@ -129,7 +129,7
@@<BR> if (!mr)<BR> return
ERR_PTR(-ENOMEM);<BR> <BR>- mr->umem = ib_umem_get(pd->p_uctx,
start, (size_t)length, access_flags);<BR>+ mr->umem =
ib_umem_get(pd->p_uctx, start, (size_t)length, access_flags,
TRUE);<BR> if (IS_ERR(mr->umem)) {<BR> // there
can be also second reason of failue - insufficient
memory,<BR> // but we can't get awared of that without changing
ib_umem_get prototype<BR>Index:
hw/mlx4/kernel/bus/ib/qp.c<BR>===================================================================<BR>---
hw/mlx4/kernel/bus/ib/qp.c (revision 1294)<BR>+++
hw/mlx4/kernel/bus/ib/qp.c (working copy)<BR>@@ -360,7 +360,7
@@<BR> goto
err;<BR> <BR> qp->umem = ib_umem_get(pd->p_uctx,
ucmd.buf_addr,<BR>-
qp->buf_size,
0);<BR>+
qp->buf_size, 0, FALSE);<BR> if (IS_ERR(qp->umem))
{<BR> err =
PTR_ERR(qp->umem);<BR> goto err;<BR>Index:
hw/mlx4/kernel/bus/ib/srq.c<BR>===================================================================<BR>---
hw/mlx4/kernel/bus/ib/srq.c (revision 1294)<BR>+++
hw/mlx4/kernel/bus/ib/srq.c (working copy)<BR>@@ -116,7 +116,7
@@<BR> }<BR> <BR> srq->umem =
ib_umem_get(pd->p_uctx,
ucmd.buf_addr,<BR>- buf_size,
0);<BR>+ buf_size, 0,
FALSE);<BR> if (IS_ERR(srq->umem))
{<BR> err =
PTR_ERR(srq->umem);<BR> goto err_srq;<BR>Index:
hw/mlx4/kernel/hca/mr.c<BR>===================================================================<BR>---
hw/mlx4/kernel/hca/mr.c (revision 1294)<BR>+++
hw/mlx4/kernel/hca/mr.c (working copy)<BR>@@ -170,7 +170,7
@@<BR> if (IS_ERR(p_ib_mr)) {<BR> err =
PTR_ERR(p_ib_mr);<BR> HCA_PRINT(TRACE_LEVEL_ERROR,
HCA_DBG_MEMORY,<BR>- ("mthca_reg_phys_mr failed (%d)\n",
err));<BR>+ ("ib_reg_phys_mr failed (%d)\n",
err));<BR> status =
errno_to_iberr(err);<BR> goto
err_reg_phys_mr;<BR> }<BR>Index:
hw/mlx4/kernel/inc/l2w_umem.h<BR>===================================================================<BR>---
hw/mlx4/kernel/inc/l2w_umem.h (revision 1294)<BR>+++
hw/mlx4/kernel/inc/l2w_umem.h (working copy)<BR>@@ -15,7 +15,7
@@<BR> void ib_umem_release(struct ib_umem
*p_ib_umem);<BR> <BR> struct ib_umem *ib_umem_get(struct ib_ucontext
*context, u64 addr,<BR>- size_t size, enum
ib_access_flags access);<BR>+ size_t size,
enum ib_access_flags access, boolean_t secure);<BR> <BR> int
ib_umem_page_count(struct ib_umem *p_ib_umem);<BR> <BR>Index:
hw/mlx4/user/hca/buf.c<BR>===================================================================<BR>---
hw/mlx4/user/hca/buf.c (revision 1294)<BR>+++
hw/mlx4/user/hca/buf.c (working copy)<BR>@@ -35,17 +35,13 @@<BR> int
mlx4_alloc_buf(struct mlx4_buf *buf, int size, int
page_size)<BR> {<BR> int ret;<BR>-<BR> ret =
posix_memalign(&buf->buf, page_size, align(size,
page_size));<BR>- if (ret)<BR>- return
ret;<BR>-<BR>- buf->length = size;<BR>-<BR>- return 0;<BR>+ if
(!ret)<BR>+ buf->length = size;<BR>+ return
ret;<BR> }<BR> <BR> void mlx4_free_buf(struct mlx4_buf
*buf)<BR> {<BR>- VirtualFree(buf->buf, 0,
MEM_RELEASE);<BR>+ posix_memfree(buf->buf);<BR> }<BR>Index:
hw/mlx4/user/hca/l2w.h<BR>===================================================================<BR>---
hw/mlx4/user/hca/l2w.h (revision 1294)<BR>+++
hw/mlx4/user/hca/l2w.h (working copy)<BR>@@ -74,17 +74,49 @@<BR> //
FUNCTIONS<BR> //
===========================================<BR> <BR>+static inline BOOLEAN
is_power_of_2(uint32_t n)<BR>+{<BR>+ return (!!n & !(n & (n-1))) ?
TRUE : FALSE;<BR>+}<BR>+<BR>+// Allocated memory is zeroed !<BR> static
inline int posix_memalign(void **memptr, int alignment, int
size)<BR> {<BR>- UNREFERENCED_PARAMETER(alignment);<BR>+ int
aligned_size, desc_size = sizeof(int);<BR>+ char *real_addr,
*aligned_addr;<BR> <BR>- *memptr = VirtualAlloc( NULL, size,
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE );<BR>- if (*memptr)
<BR>- return 0;<BR>- else <BR>- return
ENOMEM;<BR>+ // sanity check: alignment should a power of 2 and more then
2<BR>+ if ( alignment < desc_size || !is_power_of_2((uint32_t)alignment)
)<BR>+ return -EINVAL;<BR>+<BR>+ // calculate size, needed for
aligned allocation<BR>+ aligned_size = size + alignment +
desc_size;<BR>+<BR>+ // allocate<BR>+ real_addr =
cl_zalloc(aligned_size);<BR>+ if ( real_addr == NULL
)<BR>+ return -ENOMEM;<BR>+<BR>+ // calculate aligned
address<BR>+ aligned_addr = (char *)(((ULONG_PTR)(real_addr + alignment-1))
& ~(alignment - 1));<BR>+ if ( aligned_addr < real_addr + desc_size
)<BR>+ aligned_addr += alignment;<BR>+<BR>+ // store the
descriptor<BR>+ *(int*)(aligned_addr - desc_size) = (int)(aligned_addr -
real_addr);<BR>+ <BR>+ *memptr = aligned_addr;<BR>+ return
0;<BR> }<BR> <BR>+// there is no such POSIX function. Called so to be
similar to the allocation one.<BR>+static inline void posix_memfree(void
*memptr)<BR>+{<BR>+ int *desc_addr = (int*)((char*)memptr -
sizeof(int));<BR>+ char *real_addr = (char*)memptr -
*desc_addr;<BR>+ cl_free(real_addr);<BR>+}<BR>+<BR> static inline int
ffsl(uint32_t x)<BR> {<BR> int r
= 0;<BR>Index:
hw/mlx4/user/hca/qp.c<BR>===================================================================<BR>---
hw/mlx4/user/hca/qp.c (revision 1294)<BR>+++
hw/mlx4/user/hca/qp.c (working copy)<BR>@@ -685,7 +685,6
@@<BR> return
-1;<BR> }<BR> <BR>- memset(qp->buf.buf, 0,
qp->buf_size);<BR> mlx4_qp_init_sq_ownership(qp);<BR> <BR> return
0;<BR>Index:
hw/mlx4/user/hca/srq.c<BR>===================================================================<BR>---
hw/mlx4/user/hca/srq.c (revision 1294)<BR>+++
hw/mlx4/user/hca/srq.c (working copy)<BR>@@ -146,8 +146,6
@@<BR> return -1;<BR> }<BR> <BR>- //
srq->buf.buf is zeroed in posix_memalign - memset(srq->buf.buf, 0,
buf_size);<BR>-<BR> /*<BR> * Now initialize the SRQ
buffer so that all of the WQEs are<BR> * linked into the list of
free WQEs.<BR>Index:
hw/mlx4/user/hca/verbs.c<BR>===================================================================<BR>---
hw/mlx4/user/hca/verbs.c (revision 1294)<BR>+++
hw/mlx4/user/hca/verbs.c (working copy)<BR>@@ -373,8 +373,6
@@<BR> context->page_size))<BR> goto
err_alloc_buf;<BR> <BR>- // cq->buf.buf is zeroed in posix_memalign
- memset(cq->buf.buf, 0, buf_size);<BR>-<BR> cq->ibv_cq.context
= context;<BR> cq->cons_index = 0;<BR> <BR>@@
-718,7 +716,7 @@<BR> attr.cap.max_recv_wr =
p_create_attr->rq_depth;<BR> attr.cap.max_send_sge =
p_create_attr->sq_sge;<BR> attr.cap.max_recv_sge =
p_create_attr->rq_sge;<BR>- attr.cap.max_inline_data =
p_create_attr->sq_max_inline; /* absent in IBAL
*/<BR>+ attr.cap.max_inline_data =
p_create_attr->sq_max_inline;<BR> attr.qp_type =
__to_qp_type(p_create_attr->qp_type);<BR> attr.sq_sig_all =
p_create_attr->sq_signaled;<BR> <BR>Index:
hw/mthca/kernel/hca_memory.c<BR>===================================================================<BR>---
hw/mthca/kernel/hca_memory.c (revision 1294)<BR>+++
hw/mthca/kernel/hca_memory.c (working copy)<BR>@@ -88,7 +88,7
@@<BR> // register mr <BR> mr_p = ibv_reg_mr(ib_pd_p,
map_qp_ibal_acl(p_mr_create->access_ctrl),
<BR> p_mr_create->vaddr, p_mr_create->length,
<BR>- (uint64_t)p_mr_create->vaddr, um_call
);<BR>+ (uint64_t)p_mr_create->vaddr, um_call, TRUE
);<BR> if (IS_ERR(mr_p)) {<BR> err =
PTR_ERR(mr_p);<BR> HCA_PRINT(TRACE_LEVEL_ERROR,
HCA_DBG_MEMORY,<BR>Index:
hw/mthca/kernel/ib_verbs.h<BR>===================================================================<BR>---
hw/mthca/kernel/ib_verbs.h (revision 1294)<BR>+++
hw/mthca/kernel/ib_verbs.h (working copy)<BR>@@ -729,7 +729,7
@@<BR> u64
*iova_start);<BR> struct ib_mr *
(*reg_virt_mr)(struct ib_pd *pd,
<BR> void* FUNC_PTR64 vaddr,
uint64_t length, uint64_t
hca_va,<BR>- mthca_qp_access_t acc, boolean_t
um_call);<BR>+ mthca_qp_access_t acc,
boolean_t um_call, boolean_t
secure);<BR> int
(*query_mr)(struct ib_mr
*mr,<BR>
struct ib_mr_attr
*mr_attr);<BR> int
(*dereg_mr)(struct ib_mr *mr);<BR>@@ -1140,13 +1140,15 @@<BR> * @hca_va:
virtual address in HCA<BR> * @mr_access_flags: Specifies the memory access
rights.<BR> * @um_call: call from user, when TRUE.<BR>+ * @secure: secure
the memory from releasing (only for um_call == TRUE)<BR>
*/<BR> struct ib_mr *ibv_reg_mr(struct ib_pd *pd,
<BR> mthca_qp_access_t mr_access_flags,<BR> void*
FUNC_PTR64 vaddr,<BR> uint64_t length,<BR> uint64_t
hca_va,<BR>- boolean_t um_call<BR>+ boolean_t um_call,<BR>+ boolean_t secure<BR> );<BR> <BR> /**<BR>Index:
hw/mthca/kernel/mt_verbs.c<BR>===================================================================<BR>---
hw/mthca/kernel/mt_verbs.c (revision 1294)<BR>+++
hw/mthca/kernel/mt_verbs.c (working copy)<BR>@@ -171,7 +171,7
@@<BR> pd,
<BR> create_ah->mr.access_flags,
<BR> (void*)(ULONG_PTR)create_ah->mr.start,<BR>- create_ah->mr.length,
create_ah->mr.hca_va, TRUE );<BR>+ create_ah->mr.length,
create_ah->mr.hca_va, TRUE, FALSE );<BR> if (IS_ERR(ib_mr))
{<BR> err =
PTR_ERR(ib_mr);<BR> HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_AV ,("ibv_reg_mr
failed (%d)\n", err));<BR>@@ -331,7 +331,7 @@<BR> (struct
ib_pd *)(ULONG_PTR)create_srp->mr.pd_handle,
<BR> create_srp->mr.access_flags,
<BR> (void*)(ULONG_PTR)create_srp->mr.start,<BR>- create_srp->mr.length,
create_srp->mr.hca_va, TRUE
);<BR>+ create_srp->mr.length, create_srp->mr.hca_va,
TRUE, FALSE );<BR> if (IS_ERR(ib_mr))
{<BR> err =
PTR_ERR(ib_mr);<BR> HCA_PRINT(TRACE_LEVEL_ERROR
,HCA_DBG_QP ,("ibv_reg_mr failed (%d)\n", err));<BR>@@ -453,7 +453,7
@@<BR> (struct ib_pd
*)(ULONG_PTR)create_qp->mr.pd_handle,
<BR> create_qp->mr.access_flags,
<BR> (void*)(ULONG_PTR)create_qp->mr.start,<BR>- create_qp->mr.length,
create_qp->mr.hca_va, TRUE );<BR>+ create_qp->mr.length,
create_qp->mr.hca_va, TRUE, FALSE );<BR> if (IS_ERR(ib_mr))
{<BR> err =
PTR_ERR(ib_mr);<BR> HCA_PRINT(TRACE_LEVEL_ERROR
,HCA_DBG_QP ,("ibv_reg_mr failed (%d)\n", err));<BR>@@ -598,7 +598,7
@@<BR> (struct ib_pd
*)(ULONG_PTR)create_cq->mr.pd_handle,
<BR> create_cq->mr.access_flags,
<BR> (void*)(ULONG_PTR)create_cq->mr.start,<BR>- create_cq->mr.length,
create_cq->mr.hca_va, TRUE );<BR>+ create_cq->mr.length,
create_cq->mr.hca_va, TRUE, FALSE );<BR> if (IS_ERR(ib_mr))
{<BR> err =
PTR_ERR(ib_mr);<BR> HCA_PRINT(TRACE_LEVEL_ERROR
,HCA_DBG_CQ ,("ibv_reg_mr failed (%d)\n", err));<BR>@@ -688,14 +688,15
@@<BR> void*
FUNC_PTR64 vaddr,<BR> uint64_t length,<BR> uint64_t
hca_va,<BR>- boolean_t um_call<BR>+ boolean_t um_call,<BR>+ boolean_t secure<BR> )<BR> {<BR> struct
ib_mr
*ib_mr;<BR> int
err;<BR> HCA_ENTER(HCA_DBG_MEMORY);<BR> <BR>- ib_mr =
pd->device->reg_virt_mr(pd, vaddr, length, hca_va, mr_access_flags,
um_call);<BR>+ ib_mr = pd->device->reg_virt_mr(pd, vaddr, length,
hca_va, mr_access_flags, um_call, secure);<BR> if (IS_ERR(ib_mr))
{<BR> err =
PTR_ERR(ib_mr);<BR> HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_MEMORY
,("mthca_reg_user_mr failed (%d)\n", err));<BR>Index:
hw/mthca/kernel/mthca_provider.c<BR>===================================================================<BR>---
hw/mthca/kernel/mthca_provider.c (revision 1294)<BR>+++
hw/mthca/kernel/mthca_provider.c (working copy)<BR>@@ -996,7 +996,7
@@<BR> <BR> static struct ib_mr *mthca_reg_virt_mr(struct ib_pd *pd,
<BR> void* FUNC_PTR64 vaddr, uint64_t length, uint64_t
hca_va,<BR>- mthca_qp_access_t acc, boolean_t
um_call)<BR>+ mthca_qp_access_t acc, boolean_t um_call, boolean_t
secure)<BR> {<BR> struct mthca_dev *dev =
to_mdev(pd->device);<BR> struct mthca_mr *mr;<BR>@@ -1082,7
+1082,7 @@<BR> goto err_mt_alloc;<BR> <BR> //
secure memory<BR>- if (!pd->ucontext)<BR>+ if (!pd->ucontext ||
!secure)<BR> goto done;<BR> __try
{<BR> mr->secure_handle = MmSecureVirtualMemory ( vaddr,
(SIZE_T)length,<BR>@@ -1129,8 +1129,19 @@<BR> struct mthca_mr *mmr =
to_mmr(mr);<BR> struct mthca_dev* dev =
to_mdev(mr->device);<BR> <BR>- if
(mmr->secure_handle)<BR>- MmUnsecureVirtualMemory (
mmr->secure_handle );<BR>+ if (mmr->secure_handle)
{<BR>+ __try {<BR>+ MmUnsecureVirtualMemory(
mmr->secure_handle );<BR>+ mmr->secure_handle =
NULL;<BR>+ }<BR>+ __except (EXCEPTION_EXECUTE_HANDLER)
{<BR>+ NTSTATUS Status =
GetExceptionCode();<BR>+ UNUSED_PARAM_WOWPP(Status);<BR>+ HCA_PRINT(TRACE_LEVEL_ERROR
,HCA_DBG_MEMORY ,<BR>+ ("Exception 0x%x on
MmUnsecureVirtualMemory(), addr %I64x, size %I64x, seg_num %d, nr_pages %d\n",
<BR>+ Status, mmr->iobuf.va, (u64)mmr->iobuf.size,
mmr->iobuf.seg_num, mmr->iobuf.nr_pages
));<BR>+ }<BR>+ }<BR> mthca_free_mr(dev,
mmr);<BR> if
(mmr->iobuf_used)<BR> iobuf_deregister_with_cash(&mmr->iobuf);<BR>Index:
hw/mthca/user/mlnx_ual_srq.c<BR>===================================================================<BR>---
hw/mthca/user/mlnx_ual_srq.c (revision 1294)<BR>+++
hw/mthca/user/mlnx_ual_srq.c (working copy)<BR>@@ -54,11 +54,7
@@<BR> }<BR> <BR> if (srq->buf) {<BR>-#ifdef
NOT_USE_VIRTUAL_ALLOC <BR>- cl_free(srq->buf);<BR>-#else<BR>- VirtualFree(
srq->buf, 0,
MEM_RELEASE);<BR>-#endif<BR>+ posix_memfree(srq->buf);<BR> }<BR> <BR> if
(srq->wrid) <BR>@@ -158,11 +154,7 @@<BR> goto
end;<BR> <BR> err_alloc_db:<BR>-#ifdef
NOT_USE_VIRTUAL_ALLOC <BR>- cl_free(srq->buf);<BR>-#else<BR>- VirtualFree(
srq->buf, 0,
MEM_RELEASE);<BR>-#endif<BR>+ posix_memfree(srq->buf);<BR> cl_free(srq->wrid);<BR> err_alloc_buf:<BR> cl_spinlock_destroy(&srq->lock);<BR>Index:
hw/mthca/user/mlnx_uvp_memfree.c<BR>===================================================================<BR>---
hw/mthca/user/mlnx_uvp_memfree.c (revision 1294)<BR>+++
hw/mthca/user/mlnx_uvp_memfree.c (working copy)<BR>@@ -201,11 +201,7
@@<BR> <BR> for (i = 0; i < db_tab->npages;
++i)<BR> if (db_tab->page[i].db_rec)<BR>-#ifdef
NOT_USE_VIRTUAL_ALLOC <BR>- cl_free(db_tab->page[i].db_rec);<BR>-#else<BR>- VirtualFree(
db_tab->page[i].db_rec, 0,
MEM_RELEASE);<BR>-#endif<BR>+ posix_memfree(
db_tab->page[i].db_rec);<BR> <BR> cl_free(db_tab);<BR> }<BR>Index:
hw/mthca/user/mlnx_uvp_verbs.c<BR>===================================================================<BR>---
hw/mthca/user/mlnx_uvp_verbs.c (revision 1294)<BR>+++
hw/mthca/user/mlnx_uvp_verbs.c (working copy)<BR>@@ -80,11 +80,7
@@<BR> WaitForSingleObject( pd->ah_mutex, INFINITE
);<BR> for (page = pd->ah_list; page; page = next_page)
{<BR> next_page =
page->next;<BR>- #ifdef
NOT_USE_VIRTUAL_ALLOC <BR>- cl_free(page->buf);<BR>- #else<BR>- VirtualFree(
page->buf, 0,
MEM_RELEASE);<BR>- #endif<BR>+ posix_memfree(page->buf);<BR> cl_free(page);<BR> }<BR> ReleaseMutex(
pd->ah_mutex );<BR>@@ -181,7 +177,7
@@<BR> cq->set_ci_db_index);<BR> <BR> err_unreg:<BR>- cl_free(cq->buf);<BR>+ posix_memfree(cq->buf);<BR> <BR> err_memalign:<BR> cl_spinlock_destroy(&cq->lock);<BR>@@
-233,12 +229,7 @@<BR>
to_mcq(cq)->arm_db_index);<BR> }<BR> <BR>-#ifdef
NOT_USE_VIRTUAL_ALLOC <BR>- cl_free(to_mcq(cq)->buf);<BR>-#else<BR>- VirtualFree(
to_mcq(cq)->buf, 0,
MEM_RELEASE);<BR>-#endif<BR>-<BR>+ posix_memfree(to_mcq(cq)->buf);<BR> <BR> cl_spinlock_destroy(&((struct
mthca_cq *)cq)->lock);<BR> cl_free(to_mcq(cq));<BR>@@ -380,11
+371,7
@@<BR> <BR> err_spinlock_sq:<BR> cl_free(qp->wrid);<BR>-#ifdef
NOT_USE_VIRTUAL_ALLOC <BR>- cl_free(qp->buf);<BR>-#else<BR>- VirtualFree(
qp->buf, 0,
MEM_RELEASE);<BR>-#endif<BR>+ posix_memfree(qp->buf);<BR> <BR> err_nomem:<BR> cl_free(qp);<BR>@@
-501,11 +488,7 @@<BR> cl_spinlock_destroy(&((struct
mthca_qp
*)qp)->sq.lock);<BR> cl_spinlock_destroy(&((struct
mthca_qp *)qp)->rq.lock);<BR> <BR>-#ifdef
NOT_USE_VIRTUAL_ALLOC <BR>- cl_free(to_mqp(qp)->buf);<BR>-#else<BR>- VirtualFree(
to_mqp(qp)->buf, 0,
MEM_RELEASE);<BR>-#endif<BR>+ posix_memfree(to_mqp(qp)->buf);<BR> cl_free(to_mqp(qp)->wrid);<BR> cl_free(to_mqp(qp));<BR> }<BR>Index:
hw/mthca/user/mt_l2w.h<BR>===================================================================<BR>---
hw/mthca/user/mt_l2w.h (revision 1294)<BR>+++
hw/mthca/user/mt_l2w.h (working copy)<BR>@@ -52,32 +52,49
@@<BR> <BR> extern size_t g_page_size;<BR> <BR>-static inline int
posix_memalign(void **memptr, size_t alignment, size_t size)<BR>+static inline
BOOLEAN is_power_of_2(uint32_t n)<BR> {<BR>-#ifdef
NOT_USE_VIRTUAL_ALLOC <BR>- // sanity checks<BR>- if (alignment %
sizeof(void*))<BR>- return EINVAL;<BR>- if (alignment <
g_page_size) {<BR>- fprintf(stderr, "mthca: Fatal (posix_memalign):
alignment too small - %d \n", alignment );<BR>- return
EINVAL;<BR>- }<BR>+ return (!!n & !(n & (n-1))) ? TRUE :
FALSE;<BR>+}<BR> <BR>- // allocation<BR>- *memptr =
cl_malloc(size);<BR>- if (*memptr) <BR>- return
0;<BR>- else <BR>- return
ENOMEM;<BR>-#else<BR>- *memptr = VirtualAlloc( NULL, size, MEM_COMMIT |
MEM_RESERVE, PAGE_READWRITE );<BR>- if (*memptr)
<BR>- return 0;<BR>- else <BR>- return
ENOMEM;<BR>-#endif<BR>+// Allocated memory is zeroed !<BR>+static inline int
posix_memalign(void **memptr, int alignment, int size)<BR>+{<BR>+ int
aligned_size, desc_size = sizeof(int);<BR>+ char *real_addr,
*aligned_addr;<BR>+<BR>+ // sanity check: alignment should a power of 2 and
more then 2<BR>+ if ( alignment < desc_size ||
!is_power_of_2((uint32_t)alignment) )<BR>+ return
-EINVAL;<BR>+<BR>+ // calculate size, needed for aligned
allocation<BR>+ aligned_size = size + alignment +
desc_size;<BR>+<BR>+ // allocate<BR>+ real_addr =
cl_zalloc(aligned_size);<BR>+ if ( real_addr == NULL
)<BR>+ return -ENOMEM;<BR>+<BR>+ // calculate aligned
address<BR>+ aligned_addr = (char *)(((ULONG_PTR)(real_addr + alignment-1))
& ~(alignment - 1));<BR>+ if ( aligned_addr < real_addr + desc_size
)<BR>+ aligned_addr += alignment;<BR>+<BR>+ // store the
descriptor<BR>+ *(int*)(aligned_addr - desc_size) = (int)(aligned_addr -
real_addr);<BR>+ <BR>+ *memptr = aligned_addr;<BR>+ return
0;<BR> }<BR> <BR>+// there is no such POSIX function. Called so to be
similar to the allocation one.<BR>+static inline void posix_memfree(void
*memptr)<BR>+{<BR>+ int *desc_addr = (int*)((char*)memptr -
sizeof(int));<BR>+ char *real_addr = (char*)memptr -
*desc_addr;<BR>+ cl_free(real_addr);<BR>+}<BR>+<BR> //
===========================================<BR> // FUNCTIONS<BR> //
===========================================<BR></FONT></DIV><div>
<p><span style='color:#1F497D'> </span><span
style='font-size:18.0pt;font-family:Webdings;color:green'>P</span><span
style='font-size:18.0pt;font-family:"Courier New";color:green'> </span><span
style='font-size:10.0pt;font-family:"Arial","sans-serif";color:blue'> </span><span
style='font-size:10.0pt;font-family:"Arial","sans-serif";color:green'>Please consider
the environment before printing this e-mail or its attachment(s)</span><span
style='font-size:10.0pt;font-family:"Arial","sans-serif";color:blue'> </span><span
style='color:navy'><o:p></o:p></span></p>
</div><div style="color:#999999;font-size:11px;font-family:verdana"><br>Disclaimer added by <b>CodeTwo Exchange Rules</b><br><a href="http://www.codetwo.com">www.codetwo.com</a></div>
<!--418FEECD7B41410cA6AF47547865A7D9-->
<br></BODY></HTML>