<!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>