components/open-fabrics/perftest/patches/base.patch
branchs11u1-sru
changeset 2877 64163110c734
parent 715 eed3ed08f692
equal deleted inserted replaced
2876:3112a7eca680 2877:64163110c734
  1560  
  1560  
  1561  	if (user_param->r_flag->unsorted) {
  1561  	if (user_param->r_flag->unsorted) {
  1562 diff -r -u /tmp/perftest-1.3.0/send_bw.c perftest-1.3.0/send_bw.c
  1562 diff -r -u /tmp/perftest-1.3.0/send_bw.c perftest-1.3.0/send_bw.c
  1563 --- /tmp/perftest-1.3.0/send_bw.c	Thu Jan 20 07:37:18 2011
  1563 --- /tmp/perftest-1.3.0/send_bw.c	Thu Jan 20 07:37:18 2011
  1564 +++ perftest-1.3.0/send_bw.c	Fri Feb 11 04:12:47 2011
  1564 +++ perftest-1.3.0/send_bw.c	Fri Feb 11 04:12:47 2011
  1565 @@ -1,1162 +1,1166 @@
  1565 @@ -320,7 +320,7 @@
  1566 -/*
  1566  		user_parm->size = MTU_SIZE(user_parm->curr_mtu);
  1567 - * Copyright (c) 2005 Topspin Communications.  All rights reserved.
  1567  	}
  1568 - * Copyright (c) 2005 Mellanox Technologies Ltd.  All rights reserved.
  1568  
  1569 - * Copyright (c) 2009 HNR Consulting.  All rights reserved.
       
  1570 - *
       
  1571 - * This software is available to you under a choice of one of two
       
  1572 - * licenses.  You may choose to be licensed under the terms of the GNU
       
  1573 - * General Public License (GPL) Version 2, available from the file
       
  1574 - * COPYING in the main directory of this source tree, or the
       
  1575 - * OpenIB.org BSD license below:
       
  1576 - *
       
  1577 - *     Redistribution and use in source and binary forms, with or
       
  1578 - *     without modification, are permitted provided that the following
       
  1579 - *     conditions are met:
       
  1580 - *
       
  1581 - *      - Redistributions of source code must retain the above
       
  1582 - *        copyright notice, this list of conditions and the following
       
  1583 - *        disclaimer.
       
  1584 - *
       
  1585 - *      - Redistributions in binary form must reproduce the above
       
  1586 - *        copyright notice, this list of conditions and the following
       
  1587 - *        disclaimer in the documentation and/or other materials
       
  1588 - *        provided with the distribution.
       
  1589 - *
       
  1590 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
       
  1591 - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
       
  1592 - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
       
  1593 - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
       
  1594 - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
       
  1595 - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
       
  1596 - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
       
  1597 - * SOFTWARE.
       
  1598 - *
       
  1599 - * $Id$
       
  1600 - */
       
  1601 -
       
  1602 -#if HAVE_CONFIG_H
       
  1603 -#  include <config.h>
       
  1604 -#endif /* HAVE_CONFIG_H */
       
  1605 -
       
  1606 -#include <stdio.h>
       
  1607 -#include <stdlib.h>
       
  1608 -#include <unistd.h>
       
  1609 -#include <string.h>
       
  1610 -#include <limits.h>
       
  1611 -#include <malloc.h>
       
  1612 -#include <getopt.h>
       
  1613 -#include <time.h>
       
  1614 -#include <errno.h>
       
  1615 -#include <infiniband/verbs.h>
       
  1616 -
       
  1617 -#include "get_clock.h"
       
  1618 -#include "multicast_resources.h"
       
  1619 -#include "perftest_resources.h"
       
  1620 -
       
  1621 -#define VERSION 2.1
       
  1622 -
       
  1623 -static int page_size;
       
  1624 -cycles_t	*tposted;
       
  1625 -cycles_t	*tcompleted;
       
  1626 -
       
  1627 -struct pingpong_context {
       
  1628 -	struct ibv_context 		*context;
       
  1629 -	struct ibv_comp_channel *channel;
       
  1630 -	struct ibv_pd      		*pd;
       
  1631 -	struct ibv_mr     		**mr;
       
  1632 -	struct ibv_cq      		*cq;
       
  1633 -	struct ibv_qp      		**qp;
       
  1634 -	struct ibv_sge      	list;
       
  1635 -	struct ibv_send_wr  	wr;
       
  1636 -	struct ibv_sge 			*sge_list;
       
  1637 -	struct ibv_recv_wr  	*rwr;
       
  1638 -	struct ibv_ah			*ah;
       
  1639 -	void               		**buf;
       
  1640 -	unsigned            	size;
       
  1641 -	uint64_t				*my_addr;
       
  1642 -};
       
  1643 -
       
  1644 -/****************************************************************************** 
       
  1645 - *
       
  1646 - ******************************************************************************/
       
  1647 -static int set_mcast_group(struct pingpong_context *ctx,
       
  1648 -						   struct perftest_parameters *user_parm,
       
  1649 -						   struct mcast_parameters *mcg_params) {
       
  1650 -
       
  1651 -	struct ibv_port_attr port_attr;
       
  1652 -
       
  1653 -	if (ibv_query_gid(ctx->context,user_parm->ib_port,user_parm->gid_index,&mcg_params->port_gid)) {
       
  1654 -			return 1;
       
  1655 -	}
       
  1656 -		
       
  1657 -	if (ibv_query_pkey(ctx->context,user_parm->ib_port,DEF_PKEY_IDX,&mcg_params->pkey)) {
       
  1658 -		return 1;
       
  1659 -	}
       
  1660 -
       
  1661 -	if (ibv_query_port(ctx->context,user_parm->ib_port,&port_attr)) {
       
  1662 -		return 1;
       
  1663 -	}
       
  1664 -	mcg_params->sm_lid  = port_attr.sm_lid;
       
  1665 -	mcg_params->sm_sl   = port_attr.sm_sl;
       
  1666 -	mcg_params->ib_port = user_parm->ib_port;
       
  1667 -	
       
  1668 -	if (!strcmp(link_layer_str(user_parm->link_type),"IB")) {
       
  1669 -		// Request for Mcast group create registery in SM.
       
  1670 -		if (join_multicast_group(SUBN_ADM_METHOD_SET,mcg_params)) {
       
  1671 -			fprintf(stderr,"Couldn't Register the Mcast group on the SM\n");
       
  1672 -			return 1;
       
  1673 -		}
       
  1674 -	}
       
  1675 -	return 0;
       
  1676 -}
       
  1677 -
       
  1678 -/****************************************************************************** 
       
  1679 - *
       
  1680 - ******************************************************************************/
       
  1681 -static int set_up_connection(struct pingpong_context *ctx,
       
  1682 -							 struct perftest_parameters *user_parm,
       
  1683 -							 struct pingpong_dest *my_dest,
       
  1684 -							 struct mcast_parameters *mcg_params) {
       
  1685 -
       
  1686 -	int i = (user_parm->duplex) ? 1 : 0;
       
  1687 -
       
  1688 -	if (user_parm->use_mcg && (user_parm->duplex || user_parm->machine == SERVER)) {
       
  1689 -
       
  1690 -		set_multicast_gid(mcg_params,ctx->qp[0]->qp_num,(int)user_parm->machine);
       
  1691 -		if (set_mcast_group(ctx,user_parm,mcg_params)) {
       
  1692 -			return 1;
       
  1693 -		}
       
  1694 -		
       
  1695 -		while (i < user_parm->num_of_qps) {
       
  1696 -			if (ibv_attach_mcast(ctx->qp[i],&mcg_params->mgid,mcg_params->mlid)) {
       
  1697 -				fprintf(stderr, "Couldn't attach QP to MultiCast group");
       
  1698 -				return 1;
       
  1699 -			}
       
  1700 -			i++;
       
  1701 -		}
       
  1702 -
       
  1703 -		mcg_params->mcast_state |= MCAST_IS_ATTACHED;
       
  1704 -		my_dest->gid = mcg_params->mgid;
       
  1705 -		my_dest->lid = mcg_params->mlid;
       
  1706 -		my_dest->qpn = QPNUM_MCAST;
       
  1707 -
       
  1708 -	} else {
       
  1709 -		if (user_parm->gid_index != -1) {
       
  1710 -			if (ibv_query_gid(ctx->context,user_parm->ib_port,user_parm->gid_index,&my_dest->gid)) {
       
  1711 -				return -1;
       
  1712 -			}
       
  1713 -		}
       
  1714 -		my_dest->lid = ctx_get_local_lid(ctx->context,user_parm->ib_port);
       
  1715 -		my_dest->qpn = ctx->qp[0]->qp_num;
       
  1716 -	}
       
  1717 -	my_dest->psn  = lrand48() & 0xffffff;
       
  1718 -
       
  1719 -	// We do not fail test upon lid above RoCE.
       
  1720 -
       
  1721 -	if (user_parm->gid_index < 0) {
       
  1722 -		if (!my_dest->lid) {
       
  1723 -			fprintf(stderr," Local lid 0x0 detected,without any use of gid. Is SM running?\n");
       
  1724 -			return -1;
       
  1725 -		}
       
  1726 -	}
       
  1727 -	return 0;
       
  1728 -}
       
  1729 -
       
  1730 -/****************************************************************************** 
       
  1731 - *
       
  1732 - ******************************************************************************/
       
  1733 -static int init_connection(struct perftest_parameters *params,
       
  1734 - 						   struct pingpong_dest *my_dest) {
       
  1735 -
       
  1736 -	params->side = LOCAL;
       
  1737 -	ctx_print_pingpong_data(my_dest,params);
       
  1738 -	
       
  1739 -	if (params->machine == CLIENT) 
       
  1740 -		params->sockfd = ctx_client_connect(params->servername,params->port);
       
  1741 -	else 
       
  1742 -		params->sockfd = ctx_server_connect(params->port);
       
  1743 -	
       
  1744 -		
       
  1745 -	if(params->sockfd < 0) {
       
  1746 -		fprintf(stderr,"Unable to open file descriptor for socket connection");
       
  1747 -		return 1;
       
  1748 -	}
       
  1749 -	return 0;
       
  1750 -}
       
  1751 -
       
  1752 -/****************************************************************************** 
       
  1753 - *
       
  1754 - ******************************************************************************/
       
  1755 -static int destroy_ctx_resources(struct pingpong_context    *ctx, 
       
  1756 -								 struct perftest_parameters *user_parm,
       
  1757 -								 struct pingpong_dest		*my_dest,
       
  1758 -								 struct pingpong_dest		*rem_dest,
       
  1759 -								 struct mcast_parameters    *mcg_params)  {
       
  1760 -
       
  1761 -	int test_result = 0;
       
  1762 -	int i = (user_parm->duplex) ? 1 : 0;
       
  1763 -
       
  1764 -	if (user_parm->use_mcg) {
       
  1765 -
       
  1766 -		if (user_parm->machine == SERVER || user_parm->duplex) {
       
  1767 -			
       
  1768 -			while (i < user_parm->num_of_qps) {
       
  1769 -				if (ibv_detach_mcast(ctx->qp[i],&my_dest->gid,my_dest->lid)) {
       
  1770 -					fprintf(stderr, "Couldn't deattach QP from MultiCast group\n");
       
  1771 -					return 1;
       
  1772 -				}
       
  1773 -				i++;
       
  1774 -			}
       
  1775 -			mcg_params->mgid = my_dest->gid;
       
  1776 -			if (!strcmp(link_layer_str(user_parm->link_type),"IB")) {
       
  1777 -				if (join_multicast_group(SUBN_ADM_METHOD_DELETE,mcg_params)) {
       
  1778 -					fprintf(stderr,"Couldn't Unregister the Mcast group on the SM\n");
       
  1779 -					return 1;
       
  1780 -				}
       
  1781 -			}
       
  1782 -		}
       
  1783 -
       
  1784 -		if (user_parm->machine == CLIENT || user_parm->duplex) {
       
  1785 -
       
  1786 -			mcg_params->mgid = rem_dest->gid;
       
  1787 -			if (!strcmp(link_layer_str(user_parm->link_type),"IB")) {
       
  1788 -				if (join_multicast_group(SUBN_ADM_METHOD_DELETE,mcg_params)) {
       
  1789 -					fprintf(stderr,"Couldn't Unregister the Mcast group on the SM\n");
       
  1790 -					return 1;
       
  1791 -				}
       
  1792 -			}
       
  1793 -
       
  1794 -		}
       
  1795 -	}	
       
  1796 -
       
  1797 -	if (ctx->ah) {
       
  1798 -		if (ibv_destroy_ah(ctx->ah)) {
       
  1799 -			fprintf(stderr, "failed to destroy AH\n");
       
  1800 -			test_result = 1;
       
  1801 -		}
       
  1802 -	}
       
  1803 -
       
  1804 -	for(i = 0; i < user_parm->num_of_qps; i++) {
       
  1805 -		if (ibv_destroy_qp(ctx->qp[i])) {
       
  1806 -			test_result = 1;
       
  1807 -		}
       
  1808 -	}
       
  1809 -	free(ctx->qp);
       
  1810 -
       
  1811 -	if (ibv_destroy_cq(ctx->cq)) {
       
  1812 -		test_result = 1;
       
  1813 -	}
       
  1814 -
       
  1815 -	for(i = 0; i < user_parm->num_of_qps; i++) {
       
  1816 -
       
  1817 -		if (ibv_dereg_mr(ctx->mr[i])) {
       
  1818 -			test_result = 1;
       
  1819 -		}
       
  1820 -		free(ctx->buf[i]);
       
  1821 -	}
       
  1822 -	
       
  1823 -	if (ibv_dealloc_pd(ctx->pd)) {
       
  1824 -		test_result = 1;
       
  1825 -	}
       
  1826 -
       
  1827 -	if (ctx->channel) {
       
  1828 -		if (ibv_destroy_comp_channel(ctx->channel)) {
       
  1829 -			test_result = 1;
       
  1830 -		}
       
  1831 -	}
       
  1832 -	
       
  1833 -	if (ibv_close_device(ctx->context)) {
       
  1834 -		test_result = 1;
       
  1835 -	}
       
  1836 -
       
  1837 -	if (user_parm->machine == SERVER || user_parm->duplex) {
       
  1838 -		free(ctx->rwr);
       
  1839 -		free(ctx->sge_list);
       
  1840 -		free(ctx->my_addr);
       
  1841 -	}
       
  1842 -
       
  1843 -	free(ctx->mr);
       
  1844 -	free(ctx->buf);
       
  1845 -	free(ctx);
       
  1846 -	free(tposted);
       
  1847 -    free(tcompleted);
       
  1848 -	return test_result;
       
  1849 -}
       
  1850 -
       
  1851 -/****************************************************************************** 
       
  1852 - *
       
  1853 - ******************************************************************************/
       
  1854 -static struct pingpong_context *pp_init_ctx(struct ibv_device *ib_dev,
       
  1855 -											struct perftest_parameters *user_parm) {
       
  1856 -
       
  1857 -	int i,m_size;
       
  1858 -	int duplex_ind;
       
  1859 -	struct pingpong_context *ctx;
       
  1860 -
       
  1861 -	ALLOCATE(ctx,struct pingpong_context,1);
       
  1862 -	ALLOCATE(ctx->buf,void*,user_parm->num_of_qps);
       
  1863 -	ALLOCATE(ctx->mr,struct ibv_mr*,user_parm->num_of_qps);
       
  1864 -
       
  1865 -	ctx->ah       = NULL;
       
  1866 -	ctx->channel  = NULL;
       
  1867 -
       
  1868 -	duplex_ind = (user_parm->duplex && !user_parm->use_mcg) ? 2 : 1;
       
  1869 -
       
  1870 -	ctx->context = ibv_open_device(ib_dev);
       
  1871 -	if (!ctx->context) {
       
  1872 -		fprintf(stderr, "Couldn't get context for %s\n",
       
  1873 -			ibv_get_device_name(ib_dev));
       
  1874 -		return NULL;
       
  1875 -	}
       
  1876 -
       
  1877 -	// Configure the Link MTU acoording to the user or the active mtu.
       
  1878 -	if (ctx_set_mtu(ctx->context,user_parm)) {
       
  1879 -		fprintf(stderr, "Couldn't set the link layer\n");
       
  1880 -		return NULL;
       
  1881 -	}
       
  1882 -
       
  1883 -	if (user_parm->connection_type == UD && user_parm->size > MTU_SIZE(user_parm->curr_mtu)) {	 
       
  1884 -		printf(" Max msg size in UD is MTU - %d . changing to MTU\n",MTU_SIZE(user_parm->curr_mtu));
       
  1885 -		user_parm->size = MTU_SIZE(user_parm->curr_mtu);
       
  1886 -	}
       
  1887 -
       
  1888 -	if (is_dev_hermon(ctx->context) != NOT_HERMON && user_parm->inline_size != 0)
  1569 -	if (is_dev_hermon(ctx->context) != NOT_HERMON && user_parm->inline_size != 0)
  1889 -		user_parm->inline_size = 0;
       
  1890 -
       
  1891 -	printf(" Inline data is used up to %d bytes message\n", user_parm->inline_size);
       
  1892 -
       
  1893 -	ctx->size = user_parm->size;
       
  1894 -
       
  1895 -	// Finds the link type and configure the HCA accordingly.
       
  1896 -	if (ctx_set_link_layer(ctx->context,user_parm)) {
       
  1897 -		fprintf(stderr, " Couldn't set the link layer\n");
       
  1898 -		return NULL;
       
  1899 -	}
       
  1900 -	
       
  1901 -	if (user_parm->use_event) {
       
  1902 -		ctx->channel = ibv_create_comp_channel(ctx->context);
       
  1903 -		if (!ctx->channel) {
       
  1904 -			fprintf(stderr, "Couldn't create completion channel\n");
       
  1905 -			return NULL;
       
  1906 -		}
       
  1907 -	} else
       
  1908 -		ctx->channel = NULL;                  
       
  1909 -
       
  1910 -	ctx->pd = ibv_alloc_pd(ctx->context);
       
  1911 -	if (!ctx->pd) {
       
  1912 -		fprintf(stderr, "Couldn't allocate PD\n");
       
  1913 -		return NULL;
       
  1914 -	}
       
  1915 -
       
  1916 -	for (i = 0; i < user_parm->num_of_qps; i++) {
       
  1917 -
       
  1918 -		m_size = (BUFF_SIZE(user_parm->size) + IF_UD_ADD(user_parm->connection_type))*duplex_ind;
       
  1919 -		ctx->buf[i] = memalign(page_size,m_size);
       
  1920 -		if (!ctx->buf[i]) {
       
  1921 -			fprintf(stderr, "Couldn't allocate work buf.\n");
       
  1922 -			return NULL;
       
  1923 -		}
       
  1924 -		memset(ctx->buf[i],0,m_size);
       
  1925 -
       
  1926 -		// We dont really want IBV_ACCESS_LOCAL_WRITE, but IB spec says :
       
  1927 -		// The Consumer is not allowed to assign Remote Write or Remote Atomic to
       
  1928 -		// a Memory Region that has not been assigned Local Write. 
       
  1929 -		ctx->mr[i] = ibv_reg_mr(ctx->pd,
       
  1930 -								ctx->buf[i],
       
  1931 -								m_size,
       
  1932 -								IBV_ACCESS_REMOTE_WRITE | 
       
  1933 -								IBV_ACCESS_LOCAL_WRITE);
       
  1934 -
       
  1935 -		if (!ctx->mr[i]) {
       
  1936 -			fprintf(stderr, "Couldn't allocate MR\n");
       
  1937 -			return NULL;
       
  1938 -		}
       
  1939 -	}
       
  1940 -
       
  1941 -	// Create the CQ according to Client/Server or Duplex setting.
       
  1942 -	ctx->cq = ctx_cq_create(ctx->context,ctx->channel,user_parm);
       
  1943 -	if (ctx->cq == NULL) {
       
  1944 -		fprintf(stderr, "Couldn't create CQ \n");
       
  1945 -		return NULL;
       
  1946 -	}
       
  1947 -
       
  1948 -	ALLOCATE(ctx->qp,struct ibv_qp*,user_parm->num_of_qps);
       
  1949 -	
       
  1950 -	for(i=0; i < user_parm->num_of_qps; i++) {
       
  1951 -		ctx->qp[i] = ctx_qp_create(ctx->pd,ctx->cq,ctx->cq,user_parm);
       
  1952 -		if (ctx->qp[i] == NULL) {
       
  1953 -			return NULL;
       
  1954 -		}
       
  1955 -
       
  1956 -		if(ctx_modify_qp_to_init(ctx->qp[i],user_parm)) {
       
  1957 -			return NULL;
       
  1958 -		}
       
  1959 -	}
       
  1960 -
       
  1961 -	return ctx;
       
  1962 -}
       
  1963 -
       
  1964 -/****************************************************************************** 
       
  1965 - *
       
  1966 - ******************************************************************************/
       
  1967 -static int pp_connect_ctx(struct pingpong_context *ctx,int my_psn,
       
  1968 -			              struct pingpong_dest *dest, 
       
  1969 -						  struct perftest_parameters *user_parm)
       
  1970 -{
       
  1971 -	struct ibv_qp_attr attr;
       
  1972 -	memset(&attr, 0, sizeof attr);
       
  1973 -	int i;
       
  1974 -
       
  1975 -	attr.qp_state 		= IBV_QPS_RTR;
       
  1976 -	attr.path_mtu       = user_parm->curr_mtu;
       
  1977 -    attr.dest_qp_num    = dest->qpn;
       
  1978 -	attr.rq_psn         = dest->psn;
       
  1979 -	attr.ah_attr.dlid   = dest->lid;
       
  1980 -	if (user_parm->connection_type == RC) {
       
  1981 -		attr.max_dest_rd_atomic     = 1;
       
  1982 -		attr.min_rnr_timer          = 12;
       
  1983 -	}
       
  1984 -	if (user_parm->gid_index < 0) {
       
  1985 -		attr.ah_attr.is_global  = 0;
       
  1986 -		attr.ah_attr.sl         = user_parm->sl;
       
  1987 -	} else {
       
  1988 -		attr.ah_attr.is_global  = 1;
       
  1989 -		attr.ah_attr.grh.dgid   = dest->gid;
       
  1990 -		attr.ah_attr.grh.sgid_index = user_parm->gid_index;
       
  1991 -		attr.ah_attr.grh.hop_limit = 1;
       
  1992 -		attr.ah_attr.sl         = 0;
       
  1993 -	}
       
  1994 -	attr.ah_attr.src_path_bits = 0;
       
  1995 -	attr.ah_attr.port_num   = user_parm->ib_port;
       
  1996 -	
       
  1997 -	if (user_parm->connection_type == RC) {
       
  1998 -		if (ibv_modify_qp(ctx->qp[0], &attr,
       
  1999 -				  IBV_QP_STATE              |
       
  2000 -				  IBV_QP_AV                 |
       
  2001 -				  IBV_QP_PATH_MTU           |
       
  2002 -				  IBV_QP_DEST_QPN           |
       
  2003 -				  IBV_QP_RQ_PSN             |
       
  2004 -				  IBV_QP_MIN_RNR_TIMER      |
       
  2005 -				  IBV_QP_MAX_DEST_RD_ATOMIC)) {
       
  2006 -			fprintf(stderr, "Failed to modify RC QP to RTR\n");
       
  2007 -			return 1;
       
  2008 -		}
       
  2009 -		attr.timeout            = user_parm->qp_timeout;
       
  2010 -		attr.retry_cnt          = 7;
       
  2011 -		attr.rnr_retry          = 7;
       
  2012 -	} else if (user_parm->connection_type == UC) {
       
  2013 -		if (ibv_modify_qp(ctx->qp[0], &attr,
       
  2014 -				  IBV_QP_STATE              |
       
  2015 -				  IBV_QP_AV                 |
       
  2016 -				  IBV_QP_PATH_MTU           |
       
  2017 -				  IBV_QP_DEST_QPN           |
       
  2018 -				  IBV_QP_RQ_PSN)) {
       
  2019 -			fprintf(stderr, "Failed to modify UC QP to RTR\n");
       
  2020 -			return 1;
       
  2021 -		}
       
  2022 -	} 
       
  2023 -	 
       
  2024 -	else {
       
  2025 -		for (i = 0; i < user_parm->num_of_qps; i++) {
       
  2026 -			if (ibv_modify_qp(ctx->qp[i],&attr,IBV_QP_STATE )) {
       
  2027 -				fprintf(stderr, "Failed to modify UD QP to RTR\n");
       
  2028 -				return 1;
       
  2029 -			}
       
  2030 -		}
       
  2031 -		if (user_parm->machine == CLIENT || user_parm->duplex) {
       
  2032 -			ctx->ah = ibv_create_ah(ctx->pd,&attr.ah_attr);
       
  2033 -			if (!ctx->ah) {
       
  2034 -				fprintf(stderr, "Failed to create AH for UD\n");
       
  2035 -				return 1;
       
  2036 -			}
       
  2037 -		}
       
  2038 -	}
       
  2039 -
       
  2040 -	if (user_parm->machine == CLIENT || user_parm->duplex) {
       
  2041 -
       
  2042 -		attr.qp_state 	    = IBV_QPS_RTS;
       
  2043 -		attr.sq_psn 	    = my_psn;
       
  2044 -		if (user_parm->connection_type == RC) {
       
  2045 -			attr.max_rd_atomic  = 1;
       
  2046 -			if (ibv_modify_qp(ctx->qp[0], &attr,
       
  2047 -					IBV_QP_STATE              |
       
  2048 -					IBV_QP_SQ_PSN             |
       
  2049 -					IBV_QP_TIMEOUT            |
       
  2050 -					IBV_QP_RETRY_CNT          |
       
  2051 -					IBV_QP_RNR_RETRY          |
       
  2052 -					IBV_QP_MAX_QP_RD_ATOMIC)) {
       
  2053 -				fprintf(stderr, "Failed to modify RC QP to RTS\n");
       
  2054 -				return 1;
       
  2055 -			}
       
  2056 -
       
  2057 -		} else {
       
  2058 -			if(ibv_modify_qp(ctx->qp[0],&attr,IBV_QP_STATE |IBV_QP_SQ_PSN)) {
       
  2059 -				fprintf(stderr, "Failed to modify UC QP to RTS\n");
       
  2060 -				return 1;
       
  2061 -			}
       
  2062 -		}
       
  2063 -	}
       
  2064 -
       
  2065 -	return 0;
       
  2066 -}
       
  2067 -
       
  2068 -/****************************************************************************** 
       
  2069 - *
       
  2070 - ******************************************************************************/
       
  2071 -static int set_recv_wqes(struct pingpong_context *ctx,
       
  2072 -						 struct perftest_parameters *user_param) {
       
  2073 -						
       
  2074 -	int					i,j,buff_size;
       
  2075 -	int 				duplex_ind;
       
  2076 -	struct ibv_recv_wr  *bad_wr_recv;
       
  2077 -
       
  2078 -	i = (user_param->duplex && user_param->use_mcg) ? 1 : 0;
       
  2079 -	duplex_ind = (user_param->duplex && !user_param->use_mcg) ? 1 : 0;
       
  2080 -
       
  2081 -	buff_size = BUFF_SIZE(ctx->size) + IF_UD_ADD(user_param->connection_type);
       
  2082 -
       
  2083 -	while (i < user_param->num_of_qps) {
       
  2084 -
       
  2085 -		ctx->sge_list[i].addr   = (uintptr_t)ctx->buf[i] + duplex_ind*buff_size;
       
  2086 -
       
  2087 -		if (user_param->connection_type == UD) 
       
  2088 -			ctx->sge_list[i].addr += (CACHE_LINE_SIZE - UD_ADDITION);
       
  2089 -
       
  2090 -		ctx->sge_list[i].length = SIZE(user_param->connection_type,user_param->size);
       
  2091 -		ctx->sge_list[i].lkey   = ctx->mr[i]->lkey;
       
  2092 -		ctx->rwr[i].sg_list     = &ctx->sge_list[i];
       
  2093 -		ctx->rwr[i].wr_id       = i;
       
  2094 -		ctx->rwr[i].next        = NULL;
       
  2095 -		ctx->rwr[i].num_sge	    = MAX_RECV_SGE;
       
  2096 -		ctx->my_addr[i]		    = (uintptr_t)ctx->buf[i] + duplex_ind*buff_size;
       
  2097 -		
       
  2098 -		for (j = 0; j < user_param->rx_depth; ++j) {
       
  2099 -
       
  2100 -			if (ibv_post_recv(ctx->qp[i],&ctx->rwr[i],&bad_wr_recv)) {
       
  2101 -				fprintf(stderr, "Couldn't post recv Qp = %d: counter=%d\n",i,j);
       
  2102 -				return 1;
       
  2103 -			}
       
  2104 -
       
  2105 -			if (user_param->size <= (CYCLE_BUFFER / 2))
       
  2106 -				increase_loc_addr(&ctx->sge_list[i],user_param->size,j,ctx->my_addr[i],user_param->connection_type);
       
  2107 -		}
       
  2108 -		i++;
       
  2109 -	}
       
  2110 -	return 0;
       
  2111 -}
       
  2112 -
       
  2113 -/****************************************************************************** 
       
  2114 - *
       
  2115 - ******************************************************************************/
       
  2116 -static void set_send_wqe(struct pingpong_context *ctx,int rem_qpn,
       
  2117 -						 struct perftest_parameters *user_param) {
       
  2118 -
       
  2119 -	ctx->list.addr     = (uintptr_t)ctx->buf[0];
       
  2120 -	ctx->list.lkey 	   = ctx->mr[0]->lkey;
       
  2121 -
       
  2122 -	ctx->wr.sg_list    = &ctx->list;
       
  2123 -	ctx->wr.num_sge    = 1;
       
  2124 -	ctx->wr.opcode     = IBV_WR_SEND;
       
  2125 -	ctx->wr.next       = NULL;
       
  2126 -	ctx->wr.wr_id      = PINGPONG_SEND_WRID;
       
  2127 -	ctx->wr.send_flags = IBV_SEND_SIGNALED;
       
  2128 -
       
  2129 -	if (user_param->connection_type == UD) {
       
  2130 -		ctx->wr.wr.ud.ah          = ctx->ah;
       
  2131 -		ctx->wr.wr.ud.remote_qkey = DEF_QKEY;
       
  2132 -		ctx->wr.wr.ud.remote_qpn  = rem_qpn;
       
  2133 -	}
       
  2134 -}
       
  2135 -
       
  2136 -/****************************************************************************** 
       
  2137 - *
       
  2138 - ******************************************************************************/
       
  2139 -static int pp_drain_qp(struct pingpong_context *ctx,
       
  2140 -						struct perftest_parameters *user_param,
       
  2141 -						int psn,struct pingpong_dest *dest,
       
  2142 -						struct mcast_parameters *mcg_params) {
       
  2143 -
       
  2144 -	struct ibv_qp_attr attr;
       
  2145 -	struct ibv_wc      wc;
       
  2146 -	int                i;
       
  2147 -
       
  2148 -	memset(&attr, 0, sizeof attr);
       
  2149 -	attr.qp_state = IBV_QPS_ERR;
       
  2150 -
       
  2151 -	for (i = 0; i <  user_param->num_of_qps; i++) {
       
  2152 -
       
  2153 -		if (ibv_modify_qp(ctx->qp[i],&attr,IBV_QP_STATE)) {
       
  2154 -			fprintf(stderr, "Failed to modify RC QP to ERR\n");
       
  2155 -			return 1;
       
  2156 -		}
       
  2157 -
       
  2158 -		while (ibv_poll_cq(ctx->cq,1,&wc));
       
  2159 -   
       
  2160 -		attr.qp_state = IBV_QPS_RESET;
       
  2161 -
       
  2162 -		if (ibv_modify_qp(ctx->qp[i],&attr,IBV_QP_STATE)) {
       
  2163 -			fprintf(stderr, "Failed to modify RC QP to RESET\n");
       
  2164 -			return 1;
       
  2165 -		}
       
  2166 -
       
  2167 -		if(ctx_modify_qp_to_init(ctx->qp[i],user_param)) {
       
  2168 -			return 1;
       
  2169 -		}
       
  2170 -
       
  2171 -		if (user_param->use_mcg) {
       
  2172 -
       
  2173 -			if ((!user_param->duplex && user_param->machine == SERVER) || (user_param->duplex && i > 0)) {
       
  2174 -				if (ibv_attach_mcast(ctx->qp[i],&mcg_params->mgid,mcg_params->mlid)) {
       
  2175 -					fprintf(stderr, "Couldn't attach QP to MultiCast group");
       
  2176 -					return 1;
       
  2177 -				}
       
  2178 -			}
       
  2179 -		}
       
  2180 -	}
       
  2181 -
       
  2182 -	if (pp_connect_ctx(ctx,psn,dest,user_param)) {
       
  2183 -		return 1;
       
  2184 -	}
       
  2185 -
       
  2186 -	return 0;
       
  2187 -}
       
  2188 -
       
  2189 -/****************************************************************************** 
       
  2190 - *
       
  2191 - ******************************************************************************/
       
  2192 -static void print_report(struct perftest_parameters *user_param) {
       
  2193 -
       
  2194 -	double cycles_to_units;
       
  2195 -	unsigned long tsize;	/* Transferred size, in megabytes */
       
  2196 -	int i, j;
       
  2197 -	int opt_posted = 0, opt_completed = 0;
       
  2198 -	cycles_t opt_delta;
       
  2199 -	cycles_t t;
       
  2200 -
       
  2201 -
       
  2202 -	opt_delta = tcompleted[opt_posted] - tposted[opt_completed];
       
  2203 -
       
  2204 -	if (user_param->noPeak == OFF) {
       
  2205 -		/* Find the peak bandwidth, unless asked not to in command line */
       
  2206 -		for (i = 0; i < user_param->iters; ++i)
       
  2207 -			for (j = i; j < user_param->iters; ++j) {
       
  2208 -				t = (tcompleted[j] - tposted[i]) / (j - i + 1);
       
  2209 -				if (t < opt_delta) {
       
  2210 -					opt_delta  = t;
       
  2211 -					opt_posted = i;
       
  2212 -					opt_completed = j;
       
  2213 -				}
       
  2214 -			}
       
  2215 -	}
       
  2216 -
       
  2217 -	cycles_to_units = get_cpu_mhz(user_param->cpu_freq_f) * 1000000;
       
  2218 -
       
  2219 -	tsize = user_param->duplex ? 2 : 1;
       
  2220 -	tsize = tsize * user_param->size;
       
  2221 -	printf(REPORT_FMT,user_param->size,user_param->iters,(user_param->noPeak == OFF) * tsize * cycles_to_units / opt_delta / 0x100000,
       
  2222 -	       tsize * user_param->iters * cycles_to_units /(tcompleted[user_param->iters - 1] - tposted[0]) / 0x100000);
       
  2223 -}
       
  2224 -
       
  2225 -/****************************************************************************** 
       
  2226 - * Important note :															  
       
  2227 - * In case of UD/UC this is NOT the way to measureBW since we are running with 
       
  2228 - * loop on the send side , while we should run on the recieve side or enable 
       
  2229 - * retry in SW , Since the sender may be faster than the reciver.
       
  2230 - * Although	we had posted recieve it is not enough and might end this will
       
  2231 - * result in deadlock of test since both sides are stuck on poll cq.
       
  2232 - * In this test i do not solve this for the general test ,need to write
       
  2233 - * seperate test for UC/UD but in case the tx_depth is ~1/3 from the
       
  2234 - * number of iterations this should be ok .
       
  2235 - * Also note that the sender is limited in the number of send, ans
       
  2236 - * i try to make the reciver full .
       
  2237 - ******************************************************************************/
       
  2238 -int run_iter_bi(struct pingpong_context *ctx, 
       
  2239 -				struct perftest_parameters *user_param)  {
       
  2240 -
       
  2241 -	int                     scnt    = 0;
       
  2242 -	int 					ccnt    = 0;
       
  2243 -	int 					rcnt    = 0;
       
  2244 -	int 					i       = 0;
       
  2245 -	int 					num_of_qps = user_param->num_of_qps;
       
  2246 -	int 					ne;
       
  2247 -	struct ibv_wc 			*wc          = NULL;
       
  2248 -	int 					*rcnt_for_qp = NULL;
       
  2249 -	struct ibv_recv_wr      *bad_wr_recv = NULL;
       
  2250 -	struct ibv_send_wr 		*bad_wr      = NULL;
       
  2251 -
       
  2252 -	ALLOCATE(rcnt_for_qp,int,user_param->num_of_qps);
       
  2253 -	ALLOCATE(wc,struct ibv_wc,DEF_WC_SIZE);
       
  2254 -	memset(rcnt_for_qp,0,sizeof(int)*user_param->num_of_qps);
       
  2255 -
       
  2256 -	if (user_param->use_mcg)
       
  2257 -		num_of_qps--; 
       
  2258 -	
       
  2259 -	// Set the length of the scatter in case of ALL option.
       
  2260 -	ctx->list.length = user_param->size;
       
  2261 -	ctx->list.addr   = (uintptr_t)ctx->buf[0];
       
  2262 -	ctx->wr.send_flags = IBV_SEND_SIGNALED;
       
  2263 -	
       
  2264 -	if (user_param->size <= user_param->inline_size) 
       
  2265 -		ctx->wr.send_flags |= IBV_SEND_INLINE; 
       
  2266 -
       
  2267 -	while (ccnt < user_param->iters || rcnt < user_param->iters) {
       
  2268 -                
       
  2269 -		while (scnt < user_param->iters && (scnt - ccnt) < user_param->tx_depth / 2) {
       
  2270 -
       
  2271 -			if (scnt %  CQ_MODERATION == 0 && CQ_MODERATION > 1)
       
  2272 -				ctx->wr.send_flags &= ~IBV_SEND_SIGNALED;
       
  2273 -
       
  2274 -			tposted[scnt] = get_cycles();
       
  2275 -			if (ibv_post_send(ctx->qp[0],&ctx->wr, &bad_wr)) {
       
  2276 -				fprintf(stderr, "Couldn't post send: scnt=%d\n",scnt);
       
  2277 -				return 1;
       
  2278 -			}
       
  2279 -
       
  2280 -			if (user_param->size <= (CYCLE_BUFFER / 2))
       
  2281 -				increase_loc_addr(&ctx->list,user_param->size,scnt,(uintptr_t)ctx->buf[0],0);
       
  2282 -
       
  2283 -			++scnt;
       
  2284 -
       
  2285 -			if ((scnt % CQ_MODERATION) == (CQ_MODERATION - 1) || scnt == (user_param->iters - 1)) 
       
  2286 -				ctx->wr.send_flags |= IBV_SEND_SIGNALED;
       
  2287 -		}
       
  2288 -
       
  2289 -		if (user_param->use_event) {
       
  2290 -
       
  2291 -			if (ctx_notify_events(ctx->cq,ctx->channel)) {
       
  2292 -				fprintf(stderr,"Failed to notify events to CQ");
       
  2293 -				return 1;
       
  2294 -			}
       
  2295 -		}
       
  2296 -
       
  2297 -		do {
       
  2298 -			ne = ibv_poll_cq(ctx->cq,DEF_WC_SIZE,wc);
       
  2299 -			if (ne > 0) {
       
  2300 -				for (i = 0; i < ne; i++) {
       
  2301 -					
       
  2302 -					if (wc[i].status != IBV_WC_SUCCESS)
       
  2303 -						 NOTIFY_COMP_ERROR_SEND(wc[i],scnt,ccnt);
       
  2304 -
       
  2305 -					if ((int) wc[i].wr_id == PINGPONG_SEND_WRID) {
       
  2306 -						ccnt += CQ_MODERATION;
       
  2307 -						if (ccnt >= user_param->iters - 1) 
       
  2308 -							tcompleted[user_param->iters - 1] = get_cycles();
       
  2309 -
       
  2310 -						else 
       
  2311 -							tcompleted[ccnt - 1] = get_cycles();
       
  2312 -					}
       
  2313 -
       
  2314 -					else {
       
  2315 -
       
  2316 -						rcnt_for_qp[wc[i].wr_id]++;
       
  2317 -						rcnt++;
       
  2318 -						if (ibv_post_recv(ctx->qp[wc[i].wr_id],&ctx->rwr[wc[i].wr_id],&bad_wr_recv)) {
       
  2319 -							fprintf(stderr, "Couldn't post recv Qp=%d rcnt=%d\n",(int)wc[i].wr_id , rcnt_for_qp[wc[i].wr_id]);
       
  2320 -							return 15;
       
  2321 -						}
       
  2322 -
       
  2323 -						if (user_param->size <= (CYCLE_BUFFER / 2))
       
  2324 -							increase_loc_addr(&ctx->sge_list[wc[i].wr_id],
       
  2325 -							  user_param->size,rcnt_for_qp[wc[i].wr_id] + user_param->rx_depth - 1,
       
  2326 -							  ctx->my_addr[wc[i].wr_id],user_param->connection_type);	
       
  2327 -					}
       
  2328 -				}
       
  2329 -			}
       
  2330 -		} while (ne > 0);
       
  2331 -
       
  2332 -		if (ne < 0) {
       
  2333 -			fprintf(stderr, "poll CQ failed %d\n", ne);
       
  2334 -			return 1;
       
  2335 -		}
       
  2336 -	}
       
  2337 -	
       
  2338 -	if (user_param->size <= user_param->inline_size) 
       
  2339 -		ctx->wr.send_flags &= ~IBV_SEND_INLINE;
       
  2340 -	
       
  2341 -	free(rcnt_for_qp);
       
  2342 -	free(wc);
       
  2343 -	return 0;
       
  2344 -}
       
  2345 -
       
  2346 -/****************************************************************************** 
       
  2347 - *
       
  2348 - ******************************************************************************/
       
  2349 -int run_iter_uni_server(struct pingpong_context *ctx, 
       
  2350 -						struct perftest_parameters *user_param) {
       
  2351 -
       
  2352 -	int 				rcnt = 0;
       
  2353 -	int 				ne,i;
       
  2354 -	int                 *rcnt_for_qp = NULL;
       
  2355 -	struct ibv_wc 		*wc          = NULL;
       
  2356 -	struct ibv_recv_wr  *bad_wr_recv = NULL;
       
  2357 -
       
  2358 -	ALLOCATE(wc,struct ibv_wc,DEF_WC_SIZE);
       
  2359 -	ALLOCATE(rcnt_for_qp,int,user_param->num_of_qps);
       
  2360 -
       
  2361 -	memset(rcnt_for_qp,0,sizeof(int)*user_param->num_of_qps);
       
  2362 -
       
  2363 -	while (rcnt < user_param->iters) {
       
  2364 -
       
  2365 -		if (user_param->use_event) {
       
  2366 -			if (ctx_notify_events(ctx->cq,ctx->channel)) {
       
  2367 -				fprintf(stderr ," Failed to notify events to CQ");
       
  2368 -				return 1;
       
  2369 -			}
       
  2370 -		}
       
  2371 -		
       
  2372 -		do {
       
  2373 -			ne = ibv_poll_cq(ctx->cq,DEF_WC_SIZE,wc);
       
  2374 -			if (ne > 0) {
       
  2375 -				for (i = 0; i < ne; i++) {
       
  2376 -					
       
  2377 -					if (wc[i].status != IBV_WC_SUCCESS) 
       
  2378 -						NOTIFY_COMP_ERROR_RECV(wc[i],rcnt_for_qp[wc[i].wr_id]);
       
  2379 -						
       
  2380 -					rcnt_for_qp[wc[i].wr_id]++;
       
  2381 -					tcompleted[rcnt++] = get_cycles();
       
  2382 -
       
  2383 -				   	if (ibv_post_recv(ctx->qp[wc[i].wr_id],&ctx->rwr[wc[i].wr_id],&bad_wr_recv)) {
       
  2384 -						fprintf(stderr, "Couldn't post recv Qp=%d rcnt=%d\n",(int)wc[i].wr_id,rcnt_for_qp[wc[i].wr_id]);
       
  2385 -						return 15;
       
  2386 -					}
       
  2387 -
       
  2388 -					if (user_param->size <= (CYCLE_BUFFER / 2))
       
  2389 -						increase_loc_addr(&ctx->sge_list[wc[i].wr_id],user_param->size,
       
  2390 -										  rcnt_for_qp[wc[i].wr_id] + user_param->rx_depth,
       
  2391 -										  ctx->my_addr[wc[i].wr_id],user_param->connection_type);						
       
  2392 -				}
       
  2393 -			}
       
  2394 -		} while (ne > 0);
       
  2395 -
       
  2396 -		if (ne < 0) {
       
  2397 -			fprintf(stderr, "Poll Recieve CQ failed %d\n", ne);
       
  2398 -			return 1;
       
  2399 -		}
       
  2400 -	}
       
  2401 -
       
  2402 -	tposted[0] = tcompleted[0];
       
  2403 -	free(wc);
       
  2404 -	free(rcnt_for_qp);
       
  2405 -	return 0;
       
  2406 -}
       
  2407 -
       
  2408 -/****************************************************************************** 
       
  2409 - *
       
  2410 - ******************************************************************************/
       
  2411 -int run_iter_uni_client(struct pingpong_context *ctx, 
       
  2412 -						struct perftest_parameters *user_param) {
       
  2413 -
       
  2414 -	int 		       ne;
       
  2415 -	int 			   i    = 0;
       
  2416 -	int                scnt = 0;
       
  2417 -	int                ccnt = 0;
       
  2418 -	struct ibv_wc      *wc     = NULL;
       
  2419 -	struct ibv_send_wr *bad_wr = NULL;
       
  2420 -
       
  2421 -	ALLOCATE(wc,struct ibv_wc,DEF_WC_SIZE);
       
  2422 -
       
  2423 -	// Set the lenght of the scatter in case of ALL option.
       
  2424 -	ctx->list.length = user_param->size;
       
  2425 -	ctx->list.addr   = (uintptr_t)ctx->buf[0];
       
  2426 -	ctx->wr.send_flags = IBV_SEND_SIGNALED; 
       
  2427 -
       
  2428 -	if (user_param->size <= user_param->inline_size) 
       
  2429 -		ctx->wr.send_flags |= IBV_SEND_INLINE; 
       
  2430 -	
       
  2431 -
       
  2432 -	while (scnt < user_param->iters || ccnt < user_param->iters) {
       
  2433 -		while (scnt < user_param->iters && (scnt - ccnt) < user_param->tx_depth ) {
       
  2434 -
       
  2435 -			if (scnt %  CQ_MODERATION == 0 && CQ_MODERATION > 1)
       
  2436 -				ctx->wr.send_flags &= ~IBV_SEND_SIGNALED;
       
  2437 -
       
  2438 -			tposted[scnt] = get_cycles();
       
  2439 -			if (ibv_post_send(ctx->qp[0], &ctx->wr, &bad_wr)) {
       
  2440 -				fprintf(stderr, "Couldn't post send: scnt=%d\n",scnt);
       
  2441 -				return 1;
       
  2442 -			}
       
  2443 -
       
  2444 -			if (user_param->size <= (CYCLE_BUFFER / 2))
       
  2445 -				increase_loc_addr(&ctx->list,user_param->size,scnt,(uintptr_t)ctx->buf[0],0);
       
  2446 -
       
  2447 -			scnt++;
       
  2448 -
       
  2449 -			if ((scnt % CQ_MODERATION) == (CQ_MODERATION - 1) || scnt == (user_param->iters - 1)) 
       
  2450 -				ctx->wr.send_flags |= IBV_SEND_SIGNALED;
       
  2451 -		}
       
  2452 -
       
  2453 -		if (ccnt < user_param->iters) {	
       
  2454 -			
       
  2455 -			if (user_param->use_event) {
       
  2456 -				if (ctx_notify_events(ctx->cq,ctx->channel)) {
       
  2457 -					fprintf(stderr , " Failed to notify events to CQ");
       
  2458 -					return 1;
       
  2459 -				}
       
  2460 -			} 
       
  2461 -			do {
       
  2462 -				ne = ibv_poll_cq(ctx->cq,DEF_WC_SIZE,wc);
       
  2463 -				if (ne > 0) {
       
  2464 -					for (i = 0; i < DEF_WC_SIZE; i++) {
       
  2465 -
       
  2466 -						if (wc[i].status != IBV_WC_SUCCESS) 
       
  2467 -							NOTIFY_COMP_ERROR_SEND(wc[i],scnt,ccnt);
       
  2468 -			
       
  2469 -						ccnt += CQ_MODERATION;
       
  2470 -						if (ccnt >= user_param->iters - 1) 
       
  2471 -							tcompleted[user_param->iters - 1] = get_cycles();
       
  2472 -
       
  2473 -						else 
       
  2474 -							tcompleted[ccnt - 1] = get_cycles();
       
  2475 -					}
       
  2476 -				}
       
  2477 -                         
       
  2478 -					
       
  2479 -			} while (ne > 0);
       
  2480 -
       
  2481 -			if (ne < 0) {
       
  2482 -				fprintf(stderr, "poll CQ failed\n");
       
  2483 -				return 1;
       
  2484 -			}
       
  2485 -		}
       
  2486 -	}
       
  2487 -
       
  2488 -	if (user_param->size <= user_param->inline_size) 
       
  2489 -		ctx->wr.send_flags &= ~IBV_SEND_INLINE;
       
  2490 -
       
  2491 -	free(wc);
       
  2492 -	return 0;
       
  2493 -}
       
  2494 -
       
  2495 -/****************************************************************************** 
       
  2496 - *
       
  2497 - ******************************************************************************/
       
  2498 -int main(int argc, char *argv[])
       
  2499 -{
       
  2500 -	struct ibv_device		 	*ib_dev = NULL;
       
  2501 -	struct pingpong_context  	*ctx;
       
  2502 -	struct pingpong_dest	 	my_dest,rem_dest;
       
  2503 -	struct perftest_parameters  user_param;
       
  2504 -	struct mcast_parameters     mcg_params;
       
  2505 -	int                      	i = 0;
       
  2506 -	int                      	size_max_pow = 24;
       
  2507 -	int							size_of_arr;
       
  2508 -
       
  2509 -	// Pointer to The relevent function of run_iter according to machine type.
       
  2510 -	int (*ptr_to_run_iter_uni)(struct pingpong_context*,struct perftest_parameters*);
       
  2511 -
       
  2512 -	/* init default values to user's parameters */
       
  2513 -	memset(&user_param, 0 , sizeof(struct perftest_parameters));
       
  2514 -	memset(&mcg_params, 0 , sizeof(struct mcast_parameters));
       
  2515 -	memset(&my_dest   , 0 , sizeof(struct pingpong_dest));
       
  2516 -	memset(&rem_dest   , 0 , sizeof(struct pingpong_dest));
       
  2517 - 
       
  2518 -	user_param.verb    = SEND;
       
  2519 -	user_param.tst     = BW;
       
  2520 -	user_param.version = VERSION;
       
  2521 -
       
  2522 -	if (parser(&user_param,argv,argc)) 
       
  2523 -		return 1;
       
  2524 -
       
  2525 -	printf(RESULT_LINE);
       
  2526 -
       
  2527 -	user_param.rx_depth = (user_param.iters < user_param.rx_depth) ? user_param.iters : user_param.rx_depth ;
       
  2528 -
       
  2529 -    if (user_param.use_mcg) {
       
  2530 -
       
  2531 -		user_param.connection_type = UD;
       
  2532 -		if (user_param.duplex) {
       
  2533 -			user_param.num_of_qps++;
       
  2534 -			printf("                    Send Bidirectional BW  -  Multicast Test\n");
       
  2535 -		}
       
  2536 -		else {
       
  2537 -			printf("                    Send BW  -  Multicast Test\n");
       
  2538 -			if (user_param.machine == CLIENT)
       
  2539 -				user_param.num_of_qps = 1;
       
  2540 -		}
       
  2541 -    }
       
  2542 -
       
  2543 -	else if (user_param.duplex) {
       
  2544 -		    printf("                    Send Bidirectional BW Test\n");
       
  2545 -	} else 
       
  2546 -		    printf("                    Send BW Test\n");
       
  2547 -
       
  2548 -	if (user_param.use_event) 
       
  2549 -		printf(" Test with events.\n");
       
  2550 -
       
  2551 -	if (user_param.connection_type == RC)
       
  2552 -		printf(" Connection type : RC\n");
       
  2553 -	else if (user_param.connection_type == UC)
       
  2554 -		printf(" Connection type : UC\n");
       
  2555 -	else{
       
  2556 -		printf(" Connection type : UD\n");
       
  2557 -	}
       
  2558 -	
       
  2559 -	// Done with parameter parsing. Perform setup.
       
  2560 -	if (user_param.all == ON) {
       
  2561 -		// since we run all sizes 
       
  2562 -		user_param.size = MAX_SIZE;
       
  2563 -	}
       
  2564 -
       
  2565 -	srand48(getpid() * time(NULL));
       
  2566 -	page_size = sysconf(_SC_PAGESIZE);
       
  2567 -
       
  2568 -	ib_dev = ctx_find_dev(user_param.ib_devname);
       
  2569 -	if (!ib_dev)
       
  2570 -		return 7;
       
  2571 -
       
  2572 -	mcg_params.ib_devname = ibv_get_device_name(ib_dev);
       
  2573 -
       
  2574 -	ctx = pp_init_ctx(ib_dev,&user_param);
       
  2575 -	if (!ctx)
       
  2576 -		return 1;
       
  2577 -
       
  2578 -	// Set up the Connection.
       
  2579 -	if (set_up_connection(ctx,&user_param,&my_dest,&mcg_params)) {
       
  2580 -		fprintf(stderr," Unable to set up socket connection\n");
       
  2581 -		return 1;
       
  2582 -	}	
       
  2583 -
       
  2584 -	// Init the connection and print the local data.
       
  2585 -	if (init_connection(&user_param,&my_dest)) {
       
  2586 -		fprintf(stderr," Unable to init the socket connection\n");
       
  2587 -		return 1;
       
  2588 -	}
       
  2589 -
       
  2590 -	// shaking hands and gather the other side info.
       
  2591 -    if (ctx_hand_shake(&user_param,&my_dest,&rem_dest)) {
       
  2592 -        fprintf(stderr,"Failed to exchange date between server and clients\n");
       
  2593 -        return 1;
       
  2594 -        
       
  2595 -    }
       
  2596 -	// For printing only MGID in the remote side.
       
  2597 -	user_param.side = REMOTE;
       
  2598 -	ctx_print_pingpong_data(&rem_dest,&user_param);
       
  2599 -
       
  2600 -	// Joining the Send side port the Mcast gid
       
  2601 -	if (user_param.use_mcg && (user_param.machine == CLIENT || user_param.duplex)) {
       
  2602 -		memcpy(mcg_params.mgid.raw, rem_dest.gid.raw, 16);
       
  2603 -		if (set_mcast_group(ctx,&user_param,&mcg_params)) {
       
  2604 -			fprintf(stderr," Unable to Join Sender to Mcast gid\n");
       
  2605 -			return 1;
       
  2606 -		}
       
  2607 -	}
       
  2608 -
       
  2609 -	// Prepare IB resources for rtr/rts.
       
  2610 -	if (pp_connect_ctx(ctx,my_dest.psn,&rem_dest,&user_param)) {
       
  2611 -		fprintf(stderr," Unable to Connect the HCA's through the link\n");
       
  2612 -		return 1;
       
  2613 -	}
       
  2614 -	
       
  2615 -	// shaking hands and gather the other side info.
       
  2616 -    if (ctx_hand_shake(&user_param,&my_dest,&rem_dest)) {
       
  2617 -        fprintf(stderr,"Failed to exchange date between server and clients\n");
       
  2618 -        return 1;
       
  2619 -        
       
  2620 -    }
       
  2621 -
       
  2622 -	if (user_param.use_event) {
       
  2623 -		if (ibv_req_notify_cq(ctx->cq, 0)) {
       
  2624 -			fprintf(stderr, " Couldn't request CQ notification\n");
       
  2625 -			return 1;
       
  2626 -		} 
       
  2627 -	}
       
  2628 -
       
  2629 -	printf(RESULT_LINE);
       
  2630 -	printf(RESULT_FMT);
       
  2631 -
       
  2632 -	size_of_arr = (user_param.duplex) ? 1 : user_param.num_of_qps;
       
  2633 -
       
  2634 -	ALLOCATE(tposted,cycles_t,user_param.iters*size_of_arr);
       
  2635 -	ALLOCATE(tcompleted,cycles_t,user_param.iters*size_of_arr);
       
  2636 -
       
  2637 -	if (user_param.machine == SERVER || user_param.duplex) {
       
  2638 -		ALLOCATE(ctx->rwr,struct ibv_recv_wr,user_param.num_of_qps);
       
  2639 -		ALLOCATE(ctx->sge_list,struct ibv_sge,user_param.num_of_qps);
       
  2640 -		ALLOCATE(ctx->my_addr ,uint64_t ,user_param.num_of_qps);
       
  2641 -	}
       
  2642 -
       
  2643 -	ptr_to_run_iter_uni = (user_param.machine == CLIENT) ?	&run_iter_uni_client : &run_iter_uni_server;
       
  2644 -	
       
  2645 -	if (user_param.machine == SERVER && !user_param.duplex) {
       
  2646 -		user_param.noPeak = ON;
       
  2647 -	}
       
  2648 -
       
  2649 -	if (user_param.machine == CLIENT || user_param.duplex) {
       
  2650 -		set_send_wqe(ctx,rem_dest.qpn,&user_param);
       
  2651 -	}
       
  2652 -
       
  2653 -	if (user_param.all == ON) {
       
  2654 -
       
  2655 -		if (user_param.connection_type == UD) 
       
  2656 -		   size_max_pow =  (int)UD_MSG_2_EXP(MTU_SIZE(user_param.curr_mtu)) + 1;
       
  2657 -
       
  2658 -		for (i = 1; i < size_max_pow ; ++i) {
       
  2659 -			user_param.size = 1 << i;
       
  2660 -
       
  2661 -			if (user_param.machine == SERVER || user_param.duplex) {
       
  2662 -				if (set_recv_wqes(ctx,&user_param)) {
       
  2663 -					fprintf(stderr," Failed to post receive recv_wqes\n");
       
  2664 -					return 1;
       
  2665 -				}
       
  2666 -			}
       
  2667 -
       
  2668 -			if (ctx_hand_shake(&user_param,&my_dest,&rem_dest)) {
       
  2669 -				fprintf(stderr,"Failed to exchange date between server and clients\n");
       
  2670 -				return 1;
       
  2671 -			}
       
  2672 -
       
  2673 -			if (user_param.duplex) {
       
  2674 -				if(run_iter_bi(ctx,&user_param))
       
  2675 -					return 17;
       
  2676 -			} else {
       
  2677 -				if((*ptr_to_run_iter_uni)(ctx,&user_param))
       
  2678 -					return 17;
       
  2679 -			}
       
  2680 -			print_report(&user_param);
       
  2681 -
       
  2682 -			if (pp_drain_qp(ctx,&user_param,my_dest.psn,&rem_dest,&mcg_params)) {
       
  2683 -				fprintf(stderr,"Failed to drain Recv queue (performance optimization)\n");
       
  2684 -				return 1;
       
  2685 -			}
       
  2686 -
       
  2687 -			if (ctx_hand_shake(&user_param,&my_dest,&rem_dest)) {
       
  2688 -				fprintf(stderr,"Failed to exchange date between server and clients\n");
       
  2689 -				return 1;
       
  2690 -			}
       
  2691 -        
       
  2692 -		}
       
  2693 -
       
  2694 -	} else {
       
  2695 -
       
  2696 -		if (user_param.machine == SERVER || user_param.duplex) {
       
  2697 -			if (set_recv_wqes(ctx,&user_param)) {
       
  2698 -				fprintf(stderr," Failed to post receive recv_wqes\n");
       
  2699 -				return 1;
       
  2700 -			}
       
  2701 -		}
       
  2702 -
       
  2703 -		if (ctx_hand_shake(&user_param,&my_dest,&rem_dest)) {
       
  2704 -			fprintf(stderr,"Failed to exchange date between server and clients\n");
       
  2705 -			return 1;
       
  2706 -		}
       
  2707 -
       
  2708 -		if (user_param.duplex) {
       
  2709 -			if(run_iter_bi(ctx,&user_param))
       
  2710 -				return 18;
       
  2711 -
       
  2712 -		} else {
       
  2713 -			if((*ptr_to_run_iter_uni)(ctx,&user_param))
       
  2714 -				return 18;
       
  2715 -		}
       
  2716 -
       
  2717 -		print_report(&user_param);	
       
  2718 -	}
       
  2719 -		
       
  2720 -	if (ctx_close_connection(&user_param,&my_dest,&rem_dest)) {
       
  2721 -		fprintf(stderr," Failed to close connection between server and client\n");
       
  2722 -		return 1;
       
  2723 -	}
       
  2724 -
       
  2725 -	printf(RESULT_LINE);
       
  2726 -	return destroy_ctx_resources(ctx,&user_param,&my_dest,&rem_dest,&mcg_params);
       
  2727 -}
       
  2728 +/*
       
  2729 + * Copyright (c) 2005 Topspin Communications.  All rights reserved.
       
  2730 + * Copyright (c) 2005 Mellanox Technologies Ltd.  All rights reserved.
       
  2731 + * Copyright (c) 2009 HNR Consulting.  All rights reserved.
       
  2732 + *
       
  2733 + * This software is available to you under a choice of one of two
       
  2734 + * licenses.  You may choose to be licensed under the terms of the GNU
       
  2735 + * General Public License (GPL) Version 2, available from the file
       
  2736 + * COPYING in the main directory of this source tree, or the
       
  2737 + * OpenIB.org BSD license below:
       
  2738 + *
       
  2739 + *     Redistribution and use in source and binary forms, with or
       
  2740 + *     without modification, are permitted provided that the following
       
  2741 + *     conditions are met:
       
  2742 + *
       
  2743 + *      - Redistributions of source code must retain the above
       
  2744 + *        copyright notice, this list of conditions and the following
       
  2745 + *        disclaimer.
       
  2746 + *
       
  2747 + *      - Redistributions in binary form must reproduce the above
       
  2748 + *        copyright notice, this list of conditions and the following
       
  2749 + *        disclaimer in the documentation and/or other materials
       
  2750 + *        provided with the distribution.
       
  2751 + *
       
  2752 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
       
  2753 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
       
  2754 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
       
  2755 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
       
  2756 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
       
  2757 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
       
  2758 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
       
  2759 + * SOFTWARE.
       
  2760 + *
       
  2761 + * $Id$
       
  2762 + */
       
  2763 +
       
  2764 +#if HAVE_CONFIG_H
       
  2765 +#  include <config.h>
       
  2766 +#endif /* HAVE_CONFIG_H */
       
  2767 +
       
  2768 +#include <stdio.h>
       
  2769 +#include <stdlib.h>
       
  2770 +#include <unistd.h>
       
  2771 +#include <string.h>
       
  2772 +#include <limits.h>
       
  2773 +#include <malloc.h>
       
  2774 +#include <getopt.h>
       
  2775 +#include <time.h>
       
  2776 +#include <errno.h>
       
  2777 +#include <infiniband/verbs.h>
       
  2778 +
       
  2779 +#include "get_clock.h"
       
  2780 +#include "multicast_resources.h"
       
  2781 +#include "perftest_resources.h"
       
  2782 +
       
  2783 +#define VERSION 2.1
       
  2784 +
       
  2785 +static int page_size;
       
  2786 +cycles_t	*tposted;
       
  2787 +cycles_t	*tcompleted;
       
  2788 +
       
  2789 +struct pingpong_context {
       
  2790 +	struct ibv_context 		*context;
       
  2791 +	struct ibv_comp_channel *channel;
       
  2792 +	struct ibv_pd      		*pd;
       
  2793 +	struct ibv_mr     		**mr;
       
  2794 +	struct ibv_cq      		*cq;
       
  2795 +	struct ibv_qp      		**qp;
       
  2796 +	struct ibv_sge      	list;
       
  2797 +	struct ibv_send_wr  	wr;
       
  2798 +	struct ibv_sge 			*sge_list;
       
  2799 +	struct ibv_recv_wr  	*rwr;
       
  2800 +	struct ibv_ah			*ah;
       
  2801 +	void               		**buf;
       
  2802 +	unsigned            	size;
       
  2803 +	uint64_t				*my_addr;
       
  2804 +};
       
  2805 +
       
  2806 +/****************************************************************************** 
       
  2807 + *
       
  2808 + ******************************************************************************/
       
  2809 +static int set_mcast_group(struct pingpong_context *ctx,
       
  2810 +						   struct perftest_parameters *user_parm,
       
  2811 +						   struct mcast_parameters *mcg_params) {
       
  2812 +
       
  2813 +	struct ibv_port_attr port_attr;
       
  2814 +
       
  2815 +	if (ibv_query_gid(ctx->context,user_parm->ib_port,user_parm->gid_index,&mcg_params->port_gid)) {
       
  2816 +			return 1;
       
  2817 +	}
       
  2818 +		
       
  2819 +	if (ibv_query_pkey(ctx->context,user_parm->ib_port,DEF_PKEY_IDX,&mcg_params->pkey)) {
       
  2820 +		return 1;
       
  2821 +	}
       
  2822 +
       
  2823 +	if (ibv_query_port(ctx->context,user_parm->ib_port,&port_attr)) {
       
  2824 +		return 1;
       
  2825 +	}
       
  2826 +	mcg_params->sm_lid  = port_attr.sm_lid;
       
  2827 +	mcg_params->sm_sl   = port_attr.sm_sl;
       
  2828 +	mcg_params->ib_port = user_parm->ib_port;
       
  2829 +	
       
  2830 +	if (!strcmp(link_layer_str(user_parm->link_type),"IB")) {
       
  2831 +		// Request for Mcast group create registery in SM.
       
  2832 +		if (join_multicast_group(SUBN_ADM_METHOD_SET,mcg_params)) {
       
  2833 +			fprintf(stderr,"Couldn't Register the Mcast group on the SM\n");
       
  2834 +			return 1;
       
  2835 +		}
       
  2836 +	}
       
  2837 +	return 0;
       
  2838 +}
       
  2839 +
       
  2840 +/****************************************************************************** 
       
  2841 + *
       
  2842 + ******************************************************************************/
       
  2843 +static int set_up_connection(struct pingpong_context *ctx,
       
  2844 +							 struct perftest_parameters *user_parm,
       
  2845 +							 struct pingpong_dest *my_dest,
       
  2846 +							 struct mcast_parameters *mcg_params) {
       
  2847 +
       
  2848 +	int i = (user_parm->duplex) ? 1 : 0;
       
  2849 +
       
  2850 +	if (user_parm->use_mcg && (user_parm->duplex || user_parm->machine == SERVER)) {
       
  2851 +
       
  2852 +		set_multicast_gid(mcg_params,ctx->qp[0]->qp_num,(int)user_parm->machine);
       
  2853 +		if (set_mcast_group(ctx,user_parm,mcg_params)) {
       
  2854 +			return 1;
       
  2855 +		}
       
  2856 +		
       
  2857 +		while (i < user_parm->num_of_qps) {
       
  2858 +			if (ibv_attach_mcast(ctx->qp[i],&mcg_params->mgid,mcg_params->mlid)) {
       
  2859 +				fprintf(stderr, "Couldn't attach QP to MultiCast group");
       
  2860 +				return 1;
       
  2861 +			}
       
  2862 +			i++;
       
  2863 +		}
       
  2864 +
       
  2865 +		mcg_params->mcast_state |= MCAST_IS_ATTACHED;
       
  2866 +		my_dest->gid = mcg_params->mgid;
       
  2867 +		my_dest->lid = mcg_params->mlid;
       
  2868 +		my_dest->qpn = QPNUM_MCAST;
       
  2869 +
       
  2870 +	} else {
       
  2871 +		if (user_parm->gid_index != -1) {
       
  2872 +			if (ibv_query_gid(ctx->context,user_parm->ib_port,user_parm->gid_index,&my_dest->gid)) {
       
  2873 +				return -1;
       
  2874 +			}
       
  2875 +		}
       
  2876 +		my_dest->lid = ctx_get_local_lid(ctx->context,user_parm->ib_port);
       
  2877 +		my_dest->qpn = ctx->qp[0]->qp_num;
       
  2878 +	}
       
  2879 +	my_dest->psn  = lrand48() & 0xffffff;
       
  2880 +
       
  2881 +	// We do not fail test upon lid above RoCE.
       
  2882 +
       
  2883 +	if (user_parm->gid_index < 0) {
       
  2884 +		if (!my_dest->lid) {
       
  2885 +			fprintf(stderr," Local lid 0x0 detected,without any use of gid. Is SM running?\n");
       
  2886 +			return -1;
       
  2887 +		}
       
  2888 +	}
       
  2889 +	return 0;
       
  2890 +}
       
  2891 +
       
  2892 +/****************************************************************************** 
       
  2893 + *
       
  2894 + ******************************************************************************/
       
  2895 +static int init_connection(struct perftest_parameters *params,
       
  2896 + 						   struct pingpong_dest *my_dest) {
       
  2897 +
       
  2898 +	params->side = LOCAL;
       
  2899 +	ctx_print_pingpong_data(my_dest,params);
       
  2900 +	
       
  2901 +	if (params->machine == CLIENT) 
       
  2902 +		params->sockfd = ctx_client_connect(params->servername,params->port);
       
  2903 +	else 
       
  2904 +		params->sockfd = ctx_server_connect(params->port);
       
  2905 +	
       
  2906 +		
       
  2907 +	if(params->sockfd < 0) {
       
  2908 +		fprintf(stderr,"Unable to open file descriptor for socket connection");
       
  2909 +		return 1;
       
  2910 +	}
       
  2911 +	return 0;
       
  2912 +}
       
  2913 +
       
  2914 +/****************************************************************************** 
       
  2915 + *
       
  2916 + ******************************************************************************/
       
  2917 +static int destroy_ctx_resources(struct pingpong_context    *ctx, 
       
  2918 +								 struct perftest_parameters *user_parm,
       
  2919 +								 struct pingpong_dest		*my_dest,
       
  2920 +								 struct pingpong_dest		*rem_dest,
       
  2921 +								 struct mcast_parameters    *mcg_params)  {
       
  2922 +
       
  2923 +	int test_result = 0;
       
  2924 +	int i = (user_parm->duplex) ? 1 : 0;
       
  2925 +
       
  2926 +	if (user_parm->use_mcg) {
       
  2927 +
       
  2928 +		if (user_parm->machine == SERVER || user_parm->duplex) {
       
  2929 +			
       
  2930 +			while (i < user_parm->num_of_qps) {
       
  2931 +				if (ibv_detach_mcast(ctx->qp[i],&my_dest->gid,my_dest->lid)) {
       
  2932 +					fprintf(stderr, "Couldn't deattach QP from MultiCast group\n");
       
  2933 +					return 1;
       
  2934 +				}
       
  2935 +				i++;
       
  2936 +			}
       
  2937 +			mcg_params->mgid = my_dest->gid;
       
  2938 +			if (!strcmp(link_layer_str(user_parm->link_type),"IB")) {
       
  2939 +				if (join_multicast_group(SUBN_ADM_METHOD_DELETE,mcg_params)) {
       
  2940 +					fprintf(stderr,"Couldn't Unregister the Mcast group on the SM\n");
       
  2941 +					return 1;
       
  2942 +				}
       
  2943 +			}
       
  2944 +		}
       
  2945 +
       
  2946 +		if (user_parm->machine == CLIENT || user_parm->duplex) {
       
  2947 +
       
  2948 +			mcg_params->mgid = rem_dest->gid;
       
  2949 +			if (!strcmp(link_layer_str(user_parm->link_type),"IB")) {
       
  2950 +				if (join_multicast_group(SUBN_ADM_METHOD_DELETE,mcg_params)) {
       
  2951 +					fprintf(stderr,"Couldn't Unregister the Mcast group on the SM\n");
       
  2952 +					return 1;
       
  2953 +				}
       
  2954 +			}
       
  2955 +
       
  2956 +		}
       
  2957 +	}	
       
  2958 +
       
  2959 +	if (ctx->ah) {
       
  2960 +		if (ibv_destroy_ah(ctx->ah)) {
       
  2961 +			fprintf(stderr, "failed to destroy AH\n");
       
  2962 +			test_result = 1;
       
  2963 +		}
       
  2964 +	}
       
  2965 +
       
  2966 +	for(i = 0; i < user_parm->num_of_qps; i++) {
       
  2967 +		if (ibv_destroy_qp(ctx->qp[i])) {
       
  2968 +			test_result = 1;
       
  2969 +		}
       
  2970 +	}
       
  2971 +	free(ctx->qp);
       
  2972 +
       
  2973 +	if (ibv_destroy_cq(ctx->cq)) {
       
  2974 +		test_result = 1;
       
  2975 +	}
       
  2976 +
       
  2977 +	for(i = 0; i < user_parm->num_of_qps; i++) {
       
  2978 +
       
  2979 +		if (ibv_dereg_mr(ctx->mr[i])) {
       
  2980 +			test_result = 1;
       
  2981 +		}
       
  2982 +		free(ctx->buf[i]);
       
  2983 +	}
       
  2984 +	
       
  2985 +	if (ibv_dealloc_pd(ctx->pd)) {
       
  2986 +		test_result = 1;
       
  2987 +	}
       
  2988 +
       
  2989 +	if (ctx->channel) {
       
  2990 +		if (ibv_destroy_comp_channel(ctx->channel)) {
       
  2991 +			test_result = 1;
       
  2992 +		}
       
  2993 +	}
       
  2994 +	
       
  2995 +	if (ibv_close_device(ctx->context)) {
       
  2996 +		test_result = 1;
       
  2997 +	}
       
  2998 +
       
  2999 +	if (user_parm->machine == SERVER || user_parm->duplex) {
       
  3000 +		free(ctx->rwr);
       
  3001 +		free(ctx->sge_list);
       
  3002 +		free(ctx->my_addr);
       
  3003 +	}
       
  3004 +
       
  3005 +	free(ctx->mr);
       
  3006 +	free(ctx->buf);
       
  3007 +	free(ctx);
       
  3008 +	free(tposted);
       
  3009 +    free(tcompleted);
       
  3010 +	return test_result;
       
  3011 +}
       
  3012 +
       
  3013 +/****************************************************************************** 
       
  3014 + *
       
  3015 + ******************************************************************************/
       
  3016 +static struct pingpong_context *pp_init_ctx(struct ibv_device *ib_dev,
       
  3017 +											struct perftest_parameters *user_parm) {
       
  3018 +
       
  3019 +	int i,m_size;
       
  3020 +	int duplex_ind;
       
  3021 +	struct pingpong_context *ctx;
       
  3022 +
       
  3023 +	ALLOCATE(ctx,struct pingpong_context,1);
       
  3024 +	ALLOCATE(ctx->buf,void*,user_parm->num_of_qps);
       
  3025 +	ALLOCATE(ctx->mr,struct ibv_mr*,user_parm->num_of_qps);
       
  3026 +
       
  3027 +	ctx->ah       = NULL;
       
  3028 +	ctx->channel  = NULL;
       
  3029 +
       
  3030 +	duplex_ind = (user_parm->duplex && !user_parm->use_mcg) ? 2 : 1;
       
  3031 +
       
  3032 +	ctx->context = ibv_open_device(ib_dev);
       
  3033 +	if (!ctx->context) {
       
  3034 +		fprintf(stderr, "Couldn't get context for %s\n",
       
  3035 +			ibv_get_device_name(ib_dev));
       
  3036 +		return NULL;
       
  3037 +	}
       
  3038 +
       
  3039 +	// Configure the Link MTU acoording to the user or the active mtu.
       
  3040 +	if (ctx_set_mtu(ctx->context,user_parm)) {
       
  3041 +		fprintf(stderr, "Couldn't set the link layer\n");
       
  3042 +		return NULL;
       
  3043 +	}
       
  3044 +
       
  3045 +	if (user_parm->connection_type == UD && user_parm->size > MTU_SIZE(user_parm->curr_mtu)) {	 
       
  3046 +		printf(" Max msg size in UD is MTU - %d . changing to MTU\n",MTU_SIZE(user_parm->curr_mtu));
       
  3047 +		user_parm->size = MTU_SIZE(user_parm->curr_mtu);
       
  3048 +	}
       
  3049 +
       
  3050 +	if (is_dev_hermon(ctx->context) == NOT_HERMON && user_parm->inline_size != 0)
  1570 +	if (is_dev_hermon(ctx->context) == NOT_HERMON && user_parm->inline_size != 0)
  3051 +		user_parm->inline_size = 0;
  1571  		user_parm->inline_size = 0;
  3052 +
  1572  
  3053 +	printf(" Inline data is used up to %d bytes message\n", user_parm->inline_size);
  1573  	printf(" Inline data is used up to %d bytes message\n", user_parm->inline_size);
  3054 +
  1574 @@ -649,7 +649,11 @@
  3055 +	ctx->size = user_parm->size;
  1575  			}
  3056 +
  1576  	}
  3057 +	// Finds the link type and configure the HCA accordingly.
  1577  
  3058 +	if (ctx_set_link_layer(ctx->context,user_parm)) {
  1578 +#if !(defined(__SVR4) && defined(__sun))
  3059 +		fprintf(stderr, " Couldn't set the link layer\n");
  1579  	cycles_to_units = get_cpu_mhz(user_param->cpu_freq_f) * 1000000;
  3060 +		return NULL;
       
  3061 +	}
       
  3062 +	
       
  3063 +	if (user_parm->use_event) {
       
  3064 +		ctx->channel = ibv_create_comp_channel(ctx->context);
       
  3065 +		if (!ctx->channel) {
       
  3066 +			fprintf(stderr, "Couldn't create completion channel\n");
       
  3067 +			return NULL;
       
  3068 +		}
       
  3069 +	} else
       
  3070 +		ctx->channel = NULL;                  
       
  3071 +
       
  3072 +	ctx->pd = ibv_alloc_pd(ctx->context);
       
  3073 +	if (!ctx->pd) {
       
  3074 +		fprintf(stderr, "Couldn't allocate PD\n");
       
  3075 +		return NULL;
       
  3076 +	}
       
  3077 +
       
  3078 +	for (i = 0; i < user_parm->num_of_qps; i++) {
       
  3079 +
       
  3080 +		m_size = (BUFF_SIZE(user_parm->size) + IF_UD_ADD(user_parm->connection_type))*duplex_ind;
       
  3081 +		ctx->buf[i] = memalign(page_size,m_size);
       
  3082 +		if (!ctx->buf[i]) {
       
  3083 +			fprintf(stderr, "Couldn't allocate work buf.\n");
       
  3084 +			return NULL;
       
  3085 +		}
       
  3086 +		memset(ctx->buf[i],0,m_size);
       
  3087 +
       
  3088 +		// We dont really want IBV_ACCESS_LOCAL_WRITE, but IB spec says :
       
  3089 +		// The Consumer is not allowed to assign Remote Write or Remote Atomic to
       
  3090 +		// a Memory Region that has not been assigned Local Write. 
       
  3091 +		ctx->mr[i] = ibv_reg_mr(ctx->pd,
       
  3092 +								ctx->buf[i],
       
  3093 +								m_size,
       
  3094 +								IBV_ACCESS_REMOTE_WRITE | 
       
  3095 +								IBV_ACCESS_LOCAL_WRITE);
       
  3096 +
       
  3097 +		if (!ctx->mr[i]) {
       
  3098 +			fprintf(stderr, "Couldn't allocate MR\n");
       
  3099 +			return NULL;
       
  3100 +		}
       
  3101 +	}
       
  3102 +
       
  3103 +	// Create the CQ according to Client/Server or Duplex setting.
       
  3104 +	ctx->cq = ctx_cq_create(ctx->context,ctx->channel,user_parm);
       
  3105 +	if (ctx->cq == NULL) {
       
  3106 +		fprintf(stderr, "Couldn't create CQ \n");
       
  3107 +		return NULL;
       
  3108 +	}
       
  3109 +
       
  3110 +	ALLOCATE(ctx->qp,struct ibv_qp*,user_parm->num_of_qps);
       
  3111 +	
       
  3112 +	for(i=0; i < user_parm->num_of_qps; i++) {
       
  3113 +		ctx->qp[i] = ctx_qp_create(ctx->pd,ctx->cq,ctx->cq,user_parm);
       
  3114 +		if (ctx->qp[i] == NULL) {
       
  3115 +			return NULL;
       
  3116 +		}
       
  3117 +
       
  3118 +		if(ctx_modify_qp_to_init(ctx->qp[i],user_parm)) {
       
  3119 +			return NULL;
       
  3120 +		}
       
  3121 +	}
       
  3122 +
       
  3123 +	return ctx;
       
  3124 +}
       
  3125 +
       
  3126 +/****************************************************************************** 
       
  3127 + *
       
  3128 + ******************************************************************************/
       
  3129 +static int pp_connect_ctx(struct pingpong_context *ctx,int my_psn,
       
  3130 +			              struct pingpong_dest *dest, 
       
  3131 +						  struct perftest_parameters *user_parm)
       
  3132 +{
       
  3133 +	struct ibv_qp_attr attr;
       
  3134 +	memset(&attr, 0, sizeof attr);
       
  3135 +	int i;
       
  3136 +
       
  3137 +	attr.qp_state 		= IBV_QPS_RTR;
       
  3138 +	attr.path_mtu       = user_parm->curr_mtu;
       
  3139 +    attr.dest_qp_num    = dest->qpn;
       
  3140 +	attr.rq_psn         = dest->psn;
       
  3141 +	attr.ah_attr.dlid   = dest->lid;
       
  3142 +	if (user_parm->connection_type == RC) {
       
  3143 +		attr.max_dest_rd_atomic     = 1;
       
  3144 +		attr.min_rnr_timer          = 12;
       
  3145 +	}
       
  3146 +	if (user_parm->gid_index < 0) {
       
  3147 +		attr.ah_attr.is_global  = 0;
       
  3148 +		attr.ah_attr.sl         = user_parm->sl;
       
  3149 +	} else {
       
  3150 +		attr.ah_attr.is_global  = 1;
       
  3151 +		attr.ah_attr.grh.dgid   = dest->gid;
       
  3152 +		attr.ah_attr.grh.sgid_index = user_parm->gid_index;
       
  3153 +		attr.ah_attr.grh.hop_limit = 1;
       
  3154 +		attr.ah_attr.sl         = 0;
       
  3155 +	}
       
  3156 +	attr.ah_attr.src_path_bits = 0;
       
  3157 +	attr.ah_attr.port_num   = user_parm->ib_port;
       
  3158 +	
       
  3159 +	if (user_parm->connection_type == RC) {
       
  3160 +		if (ibv_modify_qp(ctx->qp[0], &attr,
       
  3161 +				  IBV_QP_STATE              |
       
  3162 +				  IBV_QP_AV                 |
       
  3163 +				  IBV_QP_PATH_MTU           |
       
  3164 +				  IBV_QP_DEST_QPN           |
       
  3165 +				  IBV_QP_RQ_PSN             |
       
  3166 +				  IBV_QP_MIN_RNR_TIMER      |
       
  3167 +				  IBV_QP_MAX_DEST_RD_ATOMIC)) {
       
  3168 +			fprintf(stderr, "Failed to modify RC QP to RTR\n");
       
  3169 +			return 1;
       
  3170 +		}
       
  3171 +		attr.timeout            = user_parm->qp_timeout;
       
  3172 +		attr.retry_cnt          = 7;
       
  3173 +		attr.rnr_retry          = 7;
       
  3174 +	} else if (user_parm->connection_type == UC) {
       
  3175 +		if (ibv_modify_qp(ctx->qp[0], &attr,
       
  3176 +				  IBV_QP_STATE              |
       
  3177 +				  IBV_QP_AV                 |
       
  3178 +				  IBV_QP_PATH_MTU           |
       
  3179 +				  IBV_QP_DEST_QPN           |
       
  3180 +				  IBV_QP_RQ_PSN)) {
       
  3181 +			fprintf(stderr, "Failed to modify UC QP to RTR\n");
       
  3182 +			return 1;
       
  3183 +		}
       
  3184 +	} 
       
  3185 +	 
       
  3186 +	else {
       
  3187 +		for (i = 0; i < user_parm->num_of_qps; i++) {
       
  3188 +			if (ibv_modify_qp(ctx->qp[i],&attr,IBV_QP_STATE )) {
       
  3189 +				fprintf(stderr, "Failed to modify UD QP to RTR\n");
       
  3190 +				return 1;
       
  3191 +			}
       
  3192 +		}
       
  3193 +		if (user_parm->machine == CLIENT || user_parm->duplex) {
       
  3194 +			ctx->ah = ibv_create_ah(ctx->pd,&attr.ah_attr);
       
  3195 +			if (!ctx->ah) {
       
  3196 +				fprintf(stderr, "Failed to create AH for UD\n");
       
  3197 +				return 1;
       
  3198 +			}
       
  3199 +		}
       
  3200 +	}
       
  3201 +
       
  3202 +	if (user_parm->machine == CLIENT || user_parm->duplex) {
       
  3203 +
       
  3204 +		attr.qp_state 	    = IBV_QPS_RTS;
       
  3205 +		attr.sq_psn 	    = my_psn;
       
  3206 +		if (user_parm->connection_type == RC) {
       
  3207 +			attr.max_rd_atomic  = 1;
       
  3208 +			if (ibv_modify_qp(ctx->qp[0], &attr,
       
  3209 +					IBV_QP_STATE              |
       
  3210 +					IBV_QP_SQ_PSN             |
       
  3211 +					IBV_QP_TIMEOUT            |
       
  3212 +					IBV_QP_RETRY_CNT          |
       
  3213 +					IBV_QP_RNR_RETRY          |
       
  3214 +					IBV_QP_MAX_QP_RD_ATOMIC)) {
       
  3215 +				fprintf(stderr, "Failed to modify RC QP to RTS\n");
       
  3216 +				return 1;
       
  3217 +			}
       
  3218 +
       
  3219 +		} else {
       
  3220 +			if(ibv_modify_qp(ctx->qp[0],&attr,IBV_QP_STATE |IBV_QP_SQ_PSN)) {
       
  3221 +				fprintf(stderr, "Failed to modify UC QP to RTS\n");
       
  3222 +				return 1;
       
  3223 +			}
       
  3224 +		}
       
  3225 +	}
       
  3226 +
       
  3227 +	return 0;
       
  3228 +}
       
  3229 +
       
  3230 +/****************************************************************************** 
       
  3231 + *
       
  3232 + ******************************************************************************/
       
  3233 +static int set_recv_wqes(struct pingpong_context *ctx,
       
  3234 +						 struct perftest_parameters *user_param) {
       
  3235 +						
       
  3236 +	int					i,j,buff_size;
       
  3237 +	int 				duplex_ind;
       
  3238 +	struct ibv_recv_wr  *bad_wr_recv;
       
  3239 +
       
  3240 +	i = (user_param->duplex && user_param->use_mcg) ? 1 : 0;
       
  3241 +	duplex_ind = (user_param->duplex && !user_param->use_mcg) ? 1 : 0;
       
  3242 +
       
  3243 +	buff_size = BUFF_SIZE(ctx->size) + IF_UD_ADD(user_param->connection_type);
       
  3244 +
       
  3245 +	while (i < user_param->num_of_qps) {
       
  3246 +
       
  3247 +		ctx->sge_list[i].addr   = (uintptr_t)ctx->buf[i] + duplex_ind*buff_size;
       
  3248 +
       
  3249 +		if (user_param->connection_type == UD) 
       
  3250 +			ctx->sge_list[i].addr += (CACHE_LINE_SIZE - UD_ADDITION);
       
  3251 +
       
  3252 +		ctx->sge_list[i].length = SIZE(user_param->connection_type,user_param->size);
       
  3253 +		ctx->sge_list[i].lkey   = ctx->mr[i]->lkey;
       
  3254 +		ctx->rwr[i].sg_list     = &ctx->sge_list[i];
       
  3255 +		ctx->rwr[i].wr_id       = i;
       
  3256 +		ctx->rwr[i].next        = NULL;
       
  3257 +		ctx->rwr[i].num_sge	    = MAX_RECV_SGE;
       
  3258 +		ctx->my_addr[i]		    = (uintptr_t)ctx->buf[i] + duplex_ind*buff_size;
       
  3259 +		
       
  3260 +		for (j = 0; j < user_param->rx_depth; ++j) {
       
  3261 +
       
  3262 +			if (ibv_post_recv(ctx->qp[i],&ctx->rwr[i],&bad_wr_recv)) {
       
  3263 +				fprintf(stderr, "Couldn't post recv Qp = %d: counter=%d\n",i,j);
       
  3264 +				return 1;
       
  3265 +			}
       
  3266 +
       
  3267 +			if (user_param->size <= (CYCLE_BUFFER / 2))
       
  3268 +				increase_loc_addr(&ctx->sge_list[i],user_param->size,j,ctx->my_addr[i],user_param->connection_type);
       
  3269 +		}
       
  3270 +		i++;
       
  3271 +	}
       
  3272 +	return 0;
       
  3273 +}
       
  3274 +
       
  3275 +/****************************************************************************** 
       
  3276 + *
       
  3277 + ******************************************************************************/
       
  3278 +static void set_send_wqe(struct pingpong_context *ctx,int rem_qpn,
       
  3279 +						 struct perftest_parameters *user_param) {
       
  3280 +
       
  3281 +	ctx->list.addr     = (uintptr_t)ctx->buf[0];
       
  3282 +	ctx->list.lkey 	   = ctx->mr[0]->lkey;
       
  3283 +
       
  3284 +	ctx->wr.sg_list    = &ctx->list;
       
  3285 +	ctx->wr.num_sge    = 1;
       
  3286 +	ctx->wr.opcode     = IBV_WR_SEND;
       
  3287 +	ctx->wr.next       = NULL;
       
  3288 +	ctx->wr.wr_id      = PINGPONG_SEND_WRID;
       
  3289 +	ctx->wr.send_flags = IBV_SEND_SIGNALED;
       
  3290 +
       
  3291 +	if (user_param->connection_type == UD) {
       
  3292 +		ctx->wr.wr.ud.ah          = ctx->ah;
       
  3293 +		ctx->wr.wr.ud.remote_qkey = DEF_QKEY;
       
  3294 +		ctx->wr.wr.ud.remote_qpn  = rem_qpn;
       
  3295 +	}
       
  3296 +}
       
  3297 +
       
  3298 +/****************************************************************************** 
       
  3299 + *
       
  3300 + ******************************************************************************/
       
  3301 +static int pp_drain_qp(struct pingpong_context *ctx,
       
  3302 +						struct perftest_parameters *user_param,
       
  3303 +						int psn,struct pingpong_dest *dest,
       
  3304 +						struct mcast_parameters *mcg_params) {
       
  3305 +
       
  3306 +	struct ibv_qp_attr attr;
       
  3307 +	struct ibv_wc      wc;
       
  3308 +	int                i;
       
  3309 +
       
  3310 +	memset(&attr, 0, sizeof attr);
       
  3311 +	attr.qp_state = IBV_QPS_ERR;
       
  3312 +
       
  3313 +	for (i = 0; i <  user_param->num_of_qps; i++) {
       
  3314 +
       
  3315 +		if (ibv_modify_qp(ctx->qp[i],&attr,IBV_QP_STATE)) {
       
  3316 +			fprintf(stderr, "Failed to modify RC QP to ERR\n");
       
  3317 +			return 1;
       
  3318 +		}
       
  3319 +
       
  3320 +		while (ibv_poll_cq(ctx->cq,1,&wc));
       
  3321 +   
       
  3322 +		attr.qp_state = IBV_QPS_RESET;
       
  3323 +
       
  3324 +		if (ibv_modify_qp(ctx->qp[i],&attr,IBV_QP_STATE)) {
       
  3325 +			fprintf(stderr, "Failed to modify RC QP to RESET\n");
       
  3326 +			return 1;
       
  3327 +		}
       
  3328 +
       
  3329 +		if(ctx_modify_qp_to_init(ctx->qp[i],user_param)) {
       
  3330 +			return 1;
       
  3331 +		}
       
  3332 +
       
  3333 +		if (user_param->use_mcg) {
       
  3334 +
       
  3335 +			if ((!user_param->duplex && user_param->machine == SERVER) || (user_param->duplex && i > 0)) {
       
  3336 +				if (ibv_attach_mcast(ctx->qp[i],&mcg_params->mgid,mcg_params->mlid)) {
       
  3337 +					fprintf(stderr, "Couldn't attach QP to MultiCast group");
       
  3338 +					return 1;
       
  3339 +				}
       
  3340 +			}
       
  3341 +		}
       
  3342 +	}
       
  3343 +
       
  3344 +	if (pp_connect_ctx(ctx,psn,dest,user_param)) {
       
  3345 +		return 1;
       
  3346 +	}
       
  3347 +
       
  3348 +	return 0;
       
  3349 +}
       
  3350 +
       
  3351 +/****************************************************************************** 
       
  3352 + *
       
  3353 + ******************************************************************************/
       
  3354 +static void print_report(struct perftest_parameters *user_param) {
       
  3355 +
       
  3356 +	double cycles_to_units;
       
  3357 +	unsigned long tsize;	/* Transferred size, in megabytes */
       
  3358 +	int i, j;
       
  3359 +	int opt_posted = 0, opt_completed = 0;
       
  3360 +	cycles_t opt_delta;
       
  3361 +	cycles_t t;
       
  3362 +
       
  3363 +
       
  3364 +	opt_delta = tcompleted[opt_posted] - tposted[opt_completed];
       
  3365 +
       
  3366 +	if (user_param->noPeak == OFF) {
       
  3367 +		/* Find the peak bandwidth, unless asked not to in command line */
       
  3368 +		for (i = 0; i < user_param->iters; ++i)
       
  3369 +			for (j = i; j < user_param->iters; ++j) {
       
  3370 +				t = (tcompleted[j] - tposted[i]) / (j - i + 1);
       
  3371 +				if (t < opt_delta) {
       
  3372 +					opt_delta  = t;
       
  3373 +					opt_posted = i;
       
  3374 +					opt_completed = j;
       
  3375 +				}
       
  3376 +			}
       
  3377 +	}
       
  3378 +
       
  3379 +#if !(defined(__SVR4) && defined(__sun))
       
  3380 +	cycles_to_units = get_cpu_mhz(user_param->cpu_freq_f) * 1000000;
       
  3381 +#else
  1580 +#else
  3382 +	cycles_to_units = 1000000000;
  1581 +	cycles_to_units = 1000000000;
  3383 +#endif
  1582 +#endif
  3384 +
  1583  
  3385 +	tsize = user_param->duplex ? 2 : 1;
  1584  	tsize = user_param->duplex ? 2 : 1;
  3386 +	tsize = tsize * user_param->size;
  1585  	tsize = tsize * user_param->size;
  3387 +	printf(REPORT_FMT,user_param->size,user_param->iters,(user_param->noPeak == OFF) * tsize * cycles_to_units / opt_delta / 0x100000,
       
  3388 +	       tsize * user_param->iters * cycles_to_units /(tcompleted[user_param->iters - 1] - tposted[0]) / 0x100000);
       
  3389 +}
       
  3390 +
       
  3391 +/****************************************************************************** 
       
  3392 + * Important note :															  
       
  3393 + * In case of UD/UC this is NOT the way to measureBW since we are running with 
       
  3394 + * loop on the send side , while we should run on the recieve side or enable 
       
  3395 + * retry in SW , Since the sender may be faster than the reciver.
       
  3396 + * Although	we had posted recieve it is not enough and might end this will
       
  3397 + * result in deadlock of test since both sides are stuck on poll cq.
       
  3398 + * In this test i do not solve this for the general test ,need to write
       
  3399 + * seperate test for UC/UD but in case the tx_depth is ~1/3 from the
       
  3400 + * number of iterations this should be ok .
       
  3401 + * Also note that the sender is limited in the number of send, ans
       
  3402 + * i try to make the reciver full .
       
  3403 + ******************************************************************************/
       
  3404 +int run_iter_bi(struct pingpong_context *ctx, 
       
  3405 +				struct perftest_parameters *user_param)  {
       
  3406 +
       
  3407 +	int                     scnt    = 0;
       
  3408 +	int 					ccnt    = 0;
       
  3409 +	int 					rcnt    = 0;
       
  3410 +	int 					i       = 0;
       
  3411 +	int 					num_of_qps = user_param->num_of_qps;
       
  3412 +	int 					ne;
       
  3413 +	struct ibv_wc 			*wc          = NULL;
       
  3414 +	int 					*rcnt_for_qp = NULL;
       
  3415 +	struct ibv_recv_wr      *bad_wr_recv = NULL;
       
  3416 +	struct ibv_send_wr 		*bad_wr      = NULL;
       
  3417 +
       
  3418 +	ALLOCATE(rcnt_for_qp,int,user_param->num_of_qps);
       
  3419 +	ALLOCATE(wc,struct ibv_wc,DEF_WC_SIZE);
       
  3420 +	memset(rcnt_for_qp,0,sizeof(int)*user_param->num_of_qps);
       
  3421 +
       
  3422 +	if (user_param->use_mcg)
       
  3423 +		num_of_qps--; 
       
  3424 +	
       
  3425 +	// Set the length of the scatter in case of ALL option.
       
  3426 +	ctx->list.length = user_param->size;
       
  3427 +	ctx->list.addr   = (uintptr_t)ctx->buf[0];
       
  3428 +	ctx->wr.send_flags = IBV_SEND_SIGNALED;
       
  3429 +	
       
  3430 +	if (user_param->size <= user_param->inline_size) 
       
  3431 +		ctx->wr.send_flags |= IBV_SEND_INLINE; 
       
  3432 +
       
  3433 +	while (ccnt < user_param->iters || rcnt < user_param->iters) {
       
  3434 +                
       
  3435 +		while (scnt < user_param->iters && (scnt - ccnt) < user_param->tx_depth / 2) {
       
  3436 +
       
  3437 +			if (scnt %  CQ_MODERATION == 0 && CQ_MODERATION > 1)
       
  3438 +				ctx->wr.send_flags &= ~IBV_SEND_SIGNALED;
       
  3439 +
       
  3440 +			tposted[scnt] = get_cycles();
       
  3441 +			if (ibv_post_send(ctx->qp[0],&ctx->wr, &bad_wr)) {
       
  3442 +				fprintf(stderr, "Couldn't post send: scnt=%d\n",scnt);
       
  3443 +				return 1;
       
  3444 +			}
       
  3445 +
       
  3446 +			if (user_param->size <= (CYCLE_BUFFER / 2))
       
  3447 +				increase_loc_addr(&ctx->list,user_param->size,scnt,(uintptr_t)ctx->buf[0],0);
       
  3448 +
       
  3449 +			++scnt;
       
  3450 +
       
  3451 +			if ((scnt % CQ_MODERATION) == (CQ_MODERATION - 1) || scnt == (user_param->iters - 1)) 
       
  3452 +				ctx->wr.send_flags |= IBV_SEND_SIGNALED;
       
  3453 +		}
       
  3454 +
       
  3455 +		if (user_param->use_event) {
       
  3456 +
       
  3457 +			if (ctx_notify_events(ctx->cq,ctx->channel)) {
       
  3458 +				fprintf(stderr,"Failed to notify events to CQ");
       
  3459 +				return 1;
       
  3460 +			}
       
  3461 +		}
       
  3462 +
       
  3463 +		do {
       
  3464 +			ne = ibv_poll_cq(ctx->cq,DEF_WC_SIZE,wc);
       
  3465 +			if (ne > 0) {
       
  3466 +				for (i = 0; i < ne; i++) {
       
  3467 +					
       
  3468 +					if (wc[i].status != IBV_WC_SUCCESS)
       
  3469 +						 NOTIFY_COMP_ERROR_SEND(wc[i],scnt,ccnt);
       
  3470 +
       
  3471 +					if ((int) wc[i].wr_id == PINGPONG_SEND_WRID) {
       
  3472 +						ccnt += CQ_MODERATION;
       
  3473 +						if (ccnt >= user_param->iters - 1) 
       
  3474 +							tcompleted[user_param->iters - 1] = get_cycles();
       
  3475 +
       
  3476 +						else 
       
  3477 +							tcompleted[ccnt - 1] = get_cycles();
       
  3478 +					}
       
  3479 +
       
  3480 +					else {
       
  3481 +
       
  3482 +						rcnt_for_qp[wc[i].wr_id]++;
       
  3483 +						rcnt++;
       
  3484 +						if (ibv_post_recv(ctx->qp[wc[i].wr_id],&ctx->rwr[wc[i].wr_id],&bad_wr_recv)) {
       
  3485 +							fprintf(stderr, "Couldn't post recv Qp=%d rcnt=%d\n",(int)wc[i].wr_id , rcnt_for_qp[wc[i].wr_id]);
       
  3486 +							return 15;
       
  3487 +						}
       
  3488 +
       
  3489 +						if (user_param->size <= (CYCLE_BUFFER / 2))
       
  3490 +							increase_loc_addr(&ctx->sge_list[wc[i].wr_id],
       
  3491 +							  user_param->size,rcnt_for_qp[wc[i].wr_id] + user_param->rx_depth - 1,
       
  3492 +							  ctx->my_addr[wc[i].wr_id],user_param->connection_type);	
       
  3493 +					}
       
  3494 +				}
       
  3495 +			}
       
  3496 +		} while (ne > 0);
       
  3497 +
       
  3498 +		if (ne < 0) {
       
  3499 +			fprintf(stderr, "poll CQ failed %d\n", ne);
       
  3500 +			return 1;
       
  3501 +		}
       
  3502 +	}
       
  3503 +	
       
  3504 +	if (user_param->size <= user_param->inline_size) 
       
  3505 +		ctx->wr.send_flags &= ~IBV_SEND_INLINE;
       
  3506 +	
       
  3507 +	free(rcnt_for_qp);
       
  3508 +	free(wc);
       
  3509 +	return 0;
       
  3510 +}
       
  3511 +
       
  3512 +/****************************************************************************** 
       
  3513 + *
       
  3514 + ******************************************************************************/
       
  3515 +int run_iter_uni_server(struct pingpong_context *ctx, 
       
  3516 +						struct perftest_parameters *user_param) {
       
  3517 +
       
  3518 +	int 				rcnt = 0;
       
  3519 +	int 				ne,i;
       
  3520 +	int                 *rcnt_for_qp = NULL;
       
  3521 +	struct ibv_wc 		*wc          = NULL;
       
  3522 +	struct ibv_recv_wr  *bad_wr_recv = NULL;
       
  3523 +
       
  3524 +	ALLOCATE(wc,struct ibv_wc,DEF_WC_SIZE);
       
  3525 +	ALLOCATE(rcnt_for_qp,int,user_param->num_of_qps);
       
  3526 +
       
  3527 +	memset(rcnt_for_qp,0,sizeof(int)*user_param->num_of_qps);
       
  3528 +
       
  3529 +	while (rcnt < user_param->iters) {
       
  3530 +
       
  3531 +		if (user_param->use_event) {
       
  3532 +			if (ctx_notify_events(ctx->cq,ctx->channel)) {
       
  3533 +				fprintf(stderr ," Failed to notify events to CQ");
       
  3534 +				return 1;
       
  3535 +			}
       
  3536 +		}
       
  3537 +		
       
  3538 +		do {
       
  3539 +			ne = ibv_poll_cq(ctx->cq,DEF_WC_SIZE,wc);
       
  3540 +			if (ne > 0) {
       
  3541 +				for (i = 0; i < ne; i++) {
       
  3542 +					
       
  3543 +					if (wc[i].status != IBV_WC_SUCCESS) 
       
  3544 +						NOTIFY_COMP_ERROR_RECV(wc[i],rcnt_for_qp[wc[i].wr_id]);
       
  3545 +						
       
  3546 +					rcnt_for_qp[wc[i].wr_id]++;
       
  3547 +					tcompleted[rcnt++] = get_cycles();
       
  3548 +
       
  3549 +				   	if (ibv_post_recv(ctx->qp[wc[i].wr_id],&ctx->rwr[wc[i].wr_id],&bad_wr_recv)) {
       
  3550 +						fprintf(stderr, "Couldn't post recv Qp=%d rcnt=%d\n",(int)wc[i].wr_id,rcnt_for_qp[wc[i].wr_id]);
       
  3551 +						return 15;
       
  3552 +					}
       
  3553 +
       
  3554 +					if (user_param->size <= (CYCLE_BUFFER / 2))
       
  3555 +						increase_loc_addr(&ctx->sge_list[wc[i].wr_id],user_param->size,
       
  3556 +										  rcnt_for_qp[wc[i].wr_id] + user_param->rx_depth,
       
  3557 +										  ctx->my_addr[wc[i].wr_id],user_param->connection_type);						
       
  3558 +				}
       
  3559 +			}
       
  3560 +		} while (ne > 0);
       
  3561 +
       
  3562 +		if (ne < 0) {
       
  3563 +			fprintf(stderr, "Poll Recieve CQ failed %d\n", ne);
       
  3564 +			return 1;
       
  3565 +		}
       
  3566 +	}
       
  3567 +
       
  3568 +	tposted[0] = tcompleted[0];
       
  3569 +	free(wc);
       
  3570 +	free(rcnt_for_qp);
       
  3571 +	return 0;
       
  3572 +}
       
  3573 +
       
  3574 +/****************************************************************************** 
       
  3575 + *
       
  3576 + ******************************************************************************/
       
  3577 +int run_iter_uni_client(struct pingpong_context *ctx, 
       
  3578 +						struct perftest_parameters *user_param) {
       
  3579 +
       
  3580 +	int 		       ne;
       
  3581 +	int 			   i    = 0;
       
  3582 +	int                scnt = 0;
       
  3583 +	int                ccnt = 0;
       
  3584 +	struct ibv_wc      *wc     = NULL;
       
  3585 +	struct ibv_send_wr *bad_wr = NULL;
       
  3586 +
       
  3587 +	ALLOCATE(wc,struct ibv_wc,DEF_WC_SIZE);
       
  3588 +
       
  3589 +	// Set the lenght of the scatter in case of ALL option.
       
  3590 +	ctx->list.length = user_param->size;
       
  3591 +	ctx->list.addr   = (uintptr_t)ctx->buf[0];
       
  3592 +	ctx->wr.send_flags = IBV_SEND_SIGNALED; 
       
  3593 +
       
  3594 +	if (user_param->size <= user_param->inline_size) 
       
  3595 +		ctx->wr.send_flags |= IBV_SEND_INLINE; 
       
  3596 +	
       
  3597 +
       
  3598 +	while (scnt < user_param->iters || ccnt < user_param->iters) {
       
  3599 +		while (scnt < user_param->iters && (scnt - ccnt) < user_param->tx_depth ) {
       
  3600 +
       
  3601 +			if (scnt %  CQ_MODERATION == 0 && CQ_MODERATION > 1)
       
  3602 +				ctx->wr.send_flags &= ~IBV_SEND_SIGNALED;
       
  3603 +
       
  3604 +			tposted[scnt] = get_cycles();
       
  3605 +			if (ibv_post_send(ctx->qp[0], &ctx->wr, &bad_wr)) {
       
  3606 +				fprintf(stderr, "Couldn't post send: scnt=%d\n",scnt);
       
  3607 +				return 1;
       
  3608 +			}
       
  3609 +
       
  3610 +			if (user_param->size <= (CYCLE_BUFFER / 2))
       
  3611 +				increase_loc_addr(&ctx->list,user_param->size,scnt,(uintptr_t)ctx->buf[0],0);
       
  3612 +
       
  3613 +			scnt++;
       
  3614 +
       
  3615 +			if ((scnt % CQ_MODERATION) == (CQ_MODERATION - 1) || scnt == (user_param->iters - 1)) 
       
  3616 +				ctx->wr.send_flags |= IBV_SEND_SIGNALED;
       
  3617 +		}
       
  3618 +
       
  3619 +		if (ccnt < user_param->iters) {	
       
  3620 +			
       
  3621 +			if (user_param->use_event) {
       
  3622 +				if (ctx_notify_events(ctx->cq,ctx->channel)) {
       
  3623 +					fprintf(stderr , " Failed to notify events to CQ");
       
  3624 +					return 1;
       
  3625 +				}
       
  3626 +			} 
       
  3627 +			do {
       
  3628 +				ne = ibv_poll_cq(ctx->cq,DEF_WC_SIZE,wc);
       
  3629 +				if (ne > 0) {
       
  3630 +					for (i = 0; i < DEF_WC_SIZE; i++) {
       
  3631 +
       
  3632 +						if (wc[i].status != IBV_WC_SUCCESS) 
       
  3633 +							NOTIFY_COMP_ERROR_SEND(wc[i],scnt,ccnt);
       
  3634 +			
       
  3635 +						ccnt += CQ_MODERATION;
       
  3636 +						if (ccnt >= user_param->iters - 1) 
       
  3637 +							tcompleted[user_param->iters - 1] = get_cycles();
       
  3638 +
       
  3639 +						else 
       
  3640 +							tcompleted[ccnt - 1] = get_cycles();
       
  3641 +					}
       
  3642 +				}
       
  3643 +                         
       
  3644 +					
       
  3645 +			} while (ne > 0);
       
  3646 +
       
  3647 +			if (ne < 0) {
       
  3648 +				fprintf(stderr, "poll CQ failed\n");
       
  3649 +				return 1;
       
  3650 +			}
       
  3651 +		}
       
  3652 +	}
       
  3653 +
       
  3654 +	if (user_param->size <= user_param->inline_size) 
       
  3655 +		ctx->wr.send_flags &= ~IBV_SEND_INLINE;
       
  3656 +
       
  3657 +	free(wc);
       
  3658 +	return 0;
       
  3659 +}
       
  3660 +
       
  3661 +/****************************************************************************** 
       
  3662 + *
       
  3663 + ******************************************************************************/
       
  3664 +int main(int argc, char *argv[])
       
  3665 +{
       
  3666 +	struct ibv_device		 	*ib_dev = NULL;
       
  3667 +	struct pingpong_context  	*ctx;
       
  3668 +	struct pingpong_dest	 	my_dest,rem_dest;
       
  3669 +	struct perftest_parameters  user_param;
       
  3670 +	struct mcast_parameters     mcg_params;
       
  3671 +	int                      	i = 0;
       
  3672 +	int                      	size_max_pow = 24;
       
  3673 +	int							size_of_arr;
       
  3674 +
       
  3675 +	// Pointer to The relevent function of run_iter according to machine type.
       
  3676 +	int (*ptr_to_run_iter_uni)(struct pingpong_context*,struct perftest_parameters*);
       
  3677 +
       
  3678 +	/* init default values to user's parameters */
       
  3679 +	memset(&user_param, 0 , sizeof(struct perftest_parameters));
       
  3680 +	memset(&mcg_params, 0 , sizeof(struct mcast_parameters));
       
  3681 +	memset(&my_dest   , 0 , sizeof(struct pingpong_dest));
       
  3682 +	memset(&rem_dest   , 0 , sizeof(struct pingpong_dest));
       
  3683 + 
       
  3684 +	user_param.verb    = SEND;
       
  3685 +	user_param.tst     = BW;
       
  3686 +	user_param.version = VERSION;
       
  3687 +
       
  3688 +	if (parser(&user_param,argv,argc)) 
       
  3689 +		return 1;
       
  3690 +
       
  3691 +	printf(RESULT_LINE);
       
  3692 +
       
  3693 +	user_param.rx_depth = (user_param.iters < user_param.rx_depth) ? user_param.iters : user_param.rx_depth ;
       
  3694 +
       
  3695 +    if (user_param.use_mcg) {
       
  3696 +
       
  3697 +		user_param.connection_type = UD;
       
  3698 +		if (user_param.duplex) {
       
  3699 +			user_param.num_of_qps++;
       
  3700 +			printf("                    Send Bidirectional BW  -  Multicast Test\n");
       
  3701 +		}
       
  3702 +		else {
       
  3703 +			printf("                    Send BW  -  Multicast Test\n");
       
  3704 +			if (user_param.machine == CLIENT)
       
  3705 +				user_param.num_of_qps = 1;
       
  3706 +		}
       
  3707 +    }
       
  3708 +
       
  3709 +	else if (user_param.duplex) {
       
  3710 +		    printf("                    Send Bidirectional BW Test\n");
       
  3711 +	} else 
       
  3712 +		    printf("                    Send BW Test\n");
       
  3713 +
       
  3714 +	if (user_param.use_event) 
       
  3715 +		printf(" Test with events.\n");
       
  3716 +
       
  3717 +	if (user_param.connection_type == RC)
       
  3718 +		printf(" Connection type : RC\n");
       
  3719 +	else if (user_param.connection_type == UC)
       
  3720 +		printf(" Connection type : UC\n");
       
  3721 +	else{
       
  3722 +		printf(" Connection type : UD\n");
       
  3723 +	}
       
  3724 +	
       
  3725 +	// Done with parameter parsing. Perform setup.
       
  3726 +	if (user_param.all == ON) {
       
  3727 +		// since we run all sizes 
       
  3728 +		user_param.size = MAX_SIZE;
       
  3729 +	}
       
  3730 +
       
  3731 +	srand48(getpid() * time(NULL));
       
  3732 +	page_size = sysconf(_SC_PAGESIZE);
       
  3733 +
       
  3734 +	ib_dev = ctx_find_dev(user_param.ib_devname);
       
  3735 +	if (!ib_dev)
       
  3736 +		return 7;
       
  3737 +
       
  3738 +	mcg_params.ib_devname = ibv_get_device_name(ib_dev);
       
  3739 +
       
  3740 +	ctx = pp_init_ctx(ib_dev,&user_param);
       
  3741 +	if (!ctx)
       
  3742 +		return 1;
       
  3743 +
       
  3744 +	// Set up the Connection.
       
  3745 +	if (set_up_connection(ctx,&user_param,&my_dest,&mcg_params)) {
       
  3746 +		fprintf(stderr," Unable to set up socket connection\n");
       
  3747 +		return 1;
       
  3748 +	}	
       
  3749 +
       
  3750 +	// Init the connection and print the local data.
       
  3751 +	if (init_connection(&user_param,&my_dest)) {
       
  3752 +		fprintf(stderr," Unable to init the socket connection\n");
       
  3753 +		return 1;
       
  3754 +	}
       
  3755 +
       
  3756 +	// shaking hands and gather the other side info.
       
  3757 +    if (ctx_hand_shake(&user_param,&my_dest,&rem_dest)) {
       
  3758 +        fprintf(stderr,"Failed to exchange date between server and clients\n");
       
  3759 +        return 1;
       
  3760 +        
       
  3761 +    }
       
  3762 +	// For printing only MGID in the remote side.
       
  3763 +	user_param.side = REMOTE;
       
  3764 +	ctx_print_pingpong_data(&rem_dest,&user_param);
       
  3765 +
       
  3766 +	// Joining the Send side port the Mcast gid
       
  3767 +	if (user_param.use_mcg && (user_param.machine == CLIENT || user_param.duplex)) {
       
  3768 +		memcpy(mcg_params.mgid.raw, rem_dest.gid.raw, 16);
       
  3769 +		if (set_mcast_group(ctx,&user_param,&mcg_params)) {
       
  3770 +			fprintf(stderr," Unable to Join Sender to Mcast gid\n");
       
  3771 +			return 1;
       
  3772 +		}
       
  3773 +	}
       
  3774 +
       
  3775 +	// Prepare IB resources for rtr/rts.
       
  3776 +	if (pp_connect_ctx(ctx,my_dest.psn,&rem_dest,&user_param)) {
       
  3777 +		fprintf(stderr," Unable to Connect the HCA's through the link\n");
       
  3778 +		return 1;
       
  3779 +	}
       
  3780 +	
       
  3781 +	// shaking hands and gather the other side info.
       
  3782 +    if (ctx_hand_shake(&user_param,&my_dest,&rem_dest)) {
       
  3783 +        fprintf(stderr,"Failed to exchange date between server and clients\n");
       
  3784 +        return 1;
       
  3785 +        
       
  3786 +    }
       
  3787 +
       
  3788 +	if (user_param.use_event) {
       
  3789 +		if (ibv_req_notify_cq(ctx->cq, 0)) {
       
  3790 +			fprintf(stderr, " Couldn't request CQ notification\n");
       
  3791 +			return 1;
       
  3792 +		} 
       
  3793 +	}
       
  3794 +
       
  3795 +	printf(RESULT_LINE);
       
  3796 +	printf(RESULT_FMT);
       
  3797 +
       
  3798 +	size_of_arr = (user_param.duplex) ? 1 : user_param.num_of_qps;
       
  3799 +
       
  3800 +	ALLOCATE(tposted,cycles_t,user_param.iters*size_of_arr);
       
  3801 +	ALLOCATE(tcompleted,cycles_t,user_param.iters*size_of_arr);
       
  3802 +
       
  3803 +	if (user_param.machine == SERVER || user_param.duplex) {
       
  3804 +		ALLOCATE(ctx->rwr,struct ibv_recv_wr,user_param.num_of_qps);
       
  3805 +		ALLOCATE(ctx->sge_list,struct ibv_sge,user_param.num_of_qps);
       
  3806 +		ALLOCATE(ctx->my_addr ,uint64_t ,user_param.num_of_qps);
       
  3807 +	}
       
  3808 +
       
  3809 +	ptr_to_run_iter_uni = (user_param.machine == CLIENT) ?	&run_iter_uni_client : &run_iter_uni_server;
       
  3810 +	
       
  3811 +	if (user_param.machine == SERVER && !user_param.duplex) {
       
  3812 +		user_param.noPeak = ON;
       
  3813 +	}
       
  3814 +
       
  3815 +	if (user_param.machine == CLIENT || user_param.duplex) {
       
  3816 +		set_send_wqe(ctx,rem_dest.qpn,&user_param);
       
  3817 +	}
       
  3818 +
       
  3819 +	if (user_param.all == ON) {
       
  3820 +
       
  3821 +		if (user_param.connection_type == UD) 
       
  3822 +		   size_max_pow =  (int)UD_MSG_2_EXP(MTU_SIZE(user_param.curr_mtu)) + 1;
       
  3823 +
       
  3824 +		for (i = 1; i < size_max_pow ; ++i) {
       
  3825 +			user_param.size = 1 << i;
       
  3826 +
       
  3827 +			if (user_param.machine == SERVER || user_param.duplex) {
       
  3828 +				if (set_recv_wqes(ctx,&user_param)) {
       
  3829 +					fprintf(stderr," Failed to post receive recv_wqes\n");
       
  3830 +					return 1;
       
  3831 +				}
       
  3832 +			}
       
  3833 +
       
  3834 +			if (ctx_hand_shake(&user_param,&my_dest,&rem_dest)) {
       
  3835 +				fprintf(stderr,"Failed to exchange date between server and clients\n");
       
  3836 +				return 1;
       
  3837 +			}
       
  3838 +
       
  3839 +			if (user_param.duplex) {
       
  3840 +				if(run_iter_bi(ctx,&user_param))
       
  3841 +					return 17;
       
  3842 +			} else {
       
  3843 +				if((*ptr_to_run_iter_uni)(ctx,&user_param))
       
  3844 +					return 17;
       
  3845 +			}
       
  3846 +			print_report(&user_param);
       
  3847 +
       
  3848 +			if (pp_drain_qp(ctx,&user_param,my_dest.psn,&rem_dest,&mcg_params)) {
       
  3849 +				fprintf(stderr,"Failed to drain Recv queue (performance optimization)\n");
       
  3850 +				return 1;
       
  3851 +			}
       
  3852 +
       
  3853 +			if (ctx_hand_shake(&user_param,&my_dest,&rem_dest)) {
       
  3854 +				fprintf(stderr,"Failed to exchange date between server and clients\n");
       
  3855 +				return 1;
       
  3856 +			}
       
  3857 +        
       
  3858 +		}
       
  3859 +
       
  3860 +	} else {
       
  3861 +
       
  3862 +		if (user_param.machine == SERVER || user_param.duplex) {
       
  3863 +			if (set_recv_wqes(ctx,&user_param)) {
       
  3864 +				fprintf(stderr," Failed to post receive recv_wqes\n");
       
  3865 +				return 1;
       
  3866 +			}
       
  3867 +		}
       
  3868 +
       
  3869 +		if (ctx_hand_shake(&user_param,&my_dest,&rem_dest)) {
       
  3870 +			fprintf(stderr,"Failed to exchange date between server and clients\n");
       
  3871 +			return 1;
       
  3872 +		}
       
  3873 +
       
  3874 +		if (user_param.duplex) {
       
  3875 +			if(run_iter_bi(ctx,&user_param))
       
  3876 +				return 18;
       
  3877 +
       
  3878 +		} else {
       
  3879 +			if((*ptr_to_run_iter_uni)(ctx,&user_param))
       
  3880 +				return 18;
       
  3881 +		}
       
  3882 +
       
  3883 +		print_report(&user_param);	
       
  3884 +	}
       
  3885 +		
       
  3886 +	if (ctx_close_connection(&user_param,&my_dest,&rem_dest)) {
       
  3887 +		fprintf(stderr," Failed to close connection between server and client\n");
       
  3888 +		return 1;
       
  3889 +	}
       
  3890 +
       
  3891 +	printf(RESULT_LINE);
       
  3892 +	return destroy_ctx_resources(ctx,&user_param,&my_dest,&rem_dest,&mcg_params);
       
  3893 +}
       
  3894 diff -r -u /tmp/perftest-1.3.0/send_lat.c perftest-1.3.0/send_lat.c
  1586 diff -r -u /tmp/perftest-1.3.0/send_lat.c perftest-1.3.0/send_lat.c
  3895 --- /tmp/perftest-1.3.0/send_lat.c	Wed Mar  2 16:04:50 2011
  1587 --- /tmp/perftest-1.3.0/send_lat.c	Wed Mar  2 16:04:50 2011
  3896 +++ perftest-1.3.0/send_lat.c	Fri Aug 26 05:29:53 2011
  1588 +++ perftest-1.3.0/send_lat.c	Fri Aug 26 05:29:53 2011
  3897 @@ -61,7 +61,8 @@
  1589 @@ -61,7 +61,8 @@
  3898  	struct ibv_sge          *sge_list;
  1590  	struct ibv_sge          *sge_list;