components/open-fabrics/perftest/patches/base.patch
branchs11-update
changeset 2868 7d6a27aef8cf
parent 2532 5b3dc1c8b85e
child 2187 391c8a50fa82
--- a/components/open-fabrics/perftest/patches/base.patch	Mon Dec 23 14:14:12 2013 -0800
+++ b/components/open-fabrics/perftest/patches/base.patch	Mon Dec 23 14:14:12 2013 -0800
@@ -1564,2335 +1564,27 @@
 diff -r -u /tmp/perftest-1.3.0/send_bw.c perftest-1.3.0/send_bw.c
 --- /tmp/perftest-1.3.0/send_bw.c	Thu Jan 20 07:37:18 2011
 +++ perftest-1.3.0/send_bw.c	Fri Feb 11 04:12:47 2011
-@@ -1,1162 +1,1166 @@
--/*
-- * Copyright (c) 2005 Topspin Communications.  All rights reserved.
-- * Copyright (c) 2005 Mellanox Technologies Ltd.  All rights reserved.
-- * Copyright (c) 2009 HNR Consulting.  All rights reserved.
-- *
-- * This software is available to you under a choice of one of two
-- * licenses.  You may choose to be licensed under the terms of the GNU
-- * General Public License (GPL) Version 2, available from the file
-- * COPYING in the main directory of this source tree, or the
-- * OpenIB.org BSD license below:
-- *
-- *     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.
-- *
-- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-- * SOFTWARE.
-- *
-- * $Id$
-- */
--
--#if HAVE_CONFIG_H
--#  include <config.h>
--#endif /* HAVE_CONFIG_H */
--
--#include <stdio.h>
--#include <stdlib.h>
--#include <unistd.h>
--#include <string.h>
--#include <limits.h>
--#include <malloc.h>
--#include <getopt.h>
--#include <time.h>
--#include <errno.h>
--#include <infiniband/verbs.h>
--
--#include "get_clock.h"
--#include "multicast_resources.h"
--#include "perftest_resources.h"
--
--#define VERSION 2.1
--
--static int page_size;
--cycles_t	*tposted;
--cycles_t	*tcompleted;
--
--struct pingpong_context {
--	struct ibv_context 		*context;
--	struct ibv_comp_channel *channel;
--	struct ibv_pd      		*pd;
--	struct ibv_mr     		**mr;
--	struct ibv_cq      		*cq;
--	struct ibv_qp      		**qp;
--	struct ibv_sge      	list;
--	struct ibv_send_wr  	wr;
--	struct ibv_sge 			*sge_list;
--	struct ibv_recv_wr  	*rwr;
--	struct ibv_ah			*ah;
--	void               		**buf;
--	unsigned            	size;
--	uint64_t				*my_addr;
--};
--
--/****************************************************************************** 
-- *
-- ******************************************************************************/
--static int set_mcast_group(struct pingpong_context *ctx,
--						   struct perftest_parameters *user_parm,
--						   struct mcast_parameters *mcg_params) {
--
--	struct ibv_port_attr port_attr;
--
--	if (ibv_query_gid(ctx->context,user_parm->ib_port,user_parm->gid_index,&mcg_params->port_gid)) {
--			return 1;
--	}
--		
--	if (ibv_query_pkey(ctx->context,user_parm->ib_port,DEF_PKEY_IDX,&mcg_params->pkey)) {
--		return 1;
--	}
--
--	if (ibv_query_port(ctx->context,user_parm->ib_port,&port_attr)) {
--		return 1;
--	}
--	mcg_params->sm_lid  = port_attr.sm_lid;
--	mcg_params->sm_sl   = port_attr.sm_sl;
--	mcg_params->ib_port = user_parm->ib_port;
--	
--	if (!strcmp(link_layer_str(user_parm->link_type),"IB")) {
--		// Request for Mcast group create registery in SM.
--		if (join_multicast_group(SUBN_ADM_METHOD_SET,mcg_params)) {
--			fprintf(stderr,"Couldn't Register the Mcast group on the SM\n");
--			return 1;
--		}
--	}
--	return 0;
--}
--
--/****************************************************************************** 
-- *
-- ******************************************************************************/
--static int set_up_connection(struct pingpong_context *ctx,
--							 struct perftest_parameters *user_parm,
--							 struct pingpong_dest *my_dest,
--							 struct mcast_parameters *mcg_params) {
--
--	int i = (user_parm->duplex) ? 1 : 0;
--
--	if (user_parm->use_mcg && (user_parm->duplex || user_parm->machine == SERVER)) {
--
--		set_multicast_gid(mcg_params,ctx->qp[0]->qp_num,(int)user_parm->machine);
--		if (set_mcast_group(ctx,user_parm,mcg_params)) {
--			return 1;
--		}
--		
--		while (i < user_parm->num_of_qps) {
--			if (ibv_attach_mcast(ctx->qp[i],&mcg_params->mgid,mcg_params->mlid)) {
--				fprintf(stderr, "Couldn't attach QP to MultiCast group");
--				return 1;
--			}
--			i++;
--		}
--
--		mcg_params->mcast_state |= MCAST_IS_ATTACHED;
--		my_dest->gid = mcg_params->mgid;
--		my_dest->lid = mcg_params->mlid;
--		my_dest->qpn = QPNUM_MCAST;
--
--	} else {
--		if (user_parm->gid_index != -1) {
--			if (ibv_query_gid(ctx->context,user_parm->ib_port,user_parm->gid_index,&my_dest->gid)) {
--				return -1;
--			}
--		}
--		my_dest->lid = ctx_get_local_lid(ctx->context,user_parm->ib_port);
--		my_dest->qpn = ctx->qp[0]->qp_num;
--	}
--	my_dest->psn  = lrand48() & 0xffffff;
--
--	// We do not fail test upon lid above RoCE.
--
--	if (user_parm->gid_index < 0) {
--		if (!my_dest->lid) {
--			fprintf(stderr," Local lid 0x0 detected,without any use of gid. Is SM running?\n");
--			return -1;
--		}
--	}
--	return 0;
--}
--
--/****************************************************************************** 
-- *
-- ******************************************************************************/
--static int init_connection(struct perftest_parameters *params,
-- 						   struct pingpong_dest *my_dest) {
--
--	params->side = LOCAL;
--	ctx_print_pingpong_data(my_dest,params);
--	
--	if (params->machine == CLIENT) 
--		params->sockfd = ctx_client_connect(params->servername,params->port);
--	else 
--		params->sockfd = ctx_server_connect(params->port);
--	
--		
--	if(params->sockfd < 0) {
--		fprintf(stderr,"Unable to open file descriptor for socket connection");
--		return 1;
--	}
--	return 0;
--}
--
--/****************************************************************************** 
-- *
-- ******************************************************************************/
--static int destroy_ctx_resources(struct pingpong_context    *ctx, 
--								 struct perftest_parameters *user_parm,
--								 struct pingpong_dest		*my_dest,
--								 struct pingpong_dest		*rem_dest,
--								 struct mcast_parameters    *mcg_params)  {
--
--	int test_result = 0;
--	int i = (user_parm->duplex) ? 1 : 0;
--
--	if (user_parm->use_mcg) {
--
--		if (user_parm->machine == SERVER || user_parm->duplex) {
--			
--			while (i < user_parm->num_of_qps) {
--				if (ibv_detach_mcast(ctx->qp[i],&my_dest->gid,my_dest->lid)) {
--					fprintf(stderr, "Couldn't deattach QP from MultiCast group\n");
--					return 1;
--				}
--				i++;
--			}
--			mcg_params->mgid = my_dest->gid;
--			if (!strcmp(link_layer_str(user_parm->link_type),"IB")) {
--				if (join_multicast_group(SUBN_ADM_METHOD_DELETE,mcg_params)) {
--					fprintf(stderr,"Couldn't Unregister the Mcast group on the SM\n");
--					return 1;
--				}
--			}
--		}
--
--		if (user_parm->machine == CLIENT || user_parm->duplex) {
--
--			mcg_params->mgid = rem_dest->gid;
--			if (!strcmp(link_layer_str(user_parm->link_type),"IB")) {
--				if (join_multicast_group(SUBN_ADM_METHOD_DELETE,mcg_params)) {
--					fprintf(stderr,"Couldn't Unregister the Mcast group on the SM\n");
--					return 1;
--				}
--			}
--
--		}
--	}	
--
--	if (ctx->ah) {
--		if (ibv_destroy_ah(ctx->ah)) {
--			fprintf(stderr, "failed to destroy AH\n");
--			test_result = 1;
--		}
--	}
--
--	for(i = 0; i < user_parm->num_of_qps; i++) {
--		if (ibv_destroy_qp(ctx->qp[i])) {
--			test_result = 1;
--		}
--	}
--	free(ctx->qp);
--
--	if (ibv_destroy_cq(ctx->cq)) {
--		test_result = 1;
--	}
--
--	for(i = 0; i < user_parm->num_of_qps; i++) {
--
--		if (ibv_dereg_mr(ctx->mr[i])) {
--			test_result = 1;
--		}
--		free(ctx->buf[i]);
--	}
--	
--	if (ibv_dealloc_pd(ctx->pd)) {
--		test_result = 1;
--	}
--
--	if (ctx->channel) {
--		if (ibv_destroy_comp_channel(ctx->channel)) {
--			test_result = 1;
--		}
--	}
--	
--	if (ibv_close_device(ctx->context)) {
--		test_result = 1;
--	}
--
--	if (user_parm->machine == SERVER || user_parm->duplex) {
--		free(ctx->rwr);
--		free(ctx->sge_list);
--		free(ctx->my_addr);
--	}
--
--	free(ctx->mr);
--	free(ctx->buf);
--	free(ctx);
--	free(tposted);
--    free(tcompleted);
--	return test_result;
--}
--
--/****************************************************************************** 
-- *
-- ******************************************************************************/
--static struct pingpong_context *pp_init_ctx(struct ibv_device *ib_dev,
--											struct perftest_parameters *user_parm) {
--
--	int i,m_size;
--	int duplex_ind;
--	struct pingpong_context *ctx;
--
--	ALLOCATE(ctx,struct pingpong_context,1);
--	ALLOCATE(ctx->buf,void*,user_parm->num_of_qps);
--	ALLOCATE(ctx->mr,struct ibv_mr*,user_parm->num_of_qps);
--
--	ctx->ah       = NULL;
--	ctx->channel  = NULL;
--
--	duplex_ind = (user_parm->duplex && !user_parm->use_mcg) ? 2 : 1;
--
--	ctx->context = ibv_open_device(ib_dev);
--	if (!ctx->context) {
--		fprintf(stderr, "Couldn't get context for %s\n",
--			ibv_get_device_name(ib_dev));
--		return NULL;
--	}
--
--	// Configure the Link MTU acoording to the user or the active mtu.
--	if (ctx_set_mtu(ctx->context,user_parm)) {
--		fprintf(stderr, "Couldn't set the link layer\n");
--		return NULL;
--	}
--
--	if (user_parm->connection_type == UD && user_parm->size > MTU_SIZE(user_parm->curr_mtu)) {	 
--		printf(" Max msg size in UD is MTU - %d . changing to MTU\n",MTU_SIZE(user_parm->curr_mtu));
--		user_parm->size = MTU_SIZE(user_parm->curr_mtu);
--	}
--
--	if (is_dev_hermon(ctx->context) != NOT_HERMON && user_parm->inline_size != 0)
--		user_parm->inline_size = 0;
--
--	printf(" Inline data is used up to %d bytes message\n", user_parm->inline_size);
--
--	ctx->size = user_parm->size;
--
--	// Finds the link type and configure the HCA accordingly.
--	if (ctx_set_link_layer(ctx->context,user_parm)) {
--		fprintf(stderr, " Couldn't set the link layer\n");
--		return NULL;
--	}
--	
--	if (user_parm->use_event) {
--		ctx->channel = ibv_create_comp_channel(ctx->context);
--		if (!ctx->channel) {
--			fprintf(stderr, "Couldn't create completion channel\n");
--			return NULL;
--		}
--	} else
--		ctx->channel = NULL;                  
--
--	ctx->pd = ibv_alloc_pd(ctx->context);
--	if (!ctx->pd) {
--		fprintf(stderr, "Couldn't allocate PD\n");
--		return NULL;
--	}
--
--	for (i = 0; i < user_parm->num_of_qps; i++) {
--
--		m_size = (BUFF_SIZE(user_parm->size) + IF_UD_ADD(user_parm->connection_type))*duplex_ind;
--		ctx->buf[i] = memalign(page_size,m_size);
--		if (!ctx->buf[i]) {
--			fprintf(stderr, "Couldn't allocate work buf.\n");
--			return NULL;
--		}
--		memset(ctx->buf[i],0,m_size);
--
--		// We dont really want IBV_ACCESS_LOCAL_WRITE, but IB spec says :
--		// The Consumer is not allowed to assign Remote Write or Remote Atomic to
--		// a Memory Region that has not been assigned Local Write. 
--		ctx->mr[i] = ibv_reg_mr(ctx->pd,
--								ctx->buf[i],
--								m_size,
--								IBV_ACCESS_REMOTE_WRITE | 
--								IBV_ACCESS_LOCAL_WRITE);
--
--		if (!ctx->mr[i]) {
--			fprintf(stderr, "Couldn't allocate MR\n");
--			return NULL;
--		}
--	}
--
--	// Create the CQ according to Client/Server or Duplex setting.
--	ctx->cq = ctx_cq_create(ctx->context,ctx->channel,user_parm);
--	if (ctx->cq == NULL) {
--		fprintf(stderr, "Couldn't create CQ \n");
--		return NULL;
--	}
--
--	ALLOCATE(ctx->qp,struct ibv_qp*,user_parm->num_of_qps);
--	
--	for(i=0; i < user_parm->num_of_qps; i++) {
--		ctx->qp[i] = ctx_qp_create(ctx->pd,ctx->cq,ctx->cq,user_parm);
--		if (ctx->qp[i] == NULL) {
--			return NULL;
--		}
--
--		if(ctx_modify_qp_to_init(ctx->qp[i],user_parm)) {
--			return NULL;
--		}
--	}
--
--	return ctx;
--}
--
--/****************************************************************************** 
-- *
-- ******************************************************************************/
--static int pp_connect_ctx(struct pingpong_context *ctx,int my_psn,
--			              struct pingpong_dest *dest, 
--						  struct perftest_parameters *user_parm)
--{
--	struct ibv_qp_attr attr;
--	memset(&attr, 0, sizeof attr);
--	int i;
--
--	attr.qp_state 		= IBV_QPS_RTR;
--	attr.path_mtu       = user_parm->curr_mtu;
--    attr.dest_qp_num    = dest->qpn;
--	attr.rq_psn         = dest->psn;
--	attr.ah_attr.dlid   = dest->lid;
--	if (user_parm->connection_type == RC) {
--		attr.max_dest_rd_atomic     = 1;
--		attr.min_rnr_timer          = 12;
--	}
--	if (user_parm->gid_index < 0) {
--		attr.ah_attr.is_global  = 0;
--		attr.ah_attr.sl         = user_parm->sl;
--	} else {
--		attr.ah_attr.is_global  = 1;
--		attr.ah_attr.grh.dgid   = dest->gid;
--		attr.ah_attr.grh.sgid_index = user_parm->gid_index;
--		attr.ah_attr.grh.hop_limit = 1;
--		attr.ah_attr.sl         = 0;
--	}
--	attr.ah_attr.src_path_bits = 0;
--	attr.ah_attr.port_num   = user_parm->ib_port;
--	
--	if (user_parm->connection_type == RC) {
--		if (ibv_modify_qp(ctx->qp[0], &attr,
--				  IBV_QP_STATE              |
--				  IBV_QP_AV                 |
--				  IBV_QP_PATH_MTU           |
--				  IBV_QP_DEST_QPN           |
--				  IBV_QP_RQ_PSN             |
--				  IBV_QP_MIN_RNR_TIMER      |
--				  IBV_QP_MAX_DEST_RD_ATOMIC)) {
--			fprintf(stderr, "Failed to modify RC QP to RTR\n");
--			return 1;
--		}
--		attr.timeout            = user_parm->qp_timeout;
--		attr.retry_cnt          = 7;
--		attr.rnr_retry          = 7;
--	} else if (user_parm->connection_type == UC) {
--		if (ibv_modify_qp(ctx->qp[0], &attr,
--				  IBV_QP_STATE              |
--				  IBV_QP_AV                 |
--				  IBV_QP_PATH_MTU           |
--				  IBV_QP_DEST_QPN           |
--				  IBV_QP_RQ_PSN)) {
--			fprintf(stderr, "Failed to modify UC QP to RTR\n");
--			return 1;
--		}
--	} 
--	 
--	else {
--		for (i = 0; i < user_parm->num_of_qps; i++) {
--			if (ibv_modify_qp(ctx->qp[i],&attr,IBV_QP_STATE )) {
--				fprintf(stderr, "Failed to modify UD QP to RTR\n");
--				return 1;
--			}
--		}
--		if (user_parm->machine == CLIENT || user_parm->duplex) {
--			ctx->ah = ibv_create_ah(ctx->pd,&attr.ah_attr);
--			if (!ctx->ah) {
--				fprintf(stderr, "Failed to create AH for UD\n");
--				return 1;
--			}
--		}
--	}
--
--	if (user_parm->machine == CLIENT || user_parm->duplex) {
--
--		attr.qp_state 	    = IBV_QPS_RTS;
--		attr.sq_psn 	    = my_psn;
--		if (user_parm->connection_type == RC) {
--			attr.max_rd_atomic  = 1;
--			if (ibv_modify_qp(ctx->qp[0], &attr,
--					IBV_QP_STATE              |
--					IBV_QP_SQ_PSN             |
--					IBV_QP_TIMEOUT            |
--					IBV_QP_RETRY_CNT          |
--					IBV_QP_RNR_RETRY          |
--					IBV_QP_MAX_QP_RD_ATOMIC)) {
--				fprintf(stderr, "Failed to modify RC QP to RTS\n");
--				return 1;
--			}
--
--		} else {
--			if(ibv_modify_qp(ctx->qp[0],&attr,IBV_QP_STATE |IBV_QP_SQ_PSN)) {
--				fprintf(stderr, "Failed to modify UC QP to RTS\n");
--				return 1;
--			}
--		}
--	}
--
--	return 0;
--}
--
--/****************************************************************************** 
-- *
-- ******************************************************************************/
--static int set_recv_wqes(struct pingpong_context *ctx,
--						 struct perftest_parameters *user_param) {
--						
--	int					i,j,buff_size;
--	int 				duplex_ind;
--	struct ibv_recv_wr  *bad_wr_recv;
--
--	i = (user_param->duplex && user_param->use_mcg) ? 1 : 0;
--	duplex_ind = (user_param->duplex && !user_param->use_mcg) ? 1 : 0;
--
--	buff_size = BUFF_SIZE(ctx->size) + IF_UD_ADD(user_param->connection_type);
--
--	while (i < user_param->num_of_qps) {
--
--		ctx->sge_list[i].addr   = (uintptr_t)ctx->buf[i] + duplex_ind*buff_size;
--
--		if (user_param->connection_type == UD) 
--			ctx->sge_list[i].addr += (CACHE_LINE_SIZE - UD_ADDITION);
--
--		ctx->sge_list[i].length = SIZE(user_param->connection_type,user_param->size);
--		ctx->sge_list[i].lkey   = ctx->mr[i]->lkey;
--		ctx->rwr[i].sg_list     = &ctx->sge_list[i];
--		ctx->rwr[i].wr_id       = i;
--		ctx->rwr[i].next        = NULL;
--		ctx->rwr[i].num_sge	    = MAX_RECV_SGE;
--		ctx->my_addr[i]		    = (uintptr_t)ctx->buf[i] + duplex_ind*buff_size;
--		
--		for (j = 0; j < user_param->rx_depth; ++j) {
--
--			if (ibv_post_recv(ctx->qp[i],&ctx->rwr[i],&bad_wr_recv)) {
--				fprintf(stderr, "Couldn't post recv Qp = %d: counter=%d\n",i,j);
--				return 1;
--			}
--
--			if (user_param->size <= (CYCLE_BUFFER / 2))
--				increase_loc_addr(&ctx->sge_list[i],user_param->size,j,ctx->my_addr[i],user_param->connection_type);
--		}
--		i++;
--	}
--	return 0;
--}
--
--/****************************************************************************** 
-- *
-- ******************************************************************************/
--static void set_send_wqe(struct pingpong_context *ctx,int rem_qpn,
--						 struct perftest_parameters *user_param) {
--
--	ctx->list.addr     = (uintptr_t)ctx->buf[0];
--	ctx->list.lkey 	   = ctx->mr[0]->lkey;
--
--	ctx->wr.sg_list    = &ctx->list;
--	ctx->wr.num_sge    = 1;
--	ctx->wr.opcode     = IBV_WR_SEND;
--	ctx->wr.next       = NULL;
--	ctx->wr.wr_id      = PINGPONG_SEND_WRID;
--	ctx->wr.send_flags = IBV_SEND_SIGNALED;
--
--	if (user_param->connection_type == UD) {
--		ctx->wr.wr.ud.ah          = ctx->ah;
--		ctx->wr.wr.ud.remote_qkey = DEF_QKEY;
--		ctx->wr.wr.ud.remote_qpn  = rem_qpn;
--	}
--}
--
--/****************************************************************************** 
-- *
-- ******************************************************************************/
--static int pp_drain_qp(struct pingpong_context *ctx,
--						struct perftest_parameters *user_param,
--						int psn,struct pingpong_dest *dest,
--						struct mcast_parameters *mcg_params) {
--
--	struct ibv_qp_attr attr;
--	struct ibv_wc      wc;
--	int                i;
--
--	memset(&attr, 0, sizeof attr);
--	attr.qp_state = IBV_QPS_ERR;
--
--	for (i = 0; i <  user_param->num_of_qps; i++) {
--
--		if (ibv_modify_qp(ctx->qp[i],&attr,IBV_QP_STATE)) {
--			fprintf(stderr, "Failed to modify RC QP to ERR\n");
--			return 1;
--		}
--
--		while (ibv_poll_cq(ctx->cq,1,&wc));
--   
--		attr.qp_state = IBV_QPS_RESET;
--
--		if (ibv_modify_qp(ctx->qp[i],&attr,IBV_QP_STATE)) {
--			fprintf(stderr, "Failed to modify RC QP to RESET\n");
--			return 1;
--		}
--
--		if(ctx_modify_qp_to_init(ctx->qp[i],user_param)) {
--			return 1;
--		}
--
--		if (user_param->use_mcg) {
--
--			if ((!user_param->duplex && user_param->machine == SERVER) || (user_param->duplex && i > 0)) {
--				if (ibv_attach_mcast(ctx->qp[i],&mcg_params->mgid,mcg_params->mlid)) {
--					fprintf(stderr, "Couldn't attach QP to MultiCast group");
--					return 1;
--				}
--			}
--		}
--	}
--
--	if (pp_connect_ctx(ctx,psn,dest,user_param)) {
--		return 1;
--	}
--
--	return 0;
--}
--
--/****************************************************************************** 
-- *
-- ******************************************************************************/
--static void print_report(struct perftest_parameters *user_param) {
--
--	double cycles_to_units;
--	unsigned long tsize;	/* Transferred size, in megabytes */
--	int i, j;
--	int opt_posted = 0, opt_completed = 0;
--	cycles_t opt_delta;
--	cycles_t t;
--
--
--	opt_delta = tcompleted[opt_posted] - tposted[opt_completed];
--
--	if (user_param->noPeak == OFF) {
--		/* Find the peak bandwidth, unless asked not to in command line */
--		for (i = 0; i < user_param->iters; ++i)
--			for (j = i; j < user_param->iters; ++j) {
--				t = (tcompleted[j] - tposted[i]) / (j - i + 1);
--				if (t < opt_delta) {
--					opt_delta  = t;
--					opt_posted = i;
--					opt_completed = j;
--				}
--			}
--	}
--
--	cycles_to_units = get_cpu_mhz(user_param->cpu_freq_f) * 1000000;
--
--	tsize = user_param->duplex ? 2 : 1;
--	tsize = tsize * user_param->size;
--	printf(REPORT_FMT,user_param->size,user_param->iters,(user_param->noPeak == OFF) * tsize * cycles_to_units / opt_delta / 0x100000,
--	       tsize * user_param->iters * cycles_to_units /(tcompleted[user_param->iters - 1] - tposted[0]) / 0x100000);
--}
--
--/****************************************************************************** 
-- * Important note :															  
-- * In case of UD/UC this is NOT the way to measureBW since we are running with 
-- * loop on the send side , while we should run on the recieve side or enable 
-- * retry in SW , Since the sender may be faster than the reciver.
-- * Although	we had posted recieve it is not enough and might end this will
-- * result in deadlock of test since both sides are stuck on poll cq.
-- * In this test i do not solve this for the general test ,need to write
-- * seperate test for UC/UD but in case the tx_depth is ~1/3 from the
-- * number of iterations this should be ok .
-- * Also note that the sender is limited in the number of send, ans
-- * i try to make the reciver full .
-- ******************************************************************************/
--int run_iter_bi(struct pingpong_context *ctx, 
--				struct perftest_parameters *user_param)  {
--
--	int                     scnt    = 0;
--	int 					ccnt    = 0;
--	int 					rcnt    = 0;
--	int 					i       = 0;
--	int 					num_of_qps = user_param->num_of_qps;
--	int 					ne;
--	struct ibv_wc 			*wc          = NULL;
--	int 					*rcnt_for_qp = NULL;
--	struct ibv_recv_wr      *bad_wr_recv = NULL;
--	struct ibv_send_wr 		*bad_wr      = NULL;
--
--	ALLOCATE(rcnt_for_qp,int,user_param->num_of_qps);
--	ALLOCATE(wc,struct ibv_wc,DEF_WC_SIZE);
--	memset(rcnt_for_qp,0,sizeof(int)*user_param->num_of_qps);
--
--	if (user_param->use_mcg)
--		num_of_qps--; 
--	
--	// Set the length of the scatter in case of ALL option.
--	ctx->list.length = user_param->size;
--	ctx->list.addr   = (uintptr_t)ctx->buf[0];
--	ctx->wr.send_flags = IBV_SEND_SIGNALED;
--	
--	if (user_param->size <= user_param->inline_size) 
--		ctx->wr.send_flags |= IBV_SEND_INLINE; 
--
--	while (ccnt < user_param->iters || rcnt < user_param->iters) {
--                
--		while (scnt < user_param->iters && (scnt - ccnt) < user_param->tx_depth / 2) {
--
--			if (scnt %  CQ_MODERATION == 0 && CQ_MODERATION > 1)
--				ctx->wr.send_flags &= ~IBV_SEND_SIGNALED;
--
--			tposted[scnt] = get_cycles();
--			if (ibv_post_send(ctx->qp[0],&ctx->wr, &bad_wr)) {
--				fprintf(stderr, "Couldn't post send: scnt=%d\n",scnt);
--				return 1;
--			}
--
--			if (user_param->size <= (CYCLE_BUFFER / 2))
--				increase_loc_addr(&ctx->list,user_param->size,scnt,(uintptr_t)ctx->buf[0],0);
--
--			++scnt;
--
--			if ((scnt % CQ_MODERATION) == (CQ_MODERATION - 1) || scnt == (user_param->iters - 1)) 
--				ctx->wr.send_flags |= IBV_SEND_SIGNALED;
--		}
--
--		if (user_param->use_event) {
--
--			if (ctx_notify_events(ctx->cq,ctx->channel)) {
--				fprintf(stderr,"Failed to notify events to CQ");
--				return 1;
--			}
--		}
--
--		do {
--			ne = ibv_poll_cq(ctx->cq,DEF_WC_SIZE,wc);
--			if (ne > 0) {
--				for (i = 0; i < ne; i++) {
--					
--					if (wc[i].status != IBV_WC_SUCCESS)
--						 NOTIFY_COMP_ERROR_SEND(wc[i],scnt,ccnt);
--
--					if ((int) wc[i].wr_id == PINGPONG_SEND_WRID) {
--						ccnt += CQ_MODERATION;
--						if (ccnt >= user_param->iters - 1) 
--							tcompleted[user_param->iters - 1] = get_cycles();
--
--						else 
--							tcompleted[ccnt - 1] = get_cycles();
--					}
--
--					else {
--
--						rcnt_for_qp[wc[i].wr_id]++;
--						rcnt++;
--						if (ibv_post_recv(ctx->qp[wc[i].wr_id],&ctx->rwr[wc[i].wr_id],&bad_wr_recv)) {
--							fprintf(stderr, "Couldn't post recv Qp=%d rcnt=%d\n",(int)wc[i].wr_id , rcnt_for_qp[wc[i].wr_id]);
--							return 15;
--						}
--
--						if (user_param->size <= (CYCLE_BUFFER / 2))
--							increase_loc_addr(&ctx->sge_list[wc[i].wr_id],
--							  user_param->size,rcnt_for_qp[wc[i].wr_id] + user_param->rx_depth - 1,
--							  ctx->my_addr[wc[i].wr_id],user_param->connection_type);	
--					}
--				}
--			}
--		} while (ne > 0);
--
--		if (ne < 0) {
--			fprintf(stderr, "poll CQ failed %d\n", ne);
--			return 1;
--		}
--	}
--	
--	if (user_param->size <= user_param->inline_size) 
--		ctx->wr.send_flags &= ~IBV_SEND_INLINE;
--	
--	free(rcnt_for_qp);
--	free(wc);
--	return 0;
--}
--
--/****************************************************************************** 
-- *
-- ******************************************************************************/
--int run_iter_uni_server(struct pingpong_context *ctx, 
--						struct perftest_parameters *user_param) {
--
--	int 				rcnt = 0;
--	int 				ne,i;
--	int                 *rcnt_for_qp = NULL;
--	struct ibv_wc 		*wc          = NULL;
--	struct ibv_recv_wr  *bad_wr_recv = NULL;
--
--	ALLOCATE(wc,struct ibv_wc,DEF_WC_SIZE);
--	ALLOCATE(rcnt_for_qp,int,user_param->num_of_qps);
--
--	memset(rcnt_for_qp,0,sizeof(int)*user_param->num_of_qps);
--
--	while (rcnt < user_param->iters) {
--
--		if (user_param->use_event) {
--			if (ctx_notify_events(ctx->cq,ctx->channel)) {
--				fprintf(stderr ," Failed to notify events to CQ");
--				return 1;
--			}
--		}
--		
--		do {
--			ne = ibv_poll_cq(ctx->cq,DEF_WC_SIZE,wc);
--			if (ne > 0) {
--				for (i = 0; i < ne; i++) {
--					
--					if (wc[i].status != IBV_WC_SUCCESS) 
--						NOTIFY_COMP_ERROR_RECV(wc[i],rcnt_for_qp[wc[i].wr_id]);
--						
--					rcnt_for_qp[wc[i].wr_id]++;
--					tcompleted[rcnt++] = get_cycles();
--
--				   	if (ibv_post_recv(ctx->qp[wc[i].wr_id],&ctx->rwr[wc[i].wr_id],&bad_wr_recv)) {
--						fprintf(stderr, "Couldn't post recv Qp=%d rcnt=%d\n",(int)wc[i].wr_id,rcnt_for_qp[wc[i].wr_id]);
--						return 15;
--					}
--
--					if (user_param->size <= (CYCLE_BUFFER / 2))
--						increase_loc_addr(&ctx->sge_list[wc[i].wr_id],user_param->size,
--										  rcnt_for_qp[wc[i].wr_id] + user_param->rx_depth,
--										  ctx->my_addr[wc[i].wr_id],user_param->connection_type);						
--				}
--			}
--		} while (ne > 0);
--
--		if (ne < 0) {
--			fprintf(stderr, "Poll Recieve CQ failed %d\n", ne);
--			return 1;
--		}
--	}
--
--	tposted[0] = tcompleted[0];
--	free(wc);
--	free(rcnt_for_qp);
--	return 0;
--}
--
--/****************************************************************************** 
-- *
-- ******************************************************************************/
--int run_iter_uni_client(struct pingpong_context *ctx, 
--						struct perftest_parameters *user_param) {
--
--	int 		       ne;
--	int 			   i    = 0;
--	int                scnt = 0;
--	int                ccnt = 0;
--	struct ibv_wc      *wc     = NULL;
--	struct ibv_send_wr *bad_wr = NULL;
--
--	ALLOCATE(wc,struct ibv_wc,DEF_WC_SIZE);
--
--	// Set the lenght of the scatter in case of ALL option.
--	ctx->list.length = user_param->size;
--	ctx->list.addr   = (uintptr_t)ctx->buf[0];
--	ctx->wr.send_flags = IBV_SEND_SIGNALED; 
--
--	if (user_param->size <= user_param->inline_size) 
--		ctx->wr.send_flags |= IBV_SEND_INLINE; 
--	
--
--	while (scnt < user_param->iters || ccnt < user_param->iters) {
--		while (scnt < user_param->iters && (scnt - ccnt) < user_param->tx_depth ) {
--
--			if (scnt %  CQ_MODERATION == 0 && CQ_MODERATION > 1)
--				ctx->wr.send_flags &= ~IBV_SEND_SIGNALED;
--
--			tposted[scnt] = get_cycles();
--			if (ibv_post_send(ctx->qp[0], &ctx->wr, &bad_wr)) {
--				fprintf(stderr, "Couldn't post send: scnt=%d\n",scnt);
--				return 1;
--			}
--
--			if (user_param->size <= (CYCLE_BUFFER / 2))
--				increase_loc_addr(&ctx->list,user_param->size,scnt,(uintptr_t)ctx->buf[0],0);
--
--			scnt++;
--
--			if ((scnt % CQ_MODERATION) == (CQ_MODERATION - 1) || scnt == (user_param->iters - 1)) 
--				ctx->wr.send_flags |= IBV_SEND_SIGNALED;
--		}
--
--		if (ccnt < user_param->iters) {	
--			
--			if (user_param->use_event) {
--				if (ctx_notify_events(ctx->cq,ctx->channel)) {
--					fprintf(stderr , " Failed to notify events to CQ");
--					return 1;
--				}
--			} 
--			do {
--				ne = ibv_poll_cq(ctx->cq,DEF_WC_SIZE,wc);
--				if (ne > 0) {
--					for (i = 0; i < DEF_WC_SIZE; i++) {
--
--						if (wc[i].status != IBV_WC_SUCCESS) 
--							NOTIFY_COMP_ERROR_SEND(wc[i],scnt,ccnt);
--			
--						ccnt += CQ_MODERATION;
--						if (ccnt >= user_param->iters - 1) 
--							tcompleted[user_param->iters - 1] = get_cycles();
--
--						else 
--							tcompleted[ccnt - 1] = get_cycles();
--					}
--				}
--                         
--					
--			} while (ne > 0);
--
--			if (ne < 0) {
--				fprintf(stderr, "poll CQ failed\n");
--				return 1;
--			}
--		}
--	}
--
--	if (user_param->size <= user_param->inline_size) 
--		ctx->wr.send_flags &= ~IBV_SEND_INLINE;
--
--	free(wc);
--	return 0;
--}
--
--/****************************************************************************** 
-- *
-- ******************************************************************************/
--int main(int argc, char *argv[])
--{
--	struct ibv_device		 	*ib_dev = NULL;
--	struct pingpong_context  	*ctx;
--	struct pingpong_dest	 	my_dest,rem_dest;
--	struct perftest_parameters  user_param;
--	struct mcast_parameters     mcg_params;
--	int                      	i = 0;
--	int                      	size_max_pow = 24;
--	int							size_of_arr;
--
--	// Pointer to The relevent function of run_iter according to machine type.
--	int (*ptr_to_run_iter_uni)(struct pingpong_context*,struct perftest_parameters*);
--
--	/* init default values to user's parameters */
--	memset(&user_param, 0 , sizeof(struct perftest_parameters));
--	memset(&mcg_params, 0 , sizeof(struct mcast_parameters));
--	memset(&my_dest   , 0 , sizeof(struct pingpong_dest));
--	memset(&rem_dest   , 0 , sizeof(struct pingpong_dest));
-- 
--	user_param.verb    = SEND;
--	user_param.tst     = BW;
--	user_param.version = VERSION;
--
--	if (parser(&user_param,argv,argc)) 
--		return 1;
--
--	printf(RESULT_LINE);
--
--	user_param.rx_depth = (user_param.iters < user_param.rx_depth) ? user_param.iters : user_param.rx_depth ;
--
--    if (user_param.use_mcg) {
--
--		user_param.connection_type = UD;
--		if (user_param.duplex) {
--			user_param.num_of_qps++;
--			printf("                    Send Bidirectional BW  -  Multicast Test\n");
--		}
--		else {
--			printf("                    Send BW  -  Multicast Test\n");
--			if (user_param.machine == CLIENT)
--				user_param.num_of_qps = 1;
--		}
--    }
--
--	else if (user_param.duplex) {
--		    printf("                    Send Bidirectional BW Test\n");
--	} else 
--		    printf("                    Send BW Test\n");
--
--	if (user_param.use_event) 
--		printf(" Test with events.\n");
--
--	if (user_param.connection_type == RC)
--		printf(" Connection type : RC\n");
--	else if (user_param.connection_type == UC)
--		printf(" Connection type : UC\n");
--	else{
--		printf(" Connection type : UD\n");
--	}
--	
--	// Done with parameter parsing. Perform setup.
--	if (user_param.all == ON) {
--		// since we run all sizes 
--		user_param.size = MAX_SIZE;
--	}
--
--	srand48(getpid() * time(NULL));
--	page_size = sysconf(_SC_PAGESIZE);
--
--	ib_dev = ctx_find_dev(user_param.ib_devname);
--	if (!ib_dev)
--		return 7;
--
--	mcg_params.ib_devname = ibv_get_device_name(ib_dev);
--
--	ctx = pp_init_ctx(ib_dev,&user_param);
--	if (!ctx)
--		return 1;
--
--	// Set up the Connection.
--	if (set_up_connection(ctx,&user_param,&my_dest,&mcg_params)) {
--		fprintf(stderr," Unable to set up socket connection\n");
--		return 1;
--	}	
--
--	// Init the connection and print the local data.
--	if (init_connection(&user_param,&my_dest)) {
--		fprintf(stderr," Unable to init the socket connection\n");
--		return 1;
--	}
--
--	// shaking hands and gather the other side info.
--    if (ctx_hand_shake(&user_param,&my_dest,&rem_dest)) {
--        fprintf(stderr,"Failed to exchange date between server and clients\n");
--        return 1;
--        
--    }
--	// For printing only MGID in the remote side.
--	user_param.side = REMOTE;
--	ctx_print_pingpong_data(&rem_dest,&user_param);
--
--	// Joining the Send side port the Mcast gid
--	if (user_param.use_mcg && (user_param.machine == CLIENT || user_param.duplex)) {
--		memcpy(mcg_params.mgid.raw, rem_dest.gid.raw, 16);
--		if (set_mcast_group(ctx,&user_param,&mcg_params)) {
--			fprintf(stderr," Unable to Join Sender to Mcast gid\n");
--			return 1;
--		}
--	}
--
--	// Prepare IB resources for rtr/rts.
--	if (pp_connect_ctx(ctx,my_dest.psn,&rem_dest,&user_param)) {
--		fprintf(stderr," Unable to Connect the HCA's through the link\n");
--		return 1;
--	}
--	
--	// shaking hands and gather the other side info.
--    if (ctx_hand_shake(&user_param,&my_dest,&rem_dest)) {
--        fprintf(stderr,"Failed to exchange date between server and clients\n");
--        return 1;
--        
--    }
--
--	if (user_param.use_event) {
--		if (ibv_req_notify_cq(ctx->cq, 0)) {
--			fprintf(stderr, " Couldn't request CQ notification\n");
--			return 1;
--		} 
--	}
--
--	printf(RESULT_LINE);
--	printf(RESULT_FMT);
--
--	size_of_arr = (user_param.duplex) ? 1 : user_param.num_of_qps;
--
--	ALLOCATE(tposted,cycles_t,user_param.iters*size_of_arr);
--	ALLOCATE(tcompleted,cycles_t,user_param.iters*size_of_arr);
--
--	if (user_param.machine == SERVER || user_param.duplex) {
--		ALLOCATE(ctx->rwr,struct ibv_recv_wr,user_param.num_of_qps);
--		ALLOCATE(ctx->sge_list,struct ibv_sge,user_param.num_of_qps);
--		ALLOCATE(ctx->my_addr ,uint64_t ,user_param.num_of_qps);
--	}
--
--	ptr_to_run_iter_uni = (user_param.machine == CLIENT) ?	&run_iter_uni_client : &run_iter_uni_server;
--	
--	if (user_param.machine == SERVER && !user_param.duplex) {
--		user_param.noPeak = ON;
--	}
--
--	if (user_param.machine == CLIENT || user_param.duplex) {
--		set_send_wqe(ctx,rem_dest.qpn,&user_param);
--	}
--
--	if (user_param.all == ON) {
--
--		if (user_param.connection_type == UD) 
--		   size_max_pow =  (int)UD_MSG_2_EXP(MTU_SIZE(user_param.curr_mtu)) + 1;
--
--		for (i = 1; i < size_max_pow ; ++i) {
--			user_param.size = 1 << i;
--
--			if (user_param.machine == SERVER || user_param.duplex) {
--				if (set_recv_wqes(ctx,&user_param)) {
--					fprintf(stderr," Failed to post receive recv_wqes\n");
--					return 1;
--				}
--			}
--
--			if (ctx_hand_shake(&user_param,&my_dest,&rem_dest)) {
--				fprintf(stderr,"Failed to exchange date between server and clients\n");
--				return 1;
--			}
--
--			if (user_param.duplex) {
--				if(run_iter_bi(ctx,&user_param))
--					return 17;
--			} else {
--				if((*ptr_to_run_iter_uni)(ctx,&user_param))
--					return 17;
--			}
--			print_report(&user_param);
--
--			if (pp_drain_qp(ctx,&user_param,my_dest.psn,&rem_dest,&mcg_params)) {
--				fprintf(stderr,"Failed to drain Recv queue (performance optimization)\n");
--				return 1;
--			}
--
--			if (ctx_hand_shake(&user_param,&my_dest,&rem_dest)) {
--				fprintf(stderr,"Failed to exchange date between server and clients\n");
--				return 1;
--			}
--        
--		}
--
--	} else {
--
--		if (user_param.machine == SERVER || user_param.duplex) {
--			if (set_recv_wqes(ctx,&user_param)) {
--				fprintf(stderr," Failed to post receive recv_wqes\n");
--				return 1;
--			}
--		}
--
--		if (ctx_hand_shake(&user_param,&my_dest,&rem_dest)) {
--			fprintf(stderr,"Failed to exchange date between server and clients\n");
--			return 1;
--		}
--
--		if (user_param.duplex) {
--			if(run_iter_bi(ctx,&user_param))
--				return 18;
--
--		} else {
--			if((*ptr_to_run_iter_uni)(ctx,&user_param))
--				return 18;
--		}
--
--		print_report(&user_param);	
--	}
--		
--	if (ctx_close_connection(&user_param,&my_dest,&rem_dest)) {
--		fprintf(stderr," Failed to close connection between server and client\n");
--		return 1;
--	}
--
--	printf(RESULT_LINE);
--	return destroy_ctx_resources(ctx,&user_param,&my_dest,&rem_dest,&mcg_params);
--}
-+/*
-+ * Copyright (c) 2005 Topspin Communications.  All rights reserved.
-+ * Copyright (c) 2005 Mellanox Technologies Ltd.  All rights reserved.
-+ * Copyright (c) 2009 HNR Consulting.  All rights reserved.
-+ *
-+ * This software is available to you under a choice of one of two
-+ * licenses.  You may choose to be licensed under the terms of the GNU
-+ * General Public License (GPL) Version 2, available from the file
-+ * COPYING in the main directory of this source tree, or the
-+ * OpenIB.org BSD license below:
-+ *
-+ *     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.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-+ * SOFTWARE.
-+ *
-+ * $Id$
-+ */
-+
-+#if HAVE_CONFIG_H
-+#  include <config.h>
-+#endif /* HAVE_CONFIG_H */
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <limits.h>
-+#include <malloc.h>
-+#include <getopt.h>
-+#include <time.h>
-+#include <errno.h>
-+#include <infiniband/verbs.h>
-+
-+#include "get_clock.h"
-+#include "multicast_resources.h"
-+#include "perftest_resources.h"
-+
-+#define VERSION 2.1
-+
-+static int page_size;
-+cycles_t	*tposted;
-+cycles_t	*tcompleted;
-+
-+struct pingpong_context {
-+	struct ibv_context 		*context;
-+	struct ibv_comp_channel *channel;
-+	struct ibv_pd      		*pd;
-+	struct ibv_mr     		**mr;
-+	struct ibv_cq      		*cq;
-+	struct ibv_qp      		**qp;
-+	struct ibv_sge      	list;
-+	struct ibv_send_wr  	wr;
-+	struct ibv_sge 			*sge_list;
-+	struct ibv_recv_wr  	*rwr;
-+	struct ibv_ah			*ah;
-+	void               		**buf;
-+	unsigned            	size;
-+	uint64_t				*my_addr;
-+};
-+
-+/****************************************************************************** 
-+ *
-+ ******************************************************************************/
-+static int set_mcast_group(struct pingpong_context *ctx,
-+						   struct perftest_parameters *user_parm,
-+						   struct mcast_parameters *mcg_params) {
-+
-+	struct ibv_port_attr port_attr;
-+
-+	if (ibv_query_gid(ctx->context,user_parm->ib_port,user_parm->gid_index,&mcg_params->port_gid)) {
-+			return 1;
-+	}
-+		
-+	if (ibv_query_pkey(ctx->context,user_parm->ib_port,DEF_PKEY_IDX,&mcg_params->pkey)) {
-+		return 1;
-+	}
-+
-+	if (ibv_query_port(ctx->context,user_parm->ib_port,&port_attr)) {
-+		return 1;
-+	}
-+	mcg_params->sm_lid  = port_attr.sm_lid;
-+	mcg_params->sm_sl   = port_attr.sm_sl;
-+	mcg_params->ib_port = user_parm->ib_port;
-+	
-+	if (!strcmp(link_layer_str(user_parm->link_type),"IB")) {
-+		// Request for Mcast group create registery in SM.
-+		if (join_multicast_group(SUBN_ADM_METHOD_SET,mcg_params)) {
-+			fprintf(stderr,"Couldn't Register the Mcast group on the SM\n");
-+			return 1;
-+		}
-+	}
-+	return 0;
-+}
-+
-+/****************************************************************************** 
-+ *
-+ ******************************************************************************/
-+static int set_up_connection(struct pingpong_context *ctx,
-+							 struct perftest_parameters *user_parm,
-+							 struct pingpong_dest *my_dest,
-+							 struct mcast_parameters *mcg_params) {
-+
-+	int i = (user_parm->duplex) ? 1 : 0;
-+
-+	if (user_parm->use_mcg && (user_parm->duplex || user_parm->machine == SERVER)) {
-+
-+		set_multicast_gid(mcg_params,ctx->qp[0]->qp_num,(int)user_parm->machine);
-+		if (set_mcast_group(ctx,user_parm,mcg_params)) {
-+			return 1;
-+		}
-+		
-+		while (i < user_parm->num_of_qps) {
-+			if (ibv_attach_mcast(ctx->qp[i],&mcg_params->mgid,mcg_params->mlid)) {
-+				fprintf(stderr, "Couldn't attach QP to MultiCast group");
-+				return 1;
-+			}
-+			i++;
-+		}
-+
-+		mcg_params->mcast_state |= MCAST_IS_ATTACHED;
-+		my_dest->gid = mcg_params->mgid;
-+		my_dest->lid = mcg_params->mlid;
-+		my_dest->qpn = QPNUM_MCAST;
-+
-+	} else {
-+		if (user_parm->gid_index != -1) {
-+			if (ibv_query_gid(ctx->context,user_parm->ib_port,user_parm->gid_index,&my_dest->gid)) {
-+				return -1;
-+			}
-+		}
-+		my_dest->lid = ctx_get_local_lid(ctx->context,user_parm->ib_port);
-+		my_dest->qpn = ctx->qp[0]->qp_num;
-+	}
-+	my_dest->psn  = lrand48() & 0xffffff;
-+
-+	// We do not fail test upon lid above RoCE.
-+
-+	if (user_parm->gid_index < 0) {
-+		if (!my_dest->lid) {
-+			fprintf(stderr," Local lid 0x0 detected,without any use of gid. Is SM running?\n");
-+			return -1;
-+		}
-+	}
-+	return 0;
-+}
-+
-+/****************************************************************************** 
-+ *
-+ ******************************************************************************/
-+static int init_connection(struct perftest_parameters *params,
-+ 						   struct pingpong_dest *my_dest) {
-+
-+	params->side = LOCAL;
-+	ctx_print_pingpong_data(my_dest,params);
-+	
-+	if (params->machine == CLIENT) 
-+		params->sockfd = ctx_client_connect(params->servername,params->port);
-+	else 
-+		params->sockfd = ctx_server_connect(params->port);
-+	
-+		
-+	if(params->sockfd < 0) {
-+		fprintf(stderr,"Unable to open file descriptor for socket connection");
-+		return 1;
-+	}
-+	return 0;
-+}
-+
-+/****************************************************************************** 
-+ *
-+ ******************************************************************************/
-+static int destroy_ctx_resources(struct pingpong_context    *ctx, 
-+								 struct perftest_parameters *user_parm,
-+								 struct pingpong_dest		*my_dest,
-+								 struct pingpong_dest		*rem_dest,
-+								 struct mcast_parameters    *mcg_params)  {
-+
-+	int test_result = 0;
-+	int i = (user_parm->duplex) ? 1 : 0;
-+
-+	if (user_parm->use_mcg) {
-+
-+		if (user_parm->machine == SERVER || user_parm->duplex) {
-+			
-+			while (i < user_parm->num_of_qps) {
-+				if (ibv_detach_mcast(ctx->qp[i],&my_dest->gid,my_dest->lid)) {
-+					fprintf(stderr, "Couldn't deattach QP from MultiCast group\n");
-+					return 1;
-+				}
-+				i++;
-+			}
-+			mcg_params->mgid = my_dest->gid;
-+			if (!strcmp(link_layer_str(user_parm->link_type),"IB")) {
-+				if (join_multicast_group(SUBN_ADM_METHOD_DELETE,mcg_params)) {
-+					fprintf(stderr,"Couldn't Unregister the Mcast group on the SM\n");
-+					return 1;
-+				}
-+			}
-+		}
-+
-+		if (user_parm->machine == CLIENT || user_parm->duplex) {
-+
-+			mcg_params->mgid = rem_dest->gid;
-+			if (!strcmp(link_layer_str(user_parm->link_type),"IB")) {
-+				if (join_multicast_group(SUBN_ADM_METHOD_DELETE,mcg_params)) {
-+					fprintf(stderr,"Couldn't Unregister the Mcast group on the SM\n");
-+					return 1;
-+				}
-+			}
-+
-+		}
-+	}	
-+
-+	if (ctx->ah) {
-+		if (ibv_destroy_ah(ctx->ah)) {
-+			fprintf(stderr, "failed to destroy AH\n");
-+			test_result = 1;
-+		}
-+	}
-+
-+	for(i = 0; i < user_parm->num_of_qps; i++) {
-+		if (ibv_destroy_qp(ctx->qp[i])) {
-+			test_result = 1;
-+		}
-+	}
-+	free(ctx->qp);
-+
-+	if (ibv_destroy_cq(ctx->cq)) {
-+		test_result = 1;
-+	}
-+
-+	for(i = 0; i < user_parm->num_of_qps; i++) {
-+
-+		if (ibv_dereg_mr(ctx->mr[i])) {
-+			test_result = 1;
-+		}
-+		free(ctx->buf[i]);
-+	}
-+	
-+	if (ibv_dealloc_pd(ctx->pd)) {
-+		test_result = 1;
-+	}
-+
-+	if (ctx->channel) {
-+		if (ibv_destroy_comp_channel(ctx->channel)) {
-+			test_result = 1;
-+		}
-+	}
-+	
-+	if (ibv_close_device(ctx->context)) {
-+		test_result = 1;
-+	}
-+
-+	if (user_parm->machine == SERVER || user_parm->duplex) {
-+		free(ctx->rwr);
-+		free(ctx->sge_list);
-+		free(ctx->my_addr);
-+	}
-+
-+	free(ctx->mr);
-+	free(ctx->buf);
-+	free(ctx);
-+	free(tposted);
-+    free(tcompleted);
-+	return test_result;
-+}
-+
-+/****************************************************************************** 
-+ *
-+ ******************************************************************************/
-+static struct pingpong_context *pp_init_ctx(struct ibv_device *ib_dev,
-+											struct perftest_parameters *user_parm) {
-+
-+	int i,m_size;
-+	int duplex_ind;
-+	struct pingpong_context *ctx;
-+
-+	ALLOCATE(ctx,struct pingpong_context,1);
-+	ALLOCATE(ctx->buf,void*,user_parm->num_of_qps);
-+	ALLOCATE(ctx->mr,struct ibv_mr*,user_parm->num_of_qps);
-+
-+	ctx->ah       = NULL;
-+	ctx->channel  = NULL;
-+
-+	duplex_ind = (user_parm->duplex && !user_parm->use_mcg) ? 2 : 1;
-+
-+	ctx->context = ibv_open_device(ib_dev);
-+	if (!ctx->context) {
-+		fprintf(stderr, "Couldn't get context for %s\n",
-+			ibv_get_device_name(ib_dev));
-+		return NULL;
-+	}
-+
-+	// Configure the Link MTU acoording to the user or the active mtu.
-+	if (ctx_set_mtu(ctx->context,user_parm)) {
-+		fprintf(stderr, "Couldn't set the link layer\n");
-+		return NULL;
-+	}
-+
-+	if (user_parm->connection_type == UD && user_parm->size > MTU_SIZE(user_parm->curr_mtu)) {	 
-+		printf(" Max msg size in UD is MTU - %d . changing to MTU\n",MTU_SIZE(user_parm->curr_mtu));
-+		user_parm->size = MTU_SIZE(user_parm->curr_mtu);
-+	}
-+
+@@ -320,7 +320,7 @@
+ 		user_parm->size = MTU_SIZE(user_parm->curr_mtu);
+ 	}
+ 
+-	if (is_dev_hermon(ctx->context) != NOT_HERMON && user_parm->inline_size != 0)
 +	if (is_dev_hermon(ctx->context) == NOT_HERMON && user_parm->inline_size != 0)
-+		user_parm->inline_size = 0;
-+
-+	printf(" Inline data is used up to %d bytes message\n", user_parm->inline_size);
-+
-+	ctx->size = user_parm->size;
-+
-+	// Finds the link type and configure the HCA accordingly.
-+	if (ctx_set_link_layer(ctx->context,user_parm)) {
-+		fprintf(stderr, " Couldn't set the link layer\n");
-+		return NULL;
-+	}
-+	
-+	if (user_parm->use_event) {
-+		ctx->channel = ibv_create_comp_channel(ctx->context);
-+		if (!ctx->channel) {
-+			fprintf(stderr, "Couldn't create completion channel\n");
-+			return NULL;
-+		}
-+	} else
-+		ctx->channel = NULL;                  
-+
-+	ctx->pd = ibv_alloc_pd(ctx->context);
-+	if (!ctx->pd) {
-+		fprintf(stderr, "Couldn't allocate PD\n");
-+		return NULL;
-+	}
-+
-+	for (i = 0; i < user_parm->num_of_qps; i++) {
-+
-+		m_size = (BUFF_SIZE(user_parm->size) + IF_UD_ADD(user_parm->connection_type))*duplex_ind;
-+		ctx->buf[i] = memalign(page_size,m_size);
-+		if (!ctx->buf[i]) {
-+			fprintf(stderr, "Couldn't allocate work buf.\n");
-+			return NULL;
-+		}
-+		memset(ctx->buf[i],0,m_size);
-+
-+		// We dont really want IBV_ACCESS_LOCAL_WRITE, but IB spec says :
-+		// The Consumer is not allowed to assign Remote Write or Remote Atomic to
-+		// a Memory Region that has not been assigned Local Write. 
-+		ctx->mr[i] = ibv_reg_mr(ctx->pd,
-+								ctx->buf[i],
-+								m_size,
-+								IBV_ACCESS_REMOTE_WRITE | 
-+								IBV_ACCESS_LOCAL_WRITE);
-+
-+		if (!ctx->mr[i]) {
-+			fprintf(stderr, "Couldn't allocate MR\n");
-+			return NULL;
-+		}
-+	}
-+
-+	// Create the CQ according to Client/Server or Duplex setting.
-+	ctx->cq = ctx_cq_create(ctx->context,ctx->channel,user_parm);
-+	if (ctx->cq == NULL) {
-+		fprintf(stderr, "Couldn't create CQ \n");
-+		return NULL;
-+	}
-+
-+	ALLOCATE(ctx->qp,struct ibv_qp*,user_parm->num_of_qps);
-+	
-+	for(i=0; i < user_parm->num_of_qps; i++) {
-+		ctx->qp[i] = ctx_qp_create(ctx->pd,ctx->cq,ctx->cq,user_parm);
-+		if (ctx->qp[i] == NULL) {
-+			return NULL;
-+		}
-+
-+		if(ctx_modify_qp_to_init(ctx->qp[i],user_parm)) {
-+			return NULL;
-+		}
-+	}
-+
-+	return ctx;
-+}
-+
-+/****************************************************************************** 
-+ *
-+ ******************************************************************************/
-+static int pp_connect_ctx(struct pingpong_context *ctx,int my_psn,
-+			              struct pingpong_dest *dest, 
-+						  struct perftest_parameters *user_parm)
-+{
-+	struct ibv_qp_attr attr;
-+	memset(&attr, 0, sizeof attr);
-+	int i;
-+
-+	attr.qp_state 		= IBV_QPS_RTR;
-+	attr.path_mtu       = user_parm->curr_mtu;
-+    attr.dest_qp_num    = dest->qpn;
-+	attr.rq_psn         = dest->psn;
-+	attr.ah_attr.dlid   = dest->lid;
-+	if (user_parm->connection_type == RC) {
-+		attr.max_dest_rd_atomic     = 1;
-+		attr.min_rnr_timer          = 12;
-+	}
-+	if (user_parm->gid_index < 0) {
-+		attr.ah_attr.is_global  = 0;
-+		attr.ah_attr.sl         = user_parm->sl;
-+	} else {
-+		attr.ah_attr.is_global  = 1;
-+		attr.ah_attr.grh.dgid   = dest->gid;
-+		attr.ah_attr.grh.sgid_index = user_parm->gid_index;
-+		attr.ah_attr.grh.hop_limit = 1;
-+		attr.ah_attr.sl         = 0;
-+	}
-+	attr.ah_attr.src_path_bits = 0;
-+	attr.ah_attr.port_num   = user_parm->ib_port;
-+	
-+	if (user_parm->connection_type == RC) {
-+		if (ibv_modify_qp(ctx->qp[0], &attr,
-+				  IBV_QP_STATE              |
-+				  IBV_QP_AV                 |
-+				  IBV_QP_PATH_MTU           |
-+				  IBV_QP_DEST_QPN           |
-+				  IBV_QP_RQ_PSN             |
-+				  IBV_QP_MIN_RNR_TIMER      |
-+				  IBV_QP_MAX_DEST_RD_ATOMIC)) {
-+			fprintf(stderr, "Failed to modify RC QP to RTR\n");
-+			return 1;
-+		}
-+		attr.timeout            = user_parm->qp_timeout;
-+		attr.retry_cnt          = 7;
-+		attr.rnr_retry          = 7;
-+	} else if (user_parm->connection_type == UC) {
-+		if (ibv_modify_qp(ctx->qp[0], &attr,
-+				  IBV_QP_STATE              |
-+				  IBV_QP_AV                 |
-+				  IBV_QP_PATH_MTU           |
-+				  IBV_QP_DEST_QPN           |
-+				  IBV_QP_RQ_PSN)) {
-+			fprintf(stderr, "Failed to modify UC QP to RTR\n");
-+			return 1;
-+		}
-+	} 
-+	 
-+	else {
-+		for (i = 0; i < user_parm->num_of_qps; i++) {
-+			if (ibv_modify_qp(ctx->qp[i],&attr,IBV_QP_STATE )) {
-+				fprintf(stderr, "Failed to modify UD QP to RTR\n");
-+				return 1;
-+			}
-+		}
-+		if (user_parm->machine == CLIENT || user_parm->duplex) {
-+			ctx->ah = ibv_create_ah(ctx->pd,&attr.ah_attr);
-+			if (!ctx->ah) {
-+				fprintf(stderr, "Failed to create AH for UD\n");
-+				return 1;
-+			}
-+		}
-+	}
-+
-+	if (user_parm->machine == CLIENT || user_parm->duplex) {
-+
-+		attr.qp_state 	    = IBV_QPS_RTS;
-+		attr.sq_psn 	    = my_psn;
-+		if (user_parm->connection_type == RC) {
-+			attr.max_rd_atomic  = 1;
-+			if (ibv_modify_qp(ctx->qp[0], &attr,
-+					IBV_QP_STATE              |
-+					IBV_QP_SQ_PSN             |
-+					IBV_QP_TIMEOUT            |
-+					IBV_QP_RETRY_CNT          |
-+					IBV_QP_RNR_RETRY          |
-+					IBV_QP_MAX_QP_RD_ATOMIC)) {
-+				fprintf(stderr, "Failed to modify RC QP to RTS\n");
-+				return 1;
-+			}
-+
-+		} else {
-+			if(ibv_modify_qp(ctx->qp[0],&attr,IBV_QP_STATE |IBV_QP_SQ_PSN)) {
-+				fprintf(stderr, "Failed to modify UC QP to RTS\n");
-+				return 1;
-+			}
-+		}
-+	}
-+
-+	return 0;
-+}
-+
-+/****************************************************************************** 
-+ *
-+ ******************************************************************************/
-+static int set_recv_wqes(struct pingpong_context *ctx,
-+						 struct perftest_parameters *user_param) {
-+						
-+	int					i,j,buff_size;
-+	int 				duplex_ind;
-+	struct ibv_recv_wr  *bad_wr_recv;
-+
-+	i = (user_param->duplex && user_param->use_mcg) ? 1 : 0;
-+	duplex_ind = (user_param->duplex && !user_param->use_mcg) ? 1 : 0;
-+
-+	buff_size = BUFF_SIZE(ctx->size) + IF_UD_ADD(user_param->connection_type);
-+
-+	while (i < user_param->num_of_qps) {
-+
-+		ctx->sge_list[i].addr   = (uintptr_t)ctx->buf[i] + duplex_ind*buff_size;
-+
-+		if (user_param->connection_type == UD) 
-+			ctx->sge_list[i].addr += (CACHE_LINE_SIZE - UD_ADDITION);
-+
-+		ctx->sge_list[i].length = SIZE(user_param->connection_type,user_param->size);
-+		ctx->sge_list[i].lkey   = ctx->mr[i]->lkey;
-+		ctx->rwr[i].sg_list     = &ctx->sge_list[i];
-+		ctx->rwr[i].wr_id       = i;
-+		ctx->rwr[i].next        = NULL;
-+		ctx->rwr[i].num_sge	    = MAX_RECV_SGE;
-+		ctx->my_addr[i]		    = (uintptr_t)ctx->buf[i] + duplex_ind*buff_size;
-+		
-+		for (j = 0; j < user_param->rx_depth; ++j) {
-+
-+			if (ibv_post_recv(ctx->qp[i],&ctx->rwr[i],&bad_wr_recv)) {
-+				fprintf(stderr, "Couldn't post recv Qp = %d: counter=%d\n",i,j);
-+				return 1;
-+			}
-+
-+			if (user_param->size <= (CYCLE_BUFFER / 2))
-+				increase_loc_addr(&ctx->sge_list[i],user_param->size,j,ctx->my_addr[i],user_param->connection_type);
-+		}
-+		i++;
-+	}
-+	return 0;
-+}
-+
-+/****************************************************************************** 
-+ *
-+ ******************************************************************************/
-+static void set_send_wqe(struct pingpong_context *ctx,int rem_qpn,
-+						 struct perftest_parameters *user_param) {
-+
-+	ctx->list.addr     = (uintptr_t)ctx->buf[0];
-+	ctx->list.lkey 	   = ctx->mr[0]->lkey;
-+
-+	ctx->wr.sg_list    = &ctx->list;
-+	ctx->wr.num_sge    = 1;
-+	ctx->wr.opcode     = IBV_WR_SEND;
-+	ctx->wr.next       = NULL;
-+	ctx->wr.wr_id      = PINGPONG_SEND_WRID;
-+	ctx->wr.send_flags = IBV_SEND_SIGNALED;
-+
-+	if (user_param->connection_type == UD) {
-+		ctx->wr.wr.ud.ah          = ctx->ah;
-+		ctx->wr.wr.ud.remote_qkey = DEF_QKEY;
-+		ctx->wr.wr.ud.remote_qpn  = rem_qpn;
-+	}
-+}
-+
-+/****************************************************************************** 
-+ *
-+ ******************************************************************************/
-+static int pp_drain_qp(struct pingpong_context *ctx,
-+						struct perftest_parameters *user_param,
-+						int psn,struct pingpong_dest *dest,
-+						struct mcast_parameters *mcg_params) {
-+
-+	struct ibv_qp_attr attr;
-+	struct ibv_wc      wc;
-+	int                i;
-+
-+	memset(&attr, 0, sizeof attr);
-+	attr.qp_state = IBV_QPS_ERR;
-+
-+	for (i = 0; i <  user_param->num_of_qps; i++) {
-+
-+		if (ibv_modify_qp(ctx->qp[i],&attr,IBV_QP_STATE)) {
-+			fprintf(stderr, "Failed to modify RC QP to ERR\n");
-+			return 1;
-+		}
-+
-+		while (ibv_poll_cq(ctx->cq,1,&wc));
-+   
-+		attr.qp_state = IBV_QPS_RESET;
-+
-+		if (ibv_modify_qp(ctx->qp[i],&attr,IBV_QP_STATE)) {
-+			fprintf(stderr, "Failed to modify RC QP to RESET\n");
-+			return 1;
-+		}
-+
-+		if(ctx_modify_qp_to_init(ctx->qp[i],user_param)) {
-+			return 1;
-+		}
-+
-+		if (user_param->use_mcg) {
-+
-+			if ((!user_param->duplex && user_param->machine == SERVER) || (user_param->duplex && i > 0)) {
-+				if (ibv_attach_mcast(ctx->qp[i],&mcg_params->mgid,mcg_params->mlid)) {
-+					fprintf(stderr, "Couldn't attach QP to MultiCast group");
-+					return 1;
-+				}
-+			}
-+		}
-+	}
-+
-+	if (pp_connect_ctx(ctx,psn,dest,user_param)) {
-+		return 1;
-+	}
-+
-+	return 0;
-+}
-+
-+/****************************************************************************** 
-+ *
-+ ******************************************************************************/
-+static void print_report(struct perftest_parameters *user_param) {
-+
-+	double cycles_to_units;
-+	unsigned long tsize;	/* Transferred size, in megabytes */
-+	int i, j;
-+	int opt_posted = 0, opt_completed = 0;
-+	cycles_t opt_delta;
-+	cycles_t t;
-+
-+
-+	opt_delta = tcompleted[opt_posted] - tposted[opt_completed];
-+
-+	if (user_param->noPeak == OFF) {
-+		/* Find the peak bandwidth, unless asked not to in command line */
-+		for (i = 0; i < user_param->iters; ++i)
-+			for (j = i; j < user_param->iters; ++j) {
-+				t = (tcompleted[j] - tposted[i]) / (j - i + 1);
-+				if (t < opt_delta) {
-+					opt_delta  = t;
-+					opt_posted = i;
-+					opt_completed = j;
-+				}
-+			}
-+	}
-+
+ 		user_parm->inline_size = 0;
+ 
+ 	printf(" Inline data is used up to %d bytes message\n", user_parm->inline_size);
+@@ -649,7 +649,11 @@
+ 			}
+ 	}
+ 
 +#if !(defined(__sparc))
-+	cycles_to_units = get_cpu_mhz(user_param->cpu_freq_f) * 1000000;
+ 	cycles_to_units = get_cpu_mhz(user_param->cpu_freq_f) * 1000000;
 +#else
 +	cycles_to_units = 1000000000;
 +#endif
-+
-+	tsize = user_param->duplex ? 2 : 1;
-+	tsize = tsize * user_param->size;
-+	printf(REPORT_FMT,user_param->size,user_param->iters,(user_param->noPeak == OFF) * tsize * cycles_to_units / opt_delta / 0x100000,
-+	       tsize * user_param->iters * cycles_to_units /(tcompleted[user_param->iters - 1] - tposted[0]) / 0x100000);
-+}
-+
-+/****************************************************************************** 
-+ * Important note :															  
-+ * In case of UD/UC this is NOT the way to measureBW since we are running with 
-+ * loop on the send side , while we should run on the recieve side or enable 
-+ * retry in SW , Since the sender may be faster than the reciver.
-+ * Although	we had posted recieve it is not enough and might end this will
-+ * result in deadlock of test since both sides are stuck on poll cq.
-+ * In this test i do not solve this for the general test ,need to write
-+ * seperate test for UC/UD but in case the tx_depth is ~1/3 from the
-+ * number of iterations this should be ok .
-+ * Also note that the sender is limited in the number of send, ans
-+ * i try to make the reciver full .
-+ ******************************************************************************/
-+int run_iter_bi(struct pingpong_context *ctx, 
-+				struct perftest_parameters *user_param)  {
-+
-+	int                     scnt    = 0;
-+	int 					ccnt    = 0;
-+	int 					rcnt    = 0;
-+	int 					i       = 0;
-+	int 					num_of_qps = user_param->num_of_qps;
-+	int 					ne;
-+	struct ibv_wc 			*wc          = NULL;
-+	int 					*rcnt_for_qp = NULL;
-+	struct ibv_recv_wr      *bad_wr_recv = NULL;
-+	struct ibv_send_wr 		*bad_wr      = NULL;
-+
-+	ALLOCATE(rcnt_for_qp,int,user_param->num_of_qps);
-+	ALLOCATE(wc,struct ibv_wc,DEF_WC_SIZE);
-+	memset(rcnt_for_qp,0,sizeof(int)*user_param->num_of_qps);
-+
-+	if (user_param->use_mcg)
-+		num_of_qps--; 
-+	
-+	// Set the length of the scatter in case of ALL option.
-+	ctx->list.length = user_param->size;
-+	ctx->list.addr   = (uintptr_t)ctx->buf[0];
-+	ctx->wr.send_flags = IBV_SEND_SIGNALED;
-+	
-+	if (user_param->size <= user_param->inline_size) 
-+		ctx->wr.send_flags |= IBV_SEND_INLINE; 
-+
-+	while (ccnt < user_param->iters || rcnt < user_param->iters) {
-+                
-+		while (scnt < user_param->iters && (scnt - ccnt) < user_param->tx_depth / 2) {
-+
-+			if (scnt %  CQ_MODERATION == 0 && CQ_MODERATION > 1)
-+				ctx->wr.send_flags &= ~IBV_SEND_SIGNALED;
-+
-+			tposted[scnt] = get_cycles();
-+			if (ibv_post_send(ctx->qp[0],&ctx->wr, &bad_wr)) {
-+				fprintf(stderr, "Couldn't post send: scnt=%d\n",scnt);
-+				return 1;
-+			}
-+
-+			if (user_param->size <= (CYCLE_BUFFER / 2))
-+				increase_loc_addr(&ctx->list,user_param->size,scnt,(uintptr_t)ctx->buf[0],0);
-+
-+			++scnt;
-+
-+			if ((scnt % CQ_MODERATION) == (CQ_MODERATION - 1) || scnt == (user_param->iters - 1)) 
-+				ctx->wr.send_flags |= IBV_SEND_SIGNALED;
-+		}
-+
-+		if (user_param->use_event) {
-+
-+			if (ctx_notify_events(ctx->cq,ctx->channel)) {
-+				fprintf(stderr,"Failed to notify events to CQ");
-+				return 1;
-+			}
-+		}
-+
-+		do {
-+			ne = ibv_poll_cq(ctx->cq,DEF_WC_SIZE,wc);
-+			if (ne > 0) {
-+				for (i = 0; i < ne; i++) {
-+					
-+					if (wc[i].status != IBV_WC_SUCCESS)
-+						 NOTIFY_COMP_ERROR_SEND(wc[i],scnt,ccnt);
-+
-+					if ((int) wc[i].wr_id == PINGPONG_SEND_WRID) {
-+						ccnt += CQ_MODERATION;
-+						if (ccnt >= user_param->iters - 1) 
-+							tcompleted[user_param->iters - 1] = get_cycles();
-+
-+						else 
-+							tcompleted[ccnt - 1] = get_cycles();
-+					}
-+
-+					else {
-+
-+						rcnt_for_qp[wc[i].wr_id]++;
-+						rcnt++;
-+						if (ibv_post_recv(ctx->qp[wc[i].wr_id],&ctx->rwr[wc[i].wr_id],&bad_wr_recv)) {
-+							fprintf(stderr, "Couldn't post recv Qp=%d rcnt=%d\n",(int)wc[i].wr_id , rcnt_for_qp[wc[i].wr_id]);
-+							return 15;
-+						}
-+
-+						if (user_param->size <= (CYCLE_BUFFER / 2))
-+							increase_loc_addr(&ctx->sge_list[wc[i].wr_id],
-+							  user_param->size,rcnt_for_qp[wc[i].wr_id] + user_param->rx_depth - 1,
-+							  ctx->my_addr[wc[i].wr_id],user_param->connection_type);	
-+					}
-+				}
-+			}
-+		} while (ne > 0);
-+
-+		if (ne < 0) {
-+			fprintf(stderr, "poll CQ failed %d\n", ne);
-+			return 1;
-+		}
-+	}
-+	
-+	if (user_param->size <= user_param->inline_size) 
-+		ctx->wr.send_flags &= ~IBV_SEND_INLINE;
-+	
-+	free(rcnt_for_qp);
-+	free(wc);
-+	return 0;
-+}
-+
-+/****************************************************************************** 
-+ *
-+ ******************************************************************************/
-+int run_iter_uni_server(struct pingpong_context *ctx, 
-+						struct perftest_parameters *user_param) {
-+
-+	int 				rcnt = 0;
-+	int 				ne,i;
-+	int                 *rcnt_for_qp = NULL;
-+	struct ibv_wc 		*wc          = NULL;
-+	struct ibv_recv_wr  *bad_wr_recv = NULL;
-+
-+	ALLOCATE(wc,struct ibv_wc,DEF_WC_SIZE);
-+	ALLOCATE(rcnt_for_qp,int,user_param->num_of_qps);
-+
-+	memset(rcnt_for_qp,0,sizeof(int)*user_param->num_of_qps);
-+
-+	while (rcnt < user_param->iters) {
-+
-+		if (user_param->use_event) {
-+			if (ctx_notify_events(ctx->cq,ctx->channel)) {
-+				fprintf(stderr ," Failed to notify events to CQ");
-+				return 1;
-+			}
-+		}
-+		
-+		do {
-+			ne = ibv_poll_cq(ctx->cq,DEF_WC_SIZE,wc);
-+			if (ne > 0) {
-+				for (i = 0; i < ne; i++) {
-+					
-+					if (wc[i].status != IBV_WC_SUCCESS) 
-+						NOTIFY_COMP_ERROR_RECV(wc[i],rcnt_for_qp[wc[i].wr_id]);
-+						
-+					rcnt_for_qp[wc[i].wr_id]++;
-+					tcompleted[rcnt++] = get_cycles();
-+
-+				   	if (ibv_post_recv(ctx->qp[wc[i].wr_id],&ctx->rwr[wc[i].wr_id],&bad_wr_recv)) {
-+						fprintf(stderr, "Couldn't post recv Qp=%d rcnt=%d\n",(int)wc[i].wr_id,rcnt_for_qp[wc[i].wr_id]);
-+						return 15;
-+					}
-+
-+					if (user_param->size <= (CYCLE_BUFFER / 2))
-+						increase_loc_addr(&ctx->sge_list[wc[i].wr_id],user_param->size,
-+										  rcnt_for_qp[wc[i].wr_id] + user_param->rx_depth,
-+										  ctx->my_addr[wc[i].wr_id],user_param->connection_type);						
-+				}
-+			}
-+		} while (ne > 0);
-+
-+		if (ne < 0) {
-+			fprintf(stderr, "Poll Recieve CQ failed %d\n", ne);
-+			return 1;
-+		}
-+	}
-+
-+	tposted[0] = tcompleted[0];
-+	free(wc);
-+	free(rcnt_for_qp);
-+	return 0;
-+}
-+
-+/****************************************************************************** 
-+ *
-+ ******************************************************************************/
-+int run_iter_uni_client(struct pingpong_context *ctx, 
-+						struct perftest_parameters *user_param) {
-+
-+	int 		       ne;
-+	int 			   i    = 0;
-+	int                scnt = 0;
-+	int                ccnt = 0;
-+	struct ibv_wc      *wc     = NULL;
-+	struct ibv_send_wr *bad_wr = NULL;
-+
-+	ALLOCATE(wc,struct ibv_wc,DEF_WC_SIZE);
-+
-+	// Set the lenght of the scatter in case of ALL option.
-+	ctx->list.length = user_param->size;
-+	ctx->list.addr   = (uintptr_t)ctx->buf[0];
-+	ctx->wr.send_flags = IBV_SEND_SIGNALED; 
-+
-+	if (user_param->size <= user_param->inline_size) 
-+		ctx->wr.send_flags |= IBV_SEND_INLINE; 
-+	
-+
-+	while (scnt < user_param->iters || ccnt < user_param->iters) {
-+		while (scnt < user_param->iters && (scnt - ccnt) < user_param->tx_depth ) {
-+
-+			if (scnt %  CQ_MODERATION == 0 && CQ_MODERATION > 1)
-+				ctx->wr.send_flags &= ~IBV_SEND_SIGNALED;
-+
-+			tposted[scnt] = get_cycles();
-+			if (ibv_post_send(ctx->qp[0], &ctx->wr, &bad_wr)) {
-+				fprintf(stderr, "Couldn't post send: scnt=%d\n",scnt);
-+				return 1;
-+			}
-+
-+			if (user_param->size <= (CYCLE_BUFFER / 2))
-+				increase_loc_addr(&ctx->list,user_param->size,scnt,(uintptr_t)ctx->buf[0],0);
-+
-+			scnt++;
-+
-+			if ((scnt % CQ_MODERATION) == (CQ_MODERATION - 1) || scnt == (user_param->iters - 1)) 
-+				ctx->wr.send_flags |= IBV_SEND_SIGNALED;
-+		}
-+
-+		if (ccnt < user_param->iters) {	
-+			
-+			if (user_param->use_event) {
-+				if (ctx_notify_events(ctx->cq,ctx->channel)) {
-+					fprintf(stderr , " Failed to notify events to CQ");
-+					return 1;
-+				}
-+			} 
-+			do {
-+				ne = ibv_poll_cq(ctx->cq,DEF_WC_SIZE,wc);
-+				if (ne > 0) {
-+					for (i = 0; i < DEF_WC_SIZE; i++) {
-+
-+						if (wc[i].status != IBV_WC_SUCCESS) 
-+							NOTIFY_COMP_ERROR_SEND(wc[i],scnt,ccnt);
-+			
-+						ccnt += CQ_MODERATION;
-+						if (ccnt >= user_param->iters - 1) 
-+							tcompleted[user_param->iters - 1] = get_cycles();
-+
-+						else 
-+							tcompleted[ccnt - 1] = get_cycles();
-+					}
-+				}
-+                         
-+					
-+			} while (ne > 0);
-+
-+			if (ne < 0) {
-+				fprintf(stderr, "poll CQ failed\n");
-+				return 1;
-+			}
-+		}
-+	}
-+
-+	if (user_param->size <= user_param->inline_size) 
-+		ctx->wr.send_flags &= ~IBV_SEND_INLINE;
-+
-+	free(wc);
-+	return 0;
-+}
-+
-+/****************************************************************************** 
-+ *
-+ ******************************************************************************/
-+int main(int argc, char *argv[])
-+{
-+	struct ibv_device		 	*ib_dev = NULL;
-+	struct pingpong_context  	*ctx;
-+	struct pingpong_dest	 	my_dest,rem_dest;
-+	struct perftest_parameters  user_param;
-+	struct mcast_parameters     mcg_params;
-+	int                      	i = 0;
-+	int                      	size_max_pow = 24;
-+	int							size_of_arr;
-+
-+	// Pointer to The relevent function of run_iter according to machine type.
-+	int (*ptr_to_run_iter_uni)(struct pingpong_context*,struct perftest_parameters*);
-+
-+	/* init default values to user's parameters */
-+	memset(&user_param, 0 , sizeof(struct perftest_parameters));
-+	memset(&mcg_params, 0 , sizeof(struct mcast_parameters));
-+	memset(&my_dest   , 0 , sizeof(struct pingpong_dest));
-+	memset(&rem_dest   , 0 , sizeof(struct pingpong_dest));
-+ 
-+	user_param.verb    = SEND;
-+	user_param.tst     = BW;
-+	user_param.version = VERSION;
-+
-+	if (parser(&user_param,argv,argc)) 
-+		return 1;
-+
-+	printf(RESULT_LINE);
-+
-+	user_param.rx_depth = (user_param.iters < user_param.rx_depth) ? user_param.iters : user_param.rx_depth ;
-+
-+    if (user_param.use_mcg) {
-+
-+		user_param.connection_type = UD;
-+		if (user_param.duplex) {
-+			user_param.num_of_qps++;
-+			printf("                    Send Bidirectional BW  -  Multicast Test\n");
-+		}
-+		else {
-+			printf("                    Send BW  -  Multicast Test\n");
-+			if (user_param.machine == CLIENT)
-+				user_param.num_of_qps = 1;
-+		}
-+    }
-+
-+	else if (user_param.duplex) {
-+		    printf("                    Send Bidirectional BW Test\n");
-+	} else 
-+		    printf("                    Send BW Test\n");
-+
-+	if (user_param.use_event) 
-+		printf(" Test with events.\n");
-+
-+	if (user_param.connection_type == RC)
-+		printf(" Connection type : RC\n");
-+	else if (user_param.connection_type == UC)
-+		printf(" Connection type : UC\n");
-+	else{
-+		printf(" Connection type : UD\n");
-+	}
-+	
-+	// Done with parameter parsing. Perform setup.
-+	if (user_param.all == ON) {
-+		// since we run all sizes 
-+		user_param.size = MAX_SIZE;
-+	}
-+
-+	srand48(getpid() * time(NULL));
-+	page_size = sysconf(_SC_PAGESIZE);
-+
-+	ib_dev = ctx_find_dev(user_param.ib_devname);
-+	if (!ib_dev)
-+		return 7;
-+
-+	mcg_params.ib_devname = ibv_get_device_name(ib_dev);
-+
-+	ctx = pp_init_ctx(ib_dev,&user_param);
-+	if (!ctx)
-+		return 1;
-+
-+	// Set up the Connection.
-+	if (set_up_connection(ctx,&user_param,&my_dest,&mcg_params)) {
-+		fprintf(stderr," Unable to set up socket connection\n");
-+		return 1;
-+	}	
-+
-+	// Init the connection and print the local data.
-+	if (init_connection(&user_param,&my_dest)) {
-+		fprintf(stderr," Unable to init the socket connection\n");
-+		return 1;
-+	}
-+
-+	// shaking hands and gather the other side info.
-+    if (ctx_hand_shake(&user_param,&my_dest,&rem_dest)) {
-+        fprintf(stderr,"Failed to exchange date between server and clients\n");
-+        return 1;
-+        
-+    }
-+	// For printing only MGID in the remote side.
-+	user_param.side = REMOTE;
-+	ctx_print_pingpong_data(&rem_dest,&user_param);
-+
-+	// Joining the Send side port the Mcast gid
-+	if (user_param.use_mcg && (user_param.machine == CLIENT || user_param.duplex)) {
-+		memcpy(mcg_params.mgid.raw, rem_dest.gid.raw, 16);
-+		if (set_mcast_group(ctx,&user_param,&mcg_params)) {
-+			fprintf(stderr," Unable to Join Sender to Mcast gid\n");
-+			return 1;
-+		}
-+	}
-+
-+	// Prepare IB resources for rtr/rts.
-+	if (pp_connect_ctx(ctx,my_dest.psn,&rem_dest,&user_param)) {
-+		fprintf(stderr," Unable to Connect the HCA's through the link\n");
-+		return 1;
-+	}
-+	
-+	// shaking hands and gather the other side info.
-+    if (ctx_hand_shake(&user_param,&my_dest,&rem_dest)) {
-+        fprintf(stderr,"Failed to exchange date between server and clients\n");
-+        return 1;
-+        
-+    }
-+
-+	if (user_param.use_event) {
-+		if (ibv_req_notify_cq(ctx->cq, 0)) {
-+			fprintf(stderr, " Couldn't request CQ notification\n");
-+			return 1;
-+		} 
-+	}
-+
-+	printf(RESULT_LINE);
-+	printf(RESULT_FMT);
-+
-+	size_of_arr = (user_param.duplex) ? 1 : user_param.num_of_qps;
-+
-+	ALLOCATE(tposted,cycles_t,user_param.iters*size_of_arr);
-+	ALLOCATE(tcompleted,cycles_t,user_param.iters*size_of_arr);
-+
-+	if (user_param.machine == SERVER || user_param.duplex) {
-+		ALLOCATE(ctx->rwr,struct ibv_recv_wr,user_param.num_of_qps);
-+		ALLOCATE(ctx->sge_list,struct ibv_sge,user_param.num_of_qps);
-+		ALLOCATE(ctx->my_addr ,uint64_t ,user_param.num_of_qps);
-+	}
-+
-+	ptr_to_run_iter_uni = (user_param.machine == CLIENT) ?	&run_iter_uni_client : &run_iter_uni_server;
-+	
-+	if (user_param.machine == SERVER && !user_param.duplex) {
-+		user_param.noPeak = ON;
-+	}
-+
-+	if (user_param.machine == CLIENT || user_param.duplex) {
-+		set_send_wqe(ctx,rem_dest.qpn,&user_param);
-+	}
-+
-+	if (user_param.all == ON) {
-+
-+		if (user_param.connection_type == UD) 
-+		   size_max_pow =  (int)UD_MSG_2_EXP(MTU_SIZE(user_param.curr_mtu)) + 1;
-+
-+		for (i = 1; i < size_max_pow ; ++i) {
-+			user_param.size = 1 << i;
-+
-+			if (user_param.machine == SERVER || user_param.duplex) {
-+				if (set_recv_wqes(ctx,&user_param)) {
-+					fprintf(stderr," Failed to post receive recv_wqes\n");
-+					return 1;
-+				}
-+			}
-+
-+			if (ctx_hand_shake(&user_param,&my_dest,&rem_dest)) {
-+				fprintf(stderr,"Failed to exchange date between server and clients\n");
-+				return 1;
-+			}
-+
-+			if (user_param.duplex) {
-+				if(run_iter_bi(ctx,&user_param))
-+					return 17;
-+			} else {
-+				if((*ptr_to_run_iter_uni)(ctx,&user_param))
-+					return 17;
-+			}
-+			print_report(&user_param);
-+
-+			if (pp_drain_qp(ctx,&user_param,my_dest.psn,&rem_dest,&mcg_params)) {
-+				fprintf(stderr,"Failed to drain Recv queue (performance optimization)\n");
-+				return 1;
-+			}
-+
-+			if (ctx_hand_shake(&user_param,&my_dest,&rem_dest)) {
-+				fprintf(stderr,"Failed to exchange date between server and clients\n");
-+				return 1;
-+			}
-+        
-+		}
-+
-+	} else {
-+
-+		if (user_param.machine == SERVER || user_param.duplex) {
-+			if (set_recv_wqes(ctx,&user_param)) {
-+				fprintf(stderr," Failed to post receive recv_wqes\n");
-+				return 1;
-+			}
-+		}
-+
-+		if (ctx_hand_shake(&user_param,&my_dest,&rem_dest)) {
-+			fprintf(stderr,"Failed to exchange date between server and clients\n");
-+			return 1;
-+		}
-+
-+		if (user_param.duplex) {
-+			if(run_iter_bi(ctx,&user_param))
-+				return 18;
-+
-+		} else {
-+			if((*ptr_to_run_iter_uni)(ctx,&user_param))
-+				return 18;
-+		}
-+
-+		print_report(&user_param);	
-+	}
-+		
-+	if (ctx_close_connection(&user_param,&my_dest,&rem_dest)) {
-+		fprintf(stderr," Failed to close connection between server and client\n");
-+		return 1;
-+	}
-+
-+	printf(RESULT_LINE);
-+	return destroy_ctx_resources(ctx,&user_param,&my_dest,&rem_dest,&mcg_params);
-+}
+ 
+ 	tsize = user_param->duplex ? 2 : 1;
+ 	tsize = tsize * user_param->size;
 diff -r -u /tmp/perftest-1.3.0/send_lat.c perftest-1.3.0/send_lat.c
 --- /tmp/perftest-1.3.0/send_lat.c	Wed Mar  2 16:04:50 2011
 +++ perftest-1.3.0/send_lat.c	Fri Aug 26 05:29:53 2011