- Merge in OFED 1.5.3 from projects/ofed/head

This commit is contained in:
Jeff Roberson 2011-03-21 09:58:24 +00:00
parent e4cd31dd3c
commit aa0a1e58f0
1129 changed files with 425502 additions and 10 deletions

View File

@ -76,6 +76,9 @@ SUBDIR+=secure
SUBDIR+=share
.endif
SUBDIR+=sys usr.bin usr.sbin
.if ${MK_OFED} != "no"
SUBDIR+=contrib/ofed
.endif
#
# We must do etc/ last for install/distribute to work.
#
@ -1210,7 +1213,11 @@ _prebuild_libs= ${_kerberos5_lib_libasn1} ${_kerberos5_lib_libheimntlm} \
_lib_libthr= lib/libthr
.endif
_generic_libs= ${_cddl_lib} gnu/lib ${_kerberos5_lib} lib ${_secure_lib} usr.bin/lex/lib
.if ${MK_OFED} != "no"
_ofed_lib= contrib/ofed/usr.lib/
.endif
_generic_libs= ${_cddl_lib} gnu/lib ${_kerberos5_lib} lib ${_secure_lib} usr.bin/lex/lib ${_ofed_lib}
lib/libopie__L lib/libtacplus__L: lib/libmd__L

5
contrib/ofed/Makefile Normal file
View File

@ -0,0 +1,5 @@
.include <bsd.own.mk>
SUBDIR = include usr.lib usr.bin
.include <bsd.subdir.mk>

View File

@ -0,0 +1,5 @@
.include <bsd.own.mk>
SUBDIR = infiniband rdma
.include <bsd.subdir.mk>

View File

@ -0,0 +1,107 @@
.include <bsd.own.mk>
INCS=
IBINCS= byteorder.h byteswap.h endian.h types.h
IBINCSDIR= ${INCLUDEDIR}/infiniband
IBVERBS= ${.CURDIR}/../../libibverbs/include/infiniband
VERBINCS= ${IBVERBS}/arch.h ${IBVERBS}/driver.h ${IBVERBS}/kern-abi.h
VERBINCS+= ${IBVERBS}/marshall.h ${IBVERBS}/opcode.h
VERBINCS+= ${IBVERBS}/sa-kern-abi.h ${IBVERBS}/sa.h ${IBVERBS}/verbs.h
VERBINCSDIR= ${INCLUDEDIR}/infiniband
IBCOMMON= ${.CURDIR}/../../management/libibcommon/include/infiniband
COMMONINCS= ${IBCOMMON}/common.h
COMMONINCSDIR= ${INCLUDEDIR}/infiniband
IBMAD= ${.CURDIR}/../../management/libibmad/include/infiniband
MADINCS= ${IBMAD}/mad.h
MADINCSDIR= ${INCLUDEDIR}/infiniband
IBUMAD= ${.CURDIR}/../../management/libibumad/include/infiniband
UMADINCS= ${IBUMAD}/umad.h
UMADINCSDIR= ${INCLUDEDIR}/infiniband
COMPLIB= ${.CURDIR}/../../management/opensm/include/complib
COMPLIBINCS= ${COMPLIB}/cl_atomic.h ${COMPLIB}/cl_atomic_osd.h
COMPLIBINCS+= ${COMPLIB}/cl_byteswap.h ${COMPLIB}/cl_byteswap_osd.h
COMPLIBINCS+= ${COMPLIB}/cl_comppool.h ${COMPLIB}/cl_debug.h
COMPLIBINCS+= ${COMPLIB}/cl_debug_osd.h ${COMPLIB}/cl_dispatcher.h
COMPLIBINCS+= ${COMPLIB}/cl_event.h ${COMPLIB}/cl_event_osd.h
COMPLIBINCS+= ${COMPLIB}/cl_event_wheel.h ${COMPLIB}/cl_fleximap.h
COMPLIBINCS+= ${COMPLIB}/cl_list.h ${COMPLIB}/cl_log.h
COMPLIBINCS+= ${COMPLIB}/cl_map.h ${COMPLIB}/cl_math.h
COMPLIBINCS+= ${COMPLIB}/cl_nodenamemap.h ${COMPLIB}/cl_packoff.h
COMPLIBINCS+= ${COMPLIB}/cl_packon.h ${COMPLIB}/cl_passivelock.h
COMPLIBINCS+= ${COMPLIB}/cl_pool.h ${COMPLIB}/cl_ptr_vector.h
COMPLIBINCS+= ${COMPLIB}/cl_qcomppool.h ${COMPLIB}/cl_qlist.h
COMPLIBINCS+= ${COMPLIB}/cl_qmap.h ${COMPLIB}/cl_qpool.h
COMPLIBINCS+= ${COMPLIB}/cl_spinlock.h ${COMPLIB}/cl_spinlock_osd.h
COMPLIBINCS+= ${COMPLIB}/cl_thread.h ${COMPLIB}/cl_thread_osd.h
COMPLIBINCS+= ${COMPLIB}/cl_threadpool.h ${COMPLIB}/cl_timer.h
COMPLIBINCS+= ${COMPLIB}/cl_timer_osd.h ${COMPLIB}/cl_types.h
COMPLIBINCS+= ${COMPLIB}/cl_types_osd.h ${COMPLIB}/cl_vector.h
COMPLIBINCSDIR= ${INCLUDEDIR}/infiniband/complib
IBADIR= ${.CURDIR}/../../management/opensm/include/iba
IBAINCS= ${IBADIR}/ib_cm_types.h ${IBADIR}/ib_types.h
IBAINCSDIR= ${INCLUDEDIR}/infiniband/iba
OPENSM= ${.CURDIR}/../../management/opensm/include/opensm
OPENSMINCS= ${OPENSM}/osm_attrib_req.h ${OPENSM}/osm_base.h
OPENSMINCS+= ${OPENSM}/osm_config.h ${OPENSM}/osm_console.h
OPENSMINCS+= ${OPENSM}/osm_console_io.h ${OPENSM}/osm_db.h
OPENSMINCS+= ${OPENSM}/osm_db_pack.h ${OPENSM}/osm_errors.h
OPENSMINCS+= ${OPENSM}/osm_event_plugin.h ${OPENSM}/osm_helper.h
OPENSMINCS+= ${OPENSM}/osm_inform.h ${OPENSM}/osm_lid_mgr.h
OPENSMINCS+= ${OPENSM}/osm_log.h ${OPENSM}/osm_mad_pool.h
OPENSMINCS+= ${OPENSM}/osm_madw.h ${OPENSM}/osm_mcast_tbl.h
OPENSMINCS+= ${OPENSM}/osm_mcm_info.h ${OPENSM}/osm_mcm_port.h
OPENSMINCS+= ${OPENSM}/osm_msgdef.h ${OPENSM}/osm_mtree.h
OPENSMINCS+= ${OPENSM}/osm_multicast.h ${OPENSM}/osm_node.h
OPENSMINCS+= ${OPENSM}/osm_opensm.h ${OPENSM}/osm_partition.h
OPENSMINCS+= ${OPENSM}/osm_path.h ${OPENSM}/osm_perfmgr.h
OPENSMINCS+= ${OPENSM}/osm_perfmgr_db.h ${OPENSM}/osm_pkey.h
OPENSMINCS+= ${OPENSM}/osm_pkey_mgr.h ${OPENSM}/osm_port.h
OPENSMINCS+= ${OPENSM}/osm_port_profile.h ${OPENSM}/osm_prefix_route.h
OPENSMINCS+= ${OPENSM}/osm_qos_policy.h ${OPENSM}/osm_remote_sm.h
OPENSMINCS+= ${OPENSM}/osm_router.h ${OPENSM}/osm_sa.h
OPENSMINCS+= ${OPENSM}/osm_sa_mad_ctrl.h ${OPENSM}/osm_service.h
OPENSMINCS+= ${OPENSM}/osm_sm.h ${OPENSM}/osm_sm_mad_ctrl.h
OPENSMINCS+= ${OPENSM}/osm_stats.h ${OPENSM}/osm_subnet.h
OPENSMINCS+= ${OPENSM}/osm_switch.h ${OPENSM}/osm_ucast_cache.h
OPENSMINCS+= ${OPENSM}/osm_ucast_mgr.h ${OPENSM}/osm_version.h
OPENSMINCS+= ${OPENSM}/osm_vl15intf.h ${OPENSM}/st.h
OPENSMINCSDIR= ${INCLUDEDIR}/infiniband/opensm
VENDOR= ${.CURDIR}/../../management/opensm/include/vendor
VENDORINCS= ${VENDOR}/osm_mtl_bind.h ${VENDOR}/osm_pkt_randomizer.h
VENDORINCS+= ${VENDOR}/osm_ts_useraccess.h ${VENDOR}/osm_umadt.h
VENDORINCS+= ${VENDOR}/osm_vendor.h ${VENDOR}/osm_vendor_al.h
VENDORINCS+= ${VENDOR}/osm_vendor_api.h ${VENDOR}/osm_vendor_ibumad.h
VENDORINCS+= ${VENDOR}/osm_vendor_mlx.h ${VENDOR}/osm_vendor_mlx_defs.h
VENDORINCS+= ${VENDOR}/osm_vendor_mlx_dispatcher.h
VENDORINCS+= ${VENDOR}/osm_vendor_mlx_hca.h
VENDORINCS+= ${VENDOR}/osm_vendor_mlx_inout.h
VENDORINCS+= ${VENDOR}/osm_vendor_mlx_rmpp_ctx.h
VENDORINCS+= ${VENDOR}/osm_vendor_mlx_sar.h ${VENDOR}/osm_vendor_mlx_sender.h
VENDORINCS+= ${VENDOR}/osm_vendor_mlx_svc.h
VENDORINCS+= ${VENDOR}/osm_vendor_mlx_transport.h
VENDORINCS+= ${VENDOR}/osm_vendor_mlx_transport_anafa.h
VENDORINCS+= ${VENDOR}/osm_vendor_mlx_txn.h
VENDORINCS+= ${VENDOR}/osm_vendor_mtl.h ${VENDOR}/osm_vendor_mtl_hca_guid.h
VENDORINCS+= ${VENDOR}/osm_vendor_mtl_transaction_mgr.h
VENDORINCS+= ${VENDOR}/osm_vendor_sa_api.h
VENDORINCS+= ${VENDOR}/osm_vendor_test.h ${VENDOR}/osm_vendor_ts.h
VENDORINCS+= ${VENDOR}/osm_vendor_umadt.h
VENDORINCSDIR= ${INCLUDEDIR}/infiniband/vendor
IBCM= ${.CURDIR}/../../libibcm/include/infiniband
IBCMINCS= ${IBCM}/cm.h ${IBCM}/cm_abi.h
IBCMINCSDIR= ${INCLUDEDIR}/infiniband
INCSGROUPS= INCS VERBINCS COMMONINCS MADINCS UMADINCS COMPLIBINCS IBAINCS
INCSGROUPS+= OPENSMINCS VENDORINCS IBCMINCS IBINCS
.include <bsd.prog.mk>

View File

@ -0,0 +1,84 @@
/*-
* Copyright (c) 2010 Isilon Systems, Inc.
* Copyright (c) 2010 iX Systems, Inc.
* Copyright (c) 2010 Panasas, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _INFINIBAND_BYTEORDER_H_
#define _INFINIBAND_BYTEORDER_H_
#include <sys/types.h>
#include <sys/endian.h>
#if BYTE_ORDER == LITTLE_ENDIAN
#define __LITTLE_ENDIAN
#else
#define __BIG_ENDIAN
#endif
#define cpu_to_le64 htole64
#define le64_to_cpu le64toh
#define cpu_to_le32 htole32
#define le32_to_cpu le32toh
#define cpu_to_le16 htole16
#define le16_to_cpu le16toh
#define cpu_to_be64 htobe64
#define be64_to_cpu be64toh
#define cpu_to_be32 htobe32
#define be32_to_cpu be32toh
#define cpu_to_be16 htobe16
#define be16_to_cpu be16toh
#define __be16_to_cpu be16toh
#define cpu_to_le64p(x) htole64(*((uint64_t *)x))
#define le64_to_cpup(x) le64toh(*((uint64_t *)x))
#define cpu_to_le32p(x) htole32(*((uint32_t *)x))
#define le32_to_cpup(x) le32toh(*((uint32_t *)x))
#define cpu_to_le16p(x) htole16(*((uint16_t *)x))
#define le16_to_cpup(x) le16toh(*((uint16_t *)x))
#define cpu_to_be64p(x) htobe64(*((uint64_t *)x))
#define be64_to_cpup(x) be64toh(*((uint64_t *)x))
#define cpu_to_be32p(x) htobe32(*((uint32_t *)x))
#define be32_to_cpup(x) be32toh(*((uint32_t *)x))
#define cpu_to_be16p(x) htobe16(*((uint16_t *)x))
#define be16_to_cpup(x) be16toh(*((uint16_t *)x))
#define cpu_to_le64s(x) do { *((uint64_t *)x) = cpu_to_le64p((x)) } while (0)
#define le64_to_cpus(x) do { *((uint64_t *)x) = le64_to_cpup((x)) } while (0)
#define cpu_to_le32s(x) do { *((uint32_t *)x) = cpu_to_le32p((x)) } while (0)
#define le32_to_cpus(x) do { *((uint32_t *)x) = le32_to_cpup((x)) } while (0)
#define cpu_to_le16s(x) do { *((uint16_t *)x) = cpu_to_le16p((x)) } while (0)
#define le16_to_cpus(x) do { *((uint16_t *)x) = le16_to_cpup((x)) } while (0)
#define cpu_to_be64s(x) do { *((uint64_t *)x) = cpu_to_be64p((x)) } while (0)
#define be64_to_cpus(x) do { *((uint64_t *)x) = be64_to_cpup((x)) } while (0)
#define cpu_to_be32s(x) do { *((uint32_t *)x) = cpu_to_be32p((x)) } while (0)
#define be32_to_cpus(x) do { *((uint32_t *)x) = be32_to_cpup((x)) } while (0)
#define cpu_to_be16s(x) do { *((uint16_t *)x) = cpu_to_be16p((x)) } while (0)
#define be16_to_cpus(x) do { *((uint16_t *)x) = be16_to_cpup((x)) } while (0)
#define swab16 bswap16
#define swab32 bswap32
#define swab64 bswap64
#endif /* _INFINIBAND_BYTEORDER_H_ */

View File

@ -0,0 +1,42 @@
/*-
* Copyright (c) 2010 Isilon Systems, Inc.
* Copyright (c) 2010 iX Systems, Inc.
* Copyright (c) 2010 Panasas, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _INFINIBAND_BYTESWAP_H_
#define _INFINIBAND_BYTESWAP_H_
/*
* This file is included for compatibility with the userland libraries
* accompanying the infiniband stack.
*/
#include <sys/types.h>
#include <sys/endian.h>
#define bswap_16 bswap16
#define bswap_32 bswap32
#define bswap_64 bswap64
#endif /* _INFINIBAND_BYTESWAP_H_ */

View File

@ -0,0 +1,42 @@
/*-
* Copyright (c) 2010 Isilon Systems, Inc.
* Copyright (c) 2010 iX Systems, Inc.
* Copyright (c) 2010 Panasas, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This file is included for compatibility with the userland libraries
* accompanying the infiniband stack.
*/
#ifndef _INFINIBAND_ENDIAN_H_
#define _INFINIBAND_ENDIAN_H_
#include <sys/types.h>
#include <sys/endian.h>
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#define __BIG_ENDIAN _BIG_ENDIAN
#define __BYTE_ORDER _BYTE_ORDER
#endif /* _INFINIBAND_ENDIAN_H_ */

View File

@ -0,0 +1,63 @@
/*-
* Copyright (c) 2010 Isilon Systems, Inc.
* Copyright (c) 2010 iX Systems, Inc.
* Copyright (c) 2010 Panasas, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _INFINIBAND_TYPES_H_
#define _INFINIBAND_TYPES_H_
#include <sys/cdefs.h>
#include <sys/types.h>
typedef int8_t s8;
typedef uint8_t u8;
typedef int8_t __s8;
typedef uint8_t __u8;
typedef int16_t s16;
typedef uint16_t u16;
typedef int16_t __s16;
typedef uint16_t __u16;
typedef int32_t s32;
typedef uint32_t u32;
typedef int32_t __s32;
typedef uint32_t __u32;
typedef int64_t s64;
typedef uint64_t u64;
typedef int64_t __s64;
typedef uint64_t __u64;
typedef uint16_t __le16;
typedef uint16_t __be16;
typedef uint32_t __le32;
typedef uint32_t __be32;
typedef uint64_t __le64;
typedef uint64_t __be64;
typedef unsigned int uint;
#endif /* _INFINIBAND_TYPES_H_ */

View File

@ -0,0 +1,10 @@
.include <bsd.own.mk>
INCS=
RDMACM= ${.CURDIR}/../../librdmacm/include/rdma
RDMACMINCS= ${RDMACM}/rdma_cma.h ${RDMACM}/rdma_cma_abi.h
RDMACMINCSDIR= ${INCLUDEDIR}/rdma
INCSGROUPS= RDMACMINCS
.include <bsd.prog.mk>

View File

@ -0,0 +1,2 @@
Sean Hefty <sean.hefty@intel.com>
Libor Michalek <libor@topspin.com>

View File

@ -0,0 +1,378 @@
This software is available to you under a choice of one of two
licenses. You may choose to be licensed under the terms of the the
OpenIB.org BSD license or the GNU General Public License (GPL) Version
2, both included below.
Copyright (c) 2004 Topspin Communications. All rights reserved.
==================================================================
OpenIB.org BSD license
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
==================================================================
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

View File

View File

@ -0,0 +1,34 @@
INCLUDES = -I$(srcdir)/include
lib_LTLIBRARIES = src/libibcm.la
AM_CFLAGS = -g -Wall -D_GNU_SOURCE
src_libibcm_la_CFLAGS = $(AM_CFLAGS)
if HAVE_LD_VERSION_SCRIPT
ibcm_version_script = -Wl,--version-script=$(srcdir)/src/libibcm.map
else
ibcm_version_script =
endif
src_libibcm_la_SOURCES = src/cm.c
src_libibcm_la_LDFLAGS = -version-info 1 -export-dynamic \
$(libibcm_version_script)
src_libibcm_la_DEPENDENCIES = $(srcdir)/src/libibcm.map
# Sample program requires use if librdmacm.
#bin_PROGRAMS = examples/ucmpost
#examples_ucmpost_SOURCES = examples/cmpost.c
#examples_ucmpost_LDADD = $(top_builddir)/src/libibcm.la
libibcmincludedir = $(includedir)/infiniband
libibcminclude_HEADERS = include/infiniband/cm_abi.h \
include/infiniband/cm.h
EXTRA_DIST = include/infiniband/cm_abi.h include/infiniband/cm.h \
src/libibcm.map libibcm.spec.in
dist-hook: libibcm.spec
cp libibcm.spec $(distdir)

View File

@ -0,0 +1,660 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = .
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
DIST_COMMON = README $(am__configure_deps) $(libibcminclude_HEADERS) \
$(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/config.h.in $(srcdir)/libibcm.spec.in \
$(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
config/compile config/config.guess config/config.sub \
config/depcomp config/install-sh config/ltmain.sh \
config/missing
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno configure.status.lineno
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES = libibcm.spec
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
am__installdirs = "$(DESTDIR)$(libdir)" \
"$(DESTDIR)$(libibcmincludedir)"
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
src_libibcm_la_LIBADD =
am_src_libibcm_la_OBJECTS = src_libibcm_la-cm.lo
src_libibcm_la_OBJECTS = $(am_src_libibcm_la_OBJECTS)
am__dirstamp = $(am__leading_dot)dirstamp
DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(src_libibcm_la_SOURCES)
DIST_SOURCES = $(src_libibcm_la_SOURCES)
libibcmincludeHEADERS_INSTALL = $(INSTALL_HEADER)
HEADERS = $(libibcminclude_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
am__remove_distdir = \
{ test ! -d $(distdir) \
|| { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -fr $(distdir); }; }
DIST_ARCHIVES = $(distdir).tar.gz
GZIP_ENV = --best
distuninstallcheck_listfiles = find . -type f -print
distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
HAVE_LD_VERSION_SCRIPT_FALSE = @HAVE_LD_VERSION_SCRIPT_FALSE@
HAVE_LD_VERSION_SCRIPT_TRUE = @HAVE_LD_VERSION_SCRIPT_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
INCLUDES = -I$(srcdir)/include
lib_LTLIBRARIES = src/libibcm.la
AM_CFLAGS = -g -Wall -D_GNU_SOURCE
src_libibcm_la_CFLAGS = $(AM_CFLAGS)
@HAVE_LD_VERSION_SCRIPT_FALSE@ibcm_version_script =
@HAVE_LD_VERSION_SCRIPT_TRUE@ibcm_version_script = -Wl,--version-script=$(srcdir)/src/libibcm.map
src_libibcm_la_SOURCES = src/cm.c
src_libibcm_la_LDFLAGS = -version-info 1 -export-dynamic \
$(libibcm_version_script)
src_libibcm_la_DEPENDENCIES = $(srcdir)/src/libibcm.map
# Sample program requires use if librdmacm.
#bin_PROGRAMS = examples/ucmpost
#examples_ucmpost_SOURCES = examples/cmpost.c
#examples_ucmpost_LDADD = $(top_builddir)/src/libibcm.la
libibcmincludedir = $(includedir)/infiniband
libibcminclude_HEADERS = include/infiniband/cm_abi.h \
include/infiniband/cm.h
EXTRA_DIST = include/infiniband/cm_abi.h include/infiniband/cm.h \
src/libibcm.map libibcm.spec.in
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
am--refresh:
@:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \
cd $(srcdir) && $(AUTOMAKE) --foreign \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
echo ' $(SHELL) ./config.status'; \
$(SHELL) ./config.status;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(top_srcdir)/configure: $(am__configure_deps)
cd $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
config.h: stamp-h1
@if test ! -f $@; then \
rm -f stamp-h1; \
$(MAKE) stamp-h1; \
else :; fi
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status config.h
$(srcdir)/config.h.in: $(am__configure_deps)
cd $(top_srcdir) && $(AUTOHEADER)
rm -f stamp-h1
touch $@
distclean-hdr:
-rm -f config.h stamp-h1
libibcm.spec: $(top_builddir)/config.status $(srcdir)/libibcm.spec.in
cd $(top_builddir) && $(SHELL) ./config.status $@
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
f=$(am__strip_dir) \
echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
else :; fi; \
done
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \
p=$(am__strip_dir) \
echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
$(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
src/$(am__dirstamp):
@$(mkdir_p) src
@: > src/$(am__dirstamp)
src/libibcm.la: $(src_libibcm_la_OBJECTS) $(src_libibcm_la_DEPENDENCIES) src/$(am__dirstamp)
$(LINK) -rpath $(libdir) $(src_libibcm_la_LDFLAGS) $(src_libibcm_la_OBJECTS) $(src_libibcm_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/src_libibcm_la-cm.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
src_libibcm_la-cm.lo: src/cm.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_libibcm_la_CFLAGS) $(CFLAGS) -MT src_libibcm_la-cm.lo -MD -MP -MF "$(DEPDIR)/src_libibcm_la-cm.Tpo" -c -o src_libibcm_la-cm.lo `test -f 'src/cm.c' || echo '$(srcdir)/'`src/cm.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/src_libibcm_la-cm.Tpo" "$(DEPDIR)/src_libibcm_la-cm.Plo"; else rm -f "$(DEPDIR)/src_libibcm_la-cm.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/cm.c' object='src_libibcm_la-cm.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_libibcm_la_CFLAGS) $(CFLAGS) -c -o src_libibcm_la-cm.lo `test -f 'src/cm.c' || echo '$(srcdir)/'`src/cm.c
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
-rm -rf src/.libs src/_libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
install-libibcmincludeHEADERS: $(libibcminclude_HEADERS)
@$(NORMAL_INSTALL)
test -z "$(libibcmincludedir)" || $(mkdir_p) "$(DESTDIR)$(libibcmincludedir)"
@list='$(libibcminclude_HEADERS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f=$(am__strip_dir) \
echo " $(libibcmincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(libibcmincludedir)/$$f'"; \
$(libibcmincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(libibcmincludedir)/$$f"; \
done
uninstall-libibcmincludeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(libibcminclude_HEADERS)'; for p in $$list; do \
f=$(am__strip_dir) \
echo " rm -f '$(DESTDIR)$(libibcmincludedir)/$$f'"; \
rm -f "$(DESTDIR)$(libibcmincludedir)/$$f"; \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
$(am__remove_distdir)
mkdir $(distdir)
$(mkdir_p) $(distdir)/. $(distdir)/config $(distdir)/include/infiniband $(distdir)/src
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$(top_distdir)" distdir="$(distdir)" \
dist-hook
-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r $(distdir)
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
dist-bzip2: distdir
tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
$(am__remove_distdir)
dist-tarZ: distdir
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__remove_distdir)
dist-shar: distdir
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
$(am__remove_distdir)
dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
$(am__remove_distdir)
dist dist-all: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac
chmod -R a-w $(distdir); chmod a+w $(distdir)
mkdir $(distdir)/_build
mkdir $(distdir)/_inst
chmod a-w $(distdir)
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& cd $(distdir)/_build \
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
$(DISTCHECK_CONFIGURE_FLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$$dc_install_base" \
&& ({ \
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
} || { rm -rf "$$dc_destdir"; exit 1; }) \
&& rm -rf "$$dc_destdir" \
&& $(MAKE) $(AM_MAKEFLAGS) dist \
&& rm -rf $(DIST_ARCHIVES) \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck
$(am__remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}'
distuninstallcheck:
@cd $(distuninstallcheck_dir) \
&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
fi ; \
$(distuninstallcheck_listfiles) ; \
exit 1; } >&2
distcleancheck: distclean
@if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left in build directory after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS) config.h
installdirs:
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libibcmincludedir)"; do \
test -z "$$dir" || $(mkdir_p) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-rm -f src/$(am__dirstamp)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-hdr distclean-libtool distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am: install-libibcmincludeHEADERS
install-exec-am: install-libLTLIBRARIES
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES \
uninstall-libibcmincludeHEADERS
.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \
clean-generic clean-libLTLIBRARIES clean-libtool ctags dist \
dist-all dist-bzip2 dist-gzip dist-hook dist-shar dist-tarZ \
dist-zip distcheck distclean distclean-compile \
distclean-generic distclean-hdr distclean-libtool \
distclean-tags distcleancheck distdir distuninstallcheck dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-exec install-exec-am \
install-info install-info-am install-libLTLIBRARIES \
install-libibcmincludeHEADERS install-man install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-info-am \
uninstall-libLTLIBRARIES uninstall-libibcmincludeHEADERS
dist-hook: libibcm.spec
cp libibcm.spec $(distdir)
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

View File

@ -0,0 +1,28 @@
This README is for userspace cm library.
Building
To make this directory, run:
./autogen.sh && ./configure && make && make install
Typically the autogen and configure steps only need be done the first
time unless configure.in or Makefile.am changes.
Libraries are installed by default at /usr/local/lib.
Device files
The userspace CM uses a device file per adapter present.
To create the appropriate character device file automatically with
udev, a rule like
KERNEL="ucm*", NAME="infiniband/%k", MODE="0666"
can be used. This will create the device node named
/dev/infiniband/ucm0
for the first HCA in the system, or you can create it manually
mknod /dev/infiniband/ucm0 c 231 224

7267
contrib/ofed/libibcm/aclocal.m4 vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,67 @@
/* config.h.in. Generated from configure.in by autoheader. */
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `ibverbs' library (-libverbs). */
#undef HAVE_LIBIBVERBS
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 to enable valgrind annotations */
#undef INCLUDE_VALGRIND
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* The size of a `long', as computed by sizeof. */
#undef SIZEOF_LONG
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Version number of package */
#undef VERSION
/* Define to empty if `const' does not conform to ANSI C. */
#undef const

View File

@ -0,0 +1,142 @@
#! /bin/sh
# Wrapper for compilers which do not understand `-c -o'.
scriptversion=2005-05-14.22
# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand `-c -o'.
Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
If you are trying to build a whole package this is not the
right script to run: please start by reading the file `INSTALL'.
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "compile $scriptversion"
exit $?
;;
esac
ofile=
cfile=
eat=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as `compile cc -o foo foo.c'.
# So we strip `-o arg' only if arg is an object.
eat=1
case $2 in
*.o | *.obj)
ofile=$2
;;
*)
set x "$@" -o "$2"
shift
;;
esac
;;
*.c)
cfile=$1
set x "$@" "$1"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no `-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# `.c' file was seen then we are probably linking. That is also
# ok.
exec "$@"
fi
# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
# Create the lock directory.
# Note: use `[/.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d
while true; do
if mkdir "$lockdir" >/dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir '$lockdir'; exit 1" 1 2 15
# Run the compile.
"$@"
ret=$?
if test -f "$cofile"; then
mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
mv "${cofile}bj" "$ofile"
fi
rmdir "$lockdir"
exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

1466
contrib/ofed/libibcm/config/config.guess vendored Executable file

File diff suppressed because it is too large Load Diff

1579
contrib/ofed/libibcm/config/config.sub vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,530 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2005-07-09.11
# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by `PROGRAMS ARGS'.
object Object file output by `PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputing dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
"$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say).
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the `deleted header file' problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' '
' < "$tmpdepfile" |
## Some versions of gcc put a space before the `:'. On the theory
## that the space means something, we add a space to the output as
## well.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like `#:fec' to the end of the
# dependency line.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr '
' ' ' >> $depfile
echo >> $depfile
# The second pass generates a dummy entry for each header file.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> $depfile
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts `$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
tmpdepfile="$stripped.u"
if test "$libtool" = yes; then
"$@" -Wc,-M
else
"$@" -M
fi
stat=$?
if test -f "$tmpdepfile"; then :
else
stripped=`echo "$stripped" | sed 's,^.*/,,'`
tmpdepfile="$stripped.u"
fi
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
if test -f "$tmpdepfile"; then
outname="$stripped.o"
# Each line is of the form `foo.o: dependent.h'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
icc)
# Intel's C compiler understands `-MD -MF file'. However on
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# ICC 7.0 will fill foo.d with something like
# foo.o: sub/foo.c
# foo.o: sub/foo.h
# which is wrong. We want:
# sub/foo.o: sub/foo.c
# sub/foo.o: sub/foo.h
# sub/foo.c:
# sub/foo.h:
# ICC 7.1 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using \ :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in `foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
# With Tru64 cc, shared objects can also be used to make a
# static library. This mecanism is used in libtool 1.4 series to
# handle both shared and static libraries in a single compilation.
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
#
# With libtool 1.5 this exception was removed, and libtool now
# generates 2 separate objects for the 2 libraries. These two
# compilations output dependencies in in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
tmpdepfile2=$dir$base.o.d # libtool 1.5
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.o.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
tmpdepfile4=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for `:'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
"$@" $dashmflag |
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' '
' < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no
for arg in "$@"; do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix="`echo $object | sed 's/^.*\././'`"
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E |
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o,
# because we must use -o when running libtool.
"$@" || exit $?
IFS=" "
for arg
do
case "$arg" in
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
echo " " >> "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

View File

@ -0,0 +1,323 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2005-05-14.22
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
chmodcmd="$chmodprog 0755"
chowncmd=
chgrpcmd=
stripcmd=
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=
dst=
dir_arg=
dstarg=
no_target_directory=
usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
-c (ignored)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
--help display this help and exit.
--version display version info and exit.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
"
while test -n "$1"; do
case $1 in
-c) shift
continue;;
-d) dir_arg=true
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
--help) echo "$usage"; exit $?;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-s) stripcmd=$stripprog
shift
continue;;
-t) dstarg=$2
shift
shift
continue;;
-T) no_target_directory=true
shift
continue;;
--version) echo "$0 $scriptversion"; exit $?;;
*) # When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
test -n "$dir_arg$dstarg" && break
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dstarg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dstarg"
shift # fnord
fi
shift # arg
dstarg=$arg
done
break;;
esac
done
if test -z "$1"; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call `install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
for src
do
# Protect names starting with `-'.
case $src in
-*) src=./$src ;;
esac
if test -n "$dir_arg"; then
dst=$src
src=
if test -d "$dst"; then
mkdircmd=:
chmodcmd=
else
mkdircmd=$mkdirprog
fi
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dstarg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dstarg
# Protect names starting with `-'.
case $dst in
-*) dst=./$dst ;;
esac
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dstarg: Is a directory" >&2
exit 1
fi
dst=$dst/`basename "$src"`
fi
fi
# This sed command emulates the dirname command.
dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# Skip lots of stat calls in the usual case.
if test ! -d "$dstdir"; then
defaultIFS='
'
IFS="${IFS-$defaultIFS}"
oIFS=$IFS
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
shift
IFS=$oIFS
pathcomp=
while test $# -ne 0 ; do
pathcomp=$pathcomp$1
shift
if test ! -d "$pathcomp"; then
$mkdirprog "$pathcomp"
# mkdir can fail with a `File exist' error in case several
# install-sh are creating the directory concurrently. This
# is OK.
test -d "$pathcomp" || exit
fi
pathcomp=$pathcomp/
done
fi
if test -n "$dir_arg"; then
$doit $mkdircmd "$dst" \
&& { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
else
dstfile=`basename "$dst"`
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
trap '(exit $?); exit' 1 2 13 15
# Copy the file name to the temp name.
$doit $cpprog "$src" "$dsttmp" &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
# Now rename the file to the real destination.
{ $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
|| {
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
if test -f "$dstdir/$dstfile"; then
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
|| $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
|| {
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
(exit 1); exit 1
}
else
:
fi
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
}
}
fi || { (exit 1); exit 1; }
done
# The final little trick to "correctly" pass the exit status to the exit trap.
{
(exit 0); exit 0
}
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,360 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2005-06-08.21
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
# Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
msg="missing on your system"
case "$1" in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
# Exit code 63 means version mismatch. This often happens
# when the user try to use an ancient version of a tool on
# a file that requires a minimum version. In this case we
# we should proceed has if the program had been absent, or
# if --run hadn't been passed.
if test $? = 63; then
run=:
msg="probably too old"
fi
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
esac
# Now exit if we have it, but it failed. Also exit now if we
# don't have it and --version was passed (most likely to detect
# the program).
case "$1" in
lex|yacc)
# Not GNU programs, they don't have --version.
;;
tar)
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
exit 1
fi
;;
*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
# Could not run --version or --help. This is probably someone
# running `$TOOL --version' or `$TOOL --help' to check whether
# $TOOL exists and not knowing $TOOL uses missing.
exit 1
fi
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case "$1" in
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case "$f" in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
autom4te)
echo 1>&2 "\
WARNING: \`$1' is needed, but is $msg.
You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;
bison|yacc)
echo 1>&2 "\
WARNING: \`$1' $msg. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if [ ! -f y.tab.h ]; then
echo >y.tab.h
fi
if [ ! -f y.tab.c ]; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex|flex)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if [ ! -f lex.yy.c ]; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
help2man)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
fi
if [ -f "$file" ]; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit 1
fi
;;
makeinfo)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
# The file to touch is that specified with -o ...
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
# ... or it is the one specified with @setfilename ...
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
# ... or it is derived from the source name (dir/f.texi becomes f.info)
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
fi
# If the file does not exist, the user really needs makeinfo;
# let's fail without touching anything.
test -f $file || exit 1
touch $file
;;
tar)
shift
# We have already tried tar in the generic part.
# Look for gnutar/gtar before invocation to avoid ugly error
# messages.
if (gnutar --version > /dev/null 2>&1); then
gnutar "$@" && exit 0
fi
if (gtar --version > /dev/null 2>&1); then
gtar "$@" && exit 0
fi
firstarg="$1"
if shift; then
case "$firstarg" in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" "$@" && exit 0
;;
esac
case "$firstarg" in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" "$@" && exit 0
;;
esac
fi
echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and is $msg.
You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

22105
contrib/ofed/libibcm/configure vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,71 @@
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.57)
AC_INIT(libibcm, 1.0.5, general@lists@openfabrics.org)
AC_CONFIG_SRCDIR([src/cm.c])
AC_CONFIG_AUX_DIR(config)
AM_CONFIG_HEADER(config.h)
AM_INIT_AUTOMAKE(libibcm, 1.0.5)
AM_PROG_LIBTOOL
AC_ARG_WITH([valgrind],
AC_HELP_STRING([--with-valgrind],
[Enable valgrind annotations - default NO]))
if test "$with_valgrind" != "" && test "$with_valgrind" != "no"; then
AC_DEFINE([INCLUDE_VALGRIND], 1,
[Define to 1 to enable valgrind annotations])
if test -d $with_valgrind; then
CPPFLAGS="$CPPLFAGS -I$with_valgrind/include"
fi
fi
AC_ARG_ENABLE(libcheck, [ --disable-libcheck do not test for presence of ib libraries],
[ if test "$enableval" = "no"; then
disable_libcheck=yes
fi
])
dnl Checks for programs
AC_PROG_CC
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_CHECK_SIZEOF(long)
dnl Checks for libraries
if test "$disable_libcheck" != "yes"; then
AC_CHECK_LIB(ibverbs, ibv_get_device_list, [],
AC_MSG_ERROR([ibv_get_device_list() not found. libibcm requires libibverbs.]))
#Need librdmacm for cmpost test program.
#AC_CHECK_LIB(rdmacm, rdma_create_id, [],
# AC_MSG_ERROR([rdma_create_id() not found. ucmpost requires librdmacm.]))
fi
dnl Checks for header files.
AC_HEADER_STDC
if test "$disable_libcheck" != "yes"; then
AC_CHECK_HEADER(infiniband/verbs.h, [],
AC_MSG_ERROR([<infiniband/verbs.h> not found. Is libibverbs installed?]))
AC_CHECK_HEADER(infiniband/marshall.h, [],
AC_MSG_ERROR([<infiniband/marshall.h> not found. Is libibverbs installed?]))
if test "$with_valgrind" != "" && test "$with_valgrind" != "no"; then
AC_CHECK_HEADER(valgrind/memcheck.h, [],
AC_MSG_ERROR([valgrind requested but <valgrind/memcheck.h> not found.]))
fi
fi
AC_CACHE_CHECK(whether ld accepts --version-script, ac_cv_version_script,
if test -n "`$LD --help < /dev/null 2>/dev/null | grep version-script`"; then
ac_cv_version_script=yes
else
ac_cv_version_script=no
fi)
AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$ac_cv_version_script" = "yes")
AC_CONFIG_FILES([Makefile libibcm.spec])
AC_OUTPUT

View File

@ -0,0 +1,586 @@
/*
* Copyright (c) 2004-2006 Intel Corporation. All rights reserved.
* Copyright (c) 2004 Topspin Corporation. All rights reserved.
* Copyright (c) 2004 Voltaire Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* $Id$
*/
#if !defined(CM_H)
#define CM_H
#include <infiniband/verbs.h>
#include <infiniband/sa.h>
#include <infiniband/byteorder.h>
#ifdef __cplusplus
extern "C" {
#endif
enum ib_cm_event_type {
IB_CM_REQ_ERROR,
IB_CM_REQ_RECEIVED,
IB_CM_REP_ERROR,
IB_CM_REP_RECEIVED,
IB_CM_RTU_RECEIVED,
IB_CM_USER_ESTABLISHED,
IB_CM_DREQ_ERROR,
IB_CM_DREQ_RECEIVED,
IB_CM_DREP_RECEIVED,
IB_CM_TIMEWAIT_EXIT,
IB_CM_MRA_RECEIVED,
IB_CM_REJ_RECEIVED,
IB_CM_LAP_ERROR,
IB_CM_LAP_RECEIVED,
IB_CM_APR_RECEIVED,
IB_CM_SIDR_REQ_ERROR,
IB_CM_SIDR_REQ_RECEIVED,
IB_CM_SIDR_REP_RECEIVED
};
enum ib_cm_data_size {
IB_CM_REQ_PRIVATE_DATA_SIZE = 92,
IB_CM_MRA_PRIVATE_DATA_SIZE = 222,
IB_CM_REJ_PRIVATE_DATA_SIZE = 148,
IB_CM_REP_PRIVATE_DATA_SIZE = 196,
IB_CM_RTU_PRIVATE_DATA_SIZE = 224,
IB_CM_DREQ_PRIVATE_DATA_SIZE = 220,
IB_CM_DREP_PRIVATE_DATA_SIZE = 224,
IB_CM_REJ_ARI_LENGTH = 72,
IB_CM_LAP_PRIVATE_DATA_SIZE = 168,
IB_CM_APR_PRIVATE_DATA_SIZE = 148,
IB_CM_APR_INFO_LENGTH = 72,
IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE = 216,
IB_CM_SIDR_REP_PRIVATE_DATA_SIZE = 136,
IB_CM_SIDR_REP_INFO_LENGTH = 72
};
struct ib_cm_device {
struct ibv_context *device_context;
int fd;
};
struct ib_cm_id {
void *context;
struct ib_cm_device *device;
uint32_t handle;
};
struct ib_cm_req_event_param {
struct ib_cm_id *listen_id;
uint8_t port;
struct ibv_sa_path_rec *primary_path;
struct ibv_sa_path_rec *alternate_path;
uint64_t remote_ca_guid; /* netork-byte order */
uint32_t remote_qkey;
uint32_t remote_qpn;
enum ibv_qp_type qp_type;
uint32_t starting_psn;
uint8_t responder_resources;
uint8_t initiator_depth;
unsigned int local_cm_response_timeout:5;
unsigned int flow_control:1;
unsigned int remote_cm_response_timeout:5;
unsigned int retry_count:3;
unsigned int rnr_retry_count:3;
unsigned int srq:1;
};
struct ib_cm_rep_event_param {
uint64_t remote_ca_guid; /* network-byte order */
uint32_t remote_qkey;
uint32_t remote_qpn;
uint32_t starting_psn;
uint8_t responder_resources;
uint8_t initiator_depth;
unsigned int target_ack_delay:5;
unsigned int failover_accepted:2;
unsigned int flow_control:1;
unsigned int rnr_retry_count:3;
unsigned int srq:1;
};
enum ib_cm_rej_reason {
IB_CM_REJ_NO_QP = 1,
IB_CM_REJ_NO_EEC = 2,
IB_CM_REJ_NO_RESOURCES = 3,
IB_CM_REJ_TIMEOUT = 4,
IB_CM_REJ_UNSUPPORTED = 5,
IB_CM_REJ_INVALID_COMM_ID = 6,
IB_CM_REJ_INVALID_COMM_INSTANCE = 7,
IB_CM_REJ_INVALID_SERVICE_ID = 8,
IB_CM_REJ_INVALID_TRANSPORT_TYPE = 9,
IB_CM_REJ_STALE_CONN = 10,
IB_CM_REJ_RDC_NOT_EXIST = 11,
IB_CM_REJ_INVALID_GID = 12,
IB_CM_REJ_INVALID_LID = 13,
IB_CM_REJ_INVALID_SL = 14,
IB_CM_REJ_INVALID_TRAFFIC_CLASS = 15,
IB_CM_REJ_INVALID_HOP_LIMIT = 16,
IB_CM_REJ_INVALID_PACKET_RATE = 17,
IB_CM_REJ_INVALID_ALT_GID = 18,
IB_CM_REJ_INVALID_ALT_LID = 19,
IB_CM_REJ_INVALID_ALT_SL = 20,
IB_CM_REJ_INVALID_ALT_TRAFFIC_CLASS = 21,
IB_CM_REJ_INVALID_ALT_HOP_LIMIT = 22,
IB_CM_REJ_INVALID_ALT_PACKET_RATE = 23,
IB_CM_REJ_PORT_CM_REDIRECT = 24,
IB_CM_REJ_PORT_REDIRECT = 25,
IB_CM_REJ_INVALID_MTU = 26,
IB_CM_REJ_INSUFFICIENT_RESP_RESOURCES = 27,
IB_CM_REJ_CONSUMER_DEFINED = 28,
IB_CM_REJ_INVALID_RNR_RETRY = 29,
IB_CM_REJ_DUPLICATE_LOCAL_COMM_ID = 30,
IB_CM_REJ_INVALID_CLASS_VERSION = 31,
IB_CM_REJ_INVALID_FLOW_LABEL = 32,
IB_CM_REJ_INVALID_ALT_FLOW_LABEL = 33
};
struct ib_cm_rej_event_param {
enum ib_cm_rej_reason reason;
void *ari;
uint8_t ari_length;
};
struct ib_cm_mra_event_param {
uint8_t service_timeout;
};
struct ib_cm_lap_event_param {
struct ibv_sa_path_rec *alternate_path;
};
enum ib_cm_apr_status {
IB_CM_APR_SUCCESS,
IB_CM_APR_INVALID_COMM_ID,
IB_CM_APR_UNSUPPORTED,
IB_CM_APR_REJECT,
IB_CM_APR_REDIRECT,
IB_CM_APR_IS_CURRENT,
IB_CM_APR_INVALID_QPN_EECN,
IB_CM_APR_INVALID_LID,
IB_CM_APR_INVALID_GID,
IB_CM_APR_INVALID_FLOW_LABEL,
IB_CM_APR_INVALID_TCLASS,
IB_CM_APR_INVALID_HOP_LIMIT,
IB_CM_APR_INVALID_PACKET_RATE,
IB_CM_APR_INVALID_SL
};
struct ib_cm_apr_event_param {
enum ib_cm_apr_status ap_status;
void *apr_info;
uint8_t info_len;
};
struct ib_cm_sidr_req_event_param {
struct ib_cm_id *listen_id;
uint8_t port;
uint16_t pkey;
};
enum ib_cm_sidr_status {
IB_SIDR_SUCCESS,
IB_SIDR_UNSUPPORTED,
IB_SIDR_REJECT,
IB_SIDR_NO_QP,
IB_SIDR_REDIRECT,
IB_SIDR_UNSUPPORTED_VERSION
};
struct ib_cm_sidr_rep_event_param {
enum ib_cm_sidr_status status;
uint32_t qkey;
uint32_t qpn;
void *info;
uint8_t info_len;
};
struct ib_cm_event {
struct ib_cm_id *cm_id;
enum ib_cm_event_type event;
union {
struct ib_cm_req_event_param req_rcvd;
struct ib_cm_rep_event_param rep_rcvd;
/* No data for RTU received events. */
struct ib_cm_rej_event_param rej_rcvd;
struct ib_cm_mra_event_param mra_rcvd;
struct ib_cm_lap_event_param lap_rcvd;
struct ib_cm_apr_event_param apr_rcvd;
/* No data for DREQ/DREP received events. */
struct ib_cm_sidr_req_event_param sidr_req_rcvd;
struct ib_cm_sidr_rep_event_param sidr_rep_rcvd;
enum ibv_wc_status send_status;
} param;
void *private_data;
};
/**
* ib_cm_get_event - Retrieves the next pending communications event,
* if no event is pending waits for an event.
* @device: CM device to retrieve the event.
* @event: Allocated information about the next communication event.
* Event should be freed using ib_cm_ack_event()
*
* IB_CM_REQ_RECEIVED and IB_CM_SIDR_REQ_RECEIVED communication events
* generated as a result of listen requests result in the allocation of a
* new @cm_id.
* Clients are responsible for destroying the new @cm_id. For peer-to-peer
* IB_CM_REQ_RECEIVED and all other events, the returned @cm_id corresponds
* to a user's existing communication identifier.
*/
int ib_cm_get_event(struct ib_cm_device *device, struct ib_cm_event **event);
/**
* ib_cm_ack_event - Free a communications event.
* @event: Event to be released.
*
* All events which are allocated by ib_cm_get_event() must be released,
* there should be a one-to-one correspondence between successful gets
* and puts.
*/
int ib_cm_ack_event(struct ib_cm_event *event);
/**
* ib_cm_open_device - Returns the device the CM uses to submit requests
* and retrieve events, corresponding to the specified verbs device.
*
* The CM device contains the file descriptor that the CM uses to
* communicate with the kernel CM component. The primary use of the
* file descriptor is to test for CM readiness events. When the CM
* becomes ready to READ there is a pending event ready, and a subsequent
* call to ib_cm_get_event will not block.
* Note: The user should not read or write directly to the CM file
* descriptor, it will likely result in an error or unexpected
* results.
*/
struct ib_cm_device* ib_cm_open_device(struct ibv_context *device_context);
/**
* ib_cm_close_device - Close a CM device.
* @device: Device to close.
*/
void ib_cm_close_device(struct ib_cm_device *device);
/**
* ib_cm_create_id - Allocate a communication identifier.
*
* Communication identifiers are used to track connection states, service
* ID resolution requests, and listen requests.
*/
int ib_cm_create_id(struct ib_cm_device *device,
struct ib_cm_id **cm_id, void *context);
/**
* ib_cm_destroy_id - Destroy a connection identifier.
* @cm_id: Connection identifier to destroy.
*/
int ib_cm_destroy_id(struct ib_cm_id *cm_id);
struct ib_cm_attr_param {
uint64_t service_id; /* network-byte order */
uint64_t service_mask; /* network-byte order */
uint32_t local_id;
uint32_t remote_id;
};
/**
* ib_cm_attr_id - Get connection identifier attributes.
* @cm_id: Connection identifier to retrieve attributes.
* @param: Destination of retreived parameters.
*
* Not all parameters are valid during all connection states.
*/
int ib_cm_attr_id(struct ib_cm_id *cm_id,
struct ib_cm_attr_param *param);
#define IB_CM_ASSIGN_SERVICE_ID_MASK __constant_cpu_to_be64(0xFF00000000000000ULL)
#define IB_CM_ASSIGN_SERVICE_ID __constant_cpu_to_be64(0x0200000000000000ULL)
/**
* ib_cm_listen - Initiates listening on the specified service ID for
* connection and service ID resolution requests.
* @cm_id: Connection identifier associated with the listen request.
* @service_id: Service identifier matched against incoming connection
* and service ID resolution requests. The service ID should be specified
* network-byte order.
* @service_mask: Mask applied to service ID used to listen across a
* range of service IDs. If set to 0, the service ID is matched
* exactly.
*/
int ib_cm_listen(struct ib_cm_id *cm_id,
uint64_t service_id,
uint64_t service_mask);
struct ib_cm_req_param {
struct ibv_sa_path_rec *primary_path;
struct ibv_sa_path_rec *alternate_path;
uint64_t service_id; /* network-byte order */
uint32_t qp_num;
enum ibv_qp_type qp_type;
uint32_t starting_psn;
void *private_data;
uint8_t private_data_len;
uint8_t peer_to_peer;
uint8_t responder_resources;
uint8_t initiator_depth;
uint8_t remote_cm_response_timeout;
uint8_t flow_control;
uint8_t local_cm_response_timeout;
uint8_t retry_count;
uint8_t rnr_retry_count;
uint8_t max_cm_retries;
uint8_t srq;
};
/**
* ib_cm_send_req - Sends a connection request to the remote node.
* @cm_id: Connection identifier that will be associated with the
* connection request.
* @param: Connection request information needed to establish the
* connection.
*/
int ib_cm_send_req(struct ib_cm_id *cm_id,
struct ib_cm_req_param *param);
struct ib_cm_rep_param {
uint32_t qp_num;
uint32_t starting_psn;
void *private_data;
uint8_t private_data_len;
uint8_t responder_resources;
uint8_t initiator_depth;
uint8_t target_ack_delay;
uint8_t failover_accepted;
uint8_t flow_control;
uint8_t rnr_retry_count;
uint8_t srq;
};
/**
* ib_cm_send_rep - Sends a connection reply in response to a connection
* request.
* @cm_id: Connection identifier that will be associated with the
* connection request.
* @param: Connection reply information needed to establish the
* connection.
*/
int ib_cm_send_rep(struct ib_cm_id *cm_id,
struct ib_cm_rep_param *param);
/**
* ib_cm_send_rtu - Sends a connection ready to use message in response
* to a connection reply message.
* @cm_id: Connection identifier associated with the connection request.
* @private_data: Optional user-defined private data sent with the
* ready to use message.
* @private_data_len: Size of the private data buffer, in bytes.
*/
int ib_cm_send_rtu(struct ib_cm_id *cm_id,
void *private_data,
uint8_t private_data_len);
/**
* ib_cm_send_dreq - Sends a disconnection request for an existing
* connection.
* @cm_id: Connection identifier associated with the connection being
* released.
* @private_data: Optional user-defined private data sent with the
* disconnection request message.
* @private_data_len: Size of the private data buffer, in bytes.
*/
int ib_cm_send_dreq(struct ib_cm_id *cm_id,
void *private_data,
uint8_t private_data_len);
/**
* ib_cm_send_drep - Sends a disconnection reply to a disconnection request.
* @cm_id: Connection identifier associated with the connection being
* released.
* @private_data: Optional user-defined private data sent with the
* disconnection reply message.
* @private_data_len: Size of the private data buffer, in bytes.
*/
int ib_cm_send_drep(struct ib_cm_id *cm_id,
void *private_data,
uint8_t private_data_len);
/**
* ib_cm_notify - Notifies the CM of an event reported to the consumer.
* @cm_id: Connection identifier to transition to established.
* @event: Type of event.
*
* This routine should be invoked by users to notify the CM of relevant
* communication events. Events that should be reported to the CM and
* when to report them are:
*
* IBV_EVENT_COMM_EST - Used when a message is received on a connected
* QP before an RTU has been received.
* IBV_EVENT_PATH_MIG - Notifies the CM that the connection has failed over
* to the alternate path.
*/
int ib_cm_notify(struct ib_cm_id *cm_id, enum ibv_event_type event);
/**
* ib_cm_send_rej - Sends a connection rejection message to the
* remote node.
* @cm_id: Connection identifier associated with the connection being
* rejected.
* @reason: Reason for the connection request rejection.
* @ari: Optional additional rejection information.
* @ari_length: Size of the additional rejection information, in bytes.
* @private_data: Optional user-defined private data sent with the
* rejection message.
* @private_data_len: Size of the private data buffer, in bytes.
*/
int ib_cm_send_rej(struct ib_cm_id *cm_id,
enum ib_cm_rej_reason reason,
void *ari,
uint8_t ari_length,
void *private_data,
uint8_t private_data_len);
/**
* ib_cm_send_mra - Sends a message receipt acknowledgement to a connection
* message.
* @cm_id: Connection identifier associated with the connection message.
* @service_timeout: The maximum time required for the sender to reply to
* to the connection message.
* @private_data: Optional user-defined private data sent with the
* message receipt acknowledgement.
* @private_data_len: Size of the private data buffer, in bytes.
*/
int ib_cm_send_mra(struct ib_cm_id *cm_id,
uint8_t service_timeout,
void *private_data,
uint8_t private_data_len);
/**
* ib_cm_send_lap - Sends a load alternate path request.
* @cm_id: Connection identifier associated with the load alternate path
* message.
* @alternate_path: A path record that identifies the alternate path to
* load.
* @private_data: Optional user-defined private data sent with the
* load alternate path message.
* @private_data_len: Size of the private data buffer, in bytes.
*/
int ib_cm_send_lap(struct ib_cm_id *cm_id,
struct ibv_sa_path_rec *alternate_path,
void *private_data,
uint8_t private_data_len);
/**
* ib_cm_init_qp_attr - Initializes the QP attributes for use in transitioning
* to a specified QP state.
* @cm_id: Communication identifier associated with the QP attributes to
* initialize.
* @qp_attr: On input, specifies the desired QP state. On output, the
* mandatory and desired optional attributes will be set in order to
* modify the QP to the specified state.
* @qp_attr_mask: The QP attribute mask that may be used to transition the
* QP to the specified state.
*
* Users must set the @qp_attr->qp_state to the desired QP state. This call
* will set all required attributes for the given transition, along with
* known optional attributes. Users may override the attributes returned from
* this call before calling ib_modify_qp.
*/
int ib_cm_init_qp_attr(struct ib_cm_id *cm_id,
struct ibv_qp_attr *qp_attr,
int *qp_attr_mask);
/**
* ib_cm_send_apr - Sends an alternate path response message in response to
* a load alternate path request.
* @cm_id: Connection identifier associated with the alternate path response.
* @status: Reply status sent with the alternate path response.
* @info: Optional additional information sent with the alternate path
* response.
* @info_length: Size of the additional information, in bytes.
* @private_data: Optional user-defined private data sent with the
* alternate path response message.
* @private_data_len: Size of the private data buffer, in bytes.
*/
int ib_cm_send_apr(struct ib_cm_id *cm_id,
enum ib_cm_apr_status status,
void *info,
uint8_t info_length,
void *private_data,
uint8_t private_data_len);
struct ib_cm_sidr_req_param {
struct ibv_sa_path_rec *path;
uint64_t service_id; /* network-byte order */
int timeout_ms;
void *private_data;
uint8_t private_data_len;
uint8_t max_cm_retries;
};
/**
* ib_cm_send_sidr_req - Sends a service ID resolution request to the
* remote node.
* @cm_id: Communication identifier that will be associated with the
* service ID resolution request.
* @param: Service ID resolution request information.
*/
int ib_cm_send_sidr_req(struct ib_cm_id *cm_id,
struct ib_cm_sidr_req_param *param);
struct ib_cm_sidr_rep_param {
uint32_t qp_num;
uint32_t qkey;
enum ib_cm_sidr_status status;
void *info;
uint8_t info_length;
void *private_data;
uint8_t private_data_len;
};
/**
* ib_cm_send_sidr_rep - Sends a service ID resolution reply to the
* remote node.
* @cm_id: Communication identifier associated with the received service ID
* resolution request.
* @param: Service ID resolution reply information.
*/
int ib_cm_send_sidr_rep(struct ib_cm_id *cm_id,
struct ib_cm_sidr_rep_param *param);
#ifdef __cplusplus
}
#endif
#endif /* CM_H */

View File

@ -0,0 +1,338 @@
/*
* Copyright (c) 2005 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* $Id$
*/
#ifndef CM_ABI_H
#define CM_ABI_H
#include <infiniband/types.h>
#include <infiniband/sa.h>
#include <infiniband/marshall.h>
/*
* This file must be kept in sync with the kernel's version of ib_user_cm.h
*/
#define IB_USER_CM_MIN_ABI_VERSION 4
#define IB_USER_CM_MAX_ABI_VERSION 5
enum {
IB_USER_CM_CMD_CREATE_ID,
IB_USER_CM_CMD_DESTROY_ID,
IB_USER_CM_CMD_ATTR_ID,
IB_USER_CM_CMD_LISTEN,
IB_USER_CM_CMD_NOTIFY,
IB_USER_CM_CMD_ESTABLISH = IB_USER_CM_CMD_NOTIFY, /* ABI 4 support */
IB_USER_CM_CMD_SEND_REQ,
IB_USER_CM_CMD_SEND_REP,
IB_USER_CM_CMD_SEND_RTU,
IB_USER_CM_CMD_SEND_DREQ,
IB_USER_CM_CMD_SEND_DREP,
IB_USER_CM_CMD_SEND_REJ,
IB_USER_CM_CMD_SEND_MRA,
IB_USER_CM_CMD_SEND_LAP,
IB_USER_CM_CMD_SEND_APR,
IB_USER_CM_CMD_SEND_SIDR_REQ,
IB_USER_CM_CMD_SEND_SIDR_REP,
IB_USER_CM_CMD_EVENT,
IB_USER_CM_CMD_INIT_QP_ATTR,
};
/*
* command ABI structures.
*/
struct cm_abi_cmd_hdr {
__u32 cmd;
__u16 in;
__u16 out;
};
struct cm_abi_create_id {
__u64 uid;
__u64 response;
};
struct cm_abi_create_id_resp {
__u32 id;
};
struct cm_abi_destroy_id {
__u64 response;
__u32 id;
__u32 reserved;
};
struct cm_abi_destroy_id_resp {
__u32 events_reported;
};
struct cm_abi_attr_id {
__u64 response;
__u32 id;
__u32 reserved;
};
struct cm_abi_attr_id_resp {
__u64 service_id;
__u64 service_mask;
__u32 local_id;
__u32 remote_id;
};
struct cm_abi_init_qp_attr {
__u64 response;
__u32 id;
__u32 qp_state;
};
struct cm_abi_listen {
__u64 service_id;
__u64 service_mask;
__u32 id;
__u32 reserved;
};
struct cm_abi_establish { /* ABI 4 support */
__u32 id;
};
struct cm_abi_notify {
__u32 id;
__u32 event;
};
struct cm_abi_private_data {
__u64 data;
__u32 id;
__u8 len;
__u8 reserved[3];
};
struct cm_abi_req {
__u32 id;
__u32 qpn;
__u32 qp_type;
__u32 psn;
__u64 sid;
__u64 data;
__u64 primary_path;
__u64 alternate_path;
__u8 len;
__u8 peer_to_peer;
__u8 responder_resources;
__u8 initiator_depth;
__u8 remote_cm_response_timeout;
__u8 flow_control;
__u8 local_cm_response_timeout;
__u8 retry_count;
__u8 rnr_retry_count;
__u8 max_cm_retries;
__u8 srq;
__u8 reserved[5];
};
struct cm_abi_rep {
__u64 uid;
__u64 data;
__u32 id;
__u32 qpn;
__u32 psn;
__u8 len;
__u8 responder_resources;
__u8 initiator_depth;
__u8 target_ack_delay;
__u8 failover_accepted;
__u8 flow_control;
__u8 rnr_retry_count;
__u8 srq;
__u8 reserved[4];
};
struct cm_abi_info {
__u32 id;
__u32 status;
__u64 info;
__u64 data;
__u8 info_len;
__u8 data_len;
__u8 reserved[6];
};
struct cm_abi_mra {
__u64 data;
__u32 id;
__u8 len;
__u8 timeout;
__u8 reserved[2];
};
struct cm_abi_lap {
__u64 path;
__u64 data;
__u32 id;
__u8 len;
__u8 reserved[3];
};
struct cm_abi_sidr_req {
__u32 id;
__u32 timeout;
__u64 sid;
__u64 data;
__u64 path;
__u16 pkey;
__u8 len;
__u8 max_cm_retries;
__u8 reserved[4];
};
struct cm_abi_sidr_rep {
__u32 id;
__u32 qpn;
__u32 qkey;
__u32 status;
__u64 info;
__u64 data;
__u8 info_len;
__u8 data_len;
__u8 reserved[6];
};
/*
* event notification ABI structures.
*/
struct cm_abi_event_get {
__u64 response;
__u64 data;
__u64 info;
__u8 data_len;
__u8 info_len;
__u8 reserved[6];
};
struct cm_abi_req_event_resp {
struct ibv_kern_path_rec primary_path;
struct ibv_kern_path_rec alternate_path;
__u64 remote_ca_guid;
__u32 remote_qkey;
__u32 remote_qpn;
__u32 qp_type;
__u32 starting_psn;
__u8 responder_resources;
__u8 initiator_depth;
__u8 local_cm_response_timeout;
__u8 flow_control;
__u8 remote_cm_response_timeout;
__u8 retry_count;
__u8 rnr_retry_count;
__u8 srq;
__u8 port;
__u8 reserved[7];
};
struct cm_abi_rep_event_resp {
__u64 remote_ca_guid;
__u32 remote_qkey;
__u32 remote_qpn;
__u32 starting_psn;
__u8 responder_resources;
__u8 initiator_depth;
__u8 target_ack_delay;
__u8 failover_accepted;
__u8 flow_control;
__u8 rnr_retry_count;
__u8 srq;
__u8 reserved[5];
};
struct cm_abi_rej_event_resp {
__u32 reason;
/* ari in cm_abi_event_get info field. */
};
struct cm_abi_mra_event_resp {
__u8 timeout;
__u8 reserved[3];
};
struct cm_abi_lap_event_resp {
struct ibv_kern_path_rec path;
};
struct cm_abi_apr_event_resp {
__u32 status;
/* apr info in cm_abi_event_get info field. */
};
struct cm_abi_sidr_req_event_resp {
__u16 pkey;
__u8 port;
__u8 reserved;
};
struct cm_abi_sidr_rep_event_resp {
__u32 status;
__u32 qkey;
__u32 qpn;
/* info in cm_abi_event_get info field. */
};
#define CM_ABI_PRES_DATA 0x01
#define CM_ABI_PRES_INFO 0x02
#define CM_ABI_PRES_PRIMARY 0x04
#define CM_ABI_PRES_ALTERNATE 0x08
struct cm_abi_event_resp {
__u64 uid;
__u32 id;
__u32 event;
__u32 present;
__u32 reserved;
union {
struct cm_abi_req_event_resp req_resp;
struct cm_abi_rep_event_resp rep_resp;
struct cm_abi_rej_event_resp rej_resp;
struct cm_abi_mra_event_resp mra_resp;
struct cm_abi_lap_event_resp lap_resp;
struct cm_abi_apr_event_resp apr_resp;
struct cm_abi_sidr_req_event_resp sidr_req_resp;
struct cm_abi_sidr_rep_event_resp sidr_rep_resp;
__u32 send_status;
} u;
};
#endif /* CM_ABI_H */

View File

@ -0,0 +1,53 @@
%define ver 1.0.5
Name: libibcm
Version: 1.0.5
Release: 1%{?dist}
Summary: Userspace InfiniBand Communication Manager.
Group: System Environment/Libraries
License: GPL/BSD
Url: http://www.openfabrics.org/
Source: http://www.openfabrics.org/downloads/%{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
%description
libibcm provides a userspace InfiniBand Communication Managment library.
%package devel
Summary: Development files for the libibcm library
Group: System Environment/Libraries
Requires: %{name} = %{version}-%{release} %{_includedir}/infiniband/verbs.h
%description devel
Development files for the libibcm library.
%prep
%setup -q -n %{name}-%{ver}
%build
%configure
make %{?_smp_mflags}
%install
rm -rf $RPM_BUILD_ROOT
%makeinstall
# remove unpackaged files from the buildroot
rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
%clean
rm -rf $RPM_BUILD_ROOT
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%files
%defattr(-,root,root,-)
%{_libdir}/libibcm*.so.*
%doc AUTHORS COPYING ChangeLog README
%files devel
%defattr(-,root,root,-)
%{_libdir}/lib*.so
%{_libdir}/*.a
%{_includedir}/*

View File

@ -0,0 +1,53 @@
%define ver @VERSION@
Name: libibcm
Version: 1.0.5
Release: 1%{?dist}
Summary: Userspace InfiniBand Communication Manager.
Group: System Environment/Libraries
License: GPL/BSD
Url: http://www.openfabrics.org/
Source: http://www.openfabrics.org/downloads/%{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
%description
libibcm provides a userspace InfiniBand Communication Managment library.
%package devel
Summary: Development files for the libibcm library
Group: System Environment/Libraries
Requires: %{name} = %{version}-%{release} %{_includedir}/infiniband/verbs.h
%description devel
Development files for the libibcm library.
%prep
%setup -q -n %{name}-%{ver}
%build
%configure
make %{?_smp_mflags}
%install
rm -rf $RPM_BUILD_ROOT
%makeinstall
# remove unpackaged files from the buildroot
rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
%clean
rm -rf $RPM_BUILD_ROOT
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%files
%defattr(-,root,root,-)
%{_libdir}/libibcm*.so.*
%doc AUTHORS COPYING ChangeLog README
%files devel
%defattr(-,root,root,-)
%{_libdir}/lib*.so
%{_libdir}/*.a
%{_includedir}/*

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,25 @@
IBCM_1.0 {
global:
ib_cm_open_device;
ib_cm_close_device;
ib_cm_get_event;
ib_cm_ack_event;
ib_cm_create_id;
ib_cm_destroy_id;
ib_cm_attr_id;
ib_cm_listen;
ib_cm_send_req;
ib_cm_send_rep;
ib_cm_send_rtu;
ib_cm_send_dreq;
ib_cm_send_drep;
ib_cm_notify;
ib_cm_send_rej;
ib_cm_send_mra;
ib_cm_send_lap;
ib_cm_send_apr;
ib_cm_send_sidr_req;
ib_cm_send_sidr_rep;
ib_cm_init_qp_attr;
local: *;
};

View File

@ -0,0 +1,4 @@
Roland Dreier <roland@topspin.com>
Dotan Barak <dotanb@mellanox.co.il>
Sean Hefty <sean.hefty@intel.com>
Michael S. Tsirkin <mst@mellanox.co.il>

View File

@ -0,0 +1,378 @@
This software is available to you under a choice of one of two
licenses. You may choose to be licensed under the terms of the the
OpenIB.org BSD license or the GNU General Public License (GPL) Version
2, both included below.
Copyright (c) 2004 Topspin Communications. All rights reserved.
==================================================================
OpenIB.org BSD license
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
==================================================================
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@ -0,0 +1,583 @@
2006-10-30 Jack Morgenstein <jackm@mellanox.co.il>
* src/cmd.c (ibv_cmd_query_qp): Unmarshall sq_draining instead of
en_sqd_async_notify.
* include/infiniband/kern-abi.h: Change en_sqd_async_notify member
of struct ibv_query_qp_resp to sq_draining.
2006-10-30 Roland Dreier <rdreier@cisco.com>
* src/init.c (find_drivers): Make find_drivers() take a const
directory name, and tweak how we strip trailing /s so that we
don't have to modify the directory name passed in. Constify
default_path too.
2006-10-25 Roland Dreier <rdreier@cisco.com>
* src/init.c (init_drivers): Remove assignment to dev->driver now
that it is gone for good.
* include/infiniband/verbs.h: Remove .driver member of struct
ibv_device, since it is never really used.
2006-10-17 Roland Dreier <rdreier@cisco.com>
* include/infiniband/arch.h: Update i386 and x86_64 memory barrier
macros to be more than compiler barriers, to guard against
out-of-order speculative reads.
* include/infiniband/arch.h: Add rmb() and wmb() macros in
addition to the full mb(), so that low-level drivers can ask for
weaker ordering if that's all that is needed.
2006-10-03 Roland Dreier <rdreier@cisco.com>
* src/cmd.c (ibv_cmd_get_context_v2, ibv_cmd_get_context)
(ibv_cmd_query_device, ibv_cmd_query_port, ibv_cmd_alloc_pd)
(ibv_cmd_reg_mr, ibv_cmd_create_cq_v2, ibv_cmd_create_cq)
(ibv_cmd_poll_cq, ibv_cmd_resize_cq, ibv_cmd_destroy_cq)
(ibv_cmd_create_srq, ibv_cmd_create_qp, ibv_cmd_post_send)
(ibv_cmd_post_recv, ibv_cmd_post_srq_recv, ibv_cmd_create_ah)
(ibv_cmd_destroy_qp): Annotate so that Valgrind knows responses
are defined after write() succeeds. The kernel writes into the
response structure directly, so without these, Valgrind thinks
that response structures are undefined memory. This is based on
patches and suggestions by Rainer Keller <keller@hlrs.de>, Jeff
Squyres <jsquyres@cisco.com> and Siqing Fan.
* src/ibverbs.h: Add wrapper for VALGRIND_MAKE_MEM_DEFINED so that
it can be used in .c files without worrying about whether Valgrind
is installed or enabled.
* configure.in: Add support for Valgrind annotation (enabled with
--with-valgrind option to configure).
* src/cmd.c (ibv_cmd_query_port, ibv_cmd_create_cq,
ibv_cmd_modify_qp): Set reserved fields to 0 to avoid future
problems and also to make Valgrind a little quieter.
* src/init.c (init_drivers): Set node_type and transport_type
values of device being created.
* include/infiniband/verbs.h: Add ibv_node_type enum value
IBV_NODE_RNIC, and add enum ibv_transport_type. Add node_type and
transport_type fields to struct ibv_device.
2006-09-12 Roland Dreier <rdreier@cisco.com>
* include/infiniband/verbs.h: Swap wr_id and next members of
struct ibv_send_wr and struct ibv_recv_wr. This allows wr_id to
be naturally aligned without padding on 32-bit platforms.
2006-08-23 Roland Dreier <rdreier@cisco.com>
* include/infiniband/driver.h: Add a definition of the macro
IBV_CMD_RESIZE_CQ_HAS_RESP_PARAMS so that low-level driver plugins
can detect the changed signature of ibv_cmd_resize_cq().
2006-08-23 Ralph Campbell <ralph.campbell@qlogic.com>
* src/cmd.c (ibv_cmd_resize_cq): Add resp and resp_size parameters
so that the low-level driver in the kernel can return
device-specific information from the resize CQ operation.
2006-07-26 Roland Dreier <rdreier@cisco.com>
* src/verbs.c (ibv_reg_mr, ibv_dereg_mr): Add calls to
ibv_dontfork_range() and ibv_dofork_range() for memory regions
registered by library consumers.
* include/infiniband/verbs.h: Add declaration of ibv_fork_init().
* include/infiniband/driver.h: Add declarations of
ibv_dontfork_range() and ibv_dofork_range().
* src/memory.c: Rewrite to use a red-black tree instead of a
linked list. Change from doing mlock()/munlock() to
madvise(..., MADV_DONTFORK) and madvise(..., MADV_DOFORK), and
change the name of the entry points to ibv_dontfork_range() and
ibv_dofork_range(). Add ibv_fork_init() for applications to
request fork-safe behavior.
* src/ibverbs.h: Kill off unused declarations.
* src/init.c (ibverbs_init): Get rid of call to ibv_init_mem_map().
* include/infiniband/verbs.h: Add addr and length field to struct
ibv_mr so that memory regions can be madvised(). This changes the
ABI, since the layout of struct ibv_mr is changed.
2006-07-04 Roland Dreier <rdreier@cisco.com>
* include/infiniband/arch.h: Fix typo in sparc mb()
implementation: the asm should just be empty -- the "sync"
instruction was mistakenly cut and pasted from the ppc version.
2006-06-07 Sean Hefty <sean.hefty@intel.com>
* src/verbs.c include/infiniband/verbs.h: Add new routines:
ibv_init_ah_from_wc() and ibv_create_ah_from_wc() to simplify UD QP
communication.
* src/marshall.c include/infiniband/marshall.h: Expose
ibv_copy_ah_attr_from_kern to retrieve ibv_ah_attr from kernel for
a UD QP.
2006-06-01 Roland Dreier <rdreier@cisco.com>
* src/device.c (ibv_get_device_list): Actually return a
NULL-terminated array as the documentation promises.
2006-05-31 Roland Dreier <rdreier@cisco.com>
* src/init.c (find_drivers): Fix memory leak: the result of
asprintf() needs to be freed when we're done with it.
* examples/asyncwatch.c (event_name_str): Print human-readable
form of IBV_EVENT_CLIENT_REREGISTER.
2006-05-31 Leonid Arsh <leonida@voltaire.com>
* include/infiniband/verbs.h: Add IBV_EVENT_CLIENT_REREGISTER.
2006-05-22 Roland Dreier <rdreier@cisco.com>
* examples/devinfo.c (print_hca_cap): Read board_id attribute from
sysfs using ibv_read_sysfs_file() instead of libsysfs.
* src/cmd.c, src/marshall.c, src/sysfs.c: Include <string.h>,
since it is no longer implicitly included via <sysfs/libsysfs.h>.
* include/infiniband/driver.h, include/infiniband/verbs.h,
src/device.c, src/init.c, src/verbs.c: Remove dependency on
libsysfs by implementing what is required directly on top of
filesystem operations.
* include/infiniband/driver.h, src/init.c: Change name of driver
entry point to ibv_driver_init(), and update prototype to remove
libsysfs dependency.
* src/marshall.c, include/infiniband/marshall.h,
include/infiniband/sa.h: Remove deprecated ib_xxx symbols.
* Makefile.am: Bump SONAME to 2, since libibverbs 1.1 will be
ABI-incompatible with libibverbs 1.0.
* Create libibverbs 1.1 branch and bump version number to 1.1-pre1.
2006-05-22 Michael S. Tsirkin <mst@mellanox.co.il>
* include/infiniband/verbs.h: Remove trailing commas from
enumerators to quiet warnings from obsolete compilers.
2006-05-02 Roland Dreier <rdreier@cisco.com>
* Release version 1.0.3.
2006-05-01 Roland Dreier <rdreier@cisco.com>
* include/infiniband/arch.h: Only SPARC V9 ISA supports membar.
So just use generic memory barrier for older sparc archs.
2006-04-11 Roland Dreier <rdreier@cisco.com>
* src/sysfs.c (ibv_read_sysfs_file): Fix memory leak if open fails.
* src/device.c (ibv_get_device_guid), src/verbs.c (ibv_query_gid,
ibv_query_pkey), src/init.c (init_drivers, check_abi_version): Use
libibverbs functions instead of libsysfs functions to get to sysfs.
* src/sysfs.c (ibv_get_sysfs_path, ibv_read_sysfs_file): Add some
simple functions for accessing sysfs without using libsysfs.
* include/infiniband/sa-kern-abi.h: Deprecate struct
ib_kern_path_rec name; struct ibv_kern_path_rec is now preferred.
* include/infiniband/sa.h: Deprecate struct ib_sa_XXX names;
struct ibv_sa_XXX is now preferred.
* src/marshall.c, include/infiniband/marshall.h: Deprecate
ib_copy_XXX() names; ibv_copy_XXX() is preferred. Add stub
wrappers with the old names so old binaries still work.
2006-04-11 Hoang-Nam Nguyen <HNGUYEN@de.ibm.com>
* src/verbs.c (ibv_rate_to_mult, mult_to_ibv_rate): Add new
functions to convert between IB rate enums and multiples of the
base 2.5 Gb/sec rate.
2006-04-11 Roland Dreier <rdreier@cisco.com>
* include/infiniband/verbs.h: Add __attribute_const macro to
portably mark functions as __attribute__((const))
2006-03-28 Roland Dreier <rdreier@cisco.com>
* src/init.c (load_driver): Print warning if dlopen() of a driver
plugin fails.
2006-03-22 Dotan Barak <dotanb@mellanox.co.il>
* examples/asyncwatch.c: Print asynchronous event name as well as
raw integer value.
2006-03-22 Roland Dreier <rdreier@cisco.com>
* include/infiniband/verbs.h (ibv_req_notify_cq): Document
parameters better.
2006-03-16 Roland Dreier <rdreier@cisco.com>
* src/cmd.c, src/device.c, src/memory.c, src/verbs.c: Add include
of <stdlib.h> to get a declaration of free() and avoid compile
warnings.
2006-03-14 Roland Dreier <rdreier@cisco.com>
* Release version 1.0.2.
* Makefile.am (EXTRA_DIST): Remove debian/ directory from
tarballs, since Debian policy is that upstream tarballs should not
include it.
2006-03-13 Roland Dreier <rdreier@cisco.com>
* Release version 1.0.1.
* src/init.c (check_abi_version), src/verbs.c (ibv_query_gid,
ibv_query_pkey): Use sysfs_open_attribute() and
sysfs_read_attribute() instead of the deprecated function
sysfs_read_attribute_value(), which is no longer present in
libsysfs2 (which is already in Debian and Ubuntu).
* Release version 1.0.
2006-03-06 Roland Dreier <rdreier@cisco.com>
* include/infiniband/verbs.h: Add enum ibv_rate to define encoding
of static_rate field (based on a patch from Jack Morgenstein
<jackm@mellanox.co.il>).
2006-03-06 Ralph Campbell <ralphc@pathscale.com>
* src/init.c (find_drivers): Fix minor memory leak: call
globfree() to free memory allocated by glob().
2006-02-23 Dotan Barak <dotanb@mellanox.co.il>
* src/cmd.c (ibv_cmd_create_srq): Add support for kernel ABI
version 6 (take SRQ capacity from kernel response to create SRQ).
2006-02-16 Roland Dreier <rdreier@cisco.com>
* Release version 1.0-rc7.
* src/cmd.c (ibv_cmd_create_qp): Add support for kernel ABI
version 5 (properly aligned struct ibv_create_qp_resp).
2006-02-15 Roland Dreier <rdreier@cisco.com>
* src/cmd.c (ibv_cmd_create_qp): Allow userspace device-specific
driver to pass in a response buffer, so that the low-level driver
in the kernel can pass back device-specific information. This
changes the userspace driver API, since the signature of
ibv_cmd_create_qp() is changed.
2006-02-14 Roland Dreier <rdreier@cisco.com>
* Release version 1.0-rc6.
2006-02-13 Dotan Barak <dotanb@mellanox.co.il>
* examples/devinfo.c (print_hca_cap): Print board_id from sysfs,
if present.
2006-02-13 Roland Dreier <rdreier@cisco.com>
* examples/asyncwatch.c, examples/device_list.c,
examples/devinfo.c: Remove cpu_to_be64()/be64_to_cpu() and use
htonll()/ntohll() from <infiniband/arch.h>.
2006-02-13 Dotan Barak <dotanb@mellanox.co.il>
* src/cmd.c (ibv_cmd_query_qp, ibv_cmd_query_srq),
include/infiniband/driver.h: Add driver interface for calling
query QP and query SRQ kernel commands.
* include/infiniband/kern-abi.h: Add kernel ABI for query QP and
query SRQ.
* src/verbs.c (ibv_query_qp, ibv_query_srq),
include/infiniband/verbs.h: Add query QP and query SRQ library
APIs. This changes the provider ABI, since new fields are added
to struct ibv_context_ops; source compatibility with provider
libraries is preserved, but binaries will have to be recompiled.
Neither source nor binary compatibility with consumers of
libibverbs is affected.
2006-02-01 Roland Dreier <rdreier@cisco.com>
* examples/rc_pingpong.c, examples/uc_pingpong.c,
examples/ud_pingpong.c, examples/srq_pingpong.c: Fix bug in
searching for device by name when there's more than one device.
2006-01-31 Roland Dreier <rdreier@cisco.com>
* include/infiniband/verbs.h, include/infiniband/driver.h: Remove
useless "extern" from function declarations.
2006-01-26 Roland Dreier <rdreier@cisco.com>
* include/infiniband/driver.h, src/cmd.c (ibv_cmd_resize_cq): Add
driver interface for calling resize CQ kernel command.
* include/infiniband/kern-abi.h: Add resize CQ kernel ABI.
* include/infiniband/verbs.h, src/verbs.c (ibv_resize_cq): Add
resize CQ library API. This changes the provider ABI, since a new
field is added to struct ibv_context_ops; source compatibility
with provider libraries is preserved, but binaries will have to be
recompiled. Neither source nor binary compatibility with
consumers of libibverbs is affected.
2006-01-25 Roland Dreier <rdreier@cisco.com>
* examples/pingpong.c, examples/pingpong.h,
examples/rc_pingpong.c, examples/uc_pingpong.c,
examples/srq_pingpong.c: Move pp_get_local_lid() to pingpong.c to
reduce code duplication.
2006-01-22 Roland Dreier <rdreier@cisco.com>
* Release version 1.0-rc5.
2006-01-22 Dotan Barak <dotanb@mellanox.co.il>
* examples/devinfo.c (main): Make ibv_devinfo list all IB devices
by default, rather than the first device only.
2006-01-20 Roland Dreier <rdreier@cisco.com>
* examples/rc_pingpong.c, examples/uc_pingpong.c,
examples/srq_pingpong.c: Add "-m/--mtu=" option to set path MTU.
(Based on a patch from Ralph Campbell <ralphc@pathscale.com>)
* examples/pingpong.c, examples/pingpong.h: Create generic
pingpong files so that we can start factoring out common code from
the pingpong examples. Start with functions to convert MTU to an
IBV enum value.
2006-01-17 Ralph Campbell <ralphc@pathscale.com>
* examples/rc_pingpong.c (main), examples/srq_pingpong.c (main),
examples/uc_pingpong.c (main), examples/ud_pingpong.c (main): Fix
race when using CQ events by arming CQ before allowing remote side
to start sending.
2006-01-06 Roland Dreier <rdreier@cisco.com>
* examples/srq_pingpong.c (main): Fix SRQ example to avoid
problems with many QPs and events. Based on a patch from Dotan
Barak (who also found the problem).
2006-01-06 Ralph Campbell <ralphc@pathscale.com>
* examples/rc_pingpong.c (main), examples/srq_pingpong.c (main),
examples/uc_pingpong.c (main), examples/ud_pingpong.c (main): Fix
test of return value of ibv_poll_cq().
2006-01-04 Dotan Barak <dotanb@mellanox.co.il>
* include/infiniband/verbs.h: Fix mask names in description of
ibv_modify_srq.
2006-01-04 Michael S. Tsirkin <mst@mellanox.co.il>
* src/init.c (ibverbs_init): Fix ibverbs_init for multiple adapters.
Noted by Christoph Raisch.
2005-12-15 Roland Dreier <rdreier@cisco.com>
* include/infiniband/verbs.h: Document that devices must be opened
before calling ibv_free_device_list().
* src/verbs.c (ibv_create_srq): Not all provider libraries will
support SRQs, so check if the create_srq method is defined before
calling it. (Based on a patch from Shirley Ma <xma@us.ibm.com>)
2005-11-11 Roland Dreier <roland@cisco.com>
* examples/asyncwatch.c, examples/rc_pingpong.c,
examples/srq_pingpong.c, examples/uc_pingpong.c,
examples/ud_pingpong.c, examples/device_list.c,
examples/devinfo.c: Update examples to match new API.
* include/infiniband/verbs.h, src/device.c, src/init.c,
src/ibverbs.h: Change from dlist-based ibv_get_devices() API to
simpler ibv_get_device_list() and ibv_free_device_list() API.
2005-11-10 Sean Hefty <sean.hefty@intel.com>
* include/infiniband/sa-kern-abi.h: New include file to contain
definitions of SA structures passed between userspace and kernel.
* include/infiniband/sa.h: New include file for definitions of
SA structures used by multiple libraries.
* include/infiniband/marshall.h src/marshall.c: New files to define
routines used to exchange data with kernel modules.
* include/infiniband/kern-abi.h: Added data structures used to exchange
QP attribute with kernel modules.
2005-11-09 Michael S. Tsirkin <mst@mellanox.co.il>
* src/device.c (ibv_get_devices): Make function reentrant by using
a mutex to make sure we initialize the device list at most once.
2005-11-08 Roland Dreier <roland@cisco.com>
* src/cmd.c (ibv_cmd_create_qp): Add handling for new create QP
interface, which has the kernel return QP capabilities.
* src/cmd.c (ibv_cmd_modify_srq): Split off handling of modify SRQ
for ABI versions 3 and older, which passed max_sge as part of command.
2005-10-30 Roland Dreier <roland@cisco.com>
* examples/srq_pingpong.c (pp_init_ctx): Create CQ with rx_depth +
num_qp entries, instead of just rx_depth + 1 entries, because
there can be one send completion pending for each QP.
2005-10-25 Roland Dreier <roland@cisco.com>
* Release version 1.0-rc4.
* examples/uc_pingpong.c (pp_connect_ctx): Fix QP attribute masks
used to modify QP to RTR and RTS -- we should not be setting
RDMA/atomic attributes for UC QPs. Now that the mthca kernel
driver bug is fixed, the error is exposed here.
* examples/rc_pingpong.c, examples/srq_pingpong.c,
examples/uc_pingpong.c, examples/ud_pingpong.c: Keep track of
whether send and/or receive is pending. This avoids failures when
the remote side receives data and posts a send very quickly, and
the local side completes the receive before the previous send.
With the old code, this could result in posting a send before the
previous send completed, and therefore overrun the send queue.
2005-10-23 Roland Dreier <roland@cisco.com>
* src/cmd.c (ibv_cmd_get_context_v2): Correct silly mistake in
computation of size of buffer for old ABI command: we need to use
sizeof *cmd instead of sizeof cmd, since cmd is a pointer.
2005-10-21 Roland Dreier <roland@cisco.com>
* src/cmd.c (ibv_cmd_post_send, ibv_cmd_post_recv,
ibv_cmd_post_srq_recv): Correct value that we check write() return
value against so that we check against the size we actually try to
write, instead of just sizeof cmd.
2005-10-19 Roland Dreier <roland@cisco.com>
* src/cmd.c (ibv_cmd_req_notify_cq): Correct how we pass
solicited_only flag into the kernel.
2005-10-13 Roland Dreier <roland@cisco.com>
* include/infiniband/driver.h, src/cmd.c, src/libibverbs.map: Add
command functions for calling new kernel commands.
* include/infiniband/verbs.h: Add qp_type to struct ibv_qp so that
we know when we're posting a send on a UD QP, and add kernel
handle member to struct ibv_ah so we can handle drivers that do
create AH and destroy AH operations in the kernel.
* include/infiniband/kern-abi.h: Add new command structures for
poll CQ, request notification for CQ, post send, post receive,
post SRQ receive, create AH and destroy AH commands. These will
be used by the PathScale userspace driver.
2005-10-12 Roland Dreier <roland@cisco.com>
* examples/srq_pingpong.c (main): Zero out unused entries in
my_dest array to avoid string overflows when we send to the other
side.
2005-10-09 Roland Dreier <roland@cisco.com>
* examples/devinfo.c (print_hca_cap): Only print max_mr_size and
page_size_cap if verbose is set.
2005-10-05 Roland Dreier <roland@cisco.com>
* src/cmd.c (ibv_cmd_modify_srq): Add function for marshalling
modify SRQ command.
2005-09-29 Roland Dreier <roland@cisco.com>
* examples/devinfo.c (print_hca_cap): Get rid of formatting of
firmware version in what should be device-independent code.
* include/infiniband/driver.h, include/infiniband/verbs.h,
src/cmd.c (ibv_cmd_query_device): Change firmware version in
struct ibv_device_attr to be a string formatted by device-specific
library.
2005-09-25 Roland Dreier <roland@cisco.com>
* examples/rc_pingpong.c, examples/srq_pingpong.c,
examples/uc_pingpong.c, examples/ud_pingpong.c: Update to match
new completion channel and CQ creation API.
* include/infiniband/driver.h, include/infiniband/verbs.h,
src/device.c, src/ibverbs.h, src/verbs.c, src/cmd.c: Add notion of
"completion channel" that allows consumers to dynamically create
and destroy file descriptors for retrieving completion events.
Completion channels are handled natively with kernel ABI version 3
and simulated with backwards compatibility implementations for ABI
versions 1 and 2.
* include/infiniband/kern-abi.h: Update to match kernel ABI
version 3.
2005-09-07 Roland Dreier <roland@cisco.com>
* src/device.c (ibv_get_device_guid): Use htonll() instead of
relying on pointer aliasing (which seems to break for some gcc
versions).
* include/infiniband/arch.h: Add htonll() and ntohll() functions.
2005-09-06 Roland Dreier <roland@cisco.com>
* include/infiniband/kern-abi.h, include/infiniband/verbs.h,
src/cmd.c, src/device.c, src/verbs.c, examples/asyncwatch.c:
Update to handle new kernel ABI for avoiding stale completion
events. This is completely analogous to the previous asynchronous
event change.
2005-08-31 Roland Dreier <roland@cisco.com>
* include/infiniband/kern-abi.h, include/infiniband/verbs.h,
src/cmd.c, src/device.c, src/ibverbs.h, src/init.c, src/verbs.c,
examples/asyncwatch.c: Update to handle new kernel ABI for
avoiding stale asynchronous events. When a CQ, QP or SRQ is
destroyed, the kernel reports the number of events it has given to
userspace, and we wait until we've handled the same number of
events.
This does introduce a library API change: consumers are now
required to call ibv_put_async_event() to release every
asynchronous event that they retrieve via ibv_get_async_event().
2005-08-30 Roland Dreier <roland@cisco.com>
* man/ibv_asyncwatch.1, man/ibv_devices.1, man/ibv_devinfo.1,
man/ibv_rc_pingpong.1, man/ibv_srq_pingpong.1,
man/ibv_uc_pingpong.1, man/ibv_ud_pingpong.1: Add man pages for
example programs.
* examples/devinfo.c: Merge with Dotan Barak's vstat tool.

View File

@ -0,0 +1,114 @@
INCLUDES = -I$(srcdir)/include
lib_LTLIBRARIES = src/libibverbs.la
AM_CFLAGS = -g -Wall -D_GNU_SOURCE
src_libibverbs_la_CFLAGS = $(AM_CFLAGS) -DIBV_CONFIG_DIR=\"$(sysconfdir)/libibverbs.d\"
libibverbs_version_script = @LIBIBVERBS_VERSION_SCRIPT@
src_libibverbs_la_SOURCES = src/cmd.c src/compat-1_0.c src/device.c src/init.c \
src/marshall.c src/memory.c src/sysfs.c src/verbs.c \
src/enum_strs.c
src_libibverbs_la_LDFLAGS = -version-info 1 -export-dynamic \
$(libibverbs_version_script)
src_libibverbs_la_DEPENDENCIES = $(srcdir)/src/libibverbs.map
bin_PROGRAMS = examples/ibv_devices examples/ibv_devinfo \
examples/ibv_asyncwatch examples/ibv_rc_pingpong examples/ibv_uc_pingpong \
examples/ibv_ud_pingpong examples/ibv_srq_pingpong
examples_ibv_devices_SOURCES = examples/device_list.c
examples_ibv_devices_LDADD = $(top_builddir)/src/libibverbs.la
examples_ibv_devinfo_SOURCES = examples/devinfo.c
examples_ibv_devinfo_LDADD = $(top_builddir)/src/libibverbs.la
examples_ibv_rc_pingpong_SOURCES = examples/rc_pingpong.c examples/pingpong.c
examples_ibv_rc_pingpong_LDADD = $(top_builddir)/src/libibverbs.la
examples_ibv_uc_pingpong_SOURCES = examples/uc_pingpong.c examples/pingpong.c
examples_ibv_uc_pingpong_LDADD = $(top_builddir)/src/libibverbs.la
examples_ibv_ud_pingpong_SOURCES = examples/ud_pingpong.c examples/pingpong.c
examples_ibv_ud_pingpong_LDADD = $(top_builddir)/src/libibverbs.la
examples_ibv_srq_pingpong_SOURCES = examples/srq_pingpong.c examples/pingpong.c
examples_ibv_srq_pingpong_LDADD = $(top_builddir)/src/libibverbs.la
examples_ibv_asyncwatch_SOURCES = examples/asyncwatch.c
examples_ibv_asyncwatch_LDADD = $(top_builddir)/src/libibverbs.la
libibverbsincludedir = $(includedir)/infiniband
libibverbsinclude_HEADERS = include/infiniband/arch.h include/infiniband/driver.h \
include/infiniband/kern-abi.h include/infiniband/opcode.h include/infiniband/verbs.h \
include/infiniband/sa-kern-abi.h include/infiniband/sa.h include/infiniband/marshall.h
man_MANS = man/ibv_asyncwatch.1 man/ibv_devices.1 man/ibv_devinfo.1 \
man/ibv_rc_pingpong.1 man/ibv_uc_pingpong.1 man/ibv_ud_pingpong.1 \
man/ibv_srq_pingpong.1 man/ibv_alloc_pd.3 man/ibv_attach_mcast.3 \
man/ibv_create_ah.3 man/ibv_create_ah_from_wc.3 \
man/ibv_create_comp_channel.3 man/ibv_create_cq.3 \
man/ibv_create_qp.3 man/ibv_create_srq.3 \
man/ibv_create_xrc_rcv_qp.3 man/ibv_event_type_str.3 \
man/ibv_fork_init.3 man/ibv_get_async_event.3 \
man/ibv_get_cq_event.3 man/ibv_get_device_guid.3 \
man/ibv_get_device_list.3 man/ibv_get_device_name.3 \
man/ibv_modify_qp.3 man/ibv_modify_srq.3 man/ibv_modify_xrc_rcv_qp.3 \
man/ibv_open_device.3 man/ibv_open_xrc_domain.3 \
man/ibv_poll_cq.3 man/ibv_post_recv.3 man/ibv_post_send.3 \
man/ibv_post_srq_recv.3 man/ibv_query_device.3 man/ibv_query_gid.3 \
man/ibv_query_pkey.3 man/ibv_query_port.3 man/ibv_query_qp.3 \
man/ibv_query_srq.3 man/ibv_query_xrc_rcv_qp.3 \
man/ibv_rate_to_mult.3 man/ibv_reg_mr.3 man/ibv_reg_xrc_rcv_qp.3 \
man/ibv_req_notify_cq.3 man/ibv_resize_cq.3 man/verbs.7
DEBIAN = debian/changelog debian/compat debian/control debian/copyright \
debian/ibverbs-utils.install debian/libibverbs1.install \
debian/libibverbs1.postinst debian/libibverbs-dev.install \
debian/rules
EXTRA_DIST = include/infiniband/driver.h include/infiniband/kern-abi.h \
include/infiniband/opcode.h include/infiniband/verbs.h include/infiniband/marshall.h \
include/infiniband/sa-kern-abi.h include/infiniband/sa.h \
src/ibverbs.h examples/pingpong.h \
src/libibverbs.map libibverbs.spec.in $(man_MANS)
dist-hook: libibverbs.spec
cp libibverbs.spec $(distdir)
install-data-hook:
cd $(DESTDIR)$(mandir)/man3 && \
$(RM) ibv_ack_async_event.3 && \
$(RM) ibv_ack_cq_events.3 && \
$(RM) ibv_close_device.3 && \
$(RM) ibv_close_xrc_domain.3 && \
$(RM) ibv_create_xrc_srq.3 && \
$(RM) ibv_dealloc_pd.3 && \
$(RM) ibv_dereg_mr.3 && \
$(RM) ibv_destroy_ah.3 && \
$(RM) ibv_destroy_comp_channel.3 && \
$(RM) ibv_destroy_cq.3 && \
$(RM) ibv_destroy_qp.3 && \
$(RM) ibv_destroy_srq.3 && \
$(RM) ibv_detach_mcast.3 && \
$(RM) ibv_free_device_list.3 && \
$(RM) ibv_init_ah_from_wc.3 && \
$(RM) ibv_unreg_xrc_rcv_qp.3 && \
$(RM) mult_to_ibv_rate.3 && \
$(RM) ibv_node_type_str.3 && \
$(RM) ibv_port_state_str.3 && \
$(LN_S) ibv_get_async_event.3 ibv_ack_async_event.3 && \
$(LN_S) ibv_get_cq_event.3 ibv_ack_cq_events.3 && \
$(LN_S) ibv_open_device.3 ibv_close_device.3 && \
$(LN_S) ibv_open_xrc_domain.3 ibv_close_xrc_domain.3 && \
$(LN_S) ibv_create_srq.3 ibv_create_xrc_srq.3 && \
$(LN_S) ibv_alloc_pd.3 ibv_dealloc_pd.3 && \
$(LN_S) ibv_reg_mr.3 ibv_dereg_mr.3 && \
$(LN_S) ibv_create_ah.3 ibv_destroy_ah.3 && \
$(LN_S) ibv_create_comp_channel.3 ibv_destroy_comp_channel.3 && \
$(LN_S) ibv_create_cq.3 ibv_destroy_cq.3 && \
$(LN_S) ibv_create_qp.3 ibv_destroy_qp.3 && \
$(LN_S) ibv_create_srq.3 ibv_destroy_srq.3 && \
$(LN_S) ibv_attach_mcast.3 ibv_detach_mcast.3 && \
$(LN_S) ibv_get_device_list.3 ibv_free_device_list.3 && \
$(LN_S) ibv_create_ah_from_wc.3 ibv_init_ah_from_wc.3 && \
$(LN_S) ibv_reg_xrc_rcv_qp.3 ibv_unreg_xrc_rcv_qp.3 && \
$(LN_S) ibv_rate_to_mult.3 mult_to_ibv_rate.3 && \
$(LN_S) ibv_event_type_str.3 ibv_node_type_str.3 && \
$(LN_S) ibv_event_type_str.3 ibv_port_state_str.3

View File

@ -0,0 +1,164 @@
Introduction
============
libibverbs is a library that allows programs to use RDMA "verbs" for
direct access to RDMA (currently InfiniBand and iWARP) hardware from
userspace. For more information on RDMA verbs, see the InfiniBand
Architecture Specification vol. 1, especially chapter 11, and the RDMA
Consortium's RDMA Protocol Verbs Specification.
Using libibverbs
================
Device nodes
------------
The verbs library expects special character device files named
/dev/infiniband/uverbsN to be created. When you load the kernel
modules, including both the low-level driver for your IB hardware as
well as the ib_uverbs module, you should see one or more uverbsN
entries in /sys/class/infiniband_verbs in addition to the
/dev/infiniband/uverbsN character device files.
To create the appropriate character device files automatically with
udev, a rule like
KERNEL="uverbs*", NAME="infiniband/%k"
can be used. This will create device nodes named
/dev/infiniband/uverbs0
and so on. Since the RDMA userspace verbs should be safe for use by
non-privileged users, you may want to add an appropriate MODE or GROUP
to your udev rule.
Permissions
-----------
To use IB verbs from userspace, a process must be able to access the
appropriate /dev/infiniband/uverbsN special device file. You can
check the permissions on this file with the command
ls -l /dev/infiniband/uverbs*
Make sure that the permissions on these files are such that the
user/group that your verbs program runs as can access the device file.
To use IB verbs from userspace, a process must also have permission to
tell the kernel to lock sufficient memory for all of your registered
memory regions as well as the memory used internally by IB resources
such as queue pairs (QPs) and completion queues (CQs). To check your
resource limits, use the command
ulimit -l
(or "limit memorylocked" for csh-like shells).
If you see a small number such as 32 (the units are KB) then you will
need to increase this limit. This is usually done for ordinary users
via the file /etc/security/limits.conf. More configuration may be
necessary if you are logging in via OpenSSH and your sshd is
configured to use privilege separation.
Valgrind support
----------------
When running applications that use libibverbs under the Valgrind
memory-checking debugger, Valgrind will falsely report "read from
uninitialized" for memory that was initialized by the kernel drivers.
Specifically, Valgrind cannot see when kernel drivers write to
userspace memory, so when the process reads from that memory, Valgrind
incorrectly assumes that the memory contents are uninitialized, and
therefore raises a warning.
libibverbs can be built with specific support for the Valgrind
memory-checking debugger by specifying the --with-valgrind command
line argument to configure. This flag enables code in libibverbs to
tell Valgrind "this memory may look uninitialized, but it's really
OK," which therefore suppresses the incorrect "read from
uninitialized" warnings. This code adds trivial overhead to the
critical performance path, so it is disabled by default. The intent
is that production users can use a "normal" build of libibverbs and
developers can use the "valgrind debug" build by simply switching
their LD_LIBRARY_PATH environment variables.
Libibverbs needs some header files from Valgrind in order to compile
this support; it is important to use the header files from the same
version of Valgrind that will be used at run time. You may need to
specify the directory where Valgrind's header files are installed as
an argument to --with-valgrind. For example
./configure --with-valgrind=/opt/valgrind
will make the libibverbs build look for valgrind headers in
/opt/valgrind/include
Reporting bugs
==============
Bugs should be reported to the OpenFabrics mailing list
<general@lists.openfabrics.org>. In your bug report, please include:
* Information about your system:
- Linux distribution and version
- Linux kernel and version
- InfiniBand/iWARP hardware and firmware version
- ... any other relevant information
* How to reproduce the bug. Command line arguments for a libibverbs
example program or source code that other developers can
compile and run is most convenient.
* If the bug is a crash, the exact output printed out when the crash
occurred, including any kernel messages produced.
* If a verbs call is mysteriously returning an error or failing, the
output of "strace -ewrite -ewrite=all <command>".
Submitting patches
==================
Patches should also be submitted to the OpenFabrics mailing list
<general@lists.openfabrics.org>. Please use unified diff form (the -u
option to GNU diff), and include a good description of what your patch
does and why it should be applied. If your patch fixes a bug, please
make sure to describe the bug and how your fix works.
Please include a change to the ChangeLog file (in standard GNU
changelog format) as part of your patch.
Make sure that your contribution can be licensed under the same
license as the original code you are patching, and that you have all
necessary permissions to release your work.
TODO
====
1.1 series
----------
The libibverbs API and ABI are frozen for all releases in the 1.1
series. Methods were added to struct ibv_context to implement the
following features, so it should be possible to add them in a future
release in the 1.1 series:
* Memory window (MW) support.
* Implement the reregister memory region (MR) verb. We will add an
extension to the IB spec to allow the application to indicate that
the region is only being extended, and that operations in progress
should _not_ fail (contrary to the IB spec, which states that
reregister must be implemented so that it behaves equivalently to a
deregister followed by a register).
Other possibilities
-------------------
There are no plans to implement the following features, which would be
needed for completeness but don't seem particularly useful. However,
if there is demand from application developers or an implementation is
contributed, then the feature may be added.
* Implement the query address handle (AH) verb.
* Implement the query memory region (MR) verb.

View File

@ -0,0 +1,8 @@
#! /bin/sh
set -x
aclocal -I config
libtoolize --force --copy
autoheader
automake --foreign --add-missing --copy
autoconf

View File

@ -0,0 +1,77 @@
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.57)
AC_INIT(libibverbs, 1.1.4, general@lists.openfabrics.org)
AC_CONFIG_SRCDIR([src/ibverbs.h])
AC_CONFIG_AUX_DIR(config)
AC_CONFIG_HEADER(config.h)
AM_INIT_AUTOMAKE(libibverbs, 1.1.4)
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
dnl Checks for programs
AC_PROG_CC
AC_GNU_SOURCE
AC_PROG_LN_S
AC_PROG_LIBTOOL
LT_INIT
AC_ARG_WITH([valgrind],
AC_HELP_STRING([--with-valgrind],
[Enable Valgrind annotations (small runtime overhead, default NO)]))
if test x$with_valgrind = x || test x$with_valgrind = xno; then
want_valgrind=no
AC_DEFINE([NVALGRIND], 1, [Define to 1 to disable Valgrind annotations.])
else
want_valgrind=yes
if test -d $with_valgrind; then
CPPFLAGS="$CPPFLAGS -I$with_valgrind/include"
fi
fi
dnl Checks for programs
AC_PROG_CC
AC_PROG_LN_S
dnl Checks for libraries
AC_CHECK_LIB(dl, dlsym, [],
AC_MSG_ERROR([dlsym() not found. libibverbs requires libdl.]))
AC_CHECK_LIB(pthread, pthread_mutex_init, [],
AC_MSG_ERROR([pthread_mutex_init() not found. libibverbs requires libpthread.]))
dnl Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADER(valgrind/memcheck.h,
[AC_DEFINE(HAVE_VALGRIND_MEMCHECK_H, 1,
[Define to 1 if you have the <valgrind/memcheck.h> header file.])],
[if test $want_valgrind = yes; then
AC_MSG_ERROR([Valgrind memcheck support requested, but <valgrind/memcheck.h> not found.])
fi])
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_CACHE_CHECK(whether ld accepts --version-script, ac_cv_version_script,
[if test -n "`$LD --help < /dev/null 2>/dev/null | grep version-script`"; then
ac_cv_version_script=yes
else
ac_cv_version_script=no
fi])
if test $ac_cv_version_script = yes; then
LIBIBVERBS_VERSION_SCRIPT='-Wl,--version-script=$(srcdir)/src/libibverbs.map'
else
LIBIBVERBS_VERSION_SCRIPT=
fi
AC_SUBST(LIBIBVERBS_VERSION_SCRIPT)
AC_CACHE_CHECK(for .symver assembler support, ac_cv_asm_symver_support,
[AC_TRY_COMPILE(, [asm("symbol:\n.symver symbol, api@ABI\n");],
ac_cv_asm_symver_support=yes,
ac_cv_asm_symver_support=no)])
if test $ac_cv_asm_symver_support = yes; then
AC_DEFINE([HAVE_SYMVER_SUPPORT], 1, [assembler has .symver support])
fi
AC_CONFIG_FILES([Makefile libibverbs.spec])
AC_OUTPUT

View File

@ -0,0 +1,78 @@
libibverbs (1.1.2-1) unstable; urgency=low
* New upstream release.
- Fix memory registration failure cause by too-big madvise()
- Fix many Valgrind false positives
- Add functions to convert enum values to strings
* Replace deprecated ${Source-Version} with ${binary:Version}
* Use DEB_DH_MAKESHLIBS_ARGS_ALL to pass appropriate -V option to
dh_makeshlibs, since new symbols were added in libibverbs 1.1.2.
(Closes: #465435)
* Add debian/watch file.
* Update control file to talk about generic RDMA and iWARP, not just
InfiniBand, since libibverbs works with both IB and iWARP.
* Acknowledge NMU (Closes: #442638).
-- Roland Dreier <rolandd@cisco.com> Fri, 18 Apr 2008 15:08:52 -0700
libibverbs (1.1.1-1.1) unstable; urgency=low
* Non-maintainer upload.
* Re-generated autotools files to fix double build bug, closes: #442638
* Bumped Standards-Version to 3.7.3, no change needed.
-- Michael Meskes <meskes@debian.org> Mon, 14 Apr 2008 10:07:58 +0000
libibverbs (1.1.1-1) unstable; urgency=low
* New upstream release.
- Initialize state of newly created QPs to RESET (fixes problems
with libmlx4/ConnectX HCAs).
- Don't warn root about RLIMIT_MEMLOCK, since it doesn't matter.
- Fix free() errors in ibv_xx_pingpong examples.
-- Roland Dreier <rolandd@cisco.com> Fri, 15 Jun 2007 12:49:02 -0700
libibverbs (1.1-1) unstable; urgency=low
* New upstream release.
- Add support for use of fork() in applications.
- Add manual pages documenting API in section 3.
- New method of finding and loading device-specific drivers.
- Add basic support for iWARP devices.
- Provide compatible ABI for applications linked against libibverbs 1.0.
* Update libtool during build to avoid setting RPATH in binaries on amd64.
-- Roland Dreier <rolandd@cisco.com> Sat, 28 Apr 2007 14:15:29 -0700
libibverbs (1.0.4-1) unstable; urgency=low
* New upstream release.
- Fix static linking so it has a chance of working.
- Fix cut-and-paste error in sparc mb() macro.
- Other miscellaneous fixes.
* Improve package description.
-- Roland Dreier <rolandd@cisco.com> Tue, 31 Oct 2006 15:04:33 -0800
libibverbs (1.0.3-1) unstable; urgency=low
* Change priority to extra, since libibverbs depends on libsysfs2, which
has priority extra. (Debian policy section 2.5 states that a package
may not depend on another package of lower priority)
* New upstream release:
- For sparc, only generate membar instruction if compiling for V9
instruction set. (Closes: #365559)
- Reduce (but not yet eliminate) dependency on libsysfs.
- Deprecate some ib_XXX symbol names and introduce ibv_XXX
replacements for internal consistency.
- Other minor fixes.
* Update to Standards-Version: 3.7.2.
-- Roland Dreier <rolandd@cisco.com> Tue, 2 May 2006 15:33:14 -0700
libibverbs (1.0.2-1) unstable; urgency=low
* Initial Release. (Closes: #325752)
-- Roland Dreier <rolandd@cisco.com> Wed, 15 Feb 2006 11:21:59 -0700

View File

@ -0,0 +1 @@
5

View File

@ -0,0 +1,80 @@
Source: libibverbs
Priority: extra
Maintainer: Roland Dreier <rolandd@cisco.com>
Build-Depends: @cdbs@, dpkg-dev (>= 1.13.19)
Standards-Version: 3.7.3
Section: libs
Homepage: http://www.openfabrics.org/
Package: libibverbs1
Section: libs
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, adduser
Description: A library for direct userspace use of RDMA (InfiniBand/iWARP)
libibverbs is a library that allows userspace processes to use RDMA
"verbs" as described in the InfiniBand Architecture Specification and
the RDMA Protocol Verbs Specification. iWARP ethernet NICs support
RDMA over hardware-offloaded TCP/IP, while InfiniBand is a
high-throughput, low-latency networking technology. InfiniBand host
channel adapters (HCAs) and iWARP NICs commonly support direct
hardware access from userspace (kernel bypass), and libibverbs
supports this when available.
.
For this library to be useful, a device-specific plug-in module
should also be installed.
.
This package contains the shared library.
Package: libibverbs-dev
Section: libdevel
Architecture: any
Depends: ${misc:Depends}, libibverbs1 (= ${binary:Version})
Description: Development files for the libibverbs library
libibverbs is a library that allows userspace processes to use RDMA
"verbs" as described in the InfiniBand Architecture Specification and
the RDMA Protocol Verbs Specification. iWARP ethernet NICs support
RDMA over hardware-offloaded TCP/IP, while InfiniBand is a
high-throughput, low-latency networking technology. InfiniBand host
channel adapters (HCAs) and iWARP NICs commonly support direct
hardware access from userspace (kernel bypass), and libibverbs
supports this when available.
.
This package is needed to compile programs against libibverbs1.
It contains the header files and static libraries (optionally)
needed for compiling.
Package: libibverbs1-dbg
Section: libdevel
Priority: extra
Architecture: any
Depends: ${misc:Depends}, libibverbs1 (= ${binary:Version})
Description: Debugging symbols for the libibverbs library
libibverbs is a library that allows userspace processes to use RDMA
"verbs" as described in the InfiniBand Architecture Specification and
the RDMA Protocol Verbs Specification. iWARP ethernet NICs support
RDMA over hardware-offloaded TCP/IP, while InfiniBand is a
high-throughput, low-latency networking technology. InfiniBand host
channel adapters (HCAs) and iWARP NICs commonly support direct
hardware access from userspace (kernel bypass), and libibverbs
supports this when available.
.
This package contains the debugging symbols associated with
libibverbs1. They will automatically be used by gdb for debugging
libibverbs-related issues.
Package: ibverbs-utils
Section: net
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Examples for the libibverbs library
libibverbs is a library that allows userspace processes to use RDMA
"verbs" as described in the InfiniBand Architecture Specification and
the RDMA Protocol Verbs Specification. iWARP ethernet NICs support
RDMA over hardware-offloaded TCP/IP, while InfiniBand is a
high-throughput, low-latency networking technology. InfiniBand host
channel adapters (HCAs) and iWARP NICs commonly support direct
hardware access from userspace (kernel bypass), and libibverbs
supports this when available.
.
This package contains useful libibverbs1 example programs such as
ibv_devinfo, which displays information about InfiniBand devices.

View File

@ -0,0 +1,49 @@
Initial Debianization:
This package was debianized by Roland Dreier <rolandd@cisco.com> on
Mon, 25 Apr 2005 10:21:08 -0700.
Source:
It was downloaded from the OpenIB web site at
<https://openib.org/downloads.html>
Authors:
Roland Dreier <roland@topspin.com>
Dotan Barak <dotanb@mellanox.co.il>
Sean Hefty <sean.hefty@intel.com>
Michael S. Tsirkin <mst@mellanox.co.il>
Portions are copyrighted by:
* Copyright (c) 2005, 2006 Cisco Systems. All rights reserved.
* Copyright (c) 2004, 2005 Intel Corporation. All rights reserved.
* Copyright (c) 2005 Mellanox Technologies Ltd. All rights reserved.
* Copyright (c) 2005 PathScale, Inc. All rights reserved.
* Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Voltaire, Inc. All rights reserved.
libibverbs is licensed under a choice of one of two licenses. You may
choose to be licensed under the terms of the GNU General Public
License (GPL) Version 2, available from the file
/usr/share/common-licenses/GPL-2 on your Debian system, or the
OpenIB.org BSD license below:
Redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following
conditions are met:
- Redistributions of source code must retain the above
copyright notice, this list of conditions and the following
disclaimer.
- Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials
provided with the distribution.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,2 @@
usr/bin
usr/share/man/man1

View File

@ -0,0 +1,3 @@
usr/include
usr/lib/libibverbs*.{a,la,so}
usr/share/man/man3

View File

@ -0,0 +1,16 @@
usr/share/man/man3/ibv_get_async_event.3 usr/share/man/man3/ibv_ack_async_event.3
usr/share/man/man3/ibv_get_cq_event.3 usr/share/man/man3/ibv_ack_cq_events.3
usr/share/man/man3/ibv_open_device.3 usr/share/man/man3/ibv_close_device.3
usr/share/man/man3/ibv_alloc_pd.3 usr/share/man/man3/ibv_dealloc_pd.3
usr/share/man/man3/ibv_reg_mr.3 usr/share/man/man3/ibv_dereg_mr.3
usr/share/man/man3/ibv_create_ah.3 usr/share/man/man3/ibv_destroy_ah.3
usr/share/man/man3/ibv_create_comp_channel.3 usr/share/man/man3/ibv_destroy_comp_channel.3
usr/share/man/man3/ibv_create_cq.3 usr/share/man/man3/ibv_destroy_cq.3
usr/share/man/man3/ibv_create_qp.3 usr/share/man/man3/ibv_destroy_qp.3
usr/share/man/man3/ibv_create_srq.3 usr/share/man/man3/ibv_destroy_srq.3
usr/share/man/man3/ibv_attach_mcast.3 usr/share/man/man3/ibv_detach_mcast.3
usr/share/man/man3/ibv_get_device_list.3 usr/share/man/man3/ibv_free_device_list.3
usr/share/man/man3/ibv_create_ah_from_wc.3 usr/share/man/man3/ibv_init_ah_from_wc.3
usr/share/man/man3/ibv_rate_to_mult.3 usr/share/man/man3/mult_to_ibv_rate.3
usr/share/man/man3/ibv_event_type_str.3 usr/share/man/man3/ibv_node_type_str.3
usr/share/man/man3/ibv_event_type_str.3 usr/share/man/man3/ibv_port_state_str.3

View File

@ -0,0 +1 @@
usr/lib/libibverbs*.so.*

View File

@ -0,0 +1,12 @@
#!/bin/sh
# postinst script for libibverbs1
set -e
if [ "$1" != configure ]; then
exit 0
fi
getent group rdma > /dev/null 2>&1 || addgroup --system --quiet rdma
#DEBHELPER#

View File

@ -0,0 +1,9 @@
#!/usr/bin/make -f
# -*- mode: makefile; coding: utf-8 -*-
DEB_DH_INSTALL_SOURCEDIR := debian/tmp
DEB_AUTO_UPDATE_LIBTOOL := post
DEB_DH_MAKESHLIBS_ARGS_ALL := -V 'libibverbs1 (>= 1.1.2)'
include /usr/share/cdbs/1/rules/debhelper.mk
include /usr/share/cdbs/1/class/autotools.mk

View File

@ -0,0 +1,3 @@
version=3
opts="uversionmangle=s/-rc/~rc/" \
http://www.openfabrics.org/downloads/verbs/libibverbs-(.+)\.tar\.gz

View File

@ -0,0 +1,28 @@
CFLAGS= -I../../../../sys/ofed/include -libverbs -lmlx4 -lmthca -pthread
all: asyncwatch devinfo device_list rc_pingpong srq_pingpong uc_pingpong ud_pingpong
clean:
rm asyncwatch devinfo device_list rc_pingpong srq_pingpong uc_pingpong ud_pingpong
asyncwatch:
gcc -o asyncwatch asyncwatch.c ${CFLAGS}
devinfo:
gcc -o devinfo devinfo.c ${CFLAGS}
device_list:
gcc -o device_list device_list.c ${CFLAGS}
rc_pingpong:
gcc -o rc_pingpong rc_pingpong.c pingpong.c ${CFLAGS}
srq_pingpong:
gcc -o srq_pingpong srq_pingpong.c pingpong.c ${CFLAGS}
uc_pingpong:
gcc -o uc_pingpong uc_pingpong.c pingpong.c ${CFLAGS}
ud_pingpong:
gcc -o ud_pingpong ud_pingpong.c pingpong.c ${CFLAGS}

View File

@ -0,0 +1,121 @@
/*
* Copyright (c) 2005 Topspin Communications. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#if HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <stdio.h>
#include <endian.h>
#include <byteswap.h>
#include <infiniband/verbs.h>
static const char *event_name_str(enum ibv_event_type event_type)
{
switch (event_type) {
case IBV_EVENT_DEVICE_FATAL:
return "IBV_EVENT_DEVICE_FATAL";
case IBV_EVENT_PORT_ACTIVE:
return "IBV_EVENT_PORT_ACTIVE";
case IBV_EVENT_PORT_ERR:
return "IBV_EVENT_PORT_ERR";
case IBV_EVENT_LID_CHANGE:
return "IBV_EVENT_LID_CHANGE";
case IBV_EVENT_PKEY_CHANGE:
return "IBV_EVENT_PKEY_CHANGE";
case IBV_EVENT_SM_CHANGE:
return "IBV_EVENT_SM_CHANGE";
case IBV_EVENT_CLIENT_REREGISTER:
return "IBV_EVENT_CLIENT_REREGISTER";
case IBV_EVENT_GID_CHANGE:
return "IBV_EVENT_GID_CHANGE";
case IBV_EVENT_CQ_ERR:
case IBV_EVENT_QP_FATAL:
case IBV_EVENT_QP_REQ_ERR:
case IBV_EVENT_QP_ACCESS_ERR:
case IBV_EVENT_COMM_EST:
case IBV_EVENT_SQ_DRAINED:
case IBV_EVENT_PATH_MIG:
case IBV_EVENT_PATH_MIG_ERR:
case IBV_EVENT_SRQ_ERR:
case IBV_EVENT_SRQ_LIMIT_REACHED:
case IBV_EVENT_QP_LAST_WQE_REACHED:
default:
return "unexpected";
}
}
int main(int argc, char *argv[])
{
struct ibv_device **dev_list;
struct ibv_context *context;
struct ibv_async_event event;
/* Force line-buffering in case stdout is redirected */
setvbuf(stdout, NULL, _IOLBF, 0);
dev_list = ibv_get_device_list(NULL);
if (!dev_list) {
perror("Failed to get IB devices list");
return 1;
}
if (!*dev_list) {
fprintf(stderr, "No IB devices found\n");
return 1;
}
context = ibv_open_device(*dev_list);
if (!context) {
fprintf(stderr, "Couldn't get context for %s\n",
ibv_get_device_name(*dev_list));
return 1;
}
printf("%s: async event FD %d\n",
ibv_get_device_name(*dev_list), context->async_fd);
while (1) {
if (ibv_get_async_event(context, &event))
return 1;
printf(" event_type %s (%d), port %d\n",
event_name_str(event.event_type),
event.event_type, event.element.port_num);
ibv_ack_async_event(&event);
}
return 0;
}

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2004 Topspin Communications. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#if HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <stdio.h>
#include <endian.h>
#include <byteswap.h>
#include <infiniband/verbs.h>
#include <infiniband/arch.h>
int main(int argc, char *argv[])
{
struct ibv_device **dev_list;
int num_devices, i;
dev_list = ibv_get_device_list(&num_devices);
if (!dev_list) {
perror("Failed to get IB devices list");
return 1;
}
printf(" %-16s\t node GUID\n", "device");
printf(" %-16s\t----------------\n", "------");
for (i = 0; i < num_devices; ++i) {
printf(" %-16s\t%016llx\n",
ibv_get_device_name(dev_list[i]),
(unsigned long long) ntohll(ibv_get_device_guid(dev_list[i])));
}
ibv_free_device_list(dev_list);
return 0;
}

View File

@ -0,0 +1,450 @@
/*
* Copyright (c) 2005 Cisco Systems. All rights reserved.
* Copyright (c) 2005 Mellanox Technologies Ltd. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#if HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <getopt.h>
#include <netinet/in.h>
#include <endian.h>
#include <byteswap.h>
#include <infiniband/verbs.h>
#include <infiniband/driver.h>
#include <infiniband/arch.h>
static int verbose;
static int null_gid(union ibv_gid *gid)
{
return !(gid->raw[8] | gid->raw[9] | gid->raw[10] | gid->raw[11] |
gid->raw[12] | gid->raw[13] | gid->raw[14] | gid->raw[15]);
}
static const char *guid_str(uint64_t node_guid, char *str)
{
node_guid = ntohll(node_guid);
sprintf(str, "%04x:%04x:%04x:%04x",
(unsigned) (node_guid >> 48) & 0xffff,
(unsigned) (node_guid >> 32) & 0xffff,
(unsigned) (node_guid >> 16) & 0xffff,
(unsigned) (node_guid >> 0) & 0xffff);
return str;
}
static const char *transport_str(enum ibv_transport_type transport)
{
switch (transport) {
case IBV_TRANSPORT_IB: return "InfiniBand";
case IBV_TRANSPORT_IWARP: return "iWARP";
default: return "invalid transport";
}
}
static const char *port_state_str(enum ibv_port_state pstate)
{
switch (pstate) {
case IBV_PORT_DOWN: return "PORT_DOWN";
case IBV_PORT_INIT: return "PORT_INIT";
case IBV_PORT_ARMED: return "PORT_ARMED";
case IBV_PORT_ACTIVE: return "PORT_ACTIVE";
default: return "invalid state";
}
}
static const char *port_phy_state_str(uint8_t phys_state)
{
switch (phys_state) {
case 1: return "SLEEP";
case 2: return "POLLING";
case 3: return "DISABLED";
case 4: return "PORT_CONFIGURATION TRAINNING";
case 5: return "LINK_UP";
case 6: return "LINK_ERROR_RECOVERY";
case 7: return "PHY TEST";
default: return "invalid physical state";
}
}
static const char *atomic_cap_str(enum ibv_atomic_cap atom_cap)
{
switch (atom_cap) {
case IBV_ATOMIC_NONE: return "ATOMIC_NONE";
case IBV_ATOMIC_HCA: return "ATOMIC_HCA";
case IBV_ATOMIC_GLOB: return "ATOMIC_GLOB";
default: return "invalid atomic capability";
}
}
static const char *mtu_str(enum ibv_mtu max_mtu)
{
switch (max_mtu) {
case IBV_MTU_256: return "256";
case IBV_MTU_512: return "512";
case IBV_MTU_1024: return "1024";
case IBV_MTU_2048: return "2048";
case IBV_MTU_4096: return "4096";
default: return "invalid MTU";
}
}
static const char *width_str(uint8_t width)
{
switch (width) {
case 1: return "1";
case 2: return "4";
case 4: return "8";
case 8: return "12";
default: return "invalid width";
}
}
static const char *speed_str(uint8_t speed)
{
switch (speed) {
case 1: return "2.5 Gbps";
case 2: return "5.0 Gbps";
case 4: return "10.0 Gbps";
default: return "invalid speed";
}
}
static const char *vl_str(uint8_t vl_num)
{
switch (vl_num) {
case 1: return "1";
case 2: return "2";
case 3: return "4";
case 4: return "8";
case 5: return "15";
default: return "invalid value";
}
}
static int print_all_port_gids(struct ibv_context *ctx, uint8_t port_num, int tbl_len)
{
union ibv_gid gid;
int rc = 0;
int i;
for (i = 0; i < tbl_len; i++) {
rc = ibv_query_gid(ctx, port_num, i, &gid);
if (rc) {
fprintf(stderr, "Failed to query gid to port %d, index %d\n",
port_num, i);
return rc;
}
if (!null_gid(&gid))
printf("\t\t\tGID[%3d]:\t\t%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
i,
gid.raw[ 0], gid.raw[ 1],
gid.raw[ 2], gid.raw[ 3],
gid.raw[ 4], gid.raw[ 5],
gid.raw[ 6], gid.raw[ 7],
gid.raw[ 8], gid.raw[ 9],
gid.raw[10], gid.raw[11],
gid.raw[12], gid.raw[13],
gid.raw[14], gid.raw[15]);
}
return rc;
}
static const char *link_layer_str(uint8_t link_layer)
{
switch (link_layer) {
case IBV_LINK_LAYER_UNSPECIFIED:
case IBV_LINK_LAYER_INFINIBAND:
return "IB";
case IBV_LINK_LAYER_ETHERNET:
return "Ethernet";
default:
return "Unknown";
}
}
static int print_hca_cap(struct ibv_device *ib_dev, uint8_t ib_port)
{
struct ibv_context *ctx;
struct ibv_device_attr device_attr;
struct ibv_port_attr port_attr;
int rc = 0;
uint8_t port;
char buf[256];
ctx = ibv_open_device(ib_dev);
if (!ctx) {
fprintf(stderr, "Failed to open device\n");
rc = 1;
goto cleanup;
}
if (ibv_query_device(ctx, &device_attr)) {
fprintf(stderr, "Failed to query device props");
rc = 2;
goto cleanup;
}
printf("hca_id:\t%s\n", ibv_get_device_name(ib_dev));
printf("\ttransport:\t\t\t%s (%d)\n",
transport_str(ib_dev->transport_type), ib_dev->transport_type);
if (strlen(device_attr.fw_ver))
printf("\tfw_ver:\t\t\t\t%s\n", device_attr.fw_ver);
printf("\tnode_guid:\t\t\t%s\n", guid_str(device_attr.node_guid, buf));
printf("\tsys_image_guid:\t\t\t%s\n", guid_str(device_attr.sys_image_guid, buf));
printf("\tvendor_id:\t\t\t0x%04x\n", device_attr.vendor_id);
printf("\tvendor_part_id:\t\t\t%d\n", device_attr.vendor_part_id);
printf("\thw_ver:\t\t\t\t0x%X\n", device_attr.hw_ver);
if (ibv_read_sysfs_file(ib_dev->ibdev_path, "board_id", buf, sizeof buf) > 0)
printf("\tboard_id:\t\t\t%s\n", buf);
printf("\tphys_port_cnt:\t\t\t%d\n", device_attr.phys_port_cnt);
if (verbose) {
printf("\tmax_mr_size:\t\t\t0x%llx\n",
(unsigned long long) device_attr.max_mr_size);
printf("\tpage_size_cap:\t\t\t0x%llx\n",
(unsigned long long) device_attr.page_size_cap);
printf("\tmax_qp:\t\t\t\t%d\n", device_attr.max_qp);
printf("\tmax_qp_wr:\t\t\t%d\n", device_attr.max_qp_wr);
printf("\tdevice_cap_flags:\t\t0x%08x\n", device_attr.device_cap_flags);
printf("\tmax_sge:\t\t\t%d\n", device_attr.max_sge);
printf("\tmax_sge_rd:\t\t\t%d\n", device_attr.max_sge_rd);
printf("\tmax_cq:\t\t\t\t%d\n", device_attr.max_cq);
printf("\tmax_cqe:\t\t\t%d\n", device_attr.max_cqe);
printf("\tmax_mr:\t\t\t\t%d\n", device_attr.max_mr);
printf("\tmax_pd:\t\t\t\t%d\n", device_attr.max_pd);
printf("\tmax_qp_rd_atom:\t\t\t%d\n", device_attr.max_qp_rd_atom);
printf("\tmax_ee_rd_atom:\t\t\t%d\n", device_attr.max_ee_rd_atom);
printf("\tmax_res_rd_atom:\t\t%d\n", device_attr.max_res_rd_atom);
printf("\tmax_qp_init_rd_atom:\t\t%d\n", device_attr.max_qp_init_rd_atom);
printf("\tmax_ee_init_rd_atom:\t\t%d\n", device_attr.max_ee_init_rd_atom);
printf("\tatomic_cap:\t\t\t%s (%d)\n",
atomic_cap_str(device_attr.atomic_cap), device_attr.atomic_cap);
printf("\tmax_ee:\t\t\t\t%d\n", device_attr.max_ee);
printf("\tmax_rdd:\t\t\t%d\n", device_attr.max_rdd);
printf("\tmax_mw:\t\t\t\t%d\n", device_attr.max_mw);
printf("\tmax_raw_ipv6_qp:\t\t%d\n", device_attr.max_raw_ipv6_qp);
printf("\tmax_raw_ethy_qp:\t\t%d\n", device_attr.max_raw_ethy_qp);
printf("\tmax_mcast_grp:\t\t\t%d\n", device_attr.max_mcast_grp);
printf("\tmax_mcast_qp_attach:\t\t%d\n", device_attr.max_mcast_qp_attach);
printf("\tmax_total_mcast_qp_attach:\t%d\n",
device_attr.max_total_mcast_qp_attach);
printf("\tmax_ah:\t\t\t\t%d\n", device_attr.max_ah);
printf("\tmax_fmr:\t\t\t%d\n", device_attr.max_fmr);
if (device_attr.max_fmr)
printf("\tmax_map_per_fmr:\t\t%d\n", device_attr.max_map_per_fmr);
printf("\tmax_srq:\t\t\t%d\n", device_attr.max_srq);
if (device_attr.max_srq) {
printf("\tmax_srq_wr:\t\t\t%d\n", device_attr.max_srq_wr);
printf("\tmax_srq_sge:\t\t\t%d\n", device_attr.max_srq_sge);
}
printf("\tmax_pkeys:\t\t\t%d\n", device_attr.max_pkeys);
printf("\tlocal_ca_ack_delay:\t\t%d\n", device_attr.local_ca_ack_delay);
}
for (port = 1; port <= device_attr.phys_port_cnt; ++port) {
/* if in the command line the user didn't ask for info about this port */
if ((ib_port) && (port != ib_port))
continue;
rc = ibv_query_port(ctx, port, &port_attr);
if (rc) {
fprintf(stderr, "Failed to query port %u props\n", port);
goto cleanup;
}
printf("\t\tport:\t%d\n", port);
printf("\t\t\tstate:\t\t\t%s (%d)\n",
port_state_str(port_attr.state), port_attr.state);
printf("\t\t\tmax_mtu:\t\t%s (%d)\n",
mtu_str(port_attr.max_mtu), port_attr.max_mtu);
printf("\t\t\tactive_mtu:\t\t%s (%d)\n",
mtu_str(port_attr.active_mtu), port_attr.active_mtu);
printf("\t\t\tsm_lid:\t\t\t%d\n", port_attr.sm_lid);
printf("\t\t\tport_lid:\t\t%d\n", port_attr.lid);
printf("\t\t\tport_lmc:\t\t0x%02x\n", port_attr.lmc);
printf("\t\t\tlink_layer:\t\t%s\n", link_layer_str(port_attr.link_layer));
if (verbose) {
printf("\t\t\tmax_msg_sz:\t\t0x%x\n", port_attr.max_msg_sz);
printf("\t\t\tport_cap_flags:\t\t0x%08x\n", port_attr.port_cap_flags);
printf("\t\t\tmax_vl_num:\t\t%s (%d)\n",
vl_str(port_attr.max_vl_num), port_attr.max_vl_num);
printf("\t\t\tbad_pkey_cntr:\t\t0x%x\n", port_attr.bad_pkey_cntr);
printf("\t\t\tqkey_viol_cntr:\t\t0x%x\n", port_attr.qkey_viol_cntr);
printf("\t\t\tsm_sl:\t\t\t%d\n", port_attr.sm_sl);
printf("\t\t\tpkey_tbl_len:\t\t%d\n", port_attr.pkey_tbl_len);
printf("\t\t\tgid_tbl_len:\t\t%d\n", port_attr.gid_tbl_len);
printf("\t\t\tsubnet_timeout:\t\t%d\n", port_attr.subnet_timeout);
printf("\t\t\tinit_type_reply:\t%d\n", port_attr.init_type_reply);
printf("\t\t\tactive_width:\t\t%sX (%d)\n",
width_str(port_attr.active_width), port_attr.active_width);
printf("\t\t\tactive_speed:\t\t%s (%d)\n",
speed_str(port_attr.active_speed), port_attr.active_speed);
printf("\t\t\tphys_state:\t\t%s (%d)\n",
port_phy_state_str(port_attr.phys_state), port_attr.phys_state);
if (print_all_port_gids(ctx, port, port_attr.gid_tbl_len))
goto cleanup;
}
printf("\n");
}
cleanup:
if (ctx)
if (ibv_close_device(ctx)) {
fprintf(stderr, "Failed to close device");
rc = 3;
}
return rc;
}
static void usage(const char *argv0)
{
printf("Usage: %s print the ca attributes\n", argv0);
printf("\n");
printf("Options:\n");
printf(" -d, --ib-dev=<dev> use IB device <dev> (default first device found)\n");
printf(" -i, --ib-port=<port> use port <port> of IB device (default all ports)\n");
printf(" -l, --list print only the IB devices names\n");
printf(" -v, --verbose print all the attributes of the IB device(s)\n");
}
int main(int argc, char *argv[])
{
char *ib_devname = NULL;
int ret = 0;
struct ibv_device **dev_list, **orig_dev_list;
int num_of_hcas;
int ib_port = 0;
/* parse command line options */
while (1) {
int c;
static struct option long_options[] = {
{ .name = "ib-dev", .has_arg = 1, .val = 'd' },
{ .name = "ib-port", .has_arg = 1, .val = 'i' },
{ .name = "list", .has_arg = 0, .val = 'l' },
{ .name = "verbose", .has_arg = 0, .val = 'v' },
{ 0, 0, 0, 0}
};
c = getopt_long(argc, argv, "d:i:lv", long_options, NULL);
if (c == -1)
break;
switch (c) {
case 'd':
ib_devname = strdup(optarg);
break;
case 'i':
ib_port = strtol(optarg, NULL, 0);
if (ib_port < 0) {
usage(argv[0]);
return 1;
}
break;
case 'v':
verbose = 1;
break;
case 'l':
dev_list = orig_dev_list = ibv_get_device_list(&num_of_hcas);
if (!dev_list) {
perror("Failed to get IB devices list");
return -1;
}
printf("%d HCA%s found:\n", num_of_hcas,
num_of_hcas != 1 ? "s" : "");
while (*dev_list) {
printf("\t%s\n", ibv_get_device_name(*dev_list));
++dev_list;
}
printf("\n");
ibv_free_device_list(orig_dev_list);
return 0;
default:
usage(argv[0]);
return -1;
}
}
dev_list = orig_dev_list = ibv_get_device_list(NULL);
if (!dev_list) {
perror("Failed to get IB devices list");
return -1;
}
if (ib_devname) {
while (*dev_list) {
if (!strcmp(ibv_get_device_name(*dev_list), ib_devname))
break;
++dev_list;
}
if (!*dev_list) {
fprintf(stderr, "IB device '%s' wasn't found\n", ib_devname);
return -1;
}
ret |= print_hca_cap(*dev_list, ib_port);
} else {
if (!*dev_list) {
fprintf(stderr, "No IB devices found\n");
return -1;
}
while (*dev_list) {
ret |= print_hca_cap(*dev_list, ib_port);
++dev_list;
}
}
if (ib_devname)
free(ib_devname);
ibv_free_device_list(orig_dev_list);
return ret;
}

View File

@ -0,0 +1,86 @@
/*
* Copyright (c) 2006 Cisco Systems. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "pingpong.h"
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
enum ibv_mtu pp_mtu_to_enum(int mtu)
{
switch (mtu) {
case 256: return IBV_MTU_256;
case 512: return IBV_MTU_512;
case 1024: return IBV_MTU_1024;
case 2048: return IBV_MTU_2048;
case 4096: return IBV_MTU_4096;
default: return -1;
}
}
uint16_t pp_get_local_lid(struct ibv_context *context, int port)
{
struct ibv_port_attr attr;
if (ibv_query_port(context, port, &attr))
return 0;
return attr.lid;
}
int pp_get_port_info(struct ibv_context *context, int port,
struct ibv_port_attr *attr)
{
return ibv_query_port(context, port, attr);
}
void wire_gid_to_gid(const char *wgid, union ibv_gid *gid)
{
char tmp[9];
uint32_t v32;
int i;
for (tmp[8] = 0, i = 0; i < 4; ++i) {
memcpy(tmp, wgid + i * 8, 8);
sscanf(tmp, "%x", &v32);
*(uint32_t *)(&gid->raw[i * 4]) = ntohl(v32);
}
}
void gid_to_wire_gid(const union ibv_gid *gid, char wgid[])
{
int i;
for (i = 0; i < 4; ++i)
sprintf(&wgid[i * 8], "%08x", htonl(*(uint32_t *)(gid->raw + i * 4)));
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2006 Cisco Systems. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef IBV_PINGPONG_H
#define IBV_PINGPONG_H
#include <sys/param.h>
#include <infiniband/verbs.h>
enum ibv_mtu pp_mtu_to_enum(int mtu);
uint16_t pp_get_local_lid(struct ibv_context *context, int port);
int pp_get_port_info(struct ibv_context *context, int port,
struct ibv_port_attr *attr);
void wire_gid_to_gid(const char *wgid, union ibv_gid *gid);
void gid_to_wire_gid(const union ibv_gid *gid, char wgid[]);
#endif /* IBV_PINGPONG_H */

View File

@ -0,0 +1,827 @@
/*
* Copyright (c) 2005 Topspin Communications. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#if HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netdb.h>
#include <stdlib.h>
#include <getopt.h>
#include <arpa/inet.h>
#include <time.h>
#include "pingpong.h"
enum {
PINGPONG_RECV_WRID = 1,
PINGPONG_SEND_WRID = 2,
};
static int page_size;
struct pingpong_context {
struct ibv_context *context;
struct ibv_comp_channel *channel;
struct ibv_pd *pd;
struct ibv_mr *mr;
struct ibv_cq *cq;
struct ibv_qp *qp;
void *buf;
int size;
int rx_depth;
int pending;
struct ibv_port_attr portinfo;
};
struct pingpong_dest {
int lid;
int qpn;
int psn;
union ibv_gid gid;
};
static int pp_connect_ctx(struct pingpong_context *ctx, int port, int my_psn,
enum ibv_mtu mtu, int sl,
struct pingpong_dest *dest, int sgid_idx)
{
struct ibv_qp_attr attr = {
.qp_state = IBV_QPS_RTR,
.path_mtu = mtu,
.dest_qp_num = dest->qpn,
.rq_psn = dest->psn,
.max_dest_rd_atomic = 1,
.min_rnr_timer = 12,
.ah_attr = {
.is_global = 0,
.dlid = dest->lid,
.sl = sl,
.src_path_bits = 0,
.port_num = port
}
};
if (dest->gid.global.interface_id) {
attr.ah_attr.is_global = 1;
attr.ah_attr.grh.hop_limit = 1;
attr.ah_attr.grh.dgid = dest->gid;
attr.ah_attr.grh.sgid_index = sgid_idx;
}
if (ibv_modify_qp(ctx->qp, &attr,
IBV_QP_STATE |
IBV_QP_AV |
IBV_QP_PATH_MTU |
IBV_QP_DEST_QPN |
IBV_QP_RQ_PSN |
IBV_QP_MAX_DEST_RD_ATOMIC |
IBV_QP_MIN_RNR_TIMER)) {
fprintf(stderr, "Failed to modify QP to RTR\n");
return 1;
}
attr.qp_state = IBV_QPS_RTS;
attr.timeout = 14;
attr.retry_cnt = 7;
attr.rnr_retry = 7;
attr.sq_psn = my_psn;
attr.max_rd_atomic = 1;
if (ibv_modify_qp(ctx->qp, &attr,
IBV_QP_STATE |
IBV_QP_TIMEOUT |
IBV_QP_RETRY_CNT |
IBV_QP_RNR_RETRY |
IBV_QP_SQ_PSN |
IBV_QP_MAX_QP_RD_ATOMIC)) {
fprintf(stderr, "Failed to modify QP to RTS\n");
return 1;
}
return 0;
}
static struct pingpong_dest *pp_client_exch_dest(const char *servername, int port,
const struct pingpong_dest *my_dest)
{
struct addrinfo *res, *t;
struct addrinfo hints = {
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM
};
char *service;
char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"];
int n;
int sockfd = -1;
struct pingpong_dest *rem_dest = NULL;
char gid[33];
if (asprintf(&service, "%d", port) < 0)
return NULL;
n = getaddrinfo(servername, service, &hints, &res);
if (n < 0) {
fprintf(stderr, "%s for %s:%d\n", gai_strerror(n), servername, port);
free(service);
return NULL;
}
for (t = res; t; t = t->ai_next) {
sockfd = socket(t->ai_family, t->ai_socktype, t->ai_protocol);
if (sockfd >= 0) {
if (!connect(sockfd, t->ai_addr, t->ai_addrlen))
break;
close(sockfd);
sockfd = -1;
}
}
freeaddrinfo(res);
free(service);
if (sockfd < 0) {
fprintf(stderr, "Couldn't connect to %s:%d\n", servername, port);
return NULL;
}
gid_to_wire_gid(&my_dest->gid, gid);
sprintf(msg, "%04x:%06x:%06x:%s", my_dest->lid, my_dest->qpn, my_dest->psn, gid);
if (write(sockfd, msg, sizeof msg) != sizeof msg) {
fprintf(stderr, "Couldn't send local address\n");
goto out;
}
if (read(sockfd, msg, sizeof msg) != sizeof msg) {
perror("client read");
fprintf(stderr, "Couldn't read remote address\n");
goto out;
}
write(sockfd, "done", sizeof "done");
rem_dest = malloc(sizeof *rem_dest);
if (!rem_dest)
goto out;
sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn, gid);
wire_gid_to_gid(gid, &rem_dest->gid);
out:
close(sockfd);
return rem_dest;
}
static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx,
int ib_port, enum ibv_mtu mtu,
int port, int sl,
const struct pingpong_dest *my_dest,
int sgid_idx)
{
struct addrinfo *res, *t;
struct addrinfo hints = {
.ai_flags = AI_PASSIVE,
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM
};
char *service;
char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"];
int n;
int sockfd = -1, connfd;
struct pingpong_dest *rem_dest = NULL;
char gid[33];
if (asprintf(&service, "%d", port) < 0)
return NULL;
n = getaddrinfo(NULL, service, &hints, &res);
if (n < 0) {
fprintf(stderr, "%s for port %d\n", gai_strerror(n), port);
free(service);
return NULL;
}
for (t = res; t; t = t->ai_next) {
sockfd = socket(t->ai_family, t->ai_socktype, t->ai_protocol);
if (sockfd >= 0) {
n = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof n);
if (!bind(sockfd, t->ai_addr, t->ai_addrlen))
break;
close(sockfd);
sockfd = -1;
}
}
freeaddrinfo(res);
free(service);
if (sockfd < 0) {
fprintf(stderr, "Couldn't listen to port %d\n", port);
return NULL;
}
listen(sockfd, 1);
connfd = accept(sockfd, NULL, 0);
close(sockfd);
if (connfd < 0) {
fprintf(stderr, "accept() failed\n");
return NULL;
}
n = read(connfd, msg, sizeof msg);
if (n != sizeof msg) {
perror("server read");
fprintf(stderr, "%d/%d: Couldn't read remote address\n", n, (int) sizeof msg);
goto out;
}
rem_dest = malloc(sizeof *rem_dest);
if (!rem_dest)
goto out;
sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn, gid);
wire_gid_to_gid(gid, &rem_dest->gid);
if (pp_connect_ctx(ctx, ib_port, my_dest->psn, mtu, sl, rem_dest, sgid_idx)) {
fprintf(stderr, "Couldn't connect to remote QP\n");
free(rem_dest);
rem_dest = NULL;
goto out;
}
gid_to_wire_gid(&my_dest->gid, gid);
sprintf(msg, "%04x:%06x:%06x:%s", my_dest->lid, my_dest->qpn, my_dest->psn, gid);
if (write(connfd, msg, sizeof msg) != sizeof msg) {
fprintf(stderr, "Couldn't send local address\n");
free(rem_dest);
rem_dest = NULL;
goto out;
}
read(connfd, msg, sizeof msg);
out:
close(connfd);
return rem_dest;
}
#include <sys/param.h>
static struct pingpong_context *pp_init_ctx(struct ibv_device *ib_dev, int size,
int rx_depth, int port,
int use_event, int is_server)
{
struct pingpong_context *ctx;
ctx = calloc(1, sizeof *ctx);
if (!ctx)
return NULL;
ctx->size = size;
ctx->rx_depth = rx_depth;
ctx->buf = malloc(roundup(size, page_size));
if (!ctx->buf) {
fprintf(stderr, "Couldn't allocate work buf.\n");
return NULL;
}
memset(ctx->buf, 0x7b + is_server, size);
ctx->context = ibv_open_device(ib_dev);
if (!ctx->context) {
fprintf(stderr, "Couldn't get context for %s\n",
ibv_get_device_name(ib_dev));
return NULL;
}
if (use_event) {
ctx->channel = ibv_create_comp_channel(ctx->context);
if (!ctx->channel) {
fprintf(stderr, "Couldn't create completion channel\n");
return NULL;
}
} else
ctx->channel = NULL;
ctx->pd = ibv_alloc_pd(ctx->context);
if (!ctx->pd) {
fprintf(stderr, "Couldn't allocate PD\n");
return NULL;
}
ctx->mr = ibv_reg_mr(ctx->pd, ctx->buf, size, IBV_ACCESS_LOCAL_WRITE);
if (!ctx->mr) {
fprintf(stderr, "Couldn't register MR\n");
return NULL;
}
ctx->cq = ibv_create_cq(ctx->context, rx_depth + 1, NULL,
ctx->channel, 0);
if (!ctx->cq) {
fprintf(stderr, "Couldn't create CQ\n");
return NULL;
}
{
struct ibv_qp_init_attr attr = {
.send_cq = ctx->cq,
.recv_cq = ctx->cq,
.cap = {
.max_send_wr = 1,
.max_recv_wr = rx_depth,
.max_send_sge = 1,
.max_recv_sge = 1
},
.qp_type = IBV_QPT_RC
};
ctx->qp = ibv_create_qp(ctx->pd, &attr);
if (!ctx->qp) {
fprintf(stderr, "Couldn't create QP\n");
return NULL;
}
}
{
struct ibv_qp_attr attr = {
.qp_state = IBV_QPS_INIT,
.pkey_index = 0,
.port_num = port,
.qp_access_flags = 0
};
if (ibv_modify_qp(ctx->qp, &attr,
IBV_QP_STATE |
IBV_QP_PKEY_INDEX |
IBV_QP_PORT |
IBV_QP_ACCESS_FLAGS)) {
fprintf(stderr, "Failed to modify QP to INIT\n");
return NULL;
}
}
return ctx;
}
int pp_close_ctx(struct pingpong_context *ctx)
{
if (ibv_destroy_qp(ctx->qp)) {
fprintf(stderr, "Couldn't destroy QP\n");
return 1;
}
if (ibv_destroy_cq(ctx->cq)) {
fprintf(stderr, "Couldn't destroy CQ\n");
return 1;
}
if (ibv_dereg_mr(ctx->mr)) {
fprintf(stderr, "Couldn't deregister MR\n");
return 1;
}
if (ibv_dealloc_pd(ctx->pd)) {
fprintf(stderr, "Couldn't deallocate PD\n");
return 1;
}
if (ctx->channel) {
if (ibv_destroy_comp_channel(ctx->channel)) {
fprintf(stderr, "Couldn't destroy completion channel\n");
return 1;
}
}
if (ibv_close_device(ctx->context)) {
fprintf(stderr, "Couldn't release context\n");
return 1;
}
free(ctx->buf);
free(ctx);
return 0;
}
static int pp_post_recv(struct pingpong_context *ctx, int n)
{
struct ibv_sge list = {
.addr = (uintptr_t) ctx->buf,
.length = ctx->size,
.lkey = ctx->mr->lkey
};
struct ibv_recv_wr wr = {
.wr_id = PINGPONG_RECV_WRID,
.sg_list = &list,
.num_sge = 1,
};
struct ibv_recv_wr *bad_wr;
int i;
for (i = 0; i < n; ++i)
if (ibv_post_recv(ctx->qp, &wr, &bad_wr))
break;
return i;
}
static int pp_post_send(struct pingpong_context *ctx)
{
struct ibv_sge list = {
.addr = (uintptr_t) ctx->buf,
.length = ctx->size,
.lkey = ctx->mr->lkey
};
struct ibv_send_wr wr = {
.wr_id = PINGPONG_SEND_WRID,
.sg_list = &list,
.num_sge = 1,
.opcode = IBV_WR_SEND,
.send_flags = IBV_SEND_SIGNALED,
};
struct ibv_send_wr *bad_wr;
return ibv_post_send(ctx->qp, &wr, &bad_wr);
}
static void usage(const char *argv0)
{
printf("Usage:\n");
printf(" %s start a server and wait for connection\n", argv0);
printf(" %s <host> connect to server at <host>\n", argv0);
printf("\n");
printf("Options:\n");
printf(" -p, --port=<port> listen on/connect to port <port> (default 18515)\n");
printf(" -d, --ib-dev=<dev> use IB device <dev> (default first device found)\n");
printf(" -i, --ib-port=<port> use port <port> of IB device (default 1)\n");
printf(" -s, --size=<size> size of message to exchange (default 4096)\n");
printf(" -m, --mtu=<size> path MTU (default 1024)\n");
printf(" -r, --rx-depth=<dep> number of receives to post at a time (default 500)\n");
printf(" -n, --iters=<iters> number of exchanges (default 1000)\n");
printf(" -l, --sl=<sl> service level value\n");
printf(" -e, --events sleep on CQ events (default poll)\n");
printf(" -g, --gid-idx=<gid index> local port gid index\n");
}
int main(int argc, char *argv[])
{
struct ibv_device **dev_list;
struct ibv_device *ib_dev;
struct pingpong_context *ctx;
struct pingpong_dest my_dest;
struct pingpong_dest *rem_dest;
struct timeval start, end;
char *ib_devname = NULL;
char *servername = NULL;
int port = 18515;
int ib_port = 1;
int size = 4096;
enum ibv_mtu mtu = IBV_MTU_1024;
int rx_depth = 500;
int iters = 1000;
int use_event = 0;
int routs;
int rcnt, scnt;
int num_cq_events = 0;
int sl = 0;
int gidx = -1;
char gid[33];
srand48(getpid() * time(NULL));
while (1) {
int c;
static struct option long_options[] = {
{ .name = "port", .has_arg = 1, .val = 'p' },
{ .name = "ib-dev", .has_arg = 1, .val = 'd' },
{ .name = "ib-port", .has_arg = 1, .val = 'i' },
{ .name = "size", .has_arg = 1, .val = 's' },
{ .name = "mtu", .has_arg = 1, .val = 'm' },
{ .name = "rx-depth", .has_arg = 1, .val = 'r' },
{ .name = "iters", .has_arg = 1, .val = 'n' },
{ .name = "sl", .has_arg = 1, .val = 'l' },
{ .name = "events", .has_arg = 0, .val = 'e' },
{ .name = "gid-idx", .has_arg = 1, .val = 'g' },
{ 0 }
};
c = getopt_long(argc, argv, "p:d:i:s:m:r:n:l:eg:", long_options, NULL);
if (c == -1)
break;
switch (c) {
case 'p':
port = strtol(optarg, NULL, 0);
if (port < 0 || port > 65535) {
usage(argv[0]);
return 1;
}
break;
case 'd':
ib_devname = strdup(optarg);
break;
case 'i':
ib_port = strtol(optarg, NULL, 0);
if (ib_port < 0) {
usage(argv[0]);
return 1;
}
break;
case 's':
size = strtol(optarg, NULL, 0);
break;
case 'm':
mtu = pp_mtu_to_enum(strtol(optarg, NULL, 0));
if (mtu < 0) {
usage(argv[0]);
return 1;
}
break;
case 'r':
rx_depth = strtol(optarg, NULL, 0);
break;
case 'n':
iters = strtol(optarg, NULL, 0);
break;
case 'l':
sl = strtol(optarg, NULL, 0);
break;
case 'e':
++use_event;
break;
case 'g':
gidx = strtol(optarg, NULL, 0);
break;
default:
usage(argv[0]);
return 1;
}
}
if (optind == argc - 1)
servername = strdup(argv[optind]);
else if (optind < argc) {
usage(argv[0]);
return 1;
}
page_size = sysconf(_SC_PAGESIZE);
dev_list = ibv_get_device_list(NULL);
if (!dev_list) {
perror("Failed to get IB devices list");
return 1;
}
if (!ib_devname) {
ib_dev = *dev_list;
if (!ib_dev) {
fprintf(stderr, "No IB devices found\n");
return 1;
}
} else {
int i;
for (i = 0; dev_list[i]; ++i)
if (!strcmp(ibv_get_device_name(dev_list[i]), ib_devname))
break;
ib_dev = dev_list[i];
if (!ib_dev) {
fprintf(stderr, "IB device %s not found\n", ib_devname);
return 1;
}
}
ctx = pp_init_ctx(ib_dev, size, rx_depth, ib_port, use_event, !servername);
if (!ctx)
return 1;
routs = pp_post_recv(ctx, ctx->rx_depth);
if (routs < ctx->rx_depth) {
fprintf(stderr, "Couldn't post receive (%d)\n", routs);
return 1;
}
if (use_event)
if (ibv_req_notify_cq(ctx->cq, 0)) {
fprintf(stderr, "Couldn't request CQ notification\n");
return 1;
}
if (pp_get_port_info(ctx->context, ib_port, &ctx->portinfo)) {
fprintf(stderr, "Couldn't get port info\n");
return 1;
}
my_dest.lid = ctx->portinfo.lid;
if (ctx->portinfo.link_layer == IBV_LINK_LAYER_INFINIBAND && !my_dest.lid) {
fprintf(stderr, "Couldn't get local LID\n");
return 1;
}
if (gidx >= 0) {
if (ibv_query_gid(ctx->context, ib_port, gidx, &my_dest.gid)) {
fprintf(stderr, "Could not get local gid for gid index %d\n", gidx);
return 1;
}
} else
memset(&my_dest.gid, 0, sizeof my_dest.gid);
my_dest.qpn = ctx->qp->qp_num;
my_dest.psn = lrand48() & 0xffffff;
inet_ntop(AF_INET6, &my_dest.gid, gid, sizeof gid);
printf(" local address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x, GID %s\n",
my_dest.lid, my_dest.qpn, my_dest.psn, gid);
if (servername)
rem_dest = pp_client_exch_dest(servername, port, &my_dest);
else
rem_dest = pp_server_exch_dest(ctx, ib_port, mtu, port, sl, &my_dest, gidx);
if (!rem_dest)
return 1;
inet_ntop(AF_INET6, &rem_dest->gid, gid, sizeof gid);
printf(" remote address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x, GID %s\n",
rem_dest->lid, rem_dest->qpn, rem_dest->psn, gid);
if (servername)
if (pp_connect_ctx(ctx, ib_port, my_dest.psn, mtu, sl, rem_dest, gidx))
return 1;
ctx->pending = PINGPONG_RECV_WRID;
if (servername) {
if (pp_post_send(ctx)) {
fprintf(stderr, "Couldn't post send\n");
return 1;
}
ctx->pending |= PINGPONG_SEND_WRID;
}
if (gettimeofday(&start, NULL)) {
perror("gettimeofday");
return 1;
}
rcnt = scnt = 0;
while (rcnt < iters || scnt < iters) {
if (use_event) {
struct ibv_cq *ev_cq;
void *ev_ctx;
if (ibv_get_cq_event(ctx->channel, &ev_cq, &ev_ctx)) {
fprintf(stderr, "Failed to get cq_event\n");
return 1;
}
++num_cq_events;
if (ev_cq != ctx->cq) {
fprintf(stderr, "CQ event for unknown CQ %p\n", ev_cq);
return 1;
}
if (ibv_req_notify_cq(ctx->cq, 0)) {
fprintf(stderr, "Couldn't request CQ notification\n");
return 1;
}
}
{
struct ibv_wc wc[2];
int ne, i;
do {
ne = ibv_poll_cq(ctx->cq, 2, wc);
if (ne < 0) {
fprintf(stderr, "poll CQ failed %d\n", ne);
return 1;
}
} while (!use_event && ne < 1);
for (i = 0; i < ne; ++i) {
if (wc[i].status != IBV_WC_SUCCESS) {
fprintf(stderr, "Failed status %s (%d) for wr_id %d\n",
ibv_wc_status_str(wc[i].status),
wc[i].status, (int) wc[i].wr_id);
return 1;
}
switch ((int) wc[i].wr_id) {
case PINGPONG_SEND_WRID:
++scnt;
break;
case PINGPONG_RECV_WRID:
if (--routs <= 1) {
routs += pp_post_recv(ctx, ctx->rx_depth - routs);
if (routs < ctx->rx_depth) {
fprintf(stderr,
"Couldn't post receive (%d)\n",
routs);
return 1;
}
}
++rcnt;
break;
default:
fprintf(stderr, "Completion for unknown wr_id %d\n",
(int) wc[i].wr_id);
return 1;
}
ctx->pending &= ~(int) wc[i].wr_id;
if (scnt < iters && !ctx->pending) {
if (pp_post_send(ctx)) {
fprintf(stderr, "Couldn't post send\n");
return 1;
}
ctx->pending = PINGPONG_RECV_WRID |
PINGPONG_SEND_WRID;
}
}
}
}
if (gettimeofday(&end, NULL)) {
perror("gettimeofday");
return 1;
}
{
float usec = (end.tv_sec - start.tv_sec) * 1000000 +
(end.tv_usec - start.tv_usec);
long long bytes = (long long) size * iters * 2;
printf("%lld bytes in %.2f seconds = %.2f Mbit/sec\n",
bytes, usec / 1000000., bytes * 8. / usec);
printf("%d iters in %.2f seconds = %.2f usec/iter\n",
iters, usec / 1000000., usec / iters);
}
ibv_ack_cq_events(ctx->cq, num_cq_events);
if (pp_close_ctx(ctx))
return 1;
ibv_free_device_list(dev_list);
free(rem_dest);
return 0;
}

View File

@ -0,0 +1,925 @@
/*
* Copyright (c) 2005 Topspin Communications. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#if HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netdb.h>
#include <getopt.h>
#include <arpa/inet.h>
#include <time.h>
#include "pingpong.h"
enum {
PINGPONG_RECV_WRID = 1,
PINGPONG_SEND_WRID = 2,
MAX_QP = 256,
};
static int page_size;
struct pingpong_context {
struct ibv_context *context;
struct ibv_comp_channel *channel;
struct ibv_pd *pd;
struct ibv_mr *mr;
struct ibv_cq *cq;
struct ibv_srq *srq;
struct ibv_qp *qp[MAX_QP];
void *buf;
int size;
int num_qp;
int rx_depth;
int pending[MAX_QP];
struct ibv_port_attr portinfo;
};
struct pingpong_dest {
int lid;
int qpn;
int psn;
union ibv_gid gid;
};
static int pp_connect_ctx(struct pingpong_context *ctx, int port, enum ibv_mtu mtu,
int sl, const struct pingpong_dest *my_dest,
const struct pingpong_dest *dest, int sgid_idx)
{
int i;
for (i = 0; i < ctx->num_qp; ++i) {
struct ibv_qp_attr attr = {
.qp_state = IBV_QPS_RTR,
.path_mtu = mtu,
.dest_qp_num = dest[i].qpn,
.rq_psn = dest[i].psn,
.max_dest_rd_atomic = 1,
.min_rnr_timer = 12,
.ah_attr = {
.is_global = 0,
.dlid = dest[i].lid,
.sl = sl,
.src_path_bits = 0,
.port_num = port
}
};
if (dest->gid.global.interface_id) {
attr.ah_attr.is_global = 1;
attr.ah_attr.grh.hop_limit = 1;
attr.ah_attr.grh.dgid = dest->gid;
attr.ah_attr.grh.sgid_index = sgid_idx;
}
if (ibv_modify_qp(ctx->qp[i], &attr,
IBV_QP_STATE |
IBV_QP_AV |
IBV_QP_PATH_MTU |
IBV_QP_DEST_QPN |
IBV_QP_RQ_PSN |
IBV_QP_MAX_DEST_RD_ATOMIC |
IBV_QP_MIN_RNR_TIMER)) {
fprintf(stderr, "Failed to modify QP[%d] to RTR\n", i);
return 1;
}
attr.qp_state = IBV_QPS_RTS;
attr.timeout = 14;
attr.retry_cnt = 7;
attr.rnr_retry = 7;
attr.sq_psn = my_dest[i].psn;
attr.max_rd_atomic = 1;
if (ibv_modify_qp(ctx->qp[i], &attr,
IBV_QP_STATE |
IBV_QP_TIMEOUT |
IBV_QP_RETRY_CNT |
IBV_QP_RNR_RETRY |
IBV_QP_SQ_PSN |
IBV_QP_MAX_QP_RD_ATOMIC)) {
fprintf(stderr, "Failed to modify QP[%d] to RTS\n", i);
return 1;
}
}
return 0;
}
static struct pingpong_dest *pp_client_exch_dest(const char *servername, int port,
const struct pingpong_dest *my_dest)
{
struct addrinfo *res, *t;
struct addrinfo hints = {
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM
};
char *service;
char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"];
int n;
int r;
int i;
int sockfd = -1;
struct pingpong_dest *rem_dest = NULL;
char gid[33];
if (asprintf(&service, "%d", port) < 0)
return NULL;
n = getaddrinfo(servername, service, &hints, &res);
if (n < 0) {
fprintf(stderr, "%s for %s:%d\n", gai_strerror(n), servername, port);
free(service);
return NULL;
}
for (t = res; t; t = t->ai_next) {
sockfd = socket(t->ai_family, t->ai_socktype, t->ai_protocol);
if (sockfd >= 0) {
if (!connect(sockfd, t->ai_addr, t->ai_addrlen))
break;
close(sockfd);
sockfd = -1;
}
}
freeaddrinfo(res);
free(service);
if (sockfd < 0) {
fprintf(stderr, "Couldn't connect to %s:%d\n", servername, port);
return NULL;
}
for (i = 0; i < MAX_QP; ++i) {
gid_to_wire_gid(&my_dest[i].gid, gid);
sprintf(msg, "%04x:%06x:%06x:%s", my_dest[i].lid, my_dest[i].qpn, my_dest[i].psn, gid);
if (write(sockfd, msg, sizeof msg) != sizeof msg) {
fprintf(stderr, "Couldn't send local address\n");
goto out;
}
}
rem_dest = malloc(MAX_QP * sizeof *rem_dest);
if (!rem_dest)
goto out;
for (i = 0; i < MAX_QP; ++i) {
n = 0;
while (n < sizeof msg) {
r = read(sockfd, msg + n, sizeof msg - n);
if (r < 0) {
perror("client read");
fprintf(stderr, "%d/%d: Couldn't read remote address [%d]\n",
n, (int) sizeof msg, i);
goto out;
}
n += r;
}
sscanf(msg, "%x:%x:%x:%s",
&rem_dest[i].lid, &rem_dest[i].qpn, &rem_dest[i].psn, gid);
wire_gid_to_gid(gid, &rem_dest[i].gid);
}
write(sockfd, "done", sizeof "done");
out:
close(sockfd);
return rem_dest;
}
static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx,
int ib_port, enum ibv_mtu mtu,
int port, int sl,
const struct pingpong_dest *my_dest,
int sgid_idx)
{
struct addrinfo *res, *t;
struct addrinfo hints = {
.ai_flags = AI_PASSIVE,
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM
};
char *service;
char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"];
int n;
int r;
int i;
int sockfd = -1, connfd;
struct pingpong_dest *rem_dest = NULL;
char gid[33];
if (asprintf(&service, "%d", port) < 0)
return NULL;
n = getaddrinfo(NULL, service, &hints, &res);
if (n < 0) {
fprintf(stderr, "%s for port %d\n", gai_strerror(n), port);
free(service);
return NULL;
}
for (t = res; t; t = t->ai_next) {
sockfd = socket(t->ai_family, t->ai_socktype, t->ai_protocol);
if (sockfd >= 0) {
n = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof n);
if (!bind(sockfd, t->ai_addr, t->ai_addrlen))
break;
close(sockfd);
sockfd = -1;
}
}
freeaddrinfo(res);
free(service);
if (sockfd < 0) {
fprintf(stderr, "Couldn't listen to port %d\n", port);
return NULL;
}
listen(sockfd, 1);
connfd = accept(sockfd, NULL, 0);
close(sockfd);
if (connfd < 0) {
fprintf(stderr, "accept() failed\n");
return NULL;
}
rem_dest = malloc(MAX_QP * sizeof *rem_dest);
if (!rem_dest)
goto out;
for (i = 0; i < MAX_QP; ++i) {
n = 0;
while (n < sizeof msg) {
r = read(connfd, msg + n, sizeof msg - n);
if (r < 0) {
perror("server read");
fprintf(stderr, "%d/%d: Couldn't read remote address [%d]\n",
n, (int) sizeof msg, i);
goto out;
}
n += r;
}
sscanf(msg, "%x:%x:%x:%s",
&rem_dest[i].lid, &rem_dest[i].qpn, &rem_dest[i].psn, gid);
wire_gid_to_gid(gid, &rem_dest[i].gid);
}
if (pp_connect_ctx(ctx, ib_port, mtu, sl, my_dest, rem_dest, sgid_idx)) {
fprintf(stderr, "Couldn't connect to remote QP\n");
free(rem_dest);
rem_dest = NULL;
goto out;
}
for (i = 0; i < MAX_QP; ++i) {
gid_to_wire_gid(&my_dest[i].gid, gid);
sprintf(msg, "%04x:%06x:%06x:%s", my_dest[i].lid, my_dest[i].qpn, my_dest[i].psn, gid);
if (write(connfd, msg, sizeof msg) != sizeof msg) {
fprintf(stderr, "Couldn't send local address\n");
free(rem_dest);
rem_dest = NULL;
goto out;
}
}
read(connfd, msg, sizeof msg);
out:
close(connfd);
return rem_dest;
}
static struct pingpong_context *pp_init_ctx(struct ibv_device *ib_dev, int size,
int num_qp, int rx_depth, int port,
int use_event)
{
struct pingpong_context *ctx;
int i;
ctx = calloc(1, sizeof *ctx);
if (!ctx)
return NULL;
ctx->size = size;
ctx->num_qp = num_qp;
ctx->rx_depth = rx_depth;
ctx->buf = malloc(roundup(size, page_size));
if (!ctx->buf) {
fprintf(stderr, "Couldn't allocate work buf.\n");
return NULL;
}
memset(ctx->buf, 0, size);
ctx->context = ibv_open_device(ib_dev);
if (!ctx->context) {
fprintf(stderr, "Couldn't get context for %s\n",
ibv_get_device_name(ib_dev));
return NULL;
}
if (use_event) {
ctx->channel = ibv_create_comp_channel(ctx->context);
if (!ctx->channel) {
fprintf(stderr, "Couldn't create completion channel\n");
return NULL;
}
} else
ctx->channel = NULL;
ctx->pd = ibv_alloc_pd(ctx->context);
if (!ctx->pd) {
fprintf(stderr, "Couldn't allocate PD\n");
return NULL;
}
ctx->mr = ibv_reg_mr(ctx->pd, ctx->buf, size, IBV_ACCESS_LOCAL_WRITE);
if (!ctx->mr) {
fprintf(stderr, "Couldn't register MR\n");
return NULL;
}
ctx->cq = ibv_create_cq(ctx->context, rx_depth + num_qp, NULL,
ctx->channel, 0);
if (!ctx->cq) {
fprintf(stderr, "Couldn't create CQ\n");
return NULL;
}
{
struct ibv_srq_init_attr attr = {
.attr = {
.max_wr = rx_depth,
.max_sge = 1
}
};
ctx->srq = ibv_create_srq(ctx->pd, &attr);
if (!ctx->srq) {
fprintf(stderr, "Couldn't create SRQ\n");
return NULL;
}
}
for (i = 0; i < num_qp; ++i) {
struct ibv_qp_init_attr attr = {
.send_cq = ctx->cq,
.recv_cq = ctx->cq,
.srq = ctx->srq,
.cap = {
.max_send_wr = 1,
.max_send_sge = 1,
},
.qp_type = IBV_QPT_RC
};
ctx->qp[i] = ibv_create_qp(ctx->pd, &attr);
if (!ctx->qp[i]) {
fprintf(stderr, "Couldn't create QP[%d]\n", i);
return NULL;
}
}
for (i = 0; i < num_qp; ++i) {
struct ibv_qp_attr attr = {
.qp_state = IBV_QPS_INIT,
.pkey_index = 0,
.port_num = port,
.qp_access_flags = 0
};
if (ibv_modify_qp(ctx->qp[i], &attr,
IBV_QP_STATE |
IBV_QP_PKEY_INDEX |
IBV_QP_PORT |
IBV_QP_ACCESS_FLAGS)) {
fprintf(stderr, "Failed to modify QP[%d] to INIT\n", i);
return NULL;
}
}
return ctx;
}
int pp_close_ctx(struct pingpong_context *ctx, int num_qp)
{
int i;
for (i = 0; i < num_qp; ++i) {
if (ibv_destroy_qp(ctx->qp[i])) {
fprintf(stderr, "Couldn't destroy QP[%d]\n", i);
return 1;
}
}
if (ibv_destroy_srq(ctx->srq)) {
fprintf(stderr, "Couldn't destroy SRQ\n");
return 1;
}
if (ibv_destroy_cq(ctx->cq)) {
fprintf(stderr, "Couldn't destroy CQ\n");
return 1;
}
if (ibv_dereg_mr(ctx->mr)) {
fprintf(stderr, "Couldn't deregister MR\n");
return 1;
}
if (ibv_dealloc_pd(ctx->pd)) {
fprintf(stderr, "Couldn't deallocate PD\n");
return 1;
}
if (ctx->channel) {
if (ibv_destroy_comp_channel(ctx->channel)) {
fprintf(stderr, "Couldn't destroy completion channel\n");
return 1;
}
}
if (ibv_close_device(ctx->context)) {
fprintf(stderr, "Couldn't release context\n");
return 1;
}
free(ctx->buf);
free(ctx);
return 0;
}
static int pp_post_recv(struct pingpong_context *ctx, int n)
{
struct ibv_sge list = {
.addr = (uintptr_t) ctx->buf,
.length = ctx->size,
.lkey = ctx->mr->lkey
};
struct ibv_recv_wr wr = {
.wr_id = PINGPONG_RECV_WRID,
.sg_list = &list,
.num_sge = 1,
};
struct ibv_recv_wr *bad_wr;
int i;
for (i = 0; i < n; ++i)
if (ibv_post_srq_recv(ctx->srq, &wr, &bad_wr))
break;
return i;
}
static int pp_post_send(struct pingpong_context *ctx, int qp_index)
{
struct ibv_sge list = {
.addr = (uintptr_t) ctx->buf,
.length = ctx->size,
.lkey = ctx->mr->lkey
};
struct ibv_send_wr wr = {
.wr_id = PINGPONG_SEND_WRID,
.sg_list = &list,
.num_sge = 1,
.opcode = IBV_WR_SEND,
.send_flags = IBV_SEND_SIGNALED,
};
struct ibv_send_wr *bad_wr;
return ibv_post_send(ctx->qp[qp_index], &wr, &bad_wr);
}
static int find_qp(int qpn, struct pingpong_context *ctx, int num_qp)
{
int i;
for (i = 0; i < num_qp; ++i)
if (ctx->qp[i]->qp_num == qpn)
return i;
return -1;
}
static void usage(const char *argv0)
{
printf("Usage:\n");
printf(" %s start a server and wait for connection\n", argv0);
printf(" %s <host> connect to server at <host>\n", argv0);
printf("\n");
printf("Options:\n");
printf(" -p, --port=<port> listen on/connect to port <port> (default 18515)\n");
printf(" -d, --ib-dev=<dev> use IB device <dev> (default first device found)\n");
printf(" -i, --ib-port=<port> use port <port> of IB device (default 1)\n");
printf(" -s, --size=<size> size of message to exchange (default 4096)\n");
printf(" -m, --mtu=<size> path MTU (default 1024)\n");
printf(" -q, --num-qp=<num> number of QPs to use (default 16)\n");
printf(" -r, --rx-depth=<dep> number of receives to post at a time (default 500)\n");
printf(" -n, --iters=<iters> number of exchanges per QP(default 1000)\n");
printf(" -l, --sl=<sl> service level value\n");
printf(" -e, --events sleep on CQ events (default poll)\n");
printf(" -g, --gid-idx=<gid index> local port gid index\n");
}
int main(int argc, char *argv[])
{
struct ibv_device **dev_list;
struct ibv_device *ib_dev;
struct ibv_wc *wc;
struct pingpong_context *ctx;
struct pingpong_dest my_dest[MAX_QP];
struct pingpong_dest *rem_dest;
struct timeval start, end;
char *ib_devname = NULL;
char *servername = NULL;
int port = 18515;
int ib_port = 1;
int size = 4096;
enum ibv_mtu mtu = IBV_MTU_1024;
int num_qp = 16;
int rx_depth = 500;
int iters = 1000;
int use_event = 0;
int routs;
int rcnt, scnt;
int num_wc;
int i;
int num_cq_events = 0;
int sl = 0;
int gidx = -1;
char gid[33];
srand48(getpid() * time(NULL));
while (1) {
int c;
static struct option long_options[] = {
{ .name = "port", .has_arg = 1, .val = 'p' },
{ .name = "ib-dev", .has_arg = 1, .val = 'd' },
{ .name = "ib-port", .has_arg = 1, .val = 'i' },
{ .name = "size", .has_arg = 1, .val = 's' },
{ .name = "mtu", .has_arg = 1, .val = 'm' },
{ .name = "num-qp", .has_arg = 1, .val = 'q' },
{ .name = "rx-depth", .has_arg = 1, .val = 'r' },
{ .name = "iters", .has_arg = 1, .val = 'n' },
{ .name = "sl", .has_arg = 1, .val = 'l' },
{ .name = "events", .has_arg = 0, .val = 'e' },
{ .name = "gid-idx", .has_arg = 1, .val = 'g' },
{ 0 }
};
c = getopt_long(argc, argv, "p:d:i:s:m:q:r:n:l:eg:", long_options, NULL);
if (c == -1)
break;
switch (c) {
case 'p':
port = strtol(optarg, NULL, 0);
if (port < 0 || port > 65535) {
usage(argv[0]);
return 1;
}
break;
case 'd':
ib_devname = strdup(optarg);
break;
case 'i':
ib_port = strtol(optarg, NULL, 0);
if (ib_port < 0) {
usage(argv[0]);
return 1;
}
break;
case 's':
size = strtol(optarg, NULL, 0);
break;
case 'm':
mtu = pp_mtu_to_enum(strtol(optarg, NULL, 0));
if (mtu < 0) {
usage(argv[0]);
return 1;
}
break;
case 'q':
num_qp = strtol(optarg, NULL, 0);
break;
case 'r':
rx_depth = strtol(optarg, NULL, 0);
break;
case 'n':
iters = strtol(optarg, NULL, 0);
break;
case 'l':
sl = strtol(optarg, NULL, 0);
break;
case 'e':
++use_event;
break;
case 'g':
gidx = strtol(optarg, NULL, 0);
break;
default:
usage(argv[0]);
return 1;
}
}
if (optind == argc - 1)
servername = strdup(argv[optind]);
else if (optind < argc) {
usage(argv[0]);
return 1;
}
if (num_qp > rx_depth) {
fprintf(stderr, "rx_depth %d is too small for %d QPs -- "
"must have at least one receive per QP.\n",
rx_depth, num_qp);
return 1;
}
num_wc = num_qp + rx_depth;
wc = alloca(num_wc * sizeof *wc);
page_size = sysconf(_SC_PAGESIZE);
dev_list = ibv_get_device_list(NULL);
if (!dev_list) {
perror("Failed to get IB devices list");
return 1;
}
if (!ib_devname) {
ib_dev = *dev_list;
if (!ib_dev) {
fprintf(stderr, "No IB devices found\n");
return 1;
}
} else {
int i;
for (i = 0; dev_list[i]; ++i)
if (!strcmp(ibv_get_device_name(dev_list[i]), ib_devname))
break;
ib_dev = dev_list[i];
if (!ib_dev) {
fprintf(stderr, "IB device %s not found\n", ib_devname);
return 1;
}
}
ctx = pp_init_ctx(ib_dev, size, num_qp, rx_depth, ib_port, use_event);
if (!ctx)
return 1;
routs = pp_post_recv(ctx, ctx->rx_depth);
if (routs < ctx->rx_depth) {
fprintf(stderr, "Couldn't post receive (%d)\n", routs);
return 1;
}
if (use_event)
if (ibv_req_notify_cq(ctx->cq, 0)) {
fprintf(stderr, "Couldn't request CQ notification\n");
return 1;
}
memset(my_dest, 0, sizeof my_dest);
if (pp_get_port_info(ctx->context, ib_port, &ctx->portinfo)) {
fprintf(stderr, "Couldn't get port info\n");
return 1;
}
for (i = 0; i < num_qp; ++i) {
my_dest[i].qpn = ctx->qp[i]->qp_num;
my_dest[i].psn = lrand48() & 0xffffff;
my_dest[i].lid = ctx->portinfo.lid;
if (ctx->portinfo.link_layer == IBV_LINK_LAYER_INFINIBAND && !my_dest[i].lid) {
fprintf(stderr, "Couldn't get local LID\n");
return 1;
}
if (gidx >= 0) {
if (ibv_query_gid(ctx->context, ib_port, gidx, &my_dest[i].gid)) {
fprintf(stderr, "Could not get local gid for gid index %d\n", gidx);
return 1;
}
} else
memset(&my_dest[i].gid, 0, sizeof my_dest[i].gid);
inet_ntop(AF_INET6, &my_dest[i].gid, gid, sizeof gid);
printf(" local address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x, GID %s\n",
my_dest[i].lid, my_dest[i].qpn, my_dest[i].psn, gid);
}
if (servername)
rem_dest = pp_client_exch_dest(servername, port, my_dest);
else
rem_dest = pp_server_exch_dest(ctx, ib_port, mtu, port, sl, my_dest, gidx);
if (!rem_dest)
return 1;
inet_ntop(AF_INET6, &rem_dest->gid, gid, sizeof gid);
for (i = 0; i < num_qp; ++i) {
inet_ntop(AF_INET6, &rem_dest[i].gid, gid, sizeof gid);
printf(" remote address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x, GID %s\n",
rem_dest[i].lid, rem_dest[i].qpn, rem_dest[i].psn, gid);
}
if (servername)
if (pp_connect_ctx(ctx, ib_port, mtu, sl, my_dest, rem_dest, gidx))
return 1;
if (servername)
for (i = 0; i < num_qp; ++i) {
if (pp_post_send(ctx, i)) {
fprintf(stderr, "Couldn't post send\n");
return 1;
}
ctx->pending[i] = PINGPONG_SEND_WRID | PINGPONG_RECV_WRID;
}
else
for (i = 0; i < num_qp; ++i)
ctx->pending[i] = PINGPONG_RECV_WRID;
if (gettimeofday(&start, NULL)) {
perror("gettimeofday");
return 1;
}
rcnt = scnt = 0;
while (rcnt < iters || scnt < iters) {
if (use_event) {
struct ibv_cq *ev_cq;
void *ev_ctx;
if (ibv_get_cq_event(ctx->channel, &ev_cq, &ev_ctx)) {
fprintf(stderr, "Failed to get cq_event\n");
return 1;
}
++num_cq_events;
if (ev_cq != ctx->cq) {
fprintf(stderr, "CQ event for unknown CQ %p\n", ev_cq);
return 1;
}
if (ibv_req_notify_cq(ctx->cq, 0)) {
fprintf(stderr, "Couldn't request CQ notification\n");
return 1;
}
}
{
int ne, qp_ind;
do {
ne = ibv_poll_cq(ctx->cq, num_wc, wc);
if (ne < 0) {
fprintf(stderr, "poll CQ failed %d\n", ne);
return 1;
}
} while (!use_event && ne < 1);
for (i = 0; i < ne; ++i) {
if (wc[i].status != IBV_WC_SUCCESS) {
fprintf(stderr, "Failed status %s (%d) for wr_id %d\n",
ibv_wc_status_str(wc[i].status),
wc[i].status, (int) wc[i].wr_id);
return 1;
}
qp_ind = find_qp(wc[i].qp_num, ctx, num_qp);
if (qp_ind < 0) {
fprintf(stderr, "Couldn't find QPN %06x\n",
wc[i].qp_num);
return 1;
}
switch ((int) wc[i].wr_id) {
case PINGPONG_SEND_WRID:
++scnt;
break;
case PINGPONG_RECV_WRID:
if (--routs <= num_qp) {
routs += pp_post_recv(ctx, ctx->rx_depth - routs);
if (routs < ctx->rx_depth) {
fprintf(stderr,
"Couldn't post receive (%d)\n",
routs);
return 1;
}
}
++rcnt;
break;
default:
fprintf(stderr, "Completion for unknown wr_id %d\n",
(int) wc[i].wr_id);
return 1;
}
ctx->pending[qp_ind] &= ~(int) wc[i].wr_id;
if (scnt < iters && !ctx->pending[qp_ind]) {
if (pp_post_send(ctx, qp_ind)) {
fprintf(stderr, "Couldn't post send\n");
return 1;
}
ctx->pending[qp_ind] = PINGPONG_RECV_WRID |
PINGPONG_SEND_WRID;
}
}
}
}
if (gettimeofday(&end, NULL)) {
perror("gettimeofday");
return 1;
}
{
float usec = (end.tv_sec - start.tv_sec) * 1000000 +
(end.tv_usec - start.tv_usec);
long long bytes = (long long) size * iters * 2;
printf("%lld bytes in %.2f seconds = %.2f Mbit/sec\n",
bytes, usec / 1000000., bytes * 8. / usec);
printf("%d iters in %.2f seconds = %.2f usec/iter\n",
iters, usec / 1000000., usec / iters);
}
ibv_ack_cq_events(ctx->cq, num_cq_events);
if (pp_close_ctx(ctx, num_qp))
return 1;
ibv_free_device_list(dev_list);
free(rem_dest);
return 0;
}

View File

@ -0,0 +1,809 @@
/*
* Copyright (c) 2005 Topspin Communications. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#if HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netdb.h>
#include <getopt.h>
#include <arpa/inet.h>
#include <time.h>
#include "pingpong.h"
enum {
PINGPONG_RECV_WRID = 1,
PINGPONG_SEND_WRID = 2,
};
static int page_size;
struct pingpong_context {
struct ibv_context *context;
struct ibv_comp_channel *channel;
struct ibv_pd *pd;
struct ibv_mr *mr;
struct ibv_cq *cq;
struct ibv_qp *qp;
void *buf;
int size;
int rx_depth;
int pending;
struct ibv_port_attr portinfo;
};
struct pingpong_dest {
int lid;
int qpn;
int psn;
union ibv_gid gid;
};
static int pp_connect_ctx(struct pingpong_context *ctx, int port, int my_psn,
enum ibv_mtu mtu, int sl,
struct pingpong_dest *dest, int sgid_idx)
{
struct ibv_qp_attr attr = {
.qp_state = IBV_QPS_RTR,
.path_mtu = mtu,
.dest_qp_num = dest->qpn,
.rq_psn = dest->psn,
.ah_attr = {
.is_global = 0,
.dlid = dest->lid,
.sl = sl,
.src_path_bits = 0,
.port_num = port
}
};
if (dest->gid.global.interface_id) {
attr.ah_attr.is_global = 1;
attr.ah_attr.grh.hop_limit = 1;
attr.ah_attr.grh.dgid = dest->gid;
attr.ah_attr.grh.sgid_index = sgid_idx;
}
if (ibv_modify_qp(ctx->qp, &attr,
IBV_QP_STATE |
IBV_QP_AV |
IBV_QP_PATH_MTU |
IBV_QP_DEST_QPN |
IBV_QP_RQ_PSN)) {
fprintf(stderr, "Failed to modify QP to RTR\n");
return 1;
}
attr.qp_state = IBV_QPS_RTS;
attr.sq_psn = my_psn;
if (ibv_modify_qp(ctx->qp, &attr,
IBV_QP_STATE |
IBV_QP_SQ_PSN)) {
fprintf(stderr, "Failed to modify QP to RTS\n");
return 1;
}
return 0;
}
static struct pingpong_dest *pp_client_exch_dest(const char *servername, int port,
const struct pingpong_dest *my_dest)
{
struct addrinfo *res, *t;
struct addrinfo hints = {
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM
};
char *service;
char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"];
int n;
int sockfd = -1;
struct pingpong_dest *rem_dest = NULL;
char gid[33];
if (asprintf(&service, "%d", port) < 0)
return NULL;
n = getaddrinfo(servername, service, &hints, &res);
if (n < 0) {
fprintf(stderr, "%s for %s:%d\n", gai_strerror(n), servername, port);
free(service);
return NULL;
}
for (t = res; t; t = t->ai_next) {
sockfd = socket(t->ai_family, t->ai_socktype, t->ai_protocol);
if (sockfd >= 0) {
if (!connect(sockfd, t->ai_addr, t->ai_addrlen))
break;
close(sockfd);
sockfd = -1;
}
}
freeaddrinfo(res);
free(service);
if (sockfd < 0) {
fprintf(stderr, "Couldn't connect to %s:%d\n", servername, port);
return NULL;
}
gid_to_wire_gid(&my_dest->gid, gid);
sprintf(msg, "%04x:%06x:%06x:%s", my_dest->lid, my_dest->qpn, my_dest->psn, gid);
if (write(sockfd, msg, sizeof msg) != sizeof msg) {
fprintf(stderr, "Couldn't send local address\n");
goto out;
}
if (read(sockfd, msg, sizeof msg) != sizeof msg) {
perror("client read");
fprintf(stderr, "Couldn't read remote address\n");
goto out;
}
write(sockfd, "done", sizeof "done");
rem_dest = malloc(sizeof *rem_dest);
if (!rem_dest)
goto out;
sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn, gid);
wire_gid_to_gid(gid, &rem_dest->gid);
out:
close(sockfd);
return rem_dest;
}
static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx,
int ib_port, enum ibv_mtu mtu,
int port, int sl,
const struct pingpong_dest *my_dest,
int sgid_idx)
{
struct addrinfo *res, *t;
struct addrinfo hints = {
.ai_flags = AI_PASSIVE,
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM
};
char *service;
char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"];
int n;
int sockfd = -1, connfd;
struct pingpong_dest *rem_dest = NULL;
char gid[33];
if (asprintf(&service, "%d", port) < 0)
return NULL;
n = getaddrinfo(NULL, service, &hints, &res);
if (n < 0) {
fprintf(stderr, "%s for port %d\n", gai_strerror(n), port);
free(service);
return NULL;
}
for (t = res; t; t = t->ai_next) {
sockfd = socket(t->ai_family, t->ai_socktype, t->ai_protocol);
if (sockfd >= 0) {
n = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof n);
if (!bind(sockfd, t->ai_addr, t->ai_addrlen))
break;
close(sockfd);
sockfd = -1;
}
}
freeaddrinfo(res);
free(service);
if (sockfd < 0) {
fprintf(stderr, "Couldn't listen to port %d\n", port);
return NULL;
}
listen(sockfd, 1);
connfd = accept(sockfd, NULL, 0);
close(sockfd);
if (connfd < 0) {
fprintf(stderr, "accept() failed\n");
return NULL;
}
n = read(connfd, msg, sizeof msg);
if (n != sizeof msg) {
perror("server read");
fprintf(stderr, "%d/%d: Couldn't read remote address\n", n, (int) sizeof msg);
goto out;
}
rem_dest = malloc(sizeof *rem_dest);
if (!rem_dest)
goto out;
sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn, gid);
wire_gid_to_gid(gid, &rem_dest->gid);
if (pp_connect_ctx(ctx, ib_port, my_dest->psn, mtu, sl, rem_dest, sgid_idx)) {
fprintf(stderr, "Couldn't connect to remote QP\n");
free(rem_dest);
rem_dest = NULL;
goto out;
}
gid_to_wire_gid(&my_dest->gid, gid);
sprintf(msg, "%04x:%06x:%06x:%s", my_dest->lid, my_dest->qpn, my_dest->psn, gid);
if (write(connfd, msg, sizeof msg) != sizeof msg) {
fprintf(stderr, "Couldn't send local address\n");
free(rem_dest);
rem_dest = NULL;
goto out;
}
read(connfd, msg, sizeof msg);
out:
close(connfd);
return rem_dest;
}
static struct pingpong_context *pp_init_ctx(struct ibv_device *ib_dev, int size,
int rx_depth, int port,
int use_event)
{
struct pingpong_context *ctx;
ctx = calloc(1, sizeof *ctx);
if (!ctx)
return NULL;
ctx->size = size;
ctx->rx_depth = rx_depth;
ctx->buf = malloc(roundup(size, page_size));
if (!ctx->buf) {
fprintf(stderr, "Couldn't allocate work buf.\n");
return NULL;
}
memset(ctx->buf, 0, size);
ctx->context = ibv_open_device(ib_dev);
if (!ctx->context) {
fprintf(stderr, "Couldn't get context for %s\n",
ibv_get_device_name(ib_dev));
return NULL;
}
if (use_event) {
ctx->channel = ibv_create_comp_channel(ctx->context);
if (!ctx->channel) {
fprintf(stderr, "Couldn't create completion channel\n");
return NULL;
}
} else
ctx->channel = NULL;
ctx->pd = ibv_alloc_pd(ctx->context);
if (!ctx->pd) {
fprintf(stderr, "Couldn't allocate PD\n");
return NULL;
}
ctx->mr = ibv_reg_mr(ctx->pd, ctx->buf, size, IBV_ACCESS_LOCAL_WRITE);
if (!ctx->mr) {
fprintf(stderr, "Couldn't register MR\n");
return NULL;
}
ctx->cq = ibv_create_cq(ctx->context, rx_depth + 1, NULL,
ctx->channel, 0);
if (!ctx->cq) {
fprintf(stderr, "Couldn't create CQ\n");
return NULL;
}
{
struct ibv_qp_init_attr attr = {
.send_cq = ctx->cq,
.recv_cq = ctx->cq,
.cap = {
.max_send_wr = 1,
.max_recv_wr = rx_depth,
.max_send_sge = 1,
.max_recv_sge = 1
},
.qp_type = IBV_QPT_UC
};
ctx->qp = ibv_create_qp(ctx->pd, &attr);
if (!ctx->qp) {
fprintf(stderr, "Couldn't create QP\n");
return NULL;
}
}
{
struct ibv_qp_attr attr = {
.qp_state = IBV_QPS_INIT,
.pkey_index = 0,
.port_num = port,
.qp_access_flags = 0
};
if (ibv_modify_qp(ctx->qp, &attr,
IBV_QP_STATE |
IBV_QP_PKEY_INDEX |
IBV_QP_PORT |
IBV_QP_ACCESS_FLAGS)) {
fprintf(stderr, "Failed to modify QP to INIT\n");
return NULL;
}
}
return ctx;
}
int pp_close_ctx(struct pingpong_context *ctx)
{
if (ibv_destroy_qp(ctx->qp)) {
fprintf(stderr, "Couldn't destroy QP\n");
return 1;
}
if (ibv_destroy_cq(ctx->cq)) {
fprintf(stderr, "Couldn't destroy CQ\n");
return 1;
}
if (ibv_dereg_mr(ctx->mr)) {
fprintf(stderr, "Couldn't deregister MR\n");
return 1;
}
if (ibv_dealloc_pd(ctx->pd)) {
fprintf(stderr, "Couldn't deallocate PD\n");
return 1;
}
if (ctx->channel) {
if (ibv_destroy_comp_channel(ctx->channel)) {
fprintf(stderr, "Couldn't destroy completion channel\n");
return 1;
}
}
if (ibv_close_device(ctx->context)) {
fprintf(stderr, "Couldn't release context\n");
return 1;
}
free(ctx->buf);
free(ctx);
return 0;
}
static int pp_post_recv(struct pingpong_context *ctx, int n)
{
struct ibv_sge list = {
.addr = (uintptr_t) ctx->buf,
.length = ctx->size,
.lkey = ctx->mr->lkey
};
struct ibv_recv_wr wr = {
.wr_id = PINGPONG_RECV_WRID,
.sg_list = &list,
.num_sge = 1,
};
struct ibv_recv_wr *bad_wr;
int i;
for (i = 0; i < n; ++i)
if (ibv_post_recv(ctx->qp, &wr, &bad_wr))
break;
return i;
}
static int pp_post_send(struct pingpong_context *ctx)
{
struct ibv_sge list = {
.addr = (uintptr_t) ctx->buf,
.length = ctx->size,
.lkey = ctx->mr->lkey
};
struct ibv_send_wr wr = {
.wr_id = PINGPONG_SEND_WRID,
.sg_list = &list,
.num_sge = 1,
.opcode = IBV_WR_SEND,
.send_flags = IBV_SEND_SIGNALED,
};
struct ibv_send_wr *bad_wr;
return ibv_post_send(ctx->qp, &wr, &bad_wr);
}
static void usage(const char *argv0)
{
printf("Usage:\n");
printf(" %s start a server and wait for connection\n", argv0);
printf(" %s <host> connect to server at <host>\n", argv0);
printf("\n");
printf("Options:\n");
printf(" -p, --port=<port> listen on/connect to port <port> (default 18515)\n");
printf(" -d, --ib-dev=<dev> use IB device <dev> (default first device found)\n");
printf(" -i, --ib-port=<port> use port <port> of IB device (default 1)\n");
printf(" -s, --size=<size> size of message to exchange (default 4096)\n");
printf(" -m, --mtu=<size> path MTU (default 1024)\n");
printf(" -r, --rx-depth=<dep> number of receives to post at a time (default 500)\n");
printf(" -n, --iters=<iters> number of exchanges (default 1000)\n");
printf(" -l, --sl=<sl> service level value\n");
printf(" -e, --events sleep on CQ events (default poll)\n");
printf(" -g, --gid-idx=<gid index> local port gid index\n");
}
int main(int argc, char *argv[])
{
struct ibv_device **dev_list;
struct ibv_device *ib_dev;
struct pingpong_context *ctx;
struct pingpong_dest my_dest;
struct pingpong_dest *rem_dest;
struct timeval start, end;
char *ib_devname = NULL;
char *servername = NULL;
int port = 18515;
int ib_port = 1;
int size = 4096;
enum ibv_mtu mtu = IBV_MTU_1024;
int rx_depth = 500;
int iters = 1000;
int use_event = 0;
int routs;
int rcnt, scnt;
int num_cq_events = 0;
int sl = 0;
int gidx = -1;
char gid[33];
srand48(getpid() * time(NULL));
while (1) {
int c;
static struct option long_options[] = {
{ .name = "port", .has_arg = 1, .val = 'p' },
{ .name = "ib-dev", .has_arg = 1, .val = 'd' },
{ .name = "ib-port", .has_arg = 1, .val = 'i' },
{ .name = "size", .has_arg = 1, .val = 's' },
{ .name = "mtu", .has_arg = 1, .val = 'm' },
{ .name = "rx-depth", .has_arg = 1, .val = 'r' },
{ .name = "iters", .has_arg = 1, .val = 'n' },
{ .name = "sl", .has_arg = 1, .val = 'l' },
{ .name = "events", .has_arg = 0, .val = 'e' },
{ .name = "gid-idx", .has_arg = 1, .val = 'g' },
{ 0 }
};
c = getopt_long(argc, argv, "p:d:i:s:m:r:n:l:eg:", long_options, NULL);
if (c == -1)
break;
switch (c) {
case 'p':
port = strtol(optarg, NULL, 0);
if (port < 0 || port > 65535) {
usage(argv[0]);
return 1;
}
break;
case 'd':
ib_devname = strdup(optarg);
break;
case 'i':
ib_port = strtol(optarg, NULL, 0);
if (ib_port < 0) {
usage(argv[0]);
return 1;
}
break;
case 's':
size = strtol(optarg, NULL, 0);
break;
case 'm':
mtu = pp_mtu_to_enum(strtol(optarg, NULL, 0));
if (mtu < 0) {
usage(argv[0]);
return 1;
}
break;
case 'r':
rx_depth = strtol(optarg, NULL, 0);
break;
case 'n':
iters = strtol(optarg, NULL, 0);
break;
case 'l':
sl = strtol(optarg, NULL, 0);
break;
case 'e':
++use_event;
break;
case 'g':
gidx = strtol(optarg, NULL, 0);
break;
default:
usage(argv[0]);
return 1;
}
}
if (optind == argc - 1)
servername = strdup(argv[optind]);
else if (optind < argc) {
usage(argv[0]);
return 1;
}
page_size = sysconf(_SC_PAGESIZE);
dev_list = ibv_get_device_list(NULL);
if (!dev_list) {
perror("Failed to get IB devices list");
return 1;
}
if (!ib_devname) {
ib_dev = *dev_list;
if (!ib_dev) {
fprintf(stderr, "No IB devices found\n");
return 1;
}
} else {
int i;
for (i = 0; dev_list[i]; ++i)
if (!strcmp(ibv_get_device_name(dev_list[i]), ib_devname))
break;
ib_dev = dev_list[i];
if (!ib_dev) {
fprintf(stderr, "IB device %s not found\n", ib_devname);
return 1;
}
}
ctx = pp_init_ctx(ib_dev, size, rx_depth, ib_port, use_event);
if (!ctx)
return 1;
routs = pp_post_recv(ctx, ctx->rx_depth);
if (routs < ctx->rx_depth) {
fprintf(stderr, "Couldn't post receive (%d)\n", routs);
return 1;
}
if (use_event)
if (ibv_req_notify_cq(ctx->cq, 0)) {
fprintf(stderr, "Couldn't request CQ notification\n");
return 1;
}
if (pp_get_port_info(ctx->context, ib_port, &ctx->portinfo)) {
fprintf(stderr, "Couldn't get port info\n");
return 1;
}
my_dest.lid = ctx->portinfo.lid;
if (ctx->portinfo.link_layer == IBV_LINK_LAYER_INFINIBAND && !my_dest.lid) {
fprintf(stderr, "Couldn't get local LID\n");
return 1;
}
if (gidx >= 0) {
if (ibv_query_gid(ctx->context, ib_port, gidx, &my_dest.gid)) {
fprintf(stderr, "Could not get local gid for gid index %d\n", gidx);
return 1;
}
} else
memset(&my_dest.gid, 0, sizeof my_dest.gid);
my_dest.qpn = ctx->qp->qp_num;
my_dest.psn = lrand48() & 0xffffff;
inet_ntop(AF_INET6, &my_dest.gid, gid, sizeof gid);
printf(" local address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x, GID %s\n",
my_dest.lid, my_dest.qpn, my_dest.psn, gid);
if (servername)
rem_dest = pp_client_exch_dest(servername, port, &my_dest);
else
rem_dest = pp_server_exch_dest(ctx, ib_port, mtu, port, sl, &my_dest, gidx);
if (!rem_dest)
return 1;
inet_ntop(AF_INET6, &rem_dest->gid, gid, sizeof gid);
printf(" remote address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x, GID %s\n",
rem_dest->lid, rem_dest->qpn, rem_dest->psn, gid);
if (servername)
if (pp_connect_ctx(ctx, ib_port, my_dest.psn, mtu, sl, rem_dest, gidx))
return 1;
ctx->pending = PINGPONG_RECV_WRID;
if (servername) {
if (pp_post_send(ctx)) {
fprintf(stderr, "Couldn't post send\n");
return 1;
}
ctx->pending |= PINGPONG_SEND_WRID;
}
if (gettimeofday(&start, NULL)) {
perror("gettimeofday");
return 1;
}
rcnt = scnt = 0;
while (rcnt < iters || scnt < iters) {
if (use_event) {
struct ibv_cq *ev_cq;
void *ev_ctx;
if (ibv_get_cq_event(ctx->channel, &ev_cq, &ev_ctx)) {
fprintf(stderr, "Failed to get cq_event\n");
return 1;
}
++num_cq_events;
if (ev_cq != ctx->cq) {
fprintf(stderr, "CQ event for unknown CQ %p\n", ev_cq);
return 1;
}
if (ibv_req_notify_cq(ctx->cq, 0)) {
fprintf(stderr, "Couldn't request CQ notification\n");
return 1;
}
}
{
struct ibv_wc wc[2];
int ne, i;
do {
ne = ibv_poll_cq(ctx->cq, 2, wc);
if (ne < 0) {
fprintf(stderr, "poll CQ failed %d\n", ne);
return 1;
}
} while (!use_event && ne < 1);
for (i = 0; i < ne; ++i) {
if (wc[i].status != IBV_WC_SUCCESS) {
fprintf(stderr, "Failed status %s (%d) for wr_id %d\n",
ibv_wc_status_str(wc[i].status),
wc[i].status, (int) wc[i].wr_id);
return 1;
}
switch ((int) wc[i].wr_id) {
case PINGPONG_SEND_WRID:
++scnt;
break;
case PINGPONG_RECV_WRID:
if (--routs <= 1) {
routs += pp_post_recv(ctx, ctx->rx_depth - routs);
if (routs < ctx->rx_depth) {
fprintf(stderr,
"Couldn't post receive (%d)\n",
routs);
return 1;
}
}
++rcnt;
break;
default:
fprintf(stderr, "Completion for unknown wr_id %d\n",
(int) wc[i].wr_id);
return 1;
}
ctx->pending &= ~(int) wc[i].wr_id;
if (scnt < iters && !ctx->pending) {
if (pp_post_send(ctx)) {
fprintf(stderr, "Couldn't post send\n");
return 1;
}
ctx->pending = PINGPONG_RECV_WRID |
PINGPONG_SEND_WRID;
}
}
}
}
if (gettimeofday(&end, NULL)) {
perror("gettimeofday");
return 1;
}
{
float usec = (end.tv_sec - start.tv_sec) * 1000000 +
(end.tv_usec - start.tv_usec);
long long bytes = (long long) size * iters * 2;
printf("%lld bytes in %.2f seconds = %.2f Mbit/sec\n",
bytes, usec / 1000000., bytes * 8. / usec);
printf("%d iters in %.2f seconds = %.2f usec/iter\n",
iters, usec / 1000000., usec / iters);
}
ibv_ack_cq_events(ctx->cq, num_cq_events);
if (pp_close_ctx(ctx))
return 1;
ibv_free_device_list(dev_list);
free(rem_dest);
return 0;
}

View File

@ -0,0 +1,803 @@
/*
* Copyright (c) 2005 Topspin Communications. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#if HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netdb.h>
#include <getopt.h>
#include <arpa/inet.h>
#include <time.h>
#include "pingpong.h"
enum {
PINGPONG_RECV_WRID = 1,
PINGPONG_SEND_WRID = 2,
};
static int page_size;
struct pingpong_context {
struct ibv_context *context;
struct ibv_comp_channel *channel;
struct ibv_pd *pd;
struct ibv_mr *mr;
struct ibv_cq *cq;
struct ibv_qp *qp;
struct ibv_ah *ah;
void *buf;
int size;
int rx_depth;
int pending;
struct ibv_port_attr portinfo;
};
struct pingpong_dest {
int lid;
int qpn;
int psn;
union ibv_gid gid;
};
static int pp_connect_ctx(struct pingpong_context *ctx, int port, int my_psn,
int sl, struct pingpong_dest *dest, int sgid_idx)
{
struct ibv_ah_attr ah_attr = {
.is_global = 0,
.dlid = dest->lid,
.sl = sl,
.src_path_bits = 0,
.port_num = port
};
struct ibv_qp_attr attr = {
.qp_state = IBV_QPS_RTR
};
if (ibv_modify_qp(ctx->qp, &attr, IBV_QP_STATE)) {
fprintf(stderr, "Failed to modify QP to RTR\n");
return 1;
}
attr.qp_state = IBV_QPS_RTS;
attr.sq_psn = my_psn;
if (ibv_modify_qp(ctx->qp, &attr,
IBV_QP_STATE |
IBV_QP_SQ_PSN)) {
fprintf(stderr, "Failed to modify QP to RTS\n");
return 1;
}
if (dest->gid.global.interface_id) {
ah_attr.is_global = 1;
ah_attr.grh.hop_limit = 1;
ah_attr.grh.dgid = dest->gid;
ah_attr.grh.sgid_index = sgid_idx;
}
ctx->ah = ibv_create_ah(ctx->pd, &ah_attr);
if (!ctx->ah) {
fprintf(stderr, "Failed to create AH\n");
return 1;
}
return 0;
}
static struct pingpong_dest *pp_client_exch_dest(const char *servername, int port,
const struct pingpong_dest *my_dest)
{
struct addrinfo *res, *t;
struct addrinfo hints = {
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM
};
char *service;
char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"];
int n;
int sockfd = -1;
struct pingpong_dest *rem_dest = NULL;
char gid[33];
if (asprintf(&service, "%d", port) < 0)
return NULL;
n = getaddrinfo(servername, service, &hints, &res);
if (n < 0) {
fprintf(stderr, "%s for %s:%d\n", gai_strerror(n), servername, port);
free(service);
return NULL;
}
for (t = res; t; t = t->ai_next) {
sockfd = socket(t->ai_family, t->ai_socktype, t->ai_protocol);
if (sockfd >= 0) {
if (!connect(sockfd, t->ai_addr, t->ai_addrlen))
break;
close(sockfd);
sockfd = -1;
}
}
freeaddrinfo(res);
free(service);
if (sockfd < 0) {
fprintf(stderr, "Couldn't connect to %s:%d\n", servername, port);
return NULL;
}
gid_to_wire_gid(&my_dest->gid, gid);
sprintf(msg, "%04x:%06x:%06x:%s", my_dest->lid, my_dest->qpn, my_dest->psn, gid);
if (write(sockfd, msg, sizeof msg) != sizeof msg) {
fprintf(stderr, "Couldn't send local address\n");
goto out;
}
if (read(sockfd, msg, sizeof msg) != sizeof msg) {
perror("client read");
fprintf(stderr, "Couldn't read remote address\n");
goto out;
}
write(sockfd, "done", sizeof "done");
rem_dest = malloc(sizeof *rem_dest);
if (!rem_dest)
goto out;
sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn, gid);
wire_gid_to_gid(gid, &rem_dest->gid);
out:
close(sockfd);
return rem_dest;
}
static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx,
int ib_port, int port, int sl,
const struct pingpong_dest *my_dest,
int sgid_idx)
{
struct addrinfo *res, *t;
struct addrinfo hints = {
.ai_flags = AI_PASSIVE,
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM
};
char *service;
char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"];
int n;
int sockfd = -1, connfd;
struct pingpong_dest *rem_dest = NULL;
char gid[33];
if (asprintf(&service, "%d", port) < 0)
return NULL;
n = getaddrinfo(NULL, service, &hints, &res);
if (n < 0) {
fprintf(stderr, "%s for port %d\n", gai_strerror(n), port);
free(service);
return NULL;
}
for (t = res; t; t = t->ai_next) {
sockfd = socket(t->ai_family, t->ai_socktype, t->ai_protocol);
if (sockfd >= 0) {
n = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof n);
if (!bind(sockfd, t->ai_addr, t->ai_addrlen))
break;
close(sockfd);
sockfd = -1;
}
}
freeaddrinfo(res);
free(service);
if (sockfd < 0) {
fprintf(stderr, "Couldn't listen to port %d\n", port);
return NULL;
}
listen(sockfd, 1);
connfd = accept(sockfd, NULL, 0);
close(sockfd);
if (connfd < 0) {
fprintf(stderr, "accept() failed\n");
return NULL;
}
n = read(connfd, msg, sizeof msg);
if (n != sizeof msg) {
perror("server read");
fprintf(stderr, "%d/%d: Couldn't read remote address\n", n, (int) sizeof msg);
goto out;
}
rem_dest = malloc(sizeof *rem_dest);
if (!rem_dest)
goto out;
sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn, gid);
wire_gid_to_gid(gid, &rem_dest->gid);
if (pp_connect_ctx(ctx, ib_port, my_dest->psn, sl, rem_dest, sgid_idx)) {
fprintf(stderr, "Couldn't connect to remote QP\n");
free(rem_dest);
rem_dest = NULL;
goto out;
}
gid_to_wire_gid(&my_dest->gid, gid);
sprintf(msg, "%04x:%06x:%06x:%s", my_dest->lid, my_dest->qpn, my_dest->psn, gid);
if (write(connfd, msg, sizeof msg) != sizeof msg) {
fprintf(stderr, "Couldn't send local address\n");
free(rem_dest);
rem_dest = NULL;
goto out;
}
read(connfd, msg, sizeof msg);
out:
close(connfd);
return rem_dest;
}
static struct pingpong_context *pp_init_ctx(struct ibv_device *ib_dev, int size,
int rx_depth, int port,
int use_event)
{
struct pingpong_context *ctx;
ctx = malloc(sizeof *ctx);
if (!ctx)
return NULL;
ctx->size = size;
ctx->rx_depth = rx_depth;
ctx->buf = malloc(roundup(size + 40, page_size));
if (!ctx->buf) {
fprintf(stderr, "Couldn't allocate work buf.\n");
return NULL;
}
memset(ctx->buf, 0, size + 40);
ctx->context = ibv_open_device(ib_dev);
if (!ctx->context) {
fprintf(stderr, "Couldn't get context for %s\n",
ibv_get_device_name(ib_dev));
return NULL;
}
if (use_event) {
ctx->channel = ibv_create_comp_channel(ctx->context);
if (!ctx->channel) {
fprintf(stderr, "Couldn't create completion channel\n");
return NULL;
}
} else
ctx->channel = NULL;
ctx->pd = ibv_alloc_pd(ctx->context);
if (!ctx->pd) {
fprintf(stderr, "Couldn't allocate PD\n");
return NULL;
}
ctx->mr = ibv_reg_mr(ctx->pd, ctx->buf, size + 40, IBV_ACCESS_LOCAL_WRITE);
if (!ctx->mr) {
fprintf(stderr, "Couldn't register MR\n");
return NULL;
}
ctx->cq = ibv_create_cq(ctx->context, rx_depth + 1, NULL,
ctx->channel, 0);
if (!ctx->cq) {
fprintf(stderr, "Couldn't create CQ\n");
return NULL;
}
{
struct ibv_qp_init_attr attr = {
.send_cq = ctx->cq,
.recv_cq = ctx->cq,
.cap = {
.max_send_wr = 1,
.max_recv_wr = rx_depth,
.max_send_sge = 1,
.max_recv_sge = 1
},
.qp_type = IBV_QPT_UD,
};
ctx->qp = ibv_create_qp(ctx->pd, &attr);
if (!ctx->qp) {
fprintf(stderr, "Couldn't create QP\n");
return NULL;
}
}
{
struct ibv_qp_attr attr = {
.qp_state = IBV_QPS_INIT,
.pkey_index = 0,
.port_num = port,
.qkey = 0x11111111
};
if (ibv_modify_qp(ctx->qp, &attr,
IBV_QP_STATE |
IBV_QP_PKEY_INDEX |
IBV_QP_PORT |
IBV_QP_QKEY)) {
fprintf(stderr, "Failed to modify QP to INIT\n");
return NULL;
}
}
return ctx;
}
int pp_close_ctx(struct pingpong_context *ctx)
{
if (ibv_destroy_qp(ctx->qp)) {
fprintf(stderr, "Couldn't destroy QP\n");
return 1;
}
if (ibv_destroy_cq(ctx->cq)) {
fprintf(stderr, "Couldn't destroy CQ\n");
return 1;
}
if (ibv_dereg_mr(ctx->mr)) {
fprintf(stderr, "Couldn't deregister MR\n");
return 1;
}
if (ibv_destroy_ah(ctx->ah)) {
fprintf(stderr, "Couldn't destroy AH\n");
return 1;
}
if (ibv_dealloc_pd(ctx->pd)) {
fprintf(stderr, "Couldn't deallocate PD\n");
return 1;
}
if (ctx->channel) {
if (ibv_destroy_comp_channel(ctx->channel)) {
fprintf(stderr, "Couldn't destroy completion channel\n");
return 1;
}
}
if (ibv_close_device(ctx->context)) {
fprintf(stderr, "Couldn't release context\n");
return 1;
}
free(ctx->buf);
free(ctx);
return 0;
}
static int pp_post_recv(struct pingpong_context *ctx, int n)
{
struct ibv_sge list = {
.addr = (uintptr_t) ctx->buf,
.length = ctx->size + 40,
.lkey = ctx->mr->lkey
};
struct ibv_recv_wr wr = {
.wr_id = PINGPONG_RECV_WRID,
.sg_list = &list,
.num_sge = 1,
};
struct ibv_recv_wr *bad_wr;
int i;
for (i = 0; i < n; ++i)
if (ibv_post_recv(ctx->qp, &wr, &bad_wr))
break;
return i;
}
static int pp_post_send(struct pingpong_context *ctx, uint32_t qpn)
{
struct ibv_sge list = {
.addr = (uintptr_t) ctx->buf + 40,
.length = ctx->size,
.lkey = ctx->mr->lkey
};
struct ibv_send_wr wr = {
.wr_id = PINGPONG_SEND_WRID,
.sg_list = &list,
.num_sge = 1,
.opcode = IBV_WR_SEND,
.send_flags = IBV_SEND_SIGNALED,
.wr = {
.ud = {
.ah = ctx->ah,
.remote_qpn = qpn,
.remote_qkey = 0x11111111
}
}
};
struct ibv_send_wr *bad_wr;
return ibv_post_send(ctx->qp, &wr, &bad_wr);
}
static void usage(const char *argv0)
{
printf("Usage:\n");
printf(" %s start a server and wait for connection\n", argv0);
printf(" %s <host> connect to server at <host>\n", argv0);
printf("\n");
printf("Options:\n");
printf(" -p, --port=<port> listen on/connect to port <port> (default 18515)\n");
printf(" -d, --ib-dev=<dev> use IB device <dev> (default first device found)\n");
printf(" -i, --ib-port=<port> use port <port> of IB device (default 1)\n");
printf(" -s, --size=<size> size of message to exchange (default 1024)\n");
printf(" -r, --rx-depth=<dep> number of receives to post at a time (default 500)\n");
printf(" -n, --iters=<iters> number of exchanges (default 1000)\n");
printf(" -e, --events sleep on CQ events (default poll)\n");
printf(" -g, --gid-idx=<gid index> local port gid index\n");
}
int main(int argc, char *argv[])
{
struct ibv_device **dev_list;
struct ibv_device *ib_dev;
struct pingpong_context *ctx;
struct pingpong_dest my_dest;
struct pingpong_dest *rem_dest;
struct timeval start, end;
char *ib_devname = NULL;
char *servername = NULL;
int port = 18515;
int ib_port = 1;
int size = 1024;
int rx_depth = 500;
int iters = 1000;
int use_event = 0;
int routs;
int rcnt, scnt;
int num_cq_events = 0;
int sl = 0;
int gidx = -1;
char gid[33];
srand48(getpid() * time(NULL));
while (1) {
int c;
static struct option long_options[] = {
{ .name = "port", .has_arg = 1, .val = 'p' },
{ .name = "ib-dev", .has_arg = 1, .val = 'd' },
{ .name = "ib-port", .has_arg = 1, .val = 'i' },
{ .name = "size", .has_arg = 1, .val = 's' },
{ .name = "rx-depth", .has_arg = 1, .val = 'r' },
{ .name = "iters", .has_arg = 1, .val = 'n' },
{ .name = "sl", .has_arg = 1, .val = 'l' },
{ .name = "events", .has_arg = 0, .val = 'e' },
{ .name = "gid-idx", .has_arg = 1, .val = 'g' },
{ 0 }
};
c = getopt_long(argc, argv, "p:d:i:s:r:n:l:eg:", long_options, NULL);
if (c == -1)
break;
switch (c) {
case 'p':
port = strtol(optarg, NULL, 0);
if (port < 0 || port > 65535) {
usage(argv[0]);
return 1;
}
break;
case 'd':
ib_devname = strdup(optarg);
break;
case 'i':
ib_port = strtol(optarg, NULL, 0);
if (ib_port < 0) {
usage(argv[0]);
return 1;
}
break;
case 's':
size = strtol(optarg, NULL, 0);
break;
case 'r':
rx_depth = strtol(optarg, NULL, 0);
break;
case 'n':
iters = strtol(optarg, NULL, 0);
break;
case 'l':
sl = strtol(optarg, NULL, 0);
break;
case 'e':
++use_event;
break;
case 'g':
gidx = strtol(optarg, NULL, 0);
break;
default:
usage(argv[0]);
return 1;
}
}
if (optind == argc - 1)
servername = strdup(argv[optind]);
else if (optind < argc) {
usage(argv[0]);
return 1;
}
page_size = sysconf(_SC_PAGESIZE);
dev_list = ibv_get_device_list(NULL);
if (!dev_list) {
perror("Failed to get IB devices list");
return 1;
}
if (!ib_devname) {
ib_dev = *dev_list;
if (!ib_dev) {
fprintf(stderr, "No IB devices found\n");
return 1;
}
} else {
int i;
for (i = 0; dev_list[i]; ++i)
if (!strcmp(ibv_get_device_name(dev_list[i]), ib_devname))
break;
ib_dev = dev_list[i];
if (!ib_dev) {
fprintf(stderr, "IB device %s not found\n", ib_devname);
return 1;
}
}
ctx = pp_init_ctx(ib_dev, size, rx_depth, ib_port, use_event);
if (!ctx)
return 1;
routs = pp_post_recv(ctx, ctx->rx_depth);
if (routs < ctx->rx_depth) {
fprintf(stderr, "Couldn't post receive (%d)\n", routs);
return 1;
}
if (use_event)
if (ibv_req_notify_cq(ctx->cq, 0)) {
fprintf(stderr, "Couldn't request CQ notification\n");
return 1;
}
if (pp_get_port_info(ctx->context, ib_port, &ctx->portinfo)) {
fprintf(stderr, "Couldn't get port info\n");
return 1;
}
my_dest.lid = ctx->portinfo.lid;
my_dest.qpn = ctx->qp->qp_num;
my_dest.psn = lrand48() & 0xffffff;
if (gidx >= 0) {
if (ibv_query_gid(ctx->context, ib_port, gidx, &my_dest.gid)) {
fprintf(stderr, "Could not get local gid for gid index %d\n", gidx);
return 1;
}
} else
memset(&my_dest.gid, 0, sizeof my_dest.gid);
inet_ntop(AF_INET6, &my_dest.gid, gid, sizeof gid);
printf(" local address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x: GID %s\n",
my_dest.lid, my_dest.qpn, my_dest.psn, gid);
if (servername)
rem_dest = pp_client_exch_dest(servername, port, &my_dest);
else
rem_dest = pp_server_exch_dest(ctx, ib_port, port, sl, &my_dest, gidx);
if (!rem_dest)
return 1;
inet_ntop(AF_INET6, &rem_dest->gid, gid, sizeof gid);
printf(" remote address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x, GID %s\n",
rem_dest->lid, rem_dest->qpn, rem_dest->psn, gid);
if (servername)
if (pp_connect_ctx(ctx, ib_port, my_dest.psn, sl, rem_dest, gidx))
return 1;
ctx->pending = PINGPONG_RECV_WRID;
if (servername) {
if (pp_post_send(ctx, rem_dest->qpn)) {
fprintf(stderr, "Couldn't post send\n");
return 1;
}
ctx->pending |= PINGPONG_SEND_WRID;
}
if (gettimeofday(&start, NULL)) {
perror("gettimeofday");
return 1;
}
rcnt = scnt = 0;
while (rcnt < iters || scnt < iters) {
if (use_event) {
struct ibv_cq *ev_cq;
void *ev_ctx;
if (ibv_get_cq_event(ctx->channel, &ev_cq, &ev_ctx)) {
fprintf(stderr, "Failed to get cq_event\n");
return 1;
}
++num_cq_events;
if (ev_cq != ctx->cq) {
fprintf(stderr, "CQ event for unknown CQ %p\n", ev_cq);
return 1;
}
if (ibv_req_notify_cq(ctx->cq, 0)) {
fprintf(stderr, "Couldn't request CQ notification\n");
return 1;
}
}
{
struct ibv_wc wc[2];
int ne, i;
do {
ne = ibv_poll_cq(ctx->cq, 2, wc);
if (ne < 0) {
fprintf(stderr, "poll CQ failed %d\n", ne);
return 1;
}
} while (!use_event && ne < 1);
for (i = 0; i < ne; ++i) {
if (wc[i].status != IBV_WC_SUCCESS) {
fprintf(stderr, "Failed status %s (%d) for wr_id %d\n",
ibv_wc_status_str(wc[i].status),
wc[i].status, (int) wc[i].wr_id);
return 1;
}
switch ((int) wc[i].wr_id) {
case PINGPONG_SEND_WRID:
++scnt;
break;
case PINGPONG_RECV_WRID:
if (--routs <= 1) {
routs += pp_post_recv(ctx, ctx->rx_depth - routs);
if (routs < ctx->rx_depth) {
fprintf(stderr,
"Couldn't post receive (%d)\n",
routs);
return 1;
}
}
++rcnt;
break;
default:
fprintf(stderr, "Completion for unknown wr_id %d\n",
(int) wc[i].wr_id);
return 1;
}
ctx->pending &= ~(int) wc[i].wr_id;
if (scnt < iters && !ctx->pending) {
if (pp_post_send(ctx, rem_dest->qpn)) {
fprintf(stderr, "Couldn't post send\n");
return 1;
}
ctx->pending = PINGPONG_RECV_WRID |
PINGPONG_SEND_WRID;
}
}
}
}
if (gettimeofday(&end, NULL)) {
perror("gettimeofday");
return 1;
}
{
float usec = (end.tv_sec - start.tv_sec) * 1000000 +
(end.tv_usec - start.tv_usec);
long long bytes = (long long) size * iters * 2;
printf("%lld bytes in %.2f seconds = %.2f Mbit/sec\n",
bytes, usec / 1000000., bytes * 8. / usec);
printf("%d iters in %.2f seconds = %.2f usec/iter\n",
iters, usec / 1000000., usec / iters);
}
ibv_ack_cq_events(ctx->cq, num_cq_events);
if (pp_close_ctx(ctx))
return 1;
ibv_free_device_list(dev_list);
free(rem_dest);
return 0;
}

View File

@ -0,0 +1,702 @@
Added support for XRC receive-only QPs.
(OFED 1.3 libibverbs commit 6e99cddf835d4715ea7ca3641944e6285f27f2df)
V2:
1. checkpatch.pl cleanups
2. Fixed u64 alignment problems in kern-abi.h
3. eliminated unneeded default_symvers
4. Added ibv_xrc_rcv_xxx lines to libibverbs.map IBVERBS_1.1
Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
---
include/infiniband/driver.h | 12 ++-
include/infiniband/kern-abi.h | 99 +++++++++++++++++++-
include/infiniband/verbs.h | 123 +++++++++++++++++++++++
src/cmd.c | 215 +++++++++++++++++++++++++++++++++++++++++
src/device.c | 52 +++++-----
src/libibverbs.map | 10 ++
src/verbs.c | 59 +++++++++++
7 files changed, 543 insertions(+), 27 deletions(-)
Index: libibverbs/include/infiniband/driver.h
===================================================================
--- libibverbs.orig/include/infiniband/driver.h 2009-11-01 15:18:20.624171000 +0200
+++ libibverbs/include/infiniband/driver.h 2009-11-01 15:18:24.572283000 +0200
@@ -144,7 +144,17 @@ int ibv_cmd_open_xrc_domain(struct ibv_c
struct ibv_open_xrc_domain_resp *resp,
size_t resp_size);
int ibv_cmd_close_xrc_domain(struct ibv_xrc_domain *d);
-
+int ibv_cmd_create_xrc_rcv_qp(struct ibv_qp_init_attr *init_attr,
+ uint32_t *xrc_rcv_qpn);
+int ibv_cmd_modify_xrc_rcv_qp(struct ibv_xrc_domain *d, uint32_t xrc_rcv_qpn,
+ struct ibv_qp_attr *attr, int attr_mask);
+int ibv_cmd_query_xrc_rcv_qp(struct ibv_xrc_domain *d, uint32_t xrc_rcv_qpn,
+ struct ibv_qp_attr *attr, int attr_mask,
+ struct ibv_qp_init_attr *init_attr);
+int ibv_cmd_reg_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain,
+ uint32_t xrc_qp_num);
+int ibv_cmd_unreg_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain,
+ uint32_t xrc_qp_num);
/*
* sysfs helper functions
Index: libibverbs/include/infiniband/kern-abi.h
===================================================================
--- libibverbs.orig/include/infiniband/kern-abi.h 2009-11-01 15:18:20.629168000 +0200
+++ libibverbs/include/infiniband/kern-abi.h 2009-11-01 15:18:24.577283000 +0200
@@ -88,7 +88,12 @@ enum {
IB_USER_VERBS_CMD_POST_SRQ_RECV,
IB_USER_VERBS_CMD_CREATE_XRC_SRQ,
IB_USER_VERBS_CMD_OPEN_XRC_DOMAIN,
- IB_USER_VERBS_CMD_CLOSE_XRC_DOMAIN
+ IB_USER_VERBS_CMD_CLOSE_XRC_DOMAIN,
+ IB_USER_VERBS_CMD_CREATE_XRC_RCV_QP,
+ IB_USER_VERBS_CMD_MODIFY_XRC_RCV_QP,
+ IB_USER_VERBS_CMD_QUERY_XRC_RCV_QP,
+ IB_USER_VERBS_CMD_REG_XRC_RCV_QP,
+ IB_USER_VERBS_CMD_UNREG_XRC_RCV_QP,
};
/*
@@ -570,6 +575,93 @@ struct ibv_destroy_qp_resp {
__u32 events_reported;
};
+struct ibv_create_xrc_rcv_qp {
+ __u32 command;
+ __u16 in_words;
+ __u16 out_words;
+ __u64 response;
+ __u64 user_handle;
+ __u32 xrc_domain_handle;
+ __u32 max_send_wr;
+ __u32 max_recv_wr;
+ __u32 max_send_sge;
+ __u32 max_recv_sge;
+ __u32 max_inline_data;
+ __u8 sq_sig_all;
+ __u8 qp_type;
+ __u8 reserved[6];
+ __u64 driver_data[0];
+};
+
+struct ibv_create_xrc_rcv_qp_resp {
+ __u32 qpn;
+ __u32 reserved;
+};
+
+struct ibv_modify_xrc_rcv_qp {
+ __u32 command;
+ __u16 in_words;
+ __u16 out_words;
+ __u32 xrc_domain_handle;
+ __u32 qp_num;
+ struct ibv_qp_dest dest;
+ struct ibv_qp_dest alt_dest;
+ __u32 attr_mask;
+ __u32 qkey;
+ __u32 rq_psn;
+ __u32 sq_psn;
+ __u32 dest_qp_num;
+ __u32 qp_access_flags;
+ __u16 pkey_index;
+ __u16 alt_pkey_index;
+ __u8 qp_state;
+ __u8 cur_qp_state;
+ __u8 path_mtu;
+ __u8 path_mig_state;
+ __u8 en_sqd_async_notify;
+ __u8 max_rd_atomic;
+ __u8 max_dest_rd_atomic;
+ __u8 min_rnr_timer;
+ __u8 port_num;
+ __u8 timeout;
+ __u8 retry_cnt;
+ __u8 rnr_retry;
+ __u8 alt_port_num;
+ __u8 alt_timeout;
+ __u8 reserved[6];
+ __u64 driver_data[0];
+};
+
+struct ibv_query_xrc_rcv_qp {
+ __u32 command;
+ __u16 in_words;
+ __u16 out_words;
+ __u64 response;
+ __u32 xrc_domain_handle;
+ __u32 qp_num;
+ __u32 attr_mask;
+ __u32 reserved;
+ __u64 driver_data[0];
+};
+
+struct ibv_reg_xrc_rcv_qp {
+ __u32 command;
+ __u16 in_words;
+ __u16 out_words;
+ __u32 xrc_domain_handle;
+ __u32 qp_num;
+ __u64 driver_data[0];
+};
+
+struct ibv_unreg_xrc_rcv_qp {
+ __u32 command;
+ __u16 in_words;
+ __u16 out_words;
+ __u32 xrc_domain_handle;
+ __u32 qp_num;
+ __u64 driver_data[0];
+};
+
struct ibv_kern_send_wr {
__u64 wr_id;
__u32 num_sge;
@@ -848,6 +940,11 @@ enum {
IB_USER_VERBS_CMD_CREATE_XRC_SRQ_V2 = -1,
IB_USER_VERBS_CMD_OPEN_XRC_DOMAIN_V2 = -1,
IB_USER_VERBS_CMD_CLOSE_XRC_DOMAIN_V2 = -1,
+ IB_USER_VERBS_CMD_CREATE_XRC_RCV_QP_V2 = -1,
+ IB_USER_VERBS_CMD_MODIFY_XRC_RCV_QP_V2 = -1,
+ IB_USER_VERBS_CMD_QUERY_XRC_RCV_QP_V2 = -1,
+ IB_USER_VERBS_CMD_REG_XRC_RCV_QP_V2 = -1,
+ IB_USER_VERBS_CMD_UNREG_XRC_RCV_QP_V2 = -1,
};
struct ibv_destroy_cq_v1 {
Index: libibverbs/include/infiniband/verbs.h
===================================================================
--- libibverbs.orig/include/infiniband/verbs.h 2009-11-01 15:18:20.635171000 +0200
+++ libibverbs/include/infiniband/verbs.h 2009-11-01 15:18:24.585280000 +0200
@@ -205,12 +205,17 @@ enum ibv_event_type {
IBV_EVENT_CLIENT_REREGISTER
};
+enum ibv_event_flags {
+ IBV_XRC_QP_EVENT_FLAG = 0x80000000,
+};
+
struct ibv_async_event {
union {
struct ibv_cq *cq;
struct ibv_qp *qp;
struct ibv_srq *srq;
int port_num;
+ uint32_t xrc_qp_num;
} element;
enum ibv_event_type event_type;
};
@@ -648,6 +653,22 @@ struct ibv_more_ops {
struct ibv_xrc_domain * (*open_xrc_domain)(struct ibv_context *context,
int fd, int oflag);
int (*close_xrc_domain)(struct ibv_xrc_domain *d);
+ int (*create_xrc_rcv_qp)(struct ibv_qp_init_attr *init_attr,
+ uint32_t *xrc_qp_num);
+ int (*modify_xrc_rcv_qp)(struct ibv_xrc_domain *xrc_domain,
+ uint32_t xrc_qp_num,
+ struct ibv_qp_attr *attr,
+ int attr_mask);
+ int (*query_xrc_rcv_qp)(struct ibv_xrc_domain *xrc_domain,
+ uint32_t xrc_qp_num,
+ struct ibv_qp_attr *attr,
+ int attr_mask,
+ struct ibv_qp_init_attr *init_attr);
+ int (*reg_xrc_rcv_qp)(struct ibv_xrc_domain *xrc_domain,
+ uint32_t xrc_qp_num);
+ int (*unreg_xrc_rcv_qp)(struct ibv_xrc_domain *xrc_domain,
+ uint32_t xrc_qp_num);
+
};
struct ibv_context_ops {
@@ -1174,6 +1195,108 @@ struct ibv_xrc_domain *ibv_open_xrc_doma
*/
int ibv_close_xrc_domain(struct ibv_xrc_domain *d);
+/**
+ * ibv_create_xrc_rcv_qp - creates an XRC QP for serving as a receive-side-only QP,
+ *
+ * This QP is created in kernel space, and persists until the last process
+ * registered for the QP calls ibv_unreg_xrc_rcv_qp() (at which time the QP
+ * is destroyed).
+ *
+ * @init_attr: init attributes to use for QP. xrc domain MUST be included here.
+ * All other fields are ignored.
+ *
+ * @xrc_rcv_qpn: qp_num of created QP (if success). To be passed to the
+ * remote node (sender). The remote node will use xrc_rcv_qpn
+ * in ibv_post_send when sending to XRC SRQ's on this host
+ * in the same xrc domain.
+ *
+ * RETURNS: success (0), or a (negative) error value.
+ *
+ * NOTE: this verb also registers the calling user-process with the QP at its
+ * creation time (implicit call to ibv_reg_xrc_rcv_qp), to avoid race
+ * conditions. The creating process will need to call ibv_unreg_xrc_qp()
+ * for the QP to release it from this process.
+ */
+int ibv_create_xrc_rcv_qp(struct ibv_qp_init_attr *init_attr,
+ uint32_t *xrc_rcv_qpn);
+
+/**
+ * ibv_modify_xrc_rcv_qp - modifies an xrc_rcv qp.
+ *
+ * @xrc_domain: xrc domain the QP belongs to (for verification).
+ * @xrc_qp_num: The (24 bit) number of the XRC QP.
+ * @attr: modify-qp attributes. The following fields must be specified:
+ * for RESET_2_INIT: qp_state, pkey_index , port, qp_access_flags
+ * for INIT_2_RTR: qp_state, path_mtu, dest_qp_num, rq_psn,
+ * max_dest_rd_atomic, min_rnr_timer, ah_attr
+ * The QP need not be brought to RTS for the QP to operate as a
+ * receive-only QP.
+ * @attr_mask: bitmap indicating which attributes are provided in the attr
+ * struct. Used for validity checking.
+ * The following bits must be set:
+ * for RESET_2_INIT: IBV_QP_PKEY_INDEX, IBV_QP_PORT,
+ * IBV_QP_ACCESS_FLAGS, IBV_QP_STATE
+ * for INIT_2_RTR: IBV_QP_AV, IBV_QP_PATH_MTU, IBV_QP_DEST_QPN,
+ * IBV_QP_RQ_PSN, IBV_QP_MAX_DEST_RD_ATOMIC,
+ * IBV_QP_MIN_RNR_TIMER, IBV_QP_STATE
+ *
+ * RETURNS: success (0), or a (positive) error value.
+ *
+ */
+int ibv_modify_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain,
+ uint32_t xrc_qp_num,
+ struct ibv_qp_attr *attr, int attr_mask);
+
+/**
+ * ibv_query_xrc_rcv_qp - queries an xrc_rcv qp.
+ *
+ * @xrc_domain: xrc domain the QP belongs to (for verification).
+ * @xrc_qp_num: The (24 bit) number of the XRC QP.
+ * @attr: for returning qp attributes.
+ * @attr_mask: bitmap indicating which attributes to return.
+ * @init_attr: for returning the init attributes
+ *
+ * RETURNS: success (0), or a (positive) error value.
+ *
+ */
+int ibv_query_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain, uint32_t xrc_qp_num,
+ struct ibv_qp_attr *attr, int attr_mask,
+ struct ibv_qp_init_attr *init_attr);
+
+/**
+ * ibv_reg_xrc_rcv_qp: registers a user process with an XRC QP which serves as
+ * a receive-side only QP.
+ *
+ * @xrc_domain: xrc domain the QP belongs to (for verification).
+ * @xrc_qp_num: The (24 bit) number of the XRC QP.
+ *
+ * RETURNS: success (0),
+ * or error (EINVAL), if:
+ * 1. There is no such QP_num allocated.
+ * 2. The QP is allocated, but is not an receive XRC QP
+ * 3. The XRC QP does not belong to the given domain.
+ */
+int ibv_reg_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain, uint32_t xrc_qp_num);
+
+/**
+ * ibv_unreg_xrc_rcv_qp: detaches a user process from an XRC QP serving as
+ * a receive-side only QP. If as a result, there are no remaining
+ * userspace processes registered for this XRC QP, it is destroyed.
+ *
+ * @xrc_domain: xrc domain the QP belongs to (for verification).
+ * @xrc_qp_num: The (24 bit) number of the XRC QP.
+ *
+ * RETURNS: success (0),
+ * or error (EINVAL), if:
+ * 1. There is no such QP_num allocated.
+ * 2. The QP is allocated, but is not an XRC QP
+ * 3. The XRC QP does not belong to the given domain.
+ * NOTE: There is no reason to return a special code if the QP is destroyed.
+ * The unregister simply succeeds.
+ */
+int ibv_unreg_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain,
+ uint32_t xrc_qp_num);
+
END_C_DECLS
# undef __attribute_const
Index: libibverbs/src/cmd.c
===================================================================
--- libibverbs.orig/src/cmd.c 2009-11-01 15:18:20.643167000 +0200
+++ libibverbs/src/cmd.c 2009-11-01 15:18:24.592284000 +0200
@@ -828,6 +828,188 @@ int ibv_cmd_modify_qp(struct ibv_qp *qp,
return 0;
}
+int ibv_cmd_create_xrc_rcv_qp(struct ibv_qp_init_attr *init_attr,
+ uint32_t *xrc_rcv_qpn)
+{
+ struct ibv_create_xrc_rcv_qp cmd;
+ struct ibv_create_xrc_rcv_qp_resp resp;
+
+ if (abi_ver < 6)
+ return ENOSYS;
+
+ IBV_INIT_CMD_RESP(&cmd, sizeof cmd, CREATE_XRC_RCV_QP, &resp,
+ sizeof resp);
+
+ cmd.xrc_domain_handle = init_attr->xrc_domain->handle;
+ cmd.max_send_wr = init_attr->cap.max_send_wr;
+ cmd.max_recv_wr = init_attr->cap.max_recv_wr;
+ cmd.max_send_sge = init_attr->cap.max_send_sge;
+ cmd.max_recv_sge = init_attr->cap.max_recv_sge;
+ cmd.max_inline_data = init_attr->cap.max_inline_data;
+ cmd.sq_sig_all = init_attr->sq_sig_all;
+ cmd.qp_type = init_attr->qp_type;
+ cmd.reserved[0] = cmd.reserved[1] = 0;
+
+ if (write(init_attr->xrc_domain->context->cmd_fd, &cmd, sizeof cmd) !=
+ sizeof cmd)
+ return errno;
+
+ *xrc_rcv_qpn = resp.qpn;
+
+ return 0;
+}
+
+int ibv_cmd_modify_xrc_rcv_qp(struct ibv_xrc_domain *d, uint32_t xrc_qp_num,
+ struct ibv_qp_attr *attr, int attr_mask)
+{
+ struct ibv_modify_xrc_rcv_qp cmd;
+
+ if (abi_ver < 6)
+ return ENOSYS;
+
+ IBV_INIT_CMD(&cmd, sizeof cmd, MODIFY_XRC_RCV_QP);
+
+ cmd.xrc_domain_handle = d->handle;
+ cmd.qp_num = xrc_qp_num;
+ cmd.attr_mask = attr_mask;
+ cmd.qkey = attr->qkey;
+ cmd.rq_psn = attr->rq_psn;
+ cmd.sq_psn = attr->sq_psn;
+ cmd.dest_qp_num = attr->dest_qp_num;
+ cmd.qp_access_flags = attr->qp_access_flags;
+ cmd.pkey_index = attr->pkey_index;
+ cmd.alt_pkey_index = attr->alt_pkey_index;
+ cmd.qp_state = attr->qp_state;
+ cmd.cur_qp_state = attr->cur_qp_state;
+ cmd.path_mtu = attr->path_mtu;
+ cmd.path_mig_state = attr->path_mig_state;
+ cmd.en_sqd_async_notify = attr->en_sqd_async_notify;
+ cmd.max_rd_atomic = attr->max_rd_atomic;
+ cmd.max_dest_rd_atomic = attr->max_dest_rd_atomic;
+ cmd.min_rnr_timer = attr->min_rnr_timer;
+ cmd.port_num = attr->port_num;
+ cmd.timeout = attr->timeout;
+ cmd.retry_cnt = attr->retry_cnt;
+ cmd.rnr_retry = attr->rnr_retry;
+ cmd.alt_port_num = attr->alt_port_num;
+ cmd.alt_timeout = attr->alt_timeout;
+
+ memcpy(cmd.dest.dgid, attr->ah_attr.grh.dgid.raw, 16);
+ cmd.dest.flow_label = attr->ah_attr.grh.flow_label;
+ cmd.dest.dlid = attr->ah_attr.dlid;
+ cmd.dest.reserved = 0;
+ cmd.dest.sgid_index = attr->ah_attr.grh.sgid_index;
+ cmd.dest.hop_limit = attr->ah_attr.grh.hop_limit;
+ cmd.dest.traffic_class = attr->ah_attr.grh.traffic_class;
+ cmd.dest.sl = attr->ah_attr.sl;
+ cmd.dest.src_path_bits = attr->ah_attr.src_path_bits;
+ cmd.dest.static_rate = attr->ah_attr.static_rate;
+ cmd.dest.is_global = attr->ah_attr.is_global;
+ cmd.dest.port_num = attr->ah_attr.port_num;
+
+ memcpy(cmd.alt_dest.dgid, attr->alt_ah_attr.grh.dgid.raw, 16);
+ cmd.alt_dest.flow_label = attr->alt_ah_attr.grh.flow_label;
+ cmd.alt_dest.dlid = attr->alt_ah_attr.dlid;
+ cmd.alt_dest.reserved = 0;
+ cmd.alt_dest.sgid_index = attr->alt_ah_attr.grh.sgid_index;
+ cmd.alt_dest.hop_limit = attr->alt_ah_attr.grh.hop_limit;
+ cmd.alt_dest.traffic_class = attr->alt_ah_attr.grh.traffic_class;
+ cmd.alt_dest.sl = attr->alt_ah_attr.sl;
+ cmd.alt_dest.src_path_bits = attr->alt_ah_attr.src_path_bits;
+ cmd.alt_dest.static_rate = attr->alt_ah_attr.static_rate;
+ cmd.alt_dest.is_global = attr->alt_ah_attr.is_global;
+ cmd.alt_dest.port_num = attr->alt_ah_attr.port_num;
+
+ cmd.reserved[0] = cmd.reserved[1] = 0;
+
+ if (write(d->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd)
+ return errno;
+
+ return 0;
+}
+
+int ibv_cmd_query_xrc_rcv_qp(struct ibv_xrc_domain *d, uint32_t xrc_qp_num,
+ struct ibv_qp_attr *attr, int attr_mask,
+ struct ibv_qp_init_attr *init_attr)
+{
+ struct ibv_query_xrc_rcv_qp cmd;
+ struct ibv_query_qp_resp resp;
+
+ if (abi_ver < 6)
+ return ENOSYS;
+
+ IBV_INIT_CMD_RESP(&cmd, sizeof cmd, QUERY_XRC_RCV_QP, &resp,
+ sizeof resp);
+ cmd.xrc_domain_handle = d->handle;
+ cmd.qp_num = xrc_qp_num;
+ cmd.attr_mask = attr_mask;
+
+ if (write(d->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd)
+ return errno;
+
+ VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp);
+
+ attr->qkey = resp.qkey;
+ attr->rq_psn = resp.rq_psn;
+ attr->sq_psn = resp.sq_psn;
+ attr->dest_qp_num = resp.dest_qp_num;
+ attr->qp_access_flags = resp.qp_access_flags;
+ attr->pkey_index = resp.pkey_index;
+ attr->alt_pkey_index = resp.alt_pkey_index;
+ attr->qp_state = resp.qp_state;
+ attr->cur_qp_state = resp.cur_qp_state;
+ attr->path_mtu = resp.path_mtu;
+ attr->path_mig_state = resp.path_mig_state;
+ attr->sq_draining = resp.sq_draining;
+ attr->max_rd_atomic = resp.max_rd_atomic;
+ attr->max_dest_rd_atomic = resp.max_dest_rd_atomic;
+ attr->min_rnr_timer = resp.min_rnr_timer;
+ attr->port_num = resp.port_num;
+ attr->timeout = resp.timeout;
+ attr->retry_cnt = resp.retry_cnt;
+ attr->rnr_retry = resp.rnr_retry;
+ attr->alt_port_num = resp.alt_port_num;
+ attr->alt_timeout = resp.alt_timeout;
+ attr->cap.max_send_wr = resp.max_send_wr;
+ attr->cap.max_recv_wr = resp.max_recv_wr;
+ attr->cap.max_send_sge = resp.max_send_sge;
+ attr->cap.max_recv_sge = resp.max_recv_sge;
+ attr->cap.max_inline_data = resp.max_inline_data;
+
+ memcpy(attr->ah_attr.grh.dgid.raw, resp.dest.dgid, 16);
+ attr->ah_attr.grh.flow_label = resp.dest.flow_label;
+ attr->ah_attr.dlid = resp.dest.dlid;
+ attr->ah_attr.grh.sgid_index = resp.dest.sgid_index;
+ attr->ah_attr.grh.hop_limit = resp.dest.hop_limit;
+ attr->ah_attr.grh.traffic_class = resp.dest.traffic_class;
+ attr->ah_attr.sl = resp.dest.sl;
+ attr->ah_attr.src_path_bits = resp.dest.src_path_bits;
+ attr->ah_attr.static_rate = resp.dest.static_rate;
+ attr->ah_attr.is_global = resp.dest.is_global;
+ attr->ah_attr.port_num = resp.dest.port_num;
+
+ memcpy(attr->alt_ah_attr.grh.dgid.raw, resp.alt_dest.dgid, 16);
+ attr->alt_ah_attr.grh.flow_label = resp.alt_dest.flow_label;
+ attr->alt_ah_attr.dlid = resp.alt_dest.dlid;
+ attr->alt_ah_attr.grh.sgid_index = resp.alt_dest.sgid_index;
+ attr->alt_ah_attr.grh.hop_limit = resp.alt_dest.hop_limit;
+ attr->alt_ah_attr.grh.traffic_class = resp.alt_dest.traffic_class;
+ attr->alt_ah_attr.sl = resp.alt_dest.sl;
+ attr->alt_ah_attr.src_path_bits = resp.alt_dest.src_path_bits;
+ attr->alt_ah_attr.static_rate = resp.alt_dest.static_rate;
+ attr->alt_ah_attr.is_global = resp.alt_dest.is_global;
+ attr->alt_ah_attr.port_num = resp.alt_dest.port_num;
+
+ init_attr->cap.max_send_wr = resp.max_send_wr;
+ init_attr->cap.max_recv_wr = resp.max_recv_wr;
+ init_attr->cap.max_send_sge = resp.max_send_sge;
+ init_attr->cap.max_recv_sge = resp.max_recv_sge;
+ init_attr->cap.max_inline_data = resp.max_inline_data;
+ init_attr->sq_sig_all = resp.sq_sig_all;
+
+ return 0;
+}
+
static int ibv_cmd_destroy_qp_v1(struct ibv_qp *qp)
{
struct ibv_destroy_qp_v1 cmd;
@@ -1192,3 +1374,36 @@ int ibv_cmd_close_xrc_domain(struct ibv_
return 0;
}
+int ibv_cmd_reg_xrc_rcv_qp(struct ibv_xrc_domain *d, uint32_t xrc_qp_num)
+{
+ struct ibv_reg_xrc_rcv_qp cmd;
+
+ if (abi_ver < 6)
+ return ENOSYS;
+
+ IBV_INIT_CMD(&cmd, sizeof cmd, REG_XRC_RCV_QP);
+ cmd.xrc_domain_handle = d->handle;
+ cmd.qp_num = xrc_qp_num;
+
+ if (write(d->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd)
+ return errno;
+ return 0;
+}
+
+int ibv_cmd_unreg_xrc_rcv_qp(struct ibv_xrc_domain *d, uint32_t xrc_qp_num)
+{
+ struct ibv_unreg_xrc_rcv_qp cmd;
+
+ if (abi_ver < 6)
+ return ENOSYS;
+
+ IBV_INIT_CMD(&cmd, sizeof cmd, UNREG_XRC_RCV_QP);
+ cmd.xrc_domain_handle = d->handle;
+ cmd.qp_num = xrc_qp_num;
+
+ if (write(d->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd)
+ return errno;
+ return 0;
+}
+
+
Index: libibverbs/src/device.c
===================================================================
--- libibverbs.orig/src/device.c 2009-11-01 15:18:17.794116000 +0200
+++ libibverbs/src/device.c 2009-11-01 15:18:24.597279000 +0200
@@ -191,31 +191,33 @@ int __ibv_get_async_event(struct ibv_con
event->event_type = ev.event_type;
- switch (event->event_type) {
- case IBV_EVENT_CQ_ERR:
- event->element.cq = (void *) (uintptr_t) ev.element;
- break;
-
- case IBV_EVENT_QP_FATAL:
- case IBV_EVENT_QP_REQ_ERR:
- case IBV_EVENT_QP_ACCESS_ERR:
- case IBV_EVENT_COMM_EST:
- case IBV_EVENT_SQ_DRAINED:
- case IBV_EVENT_PATH_MIG:
- case IBV_EVENT_PATH_MIG_ERR:
- case IBV_EVENT_QP_LAST_WQE_REACHED:
- event->element.qp = (void *) (uintptr_t) ev.element;
- break;
-
- case IBV_EVENT_SRQ_ERR:
- case IBV_EVENT_SRQ_LIMIT_REACHED:
- event->element.srq = (void *) (uintptr_t) ev.element;
- break;
-
- default:
- event->element.port_num = ev.element;
- break;
- }
+ if (event->event_type & IBV_XRC_QP_EVENT_FLAG) {
+ event->element.xrc_qp_num = ev.element;
+ } else
+ switch (event->event_type) {
+ case IBV_EVENT_CQ_ERR:
+ event->element.cq = (void *) (uintptr_t) ev.element;
+ break;
+
+ case IBV_EVENT_QP_FATAL:
+ case IBV_EVENT_QP_REQ_ERR:
+ case IBV_EVENT_QP_ACCESS_ERR:
+ case IBV_EVENT_COMM_EST:
+ case IBV_EVENT_SQ_DRAINED:
+ case IBV_EVENT_PATH_MIG:
+ case IBV_EVENT_PATH_MIG_ERR:
+ case IBV_EVENT_QP_LAST_WQE_REACHED:
+ event->element.qp = (void *) (uintptr_t) ev.element;
+ break;
+
+ case IBV_EVENT_SRQ_ERR:
+ case IBV_EVENT_SRQ_LIMIT_REACHED:
+ event->element.srq = (void *) (uintptr_t) ev.element;
+ break;
+ default:
+ event->element.port_num = ev.element;
+ break;
+ }
if (context->ops.async_event)
context->ops.async_event(event);
Index: libibverbs/src/libibverbs.map
===================================================================
--- libibverbs.orig/src/libibverbs.map 2009-11-01 15:18:20.646169000 +0200
+++ libibverbs/src/libibverbs.map 2009-11-01 15:18:24.600279000 +0200
@@ -97,6 +97,16 @@ IBVERBS_1.1 {
ibv_cmd_open_xrc_domain;
ibv_close_xrc_domain;
ibv_cmd_close_xrc_domain;
+ ibv_create_xrc_rcv_qp;
+ ibv_cmd_create_xrc_rcv_qp;
+ ibv_modify_xrc_rcv_qp;
+ ibv_cmd_modify_xrc_rcv_qp;
+ ibv_query_xrc_rcv_qp;
+ ibv_cmd_query_xrc_rcv_qp;
+ ibv_reg_xrc_rcv_qp;
+ ibv_cmd_reg_xrc_rcv_qp;
+ ibv_unreg_xrc_rcv_qp;
+ ibv_cmd_unreg_xrc_rcv_qp;
ibv_node_type_str;
ibv_port_state_str;
Index: libibverbs/src/verbs.c
===================================================================
--- libibverbs.orig/src/verbs.c 2009-11-01 15:18:20.650169000 +0200
+++ libibverbs/src/verbs.c 2009-11-01 15:18:24.604279000 +0200
@@ -597,3 +597,62 @@ int ibv_close_xrc_domain(struct ibv_xrc_
return d->context->more_ops->close_xrc_domain(d);
}
+
+int ibv_create_xrc_rcv_qp(struct ibv_qp_init_attr *init_attr,
+ uint32_t *xrc_rcv_qpn)
+{
+ struct ibv_context *c;
+ if (!init_attr || !(init_attr->xrc_domain))
+ return EINVAL;
+
+ c = init_attr->xrc_domain->context;
+ if (!c->more_ops)
+ return ENOSYS;
+
+ return c->more_ops->create_xrc_rcv_qp(init_attr,
+ xrc_rcv_qpn);
+}
+
+int ibv_modify_xrc_rcv_qp(struct ibv_xrc_domain *d,
+ uint32_t xrc_rcv_qpn,
+ struct ibv_qp_attr *attr,
+ int attr_mask)
+{
+ if (!d || !attr)
+ return EINVAL;
+
+ if (!d->context->more_ops)
+ return ENOSYS;
+
+ return d->context->more_ops->modify_xrc_rcv_qp(d, xrc_rcv_qpn, attr,
+ attr_mask);
+}
+
+int ibv_query_xrc_rcv_qp(struct ibv_xrc_domain *d,
+ uint32_t xrc_rcv_qpn,
+ struct ibv_qp_attr *attr,
+ int attr_mask,
+ struct ibv_qp_init_attr *init_attr)
+{
+ if (!d)
+ return EINVAL;
+
+ if (!d->context->more_ops)
+ return ENOSYS;
+
+ return d->context->more_ops->query_xrc_rcv_qp(d, xrc_rcv_qpn, attr,
+ attr_mask, init_attr);
+}
+
+int ibv_reg_xrc_rcv_qp(struct ibv_xrc_domain *d,
+ uint32_t xrc_rcv_qpn)
+{
+ return d->context->more_ops->reg_xrc_rcv_qp(d, xrc_rcv_qpn);
+}
+
+int ibv_unreg_xrc_rcv_qp(struct ibv_xrc_domain *d,
+ uint32_t xrc_rcv_qpn)
+{
+ return d->context->more_ops->unreg_xrc_rcv_qp(d, xrc_rcv_qpn);
+}
+

View File

@ -0,0 +1,503 @@
This patch includes the following commits from OFED 1.3 libibverbs:
Implement eXtended Reliable Connections (a7df4af8eb84738f36db4161a4272fa02fc6741e)
Re-define IBV_DEVICE_XRC to conform to its new position (5042a9cab0ae2f7ad61bdf88dfed6fb10b700797)
Set "is_srq" flag only when the QP has an SRQ (6f6d29e74ca0c19a8821990aad603e3c575b7f4d)
for XRC QPs, return xrc_domain in ibv_query_qp (018c44a44ff0344dfe7cf5f6598f81d81769164e)
V2:
1. checkpatch.pl cleanups
2. fixed u64 alignment problems in uverbs.h ABI structs
3. eliminated unnecessary default_symvers
4. modified xrc_ops to more_ops
Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
include/infiniband/driver.h | 11 +++++
include/infiniband/kern-abi.h | 47 ++++++++++++++++++++++-
include/infiniband/verbs.h | 85 ++++++++++++++++++++++++++++++++++++++++-
src/cmd.c | 72 ++++++++++++++++++++++++++++++++++-
src/libibverbs.map | 6 +++
src/verbs.c | 54 ++++++++++++++++++++++++++
6 files changed, 271 insertions(+), 4 deletions(-)
Index: libibverbs/include/infiniband/driver.h
===================================================================
--- libibverbs.orig/include/infiniband/driver.h 2009-11-01 15:18:17.920111000 +0200
+++ libibverbs/include/infiniband/driver.h 2009-11-01 15:18:20.624171000 +0200
@@ -99,6 +99,11 @@ int ibv_cmd_create_srq(struct ibv_pd *pd
struct ibv_srq *srq, struct ibv_srq_init_attr *attr,
struct ibv_create_srq *cmd, size_t cmd_size,
struct ibv_create_srq_resp *resp, size_t resp_size);
+int ibv_cmd_create_xrc_srq(struct ibv_pd *pd,
+ struct ibv_srq *srq, struct ibv_srq_init_attr *attr,
+ uint32_t xrc_domain, uint32_t xrc_cq,
+ struct ibv_create_xrc_srq *cmd, size_t cmd_size,
+ struct ibv_create_srq_resp *resp, size_t resp_size);
int ibv_cmd_modify_srq(struct ibv_srq *srq,
struct ibv_srq_attr *srq_attr,
int srq_attr_mask,
@@ -134,6 +139,12 @@ int ibv_cmd_detach_mcast(struct ibv_qp *
int ibv_dontfork_range(void *base, size_t size);
int ibv_dofork_range(void *base, size_t size);
+int ibv_cmd_open_xrc_domain(struct ibv_context *context, int fd, int oflag,
+ struct ibv_xrc_domain *d,
+ struct ibv_open_xrc_domain_resp *resp,
+ size_t resp_size);
+int ibv_cmd_close_xrc_domain(struct ibv_xrc_domain *d);
+
/*
* sysfs helper functions
Index: libibverbs/include/infiniband/kern-abi.h
===================================================================
--- libibverbs.orig/include/infiniband/kern-abi.h 2009-11-01 15:18:17.921121000 +0200
+++ libibverbs/include/infiniband/kern-abi.h 2009-11-01 15:18:20.629168000 +0200
@@ -85,7 +85,10 @@ enum {
IB_USER_VERBS_CMD_MODIFY_SRQ,
IB_USER_VERBS_CMD_QUERY_SRQ,
IB_USER_VERBS_CMD_DESTROY_SRQ,
- IB_USER_VERBS_CMD_POST_SRQ_RECV
+ IB_USER_VERBS_CMD_POST_SRQ_RECV,
+ IB_USER_VERBS_CMD_CREATE_XRC_SRQ,
+ IB_USER_VERBS_CMD_OPEN_XRC_DOMAIN,
+ IB_USER_VERBS_CMD_CLOSE_XRC_DOMAIN
};
/*
@@ -706,6 +709,21 @@ struct ibv_create_srq {
__u64 driver_data[0];
};
+struct ibv_create_xrc_srq {
+ __u32 command;
+ __u16 in_words;
+ __u16 out_words;
+ __u64 response;
+ __u64 user_handle;
+ __u32 pd_handle;
+ __u32 max_wr;
+ __u32 max_sge;
+ __u32 srq_limit;
+ __u32 xrcd_handle;
+ __u32 xrc_cq;
+ __u64 driver_data[0];
+};
+
struct ibv_create_srq_resp {
__u32 srq_handle;
__u32 max_wr;
@@ -754,6 +772,30 @@ struct ibv_destroy_srq_resp {
__u32 events_reported;
};
+struct ibv_open_xrc_domain {
+ __u32 command;
+ __u16 in_words;
+ __u16 out_words;
+ __u64 response;
+ __u32 fd;
+ __u32 oflags;
+ __u64 driver_data[0];
+};
+
+struct ibv_open_xrc_domain_resp {
+ __u32 xrcd_handle;
+};
+
+struct ibv_close_xrc_domain {
+ __u32 command;
+ __u16 in_words;
+ __u16 out_words;
+ __u64 response;
+ __u32 xrcd_handle;
+ __u32 reserved;
+ __u64 driver_data[0];
+};
+
/*
* Compatibility with older ABI versions
*/
@@ -803,6 +845,9 @@ enum {
* trick opcodes in IBV_INIT_CMD() doesn't break.
*/
IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL_V2 = -1,
+ IB_USER_VERBS_CMD_CREATE_XRC_SRQ_V2 = -1,
+ IB_USER_VERBS_CMD_OPEN_XRC_DOMAIN_V2 = -1,
+ IB_USER_VERBS_CMD_CLOSE_XRC_DOMAIN_V2 = -1,
};
struct ibv_destroy_cq_v1 {
Index: libibverbs/include/infiniband/verbs.h
===================================================================
--- libibverbs.orig/include/infiniband/verbs.h 2009-11-01 15:18:17.924118000 +0200
+++ libibverbs/include/infiniband/verbs.h 2009-11-01 15:18:20.635171000 +0200
@@ -92,7 +92,8 @@ enum ibv_device_cap_flags {
IBV_DEVICE_SYS_IMAGE_GUID = 1 << 11,
IBV_DEVICE_RC_RNR_NAK_GEN = 1 << 12,
IBV_DEVICE_SRQ_RESIZE = 1 << 13,
- IBV_DEVICE_N_NOTIFY_CQ = 1 << 14
+ IBV_DEVICE_N_NOTIFY_CQ = 1 << 14,
+ IBV_DEVICE_XRC = 1 << 20
};
enum ibv_atomic_cap {
@@ -371,6 +372,11 @@ struct ibv_ah_attr {
uint8_t port_num;
};
+struct ibv_xrc_domain {
+ struct ibv_context *context;
+ uint32_t handle;
+};
+
enum ibv_srq_attr_mask {
IBV_SRQ_MAX_WR = 1 << 0,
IBV_SRQ_LIMIT = 1 << 1
@@ -390,7 +396,8 @@ struct ibv_srq_init_attr {
enum ibv_qp_type {
IBV_QPT_RC = 2,
IBV_QPT_UC,
- IBV_QPT_UD
+ IBV_QPT_UD,
+ IBV_QPT_XRC
};
struct ibv_qp_cap {
@@ -409,6 +416,7 @@ struct ibv_qp_init_attr {
struct ibv_qp_cap cap;
enum ibv_qp_type qp_type;
int sq_sig_all;
+ struct ibv_xrc_domain *xrc_domain;
};
enum ibv_qp_attr_mask {
@@ -527,6 +535,7 @@ struct ibv_send_wr {
uint32_t remote_qkey;
} ud;
} wr;
+ uint32_t xrc_remote_srq_num;
};
struct ibv_recv_wr {
@@ -554,6 +563,10 @@ struct ibv_srq {
pthread_mutex_t mutex;
pthread_cond_t cond;
uint32_t events_completed;
+
+ uint32_t xrc_srq_num;
+ struct ibv_xrc_domain *xrc_domain;
+ struct ibv_cq *xrc_cq;
};
struct ibv_qp {
@@ -571,6 +584,8 @@ struct ibv_qp {
pthread_mutex_t mutex;
pthread_cond_t cond;
uint32_t events_completed;
+
+ struct ibv_xrc_domain *xrc_domain;
};
struct ibv_comp_channel {
@@ -625,6 +640,16 @@ struct ibv_device {
char ibdev_path[IBV_SYSFS_PATH_MAX];
};
+struct ibv_more_ops {
+ struct ibv_srq * (*create_xrc_srq)(struct ibv_pd *pd,
+ struct ibv_xrc_domain *xrc_domain,
+ struct ibv_cq *xrc_cq,
+ struct ibv_srq_init_attr *srq_init_attr);
+ struct ibv_xrc_domain * (*open_xrc_domain)(struct ibv_context *context,
+ int fd, int oflag);
+ int (*close_xrc_domain)(struct ibv_xrc_domain *d);
+};
+
struct ibv_context_ops {
int (*query_device)(struct ibv_context *context,
struct ibv_device_attr *device_attr);
@@ -691,6 +716,7 @@ struct ibv_context {
int num_comp_vectors;
pthread_mutex_t mutex;
void *abi_compat;
+ struct ibv_more_ops *more_ops;
};
/**
@@ -913,6 +939,25 @@ struct ibv_srq *ibv_create_srq(struct ib
struct ibv_srq_init_attr *srq_init_attr);
/**
+ * ibv_create_xrc_srq - Creates a SRQ associated with the specified protection
+ * domain and xrc domain.
+ * @pd: The protection domain associated with the SRQ.
+ * @xrc_domain: The XRC domain associated with the SRQ.
+ * @xrc_cq: CQ to report completions for XRC packets on.
+ *
+ * @srq_init_attr: A list of initial attributes required to create the SRQ.
+ *
+ * srq_attr->max_wr and srq_attr->max_sge are read the determine the
+ * requested size of the SRQ, and set to the actual values allocated
+ * on return. If ibv_create_srq() succeeds, then max_wr and max_sge
+ * will always be at least as large as the requested values.
+ */
+struct ibv_srq *ibv_create_xrc_srq(struct ibv_pd *pd,
+ struct ibv_xrc_domain *xrc_domain,
+ struct ibv_cq *xrc_cq,
+ struct ibv_srq_init_attr *srq_init_attr);
+
+/**
* ibv_modify_srq - Modifies the attributes for the specified SRQ.
* @srq: The SRQ to modify.
* @srq_attr: On input, specifies the SRQ attributes to modify. On output,
@@ -1093,6 +1138,42 @@ const char *ibv_port_state_str(enum ibv_
*/
const char *ibv_event_type_str(enum ibv_event_type event);
+/**
+ * ibv_open_xrc_domain - open an XRC domain
+ * Returns a reference to an XRC domain.
+ *
+ * @context: Device context
+ * @fd: descriptor for inode associated with the domain
+ * If fd == -1, no inode is associated with the domain; in this ca= se,
+ * the only legal value for oflag is O_CREAT
+ *
+ * @oflag: oflag values are constructed by OR-ing flags from the following list
+ *
+ * O_CREAT
+ * If a domain belonging to device named by context is already associated
+ * with the inode, this flag has no effect, except as noted under O_EXCL
+ * below. Otherwise, a new XRC domain is created and is associated with
+ * inode specified by fd.
+ *
+ * O_EXCL
+ * If O_EXCL and O_CREAT are set, open will fail if a domain associated with
+ * the inode exists. The check for the existence of the domain and creation
+ * of the domain if it does not exist is atomic with respect to other
+ * processes executing open with fd naming the same inode.
+ */
+struct ibv_xrc_domain *ibv_open_xrc_domain(struct ibv_context *context,
+ int fd, int oflag);
+
+/**
+ * ibv_close_xrc_domain - close an XRC domain
+ * If this is the last reference, destroys the domain.
+ *
+ * @d: reference to XRC domain to close
+ *
+ * close is implicitly performed at process exit.
+ */
+int ibv_close_xrc_domain(struct ibv_xrc_domain *d);
+
END_C_DECLS
# undef __attribute_const
Index: libibverbs/src/cmd.c
===================================================================
--- libibverbs.orig/src/cmd.c 2009-11-01 15:18:17.927111000 +0200
+++ libibverbs/src/cmd.c 2009-11-01 15:18:20.643167000 +0200
@@ -483,6 +483,34 @@ int ibv_cmd_create_srq(struct ibv_pd *pd
return 0;
}
+int ibv_cmd_create_xrc_srq(struct ibv_pd *pd,
+ struct ibv_srq *srq, struct ibv_srq_init_attr *attr,
+ uint32_t xrcd_handle, uint32_t xrc_cq,
+ struct ibv_create_xrc_srq *cmd, size_t cmd_size,
+ struct ibv_create_srq_resp *resp, size_t resp_size)
+{
+ IBV_INIT_CMD_RESP(cmd, cmd_size, CREATE_XRC_SRQ, resp, resp_size);
+ cmd->user_handle = (uintptr_t) srq;
+ cmd->pd_handle = pd->handle;
+ cmd->max_wr = attr->attr.max_wr;
+ cmd->max_sge = attr->attr.max_sge;
+ cmd->srq_limit = attr->attr.srq_limit;
+ cmd->xrcd_handle = xrcd_handle;
+ cmd->xrc_cq = xrc_cq;
+
+ if (write(pd->context->cmd_fd, cmd, cmd_size) != cmd_size)
+ return errno;
+
+ VALGRIND_MAKE_MEM_DEFINED(resp, resp_size);
+
+ srq->handle = resp->srq_handle;
+ srq->context = pd->context;
+ attr->attr.max_wr = resp->max_wr;
+ attr->attr.max_sge = resp->max_sge;
+
+ return 0;
+}
+
static int ibv_cmd_modify_srq_v3(struct ibv_srq *srq,
struct ibv_srq_attr *srq_attr,
int srq_attr_mask,
@@ -603,7 +631,6 @@ int ibv_cmd_create_qp(struct ibv_pd *pd,
cmd->pd_handle = pd->handle;
cmd->send_cq_handle = attr->send_cq->handle;
cmd->recv_cq_handle = attr->recv_cq->handle;
- cmd->srq_handle = attr->srq ? attr->srq->handle : 0;
cmd->max_send_wr = attr->cap.max_send_wr;
cmd->max_recv_wr = attr->cap.max_recv_wr;
cmd->max_send_sge = attr->cap.max_send_sge;
@@ -612,6 +639,9 @@ int ibv_cmd_create_qp(struct ibv_pd *pd,
cmd->sq_sig_all = attr->sq_sig_all;
cmd->qp_type = attr->qp_type;
cmd->is_srq = !!attr->srq;
+ cmd->srq_handle = attr->qp_type == IBV_QPT_XRC ?
+ (attr->xrc_domain ? attr->xrc_domain->handle : 0) :
+ (attr->srq ? attr->srq->handle : 0);
cmd->reserved = 0;
if (write(pd->context->cmd_fd, cmd, cmd_size) != cmd_size)
@@ -722,6 +752,8 @@ int ibv_cmd_query_qp(struct ibv_qp *qp,
init_attr->recv_cq = qp->recv_cq;
init_attr->srq = qp->srq;
init_attr->qp_type = qp->qp_type;
+ if (qp->qp_type == IBV_QPT_XRC)
+ init_attr->xrc_domain = qp->xrc_domain;
init_attr->cap.max_send_wr = resp.max_send_wr;
init_attr->cap.max_recv_wr = resp.max_recv_wr;
init_attr->cap.max_send_sge = resp.max_send_sge;
@@ -1122,3 +1154,41 @@ int ibv_cmd_detach_mcast(struct ibv_qp *
return 0;
}
+
+int ibv_cmd_open_xrc_domain(struct ibv_context *context, int fd, int oflag,
+ struct ibv_xrc_domain *d,
+ struct ibv_open_xrc_domain_resp *resp,
+ size_t resp_size)
+{
+ struct ibv_open_xrc_domain cmd;
+
+ if (abi_ver < 6)
+ return ENOSYS;
+
+ IBV_INIT_CMD_RESP(&cmd, sizeof cmd, OPEN_XRC_DOMAIN, resp, resp_size);
+ cmd.fd = fd;
+ cmd.oflags = oflag;
+
+ if (write(context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd)
+ return errno;
+
+ d->handle = resp->xrcd_handle;
+
+ return 0;
+}
+
+int ibv_cmd_close_xrc_domain(struct ibv_xrc_domain *d)
+{
+ struct ibv_close_xrc_domain cmd;
+
+ if (abi_ver < 6)
+ return ENOSYS;
+
+ IBV_INIT_CMD(&cmd, sizeof cmd, CLOSE_XRC_DOMAIN);
+ cmd.xrcd_handle = d->handle;
+
+ if (write(d->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd)
+ return errno;
+ return 0;
+}
+
Index: libibverbs/src/libibverbs.map
===================================================================
--- libibverbs.orig/src/libibverbs.map 2009-11-01 15:18:17.928115000 +0200
+++ libibverbs/src/libibverbs.map 2009-11-01 15:18:20.646169000 +0200
@@ -91,6 +91,12 @@ IBVERBS_1.1 {
ibv_dontfork_range;
ibv_dofork_range;
ibv_register_driver;
+ ibv_create_xrc_srq;
+ ibv_cmd_create_xrc_srq;
+ ibv_open_xrc_domain;
+ ibv_cmd_open_xrc_domain;
+ ibv_close_xrc_domain;
+ ibv_cmd_close_xrc_domain;
ibv_node_type_str;
ibv_port_state_str;
Index: libibverbs/src/verbs.c
===================================================================
--- libibverbs.orig/src/verbs.c 2009-11-01 15:18:17.931119000 +0200
+++ libibverbs/src/verbs.c 2009-11-01 15:18:20.650169000 +0200
@@ -366,6 +366,9 @@ struct ibv_srq *__ibv_create_srq(struct
srq->context = pd->context;
srq->srq_context = srq_init_attr->srq_context;
srq->pd = pd;
+ srq->xrc_domain = NULL;
+ srq->xrc_cq = NULL;
+ srq->xrc_srq_num = 0;
srq->events_completed = 0;
pthread_mutex_init(&srq->mutex, NULL);
pthread_cond_init(&srq->cond, NULL);
@@ -375,6 +378,32 @@ struct ibv_srq *__ibv_create_srq(struct
}
default_symver(__ibv_create_srq, ibv_create_srq);
+struct ibv_srq *ibv_create_xrc_srq(struct ibv_pd *pd,
+ struct ibv_xrc_domain *xrc_domain,
+ struct ibv_cq *xrc_cq,
+ struct ibv_srq_init_attr *srq_init_attr)
+{
+ struct ibv_srq *srq;
+
+ if (!pd->context->more_ops)
+ return NULL;
+
+ srq = pd->context->more_ops->create_xrc_srq(pd, xrc_domain,
+ xrc_cq, srq_init_attr);
+ if (srq) {
+ srq->context = pd->context;
+ srq->srq_context = srq_init_attr->srq_context;
+ srq->pd = pd;
+ srq->xrc_domain = xrc_domain;
+ srq->xrc_cq = xrc_cq;
+ srq->events_completed = 0;
+ pthread_mutex_init(&srq->mutex, NULL);
+ pthread_cond_init(&srq->cond, NULL);
+ }
+
+ return srq;
+}
+
int __ibv_modify_srq(struct ibv_srq *srq,
struct ibv_srq_attr *srq_attr,
int srq_attr_mask)
@@ -410,6 +439,8 @@ struct ibv_qp *__ibv_create_qp(struct ib
qp->qp_type = qp_init_attr->qp_type;
qp->state = IBV_QPS_RESET;
qp->events_completed = 0;
+ qp->xrc_domain = qp_init_attr->qp_type == IBV_QPT_XRC ?
+ qp_init_attr->xrc_domain : NULL;
pthread_mutex_init(&qp->mutex, NULL);
pthread_cond_init(&qp->cond, NULL);
}
@@ -543,3 +574,26 @@ int __ibv_detach_mcast(struct ibv_qp *qp
return qp->context->ops.detach_mcast(qp, gid, lid);
}
default_symver(__ibv_detach_mcast, ibv_detach_mcast);
+
+struct ibv_xrc_domain *ibv_open_xrc_domain(struct ibv_context *context,
+ int fd, int oflag)
+{
+ struct ibv_xrc_domain *d;
+
+ if (!context->more_ops)
+ return NULL;
+
+ d = context->more_ops->open_xrc_domain(context, fd, oflag);
+ if (d)
+ d->context = context;
+
+ return d;
+}
+
+int ibv_close_xrc_domain(struct ibv_xrc_domain *d)
+{
+ if (!d->context->more_ops)
+ return 0;
+
+ return d->context->more_ops->close_xrc_domain(d);
+}

View File

@ -0,0 +1,686 @@
commit b7c5820ce48a4fc3c8464872f0a554df6e7bbb47
Author: Dotan Barak <dotanb@mellanox.co.il>
Date: Mon Feb 25 16:50:38 2008 +0200
Add XRC (eXtended Reliable Connection) support to all of the relevant man pages
and add new man pages to new XRC verbs.
Signed-off-by: Dotan Barak <dotanb@dev.mellanox.co.il>
Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
diff --git a/man/ibv_create_qp.3 b/man/ibv_create_qp.3
index abd5449..fb6f041 100644
Index: libibverbs/man/ibv_create_qp.3
===================================================================
--- libibverbs.orig/man/ibv_create_qp.3 2008-06-05 15:21:54.000000000 +0300
+++ libibverbs/man/ibv_create_qp.3 2008-06-05 16:25:21.000000000 +0300
@@ -28,8 +28,9 @@ struct ibv_cq *send_cq;
struct ibv_cq *recv_cq; /* CQ to be associated with the Receive Queue (RQ) */
struct ibv_srq *srq; /* SRQ handle if QP is to be associated with an SRQ, otherwise NULL */
struct ibv_qp_cap cap; /* QP capabilities */
-enum ibv_qp_type qp_type; /* QP Transport Service Type: IBV_QPT_RC, IBV_QPT_UC, or IBV_QPT_UD */
+enum ibv_qp_type qp_type; /* QP Transport Service Type: IBV_QPT_RC, IBV_QPT_UC, IBV_QPT_UD or IBV_QPT_XRC */
int sq_sig_all; /* If set, each Work Request (WR) submitted to the SQ generates a completion entry */
+struct ibv_xrc_domain *xrc_domain; /* XRC domain the QP will be associated with (valid only for IBV_QPT_XRC QP), otherwise NULL */
.in -8
};
.sp
Index: libibverbs/man/ibv_create_srq.3
===================================================================
--- libibverbs.orig/man/ibv_create_srq.3 2008-06-05 15:21:54.000000000 +0300
+++ libibverbs/man/ibv_create_srq.3 2008-06-05 16:25:21.000000000 +0300
@@ -10,12 +10,26 @@ ibv_create_srq, ibv_destroy_srq \- creat
.BI "struct ibv_srq *ibv_create_srq(struct ibv_pd " "*pd" ", struct "
.BI " ibv_srq_init_attr " "*srq_init_attr" );
.sp
+.BI "struct ibv_srq *ibv_create_xrc_srq(struct ibv_pd " "*pd" ",
+.BI " struct ibv_xrc_domain " "*xrc_domain" ",
+.BI " struct ibv_cq " "*xrc_cq" ",
+.BI " struct ibv_srq_init_attr " "*srq_init_attr" );
+.sp
.BI "int ibv_destroy_srq(struct ibv_srq " "*srq" );
.fi
.SH "DESCRIPTION"
.B ibv_create_srq()
creates a shared receive queue (SRQ) associated with the protection domain
.I pd\fR.
+.PP
+.B ibv_create_xrc_srq()
+creates an XRC shared receive queue (SRQ) associated with the protection domain
+.I pd\fR,
+the XRC domain
+.I xrc_domain
+and the CQ which will hold the XRC completion
+.I xrc_cq\fR.
+.PP
The argument
.I srq_init_attr
is an ibv_srq_init_attr struct, as defined in <infiniband/verbs.h>.
Index: libibverbs/man/ibv_create_xrc_rcv_qp.3
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ libibverbs/man/ibv_create_xrc_rcv_qp.3 2008-06-05 16:25:21.000000000 +0300
@@ -0,0 +1,70 @@
+.\" -*- nroff -*-
+.\"
+.TH IBV_CREATE_XRC_RCV_QP 3 2008-02-10 libibverbs "Libibverbs Programmer's Manual"
+.SH "NAME"
+ibv_create_xrc_rcv_qp \- create an XRC queue pair (QP) for serving as a receive-side only QP
+.SH "SYNOPSIS"
+.nf
+.B #include <infiniband/verbs.h>
+.sp
+.BI "int ibv_create_xrc_rcv_qp(struct ibv_qp_init_attr " "*init_attr" ,
+.BI " uint32_t " "*xrc_rcv_qpn" );
+.fi
+.SH "DESCRIPTION"
+.B ibv_create_xrc_rcv_qp()
+creates an XRC queue pair (QP) for serving as a receive-side only QP and returns its number through the pointer
+.I xrc_rcv_qpn\fR.
+This QP number should be passed to the remote node (sender).
+The remote node will use
+.I xrc_rcv_qpn
+in
+.B ibv_post_send()
+when sending to an XRC SRQ on this host in the same xrc domain as the XRC receive QP.
+This QP is created in kernel space, and persists until the last process registered for the QP
+calls
+.B ibv_unreg_xrc_rcv_qp()
+(at which time the QP is destroyed).
+.PP
+The process which creates this QP is automatically registered for it, and should also call
+.B ibv_unreg_xrc_rcv_qp()
+at some point, to unregister.
+
+Processes which wish to receive on an XRC SRQ via this QP should call
+.B ibv_reg_xrc_rcv_qp()
+for this QP, to guarantee that the QP will not be destroyed while they are still using it for receiving on the XRC SRQ.
+.PP
+The argument
+.I qp_init_attr
+is an ibv_qp_init_attr struct, as defined in <infiniband/verbs.h>.
+.PP
+.nf
+struct ibv_qp_init_attr {
+.in +8
+void *qp_context; /* value is being ignored */
+struct ibv_cq *send_cq; /* value is being ignored */
+struct ibv_cq *recv_cq; /* value is being ignored */
+struct ibv_srq *srq; /* value is being ignored */
+struct ibv_qp_cap cap; /* value is being ignored */
+enum ibv_qp_type qp_type; /* value is being ignored */
+int sq_sig_all; /* value is being ignored */
+struct ibv_xrc_domain *xrc_domain; /* XRC domain the QP will be associated with */
+.in -8
+};
+.fi
+.PP
+Most of the attributes in
+.I qp_init_attr
+are being ignored because this QP is a receive only QP and all RR are being posted to an SRQ.
+.SH "RETURN VALUE"
+.B ibv_create_xrc_rcv_qp()
+returns 0 on success, or the value of errno on failure (which indicates the failure reason).
+.SH "SEE ALSO"
+.BR ibv_open_xrc_domain (3),
+.BR ibv_modify_xrc_rcv_qp (3),
+.BR ibv_query_xrc_rcv_qp (3),
+.BR ibv_reg_xrc_rcv_qp (3),
+.BR ibv_unreg_xrc_rcv_qp (3),
+.BR ibv_post_send (3)
+.SH "AUTHORS"
+.TP
+Dotan Barak <dotanb@mellanox.co.il>
Index: libibverbs/man/ibv_modify_xrc_rcv_qp.3
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ libibverbs/man/ibv_modify_xrc_rcv_qp.3 2008-06-05 16:25:21.000000000 +0300
@@ -0,0 +1,141 @@
+.\" -*- nroff -*-
+.\"
+.TH IBV_MODIFY_XRC_RCV_QP 3 2008-02-10 libibverbs "Libibverbs Programmer's Manual"
+.SH "NAME"
+ibv_modify_xrc_rcv_qp \- modify the attributes of an XRC receive queue pair (QP)
+.SH "SYNOPSIS"
+.nf
+.B #include <infiniband/verbs.h>
+.sp
+.BI "int ibv_modify_xrc_rcv_qp(struct ibv_xrc_domain " "*xrc_domain" ", uint32_t " "xrc_qp_num" ,
+.BI " struct ibv_qp_attr " "*attr" ", int " "attr_mask" );
+.fi
+.SH "DESCRIPTION"
+.B ibv_modify_qp()
+modifies the attributes of an XRC receive QP with the number
+.I xrc_qp_num
+which is associated with the XRC domain
+.I xrc_domain
+with the attributes in
+.I attr
+according to the mask
+.I attr_mask
+and move the QP state through the following transitions: Reset -> Init -> RTR.
+.I attr_mask
+should indicate all of the attributes which will be used in this QP transition and the following masks (at least) should be set:
+.PP
+.nf
+Next state Required attributes
+\-\-\-\-\-\-\-\-\-\- \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+Init \fB IBV_QP_STATE, IBV_QP_PKEY_INDEX, IBV_QP_PORT, \fR
+ \fB IBV_QP_ACCESS_FLAGS \fR
+RTR \fB IBV_QP_STATE, IBV_QP_AV, IBV_QP_PATH_MTU, \fR
+ \fB IBV_QP_DEST_QPN, IBV_QP_RQ_PSN, \fR
+ \fB IBV_QP_MAX_DEST_RD_ATOMIC, IBV_QP_MIN_RNR_TIMER \fR
+.fi
+.PP
+The user can add optional attributes as well.
+.PP
+The argument \fIattr\fR is an ibv_qp_attr struct, as defined in <infiniband/verbs.h>.
+.PP
+.nf
+struct ibv_qp_attr {
+.in +8
+enum ibv_qp_state qp_state; /* Move the QP to this state */
+enum ibv_qp_state cur_qp_state; /* Assume this is the current QP state */
+enum ibv_mtu path_mtu; /* Path MTU (valid only for RC/UC QPs) */
+enum ibv_mig_state path_mig_state; /* Path migration state (valid if HCA supports APM) */
+uint32_t qkey; /* Q_Key for the QP (valid only for UD QPs) */
+uint32_t rq_psn; /* PSN for receive queue (valid only for RC/UC QPs) */
+uint32_t sq_psn; /* PSN for send queue (valid only for RC/UC QPs) */
+uint32_t dest_qp_num; /* Destination QP number (valid only for RC/UC QPs) */
+int qp_access_flags; /* Mask of enabled remote access operations (valid only for RC/UC QPs) */
+struct ibv_qp_cap cap; /* QP capabilities (valid if HCA supports QP resizing) */
+struct ibv_ah_attr ah_attr; /* Primary path address vector (valid only for RC/UC QPs) */
+struct ibv_ah_attr alt_ah_attr; /* Alternate path address vector (valid only for RC/UC QPs) */
+uint16_t pkey_index; /* Primary P_Key index */
+uint16_t alt_pkey_index; /* Alternate P_Key index */
+uint8_t en_sqd_async_notify; /* Enable SQD.drained async notification (Valid only if qp_state is SQD) */
+uint8_t sq_draining; /* Is the QP draining? Irrelevant for ibv_modify_qp() */
+uint8_t max_rd_atomic; /* Number of outstanding RDMA reads & atomic operations on the destination QP (valid only for RC QPs) */
+uint8_t max_dest_rd_atomic; /* Number of responder resources for handling incoming RDMA reads & atomic operations (valid only for RC QPs) */
+uint8_t min_rnr_timer; /* Minimum RNR NAK timer (valid only for RC QPs) */
+uint8_t port_num; /* Primary port number */
+uint8_t timeout; /* Local ack timeout for primary path (valid only for RC QPs) */
+uint8_t retry_cnt; /* Retry count (valid only for RC QPs) */
+uint8_t rnr_retry; /* RNR retry (valid only for RC QPs) */
+uint8_t alt_port_num; /* Alternate port number */
+uint8_t alt_timeout; /* Local ack timeout for alternate path (valid only for RC QPs) */
+.in -8
+};
+.fi
+.PP
+For details on struct ibv_qp_cap see the description of
+.B ibv_create_qp()\fR.
+For details on struct ibv_ah_attr see the description of
+.B ibv_create_ah()\fR.
+.PP
+The argument
+.I attr_mask
+specifies the QP attributes to be modified.
+The argument is either 0 or the bitwise OR of one or more of the following flags:
+.PP
+.TP
+.B IBV_QP_STATE \fR Modify qp_state
+.TP
+.B IBV_QP_CUR_STATE \fR Set cur_qp_state
+.TP
+.B IBV_QP_EN_SQD_ASYNC_NOTIFY \fR Set en_sqd_async_notify
+.TP
+.B IBV_QP_ACCESS_FLAGS \fR Set qp_access_flags
+.TP
+.B IBV_QP_PKEY_INDEX \fR Set pkey_index
+.TP
+.B IBV_QP_PORT \fR Set port_num
+.TP
+.B IBV_QP_QKEY \fR Set qkey
+.TP
+.B IBV_QP_AV \fR Set ah_attr
+.TP
+.B IBV_QP_PATH_MTU \fR Set path_mtu
+.TP
+.B IBV_QP_TIMEOUT \fR Set timeout
+.TP
+.B IBV_QP_RETRY_CNT \fR Set retry_cnt
+.TP
+.B IBV_QP_RNR_RETRY \fR Set rnr_retry
+.TP
+.B IBV_QP_RQ_PSN \fR Set rq_psn
+.TP
+.B IBV_QP_MAX_QP_RD_ATOMIC \fR Set max_rd_atomic
+.TP
+.B IBV_QP_ALT_PATH \fR Set the alternative path via: alt_ah_attr, alt_pkey_index, alt_port_num, alt_timeout
+.TP
+.B IBV_QP_MIN_RNR_TIMER \fR Set min_rnr_timer
+.TP
+.B IBV_QP_SQ_PSN \fR Set sq_psn
+.TP
+.B IBV_QP_MAX_DEST_RD_ATOMIC \fR Set max_dest_rd_atomic
+.TP
+.B IBV_QP_PATH_MIG_STATE \fR Set path_mig_state
+.TP
+.B IBV_QP_CAP \fR Set cap
+.TP
+.B IBV_QP_DEST_QPN \fR Set dest_qp_num
+.SH "RETURN VALUE"
+.B ibv_modify_xrc_rcv_qp()
+returns 0 on success, or the value of errno on failure (which indicates the failure reason).
+.SH "NOTES"
+If any of the modify attributes or the modify mask are invalid, none
+of the attributes will be modified (including the QP state).
+.PP
+Not all devices support alternate paths. To check if a device supports it, check if the
+.B IBV_DEVICE_AUTO_PATH_MIG
+bit is set in the device capabilities flags.
+.SH "SEE ALSO"
+.BR ibv_open_xrc_domain (3),
+.BR ibv_create_xrc_rcv_qp (3),
+.BR ibv_query_xrc_rcv_qp (3)
+.SH "AUTHORS"
+.TP
+Dotan Barak <dotanb@mellanox.co.il>
Index: libibverbs/man/ibv_open_xrc_domain.3
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ libibverbs/man/ibv_open_xrc_domain.3 2008-06-05 16:25:21.000000000 +0300
@@ -0,0 +1,80 @@
+.\" -*- nroff -*-
+.\"
+.TH IBV_OPEN_XRC_DOMAIN 3 2008-02-10 libibverbs "Libibverbs Programmer's Manual"
+.SH "NAME"
+ibv_open_xrc_domain, ibv_close_xrc_domain \- open or close an eXtended Reliable Connection (XRC) domain
+.SH "SYNOPSIS"
+.nf
+.B #include <fcntl.h>
+.B #include <infiniband/verbs.h>
+.sp
+.BI "struct ibv_xrc_domain *ibv_open_xrc_domain(struct ibv_context " "*context" ","
+.BI " int " "fd" ", int " "oflag" );
+.nl
+.BI "int ibv_close_xrc_domain(struct ibv_xrc_domain " "*d" );
+.fi
+.SH "DESCRIPTION"
+.B ibv_open_xrc_domain()
+open an XRC domain for the InfiniBand device context
+.I context
+or return a reference to an opened one\fR.
+.I fd
+is the file descriptor to be associated with the XRC domain.
+The argument
+.I oflag
+describes the desired file creation attributes; it is either 0 or the bitwise OR of one or more of the following flags:
+.PP
+.TP
+.B O_CREAT
+If a domain belonging to device named by context is already associated with the inode, this flag has
+no effect, except as noted under
+.BR O_EXCL
+below. Otherwise, a new XRC domain is created and is associated with inode specified by
+.IR fd\fR.
+.TP
+.B O_EXCL
+If
+.BR O_EXCL
+and
+.BR O_CREAT
+are set, open will fail if a domain associated with the inode exists.
+The check for the existence of the domain and creation
+of the domain if it does not exist is atomic with respect to other
+processes executing open with
+.IR fd
+naming the same inode.
+.PP
+If
+.I fd
+equals -1, no inode is is associated with the domain, and the only valid value for
+.I oflag
+is
+.B O_CREAT\fR.
+.PP
+.B ibv_close_xrc_domain()
+closes the XRC domain
+.I d\fR.
+If this is the last reference, the XRC domain will be destroyed.
+.SH "RETURN VALUE"
+.B ibv_open_xrc_domain()
+returns a pointer to an opened XRC, or NULL if the request fails.
+.PP
+.B ibv_close_xrc_domain()
+returns 0 on success, or the value of errno on failure (which indicates the failure reason).
+.SH "NOTES"
+Not all devices support XRC. To check if a device supports it, check if the
+.B IBV_DEVICE_XRC
+bit is set in the device capabilities flags.
+.PP
+.B ibv_close_xrc_domain()
+may fail if any QP or SRQ are still associated with the XRC domain being closed.
+.SH "SEE ALSO"
+.BR ibv_create_xrc_srq (3),
+.BR ibv_create_qp (3),
+.BR ibv_create_xrc_rcv_qp (3),
+.BR ibv_modify_xrc_rcv_qp (3),
+.BR ibv_query_xrc_rcv_qp (3),
+.BR ibv_reg_xrc_rcv_qp (3)
+.SH "AUTHORS"
+.TP
+Dotan Barak <dotanb@mellanox.co.il>
Index: libibverbs/man/ibv_post_send.3
===================================================================
--- libibverbs.orig/man/ibv_post_send.3 2008-06-05 15:21:55.000000000 +0300
+++ libibverbs/man/ibv_post_send.3 2008-06-05 16:25:21.000000000 +0300
@@ -60,6 +60,7 @@ uint32_t remote_qkey; /* Q_Key
} ud;
.in -8
} wr;
+uint32_t xrc_remote_srq_num; /* SRQ number of the destination XRC */
.in -8
};
.sp
@@ -76,15 +77,15 @@ uint32_t lkey;
Each QP Transport Service Type supports a specific set of opcodes, as shown in the following table:
.PP
.nf
-OPCODE | IBV_QPT_UD | IBV_QPT_UC | IBV_QPT_RC
-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-
-IBV_WR_SEND | X | X | X
-IBV_WR_SEND_WITH_IMM | X | X | X
-IBV_WR_RDMA_WRITE | | X | X
-IBV_WR_RDMA_WRITE_WITH_IMM | | X | X
-IBV_WR_RDMA_READ | | | X
-IBV_WR_ATOMIC_CMP_AND_SWP | | | X
-IBV_WR_ATOMIC_FETCH_AND_ADD | | | X
+OPCODE | IBV_QPT_UD | IBV_QPT_UC | IBV_QPT_RC | IBV_QPT_XRC
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-
+IBV_WR_SEND | X | X | X | X
+IBV_WR_SEND_WITH_IMM | X | X | X | X
+IBV_WR_RDMA_WRITE | | X | X | X
+IBV_WR_RDMA_WRITE_WITH_IMM | | X | X | X
+IBV_WR_RDMA_READ | | | X | X
+IBV_WR_ATOMIC_CMP_AND_SWP | | | X | X
+IBV_WR_ATOMIC_FETCH_AND_ADD | | | X | X
.fi
.PP
The attribute send_flags describes the properties of the \s-1WR\s0. It is either 0 or the bitwise \s-1OR\s0 of one or more of the following flags:
@@ -114,6 +115,7 @@ IBV_SEND_INLINE flag was set, the buffer
after the call returns.
.SH "SEE ALSO"
.BR ibv_create_qp (3),
+.BR ibv_create_xrc_rcv_qp (3),
.BR ibv_create_ah (3),
.BR ibv_post_recv (3),
.BR ibv_post_srq_recv (3),
Index: libibverbs/man/ibv_query_xrc_rcv_qp.3
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ libibverbs/man/ibv_query_xrc_rcv_qp.3 2008-06-05 16:25:21.000000000 +0300
@@ -0,0 +1,89 @@
+.\" -*- nroff -*-
+.\"
+.TH IBV_QUERY_XRC_RCV_QP 3 2008-02-10 libibverbs "Libibverbs Programmer's Manual"
+.SH "NAME"
+ibv_query_xrc_rcv_qp \- get the attributes of an XRC receive queue pair (QP)
+.SH "SYNOPSIS"
+.nf
+.B #include <infiniband/verbs.h>
+.sp
+.BI "int ibv_query_xrc_rcv_qp(struct ibv_xrc_domain " "*xrc_domain" ", uint32_t " "xrc_qp_num" ,
+.BI " struct ibv_qp_attr " "*attr" ", int " "attr_mask" ,
+.BI " struct ibv_qp_init_attr " "*init_attr" );
+.fi
+.SH "DESCRIPTION"
+.B ibv_query_xrc_rcv_qp()
+gets the attributes specified in
+.I attr_mask
+for the XRC receive QP with the number
+.I xrc_qp_num
+which is associated with the XRC domain
+.I xrc_domain
+and returns them through the pointers
+.I attr
+and
+.I init_attr\fR.
+The argument
+.I attr
+is an ibv_qp_attr struct, as defined in <infiniband/verbs.h>.
+.PP
+.nf
+struct ibv_qp_attr {
+.in +8
+enum ibv_qp_state qp_state; /* Current QP state */
+enum ibv_qp_state cur_qp_state; /* Current QP state - irrelevant for ibv_query_qp */
+enum ibv_mtu path_mtu; /* Path MTU (valid only for RC/UC QPs) */
+enum ibv_mig_state path_mig_state; /* Path migration state (valid if HCA supports APM) */
+uint32_t qkey; /* Q_Key of the QP (valid only for UD QPs) */
+uint32_t rq_psn; /* PSN for receive queue (valid only for RC/UC QPs) */
+uint32_t sq_psn; /* PSN for send queue (valid only for RC/UC QPs) */
+uint32_t dest_qp_num; /* Destination QP number (valid only for RC/UC QPs) */
+int qp_access_flags; /* Mask of enabled remote access operations (valid only for RC/UC QPs) */
+struct ibv_qp_cap cap; /* QP capabilities */
+struct ibv_ah_attr ah_attr; /* Primary path address vector (valid only for RC/UC QPs) */
+struct ibv_ah_attr alt_ah_attr; /* Alternate path address vector (valid only for RC/UC QPs) */
+uint16_t pkey_index; /* Primary P_Key index */
+uint16_t alt_pkey_index; /* Alternate P_Key index */
+uint8_t en_sqd_async_notify; /* Enable SQD.drained async notification - irrelevant for ibv_query_qp */
+uint8_t sq_draining; /* Is the QP draining? (Valid only if qp_state is SQD) */
+uint8_t max_rd_atomic; /* Number of outstanding RDMA reads & atomic operations on the destination QP (valid only for RC QPs) */
+uint8_t max_dest_rd_atomic; /* Number of responder resources for handling incoming RDMA reads & atomic operations (valid only for RC QPs) */
+uint8_t min_rnr_timer; /* Minimum RNR NAK timer (valid only for RC QPs) */
+uint8_t port_num; /* Primary port number */
+uint8_t timeout; /* Local ack timeout for primary path (valid only for RC QPs) */
+uint8_t retry_cnt; /* Retry count (valid only for RC QPs) */
+uint8_t rnr_retry; /* RNR retry (valid only for RC QPs) */
+uint8_t alt_port_num; /* Alternate port number */
+uint8_t alt_timeout; /* Local ack timeout for alternate path (valid only for RC QPs) */
+.in -8
+};
+.fi
+.PP
+For details on struct ibv_qp_cap see the description of
+.B ibv_create_qp()\fR.
+For details on struct ibv_ah_attr see the description of
+.B ibv_create_ah()\fR.
+.SH "RETURN VALUE"
+.B ibv_query_xrc_rcv_qp()
+returns 0 on success, or the value of errno on failure (which indicates the failure reason).
+.SH "NOTES"
+The argument
+.I attr_mask
+is a hint that specifies the minimum list of attributes to retrieve.
+Some InfiniBand devices may return extra attributes not requested, for
+example if the value can be returned cheaply.
+.PP
+Attribute values are valid if they have been set using
+.B ibv_modify_xrc_rcv_qp()\fR.
+The exact list of valid attributes depends on the QP state.
+.PP
+Multiple calls to
+.B ibv_query_xrc_rcv_qp()
+may yield some differences in the values returned for the following attributes: qp_state, path_mig_state, sq_draining, ah_attr (if APM is enabled).
+.SH "SEE ALSO"
+.BR ibv_open_xrc_domain (3),
+.BR ibv_create_xrc_rcv_qp (3),
+.BR ibv_modify_xrc_rcv_qp (3)
+.SH "AUTHORS"
+.TP
+Dotan Barak <dotanb@mellanox.co.il>
Index: libibverbs/man/ibv_reg_xrc_rcv_qp.3
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ libibverbs/man/ibv_reg_xrc_rcv_qp.3 2008-06-05 16:25:21.000000000 +0300
@@ -0,0 +1,57 @@
+.\" -*- nroff -*-
+.\"
+.TH IBV_REG_XRC_RCV_QP 3 2008-10-02 libibverbs "Libibverbs Programmer's Manual"
+.SH "NAME"
+ibv_reg_xrc_rcv_qp, ibv_unreg_xrc_rcv_qp \- register and unregister a user process with an XRC receive queue pair (QP)
+.SH "SYNOPSIS"
+.nf
+.B #include <infiniband/verbs.h>
+.sp
+.BI "int ibv_reg_xrc_rcv_qp(struct ibv_xrc_domain " "*xrc_domain" ", uint32_t " "xrc_qp_num" ");
+.nl
+.BI "int ibv_unreg_xrc_rcv_qp(struct ibv_xrc_domain " "*xrc_domain" ", uint32_t " "xrc_qp_num" ");
+.fi
+.SH "DESCRIPTION"
+.B ibv_reg_xrc_rcv_qp()
+registers a user process with the XRC receive QP (created via
+.B ibv_create_xrc_rcv_qp()
+) whose number is
+.I xrc_qp_num\fR,
+and which is associated with the XRC domain
+.I xrc_domain\fR.
+.PP
+.B ibv_unreg_xrc_rcv_qp()
+unregisters a user process from the XRC receive QP number
+.I xrc_qp_num\fR,
+which is associated with the XRC domain
+.I xrc_domain\fR.
+When the number of user processes registered with this XRC receive QP drops to zero, the QP is destroyed.
+.SH "RETURN VALUE"
+.B ibv_reg_xrc_rcv_qp()
+and
+.B ibv_unreg_xrc_rcv_qp()
+returns 0 on success, or the value of errno on failure (which indicates the failure reason).
+.SH "NOTES"
+.B ibv_reg_xrc_rcv_qp()
+and
+.B ibv_unreg_xrc_rcv_qp()
+may fail if the number
+.I xrc_qp_num
+is not a number of a valid XRC receive QP (the QP is not allocated or it is the number of a non-XRC QP), or
+the XRC receive QP was created with an XRC domain other than
+.I xrc_domain\fR.
+
+If a process is still registered with any XRC RCV QPs belonging to some domain,
+.B ibv_close_xrc_domain()
+will return failure if called for that domain in that process.
+
+.B ibv_create_xrc_rcv_qp()
+performs an implicit registration for the creating process; when that process is finished with the XRC RCV QP, it should call
+.B ibv_unreg_xrc_rcv_qp()
+for that QP. Note that if no other processes are registered with the QP at this time, its registration count will drop to zero and it will be destroyed.
+.SH "SEE ALSO"
+.BR ibv_open_xrc_domain (3),
+.BR ibv_create_xrc_rcv_qp (3)
+.SH "AUTHORS"
+.TP
+Dotan Barak <dotanb@mellanox.co.il>
Index: libibverbs/man/verbs.7
===================================================================
--- libibverbs.orig/man/verbs.7 2008-06-05 15:24:00.000000000 +0300
+++ libibverbs/man/verbs.7 2008-06-05 16:25:21.000000000 +0300
@@ -1,6 +1,6 @@
.\" -*- nroff -*-
.\"
-.TH VERBS 7 2008-01-17 libibverbs "Libibverbs Programmer's Manual"
+.TH VERBS 7 2008-02-25 libibverbs "Libibverbs Programmer's Manual"
.SH "NAME"
verbs \- Infiniband verbs library
.SH "SYNOPSIS"
@@ -8,7 +8,7 @@ verbs \- Infiniband verbs library
.B #include <infiniband/verbs.h>
.fi
.SH "DESCRIPTION"
-This library is an implementation of the verbs according to the Infiniband specification volume 1.2. It handles the control path of creating, modifying, querying and destroying resources such as Protection Domains (PD), Completion Queues (CQ), Queue-Pairs (QP), Shared Receive Queues (SRQ), Address Handles (AH), Memory Regions (MR). It also handles sending and receiving data posted to QPs and SRQs, getting completions from CQs using polling and completions events.
+This library is an implementation of the verbs based on the Infiniband specification volume 1.2 chapter 11. It handles the control path of creating, modifying, querying and destroying resources such as Protection Domains (PD), Completion Queues (CQ), Queue-Pairs (QP), Shared Receive Queues (SRQ), Address Handles (AH), Memory Regions (MR). It also handles sending and receiving data posted to QPs and SRQs, getting completions from CQs using polling and completions events.
The control path is implemented through system calls to the uverbs kernel module which further calls the low level HW driver. The data path is implemented through calls made to low level HW library which in most cases interacts directly with the HW providing kernel and network stack bypass (saving context/mode switches) along with zero copy and an asynchronous I/O model.
@@ -117,6 +117,25 @@ int ibv_modify_srq(struct ibv_srq *srq,
enum ibv_srq_attr_mask srq_attr_mask);
int ibv_query_srq(struct ibv_srq *srq, struct ibv_srq_attr *srq_attr);
+.B eXtended Reliable Connection control
+
+struct ibv_xrc_domain *ibv_open_xrc_domain(struct ibv_context *context,
+ int fd, int oflag);
+int ibv_close_xrc_domain(struct ibv_xrc_domain *d);
+struct ibv_srq *ibv_create_xrc_srq(struct ibv_pd *pd,
+ struct ibv_xrc_domain *xrc_domain,
+ struct ibv_cq *xrc_cq,
+ struct ibv_srq_init_attr *srq_init_attr);
+int ibv_create_xrc_rcv_qp(struct ibv_qp_init_attr *init_attr,
+ uint32_t *xrc_rcv_qpn);
+int ibv_modify_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain, uint32_t xrc_qp_num,
+ struct ibv_qp_attr *attr, int attr_mask);
+int ibv_query_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain, uint32_t xrc_qp_num,
+ struct ibv_qp_attr *attr, int attr_mask,
+ struct ibv_qp_init_attr *init_attr);
+int ibv_reg_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain, uint32_t xrc_qp_num);
+int ibv_unreg_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain, uint32_t xrc_qp_num);
+
.B Queue Pair control
struct ibv_qp *ibv_create_qp(struct ibv_pd *pd,
@@ -183,6 +202,14 @@ enum ibv_rate mult_to_ibv_rate(int mult)
\fIibv_destroy_srq\fP(),
\fIibv_modify_srq\fP(),
\fIibv_query_srq\fP(),
+\fIibv_open_xrc_domain\fP(),
+\fIibv_close_xrc_domain\fP(),
+\fIibv_create_xrc_srq\fP(),
+\fIibv_create_xrc_rcv_qp\fP(),
+\fIibv_modify_xrc_rcv_qp\fP(),
+\fIibv_query_xrc_rcv_qp\fP(),
+\fIibv_reg_xrc_rcv_qp\fP(),
+\fIibv_unreg_xrc_rcv_qp\fP(),
\fIibv_post_srq_recv\fP(),
\fIibv_create_qp\fP(),
\fIibv_destroy_qp\fP(),
Index: libibverbs/Makefile.am
===================================================================
--- libibverbs.orig/Makefile.am 2008-06-05 15:24:00.000000000 +0300
+++ libibverbs/Makefile.am 2008-06-05 16:39:27.000000000 +0300
@@ -44,15 +44,18 @@ man_MANS = man/ibv_asyncwatch.1 man/ibv_
man/ibv_srq_pingpong.1 man/ibv_alloc_pd.3 man/ibv_attach_mcast.3 \
man/ibv_create_ah.3 man/ibv_create_ah_from_wc.3 \
man/ibv_create_comp_channel.3 man/ibv_create_cq.3 \
- man/ibv_create_qp.3 man/ibv_create_srq.3 man/ibv_event_type_str.3 \
+ man/ibv_create_qp.3 man/ibv_create_srq.3 \
+ man/ibv_create_xrc_rcv_qp.3 man/ibv_event_type_str.3 \
man/ibv_fork_init.3 man/ibv_get_async_event.3 \
man/ibv_get_cq_event.3 man/ibv_get_device_guid.3 \
man/ibv_get_device_list.3 man/ibv_get_device_name.3 \
- man/ibv_modify_qp.3 man/ibv_modify_srq.3 man/ibv_open_device.3 \
+ man/ibv_modify_qp.3 man/ibv_modify_srq.3 man/ibv_modify_xrc_rcv_qp.3 \
+ man/ibv_open_device.3 man/ibv_open_xrc_domain.3 \
man/ibv_poll_cq.3 man/ibv_post_recv.3 man/ibv_post_send.3 \
man/ibv_post_srq_recv.3 man/ibv_query_device.3 man/ibv_query_gid.3 \
man/ibv_query_pkey.3 man/ibv_query_port.3 man/ibv_query_qp.3 \
- man/ibv_query_srq.3 man/ibv_rate_to_mult.3 man/ibv_reg_mr.3 \
+ man/ibv_query_srq.3 man/ibv_query_xrc_rcv_qp.3 \
+ man/ibv_rate_to_mult.3 man/ibv_reg_mr.3 man/ibv_reg_xrc_rcv_qp.3 \
man/ibv_req_notify_cq.3 man/ibv_resize_cq.3 man/verbs.7
DEBIAN = debian/changelog debian/compat debian/control debian/copyright \
@@ -74,6 +77,8 @@ install-data-hook:
$(RM) ibv_ack_async_event.3 && \
$(RM) ibv_ack_cq_events.3 && \
$(RM) ibv_close_device.3 && \
+ $(RM) ibv_close_xrc_domain.3 && \
+ $(RM) ibv_create_xrc_srq.3 && \
$(RM) ibv_dealloc_pd.3 && \
$(RM) ibv_dereg_mr.3 && \
$(RM) ibv_destroy_ah.3 && \
@@ -84,12 +89,15 @@ install-data-hook:
$(RM) ibv_detach_mcast.3 && \
$(RM) ibv_free_device_list.3 && \
$(RM) ibv_init_ah_from_wc.3 && \
+ $(RM) ibv_unreg_xrc_rcv_qp.3 && \
$(RM) mult_to_ibv_rate.3 && \
$(RM) ibv_node_type_str.3 && \
$(RM) ibv_port_state_str.3 && \
$(LN_S) ibv_get_async_event.3 ibv_ack_async_event.3 && \
$(LN_S) ibv_get_cq_event.3 ibv_ack_cq_events.3 && \
$(LN_S) ibv_open_device.3 ibv_close_device.3 && \
+ $(LN_S) ibv_open_xrc_domain.3 ibv_close_xrc_domain.3 && \
+ $(LN_S) ibv_create_srq.3 ibv_create_xrc_srq.3 && \
$(LN_S) ibv_alloc_pd.3 ibv_dealloc_pd.3 && \
$(LN_S) ibv_reg_mr.3 ibv_dereg_mr.3 && \
$(LN_S) ibv_create_ah.3 ibv_destroy_ah.3 && \
@@ -100,6 +108,7 @@ install-data-hook:
$(LN_S) ibv_attach_mcast.3 ibv_detach_mcast.3 && \
$(LN_S) ibv_get_device_list.3 ibv_free_device_list.3 && \
$(LN_S) ibv_create_ah_from_wc.3 ibv_init_ah_from_wc.3 && \
+ $(LN_S) ibv_reg_xrc_rcv_qp.3 ibv_unreg_xrc_rcv_qp.3 && \
$(LN_S) ibv_rate_to_mult.3 mult_to_ibv_rate.3 && \
$(LN_S) ibv_event_type_str.3 ibv_node_type_str.3 && \
$(LN_S) ibv_event_type_str.3 ibv_port_state_str.3

View File

@ -0,0 +1,25 @@
From 8f2b7717984fe025d357023bdd2e1b17cd7bcb0b Mon Sep 17 00:00:00 2001
From: Jack Morgenstein <jackm@dev.mellanox.co.il>
Date: Mon, 7 Jun 2010 18:21:53 +0300
Subject: configure.in -- add AC_PROG_LIBTOOL for earlier versions of automake.
Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
---
configure.in | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/configure.in b/configure.in
index 83368a9..d0678c8 100644
--- a/configure.in
+++ b/configure.in
@@ -13,6 +13,7 @@ AC_PROG_CC
AC_GNU_SOURCE
AC_PROG_LN_S
+AC_PROG_LIBTOOL
LT_INIT
AC_ARG_WITH([valgrind],
--
1.6.3.2

View File

@ -0,0 +1,62 @@
move pthread_cond_t fields to the end of structs, because
their size changed from RHAS4 to RHAS5. In all the cases,
the intervening entries were not accessed outside libibverbs
(in non-XRC applications).
The structs modified are: ibv_cq, ibv_srq, and ibv_qp.
(OFED 1.3 libibverbs commit 4c29c266a3c0932cd06e8f2b4e238aecd3c65dcc)
Pointed out by: Changqing Tang <changquing.tang@hp.com>
Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
Index: libibverbs/include/infiniband/verbs.h
===================================================================
--- libibverbs.orig/include/infiniband/verbs.h 2009-11-01 15:18:24.585280000 +0200
+++ libibverbs/include/infiniband/verbs.h 2009-11-01 15:18:28.759417000 +0200
@@ -565,13 +565,14 @@ struct ibv_srq {
struct ibv_pd *pd;
uint32_t handle;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
uint32_t events_completed;
uint32_t xrc_srq_num;
struct ibv_xrc_domain *xrc_domain;
struct ibv_cq *xrc_cq;
+
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
};
struct ibv_qp {
@@ -586,11 +587,12 @@ struct ibv_qp {
enum ibv_qp_state state;
enum ibv_qp_type qp_type;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
uint32_t events_completed;
struct ibv_xrc_domain *xrc_domain;
+
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
};
struct ibv_comp_channel {
@@ -606,10 +608,11 @@ struct ibv_cq {
uint32_t handle;
int cqe;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
uint32_t comp_events_completed;
uint32_t async_events_completed;
+
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
};
struct ibv_ah {

View File

@ -0,0 +1,28 @@
libibverbs: add raw ethernet QP type IBV_QPT_RAW_ETH=7
The patch enables usage of L2 raw ethernet QP type for user-space
applications.
Miroslaw Walukiewicz
Signed-off-by: Mirek Walukiewicz <miroslaw.walukiewicz@intel.com>
---
include/infiniband/verbs.h | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/include/infiniband/verbs.h b/include/infiniband/verbs.h
index fe9ab62..a340ffb 100644
--- a/include/infiniband/verbs.h
+++ b/include/infiniband/verbs.h
@@ -397,7 +397,8 @@ enum ibv_qp_type {
IBV_QPT_RC = 2,
IBV_QPT_UC,
IBV_QPT_UD,
- IBV_QPT_XRC
+ IBV_QPT_XRC,
+ IBV_QPT_RAW_ETH = 8
};
struct ibv_qp_cap {

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,112 @@
[PATCHv7 3/4] libibverbs: Add API to retrieve eth MAC
Add a command to retrieve the MAC address of a port's GID. This is required by
libraries to build work requests when the port's link layer is Ethernet.
Signed-off-by: Eli Cohen <eli@mellanox.co.il>
---
include/infiniband/driver.h | 1 +
include/infiniband/kern-abi.h | 20 +++++++++++++++++++-
src/cmd.c | 19 +++++++++++++++++++
src/libibverbs.map | 1 +
4 files changed, 40 insertions(+), 1 deletions(-)
Index: libibverbs/include/infiniband/driver.h
===================================================================
--- libibverbs.orig/include/infiniband/driver.h 2010-02-18 13:48:37.000000000 +0200
+++ libibverbs/include/infiniband/driver.h 2010-02-18 13:50:53.000000000 +0200
@@ -136,6 +136,11 @@ int ibv_cmd_create_ah(struct ibv_pd *pd,
int ibv_cmd_destroy_ah(struct ibv_ah *ah);
int ibv_cmd_attach_mcast(struct ibv_qp *qp, const union ibv_gid *gid, uint16_t lid);
int ibv_cmd_detach_mcast(struct ibv_qp *qp, const union ibv_gid *gid, uint16_t lid);
+int ibv_cmd_get_eth_l2_addr(struct ibv_pd *pd, uint8_t port, const union ibv_gid *gid,
+ int sgid_idx, uint8_t *mac, uint16_t *vlan_id);
+
+int ibv_cmd_get_eth_l2_addr(struct ibv_pd *pd, uint8_t port, const union ibv_gid *gid,
+ int sgid_idx, uint8_t *mac, uint16_t *vlan_id);
int ibv_dontfork_range(void *base, size_t size);
int ibv_dofork_range(void *base, size_t size);
Index: libibverbs/include/infiniband/kern-abi.h
===================================================================
--- libibverbs.orig/include/infiniband/kern-abi.h 2010-02-18 13:48:46.000000000 +0200
+++ libibverbs/include/infiniband/kern-abi.h 2010-02-18 13:50:53.000000000 +0200
@@ -94,6 +94,7 @@ enum {
IB_USER_VERBS_CMD_QUERY_XRC_RCV_QP,
IB_USER_VERBS_CMD_REG_XRC_RCV_QP,
IB_USER_VERBS_CMD_UNREG_XRC_RCV_QP,
+ IB_USER_VERBS_CMD_GET_ETH_L2_ADDR,
};
/*
@@ -946,6 +947,7 @@ enum {
IB_USER_VERBS_CMD_QUERY_XRC_RCV_QP_V2 = -1,
IB_USER_VERBS_CMD_REG_XRC_RCV_QP_V2 = -1,
IB_USER_VERBS_CMD_UNREG_XRC_RCV_QP_V2 = -1,
+ IB_USER_VERBS_CMD_GET_ETH_L2_ADDR_V2 = -1,
};
struct ibv_destroy_cq_v1 {
@@ -1021,4 +1023,21 @@ struct ibv_create_srq_resp_v5 {
__u32 srq_handle;
};
+struct ibv_get_eth_l2_addr {
+ __u32 command;
+ __u16 in_words;
+ __u16 out_words;
+ __u64 response;
+ __u32 pd_handle;
+ __u8 port;
+ __u8 sgid_idx;
+ __u8 reserved[2];
+ __u8 dgid[16];
+};
+
+struct ibv_get_eth_l2_addr_resp {
+ __u8 mac[6];
+ __u16 vlan_id;
+};
+
#endif /* KERN_ABI_H */
Index: libibverbs/src/cmd.c
===================================================================
--- libibverbs.orig/src/cmd.c 2010-02-18 13:48:46.000000000 +0200
+++ libibverbs/src/cmd.c 2010-02-18 13:50:53.000000000 +0200
@@ -1407,4 +1407,24 @@ int ibv_cmd_unreg_xrc_rcv_qp(struct ibv_
return 0;
}
+int ibv_cmd_get_eth_l2_addr(struct ibv_pd *pd, uint8_t port, const union ibv_gid *gid,
+ int sgid_idx, uint8_t *mac, uint16_t *vlan_id)
+{
+ struct ibv_get_eth_l2_addr cmd;
+ struct ibv_get_eth_l2_addr_resp resp;
+
+ IBV_INIT_CMD_RESP(&cmd, sizeof cmd, GET_ETH_L2_ADDR, &resp, sizeof resp);
+ memcpy(cmd.dgid, gid, sizeof cmd.dgid);
+ cmd.pd_handle = pd->handle;
+ cmd.port = port;
+ cmd.sgid_idx = sgid_idx;
+
+ if (write(pd->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd)
+ return errno;
+
+ memcpy(mac, resp.mac, 6);
+ *vlan_id = resp.vlan_id;
+
+ return 0;
+}
Index: libibverbs/src/libibverbs.map
===================================================================
--- libibverbs.orig/src/libibverbs.map 2010-02-18 13:48:37.000000000 +0200
+++ libibverbs/src/libibverbs.map 2010-02-18 13:50:53.000000000 +0200
@@ -64,6 +64,7 @@ IBVERBS_1.0 {
ibv_cmd_destroy_ah;
ibv_cmd_attach_mcast;
ibv_cmd_detach_mcast;
+ ibv_cmd_get_eth_l2_addr;
ibv_copy_qp_attr_from_kern;
ibv_copy_path_rec_from_kern;
ibv_copy_path_rec_to_kern;

View File

@ -0,0 +1,50 @@
[PATCHv7 2/4] libibverbs: change kernel API to accept link layer
Modify the code to allow passing the link layer of a port from kernel to user.
Update ibv_query_port.3 man page with the change.
Signed-off-by: Eli Cohen <eli@mellanox.co.il>
---
include/infiniband/kern-abi.h | 3 ++-
man/ibv_query_port.3 | 1 +
src/cmd.c | 1 +
3 files changed, 4 insertions(+), 1 deletions(-)
Index: libibverbs/include/infiniband/kern-abi.h
===================================================================
--- libibverbs.orig/include/infiniband/kern-abi.h 2010-06-08 11:08:57.895171000 +0300
+++ libibverbs/include/infiniband/kern-abi.h 2010-06-08 11:09:10.172540000 +0300
@@ -231,7 +231,8 @@ struct ibv_query_port_resp {
__u8 active_width;
__u8 active_speed;
__u8 phys_state;
- __u8 reserved[3];
+ __u8 link_layer;
+ __u8 reserved[2];
};
struct ibv_alloc_pd {
Index: libibverbs/man/ibv_query_port.3
===================================================================
--- libibverbs.orig/man/ibv_query_port.3 2010-06-08 11:08:57.951172000 +0300
+++ libibverbs/man/ibv_query_port.3 2010-06-08 11:09:10.177543000 +0300
@@ -44,6 +44,7 @@ uint8_t init_type_reply;
uint8_t active_width; /* Currently active link width */
uint8_t active_speed; /* Currently active link speed */
uint8_t phys_state; /* Physical port state */
+uint8_t link_layer; /* link layer protocol of the port */
.in -8
};
.sp
Index: libibverbs/src/cmd.c
===================================================================
--- libibverbs.orig/src/cmd.c 2010-06-08 11:08:57.999167000 +0300
+++ libibverbs/src/cmd.c 2010-06-08 11:09:10.186539000 +0300
@@ -196,6 +196,7 @@ int ibv_cmd_query_port(struct ibv_contex
port_attr->active_width = resp.active_width;
port_attr->active_speed = resp.active_speed;
port_attr->phys_state = resp.phys_state;
+ port_attr->link_layer = resp.link_layer;
return 0;
}

View File

@ -0,0 +1,70 @@
[PATCHv7 1/4] libibverbs: Add link layer field to ibv_port_attr
This field can have one of the values - IBV_LINK_LAYER_UNSPECIFIED,
IBV_LINK_LAYER_INFINIBAND, IBV_LINK_LAYER_ETHERNET. It can be used by
applications to know the link layer used by the port, which can be either
Infiniband or Ethernet. The addition of the new field does not change the size
of struct ibv_port_attr due to alignment of the preceding field. Binary
compatibility is not compromised either since new apps with old libraries will
determine the link layer as IB while old applications with new a new library do
not read this field.
Solution suggested by:
Roland Dreier <rolandd@cisco.com>
Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
Signed-off-by: Eli Cohen <eli@mellanox.co.il>
---
include/infiniband/verbs.h | 21 +++++++++++++++++++++
1 files changed, 21 insertions(+), 0 deletions(-)
Index: libibverbs/include/infiniband/verbs.h
===================================================================
--- libibverbs.orig/include/infiniband/verbs.h 2010-06-08 11:00:05.575721000 +0300
+++ libibverbs/include/infiniband/verbs.h 2010-06-08 11:00:39.442737000 +0300
@@ -162,6 +162,12 @@ enum ibv_port_state {
IBV_PORT_ACTIVE_DEFER = 5
};
+enum {
+ IBV_LINK_LAYER_UNSPECIFIED,
+ IBV_LINK_LAYER_INFINIBAND,
+ IBV_LINK_LAYER_ETHERNET,
+};
+
struct ibv_port_attr {
enum ibv_port_state state;
enum ibv_mtu max_mtu;
@@ -182,6 +188,8 @@ struct ibv_port_attr {
uint8_t active_width;
uint8_t active_speed;
uint8_t phys_state;
+ uint8_t link_layer;
+ uint8_t pad;
};
enum ibv_event_type {
@@ -743,6 +751,16 @@ struct ibv_context {
struct ibv_more_ops *more_ops;
};
+static inline int ___ibv_query_port(struct ibv_context *context,
+ uint8_t port_num,
+ struct ibv_port_attr *port_attr)
+{
+ port_attr->link_layer = IBV_LINK_LAYER_UNSPECIFIED;
+ port_attr->pad = 0;
+
+ return context->ops.query_port(context, port_num, port_attr);
+}
+
/**
* ibv_get_device_list - Get list of IB devices currently available
* @num_devices: optional. if non-NULL, set to the number of devices
@@ -1304,4 +1322,7 @@ END_C_DECLS
# undef __attribute_const
+#define ibv_query_port(context, port_num, port_attr) \
+ ___ibv_query_port(context, port_num, port_attr)
+
#endif /* INFINIBAND_VERBS_H */

View File

@ -0,0 +1,13 @@
diff --git a/libibverbs.spec.in b/libibverbs.spec.in
index d8cc4ee..daa3051 100644
--- a/libibverbs.spec.in
+++ b/libibverbs.spec.in
@@ -85,7 +85,7 @@ rm -rf $RPM_BUILD_ROOT
%{_mandir}/man1/*
%changelog
-* Thu Jun 3 Roland Dreier <rdreier@cisco.com> - 1.1.4-1
+* Thu Jun 3 2010 Roland Dreier <rdreier@cisco.com> - 1.1.4-1
- New upstream release
* Thu Oct 29 2009 Roland Dreier <rdreier@cisco.com> - 1.1.3-1

View File

@ -0,0 +1,14 @@
verbs_man_page.patch
XRC_man_pages.patch
XRC_base_implementation.patch
XRC_RCV_QP.patch
pthread_cond_t_fields.patch
rocee_link_layer.patch
rocee_kernel_accept_link_layer.patch
rocee_get_mac.patch
rocee_examples.patch
qpt_raw_eth.patch
configure_in-AC_PROG_LIBTOOL-for-automake.patch
rpm_spec_changelog_fix.patch
iboe_adapt_new_api.patch
support_gid_change.patch

View File

@ -0,0 +1,242 @@
commit ebc306b0ad2a8a873a195b26ebafe704da001981
Author: Dotan Barak <dotanb@dev.mellanox.co.il>
Date: Sun Feb 3 17:58:53 2008 +0200
libibverbs: Added the man page verbs.7
Added the man page verbs.7 which is an introduction to libibverbs man pages.
Signed-off-by: Dotan Barak <dotanb@dev.mellanox.co.il>
Signed-off-by: Or Gerlitz <ogerlitz@voltaire.com>
Index: libibverbs/Makefile.am
===================================================================
--- libibverbs.orig/Makefile.am 2010-06-07 18:38:19.088451000 +0300
+++ libibverbs/Makefile.am 2010-06-08 10:58:10.061113000 +0300
@@ -53,7 +53,7 @@ man_MANS = man/ibv_asyncwatch.1 man/ibv_
man/ibv_post_srq_recv.3 man/ibv_query_device.3 man/ibv_query_gid.3 \
man/ibv_query_pkey.3 man/ibv_query_port.3 man/ibv_query_qp.3 \
man/ibv_query_srq.3 man/ibv_rate_to_mult.3 man/ibv_reg_mr.3 \
- man/ibv_req_notify_cq.3 man/ibv_resize_cq.3
+ man/ibv_req_notify_cq.3 man/ibv_resize_cq.3 man/verbs.7
DEBIAN = debian/changelog debian/compat debian/control debian/copyright \
debian/ibverbs-utils.install debian/libibverbs1.install \
Index: libibverbs/libibverbs.spec.in
===================================================================
--- libibverbs.orig/libibverbs.spec.in 2010-06-08 10:47:13.106792000 +0300
+++ libibverbs/libibverbs.spec.in 2010-06-08 10:58:10.160119000 +0300
@@ -74,6 +74,7 @@ rm -rf $RPM_BUILD_ROOT
%{_libdir}/lib*.so
%{_includedir}/*
%{_mandir}/man3/*
+%{_mandir}/man7/*
%files devel-static
%defattr(-,root,root,-)
Index: libibverbs/man/verbs.7
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ libibverbs/man/verbs.7 2010-06-08 10:58:10.360115000 +0300
@@ -0,0 +1,201 @@
+.\" -*- nroff -*-
+.\"
+.TH VERBS 7 2008-01-17 libibverbs "Libibverbs Programmer's Manual"
+.SH "NAME"
+verbs \- Infiniband verbs library
+.SH "SYNOPSIS"
+.nf
+.B #include <infiniband/verbs.h>
+.fi
+.SH "DESCRIPTION"
+This library is an implementation of the verbs according to the Infiniband specification volume 1.2. It handles the control path of creating, modifying, querying and destroying resources such as Protection Domains (PD), Completion Queues (CQ), Queue-Pairs (QP), Shared Receive Queues (SRQ), Address Handles (AH), Memory Regions (MR). It also handles sending and receiving data posted to QPs and SRQs, getting completions from CQs using polling and completions events.
+
+The control path is implemented through system calls to the uverbs kernel module which further calls the low level HW driver. The data path is implemented through calls made to low level HW library which in most cases interacts directly with the HW providing kernel and network stack bypass (saving context/mode switches) along with zero copy and an asynchronous I/O model.
+
+
+Typically, under network and RDMA programming, there are operations which involve interaction with remote peers (such as address resolution and connection establishment) and remote entities (such as route resolution and joining a multicast group under IB), where a resource managed through IB verbs such as QP or AH would be eventually created or effected from this interaction. In such cases, applications whose addressing semantics is based on IP can use librdmacm (see rdma_cm(7)) which works in conjunction with libibverbs.
+
+This library is thread safe library and verbs can be called from every thread in the process (the same resource can even be handled from different threads, for example: ibv_poll_cq can be called from more than one thread).
+
+However, it is up to the user to stop working with a resource after it was destroyed (by the same thread or by any other thread), this may result a segmentation fault.
+
+If fork (or any other system call that perform fork directly or indirectly) is being used, please see ibv_fork_init(3).
+
+.LP
+The following shall be declared as functions and may also be defined
+as macros. Function prototypes shall be provided.
+.RS
+.nf
+
+\fB
+.B Library functions
+
+int ibv_fork_init(void);
+
+.B Device functions
+
+struct ibv_device **ibv_get_device_list(int *num_devices);
+void ibv_free_device_list(struct ibv_device **list);
+const char *ibv_get_device_name(struct ibv_device *device);
+uint64_t ibv_get_device_guid(struct ibv_device *device);
+
+.B Context functions
+
+struct ibv_context *ibv_open_device(struct ibv_device *device);
+int ibv_close_device(struct ibv_context *context);
+
+.B Queries
+
+int ibv_query_device(struct ibv_context *context,
+ struct ibv_device_attr *device_attr);
+int ibv_query_port(struct ibv_context *context, uint8_t port_num,
+ struct ibv_port_attr *port_attr);
+int ibv_query_pkey(struct ibv_context *context, uint8_t port_num,
+ int index, uint16_t *pkey);
+int ibv_query_gid(struct ibv_context *context, uint8_t port_num,
+ int index, union ibv_gid *gid);
+
+.B Asynchronous events
+
+int ibv_get_async_event(struct ibv_context *context,
+ struct ibv_async_event *event);
+void ibv_ack_async_event(struct ibv_async_event *event);
+
+.B Protection Domains
+
+struct ibv_pd *ibv_alloc_pd(struct ibv_context *context);
+int ibv_dealloc_pd(struct ibv_pd *pd);
+
+.B Memory Regions
+
+struct ibv_mr *ibv_reg_mr(struct ibv_pd *pd, void *addr,
+ size_t length, enum ibv_access_flags access);
+int ibv_dereg_mr(struct ibv_mr *mr);
+
+.B Address Handles
+
+struct ibv_ah *ibv_create_ah(struct ibv_pd *pd, struct ibv_ah_attr *attr);
+int ibv_init_ah_from_wc(struct ibv_context *context, uint8_t port_num,
+ struct ibv_wc *wc, struct ibv_grh *grh,
+ struct ibv_ah_attr *ah_attr);
+struct ibv_ah *ibv_create_ah_from_wc(struct ibv_pd *pd, struct ibv_wc *wc,
+ struct ibv_grh *grh, uint8_t port_num);
+int ibv_destroy_ah(struct ibv_ah *ah);
+
+.B Completion event channels
+
+struct ibv_comp_channel *ibv_create_comp_channel(struct ibv_context *context);
+int ibv_destroy_comp_channel(struct ibv_comp_channel *channel);
+
+.B Completion Queues Control
+
+struct ibv_cq *ibv_create_cq(struct ibv_context *context, int cqe,
+ void *cq_context,
+ struct ibv_comp_channel *channel,
+ int comp_vector);
+int ibv_destroy_cq(struct ibv_cq *cq);
+int ibv_resize_cq(struct ibv_cq *cq, int cqe);
+
+.B Reading Completions from CQ
+
+int ibv_poll_cq(struct ibv_cq *cq, int num_entries, struct ibv_wc *wc);
+
+.B Requesting / Managing CQ events
+
+int ibv_req_notify_cq(struct ibv_cq *cq, int solicited_only);
+int ibv_get_cq_event(struct ibv_comp_channel *channel,
+ struct ibv_cq **cq, void **cq_context);
+void ibv_ack_cq_events(struct ibv_cq *cq, unsigned int nevents);
+
+.B Shared Receive Queue control
+
+struct ibv_srq *ibv_create_srq(struct ibv_pd *pd,
+ struct ibv_srq_init_attr *srq_init_attr);
+int ibv_destroy_srq(struct ibv_srq *srq);
+int ibv_modify_srq(struct ibv_srq *srq,
+ struct ibv_srq_attr *srq_attr,
+ enum ibv_srq_attr_mask srq_attr_mask);
+int ibv_query_srq(struct ibv_srq *srq, struct ibv_srq_attr *srq_attr);
+
+.B Queue Pair control
+
+struct ibv_qp *ibv_create_qp(struct ibv_pd *pd,
+ struct ibv_qp_init_attr *qp_init_attr);
+int ibv_destroy_qp(struct ibv_qp *qp);
+int ibv_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr,
+ enum ibv_qp_attr_mask attr_mask);
+int ibv_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr,
+ enum ibv_qp_attr_mask attr_mask,
+ struct ibv_qp_init_attr *init_attr);
+
+.B posting Work Requests to QPs/SRQs
+int ibv_post_send(struct ibv_qp *qp, struct ibv_send_wr *wr,
+ struct ibv_send_wr **bad_wr);
+int ibv_post_recv(struct ibv_qp *qp, struct ibv_recv_wr *wr,
+ struct ibv_recv_wr **bad_wr);
+int ibv_post_srq_recv(struct ibv_srq *srq,
+ struct ibv_recv_wr *recv_wr,
+ struct ibv_recv_wr **bad_recv_wr);
+
+.B Multicast group
+
+int ibv_attach_mcast(struct ibv_qp *qp, union ibv_gid *gid, uint16_t lid);
+int ibv_detach_mcast(struct ibv_qp *qp, union ibv_gid *gid, uint16_t lid);
+
+.B General functions
+
+int ibv_rate_to_mult(enum ibv_rate rate);
+enum ibv_rate mult_to_ibv_rate(int mult);
+\fP
+.SH "SEE ALSO"
+.LP
+\fIibv_fork_init\fP(),
+\fIibv_get_device_list\fP(),
+\fIibv_free_device_list\fP(),
+\fIibv_get_device_name\fP(),
+\fIibv_get_device_guid\fP(),
+\fIibv_open_device\fP(),
+\fIibv_close_device\fP(),
+\fIibv_query_device\fP(),
+\fIibv_query_port\fP(),
+\fIibv_query_pkey\fP(),
+\fIibv_query_gid\fP(),
+\fIibv_get_async_event\fP(),
+\fIibv_ack_async_event\fP(),
+\fIibv_alloc_pd\fP(),
+\fIibv_dealloc_pd\fP(),
+\fIibv_reg_mr\fP(),
+\fIibv_dereg_mr\fP(),
+\fIibv_create_ah\fP(),
+\fIibv_init_ah_from_wc\fP(),
+\fIibv_create_ah_from_wc\fP(),
+\fIibv_destroy_ah\fP(),
+\fIibv_create_comp_channel\fP(),
+\fIibv_destroy_comp_channel\fP(),
+\fIibv_create_cq\fP(),
+\fIibv_destroy_cq\fP(),
+\fIibv_resize_cq\fP(),
+\fIibv_poll_cq\fP(),
+\fIibv_req_notify_cq\fP(),
+\fIibv_get_cq_event\fP(),
+\fIibv_ack_cq_events\fP(),
+\fIibv_create_srq\fP(),
+\fIibv_destroy_srq\fP(),
+\fIibv_modify_srq\fP(),
+\fIibv_query_srq\fP(),
+\fIibv_post_srq_recv\fP(),
+\fIibv_create_qp\fP(),
+\fIibv_destroy_qp\fP(),
+\fIibv_modify_qp\fP(),
+\fIibv_query_qp\fP(),
+\fIibv_post_send\fP(),
+\fIibv_post_recv\fP(),
+\fIibv_attach_mcast\fP(),
+\fIibv_detach_mcast\fP(),
+\fIibv_rate_to_mult\fP(),
+\fImult_to_ibv_rate\fP()
+.SH "AUTHORS"
+.TP
+Dotan Barak <dotanb@mellanox.co.il>
+.TP
+Or Gerlitz <ogerlitz@voltaire.com>

View File

@ -0,0 +1,129 @@
/*
* Copyright (c) 2005 Topspin Communications. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef INFINIBAND_ARCH_H
#define INFINIBAND_ARCH_H
#include <stdint.h>
#include <infiniband/endian.h>
#include <infiniband/byteswap.h>
#if __BYTE_ORDER == __LITTLE_ENDIAN
static inline uint64_t htonll(uint64_t x) { return bswap_64(x); }
static inline uint64_t ntohll(uint64_t x) { return bswap_64(x); }
#elif __BYTE_ORDER == __BIG_ENDIAN
static inline uint64_t htonll(uint64_t x) { return x; }
static inline uint64_t ntohll(uint64_t x) { return x; }
#else
#error __BYTE_ORDER is neither __LITTLE_ENDIAN nor __BIG_ENDIAN
#endif
/*
* Architecture-specific defines. Currently, an architecture is
* required to implement the following operations:
*
* mb() - memory barrier. No loads or stores may be reordered across
* this macro by either the compiler or the CPU.
* rmb() - read memory barrier. No loads may be reordered across this
* macro by either the compiler or the CPU.
* wmb() - write memory barrier. No stores may be reordered across
* this macro by either the compiler or the CPU.
* wc_wmb() - flush write combine buffers. No write-combined writes
* will be reordered across this macro by either the compiler or
* the CPU.
*/
#if defined(__i386__)
#define mb() asm volatile("lock; addl $0,0(%%esp) " ::: "memory")
#define rmb() mb()
#define wmb() asm volatile("" ::: "memory")
#define wc_wmb() mb()
#elif defined(__x86_64__)
/*
* Only use lfence for mb() and rmb() because we don't care about
* ordering against non-temporal stores (for now at least).
*/
#define mb() asm volatile("lfence" ::: "memory")
#define rmb() mb()
#define wmb() asm volatile("" ::: "memory")
#define wc_wmb() asm volatile("sfence" ::: "memory")
#elif defined(__PPC64__)
#define mb() asm volatile("sync" ::: "memory")
#define rmb() asm volatile("lwsync" ::: "memory")
#define wmb() mb()
#define wc_wmb() wmb()
#elif defined(__ia64__)
#define mb() asm volatile("mf" ::: "memory")
#define rmb() mb()
#define wmb() mb()
#define wc_wmb() asm volatile("fwb" ::: "memory")
#elif defined(__PPC__)
#define mb() asm volatile("sync" ::: "memory")
#define rmb() mb()
#define wmb() mb()
#define wc_wmb() wmb()
#elif defined(__sparc_v9__)
#define mb() asm volatile("membar #LoadLoad | #LoadStore | #StoreStore | #StoreLoad" ::: "memory")
#define rmb() asm volatile("membar #LoadLoad" ::: "memory")
#define wmb() asm volatile("membar #StoreStore" ::: "memory")
#define wc_wmb() wmb()
#elif defined(__sparc__)
#define mb() asm volatile("" ::: "memory")
#define rmb() mb()
#define wmb() mb()
#define wc_wmb() wmb()
#else
#warning No architecture specific defines found. Using generic implementation.
#define mb() asm volatile("" ::: "memory")
#define rmb() mb()
#define wmb() mb()
#define wc_wmb() wmb()
#endif
#endif /* INFINIBAND_ARCH_H */

View File

@ -0,0 +1,172 @@
/*
* Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
* Copyright (c) 2005, 2006 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2005 PathScale, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef INFINIBAND_DRIVER_H
#define INFINIBAND_DRIVER_H
#include <infiniband/verbs.h>
#include <infiniband/kern-abi.h>
#ifdef __cplusplus
# define BEGIN_C_DECLS extern "C" {
# define END_C_DECLS }
#else /* !__cplusplus */
# define BEGIN_C_DECLS
# define END_C_DECLS
#endif /* __cplusplus */
/*
* Extension that low-level drivers should add to their .so filename
* (probably via libtool "-release" option). For example a low-level
* driver named "libfoo" should build a plug-in named "libfoo-rdmav2.so".
*/
#define IBV_DEVICE_LIBRARY_EXTENSION rdmav2
typedef struct ibv_device *(*ibv_driver_init_func)(const char *uverbs_sys_path,
int abi_version);
void ibv_register_driver(const char *name, ibv_driver_init_func init_func);
int ibv_cmd_get_context(struct ibv_context *context, struct ibv_get_context *cmd,
size_t cmd_size, struct ibv_get_context_resp *resp,
size_t resp_size);
int ibv_cmd_query_device(struct ibv_context *context,
struct ibv_device_attr *device_attr,
uint64_t *raw_fw_ver,
struct ibv_query_device *cmd, size_t cmd_size);
int ibv_cmd_query_port(struct ibv_context *context, uint8_t port_num,
struct ibv_port_attr *port_attr,
struct ibv_query_port *cmd, size_t cmd_size);
int ibv_cmd_query_gid(struct ibv_context *context, uint8_t port_num,
int index, union ibv_gid *gid);
int ibv_cmd_query_pkey(struct ibv_context *context, uint8_t port_num,
int index, uint16_t *pkey);
int ibv_cmd_alloc_pd(struct ibv_context *context, struct ibv_pd *pd,
struct ibv_alloc_pd *cmd, size_t cmd_size,
struct ibv_alloc_pd_resp *resp, size_t resp_size);
int ibv_cmd_dealloc_pd(struct ibv_pd *pd);
#define IBV_CMD_REG_MR_HAS_RESP_PARAMS
int ibv_cmd_reg_mr(struct ibv_pd *pd, void *addr, size_t length,
uint64_t hca_va, int access,
struct ibv_mr *mr, struct ibv_reg_mr *cmd,
size_t cmd_size,
struct ibv_reg_mr_resp *resp, size_t resp_size);
int ibv_cmd_dereg_mr(struct ibv_mr *mr);
int ibv_cmd_create_cq(struct ibv_context *context, int cqe,
struct ibv_comp_channel *channel,
int comp_vector, struct ibv_cq *cq,
struct ibv_create_cq *cmd, size_t cmd_size,
struct ibv_create_cq_resp *resp, size_t resp_size);
int ibv_cmd_poll_cq(struct ibv_cq *cq, int ne, struct ibv_wc *wc);
int ibv_cmd_req_notify_cq(struct ibv_cq *cq, int solicited_only);
#define IBV_CMD_RESIZE_CQ_HAS_RESP_PARAMS
int ibv_cmd_resize_cq(struct ibv_cq *cq, int cqe,
struct ibv_resize_cq *cmd, size_t cmd_size,
struct ibv_resize_cq_resp *resp, size_t resp_size);
int ibv_cmd_destroy_cq(struct ibv_cq *cq);
int ibv_cmd_create_srq(struct ibv_pd *pd,
struct ibv_srq *srq, struct ibv_srq_init_attr *attr,
struct ibv_create_srq *cmd, size_t cmd_size,
struct ibv_create_srq_resp *resp, size_t resp_size);
int ibv_cmd_create_xrc_srq(struct ibv_pd *pd,
struct ibv_srq *srq, struct ibv_srq_init_attr *attr,
uint32_t xrc_domain, uint32_t xrc_cq,
struct ibv_create_xrc_srq *cmd, size_t cmd_size,
struct ibv_create_srq_resp *resp, size_t resp_size);
int ibv_cmd_modify_srq(struct ibv_srq *srq,
struct ibv_srq_attr *srq_attr,
int srq_attr_mask,
struct ibv_modify_srq *cmd, size_t cmd_size);
int ibv_cmd_query_srq(struct ibv_srq *srq,
struct ibv_srq_attr *srq_attr,
struct ibv_query_srq *cmd, size_t cmd_size);
int ibv_cmd_destroy_srq(struct ibv_srq *srq);
int ibv_cmd_create_qp(struct ibv_pd *pd,
struct ibv_qp *qp, struct ibv_qp_init_attr *attr,
struct ibv_create_qp *cmd, size_t cmd_size,
struct ibv_create_qp_resp *resp, size_t resp_size);
int ibv_cmd_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *qp_attr,
int attr_mask,
struct ibv_qp_init_attr *qp_init_attr,
struct ibv_query_qp *cmd, size_t cmd_size);
int ibv_cmd_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr,
int attr_mask,
struct ibv_modify_qp *cmd, size_t cmd_size);
int ibv_cmd_destroy_qp(struct ibv_qp *qp);
int ibv_cmd_post_send(struct ibv_qp *ibqp, struct ibv_send_wr *wr,
struct ibv_send_wr **bad_wr);
int ibv_cmd_post_recv(struct ibv_qp *ibqp, struct ibv_recv_wr *wr,
struct ibv_recv_wr **bad_wr);
int ibv_cmd_post_srq_recv(struct ibv_srq *srq, struct ibv_recv_wr *wr,
struct ibv_recv_wr **bad_wr);
int ibv_cmd_create_ah(struct ibv_pd *pd, struct ibv_ah *ah,
struct ibv_ah_attr *attr);
int ibv_cmd_destroy_ah(struct ibv_ah *ah);
int ibv_cmd_attach_mcast(struct ibv_qp *qp, const union ibv_gid *gid, uint16_t lid);
int ibv_cmd_detach_mcast(struct ibv_qp *qp, const union ibv_gid *gid, uint16_t lid);
int ibv_dontfork_range(void *base, size_t size);
int ibv_dofork_range(void *base, size_t size);
int ibv_cmd_open_xrc_domain(struct ibv_context *context, int fd, int oflag,
struct ibv_xrc_domain *d,
struct ibv_open_xrc_domain_resp *resp,
size_t resp_size);
int ibv_cmd_close_xrc_domain(struct ibv_xrc_domain *d);
int ibv_cmd_create_xrc_rcv_qp(struct ibv_qp_init_attr *init_attr,
uint32_t *xrc_rcv_qpn);
int ibv_cmd_modify_xrc_rcv_qp(struct ibv_xrc_domain *d, uint32_t xrc_rcv_qpn,
struct ibv_qp_attr *attr, int attr_mask);
int ibv_cmd_query_xrc_rcv_qp(struct ibv_xrc_domain *d, uint32_t xrc_rcv_qpn,
struct ibv_qp_attr *attr, int attr_mask,
struct ibv_qp_init_attr *init_attr);
int ibv_cmd_reg_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain,
uint32_t xrc_qp_num);
int ibv_cmd_unreg_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain,
uint32_t xrc_qp_num);
/*
* sysfs helper functions
*/
const char *ibv_get_sysfs_path(void);
int ibv_read_sysfs_file(const char *dir, const char *file,
char *buf, size_t size);
int ibv_resolve_eth_gid(const struct ibv_pd *pd, uint8_t port_num,
union ibv_gid *dgid, uint8_t sgid_index,
uint8_t mac[], uint16_t *vlan, uint8_t *tagged,
uint8_t *is_mcast);
#endif /* INFINIBAND_DRIVER_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2005 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef INFINIBAND_MARSHALL_H
#define INFINIBAND_MARSHALL_H
#include <infiniband/verbs.h>
#include <infiniband/sa.h>
#include <infiniband/kern-abi.h>
#include <infiniband/sa-kern-abi.h>
#ifdef __cplusplus
# define BEGIN_C_DECLS extern "C" {
# define END_C_DECLS }
#else /* !__cplusplus */
# define BEGIN_C_DECLS
# define END_C_DECLS
#endif /* __cplusplus */
BEGIN_C_DECLS
void ibv_copy_qp_attr_from_kern(struct ibv_qp_attr *dst,
struct ibv_kern_qp_attr *src);
void ibv_copy_ah_attr_from_kern(struct ibv_ah_attr *dst,
struct ibv_kern_ah_attr *src);
void ibv_copy_path_rec_from_kern(struct ibv_sa_path_rec *dst,
struct ibv_kern_path_rec *src);
void ibv_copy_path_rec_to_kern(struct ibv_kern_path_rec *dst,
struct ibv_sa_path_rec *src);
END_C_DECLS
#endif /* INFINIBAND_MARSHALL_H */

View File

@ -0,0 +1,147 @@
/*
* Copyright (c) 2005 Topspin Communications. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef INFINIBAND_OPCODE_H
#define INFINIBAND_OPCODE_H
/*
* This macro cleans up the definitions of constants for BTH opcodes.
* It is used to define constants such as IBV_OPCODE_UD_SEND_ONLY,
* which becomes IBV_OPCODE_UD + IBV_OPCODE_SEND_ONLY, and this gives
* the correct value.
*
* In short, user code should use the constants defined using the
* macro rather than worrying about adding together other constants.
*/
#define IBV_OPCODE(transport, op) \
IBV_OPCODE_ ## transport ## _ ## op = \
IBV_OPCODE_ ## transport + IBV_OPCODE_ ## op
enum {
/* transport types -- just used to define real constants */
IBV_OPCODE_RC = 0x00,
IBV_OPCODE_UC = 0x20,
IBV_OPCODE_RD = 0x40,
IBV_OPCODE_UD = 0x60,
/* operations -- just used to define real constants */
IBV_OPCODE_SEND_FIRST = 0x00,
IBV_OPCODE_SEND_MIDDLE = 0x01,
IBV_OPCODE_SEND_LAST = 0x02,
IBV_OPCODE_SEND_LAST_WITH_IMMEDIATE = 0x03,
IBV_OPCODE_SEND_ONLY = 0x04,
IBV_OPCODE_SEND_ONLY_WITH_IMMEDIATE = 0x05,
IBV_OPCODE_RDMA_WRITE_FIRST = 0x06,
IBV_OPCODE_RDMA_WRITE_MIDDLE = 0x07,
IBV_OPCODE_RDMA_WRITE_LAST = 0x08,
IBV_OPCODE_RDMA_WRITE_LAST_WITH_IMMEDIATE = 0x09,
IBV_OPCODE_RDMA_WRITE_ONLY = 0x0a,
IBV_OPCODE_RDMA_WRITE_ONLY_WITH_IMMEDIATE = 0x0b,
IBV_OPCODE_RDMA_READ_REQUEST = 0x0c,
IBV_OPCODE_RDMA_READ_RESPONSE_FIRST = 0x0d,
IBV_OPCODE_RDMA_READ_RESPONSE_MIDDLE = 0x0e,
IBV_OPCODE_RDMA_READ_RESPONSE_LAST = 0x0f,
IBV_OPCODE_RDMA_READ_RESPONSE_ONLY = 0x10,
IBV_OPCODE_ACKNOWLEDGE = 0x11,
IBV_OPCODE_ATOMIC_ACKNOWLEDGE = 0x12,
IBV_OPCODE_COMPARE_SWAP = 0x13,
IBV_OPCODE_FETCH_ADD = 0x14,
/* real constants follow -- see comment about above IBV_OPCODE()
macro for more details */
/* RC */
IBV_OPCODE(RC, SEND_FIRST),
IBV_OPCODE(RC, SEND_MIDDLE),
IBV_OPCODE(RC, SEND_LAST),
IBV_OPCODE(RC, SEND_LAST_WITH_IMMEDIATE),
IBV_OPCODE(RC, SEND_ONLY),
IBV_OPCODE(RC, SEND_ONLY_WITH_IMMEDIATE),
IBV_OPCODE(RC, RDMA_WRITE_FIRST),
IBV_OPCODE(RC, RDMA_WRITE_MIDDLE),
IBV_OPCODE(RC, RDMA_WRITE_LAST),
IBV_OPCODE(RC, RDMA_WRITE_LAST_WITH_IMMEDIATE),
IBV_OPCODE(RC, RDMA_WRITE_ONLY),
IBV_OPCODE(RC, RDMA_WRITE_ONLY_WITH_IMMEDIATE),
IBV_OPCODE(RC, RDMA_READ_REQUEST),
IBV_OPCODE(RC, RDMA_READ_RESPONSE_FIRST),
IBV_OPCODE(RC, RDMA_READ_RESPONSE_MIDDLE),
IBV_OPCODE(RC, RDMA_READ_RESPONSE_LAST),
IBV_OPCODE(RC, RDMA_READ_RESPONSE_ONLY),
IBV_OPCODE(RC, ACKNOWLEDGE),
IBV_OPCODE(RC, ATOMIC_ACKNOWLEDGE),
IBV_OPCODE(RC, COMPARE_SWAP),
IBV_OPCODE(RC, FETCH_ADD),
/* UC */
IBV_OPCODE(UC, SEND_FIRST),
IBV_OPCODE(UC, SEND_MIDDLE),
IBV_OPCODE(UC, SEND_LAST),
IBV_OPCODE(UC, SEND_LAST_WITH_IMMEDIATE),
IBV_OPCODE(UC, SEND_ONLY),
IBV_OPCODE(UC, SEND_ONLY_WITH_IMMEDIATE),
IBV_OPCODE(UC, RDMA_WRITE_FIRST),
IBV_OPCODE(UC, RDMA_WRITE_MIDDLE),
IBV_OPCODE(UC, RDMA_WRITE_LAST),
IBV_OPCODE(UC, RDMA_WRITE_LAST_WITH_IMMEDIATE),
IBV_OPCODE(UC, RDMA_WRITE_ONLY),
IBV_OPCODE(UC, RDMA_WRITE_ONLY_WITH_IMMEDIATE),
/* RD */
IBV_OPCODE(RD, SEND_FIRST),
IBV_OPCODE(RD, SEND_MIDDLE),
IBV_OPCODE(RD, SEND_LAST),
IBV_OPCODE(RD, SEND_LAST_WITH_IMMEDIATE),
IBV_OPCODE(RD, SEND_ONLY),
IBV_OPCODE(RD, SEND_ONLY_WITH_IMMEDIATE),
IBV_OPCODE(RD, RDMA_WRITE_FIRST),
IBV_OPCODE(RD, RDMA_WRITE_MIDDLE),
IBV_OPCODE(RD, RDMA_WRITE_LAST),
IBV_OPCODE(RD, RDMA_WRITE_LAST_WITH_IMMEDIATE),
IBV_OPCODE(RD, RDMA_WRITE_ONLY),
IBV_OPCODE(RD, RDMA_WRITE_ONLY_WITH_IMMEDIATE),
IBV_OPCODE(RD, RDMA_READ_REQUEST),
IBV_OPCODE(RD, RDMA_READ_RESPONSE_FIRST),
IBV_OPCODE(RD, RDMA_READ_RESPONSE_MIDDLE),
IBV_OPCODE(RD, RDMA_READ_RESPONSE_LAST),
IBV_OPCODE(RD, RDMA_READ_RESPONSE_ONLY),
IBV_OPCODE(RD, ACKNOWLEDGE),
IBV_OPCODE(RD, ATOMIC_ACKNOWLEDGE),
IBV_OPCODE(RD, COMPARE_SWAP),
IBV_OPCODE(RD, FETCH_ADD),
/* UD */
IBV_OPCODE(UD, SEND_ONLY),
IBV_OPCODE(UD, SEND_ONLY_WITH_IMMEDIATE)
};
#endif /* INFINIBAND_OPCODE_H */

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2005 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef INFINIBAND_SA_KERN_ABI_H
#define INFINIBAND_SA_KERN_ABI_H
#include <infiniband/types.h>
/*
* Obsolete, deprecated names. Will be removed in libibverbs 1.1.
*/
#define ib_kern_path_rec ibv_kern_path_rec
struct ibv_kern_path_rec {
__u8 dgid[16];
__u8 sgid[16];
__u16 dlid;
__u16 slid;
__u32 raw_traffic;
__u32 flow_label;
__u32 reversible;
__u32 mtu;
__u16 pkey;
__u8 hop_limit;
__u8 traffic_class;
__u8 numb_path;
__u8 sl;
__u8 mtu_selector;
__u8 rate_selector;
__u8 rate;
__u8 packet_life_time_selector;
__u8 packet_life_time;
__u8 preference;
};
#endif /* INFINIBAND_SA_KERN_ABI_H */

View File

@ -0,0 +1,135 @@
/*
* Copyright (c) 2004 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Voltaire, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef INFINIBAND_SA_H
#define INFINIBAND_SA_H
#include <infiniband/verbs.h>
struct ibv_sa_path_rec {
/* reserved */
/* reserved */
union ibv_gid dgid;
union ibv_gid sgid;
uint16_t dlid;
uint16_t slid;
int raw_traffic;
/* reserved */
uint32_t flow_label;
uint8_t hop_limit;
uint8_t traffic_class;
int reversible;
uint8_t numb_path;
uint16_t pkey;
/* reserved */
uint8_t sl;
uint8_t mtu_selector;
uint8_t mtu;
uint8_t rate_selector;
uint8_t rate;
uint8_t packet_life_time_selector;
uint8_t packet_life_time;
uint8_t preference;
};
struct ibv_sa_mcmember_rec {
union ibv_gid mgid;
union ibv_gid port_gid;
uint32_t qkey;
uint16_t mlid;
uint8_t mtu_selector;
uint8_t mtu;
uint8_t traffic_class;
uint16_t pkey;
uint8_t rate_selector;
uint8_t rate;
uint8_t packet_life_time_selector;
uint8_t packet_life_time;
uint8_t sl;
uint32_t flow_label;
uint8_t hop_limit;
uint8_t scope;
uint8_t join_state;
int proxy_join;
};
struct ibv_sa_service_rec {
uint64_t id;
union ibv_gid gid;
uint16_t pkey;
/* uint16_t resv; */
uint32_t lease;
uint8_t key[16];
uint8_t name[64];
uint8_t data8[16];
uint16_t data16[8];
uint32_t data32[4];
uint64_t data64[2];
};
#define IBV_PATH_RECORD_REVERSIBLE 0x80
struct ibv_path_record {
uint64_t service_id;
union ibv_gid dgid;
union ibv_gid sgid;
uint16_t dlid;
uint16_t slid;
uint32_t flowlabel_hoplimit; /* resv-31:28 flow label-27:8 hop limit-7:0*/
uint8_t tclass;
uint8_t reversible_numpath; /* reversible-7:7 num path-6:0 */
uint16_t pkey;
uint16_t qosclass_sl; /* qos class-15:4 sl-3:0 */
uint8_t mtu; /* mtu selector-7:6 mtu-5:0 */
uint8_t rate; /* rate selector-7:6 rate-5:0 */
uint8_t packetlifetime; /* lifetime selector-7:6 lifetime-5:0 */
uint8_t preference;
uint8_t reserved[6];
};
#define IBV_PATH_FLAG_GMP (1<<0)
#define IBV_PATH_FLAG_PRIMARY (1<<1)
#define IBV_PATH_FLAG_ALTERNATE (1<<2)
#define IBV_PATH_FLAG_OUTBOUND (1<<3)
#define IBV_PATH_FLAG_INBOUND (1<<4)
#define IBV_PATH_FLAG_INBOUND_REVERSE (1<<5)
#define IBV_PATH_FLAG_BIDIRECTIONAL (IBV_PATH_FLAG_OUTBOUND | \
IBV_PATH_FLAG_INBOUND_REVERSE)
struct ibv_path_data {
uint32_t flags;
uint32_t reserved;
struct ibv_path_record path;
};
#endif /* INFINIBAND_SA_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,146 @@
Name: libibverbs
Version: 1.1.4
Release: 1%{?dist}
Summary: A library for direct userspace use of RDMA (InfiniBand/iWARP) hardware
Group: System Environment/Libraries
License: GPLv2 or BSD
Url: http://openfabrics.org/
Source: http://openfabrics.org/downloads/verbs/libibverbs-1.1.4.tar.gz
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
Requires(post): /sbin/ldconfig
Requires(postun): /sbin/ldconfig
%description
libibverbs is a library that allows userspace processes to use RDMA
"verbs" as described in the InfiniBand Architecture Specification and
the RDMA Protocol Verbs Specification. This includes direct hardware
access from userspace to InfiniBand/iWARP adapters (kernel bypass) for
fast path operations.
For this library to be useful, a device-specific plug-in module should
also be installed.
%package devel
Summary: Development files for the libibverbs library
Group: System Environment/Libraries
Requires: %{name} = %{version}-%{release}
%description devel
Header files for the libibverbs library.
%package devel-static
Summary: Static development files for the libibverbs library
Group: System Environment/Libraries
%description devel-static
Static libraries for the libibverbs library.
%package utils
Summary: Examples for the libibverbs library
Group: System Environment/Libraries
Requires: %{name} = %{version}-%{release}
%description utils
Useful libibverbs1 example programs such as ibv_devinfo, which
displays information about RDMA devices.
%prep
%setup -q -n %{name}-@VERSION@
%build
%configure
make %{?_smp_mflags}
%install
rm -rf $RPM_BUILD_ROOT
make DESTDIR=%{buildroot} install
# remove unpackaged files from the buildroot
rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
%clean
rm -rf $RPM_BUILD_ROOT
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%files
%defattr(-,root,root,-)
%{_libdir}/libibverbs*.so.*
%doc AUTHORS COPYING ChangeLog README
%files devel
%defattr(-,root,root,-)
%{_libdir}/lib*.so
%{_includedir}/*
%{_mandir}/man3/*
%{_mandir}/man7/*
%files devel-static
%defattr(-,root,root,-)
%{_libdir}/*.a
%files utils
%defattr(-,root,root,-)
%{_bindir}/*
%{_mandir}/man1/*
%changelog
* Thu Jun 3 2010 Roland Dreier <rdreier@cisco.com> - 1.1.4-1
- New upstream release
* Thu Oct 29 2009 Roland Dreier <rdreier@cisco.com> - 1.1.3-1
- New upstream release
* Fri Jul 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.1.2-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
* Wed Feb 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.1.2-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
* Wed Apr 16 2008 Roland Dreier <rdreier@cisco.com> - 1.1.2-1
- New upstream release
- Update description to mention RDMA and iWARP, not just InfiniBand
- Add "Requires" tag for libibverbs base package to -devel
* Fri Jun 15 2007 Roland Dreier <rdreier@cisco.com> - 1.1.1-1
- New upstream release
* Wed Apr 11 2007 Roland Dreier <rdreier@cisco.com> - 1.1-1
- New upstream release
* Mon May 22 2006 Roland Dreier <rdreier@cisco.com> - 1.1-0.1.rc2
- New upstream release
- Remove dependency on libsysfs, since it is no longer used
- Put section 3 manpages in devel package.
- Spec file cleanups: remove unused ver macro, improve BuildRoot, add
Requires for /sbin/ldconfig, split static libraries into
devel-static package, and don't use makeinstall any more (all
suggested by Doug Ledford <dledford@redhat.com>).
* Thu May 4 2006 Roland Dreier <rdreier@cisco.com> - 1.0.4-1
- New upstream release
* Mon Mar 14 2006 Roland Dreier <rdreier@cisco.com> - 1.0.3-1
- New upstream release
* Mon Mar 13 2006 Roland Dreier <rdreier@cisco.com> - 1.0.1-1
- New upstream release
* Thu Feb 16 2006 Roland Dreier <rdreier@cisco.com> - 1.0-1
- New upstream release
* Wed Feb 15 2006 Roland Dreier <rolandd@cisco.com> - 1.0-0.5.rc7
- New upstream release
* Sun Jan 22 2006 Roland Dreier <rolandd@cisco.com> - 1.0-0.4.rc6
- New upstream release
* Tue Oct 25 2005 Roland Dreier <rolandd@cisco.com> - 1.0-0.3.rc5
- New upstream release
* Wed Oct 5 2005 Roland Dreier <rolandd@cisco.com> - 1.0-0.2.rc4
- Update to upstream 1.0-rc4 release
* Mon Sep 26 2005 Roland Dreier <rolandd@cisco.com> - 1.0-0.1.rc3
- Initial attempt at Fedora Extras-compliant spec file

View File

@ -0,0 +1,40 @@
.\" -*- nroff -*-
.\"
.TH IBV_ALLOC_PD 3 2006-10-31 libibverbs "Libibverbs Programmer's Manual"
.SH "NAME"
ibv_alloc_pd, ibv_dealloc_pd \- allocate or deallocate a protection domain (PDs)
.SH "SYNOPSIS"
.nf
.B #include <infiniband/verbs.h>
.sp
.BI "struct ibv_pd *ibv_alloc_pd(struct ibv_context " "*context" );
.sp
.BI "int ibv_dealloc_pd(struct ibv_pd " "*pd" );
.fi
.SH "DESCRIPTION"
.B ibv_alloc_pd()
allocates a PD for the RDMA device context
.I context\fR.
.PP
.B ibv_dealloc_pd()
deallocates the PD
.I pd\fR.
.SH "RETURN VALUE"
.B ibv_alloc_pd()
returns a pointer to the allocated PD, or NULL if the request fails.
.PP
.B ibv_dealloc_pd()
returns 0 on success, or the value of errno on failure (which indicates the failure reason).
.SH "NOTES"
.B ibv_dealloc_pd()
may fail if any other resource is still associated with the PD being
freed.
.SH "SEE ALSO"
.BR ibv_reg_mr (3),
.BR ibv_create_srq (3),
.BR ibv_create_qp (3),
.BR ibv_create_ah (3),
.BR ibv_create_ah_from_wc (3)
.SH "AUTHORS"
.TP
Dotan Barak <dotanb@mellanox.co.il>

View File

@ -0,0 +1,16 @@
.TH IBV_ASYNCWATCH 1 "August 30, 2005" "libibverbs" "USER COMMANDS"
.SH NAME
ibv_asyncwatch \- display asynchronous events
.SH SYNOPSIS
.B ibv_asyncwatch
.SH DESCRIPTION
.PP
Display asynchronous events forwarded to userspace for an RDMA device.
.SH AUTHORS
.TP
Roland Dreier
.RI < rolandd@cisco.com >

View File

@ -0,0 +1,53 @@
.\" -*- nroff -*-
.\"
.TH IBV_ATTACH_MCAST 3 2006-10-31 libibverbs "Libibverbs Programmer's Manual"
.SH "NAME"
ibv_attach_mcast, ibv_detach_mcast \- attach and detach a queue pair
(QPs) to/from a multicast group
.SH "SYNOPSIS"
.nf
.B #include <infiniband/verbs.h>
.sp
.BI "int ibv_attach_mcast(struct ibv_qp " "*qp" ", const union ibv_gid " "*gid" ",
.BI " uint16_t " "lid" ");
.sp
.BI "int ibv_detach_mcast(struct ibv_qp " "*qp" ", const union ibv_gid " "*gid" ",
.BI " uint16_t " "lid" ");
.fi
.SH "DESCRIPTION"
.B ibv_attach_mcast()
attaches the QP
.I qp
to the multicast group having MGID
.I gid
and MLID
.I lid\fR.
.PP
.B ibv_detach_mcast()
detaches the QP
.I qp
to the multicast group having MGID
.I gid
and MLID
.I lid\fR.
.SH "RETURN VALUE"
.B ibv_attach_mcast()
and
.B ibv_detach_mcast()
returns 0 on success, or the value of errno on failure (which indicates the failure reason).
.SH "NOTES"
Only QPs of Transport Service Type
.BR IBV_QPT_UD
may be attached to multicast groups.
.PP
If a QP is attached to the same multicast group multiple times, the QP will still receive a single copy of a multicast message.
.PP
In order to receive multicast messages, a join request for the
multicast group must be sent to the subnet administrator (SA), so that
the fabric's multicast routing is configured to deliver messages to
the local port.
.SH "SEE ALSO"
.BR ibv_create_qp (3)
.SH "AUTHORS"
.TP
Dotan Barak <dotanb@mellanox.co.il>

View File

@ -0,0 +1,64 @@
.\" -*- nroff -*-
.\"
.TH IBV_CREATE_AH 3 2006-10-31 libibverbs "Libibverbs Programmer's Manual"
.SH "NAME"
ibv_create_ah, ibv_destroy_ah \- create or destroy an address handle (AH)
.SH "SYNOPSIS"
.nf
.B #include <infiniband/verbs.h>
.sp
.BI "struct ibv_ah *ibv_create_ah(struct ibv_pd " "*pd" ",
.BI " struct ibv_ah_attr " "*attr" ");
.sp
.BI "int ibv_destroy_ah(struct ibv_ah " "*ah" ");
.fi
.SH "DESCRIPTION"
.B ibv_create_ah()
creates an address handle (AH) associated with the protection domain
.I pd\fR.
The argument
.I attr
is an ibv_ah_attr struct, as defined in <infiniband/verbs.h>.
.PP
.nf
struct ibv_ah_attr {
.in +8
struct ibv_global_route grh; /* Global Routing Header (GRH) attributes */
uint16_t dlid; /* Destination LID */
uint8_t sl; /* Service Level */
uint8_t src_path_bits; /* Source path bits */
uint8_t static_rate; /* Maximum static rate */
uint8_t is_global; /* GRH attributes are valid */
uint8_t port_num; /* Physical port number */
.in -8
};
.sp
.nf
struct ibv_global_route {
.in +8
union ibv_gid dgid; /* Destination GID or MGID */
uint32_t flow_label; /* Flow label */
uint8_t sgid_index; /* Source GID index */
uint8_t hop_limit; /* Hop limit */
uint8_t traffic_class; /* Traffic class */
.in -8
};
.fi
.sp
.PP
.B ibv_destroy_ah()
destroys the AH
.I ah\fR.
.SH "RETURN VALUE"
.B ibv_create_ah()
returns a pointer to the created AH, or NULL if the request fails.
.PP
.B ibv_destroy_ah()
returns 0 on success, or the value of errno on failure (which indicates the failure reason).
.SH "SEE ALSO"
.BR ibv_alloc_pd (3),
.BR ibv_init_ah_from_wc (3),
.BR ibv_create_ah_from_wc (3)
.SH "AUTHORS"
.TP
Dotan Barak <dotanb@mellanox.co.il>

View File

@ -0,0 +1,63 @@
.\" -*- nroff -*-
.\"
.TH IBV_CREATE_AH_FROM_WC 3 2006-10-31 libibverbs "Libibverbs Programmer's Manual"
.SH "NAME"
ibv_init_ah_from_wc, ibv_create_ah_from_wc \- initialize or create an
address handle (AH) from a work completion
.SH "SYNOPSIS"
.nf
.B #include <infiniband/verbs.h>
.sp
.BI "int ibv_init_ah_from_wc(struct ibv_context " "*context" ", uint8_t " "port_num" ,
.BI " struct ibv_wc " "*wc" ", struct ibv_grh " "*grh" ,
.BI " struct ibv_ah_attr " "*ah_attr" );
.sp
.BI "struct ibv_ah *ibv_create_ah_from_wc(struct ibv_pd " "*pd" ,
.BI " struct ibv_wc " "*wc" ,
.BI " struct ibv_grh " "*grh" ,
.BI " uint8_t " "port_num" );
.fi
.SH "DESCRIPTION"
.B ibv_init_ah_from_wc()
initializes the address handle (AH) attribute structure
.I ah_attr
for the RDMA device context
.I context
using the port number
.I port_num\fR,
using attributes from the work completion
.I wc
and the Global Routing Header (GRH) structure
.I grh\fR.
.PP
.B ibv_create_ah_from_wc()
creates an AH associated with the protection domain
.I pd
using the port number
.I port_num\fR,
using attributes from the work completion
.I wc
and the Global Routing Header (GRH) structure
.I grh\fR.
.SH "RETURN VALUE"
.B ibv_init_ah_from_wc()
returns 0 on success, and \-1 on error.
.PP
.B ibv_create_ah_from_wc()
returns a pointer to the created AH, or NULL if the request fails.
.SH "NOTES"
The filled structure
.I ah_attr
returned from
.B ibv_init_ah_from_wc()
can be used to create a new AH using
.B ibv_create_ah()\fR.
.SH "SEE ALSO"
.BR ibv_open_device (3),
.BR ibv_alloc_pd (3),
.BR ibv_create_ah (3),
.BR ibv_destroy_ah (3),
.BR ibv_poll_cq (3)
.SH "AUTHORS"
.TP
Dotan Barak <dotanb@mellanox.co.il>

View File

@ -0,0 +1,50 @@
.\" -*- nroff -*-
.\"
.TH IBV_CREATE_COMP_CHANNEL 3 2006-10-31 libibverbs "Libibverbs Programmer's Manual"
.SH "NAME"
ibv_create_comp_channel, ibv_destroy_comp_channel \- create or
destroy a completion event channel
.SH "SYNOPSIS"
.nf
.B #include <infiniband/verbs.h>
.sp
.BI "struct ibv_comp_channel *ibv_create_comp_channel(struct ibv_context
.BI " " "*context" );
.sp
.BI "int ibv_destroy_comp_channel(struct ibv_comp_channel " "*channel" );
.fi
.SH "DESCRIPTION"
.B ibv_create_comp_channel()
creates a completion event channel for the RDMA device context
.I context\fR.
.PP
.B ibv_destroy_comp_channel()
destroys the completion event channel
.I channel\fR.
.SH "RETURN VALUE"
.B ibv_create_comp_channel()
returns a pointer to the created completion event channel, or NULL if the request fails.
.PP
.B ibv_destroy_comp_channel()
returns 0 on success, or the value of errno on failure (which indicates the failure reason).
.SH "NOTES"
A "completion channel" is an abstraction introduced by libibverbs that
does not exist in the InfiniBand Architecture verbs specification or
RDMA Protocol Verbs Specification. A completion channel is
essentially file descriptor that is used to deliver completion
notifications to a userspace process. When a completion event is
generated for a completion queue (CQ), the event is delivered via the
completion channel attached to that CQ. This may be useful to steer
completion events to different threads by using multiple completion
channels.
.PP
.B ibv_destroy_comp_channel()
fails if any CQs are still associated with the completion event
channel being destroyed.
.SH "SEE ALSO"
.BR ibv_open_device (3),
.BR ibv_create_cq (3),
.BR ibv_get_cq_event (3)
.SH "AUTHORS"
.TP
Dotan Barak <dotanb@mellanox.co.il>

View File

@ -0,0 +1,58 @@
.\" -*- nroff -*-
.\"
.TH IBV_CREATE_CQ 3 2006-10-31 libibverbs "Libibverbs Programmer's Manual"
.SH "NAME"
ibv_create_cq, ibv_destroy_cq \- create or destroy a completion queue (CQ)
.SH "SYNOPSIS"
.nf
.B #include <infiniband/verbs.h>
.sp
.BI "struct ibv_cq *ibv_create_cq(struct ibv_context " "*context" ", int " "cqe" ,
.BI " void " "*cq_context" ,
.BI " struct ibv_comp_channel " "*channel" ,
.BI " int " "comp_vector" );
.sp
.BI "int ibv_destroy_cq(struct ibv_cq " "*cq" );
.fi
.SH "DESCRIPTION"
.B ibv_create_cq()
creates a completion queue (CQ) with at least
.I cqe
entries for the RDMA device context
.I context\fR.
The pointer
.I cq_context
will be used to set user context pointer of the CQ structure. The argument
.I channel
is optional; if not NULL, the completion channel
.I channel
will be used to return completion events. The CQ will use the
completion vector
.I comp_vector
for signaling completion events; it must be at least zero and less than
.I context\fR->num_comp_vectors.
.PP
.B ibv_destroy_cq()
destroys the CQ
.I cq\fR.
.SH "RETURN VALUE"
.B ibv_create_cq()
returns a pointer to the CQ, or NULL if the request fails.
.PP
.B ibv_destroy_cq()
returns 0 on success, or the value of errno on failure (which indicates the failure reason).
.SH "NOTES"
.B ibv_create_cq()
may create a CQ with size greater than or equal to the requested
size. Check the cqe attribute in the returned CQ for the actual size.
.PP
.B ibv_destroy_cq()
fails if any queue pair is still associated with this CQ.
.SH "SEE ALSO"
.BR ibv_resize_cq (3),
.BR ibv_req_notify_cq (3),
.BR ibv_ack_cq_events (3),
.BR ibv_create_qp (3)
.SH "AUTHORS"
.TP
Dotan Barak <dotanb@mellanox.co.il>

View File

@ -0,0 +1,86 @@
.\" -*- nroff -*-
.\"
.TH IBV_CREATE_QP 3 2006-10-31 libibverbs "Libibverbs Programmer's Manual"
.SH "NAME"
ibv_create_qp, ibv_destroy_qp \- create or destroy a queue pair (QP)
.SH "SYNOPSIS"
.nf
.B #include <infiniband/verbs.h>
.sp
.BI "struct ibv_qp *ibv_create_qp(struct ibv_pd " "*pd" ,
.BI " struct ibv_qp_init_attr " "*qp_init_attr" );
.sp
.BI "int ibv_destroy_qp(struct ibv_qp " "*qp" );
.fi
.SH "DESCRIPTION"
.B ibv_create_qp()
creates a queue pair (QP) associated with the protection domain
.I pd\fR.
The argument
.I qp_init_attr
is an ibv_qp_init_attr struct, as defined in <infiniband/verbs.h>.
.PP
.nf
struct ibv_qp_init_attr {
.in +8
void *qp_context; /* Associated context of the QP */
struct ibv_cq *send_cq; /* CQ to be associated with the Send Queue (SQ) */
struct ibv_cq *recv_cq; /* CQ to be associated with the Receive Queue (RQ) */
struct ibv_srq *srq; /* SRQ handle if QP is to be associated with an SRQ, otherwise NULL */
struct ibv_qp_cap cap; /* QP capabilities */
enum ibv_qp_type qp_type; /* QP Transport Service Type: IBV_QPT_RC, IBV_QPT_UC, IBV_QPT_UD or IBV_QPT_XRC */
int sq_sig_all; /* If set, each Work Request (WR) submitted to the SQ generates a completion entry */
struct ibv_xrc_domain *xrc_domain; /* XRC domain the QP will be associated with (valid only for IBV_QPT_XRC QP), otherwise NULL */
.in -8
};
.sp
.nf
struct ibv_qp_cap {
.in +8
uint32_t max_send_wr; /* Requested max number of outstanding WRs in the SQ */
uint32_t max_recv_wr; /* Requested max number of outstanding WRs in the RQ */
uint32_t max_send_sge; /* Requested max number of scatter/gather (s/g) elements in a WR in the SQ */
uint32_t max_recv_sge; /* Requested max number of s/g elements in a WR in the SQ */
uint32_t max_inline_data;/* Requested max number of data (bytes) that can be posted inline to the SQ, otherwise 0 */
.in -8
};
.fi
.PP
The function
.B ibv_create_qp()
will update the
.I qp_init_attr\fB\fR->cap
struct with the actual \s-1QP\s0 values of the QP that was created;
the values will be greater than or equal to the values requested.
.PP
.B ibv_destroy_qp()
destroys the QP
.I qp\fR.
.SH "RETURN VALUE"
.B ibv_create_qp()
returns a pointer to the created QP, or NULL if the request fails.
Check the QP number (\fBqp_num\fR) in the returned QP.
.PP
.B ibv_destroy_qp()
returns 0 on success, or the value of errno on failure (which indicates the failure reason).
.SH "NOTES"
.B ibv_create_qp()
will fail if a it is asked to create QP of a type other than
.B IBV_QPT_RC
or
.B IBV_QPT_UD
associated with an SRQ.
.PP
The attributes max_recv_wr and max_recv_sge are ignored by
.B ibv_create_qp()
if the QP is to be associated with an SRQ.
.PP
.B ibv_destroy_qp()
fails if the QP is attached to a multicast group.
.SH "SEE ALSO"
.BR ibv_alloc_pd (3),
.BR ibv_modify_qp (3),
.BR ibv_query_qp (3)
.SH "AUTHORS"
.TP
Dotan Barak <dotanb@mellanox.co.il>

View File

@ -0,0 +1,81 @@
.\" -*- nroff -*-
.\"
.TH IBV_CREATE_SRQ 3 2006-10-31 libibverbs "Libibverbs Programmer's Manual"
.SH "NAME"
ibv_create_srq, ibv_destroy_srq \- create or destroy a shared receive queue (SRQ)
.SH "SYNOPSIS"
.nf
.B #include <infiniband/verbs.h>
.sp
.BI "struct ibv_srq *ibv_create_srq(struct ibv_pd " "*pd" ", struct "
.BI " ibv_srq_init_attr " "*srq_init_attr" );
.sp
.BI "struct ibv_srq *ibv_create_xrc_srq(struct ibv_pd " "*pd" ",
.BI " struct ibv_xrc_domain " "*xrc_domain" ",
.BI " struct ibv_cq " "*xrc_cq" ",
.BI " struct ibv_srq_init_attr " "*srq_init_attr" );
.sp
.BI "int ibv_destroy_srq(struct ibv_srq " "*srq" );
.fi
.SH "DESCRIPTION"
.B ibv_create_srq()
creates a shared receive queue (SRQ) associated with the protection domain
.I pd\fR.
.PP
.B ibv_create_xrc_srq()
creates an XRC shared receive queue (SRQ) associated with the protection domain
.I pd\fR,
the XRC domain
.I xrc_domain
and the CQ which will hold the XRC completion
.I xrc_cq\fR.
.PP
The argument
.I srq_init_attr
is an ibv_srq_init_attr struct, as defined in <infiniband/verbs.h>.
.PP
.nf
struct ibv_srq_init_attr {
.in +8
void *srq_context; /* Associated context of the SRQ */
struct ibv_srq_attr attr; /* SRQ attributes */
.in -8
};
.sp
.nf
struct ibv_srq_attr {
.in +8
uint32_t max_wr; /* Requested max number of outstanding work requests (WRs) in the SRQ */
uint32_t max_sge; /* Requested max number of scatter elements per WR */
uint32_t srq_limit; /* The limit value of the SRQ (irrelevant for ibv_create_srq) */
.in -8
};
.fi
.PP
The function
.B ibv_create_srq()
will update the
.I srq_init_attr
struct with the original values of the SRQ that was created; the
values of max_wr and max_sge will be greater than or equal to the
values requested.
.PP
.B ibv_destroy_srq()
destroys the SRQ
.I srq\fR.
.SH "RETURN VALUE"
.B ibv_create_srq()
returns a pointer to the created SRQ, or NULL if the request fails.
.PP
.B ibv_destroy_srq()
returns 0 on success, or the value of errno on failure (which indicates the failure reason).
.SH "NOTES"
.B ibv_destroy_srq()
fails if any queue pair is still associated with this SRQ.
.SH "SEE ALSO"
.BR ibv_alloc_pd (3),
.BR ibv_modify_srq (3),
.BR ibv_query_srq (3)
.SH "AUTHORS"
.TP
Dotan Barak <dotanb@mellanox.co.il>

View File

@ -0,0 +1,70 @@
.\" -*- nroff -*-
.\"
.TH IBV_CREATE_XRC_RCV_QP 3 2008-02-10 libibverbs "Libibverbs Programmer's Manual"
.SH "NAME"
ibv_create_xrc_rcv_qp \- create an XRC queue pair (QP) for serving as a receive-side only QP
.SH "SYNOPSIS"
.nf
.B #include <infiniband/verbs.h>
.sp
.BI "int ibv_create_xrc_rcv_qp(struct ibv_qp_init_attr " "*init_attr" ,
.BI " uint32_t " "*xrc_rcv_qpn" );
.fi
.SH "DESCRIPTION"
.B ibv_create_xrc_rcv_qp()
creates an XRC queue pair (QP) for serving as a receive-side only QP and returns its number through the pointer
.I xrc_rcv_qpn\fR.
This QP number should be passed to the remote node (sender).
The remote node will use
.I xrc_rcv_qpn
in
.B ibv_post_send()
when sending to an XRC SRQ on this host in the same xrc domain as the XRC receive QP.
This QP is created in kernel space, and persists until the last process registered for the QP
calls
.B ibv_unreg_xrc_rcv_qp()
(at which time the QP is destroyed).
.PP
The process which creates this QP is automatically registered for it, and should also call
.B ibv_unreg_xrc_rcv_qp()
at some point, to unregister.
Processes which wish to receive on an XRC SRQ via this QP should call
.B ibv_reg_xrc_rcv_qp()
for this QP, to guarantee that the QP will not be destroyed while they are still using it for receiving on the XRC SRQ.
.PP
The argument
.I qp_init_attr
is an ibv_qp_init_attr struct, as defined in <infiniband/verbs.h>.
.PP
.nf
struct ibv_qp_init_attr {
.in +8
void *qp_context; /* value is being ignored */
struct ibv_cq *send_cq; /* value is being ignored */
struct ibv_cq *recv_cq; /* value is being ignored */
struct ibv_srq *srq; /* value is being ignored */
struct ibv_qp_cap cap; /* value is being ignored */
enum ibv_qp_type qp_type; /* value is being ignored */
int sq_sig_all; /* value is being ignored */
struct ibv_xrc_domain *xrc_domain; /* XRC domain the QP will be associated with */
.in -8
};
.fi
.PP
Most of the attributes in
.I qp_init_attr
are being ignored because this QP is a receive only QP and all RR are being posted to an SRQ.
.SH "RETURN VALUE"
.B ibv_create_xrc_rcv_qp()
returns 0 on success, or the value of errno on failure (which indicates the failure reason).
.SH "SEE ALSO"
.BR ibv_open_xrc_domain (3),
.BR ibv_modify_xrc_rcv_qp (3),
.BR ibv_query_xrc_rcv_qp (3),
.BR ibv_reg_xrc_rcv_qp (3),
.BR ibv_unreg_xrc_rcv_qp (3),
.BR ibv_post_send (3)
.SH "AUTHORS"
.TP
Dotan Barak <dotanb@mellanox.co.il>

View File

@ -0,0 +1,19 @@
.TH IBV_DEVICES 1 "August 30, 2005" "libibverbs" "USER COMMANDS"
.SH NAME
ibv_devices \- list RDMA devices
.SH SYNOPSIS
.B ibv_devices
.SH DESCRIPTION
.PP
List RDMA devices available for use from userspace.
.SH SEE ALSO
.BR ibv_devinfo (1)
.SH AUTHORS
.TP
Roland Dreier
.RI < rolandd@cisco.com >

View File

@ -0,0 +1,39 @@
.TH IBV_DEVINFO 1 "August 30, 2005" "libibverbs" "USER COMMANDS"
.SH NAME
ibv_devinfo \- query RDMA devices
.SH SYNOPSIS
.B ibv_devinfo
[\-d device] [\-i port] [\-l] [\-v]
.SH DESCRIPTION
.PP
Print information about RDMA devices available for use from userspace.
.SH OPTIONS
.PP
.TP
\fB\-d\fR, \fB\-\-ib\-dev\fR=\fIDEVICE\fR
use IB device \fIDEVICE\fR (default first device found)
\fB\-i\fR, \fB\-\-ib\-port\fR=\fIPORT\fR
query port \fIPORT\fR (default all ports)
\fB\-l\fR, \fB\-\-list\fR
only list names of RDMA devices
\fB\-v\fR, \fB\-\-verbose\fR
print all available information about RDMA devices
.SH SEE ALSO
.BR ibv_devices (1)
.SH AUTHORS
.TP
Dotan Barak
.RI < dotanb@mellanox.co.il >
.TP
Roland Dreier
.RI < rolandd@cisco.com >

View File

@ -0,0 +1,40 @@
.\" -*- nroff -*-
.\"
.TH IBV_EVENT_TYPE_STR 3 2006-10-31 libibverbs "Libibverbs Programmer's Manual"
.SH "NAME"
.nf
ibv_event_type_str \- Return string describing event_type enum value
.sp
ibv_node_type_str \- Return string describing node_type enum value
.sp
ibv_port_state_str \- Return string describing port_state enum value
.SH "SYNOPSIS"
.nf
.B #include <infiniband/verbs.h>
.sp
.BI "const char *ibv_event_type_str(enum ibv_event_type " "event_type");
.sp
.BI "const char *ibv_node_type_str(enum ibv_node_type " "node_type");
.sp
.BI "const char *ibv_port_state_str(enum ibv_port_state " "port_state");
.fi
.SH "DESCRIPTION"
.B ibv_node_type_str()
returns a string describing the node type enum value
.IR node_type .
.PP
.B ibv_port_state_str()
returns a string describing the port state enum value
.IR port_state .
.PP
.B ibv_event_type_str()
returns a string describing the event type enum value
.IR event_type .
.SH "RETURN VALUE"
These functions return a constant string that describes the enum value
passed as their argument.
.SH "AUTHOR"
.TP
Roland Dreier
.RI < rolandd@cisco.com >

View File

@ -0,0 +1,58 @@
.\" -*- nroff -*-
.\"
.TH IBV_FORK_INIT 3 2006-10-31 libibverbs "Libibverbs Programmer's Manual"
.SH "NAME"
ibv_fork_init \- initialize libibverbs to support fork()
.SH "SYNOPSIS"
.nf
.B #include <infiniband/verbs.h>
.sp
.BI "int ibv_fork_init(void);
.fi
.SH "DESCRIPTION"
.B ibv_fork_init()
initializes libibverbs's data structures to handle
.B fork()
function calls correctly and avoid data corruption, whether
.B fork()
is called explicitly or implicitly (such as in
.B system()\fR).
.PP
It is not necessary to use this function if all parent process threads
are always blocked until all child processes end or change address
spaces via an
.B exec()
operation.
.SH "RETURN VALUE"
.B ibv_fork_init()
returns 0 on success, or the value of errno on failure (which indicates the failure reason).
.SH "NOTES"
.B ibv_fork_init()
works on Linux kernels supporting the
.BR MADV_DONTFORK
flag for
.B madvise()
(2.6.17 and higher).
.PP
Setting the environment variable
.BR RDMAV_FORK_SAFE
or
.BR IBV_FORK_SAFE
has the same effect as calling
.B ibv_fork_init()\fR.
.PP
Calling
.B ibv_fork_init()
will reduce performance due to an extra system call for every memory
registration, and the additional memory allocated to track memory
regions. The precise performance impact depends on the workload and
usually will not be significant.
.SH "SEE ALSO"
.BR fork (2),
.BR wait (2),
.BR system (3),
.BR exec (3),
.BR ibv_get_device_list (3)
.SH "AUTHORS"
.TP
Dotan Barak <dotanb@mellanox.co.il>

View File

@ -0,0 +1,162 @@
.\" -*- nroff -*-
.\"
.TH IBV_GET_ASYNC_EVENT 3 2006-10-31 libibverbs "Libibverbs Programmer's Manual"
.SH "NAME"
ibv_get_async_event, ibv_ack_async_event \- get or acknowledge asynchronous events
.SH "SYNOPSIS"
.nf
.B #include <infiniband/verbs.h>
.sp
.BI "int ibv_get_async_event(struct ibv_context " "*context" ,
.BI " struct ibv_async_event " "*event" );
.sp
.BI "void ibv_ack_async_event(struct ibv_async_event " "*event" );
.fi
.SH "DESCRIPTION"
.B ibv_get_async_event()
waits for the next async event of the RDMA device context
.I context
and returns it through the pointer
.I event\fR,
which is an ibv_async_event struct, as defined in <infiniband/verbs.h>.
.PP
.nf
struct ibv_async_event {
.in +8
union {
.in +8
struct ibv_cq *cq; /* CQ that got the event */
struct ibv_qp *qp; /* QP that got the event */
struct ibv_srq *srq; /* SRQ that got the event */
int port_num; /* port number that got the event */
.in -8
} element;
enum ibv_event_type event_type; /* type of the event */
.in -8
};
.fi
.PP
One member of the element union will be valid, depending on the
event_type member of the structure. event_type will be one of the
following events:
.PP
.I QP events:
.TP
.B IBV_EVENT_QP_FATAL \fR Error occurred on a QP and it transitioned to error state
.TP
.B IBV_EVENT_QP_REQ_ERR \fR Invalid Request Local Work Queue Error
.TP
.B IBV_EVENT_QP_ACCESS_ERR \fR Local access violation error
.TP
.B IBV_EVENT_COMM_EST \fR Communication was established on a QP
.TP
.B IBV_EVENT_SQ_DRAINED \fR Send Queue was drained of outstanding messages in progress
.TP
.B IBV_EVENT_PATH_MIG \fR A connection has migrated to the alternate path
.TP
.B IBV_EVENT_PATH_MIG_ERR \fR A connection failed to migrate to the alternate path
.TP
.B IBV_EVENT_QP_LAST_WQE_REACHED \fR Last WQE Reached on a QP associated with an SRQ
.PP
.I CQ events:
.TP
.B IBV_EVENT_CQ_ERR \fR CQ is in error (CQ overrun)
.PP
.I SRQ events:
.TP
.B IBV_EVENT_SRQ_ERR \fR Error occurred on an SRQ
.TP
.B IBV_EVENT_SRQ_LIMIT_REACHED \fR SRQ limit was reached
.PP
.I Port events:
.TP
.B IBV_EVENT_PORT_ACTIVE \fR Link became active on a port
.TP
.B IBV_EVENT_PORT_ERR \fR Link became unavailable on a port
.TP
.B IBV_EVENT_LID_CHANGE \fR LID was changed on a port
.TP
.B IBV_EVENT_PKEY_CHANGE \fR P_Key table was changed on a port
.TP
.B IBV_EVENT_SM_CHANGE \fR SM was changed on a port
.TP
.B IBV_EVENT_CLIENT_REREGISTER \fR SM sent a CLIENT_REREGISTER request to a port
.PP
.I CA events:
.TP
.B IBV_EVENT_DEVICE_FATAL \fR CA is in FATAL state
.PP
.B ibv_ack_async_event()
acknowledge the async event
.I event\fR.
.SH "RETURN VALUE"
.B ibv_get_async_event()
returns 0 on success, and \-1 on error.
.PP
.B ibv_ack_async_event()
returns no value.
.SH "NOTES"
All async events that
.B ibv_get_async_event()
returns must be acknowledged using
.B ibv_ack_async_event()\fR.
To avoid races, destroying an object (CQ, SRQ or QP) will wait for all
affiliated events for the object to be acknowledged; this avoids an
application retrieving an affiliated event after the corresponding
object has already been destroyed.
.PP
.B ibv_get_async_event()
is a blocking function. If multiple threads call this function
simultaneously, then when an async event occurs, only one thread will
receive it, and it is not possible to predict which thread will
receive it.
.SH "EXAMPLES"
The following code example demonstrates one possible way to work with async events in non-blocking mode.
It performs the following steps:
.PP
1. Set the async events queue work mode to be non-blocked
.br
2. Poll the queue until it has an async event
.br
3. Get the async event and ack it
.PP
.nf
/* change the blocking mode of the async event queue */
flags = fcntl(ctx->async_fd, F_GETFL);
rc = fcntl(ctx->async_fd, F_SETFL, flags | O_NONBLOCK);
if (rc < 0) {
fprintf(stderr, "Failed to change file descriptor of async event queue\en");
return 1;
}
/*
* poll the queue until it has an event and sleep ms_timeout
* milliseconds between any iteration
*/
my_pollfd.fd = ctx->async_fd;
my_pollfd.events = POLLIN;
my_pollfd.revents = 0;
do {
rc = poll(&my_pollfd, 1, ms_timeout);
} while (rc == 0);
if (rc < 0) {
fprintf(stderr, "poll failed\en");
return 1;
}
/* Get the async event */
if (ibv_get_async_event(ctx, &async_event)) {
fprintf(stderr, "Failed to get async_event\en");
return 1;
}
/* Ack the event */
ibv_ack_async_event(&async_event);
.fi
.SH "SEE ALSO"
.BR ibv_open_device (3)
.SH "AUTHORS"
.TP
Dotan Barak <dotanb@mellanox.co.il>

View File

@ -0,0 +1,185 @@
.\" -*- nroff -*-
.\"
.TH IBV_GET_CQ_EVENT 3 2006-10-31 libibverbs "Libibverbs Programmer's Manual"
.SH "NAME"
ibv_get_cq_event, ibv_ack_cq_events \- get and acknowledge completion queue (CQ) events
.SH "SYNOPSIS"
.nf
.B #include <infiniband/verbs.h>
.sp
.BI "int ibv_get_cq_event(struct ibv_comp_channel " "*channel" ,
.BI " struct ibv_cq " "**cq" ", void " "**cq_context" );
.sp
.BI "void ibv_ack_cq_events(struct ibv_cq " "*cq" ", unsigned int " "nevents" );
.fi
.SH "DESCRIPTION"
.B ibv_get_cq_event()
waits for the next completion event in the completion event channel
.I channel\fR.
Fills the arguments
.I cq
with the CQ that got the event and
.I cq_context
with the CQ's context\fR.
.PP
.B ibv_ack_cq_events()
acknowledges
.I nevents
events on the CQ
.I cq\fR.
.SH "RETURN VALUE"
.B ibv_get_cq_event()
returns 0 on success, and \-1 on error.
.PP
.B ibv_ack_cq_events()
returns no value.
.SH "NOTES"
All completion events that
.B ibv_get_cq_event()
returns must be acknowledged using
.B ibv_ack_cq_events()\fR.
To avoid races, destroying a CQ will wait for all completion events to
be acknowledged; this guarantees a one-to-one correspondence between
acks and successful gets.
.PP
Calling
.B ibv_ack_cq_events()
may be relatively expensive in the datapath, since it must take a
mutex. Therefore it may be better to amortize this cost by
keeping a count of the number of events needing acknowledgement and
acking several completion events in one call to
.B ibv_ack_cq_events()\fR.
.SH "EXAMPLES"
The following code example demonstrates one possible way to work with
completion events. It performs the following steps:
.PP
Stage I: Preparation
.br
1. Creates a CQ
.br
2. Requests for notification upon a new (first) completion event
.PP
Stage II: Completion Handling Routine
.br
3. Wait for the completion event and ack it
.br
4. Request for notification upon the next completion event
.br
5. Empty the CQ
.PP
Note that an extra event may be triggered without having a
corresponding completion entry in the CQ. This occurs if a completion
entry is added to the CQ between Step 4 and Step 5, and the CQ is then
emptied (polled) in Step 5.
.PP
.nf
cq = ibv_create_cq(ctx, 1, ev_ctx, channel, 0);
if (!cq) {
fprintf(stderr, "Failed to create CQ\en");
return 1;
}
.PP
/* Request notification before any completion can be created */
if (ibv_req_notify_cq(cq, 0)) {
fprintf(stderr, "Couldn't request CQ notification\en");
return 1;
}
.PP
\&.
\&.
\&.
.PP
/* Wait for the completion event */
if (ibv_get_cq_event(channel, &ev_cq, &ev_ctx)) {
fprintf(stderr, "Failed to get cq_event\en");
return 1;
}
/* Ack the event */
ibv_ack_cq_events(ev_cq, 1);
.PP
/* Request notification upon the next completion event */
if (ibv_req_notify_cq(ev_cq, 0)) {
fprintf(stderr, "Couldn't request CQ notification\en");
return 1;
}
.PP
/* Empty the CQ: poll all of the completions from the CQ (if any exist) */
do {
ne = ibv_poll_cq(cq, 1, &wc);
if (ne < 0) {
fprintf(stderr, "Failed to poll completions from the CQ\en");
return 1;
}
/* there may be an extra event with no completion in the CQ */
if (ne == 0)
continue;
.PP
if (wc.status != IBV_WC_SUCCESS) {
fprintf(stderr, "Completion with status 0x%x was found\en", wc.status);
return 1;
}
} while (ne);
.fi
The following code example demonstrates one possible way to work with
completion events in non-blocking mode. It performs the following
steps:
.PP
1. Set the completion event channel to be non-blocked
.br
2. Poll the channel until there it has a completion event
.br
3. Get the completion event and ack it
.PP
.nf
/* change the blocking mode of the completion channel */
flags = fcntl(channel->fd, F_GETFL);
rc = fcntl(channel->fd, F_SETFL, flags | O_NONBLOCK);
if (rc < 0) {
fprintf(stderr, "Failed to change file descriptor of completion event channel\en");
return 1;
}
/*
* poll the channel until it has an event and sleep ms_timeout
* milliseconds between any iteration
*/
my_pollfd.fd = channel->fd;
my_pollfd.events = POLLIN;
my_pollfd.revents = 0;
do {
rc = poll(&my_pollfd, 1, ms_timeout);
} while (rc == 0);
if (rc < 0) {
fprintf(stderr, "poll failed\en");
return 1;
}
ev_cq = cq;
/* Wait for the completion event */
if (ibv_get_cq_event(channel, &ev_cq, &ev_ctx)) {
fprintf(stderr, "Failed to get cq_event\en");
return 1;
}
/* Ack the event */
ibv_ack_cq_events(ev_cq, 1);
.fi
.SH "SEE ALSO"
.BR ibv_create_comp_channel (3),
.BR ibv_create_cq (3),
.BR ibv_req_notify_cq (3),
.BR ibv_poll_cq (3)
.SH "AUTHORS"
.TP
Dotan Barak
.RI < dotanb@mellanox.co.il >

Some files were not shown because too many files have changed in this diff Show More