Merge pull request #556 from jsquyres/pr/libfabric-1.0rc6
Update embedded libfabric to 1.0rc6
Этот коммит содержится в:
Коммит
5114f7f37a
@ -696,7 +696,7 @@ static int start_av_insert(opal_btl_usnic_module_t *module,
|
||||
ret = fi_av_insert(module->av, &sin, 1,
|
||||
&endpoint->endpoint_remote_addrs[channel], 0, context);
|
||||
/* Did an error occur? */
|
||||
if (1 != ret) {
|
||||
if (0 != ret) {
|
||||
opal_show_help("help-mpi-btl-usnic.txt", "libfabric API failed",
|
||||
true,
|
||||
opal_process_info.nodename,
|
||||
|
@ -247,6 +247,7 @@ _psm_files = \
|
||||
prov/psm/src/psmx_init.c \
|
||||
prov/psm/src/psmx_domain.c \
|
||||
prov/psm/src/psmx_cq.c \
|
||||
prov/psm/src/psmx_eq.c \
|
||||
prov/psm/src/psmx_cntr.c \
|
||||
prov/psm/src/psmx_av.c \
|
||||
prov/psm/src/psmx_ep.c \
|
||||
@ -434,7 +435,6 @@ dummy_man_pages = \
|
||||
man/man3/fi_trecv.3 \
|
||||
man/man3/fi_trecvmsg.3 \
|
||||
man/man3/fi_trecvv.3 \
|
||||
man/man3/fi_tsearch.3 \
|
||||
man/man3/fi_tsend.3 \
|
||||
man/man3/fi_tsenddata.3 \
|
||||
man/man3/fi_tsendmsg.3 \
|
||||
|
@ -1,13 +1,78 @@
|
||||
This README is for userspace RDMA fabric library.
|
||||
Version Libfabric v1.0.0rc6
|
||||
Released on 2015-04-24
|
||||
|
||||
Introduction
|
||||
============
|
||||
Libfabric is a communication library that exports interfaces for
|
||||
fabric services to applications. Libfabric is the core component
|
||||
of the Open Fabrics Interfaces (OFI) framework.
|
||||
|
||||
Libfabric has the following objectives:
|
||||
|
||||
* High-performance: provide optimized software paths to hardware
|
||||
- Independent of hardware implementations
|
||||
* Scalable: targets support for millions of processes
|
||||
- Designed to reduce cache and memory footprint
|
||||
- Scalable address resolution and storage
|
||||
- Tight data structures
|
||||
* Application-centric
|
||||
- Interfaces co-designed with application developers and hardware
|
||||
vendors
|
||||
* Extensible
|
||||
- Easily adaptable to support future application needs
|
||||
|
||||
OFI is being developed by the OFI Working Group (OFIWG) a subgroup
|
||||
of the OpenFabrics Alliance (OFA). Participation in OFIWG
|
||||
(pronounced o-fee-wig) is open to anyone, regardless of their
|
||||
membership in OFA.
|
||||
|
||||
The goal of OFI and libfabric is to define interfaces that enable
|
||||
a tight semantic map between applications and underlying fabric
|
||||
services. Specifically, libfabric software interfaces have been
|
||||
co-designed with fabric hardware providers and application developers,
|
||||
with an initial focus on the needs of HPC users. OFI supports multiple
|
||||
interface semantics, is fabric and hardware implementation agnostic,
|
||||
and leverages and expands the existing RDMA open source community.
|
||||
|
||||
For more information regarding the OFI project, please visit the OFIWG
|
||||
GitHub site:
|
||||
|
||||
http://ofiwg.github.io/libfabric/
|
||||
|
||||
|
||||
Support
|
||||
=======
|
||||
OFI targets support for the Linux operating system. A reasonable effort
|
||||
is made to support all major, modern Linux distributions; however,
|
||||
validation is limited to the most recent 2-3 releases of RedHat
|
||||
Enterprise Linux (RHEL)and SUSE Linux Enterprise Server (SLES).
|
||||
OFI aligns its supported distributions with the most current
|
||||
OpenFabrics Enterprise Distribution (OFED) software releases. With
|
||||
the exception of the sockets provider, which is provided for development
|
||||
purposes, distro support for a specific provider is vendor specific.
|
||||
|
||||
Libfabric will also run on OS-X, but OS X support is provided as a convenience
|
||||
for developers.
|
||||
|
||||
Bugs, issues, or requests for feature enhancements may be made directly to
|
||||
the github issues list:
|
||||
|
||||
https://github.com/ofiwg/libfabric/issues
|
||||
|
||||
Additionally, users may post questions, comments, bugs, etc. to the OFIWG
|
||||
mailing list. (Don't be bashful. We don't bite.)
|
||||
|
||||
ofiwg@lists.openfabrics.org
|
||||
|
||||
Patches may be submitted using github (preferred) or posted to the OFIWG
|
||||
mail list.
|
||||
|
||||
Version Libfabric v1.0.0rc5
|
||||
Released on 2015-04-02
|
||||
|
||||
Building
|
||||
========
|
||||
To make this directory, run:
|
||||
./autogen.sh && ./configure && make && make install
|
||||
To install from a libfabric source package run the following commands:
|
||||
|
||||
Typically the autogen and configure steps only need be done the first
|
||||
time unless configure.ac or Makefile.am changes.
|
||||
./configure && make && make install
|
||||
|
||||
If building directly from the libfabric git tree, run './autogen.sh'
|
||||
before the configure step.
|
||||
|
1552
opal/mca/common/libfabric/libfabric/config/config.guess
поставляемый
1552
opal/mca/common/libfabric/libfabric/config/config.guess
поставляемый
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
1788
opal/mca/common/libfabric/libfabric/config/config.sub
поставляемый
1788
opal/mca/common/libfabric/libfabric/config/config.sub
поставляемый
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@ -1,791 +0,0 @@
|
||||
#! /bin/sh
|
||||
# depcomp - compile a program generating dependencies as side-effects
|
||||
|
||||
scriptversion=2013-05-30.07; # UTC
|
||||
|
||||
# Copyright (C) 1999-2013 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# 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 outputting dependencies.
|
||||
libtool Whether libtool is used (yes/no).
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "depcomp $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
|
||||
# Get the directory component of the given path, and save it in the
|
||||
# global variables '$dir'. Note that this directory component will
|
||||
# be either empty or ending with a '/' character. This is deliberate.
|
||||
set_dir_from ()
|
||||
{
|
||||
case $1 in
|
||||
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
|
||||
*) dir=;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Get the suffix-stripped basename of the given path, and save it the
|
||||
# global variable '$base'.
|
||||
set_base_from ()
|
||||
{
|
||||
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
|
||||
}
|
||||
|
||||
# If no dependency file was actually created by the compiler invocation,
|
||||
# we still have to create a dummy depfile, to avoid errors with the
|
||||
# Makefile "include basename.Plo" scheme.
|
||||
make_dummy_depfile ()
|
||||
{
|
||||
echo "#dummy" > "$depfile"
|
||||
}
|
||||
|
||||
# Factor out some common post-processing of the generated depfile.
|
||||
# Requires the auxiliary global variable '$tmpdepfile' to be set.
|
||||
aix_post_process_depfile ()
|
||||
{
|
||||
# If the compiler actually managed to produce a dependency file,
|
||||
# post-process it.
|
||||
if test -f "$tmpdepfile"; then
|
||||
# Each line is of the form 'foo.o: dependency.h'.
|
||||
# Do two passes, one to just change these to
|
||||
# $object: dependency.h
|
||||
# and one to simply output
|
||||
# dependency.h:
|
||||
# which is needed to avoid the deleted-header problem.
|
||||
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
|
||||
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
|
||||
} > "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
else
|
||||
make_dummy_depfile
|
||||
fi
|
||||
}
|
||||
|
||||
# A tabulation character.
|
||||
tab=' '
|
||||
# A newline character.
|
||||
nl='
|
||||
'
|
||||
# Character ranges might be problematic outside the C locale.
|
||||
# These definitions help.
|
||||
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
lower=abcdefghijklmnopqrstuvwxyz
|
||||
digits=0123456789
|
||||
alpha=${upper}${lower}
|
||||
|
||||
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"
|
||||
|
||||
# Avoid interferences from the environment.
|
||||
gccflag= dashmflag=
|
||||
|
||||
# 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
|
||||
|
||||
cygpath_u="cygpath -u -f -"
|
||||
if test "$depmode" = msvcmsys; then
|
||||
# This is just like msvisualcpp but w/o cygpath translation.
|
||||
# Just convert the backslash-escaped backslashes to single forward
|
||||
# slashes to satisfy depend.m4
|
||||
cygpath_u='sed s,\\\\,/,g'
|
||||
depmode=msvisualcpp
|
||||
fi
|
||||
|
||||
if test "$depmode" = msvc7msys; then
|
||||
# This is just like msvc7 but w/o cygpath translation.
|
||||
# Just convert the backslash-escaped backslashes to single forward
|
||||
# slashes to satisfy depend.m4
|
||||
cygpath_u='sed s,\\\\,/,g'
|
||||
depmode=msvc7
|
||||
fi
|
||||
|
||||
if test "$depmode" = xlc; then
|
||||
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
|
||||
gccflag=-qmakedep=gcc,-MF
|
||||
depmode=gcc
|
||||
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.
|
||||
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
|
||||
## the command line argument order; so add the flags where they
|
||||
## appear in depend2.am. Note that the slowdown incurred here
|
||||
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
|
||||
*) set fnord "$@" "$arg" ;;
|
||||
esac
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
done
|
||||
"$@"
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
mv "$tmpdepfile" "$depfile"
|
||||
;;
|
||||
|
||||
gcc)
|
||||
## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
|
||||
## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
|
||||
## (see the conditional assignment to $gccflag above).
|
||||
## 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). Also, it might not be
|
||||
## supported by the other compilers which use the 'gcc' depmode.
|
||||
## - 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 -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
# 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.
|
||||
## 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. hp depmode also adds that space, but also prefixes the VPATH
|
||||
## to the object. Take care to not repeat it in the output.
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -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 -ne 0; then
|
||||
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 ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
|
||||
| tr "$nl" ' ' >> "$depfile"
|
||||
echo >> "$depfile"
|
||||
# The second pass generates a dummy entry for each header file.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
|
||||
>> "$depfile"
|
||||
else
|
||||
make_dummy_depfile
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
xlc)
|
||||
# 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
|
||||
;;
|
||||
|
||||
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.
|
||||
set_dir_from "$object"
|
||||
set_base_from "$object"
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$base.u
|
||||
tmpdepfile3=$dir.libs/$base.u
|
||||
"$@" -Wc,-M
|
||||
else
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$dir$base.u
|
||||
tmpdepfile3=$dir$base.u
|
||||
"$@" -M
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
aix_post_process_depfile
|
||||
;;
|
||||
|
||||
tcc)
|
||||
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
|
||||
# FIXME: That version still under development at the moment of writing.
|
||||
# Make that this statement remains true also for stable, released
|
||||
# versions.
|
||||
# It will wrap lines (doesn't matter whether long or short) with a
|
||||
# trailing '\', as in:
|
||||
#
|
||||
# foo.o : \
|
||||
# foo.c \
|
||||
# foo.h \
|
||||
#
|
||||
# It will put a trailing '\' even on the last line, and will use leading
|
||||
# spaces rather than leading tabs (at least since its commit 0394caf7
|
||||
# "Emit spaces for -MD").
|
||||
"$@" -MD -MF "$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
|
||||
# We have to change lines of the first kind to '$object: \'.
|
||||
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
|
||||
# And for each line of the second kind, we have to emit a 'dep.h:'
|
||||
# dummy dependency, to avoid the deleted-header problem.
|
||||
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
## The order of this option in the case statement is important, since the
|
||||
## shell code in configure will try each of these formats in the order
|
||||
## listed in this file. A plain '-MD' option would be understood by many
|
||||
## compilers, so we must ensure this comes after the gcc and icc options.
|
||||
pgcc)
|
||||
# Portland's C compiler understands '-MD'.
|
||||
# Will always output deps to 'file.d' where file is the root name of the
|
||||
# source file under compilation, even if file resides in a subdirectory.
|
||||
# The object file name does not affect the name of the '.d' file.
|
||||
# pgcc 10.2 will output
|
||||
# foo.o: sub/foo.c sub/foo.h
|
||||
# and will wrap long lines using '\' :
|
||||
# foo.o: sub/foo.c ... \
|
||||
# sub/foo.h ... \
|
||||
# ...
|
||||
set_dir_from "$object"
|
||||
# Use the source, not the object, to determine the base name, since
|
||||
# that's sadly what pgcc will do too.
|
||||
set_base_from "$source"
|
||||
tmpdepfile=$base.d
|
||||
|
||||
# For projects that build the same source file twice into different object
|
||||
# files, the pgcc approach of using the *source* file root name can cause
|
||||
# problems in parallel builds. Use a locking strategy to avoid stomping on
|
||||
# the same $tmpdepfile.
|
||||
lockdir=$base.d-lock
|
||||
trap "
|
||||
echo '$0: caught signal, cleaning up...' >&2
|
||||
rmdir '$lockdir'
|
||||
exit 1
|
||||
" 1 2 13 15
|
||||
numtries=100
|
||||
i=$numtries
|
||||
while test $i -gt 0; do
|
||||
# mkdir is a portable test-and-set.
|
||||
if mkdir "$lockdir" 2>/dev/null; then
|
||||
# This process acquired the lock.
|
||||
"$@" -MD
|
||||
stat=$?
|
||||
# Release the lock.
|
||||
rmdir "$lockdir"
|
||||
break
|
||||
else
|
||||
# If the lock is being held by a different process, wait
|
||||
# until the winning process is done or we timeout.
|
||||
while test -d "$lockdir" && test $i -gt 0; do
|
||||
sleep 1
|
||||
i=`expr $i - 1`
|
||||
done
|
||||
fi
|
||||
i=`expr $i - 1`
|
||||
done
|
||||
trap - 1 2 13 15
|
||||
if test $i -le 0; then
|
||||
echo "$0: failed to acquire lock after $numtries attempts" >&2
|
||||
echo "$0: check lockdir '$lockdir'" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test $stat -ne 0; then
|
||||
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"
|
||||
;;
|
||||
|
||||
hp2)
|
||||
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
|
||||
# compilers, which have integrated preprocessors. The correct option
|
||||
# to use with these is +Maked; it writes dependencies to a file named
|
||||
# 'foo.d', which lands next to the object file, wherever that
|
||||
# happens to be.
|
||||
# Much of this is similar to the tru64 case; see comments there.
|
||||
set_dir_from "$object"
|
||||
set_base_from "$object"
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir.libs/$base.d
|
||||
"$@" -Wc,+Maked
|
||||
else
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
"$@" +Maked
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
|
||||
# Add 'dependent.h:' lines.
|
||||
sed -ne '2,${
|
||||
s/^ *//
|
||||
s/ \\*$//
|
||||
s/$/:/
|
||||
p
|
||||
}' "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
make_dummy_depfile
|
||||
fi
|
||||
rm -f "$tmpdepfile" "$tmpdepfile2"
|
||||
;;
|
||||
|
||||
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.
|
||||
set_dir_from "$object"
|
||||
set_base_from "$object"
|
||||
|
||||
if test "$libtool" = yes; then
|
||||
# Libtool generates 2 separate objects for the 2 libraries. These
|
||||
# two compilations output dependencies 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$base.o.d # libtool 1.5
|
||||
tmpdepfile2=$dir.libs/$base.o.d # Likewise.
|
||||
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
|
||||
"$@" -Wc,-MD
|
||||
else
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
tmpdepfile3=$dir$base.d
|
||||
"$@" -MD
|
||||
fi
|
||||
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
# Same post-processing that is required for AIX mode.
|
||||
aix_post_process_depfile
|
||||
;;
|
||||
|
||||
msvc7)
|
||||
if test "$libtool" = yes; then
|
||||
showIncludes=-Wc,-showIncludes
|
||||
else
|
||||
showIncludes=-showIncludes
|
||||
fi
|
||||
"$@" $showIncludes > "$tmpdepfile"
|
||||
stat=$?
|
||||
grep -v '^Note: including file: ' "$tmpdepfile"
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
# The first sed program below extracts the file names and escapes
|
||||
# backslashes for cygpath. The second sed program outputs the file
|
||||
# name when reading, but also accumulates all include files in the
|
||||
# hold buffer in order to output them again at the end. This only
|
||||
# works with sed implementations that can handle large buffers.
|
||||
sed < "$tmpdepfile" -n '
|
||||
/^Note: including file: *\(.*\)/ {
|
||||
s//\1/
|
||||
s/\\/\\\\/g
|
||||
p
|
||||
}' | $cygpath_u | sort -u | sed -n '
|
||||
s/ /\\ /g
|
||||
s/\(.*\)/'"$tab"'\1 \\/p
|
||||
s/.\(.*\) \\/\1:/
|
||||
H
|
||||
$ {
|
||||
s/.*/'"$tab"'/
|
||||
G
|
||||
p
|
||||
}' >> "$depfile"
|
||||
echo >> "$depfile" # make sure the fragment doesn't end with a backslash
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvc7msys)
|
||||
# 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
|
||||
;;
|
||||
|
||||
#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 "X$1" != 'X--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|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process this sed invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| 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 "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
# X makedepend
|
||||
shift
|
||||
cleared=no eat=no
|
||||
for arg
|
||||
do
|
||||
case $cleared in
|
||||
no)
|
||||
set ""; shift
|
||||
cleared=yes ;;
|
||||
esac
|
||||
if test $eat = yes; then
|
||||
eat=no
|
||||
continue
|
||||
fi
|
||||
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.
|
||||
-arch)
|
||||
eat=yes ;;
|
||||
-*|$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"
|
||||
# makedepend may prepend the VPATH from the source file name to the object.
|
||||
# No need to regex-escape $object, excess matching of '.' is harmless.
|
||||
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process the last invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed '1,2d' "$tmpdepfile" \
|
||||
| tr ' ' "$nl" \
|
||||
| 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 "X$1" != 'X--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.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case "$arg" in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
|
||||
set fnord "$@"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
"$@" -E 2>/dev/null |
|
||||
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
|
||||
echo "$tab" >> "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvcmsys)
|
||||
# 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
|
||||
;;
|
||||
|
||||
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-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
@ -1,527 +0,0 @@
|
||||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2011-11-20.07; # UTC
|
||||
|
||||
# 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.
|
||||
|
||||
nl='
|
||||
'
|
||||
IFS=" "" $nl"
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit=${DOITPROG-}
|
||||
if test -z "$doit"; then
|
||||
doit_exec=exec
|
||||
else
|
||||
doit_exec=$doit
|
||||
fi
|
||||
|
||||
# Put in absolute file names if you don't have them in your path;
|
||||
# or use environment vars.
|
||||
|
||||
chgrpprog=${CHGRPPROG-chgrp}
|
||||
chmodprog=${CHMODPROG-chmod}
|
||||
chownprog=${CHOWNPROG-chown}
|
||||
cmpprog=${CMPPROG-cmp}
|
||||
cpprog=${CPPROG-cp}
|
||||
mkdirprog=${MKDIRPROG-mkdir}
|
||||
mvprog=${MVPROG-mv}
|
||||
rmprog=${RMPROG-rm}
|
||||
stripprog=${STRIPPROG-strip}
|
||||
|
||||
posix_glob='?'
|
||||
initialize_posix_glob='
|
||||
test "$posix_glob" != "?" || {
|
||||
if (set -f) 2>/dev/null; then
|
||||
posix_glob=
|
||||
else
|
||||
posix_glob=:
|
||||
fi
|
||||
}
|
||||
'
|
||||
|
||||
posix_mkdir=
|
||||
|
||||
# Desired mode of installed file.
|
||||
mode=0755
|
||||
|
||||
chgrpcmd=
|
||||
chmodcmd=$chmodprog
|
||||
chowncmd=
|
||||
mvcmd=$mvprog
|
||||
rmcmd="$rmprog -f"
|
||||
stripcmd=
|
||||
|
||||
src=
|
||||
dst=
|
||||
dir_arg=
|
||||
dst_arg=
|
||||
|
||||
copy_on_change=false
|
||||
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:
|
||||
--help display this help and exit.
|
||||
--version display version info and exit.
|
||||
|
||||
-c (ignored)
|
||||
-C install only if different (preserve the last data modification time)
|
||||
-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.
|
||||
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
|
||||
RMPROG STRIPPROG
|
||||
"
|
||||
|
||||
while test $# -ne 0; do
|
||||
case $1 in
|
||||
-c) ;;
|
||||
|
||||
-C) copy_on_change=true;;
|
||||
|
||||
-d) dir_arg=true;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift;;
|
||||
|
||||
--help) echo "$usage"; exit $?;;
|
||||
|
||||
-m) mode=$2
|
||||
case $mode in
|
||||
*' '* | *' '* | *'
|
||||
'* | *'*'* | *'?'* | *'['*)
|
||||
echo "$0: invalid mode: $mode" >&2
|
||||
exit 1;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift;;
|
||||
|
||||
-s) stripcmd=$stripprog;;
|
||||
|
||||
-t) dst_arg=$2
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-T) no_target_directory=true;;
|
||||
|
||||
--version) echo "$0 $scriptversion"; exit $?;;
|
||||
|
||||
--) shift
|
||||
break;;
|
||||
|
||||
-*) echo "$0: invalid option: $1" >&2
|
||||
exit 1;;
|
||||
|
||||
*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
|
||||
# When -d is used, all remaining arguments are directories to create.
|
||||
# When -t is used, the destination is already specified.
|
||||
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||
for arg
|
||||
do
|
||||
if test -n "$dst_arg"; then
|
||||
# $@ is not empty: it contains at least $arg.
|
||||
set fnord "$@" "$dst_arg"
|
||||
shift # fnord
|
||||
fi
|
||||
shift # arg
|
||||
dst_arg=$arg
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if test $# -eq 0; 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
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
do_exit='(exit $ret); exit $ret'
|
||||
trap "ret=129; $do_exit" 1
|
||||
trap "ret=130; $do_exit" 2
|
||||
trap "ret=141; $do_exit" 13
|
||||
trap "ret=143; $do_exit" 15
|
||||
|
||||
# Set umask so as not to create temps with too-generous modes.
|
||||
# However, 'strip' requires both read and write access to temps.
|
||||
case $mode in
|
||||
# Optimize common cases.
|
||||
*644) cp_umask=133;;
|
||||
*755) cp_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw='% 200'
|
||||
fi
|
||||
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
|
||||
*)
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw=,u+rw
|
||||
fi
|
||||
cp_umask=$mode$u_plus_rw;;
|
||||
esac
|
||||
fi
|
||||
|
||||
for src
|
||||
do
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $src in
|
||||
-* | [=\(\)!]) src=./$src;;
|
||||
esac
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
dst=$src
|
||||
dstdir=$dst
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
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 "$dst_arg"; then
|
||||
echo "$0: no destination specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
dst=$dst_arg
|
||||
|
||||
# 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: $dst_arg: Is a directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
dstdir=$dst
|
||||
dst=$dstdir/`basename "$src"`
|
||||
dstdir_status=0
|
||||
else
|
||||
# Prefer dirname, but fall back on a substitute if dirname fails.
|
||||
dstdir=`
|
||||
(dirname "$dst") 2>/dev/null ||
|
||||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
|
||||
X"$dst" : 'X\(//\)[^/]' \| \
|
||||
X"$dst" : 'X\(//\)$' \| \
|
||||
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
|
||||
echo X"$dst" |
|
||||
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\/\)[^/].*/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\/\)$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\).*/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
s/.*/./; q'
|
||||
`
|
||||
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
fi
|
||||
fi
|
||||
|
||||
obsolete_mkdir_used=false
|
||||
|
||||
if test $dstdir_status != 0; then
|
||||
case $posix_mkdir in
|
||||
'')
|
||||
# Create intermediate dirs using mode 755 as modified by the umask.
|
||||
# This is like FreeBSD 'install' as of 1997-10-28.
|
||||
umask=`umask`
|
||||
case $stripcmd.$umask in
|
||||
# Optimize common cases.
|
||||
*[2367][2367]) mkdir_umask=$umask;;
|
||||
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
mkdir_umask=`expr $umask + 22 \
|
||||
- $umask % 100 % 40 + $umask % 20 \
|
||||
- $umask % 10 % 4 + $umask % 2
|
||||
`;;
|
||||
*) mkdir_umask=$umask,go-w;;
|
||||
esac
|
||||
|
||||
# With -d, create the new directory with the user-specified mode.
|
||||
# Otherwise, rely on $mkdir_umask.
|
||||
if test -n "$dir_arg"; then
|
||||
mkdir_mode=-m$mode
|
||||
else
|
||||
mkdir_mode=
|
||||
fi
|
||||
|
||||
posix_mkdir=false
|
||||
case $umask in
|
||||
*[123567][0-7][0-7])
|
||||
# POSIX mkdir -p sets u+wx bits regardless of umask, which
|
||||
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
|
||||
;;
|
||||
*)
|
||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
|
||||
|
||||
if (umask $mkdir_umask &&
|
||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
|
||||
then
|
||||
if test -z "$dir_arg" || {
|
||||
# Check for POSIX incompatibilities with -m.
|
||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
||||
# other-writable bit of parent directory when it shouldn't.
|
||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
||||
ls_ld_tmpdir=`ls -ld "$tmpdir"`
|
||||
case $ls_ld_tmpdir in
|
||||
d????-?r-*) different_mode=700;;
|
||||
d????-?--*) different_mode=755;;
|
||||
*) false;;
|
||||
esac &&
|
||||
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
|
||||
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
|
||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
||||
}
|
||||
}
|
||||
then posix_mkdir=:
|
||||
fi
|
||||
rmdir "$tmpdir/d" "$tmpdir"
|
||||
else
|
||||
# Remove any dirs left behind by ancient mkdir implementations.
|
||||
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
|
||||
fi
|
||||
trap '' 0;;
|
||||
esac;;
|
||||
esac
|
||||
|
||||
if
|
||||
$posix_mkdir && (
|
||||
umask $mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
|
||||
)
|
||||
then :
|
||||
else
|
||||
|
||||
# The umask is ridiculous, or mkdir does not conform to POSIX,
|
||||
# or it failed possibly due to a race condition. Create the
|
||||
# directory the slow way, step by step, checking for races as we go.
|
||||
|
||||
case $dstdir in
|
||||
/*) prefix='/';;
|
||||
[-=\(\)!]*) prefix='./';;
|
||||
*) prefix='';;
|
||||
esac
|
||||
|
||||
eval "$initialize_posix_glob"
|
||||
|
||||
oIFS=$IFS
|
||||
IFS=/
|
||||
$posix_glob set -f
|
||||
set fnord $dstdir
|
||||
shift
|
||||
$posix_glob set +f
|
||||
IFS=$oIFS
|
||||
|
||||
prefixes=
|
||||
|
||||
for d
|
||||
do
|
||||
test X"$d" = X && continue
|
||||
|
||||
prefix=$prefix$d
|
||||
if test -d "$prefix"; then
|
||||
prefixes=
|
||||
else
|
||||
if $posix_mkdir; then
|
||||
(umask=$mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
|
||||
# Don't fail if two instances are running concurrently.
|
||||
test -d "$prefix" || exit 1
|
||||
else
|
||||
case $prefix in
|
||||
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
|
||||
*) qprefix=$prefix;;
|
||||
esac
|
||||
prefixes="$prefixes '$qprefix'"
|
||||
fi
|
||||
fi
|
||||
prefix=$prefix/
|
||||
done
|
||||
|
||||
if test -n "$prefixes"; then
|
||||
# Don't fail if two instances are running concurrently.
|
||||
(umask $mkdir_umask &&
|
||||
eval "\$doit_exec \$mkdirprog $prefixes") ||
|
||||
test -d "$dstdir" || exit 1
|
||||
obsolete_mkdir_used=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
|
||||
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
|
||||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
|
||||
else
|
||||
|
||||
# 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
|
||||
|
||||
# Copy the file name to the temp name.
|
||||
(umask $cp_umask && $doit_exec $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 $mode "$dsttmp"; } &&
|
||||
|
||||
# If -C, don't bother to copy if it wouldn't change the file.
|
||||
if $copy_on_change &&
|
||||
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
|
||||
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
|
||||
|
||||
eval "$initialize_posix_glob" &&
|
||||
$posix_glob set -f &&
|
||||
set X $old && old=:$2:$4:$5:$6 &&
|
||||
set X $new && new=:$2:$4:$5:$6 &&
|
||||
$posix_glob set +f &&
|
||||
|
||||
test "$old" = "$new" &&
|
||||
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
|
||||
then
|
||||
rm -f "$dsttmp"
|
||||
else
|
||||
# Rename the file to the real destination.
|
||||
$doit $mvcmd -f "$dsttmp" "$dst" 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.
|
||||
{
|
||||
test ! -f "$dst" ||
|
||||
$doit $rmcmd -f "$dst" 2>/dev/null ||
|
||||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|
||||
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
|
||||
} ||
|
||||
{ echo "$0: cannot unlink or rename $dst" >&2
|
||||
(exit 1); exit 1
|
||||
}
|
||||
} &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
$doit $mvcmd "$dsttmp" "$dst"
|
||||
}
|
||||
fi || exit 1
|
||||
|
||||
trap '' 0
|
||||
fi
|
||||
done
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
7982
opal/mca/common/libfabric/libfabric/config/libtool.m4
поставляемый
7982
opal/mca/common/libfabric/libfabric/config/libtool.m4
поставляемый
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
384
opal/mca/common/libfabric/libfabric/config/ltoptions.m4
поставляемый
384
opal/mca/common/libfabric/libfabric/config/ltoptions.m4
поставляемый
@ -1,384 +0,0 @@
|
||||
# Helper functions for option handling. -*- Autoconf -*-
|
||||
#
|
||||
# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
|
||||
# Inc.
|
||||
# Written by Gary V. Vaughan, 2004
|
||||
#
|
||||
# This file 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.
|
||||
|
||||
# serial 7 ltoptions.m4
|
||||
|
||||
# This is to help aclocal find these macros, as it can't see m4_define.
|
||||
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
|
||||
|
||||
|
||||
# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
|
||||
# ------------------------------------------
|
||||
m4_define([_LT_MANGLE_OPTION],
|
||||
[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
|
||||
|
||||
|
||||
# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
|
||||
# ---------------------------------------
|
||||
# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
|
||||
# matching handler defined, dispatch to it. Other OPTION-NAMEs are
|
||||
# saved as a flag.
|
||||
m4_define([_LT_SET_OPTION],
|
||||
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
|
||||
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
|
||||
_LT_MANGLE_DEFUN([$1], [$2]),
|
||||
[m4_warning([Unknown $1 option `$2'])])[]dnl
|
||||
])
|
||||
|
||||
|
||||
# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
|
||||
# ------------------------------------------------------------
|
||||
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
|
||||
m4_define([_LT_IF_OPTION],
|
||||
[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
|
||||
|
||||
|
||||
# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
|
||||
# -------------------------------------------------------
|
||||
# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
|
||||
# are set.
|
||||
m4_define([_LT_UNLESS_OPTIONS],
|
||||
[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
|
||||
[m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
|
||||
[m4_define([$0_found])])])[]dnl
|
||||
m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
|
||||
])[]dnl
|
||||
])
|
||||
|
||||
|
||||
# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
|
||||
# ----------------------------------------
|
||||
# OPTION-LIST is a space-separated list of Libtool options associated
|
||||
# with MACRO-NAME. If any OPTION has a matching handler declared with
|
||||
# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
|
||||
# the unknown option and exit.
|
||||
m4_defun([_LT_SET_OPTIONS],
|
||||
[# Set options
|
||||
m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
|
||||
[_LT_SET_OPTION([$1], _LT_Option)])
|
||||
|
||||
m4_if([$1],[LT_INIT],[
|
||||
dnl
|
||||
dnl Simply set some default values (i.e off) if boolean options were not
|
||||
dnl specified:
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
|
||||
])
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
|
||||
])
|
||||
dnl
|
||||
dnl If no reference was made to various pairs of opposing options, then
|
||||
dnl we run the default mode handler for the pair. For example, if neither
|
||||
dnl `shared' nor `disable-shared' was passed, we enable building of shared
|
||||
dnl archives by default:
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
|
||||
[_LT_ENABLE_FAST_INSTALL])
|
||||
])
|
||||
])# _LT_SET_OPTIONS
|
||||
|
||||
|
||||
## --------------------------------- ##
|
||||
## Macros to handle LT_INIT options. ##
|
||||
## --------------------------------- ##
|
||||
|
||||
# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
|
||||
# -----------------------------------------
|
||||
m4_define([_LT_MANGLE_DEFUN],
|
||||
[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
|
||||
|
||||
|
||||
# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
|
||||
# -----------------------------------------------
|
||||
m4_define([LT_OPTION_DEFINE],
|
||||
[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
|
||||
])# LT_OPTION_DEFINE
|
||||
|
||||
|
||||
# dlopen
|
||||
# ------
|
||||
LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
|
||||
])
|
||||
|
||||
AU_DEFUN([AC_LIBTOOL_DLOPEN],
|
||||
[_LT_SET_OPTION([LT_INIT], [dlopen])
|
||||
AC_DIAGNOSE([obsolete],
|
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you
|
||||
put the `dlopen' option into LT_INIT's first parameter.])
|
||||
])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
|
||||
|
||||
|
||||
# win32-dll
|
||||
# ---------
|
||||
# Declare package support for building win32 dll's.
|
||||
LT_OPTION_DEFINE([LT_INIT], [win32-dll],
|
||||
[enable_win32_dll=yes
|
||||
|
||||
case $host in
|
||||
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
|
||||
AC_CHECK_TOOL(AS, as, false)
|
||||
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
|
||||
AC_CHECK_TOOL(OBJDUMP, objdump, false)
|
||||
;;
|
||||
esac
|
||||
|
||||
test -z "$AS" && AS=as
|
||||
_LT_DECL([], [AS], [1], [Assembler program])dnl
|
||||
|
||||
test -z "$DLLTOOL" && DLLTOOL=dlltool
|
||||
_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
|
||||
|
||||
test -z "$OBJDUMP" && OBJDUMP=objdump
|
||||
_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
|
||||
])# win32-dll
|
||||
|
||||
AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
|
||||
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
|
||||
_LT_SET_OPTION([LT_INIT], [win32-dll])
|
||||
AC_DIAGNOSE([obsolete],
|
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you
|
||||
put the `win32-dll' option into LT_INIT's first parameter.])
|
||||
])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
|
||||
|
||||
|
||||
# _LT_ENABLE_SHARED([DEFAULT])
|
||||
# ----------------------------
|
||||
# implement the --enable-shared flag, and supports the `shared' and
|
||||
# `disable-shared' LT_INIT options.
|
||||
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
|
||||
m4_define([_LT_ENABLE_SHARED],
|
||||
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
|
||||
AC_ARG_ENABLE([shared],
|
||||
[AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
|
||||
[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
|
||||
[p=${PACKAGE-default}
|
||||
case $enableval in
|
||||
yes) enable_shared=yes ;;
|
||||
no) enable_shared=no ;;
|
||||
*)
|
||||
enable_shared=no
|
||||
# Look at the argument we got. We use all the common list separators.
|
||||
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
|
||||
for pkg in $enableval; do
|
||||
IFS="$lt_save_ifs"
|
||||
if test "X$pkg" = "X$p"; then
|
||||
enable_shared=yes
|
||||
fi
|
||||
done
|
||||
IFS="$lt_save_ifs"
|
||||
;;
|
||||
esac],
|
||||
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
|
||||
|
||||
_LT_DECL([build_libtool_libs], [enable_shared], [0],
|
||||
[Whether or not to build shared libraries])
|
||||
])# _LT_ENABLE_SHARED
|
||||
|
||||
LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
|
||||
LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
|
||||
|
||||
# Old names:
|
||||
AC_DEFUN([AC_ENABLE_SHARED],
|
||||
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
|
||||
])
|
||||
|
||||
AC_DEFUN([AC_DISABLE_SHARED],
|
||||
[_LT_SET_OPTION([LT_INIT], [disable-shared])
|
||||
])
|
||||
|
||||
AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
|
||||
AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AM_ENABLE_SHARED], [])
|
||||
dnl AC_DEFUN([AM_DISABLE_SHARED], [])
|
||||
|
||||
|
||||
|
||||
# _LT_ENABLE_STATIC([DEFAULT])
|
||||
# ----------------------------
|
||||
# implement the --enable-static flag, and support the `static' and
|
||||
# `disable-static' LT_INIT options.
|
||||
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
|
||||
m4_define([_LT_ENABLE_STATIC],
|
||||
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
|
||||
AC_ARG_ENABLE([static],
|
||||
[AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
|
||||
[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
|
||||
[p=${PACKAGE-default}
|
||||
case $enableval in
|
||||
yes) enable_static=yes ;;
|
||||
no) enable_static=no ;;
|
||||
*)
|
||||
enable_static=no
|
||||
# Look at the argument we got. We use all the common list separators.
|
||||
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
|
||||
for pkg in $enableval; do
|
||||
IFS="$lt_save_ifs"
|
||||
if test "X$pkg" = "X$p"; then
|
||||
enable_static=yes
|
||||
fi
|
||||
done
|
||||
IFS="$lt_save_ifs"
|
||||
;;
|
||||
esac],
|
||||
[enable_static=]_LT_ENABLE_STATIC_DEFAULT)
|
||||
|
||||
_LT_DECL([build_old_libs], [enable_static], [0],
|
||||
[Whether or not to build static libraries])
|
||||
])# _LT_ENABLE_STATIC
|
||||
|
||||
LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
|
||||
LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
|
||||
|
||||
# Old names:
|
||||
AC_DEFUN([AC_ENABLE_STATIC],
|
||||
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
|
||||
])
|
||||
|
||||
AC_DEFUN([AC_DISABLE_STATIC],
|
||||
[_LT_SET_OPTION([LT_INIT], [disable-static])
|
||||
])
|
||||
|
||||
AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
|
||||
AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AM_ENABLE_STATIC], [])
|
||||
dnl AC_DEFUN([AM_DISABLE_STATIC], [])
|
||||
|
||||
|
||||
|
||||
# _LT_ENABLE_FAST_INSTALL([DEFAULT])
|
||||
# ----------------------------------
|
||||
# implement the --enable-fast-install flag, and support the `fast-install'
|
||||
# and `disable-fast-install' LT_INIT options.
|
||||
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
|
||||
m4_define([_LT_ENABLE_FAST_INSTALL],
|
||||
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
|
||||
AC_ARG_ENABLE([fast-install],
|
||||
[AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
|
||||
[optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
|
||||
[p=${PACKAGE-default}
|
||||
case $enableval in
|
||||
yes) enable_fast_install=yes ;;
|
||||
no) enable_fast_install=no ;;
|
||||
*)
|
||||
enable_fast_install=no
|
||||
# Look at the argument we got. We use all the common list separators.
|
||||
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
|
||||
for pkg in $enableval; do
|
||||
IFS="$lt_save_ifs"
|
||||
if test "X$pkg" = "X$p"; then
|
||||
enable_fast_install=yes
|
||||
fi
|
||||
done
|
||||
IFS="$lt_save_ifs"
|
||||
;;
|
||||
esac],
|
||||
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
|
||||
|
||||
_LT_DECL([fast_install], [enable_fast_install], [0],
|
||||
[Whether or not to optimize for fast installation])dnl
|
||||
])# _LT_ENABLE_FAST_INSTALL
|
||||
|
||||
LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
|
||||
LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
|
||||
|
||||
# Old names:
|
||||
AU_DEFUN([AC_ENABLE_FAST_INSTALL],
|
||||
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
|
||||
AC_DIAGNOSE([obsolete],
|
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
|
||||
the `fast-install' option into LT_INIT's first parameter.])
|
||||
])
|
||||
|
||||
AU_DEFUN([AC_DISABLE_FAST_INSTALL],
|
||||
[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
|
||||
AC_DIAGNOSE([obsolete],
|
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
|
||||
the `disable-fast-install' option into LT_INIT's first parameter.])
|
||||
])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
|
||||
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
|
||||
|
||||
|
||||
# _LT_WITH_PIC([MODE])
|
||||
# --------------------
|
||||
# implement the --with-pic flag, and support the `pic-only' and `no-pic'
|
||||
# LT_INIT options.
|
||||
# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
|
||||
m4_define([_LT_WITH_PIC],
|
||||
[AC_ARG_WITH([pic],
|
||||
[AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
|
||||
[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
|
||||
[lt_p=${PACKAGE-default}
|
||||
case $withval in
|
||||
yes|no) pic_mode=$withval ;;
|
||||
*)
|
||||
pic_mode=default
|
||||
# Look at the argument we got. We use all the common list separators.
|
||||
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
|
||||
for lt_pkg in $withval; do
|
||||
IFS="$lt_save_ifs"
|
||||
if test "X$lt_pkg" = "X$lt_p"; then
|
||||
pic_mode=yes
|
||||
fi
|
||||
done
|
||||
IFS="$lt_save_ifs"
|
||||
;;
|
||||
esac],
|
||||
[pic_mode=default])
|
||||
|
||||
test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
|
||||
|
||||
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
|
||||
])# _LT_WITH_PIC
|
||||
|
||||
LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
|
||||
LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
|
||||
|
||||
# Old name:
|
||||
AU_DEFUN([AC_LIBTOOL_PICMODE],
|
||||
[_LT_SET_OPTION([LT_INIT], [pic-only])
|
||||
AC_DIAGNOSE([obsolete],
|
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you
|
||||
put the `pic-only' option into LT_INIT's first parameter.])
|
||||
])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
|
||||
|
||||
## ----------------- ##
|
||||
## LTDL_INIT Options ##
|
||||
## ----------------- ##
|
||||
|
||||
m4_define([_LTDL_MODE], [])
|
||||
LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
|
||||
[m4_define([_LTDL_MODE], [nonrecursive])])
|
||||
LT_OPTION_DEFINE([LTDL_INIT], [recursive],
|
||||
[m4_define([_LTDL_MODE], [recursive])])
|
||||
LT_OPTION_DEFINE([LTDL_INIT], [subproject],
|
||||
[m4_define([_LTDL_MODE], [subproject])])
|
||||
|
||||
m4_define([_LTDL_TYPE], [])
|
||||
LT_OPTION_DEFINE([LTDL_INIT], [installable],
|
||||
[m4_define([_LTDL_TYPE], [installable])])
|
||||
LT_OPTION_DEFINE([LTDL_INIT], [convenience],
|
||||
[m4_define([_LTDL_TYPE], [convenience])])
|
123
opal/mca/common/libfabric/libfabric/config/ltsugar.m4
поставляемый
123
opal/mca/common/libfabric/libfabric/config/ltsugar.m4
поставляемый
@ -1,123 +0,0 @@
|
||||
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
|
||||
#
|
||||
# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
|
||||
# Written by Gary V. Vaughan, 2004
|
||||
#
|
||||
# This file 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.
|
||||
|
||||
# serial 6 ltsugar.m4
|
||||
|
||||
# This is to help aclocal find these macros, as it can't see m4_define.
|
||||
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
|
||||
|
||||
|
||||
# lt_join(SEP, ARG1, [ARG2...])
|
||||
# -----------------------------
|
||||
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
|
||||
# associated separator.
|
||||
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
|
||||
# versions in m4sugar had bugs.
|
||||
m4_define([lt_join],
|
||||
[m4_if([$#], [1], [],
|
||||
[$#], [2], [[$2]],
|
||||
[m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
|
||||
m4_define([_lt_join],
|
||||
[m4_if([$#$2], [2], [],
|
||||
[m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
|
||||
|
||||
|
||||
# lt_car(LIST)
|
||||
# lt_cdr(LIST)
|
||||
# ------------
|
||||
# Manipulate m4 lists.
|
||||
# These macros are necessary as long as will still need to support
|
||||
# Autoconf-2.59 which quotes differently.
|
||||
m4_define([lt_car], [[$1]])
|
||||
m4_define([lt_cdr],
|
||||
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
|
||||
[$#], 1, [],
|
||||
[m4_dquote(m4_shift($@))])])
|
||||
m4_define([lt_unquote], $1)
|
||||
|
||||
|
||||
# lt_append(MACRO-NAME, STRING, [SEPARATOR])
|
||||
# ------------------------------------------
|
||||
# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
|
||||
# Note that neither SEPARATOR nor STRING are expanded; they are appended
|
||||
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
|
||||
# No SEPARATOR is output if MACRO-NAME was previously undefined (different
|
||||
# than defined and empty).
|
||||
#
|
||||
# This macro is needed until we can rely on Autoconf 2.62, since earlier
|
||||
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
|
||||
m4_define([lt_append],
|
||||
[m4_define([$1],
|
||||
m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
|
||||
|
||||
|
||||
|
||||
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
|
||||
# ----------------------------------------------------------
|
||||
# Produce a SEP delimited list of all paired combinations of elements of
|
||||
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
|
||||
# has the form PREFIXmINFIXSUFFIXn.
|
||||
# Needed until we can rely on m4_combine added in Autoconf 2.62.
|
||||
m4_define([lt_combine],
|
||||
[m4_if(m4_eval([$# > 3]), [1],
|
||||
[m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
|
||||
[[m4_foreach([_Lt_prefix], [$2],
|
||||
[m4_foreach([_Lt_suffix],
|
||||
]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
|
||||
[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
|
||||
|
||||
|
||||
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
|
||||
# -----------------------------------------------------------------------
|
||||
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
|
||||
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
|
||||
m4_define([lt_if_append_uniq],
|
||||
[m4_ifdef([$1],
|
||||
[m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
|
||||
[lt_append([$1], [$2], [$3])$4],
|
||||
[$5])],
|
||||
[lt_append([$1], [$2], [$3])$4])])
|
||||
|
||||
|
||||
# lt_dict_add(DICT, KEY, VALUE)
|
||||
# -----------------------------
|
||||
m4_define([lt_dict_add],
|
||||
[m4_define([$1($2)], [$3])])
|
||||
|
||||
|
||||
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
|
||||
# --------------------------------------------
|
||||
m4_define([lt_dict_add_subkey],
|
||||
[m4_define([$1($2:$3)], [$4])])
|
||||
|
||||
|
||||
# lt_dict_fetch(DICT, KEY, [SUBKEY])
|
||||
# ----------------------------------
|
||||
m4_define([lt_dict_fetch],
|
||||
[m4_ifval([$3],
|
||||
m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
|
||||
m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
|
||||
|
||||
|
||||
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
|
||||
# -----------------------------------------------------------------
|
||||
m4_define([lt_if_dict_fetch],
|
||||
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
|
||||
[$5],
|
||||
[$6])])
|
||||
|
||||
|
||||
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
|
||||
# --------------------------------------------------------------
|
||||
m4_define([lt_dict_filter],
|
||||
[m4_if([$5], [], [],
|
||||
[lt_join(m4_quote(m4_default([$4], [[, ]])),
|
||||
lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
|
||||
[lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
|
||||
])
|
23
opal/mca/common/libfabric/libfabric/config/ltversion.m4
поставляемый
23
opal/mca/common/libfabric/libfabric/config/ltversion.m4
поставляемый
@ -1,23 +0,0 @@
|
||||
# ltversion.m4 -- version numbers -*- Autoconf -*-
|
||||
#
|
||||
# Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
# Written by Scott James Remnant, 2004
|
||||
#
|
||||
# This file 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.
|
||||
|
||||
# @configure_input@
|
||||
|
||||
# serial 3337 ltversion.m4
|
||||
# This file is part of GNU Libtool
|
||||
|
||||
m4_define([LT_PACKAGE_VERSION], [2.4.2])
|
||||
m4_define([LT_PACKAGE_REVISION], [1.3337])
|
||||
|
||||
AC_DEFUN([LTVERSION_VERSION],
|
||||
[macro_version='2.4.2'
|
||||
macro_revision='1.3337'
|
||||
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
|
||||
_LT_DECL(, macro_revision, 0)
|
||||
])
|
98
opal/mca/common/libfabric/libfabric/config/lt~obsolete.m4
поставляемый
98
opal/mca/common/libfabric/libfabric/config/lt~obsolete.m4
поставляемый
@ -1,98 +0,0 @@
|
||||
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
|
||||
#
|
||||
# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
|
||||
# Written by Scott James Remnant, 2004.
|
||||
#
|
||||
# This file 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.
|
||||
|
||||
# serial 5 lt~obsolete.m4
|
||||
|
||||
# These exist entirely to fool aclocal when bootstrapping libtool.
|
||||
#
|
||||
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
|
||||
# which have later been changed to m4_define as they aren't part of the
|
||||
# exported API, or moved to Autoconf or Automake where they belong.
|
||||
#
|
||||
# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
|
||||
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
|
||||
# using a macro with the same name in our local m4/libtool.m4 it'll
|
||||
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
|
||||
# and doesn't know about Autoconf macros at all.)
|
||||
#
|
||||
# So we provide this file, which has a silly filename so it's always
|
||||
# included after everything else. This provides aclocal with the
|
||||
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
|
||||
# because those macros already exist, or will be overwritten later.
|
||||
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
|
||||
#
|
||||
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
|
||||
# Yes, that means every name once taken will need to remain here until
|
||||
# we give up compatibility with versions before 1.7, at which point
|
||||
# we need to keep only those names which we still refer to.
|
||||
|
||||
# This is to help aclocal find these macros, as it can't see m4_define.
|
||||
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
|
||||
|
||||
m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
|
||||
m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
|
||||
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
|
||||
m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
|
||||
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
|
||||
m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
|
||||
m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
|
||||
m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
|
||||
m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
|
||||
m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
|
||||
m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
|
||||
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
|
||||
m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
|
||||
m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
|
||||
m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
|
||||
m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
|
||||
m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
|
||||
m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
|
||||
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
|
||||
m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
|
||||
m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
|
||||
m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
|
||||
m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
|
||||
m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
|
||||
m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
|
||||
m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
|
||||
m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
|
||||
m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
|
||||
m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
|
||||
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
|
||||
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
|
||||
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
|
||||
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
|
||||
m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
|
||||
m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
|
||||
m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
|
||||
m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
|
||||
m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
|
||||
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
|
||||
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
|
@ -1,215 +0,0 @@
|
||||
#! /bin/sh
|
||||
# Common wrapper for a few potentially missing GNU programs.
|
||||
|
||||
scriptversion=2012-06-26.16; # UTC
|
||||
|
||||
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
|
||||
# Originally written 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# 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
|
||||
|
||||
case $1 in
|
||||
|
||||
--is-lightweight)
|
||||
# Used by our autoconf macros to check whether the available missing
|
||||
# script is modern enough.
|
||||
exit 0
|
||||
;;
|
||||
|
||||
--run)
|
||||
# Back-compat with the calling convention used by older automake.
|
||||
shift
|
||||
;;
|
||||
|
||||
-h|--h|--he|--hel|--help)
|
||||
echo "\
|
||||
$0 [OPTION]... PROGRAM [ARGUMENT]...
|
||||
|
||||
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
|
||||
to PROGRAM being missing or too old.
|
||||
|
||||
Options:
|
||||
-h, --help display this help and exit
|
||||
-v, --version output version information and exit
|
||||
|
||||
Supported PROGRAM values:
|
||||
aclocal autoconf autoheader autom4te automake makeinfo
|
||||
bison yacc flex lex help2man
|
||||
|
||||
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
|
||||
'g' are ignored when checking the name.
|
||||
|
||||
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
|
||||
|
||||
# Run the given program, remember its exit status.
|
||||
"$@"; st=$?
|
||||
|
||||
# If it succeeded, we are done.
|
||||
test $st -eq 0 && exit 0
|
||||
|
||||
# Also exit now if we it failed (or wasn't found), and '--version' was
|
||||
# passed; such an option is passed most likely to detect whether the
|
||||
# program is present and works.
|
||||
case $2 in --version|--help) exit $st;; esac
|
||||
|
||||
# Exit code 63 means version mismatch. This often happens when the user
|
||||
# tries to use an ancient version of a tool on a file that requires a
|
||||
# minimum version.
|
||||
if test $st -eq 63; then
|
||||
msg="probably too old"
|
||||
elif test $st -eq 127; then
|
||||
# Program was missing.
|
||||
msg="missing on your system"
|
||||
else
|
||||
# Program was found and executed, but failed. Give up.
|
||||
exit $st
|
||||
fi
|
||||
|
||||
perl_URL=http://www.perl.org/
|
||||
flex_URL=http://flex.sourceforge.net/
|
||||
gnu_software_URL=http://www.gnu.org/software
|
||||
|
||||
program_details ()
|
||||
{
|
||||
case $1 in
|
||||
aclocal|automake)
|
||||
echo "The '$1' program is part of the GNU Automake package:"
|
||||
echo "<$gnu_software_URL/automake>"
|
||||
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
|
||||
echo "<$gnu_software_URL/autoconf>"
|
||||
echo "<$gnu_software_URL/m4/>"
|
||||
echo "<$perl_URL>"
|
||||
;;
|
||||
autoconf|autom4te|autoheader)
|
||||
echo "The '$1' program is part of the GNU Autoconf package:"
|
||||
echo "<$gnu_software_URL/autoconf/>"
|
||||
echo "It also requires GNU m4 and Perl in order to run:"
|
||||
echo "<$gnu_software_URL/m4/>"
|
||||
echo "<$perl_URL>"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
give_advice ()
|
||||
{
|
||||
# Normalize program name to check for.
|
||||
normalized_program=`echo "$1" | sed '
|
||||
s/^gnu-//; t
|
||||
s/^gnu//; t
|
||||
s/^g//; t'`
|
||||
|
||||
printf '%s\n' "'$1' is $msg."
|
||||
|
||||
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
|
||||
case $normalized_program in
|
||||
autoconf*)
|
||||
echo "You should only need it if you modified 'configure.ac',"
|
||||
echo "or m4 files included by it."
|
||||
program_details 'autoconf'
|
||||
;;
|
||||
autoheader*)
|
||||
echo "You should only need it if you modified 'acconfig.h' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'autoheader'
|
||||
;;
|
||||
automake*)
|
||||
echo "You should only need it if you modified 'Makefile.am' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'automake'
|
||||
;;
|
||||
aclocal*)
|
||||
echo "You should only need it if you modified 'acinclude.m4' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'aclocal'
|
||||
;;
|
||||
autom4te*)
|
||||
echo "You might have modified some maintainer files that require"
|
||||
echo "the 'automa4te' program to be rebuilt."
|
||||
program_details 'autom4te'
|
||||
;;
|
||||
bison*|yacc*)
|
||||
echo "You should only need it if you modified a '.y' file."
|
||||
echo "You may want to install the GNU Bison package:"
|
||||
echo "<$gnu_software_URL/bison/>"
|
||||
;;
|
||||
lex*|flex*)
|
||||
echo "You should only need it if you modified a '.l' file."
|
||||
echo "You may want to install the Fast Lexical Analyzer package:"
|
||||
echo "<$flex_URL>"
|
||||
;;
|
||||
help2man*)
|
||||
echo "You should only need it if you modified a dependency" \
|
||||
"of a man page."
|
||||
echo "You may want to install the GNU Help2man package:"
|
||||
echo "<$gnu_software_URL/help2man/>"
|
||||
;;
|
||||
makeinfo*)
|
||||
echo "You should only need it if you modified a '.texi' file, or"
|
||||
echo "any other file indirectly affecting the aspect of the manual."
|
||||
echo "You might want to install the Texinfo package:"
|
||||
echo "<$gnu_software_URL/texinfo/>"
|
||||
echo "The spurious makeinfo call might also be the consequence of"
|
||||
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
|
||||
echo "want to install GNU make:"
|
||||
echo "<$gnu_software_URL/make/>"
|
||||
;;
|
||||
*)
|
||||
echo "You might have modified some files without having the proper"
|
||||
echo "tools for further handling them. Check the 'README' file, it"
|
||||
echo "often tells you about the needed prerequisites for installing"
|
||||
echo "this package. You may also peek at any GNU archive site, in"
|
||||
echo "case some other package contains this missing '$1' program."
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
give_advice "$1" | sed -e '1s/^/WARNING: /' \
|
||||
-e '2,$s/^/ /' >&2
|
||||
|
||||
# Propagate the correct exit status (expected to be 127 for a program
|
||||
# not found, 63 for a program that failed due to version mismatch).
|
||||
exit $st
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
@ -1,7 +1,7 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT([libfabric], [1.0.0rc5], [ofiwg@lists.openfabrics.org])
|
||||
AC_INIT([libfabric], [1.0.0rc6], [ofiwg@lists.openfabrics.org])
|
||||
AC_CONFIG_SRCDIR([src/fabric.c])
|
||||
AC_CONFIG_AUX_DIR(config)
|
||||
AC_CONFIG_MACRO_DIR(config)
|
||||
|
@ -37,6 +37,7 @@
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
@ -127,55 +128,128 @@ static inline uint64_t roundup_power_of_two(uint64_t n)
|
||||
|
||||
#if PT_LOCK_SPIN == 1
|
||||
|
||||
#define fastlock_t pthread_spinlock_t
|
||||
#define fastlock_init(lock) pthread_spin_init(lock, PTHREAD_PROCESS_PRIVATE)
|
||||
#define fastlock_destroy(lock) pthread_spin_destroy(lock)
|
||||
#define fastlock_acquire(lock) pthread_spin_lock(lock)
|
||||
#define fastlock_release(lock) pthread_spin_unlock(lock)
|
||||
#define fastlock_t_ pthread_spinlock_t
|
||||
#define fastlock_init_(lock) pthread_spin_init(lock, PTHREAD_PROCESS_PRIVATE)
|
||||
#define fastlock_destroy_(lock) pthread_spin_destroy(lock)
|
||||
#define fastlock_acquire_(lock) pthread_spin_lock(lock)
|
||||
#define fastlock_release_(lock) pthread_spin_unlock(lock)
|
||||
|
||||
#else
|
||||
|
||||
#define fastlock_t pthread_mutex_t
|
||||
#define fastlock_init(lock) pthread_mutex_init(lock, NULL)
|
||||
#define fastlock_destroy(lock) pthread_mutex_destroy(lock)
|
||||
#define fastlock_acquire(lock) pthread_mutex_lock(lock)
|
||||
#define fastlock_release(lock) pthread_mutex_unlock(lock)
|
||||
#define fastlock_t_ pthread_mutex_t
|
||||
#define fastlock_init_(lock) pthread_mutex_init(lock, NULL)
|
||||
#define fastlock_destroy_(lock) pthread_mutex_destroy(lock)
|
||||
#define fastlock_acquire_(lock) pthread_mutex_lock(lock)
|
||||
#define fastlock_release_(lock) pthread_mutex_unlock(lock)
|
||||
|
||||
#endif /* PT_LOCK_SPIN */
|
||||
|
||||
#if ENABLE_DEBUG
|
||||
|
||||
typedef struct {
|
||||
fastlock_t_ impl;
|
||||
int is_initialized;
|
||||
} fastlock_t;
|
||||
|
||||
# define fastlock_init(lock) \
|
||||
do { \
|
||||
(lock)->is_initialized = 1; \
|
||||
fastlock_init_(&(lock)->impl); \
|
||||
} while (0)
|
||||
|
||||
# define fastlock_destroy(lock) \
|
||||
do { \
|
||||
assert((lock)->is_initialized); \
|
||||
(lock)->is_initialized = 0; \
|
||||
fastlock_destroy_(&(lock)->impl); \
|
||||
} while (0)
|
||||
|
||||
static inline int fastlock_acquire(fastlock_t *lock)
|
||||
{
|
||||
assert(lock->is_initialized);
|
||||
return fastlock_acquire_(&lock->impl);
|
||||
}
|
||||
|
||||
# define fastlock_release(lock) \
|
||||
do { \
|
||||
assert((lock)->is_initialized); \
|
||||
fastlock_release_(&(lock)->impl); \
|
||||
} while (0)
|
||||
|
||||
#else /* !ENABLE_DEBUG */
|
||||
|
||||
# define fastlock_t fastlock_t_
|
||||
# define fastlock_init(lock) fastlock_init_(lock)
|
||||
# define fastlock_destroy(lock) fastlock_destroy_(lock)
|
||||
# define fastlock_acquire(lock) fastlock_acquire_(lock)
|
||||
# define fastlock_release(lock) fastlock_release_(lock)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if ENABLE_DEBUG
|
||||
#define ATOMIC_IS_INITIALIZED(atomic) assert(atomic->is_initialized)
|
||||
#else
|
||||
#define ATOMIC_IS_INITIALIZED(atomic)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ATOMICS
|
||||
typedef atomic_int atomic_t;
|
||||
typedef struct {
|
||||
atomic_int val;
|
||||
#if ENABLE_DEBUG
|
||||
int is_initialized;
|
||||
#endif
|
||||
} atomic_t;
|
||||
|
||||
static inline int atomic_inc(atomic_t *atomic)
|
||||
{
|
||||
return atomic_fetch_add_explicit(atomic, 1, memory_order_acq_rel) + 1;
|
||||
ATOMIC_IS_INITIALIZED(atomic);
|
||||
return atomic_fetch_add_explicit(&atomic->val, 1, memory_order_acq_rel) + 1;
|
||||
}
|
||||
|
||||
static inline int atomic_dec(atomic_t *atomic)
|
||||
{
|
||||
return atomic_fetch_sub_explicit(atomic, 1, memory_order_acq_rel) - 1;
|
||||
ATOMIC_IS_INITIALIZED(atomic);
|
||||
return atomic_fetch_sub_explicit(&atomic->val, 1, memory_order_acq_rel) - 1;
|
||||
}
|
||||
|
||||
static inline int atomic_set(atomic_t *atomic, int value)
|
||||
{
|
||||
atomic_store(atomic, value);
|
||||
ATOMIC_IS_INITIALIZED(atomic);
|
||||
atomic_store(&atomic->val, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline int atomic_get(atomic_t *atomic)
|
||||
{
|
||||
return atomic_load(atomic);
|
||||
ATOMIC_IS_INITIALIZED(atomic);
|
||||
return atomic_load(&atomic->val);
|
||||
}
|
||||
|
||||
/* avoid using "atomic_init" so we don't conflict with symbol/macro from stdatomic.h */
|
||||
static inline void atomic_initialize(atomic_t *atomic, int value)
|
||||
{
|
||||
atomic_init(&atomic->val, value);
|
||||
#if ENABLE_DEBUG
|
||||
atomic->is_initialized = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
typedef struct { fastlock_t lock; int val; } atomic_t;
|
||||
typedef struct {
|
||||
fastlock_t lock;
|
||||
int val;
|
||||
#if ENABLE_DEBUG
|
||||
int is_initialized;
|
||||
#endif
|
||||
} atomic_t;
|
||||
|
||||
static inline int atomic_inc(atomic_t *atomic)
|
||||
{
|
||||
int v;
|
||||
|
||||
ATOMIC_IS_INITIALIZED(atomic);
|
||||
fastlock_acquire(&atomic->lock);
|
||||
v = ++(atomic->val);
|
||||
fastlock_release(&atomic->lock);
|
||||
@ -186,6 +260,7 @@ static inline int atomic_dec(atomic_t *atomic)
|
||||
{
|
||||
int v;
|
||||
|
||||
ATOMIC_IS_INITIALIZED(atomic);
|
||||
fastlock_acquire(&atomic->lock);
|
||||
v = --(atomic->val);
|
||||
fastlock_release(&atomic->lock);
|
||||
@ -194,20 +269,26 @@ static inline int atomic_dec(atomic_t *atomic)
|
||||
|
||||
static inline int atomic_set(atomic_t *atomic, int value)
|
||||
{
|
||||
ATOMIC_IS_INITIALIZED(atomic);
|
||||
fastlock_acquire(&atomic->lock);
|
||||
atomic->val = value;
|
||||
fastlock_release(&atomic->lock);
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline void atomic_init(atomic_t *atomic, int value)
|
||||
/* avoid using "atomic_init" so we don't conflict with symbol/macro from stdatomic.h */
|
||||
static inline void atomic_initialize(atomic_t *atomic, int value)
|
||||
{
|
||||
fastlock_init(&atomic->lock);
|
||||
atomic->val = value;
|
||||
#if ENABLE_DEBUG
|
||||
atomic->is_initialized = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int atomic_get(atomic_t *atomic)
|
||||
{
|
||||
ATOMIC_IS_INITIALIZED(atomic);
|
||||
return atomic->val;
|
||||
}
|
||||
|
||||
@ -228,6 +309,7 @@ int fi_rma_initiate_allowed(uint64_t caps);
|
||||
int fi_rma_target_allowed(uint64_t caps);
|
||||
|
||||
uint64_t fi_gettime_ms(void);
|
||||
int fi_fd_nonblock(int fd);
|
||||
|
||||
#define RDMA_CONF_DIR SYSCONFDIR "/" RDMADIR
|
||||
#define FI_CONF_DIR RDMA_CONF_DIR "/fabric"
|
||||
|
@ -150,6 +150,7 @@ int fi_no_atomic_compwritevalid(struct fid_ep *ep,
|
||||
/*
|
||||
static struct fi_ops_cm X = {
|
||||
.size = sizeof(struct fi_ops_cm),
|
||||
.setname = fi_no_setname,
|
||||
.getname = fi_no_getname,
|
||||
.getpeer = fi_no_getpeer,
|
||||
.connect = fi_no_connect,
|
||||
@ -159,13 +160,14 @@ static struct fi_ops_cm X = {
|
||||
.shutdown = fi_no_shutdown,
|
||||
};
|
||||
*/
|
||||
int fi_no_setname(fid_t fid, void *addr, size_t addrlen);
|
||||
int fi_no_getname(fid_t fid, void *addr, size_t *addrlen);
|
||||
int fi_no_getpeer(struct fid_ep *ep, void *addr, size_t *addrlen);
|
||||
int fi_no_connect(struct fid_ep *ep, const void *addr,
|
||||
const void *param, size_t paramlen);
|
||||
int fi_no_listen(struct fid_pep *pep);
|
||||
int fi_no_accept(struct fid_ep *ep, const void *param, size_t paramlen);
|
||||
int fi_no_reject(struct fid_pep *pep, fi_connreq_t connreq,
|
||||
int fi_no_reject(struct fid_pep *pep, fid_t handle,
|
||||
const void *param, size_t paramlen);
|
||||
int fi_no_shutdown(struct fid_ep *ep, uint64_t flags);
|
||||
|
||||
|
@ -123,7 +123,7 @@ struct slist {
|
||||
|
||||
static inline void slist_init(struct slist *list)
|
||||
{
|
||||
list->head = NULL;
|
||||
list->head = list->tail = NULL;
|
||||
}
|
||||
|
||||
static inline int slist_empty(struct slist *list)
|
||||
@ -238,17 +238,18 @@ static inline int dlistfd_empty(struct dlistfd_head *head)
|
||||
|
||||
static inline void dlistfd_signal(struct dlistfd_head *head)
|
||||
{
|
||||
char c = 0;
|
||||
if (head->fdwcnt == head->fdrcnt) {
|
||||
if (write(head->fd[LIST_WRITE_FD], head, sizeof head) == sizeof head)
|
||||
if (write(head->fd[LIST_WRITE_FD], &c, sizeof c) == sizeof c)
|
||||
head->fdwcnt++;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void dlistfd_reset(struct dlistfd_head *head)
|
||||
{
|
||||
void *buf;
|
||||
char c;
|
||||
if (dlistfd_empty(head) && (head->fdrcnt < head->fdwcnt)) {
|
||||
if (read(head->fd[LIST_READ_FD], &buf, sizeof buf) == sizeof buf)
|
||||
if (read(head->fd[LIST_READ_FD], &c, sizeof c) == sizeof c)
|
||||
head->fdrcnt++;
|
||||
}
|
||||
}
|
||||
|
@ -138,6 +138,12 @@ static inline void rbread(struct ringbuf *rb, void *buf, size_t len)
|
||||
rb->rcnt += len;
|
||||
}
|
||||
|
||||
static inline size_t rbdiscard(struct ringbuf *rb, size_t len)
|
||||
{
|
||||
size_t used_len = MIN(rbused(rb), len);
|
||||
rb->rcnt += used_len;
|
||||
return used_len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ring buffer with blocking read support using an fd
|
||||
@ -212,18 +218,19 @@ static inline size_t rbfdavail(struct ringbuffd *rbfd)
|
||||
|
||||
static inline void rbfdsignal(struct ringbuffd *rbfd)
|
||||
{
|
||||
char c = 0;
|
||||
if (rbfd->fdwcnt == rbfd->fdrcnt) {
|
||||
if (write(rbfd->fd[RB_WRITE_FD], rbfd, sizeof rbfd) == sizeof rbfd)
|
||||
if (write(rbfd->fd[RB_WRITE_FD], &c, sizeof c) == sizeof c)
|
||||
rbfd->fdwcnt++;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void rbfdreset(struct ringbuffd *rbfd)
|
||||
{
|
||||
void *buf;
|
||||
char c;
|
||||
|
||||
if (rbfdempty(rbfd) && (rbfd->fdrcnt < rbfd->fdwcnt)) {
|
||||
if (read(rbfd->fd[RB_READ_FD], &buf, sizeof buf) == sizeof buf)
|
||||
if (read(rbfd->fd[RB_READ_FD], &c, sizeof c) == sizeof c)
|
||||
rbfd->fdrcnt++;
|
||||
}
|
||||
}
|
||||
|
@ -47,9 +47,6 @@ extern "C" {
|
||||
((type *) ((char *)ptr - offsetof(type, field)))
|
||||
#endif
|
||||
|
||||
#define FI_DEFINE_HANDLE(name) struct name##_s { int dummy; }; \
|
||||
typedef struct name##_s *name
|
||||
|
||||
enum {
|
||||
FI_MAJOR_VERSION = 1,
|
||||
FI_MINOR_VERSION = 0,
|
||||
@ -88,56 +85,47 @@ typedef struct fid *fid_t;
|
||||
*/
|
||||
#define FI_PROV_SPECIFIC (1 << 31)
|
||||
|
||||
/* fi_info and operation flags - pass into endpoint ops calls.
|
||||
* A user may also set these on a endpoint by using fcntl, which has the
|
||||
* affect of applying them to all applicable operations.
|
||||
/*
|
||||
* Flags
|
||||
* The 64-bit flag field is used as follows:
|
||||
* 1-grow up common (usable with multiple operations)
|
||||
* 59-grow down operation specific (used for single call/class)
|
||||
* 60 - 63 provider specific
|
||||
*/
|
||||
|
||||
/* FI capabilities */
|
||||
#define FI_MSG (1ULL << 1)
|
||||
#define FI_RMA (1ULL << 2)
|
||||
#define FI_TAGGED (1ULL << 3)
|
||||
#define FI_ATOMIC (1ULL << 4)
|
||||
#define FI_ATOMICS FI_ATOMIC
|
||||
#define FI_DYNAMIC_MR (1ULL << 7)
|
||||
#define FI_NAMED_RX_CTX (1ULL << 8)
|
||||
#define FI_DIRECTED_RECV (1ULL << 10)
|
||||
|
||||
/*
|
||||
* Flags
|
||||
* The 64-bit flag field is divided as follows:
|
||||
* bits use
|
||||
* 0 - 10 operation specific (used for a single call)
|
||||
* 11 - 32 common (usable with multiple operations)
|
||||
* 33 - 59 reserved
|
||||
* 60 - 63 provider specific
|
||||
*/
|
||||
|
||||
#define FI_INJECT (1ULL << 11)
|
||||
#define FI_MULTI_RECV (1ULL << 12)
|
||||
#define FI_SOURCE (1ULL << 13)
|
||||
#define FI_SYMMETRIC (1ULL << 14)
|
||||
|
||||
#define FI_READ (1ULL << 16)
|
||||
#define FI_WRITE (1ULL << 17)
|
||||
#define FI_RECV (1ULL << 18)
|
||||
#define FI_SEND (1ULL << 19)
|
||||
#define FI_READ (1ULL << 8)
|
||||
#define FI_WRITE (1ULL << 9)
|
||||
#define FI_RECV (1ULL << 10)
|
||||
#define FI_SEND (1ULL << 11)
|
||||
#define FI_TRANSMIT FI_SEND
|
||||
#define FI_REMOTE_READ (1ULL << 20)
|
||||
#define FI_REMOTE_WRITE (1ULL << 21)
|
||||
#define FI_REMOTE_READ (1ULL << 12)
|
||||
#define FI_REMOTE_WRITE (1ULL << 13)
|
||||
|
||||
#define FI_REMOTE_CQ_DATA (1ULL << 24)
|
||||
#define FI_CANCEL (1ULL << 25)
|
||||
#define FI_MORE (1ULL << 26)
|
||||
#define FI_PEEK (1ULL << 27)
|
||||
#define FI_TRIGGER (1ULL << 28)
|
||||
#define FI_FENCE (1ULL << 29)
|
||||
#define FI_MULTI_RECV (1ULL << 16)
|
||||
#define FI_REMOTE_CQ_DATA (1ULL << 17)
|
||||
#define FI_MORE (1ULL << 18)
|
||||
#define FI_PEEK (1ULL << 19)
|
||||
#define FI_TRIGGER (1ULL << 20)
|
||||
#define FI_FENCE (1ULL << 21)
|
||||
|
||||
#define FI_EVENT (1ULL << 32)
|
||||
#define FI_COMPLETION FI_EVENT
|
||||
#define FI_INJECT_COMPLETE (1ULL << 33)
|
||||
#define FI_TRANSMIT_COMPLETE (1ULL << 34)
|
||||
#define FI_COMMIT_COMPLETE (1ULL << 35)
|
||||
#define FI_COMPLETION (1ULL << 24)
|
||||
#define FI_EVENT FI_COMPLETION
|
||||
#define FI_INJECT (1ULL << 25)
|
||||
#define FI_INJECT_COMPLETE (1ULL << 26)
|
||||
#define FI_TRANSMIT_COMPLETE (1ULL << 27)
|
||||
#define FI_DELIVERY_COMPLETE (1ULL << 28)
|
||||
|
||||
/* fi_getinfo()-specific flags */
|
||||
#define FI_RMA_EVENT (1ULL << 56)
|
||||
#define FI_SOURCE (1ULL << 57)
|
||||
#define FI_NAMED_RX_CTX (1ULL << 58)
|
||||
#define FI_DIRECTED_RECV (1ULL << 59)
|
||||
|
||||
|
||||
struct fi_ioc {
|
||||
@ -161,7 +149,6 @@ enum {
|
||||
#define FI_ADDR_NOTAVAIL UINT64_MAX
|
||||
#define FI_SHARED_CONTEXT (-(size_t)1)
|
||||
typedef uint64_t fi_addr_t;
|
||||
FI_DEFINE_HANDLE(fi_connreq_t);
|
||||
|
||||
enum fi_av_type {
|
||||
FI_AV_UNSPEC,
|
||||
@ -169,6 +156,12 @@ enum fi_av_type {
|
||||
FI_AV_TABLE
|
||||
};
|
||||
|
||||
enum fi_mr_mode {
|
||||
FI_MR_UNSPEC,
|
||||
FI_MR_BASIC,
|
||||
FI_MR_SCALABLE
|
||||
};
|
||||
|
||||
enum fi_progress {
|
||||
FI_PROGRESS_UNSPEC,
|
||||
FI_PROGRESS_AUTO,
|
||||
@ -227,12 +220,11 @@ enum {
|
||||
};
|
||||
|
||||
/* Mode bits */
|
||||
#define FI_CONTEXT (1ULL << 0)
|
||||
#define FI_LOCAL_MR (1ULL << 1)
|
||||
#define FI_PROV_MR_ATTR (1ULL << 2)
|
||||
#define FI_MSG_PREFIX (1ULL << 3)
|
||||
#define FI_ASYNC_IOV (1ULL << 4)
|
||||
#define FI_RX_CQ_DATA (1ULL << 5)
|
||||
#define FI_CONTEXT (1ULL << 59)
|
||||
#define FI_MSG_PREFIX (1ULL << 58)
|
||||
#define FI_ASYNC_IOV (1ULL << 57)
|
||||
#define FI_RX_CQ_DATA (1ULL << 56)
|
||||
#define FI_LOCAL_MR (1ULL << 55)
|
||||
|
||||
struct fi_tx_attr {
|
||||
uint64_t caps;
|
||||
@ -279,6 +271,7 @@ struct fi_domain_attr {
|
||||
enum fi_progress data_progress;
|
||||
enum fi_resource_mgmt resource_mgmt;
|
||||
enum fi_av_type av_type;
|
||||
enum fi_mr_mode mr_mode;
|
||||
size_t mr_key_size;
|
||||
size_t cq_data_size;
|
||||
size_t cq_cnt;
|
||||
@ -287,6 +280,8 @@ struct fi_domain_attr {
|
||||
size_t rx_ctx_cnt;
|
||||
size_t max_ep_tx_ctx;
|
||||
size_t max_ep_rx_ctx;
|
||||
size_t max_ep_stx_ctx;
|
||||
size_t max_ep_srx_ctx;
|
||||
};
|
||||
|
||||
struct fi_fabric_attr {
|
||||
@ -305,7 +300,7 @@ struct fi_info {
|
||||
size_t dest_addrlen;
|
||||
void *src_addr;
|
||||
void *dest_addr;
|
||||
fi_connreq_t connreq;
|
||||
fid_t handle;
|
||||
struct fi_tx_attr *tx_attr;
|
||||
struct fi_rx_attr *rx_attr;
|
||||
struct fi_ep_attr *ep_attr;
|
||||
@ -331,12 +326,16 @@ enum {
|
||||
FI_CLASS_CQ,
|
||||
FI_CLASS_CNTR,
|
||||
FI_CLASS_WAIT,
|
||||
FI_CLASS_POLL
|
||||
FI_CLASS_POLL,
|
||||
FI_CLASS_CONNREQ
|
||||
};
|
||||
|
||||
struct fi_eq_attr;
|
||||
struct fi_wait_attr;
|
||||
|
||||
/* fi_bind()-specific flags */
|
||||
#define FI_SELECTIVE_COMPLETION (1ULL << 59)
|
||||
|
||||
struct fi_ops {
|
||||
size_t size;
|
||||
int (*close)(struct fid *fid);
|
||||
|
@ -43,13 +43,14 @@ extern "C" {
|
||||
|
||||
struct fi_ops_cm {
|
||||
size_t size;
|
||||
int (*setname)(fid_t fid, void *addr, size_t addrlen);
|
||||
int (*getname)(fid_t fid, void *addr, size_t *addrlen);
|
||||
int (*getpeer)(struct fid_ep *ep, void *addr, size_t *addrlen);
|
||||
int (*connect)(struct fid_ep *ep, const void *addr,
|
||||
const void *param, size_t paramlen);
|
||||
int (*listen)(struct fid_pep *pep);
|
||||
int (*accept)(struct fid_ep *ep, const void *param, size_t paramlen);
|
||||
int (*reject)(struct fid_pep *pep, fi_connreq_t connreq,
|
||||
int (*reject)(struct fid_pep *pep, fid_t handle,
|
||||
const void *param, size_t paramlen);
|
||||
int (*shutdown)(struct fid_ep *ep, uint64_t flags);
|
||||
};
|
||||
@ -57,6 +58,12 @@ struct fi_ops_cm {
|
||||
|
||||
#ifndef FABRIC_DIRECT
|
||||
|
||||
static inline int fi_setname(fid_t fid, void *addr, size_t addrlen)
|
||||
{
|
||||
struct fid_ep *ep = container_of(fid, struct fid_ep, fid);
|
||||
return ep->cm->setname(fid, addr, addrlen);
|
||||
}
|
||||
|
||||
static inline int fi_getname(fid_t fid, void *addr, size_t *addrlen)
|
||||
{
|
||||
struct fid_ep *ep = container_of(fid, struct fid_ep, fid);
|
||||
@ -87,10 +94,10 @@ fi_accept(struct fid_ep *ep, const void *param, size_t paramlen)
|
||||
}
|
||||
|
||||
static inline int
|
||||
fi_reject(struct fid_pep *pep, fi_connreq_t connreq,
|
||||
fi_reject(struct fid_pep *pep, fid_t handle,
|
||||
const void *param, size_t paramlen)
|
||||
{
|
||||
return pep->cm->reject(pep, connreq, param, paramlen);
|
||||
return pep->cm->reject(pep, handle, param, paramlen);
|
||||
}
|
||||
|
||||
static inline int fi_shutdown(struct fid_ep *ep, uint64_t flags)
|
||||
|
@ -47,6 +47,8 @@ extern "C" {
|
||||
* Maps and stores transport/network addresses.
|
||||
*/
|
||||
|
||||
#define FI_SYMMETRIC (1ULL << 59)
|
||||
|
||||
struct fi_av_attr {
|
||||
enum fi_av_type type;
|
||||
int rx_ctx_bits;
|
||||
@ -129,10 +131,6 @@ struct fi_ops_domain {
|
||||
};
|
||||
|
||||
|
||||
/* Memory registration flags */
|
||||
#define FI_MR_OFFSET (1ULL << 0)
|
||||
#define FI_MR_KEY (1ULL << 1)
|
||||
|
||||
struct fi_ops_mr {
|
||||
size_t size;
|
||||
int (*reg)(struct fid *fid, const void *buf, size_t len,
|
||||
@ -147,7 +145,7 @@ struct fi_ops_mr {
|
||||
};
|
||||
|
||||
/* Domain bind flags */
|
||||
#define FI_REG_MR (1ULL << 0)
|
||||
#define FI_REG_MR (1ULL << 59)
|
||||
|
||||
struct fid_domain {
|
||||
struct fid fid;
|
||||
|
@ -135,7 +135,7 @@ struct fi_eq_err_entry {
|
||||
uint64_t data;
|
||||
int err;
|
||||
int prov_errno;
|
||||
/* err_data is available until the next time the CQ is read */
|
||||
/* err_data is available until the next time the EQ is read */
|
||||
void *err_data;
|
||||
size_t err_data_size;
|
||||
};
|
||||
|
@ -41,8 +41,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define FI_CLAIM (1ULL << 0)
|
||||
#define FI_DISCARD FI_CANCEL
|
||||
#define FI_CLAIM (1ULL << 59)
|
||||
#define FI_DISCARD (1ULL << 58)
|
||||
|
||||
struct fi_msg_tagged {
|
||||
const struct iovec *msg_iov;
|
||||
@ -77,8 +77,6 @@ struct fi_ops_tagged {
|
||||
uint64_t data, fi_addr_t dest_addr, uint64_t tag, void *context);
|
||||
ssize_t (*injectdata)(struct fid_ep *ep, const void *buf, size_t len,
|
||||
uint64_t data, fi_addr_t dest_addr, uint64_t tag);
|
||||
ssize_t (*search)(struct fid_ep *ep, uint64_t *tag, uint64_t ignore,
|
||||
uint64_t flags, fi_addr_t *src_addr, size_t *len, void *context);
|
||||
};
|
||||
|
||||
|
||||
@ -149,14 +147,6 @@ fi_tinjectdata(struct fid_ep *ep, const void *buf, size_t len,
|
||||
return ep->tagged->injectdata(ep, buf, len, data, dest_addr, tag);
|
||||
}
|
||||
|
||||
static inline ssize_t
|
||||
fi_tsearch(struct fid_ep *ep, uint64_t *tag, uint64_t ignore, uint64_t flags,
|
||||
fi_addr_t *src_addr, size_t *len, void *context)
|
||||
{
|
||||
return ep->tagged->search(ep, tag, ignore, flags, src_addr,
|
||||
len, context);
|
||||
}
|
||||
|
||||
|
||||
#else // FABRIC_DIRECT
|
||||
#include <rdma/fi_direct_tagged.h>
|
||||
|
@ -1,5 +1,5 @@
|
||||
Name: libfabric
|
||||
Version: 1.0.0rc5
|
||||
Version: 1.0.0rc6
|
||||
Release: 1%{?dist}
|
||||
Summary: User-space RDMA Fabric Interfaces
|
||||
Group: System Environment/Libraries
|
||||
@ -61,5 +61,5 @@ rm -rf %{buildroot}
|
||||
%{_mandir}/man7/*
|
||||
|
||||
%changelog
|
||||
* Tue Apr 1 2015 Open Fabrics Interfaces Working Group <ofiwg@lists.openfabrics.org> 1.0.0
|
||||
- Release 1.0.0rc5
|
||||
* Fri Apr 24 2015 Open Fabrics Interfaces Working Group <ofiwg@lists.openfabrics.org> 1.0.0
|
||||
- Release 1.0.0rc6
|
||||
|
@ -61,5 +61,5 @@ rm -rf %{buildroot}
|
||||
%{_mandir}/man7/*
|
||||
|
||||
%changelog
|
||||
* Tue Apr 1 2015 Open Fabrics Interfaces Working Group <ofiwg@lists.openfabrics.org> 1.0.0
|
||||
- Release 1.0.0rc5
|
||||
* Fri Apr 24 2015 Open Fabrics Interfaces Working Group <ofiwg@lists.openfabrics.org> 1.0.0
|
||||
- Release 1.0.0rc6
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH fi_av 3 "2015\-03\-31" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_av 3 "2015\-04\-23" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
fi_av - Address vector operations
|
||||
@ -271,20 +271,24 @@ references during data transfer operations.
|
||||
.PP
|
||||
For AV\[aq]s of type FI_AV_TABLE, addresses are placed into the table in
|
||||
order.
|
||||
That is, the first address inserted may be referenced at index 0.
|
||||
The fi_addr parameter may be NULL in this case.
|
||||
Otherwise, fi_addr must reference an array of fi_addr_t, and the buffer
|
||||
must remain valid until the insertion operation completes.
|
||||
An address is inserted at the lowest index that corresponds to an unused
|
||||
table location, with indices starting at 0.
|
||||
That is, the first address inserted may be referenced at index 0, the
|
||||
second at index 1, and so forth.
|
||||
When addresses are inserted into an AV table, the assigned fi_addr
|
||||
values will be simple indices corresponding to the entry into the table
|
||||
where the address was inserted.
|
||||
Index values accumulate across successive insert calls in the order the
|
||||
calls are made, not necessarily in the order the insertions complete.
|
||||
.PP
|
||||
Because insertions occur at a pre-determined index, the fi_addr
|
||||
parameter may be NULL.
|
||||
If fi_addr is non-NULL, it must reference an array of fi_addr_t, and the
|
||||
buffer must remain valid until the insertion operation completes.
|
||||
Note that if fi_addr is NULL and synchronous operation is requested,
|
||||
individual insertion failures cannot be reported and the application
|
||||
must use other calls, such as \f[C]fi_av_lookup\f[] to learn which
|
||||
specific addresses failed to insert.
|
||||
When addresses are inserted into an AV of type FI_AV_TABLE, the assigned
|
||||
fi_addr values will be simple indices corresponding to the entry into
|
||||
the table where the address was inserted.
|
||||
Addresses are indexed in order of their insertion.
|
||||
Index values accumulate across successive insert calls in the order the
|
||||
calls are made, not necessarily in the order the insertions complete.
|
||||
.PP
|
||||
\f[I]flags\f[] : The following flag may be passed to fi_av_insert
|
||||
.IP \[bu] 2
|
||||
@ -325,7 +329,7 @@ numeric suffix if nodecnt > 1.
|
||||
.PP
|
||||
As an example, if node = "10.1.1.1", nodecnt = 2, service = "5000", and
|
||||
svccnt = 2, the following addresses will be inserted into the AV in the
|
||||
order shown: 10.1.1.1:5000, 10.1.1.1:5001, 10.1.1.2:5000, 10.1.1.1:5001.
|
||||
order shown: 10.1.1.1:5000, 10.1.1.1:5001, 10.1.1.2:5000, 10.1.1.2:5001.
|
||||
If node were replaced by the hostname "host10", the addresses would be:
|
||||
host10:5000, host10:5001, host11:5000, host11:5001.
|
||||
.PP
|
||||
@ -388,12 +392,18 @@ been specified.
|
||||
Similarly, a provider may lazily release resources from removed entries.
|
||||
.SH RETURN VALUES
|
||||
.PP
|
||||
The insert calls return the number of addresses successfully inserted or
|
||||
the number of asynchronous insertions initiated if FI_EVENT is set.
|
||||
Insertion calls for an AV opened for synchronous operation will return
|
||||
the number of addresses that were successfully inserted.
|
||||
In the case of failure, the return value will be less than the number of
|
||||
addresses that were specified.
|
||||
.PP
|
||||
Other calls return 0 on success.
|
||||
Insertion calls for an AV opened for asynchronous operation (with
|
||||
FI_EVENT flag specified) will return 0 if the operation was successfully
|
||||
initiated.
|
||||
In the case of failure, a negative fabric errno will be returned.
|
||||
.PP
|
||||
On error, a negative value corresponding to fabric errno is returned.
|
||||
All other calls return 0 on success, or a negative value corresponding
|
||||
to fabric errno on error.
|
||||
Fabric errno values are defined in \f[C]rdma/fi_errno.h\f[].
|
||||
.SH ERRORS
|
||||
.SH SEE ALSO
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH fi_cm 3 "2015\-02\-26" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_cm 3 "2015\-04\-23" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
fi_cm - Connection management operations
|
||||
@ -6,7 +6,8 @@ fi_cm - Connection management operations
|
||||
fi_connect / fi_listen / fi_accept / fi_reject / fi_shutdown : Manage
|
||||
endpoint connection state.
|
||||
.PP
|
||||
fi_getname / fi_getpeer : Return local or peer endpoint address
|
||||
fi_setname / fi_getname / fi_getpeer : Set local, or return local or
|
||||
peer endpoint address.
|
||||
.SH SYNOPSIS
|
||||
.IP
|
||||
.nf
|
||||
@ -20,11 +21,13 @@ int\ fi_listen(struct\ fid_pep\ *pep);
|
||||
|
||||
int\ fi_accept(struct\ fid_ep\ *ep,\ const\ void\ *param,\ size_t\ paramlen);
|
||||
|
||||
int\ fi_reject(struct\ fid_pep\ *pep,\ fi_connreq_t\ connreq,
|
||||
int\ fi_reject(struct\ fid_pep\ *pep,\ fid_t\ handle,
|
||||
\ \ \ \ const\ void\ *param,\ size_t\ paramlen);
|
||||
|
||||
int\ fi_shutdown(struct\ fid_ep\ *ep,\ uint64_t\ flags);
|
||||
|
||||
int\ fi_setname(fid_t\ fid,\ void\ *addr,\ size_t\ addrlen);
|
||||
|
||||
int\ fi_getname(fid_t\ fid,\ void\ *addr,\ size_t\ *addrlen);
|
||||
|
||||
int\ fi_getpeer(struct\ fid_ep\ *ep,\ void\ *addr,\ size_t\ *addrlen);
|
||||
@ -34,8 +37,11 @@ int\ fi_getpeer(struct\ fid_ep\ *ep,\ void\ *addr,\ size_t\ *addrlen);
|
||||
.PP
|
||||
\f[I]ep / pep\f[] : Fabric endpoint on which to change connection state.
|
||||
.PP
|
||||
\f[I]addr\f[] : Buffer to store queried address (get), or address to
|
||||
connect.
|
||||
\f[I]addr\f[] : Buffer to address.
|
||||
On a set call, the endpoint will be assigned the specified address.
|
||||
On a get, the local address will be copied into the buffer, up to the
|
||||
space provided.
|
||||
For connect, this parameter indicates the peer address to connect to.
|
||||
The address must be in the same format as that specified using fi_info:
|
||||
addr_format when the endpoint was created.
|
||||
.PP
|
||||
@ -82,7 +88,7 @@ connection request event (FI_CONNREQ).
|
||||
After receiving such an event, the application allocates a new endpoint
|
||||
to accept the connection.
|
||||
This endpoint must be allocated using an fi_info structure referencing
|
||||
the connreq from this FI_CONNREQ event.
|
||||
the handle from this FI_CONNREQ event.
|
||||
fi_accept is then invoked with the newly allocated endpoint.
|
||||
If the listening application wishes to reject a connection request, it
|
||||
calls fi_reject with the listening endpoint and a reference to the
|
||||
@ -132,6 +138,28 @@ Note that in the abrupt close case, an FI_SHUTDOWN event will only be
|
||||
generated if the peer system is reachable and a service or kernel agent
|
||||
on the peer system is able to notify the local endpoint that the
|
||||
connection has been aborted.
|
||||
.SS fi_setname
|
||||
.PP
|
||||
The fi_setname call may be used to modify or assign the address of the
|
||||
local endpoint.
|
||||
It is conceptually similar to the socket bind operation.
|
||||
An endpoint may be assigned an address on its creation, through the
|
||||
fi_info structure.
|
||||
The fi_setname call allows an endpoint to be created without being
|
||||
associated with a specific service (i.e.
|
||||
port number) and/or node (i.e.
|
||||
network) address, with the addressing assigned dynamically.
|
||||
The format of the specified addressing data must match that specified
|
||||
through the fi_info structure when the endpoint was created.
|
||||
.PP
|
||||
If no service address is specified and a service address has not yet
|
||||
been assigned to the endpoint, then the provider will allocate a service
|
||||
address and assign it to the endpoint.
|
||||
If a node or service address is specified, then, upon successful
|
||||
completion of fi_setname, the endpoint will be assigned the given
|
||||
addressing.
|
||||
If an address cannot be assigned, or the endpoint address cannot be
|
||||
modified, an appropriate fabric error number is returned.
|
||||
.SS fi_getname / fi_getpeer
|
||||
.PP
|
||||
The fi_getname and fi_getpeer calls may be used to retrieve the local or
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH fi_cntr 3 "2015\-01\-29" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_cntr 3 "2015\-01\-29" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
fi_cntr - Completion and event counter operations
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH fi_control 3 "2015\-02\-16" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_control 3 "2015\-02\-16" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
fi_control - Perform an operation on a fabric resource.
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH fi_cq 3 "2015\-03\-31" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_cq 3 "2015\-04\-03" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
fi_cq - Completion queue operations
|
||||
@ -368,8 +368,8 @@ Users may call fi_cq_strerror to convert provider specific error
|
||||
information into a printable string for debugging purposes.
|
||||
.SS fi_cq_signal
|
||||
.PP
|
||||
The fi_cq_signal call will signal the wait object used by the
|
||||
fi_cq_sread and fi_cq_sreadfrom function.
|
||||
The fi_cq_signal call will unblock any thread waiting in fi_cq_sread or
|
||||
fi_cq_sreadfrom.
|
||||
This may be used to wake-up a thread that is blocked waiting to read a
|
||||
completion operation.
|
||||
The fi_cq_signal operation is only available if the CQ was configured
|
||||
@ -380,44 +380,47 @@ Completion flags provide additional details regarding the completed
|
||||
operation.
|
||||
The following completion flags are defined.
|
||||
.PP
|
||||
*FI_SEND : Indicates that the completion was for a send operation.
|
||||
\f[I]FI_SEND\f[] : Indicates that the completion was for a send
|
||||
operation.
|
||||
This flag may be combined with an FI_MSG or FI_TAGGED flag.
|
||||
.PP
|
||||
*FI_RECV : Indicates that the completion was for a receive operation.
|
||||
\f[I]FI_RECV\f[] : Indicates that the completion was for a receive
|
||||
operation.
|
||||
This flag may be combined with an FI_MSG or FI_TAGGED flag.
|
||||
.PP
|
||||
*FI_RMA : Indicates that an RMA operation completed.
|
||||
\f[I]FI_RMA\f[] : Indicates that an RMA operation completed.
|
||||
This flag may be combined with an FI_READ, FI_WRITE, FI_REMOTE_READ, or
|
||||
FI_REMOTE_WRITE flag.
|
||||
.PP
|
||||
*FI_ATOMIC : Indicates that an atomic operation completed.
|
||||
\f[I]FI_ATOMIC\f[] : Indicates that an atomic operation completed.
|
||||
This flag may be combined with an FI_READ, FI_WRITE, FI_REMOTE_READ, or
|
||||
FI_REMOTE_WRITE flag.
|
||||
.PP
|
||||
*FI_MSG : Indicates that a message-based operation completed.
|
||||
\f[I]FI_MSG\f[] : Indicates that a message-based operation completed.
|
||||
This flag may be combined with an FI_SEND or FI_RECV flag.
|
||||
.PP
|
||||
*FI_TAGGED : Indicates that a tagged message operation completed.
|
||||
\f[I]FI_TAGGED\f[] : Indicates that a tagged message operation
|
||||
completed.
|
||||
This flag may be combined with an FI_SEND or FI_RECV flag.
|
||||
.PP
|
||||
*FI_READ : Indicates that a locally initiated RMA or atomic read
|
||||
\f[I]FI_READ\f[] : Indicates that a locally initiated RMA or atomic read
|
||||
operation has completed.
|
||||
This flag may be combined with an FI_RMA or FI_ATOMIC flag.
|
||||
.PP
|
||||
*FI_WRITE : Indicates that a locally initiated RMA or atomic write
|
||||
operation has completed.
|
||||
\f[I]FI_WRITE\f[] : Indicates that a locally initiated RMA or atomic
|
||||
write operation has completed.
|
||||
This flag may be combined with an FI_RMA or FI_ATOMIC flag.
|
||||
.PP
|
||||
*FI_REMOTE_READ : Indicates that a remotely initiated RMA or atomic read
|
||||
operation has completed.
|
||||
\f[I]FI_REMOTE_READ\f[] : Indicates that a remotely initiated RMA or
|
||||
atomic read operation has completed.
|
||||
This flag may be combined with an FI_RMA or FI_ATOMIC flag.
|
||||
.PP
|
||||
*FI_REMOTE_WRITE : Indicates that a remotely initiated RMA or atomic
|
||||
read operation has completed.
|
||||
\f[I]FI_REMOTE_WRITE\f[] : Indicates that a remotely initiated RMA or
|
||||
atomic read operation has completed.
|
||||
This flag may be combined with an FI_RMA or FI_ATOMIC flag.
|
||||
.PP
|
||||
*FI_REMOTE_CQ_DATA : This indicates that remote CQ data is available as
|
||||
part of the completion.
|
||||
\f[I]FI_REMOTE_CQ_DATA\f[] : This indicates that remote CQ data is
|
||||
available as part of the completion.
|
||||
.PP
|
||||
\f[I]FI_MULTI_RECV\f[] : This flag applies to receive buffers that were
|
||||
posted with the FI_MULTI_RECV flag set.
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH fi_domain 3 "2015\-03\-24" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_domain 3 "2015\-04\-23" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
fi_domain - Open a fabric access domain
|
||||
@ -102,6 +102,7 @@ struct\ fi_domain_attr\ {
|
||||
\ \ \ \ enum\ fi_progress\ \ \ \ \ \ data_progress;
|
||||
\ \ \ \ enum\ fi_resource_mgmt\ resource_mgmt;
|
||||
\ \ \ \ enum\ fi_av_type\ \ \ \ \ \ \ av_type;
|
||||
\ \ \ \ enum\ fi_mr_mode\ \ \ \ \ \ \ mr_mode;
|
||||
\ \ \ \ size_t\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ mr_key_size;
|
||||
\ \ \ \ size_t\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ cq_data_size;
|
||||
\ \ \ \ size_t\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ cq_cnt;
|
||||
@ -110,6 +111,8 @@ struct\ fi_domain_attr\ {
|
||||
\ \ \ \ size_t\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ rx_ctx_cnt;
|
||||
\ \ \ \ size_t\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ max_ep_tx_ctx;
|
||||
\ \ \ \ size_t\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ max_ep_rx_ctx;
|
||||
\ \ \ \ size_t\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ max_ep_stx_ctx;
|
||||
\ \ \ \ size_t\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ max_ep_srx_ctx;
|
||||
};
|
||||
\f[]
|
||||
.fi
|
||||
@ -389,6 +392,31 @@ support either address vector format.
|
||||
In this case, a provider may return FI_AV_UNSPEC to indicate that either
|
||||
format is supportable, or may return another AV type to indicate the
|
||||
optimal AV type supported by this domain.
|
||||
.SS Memory Registration Mode (mr_mode)
|
||||
.PP
|
||||
Specifies the method of memory registration that is used with this
|
||||
domain.
|
||||
For additional details on MR mode, see \f[C]fi_mr\f[](3).
|
||||
The following values may be specified.
|
||||
.PP
|
||||
\f[I]FI_MR_UNSPEC\f[] : Any memory registration mode is requested and
|
||||
supported.
|
||||
.PP
|
||||
\f[I]FI_MR_BASIC\f[] : Only basic memory registration operations are
|
||||
requested or supported.
|
||||
.PP
|
||||
\f[I]FI_MR_SCALABLE\f[] : Only scalable memory registration operations
|
||||
are requested or supported.
|
||||
.PP
|
||||
Buffers used in data transfer operations may require notifying the
|
||||
provider of their use before a data transfer can occur.
|
||||
The mr_mode field indicates the type of memory registration that is
|
||||
required, and when registration is necessary.
|
||||
Applications that require the use of a specific registration mode should
|
||||
set the domain attribute mr_mode to the necessary value when calling
|
||||
fi_getinfo.
|
||||
The value FI_MR_UNSPEC may be used to indicate support for any
|
||||
registration mode.
|
||||
.SS MR Key Size (mr_key_size)
|
||||
.PP
|
||||
Size of the memory region remote access key, in bytes.
|
||||
@ -407,8 +435,8 @@ If supported (non-zero value is returned), the minimum size of remote CQ
|
||||
data must be at least 4-bytes.
|
||||
.SS Completion Queue Count (cq_cnt)
|
||||
.PP
|
||||
The total number of completion queues supported by the domain, relative
|
||||
to any specified or default CQ attributes.
|
||||
The optimal number of completion queues supported by the domain,
|
||||
relative to any specified or default CQ attributes.
|
||||
The cq_cnt value may be a fixed value of the maximum number of CQs
|
||||
supported by the underlying provider, or may be a dynamic value, based
|
||||
on the default attributes of an allocated CQ, such as the CQ size and
|
||||
@ -454,6 +482,14 @@ endpoint.
|
||||
.PP
|
||||
The maximum number of receive contexts that may be associated with an
|
||||
endpoint.
|
||||
.SS Maximum Sharing of Transmit Context (max_ep_stx_ctx)
|
||||
.PP
|
||||
The maximum number of endpoints that may be associated with a shared
|
||||
transmit context.
|
||||
.SS Maximum Sharing of Receive Context (max_ep_srx_ctx)
|
||||
.PP
|
||||
The maximum number of endpoints that may be associated with a shared
|
||||
receive context.
|
||||
.SH RETURN VALUE
|
||||
.PP
|
||||
Returns 0 on success.
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH fi_endpoint 3 "2015\-03\-31" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_endpoint 3 "2015\-04\-24" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
fi_endpoint - Fabric endpoint operations
|
||||
@ -124,6 +124,7 @@ ssize_t\ fi_tx_size_left(struct\ fid_ep\ *ep);
|
||||
\f[I]fid\f[] : On creation, specifies a fabric or access domain.
|
||||
On bind, identifies the event queue, completion queue or address vector
|
||||
to bind to the endpoint.
|
||||
In other cases, it\[aq]s a fabric identifier of an associated resource.
|
||||
.PP
|
||||
\f[I]info\f[] : Details about the fabric interface endpoint to be
|
||||
opened, obtained from fi_getinfo.
|
||||
@ -134,16 +135,18 @@ opened, obtained from fi_getinfo.
|
||||
.PP
|
||||
\f[I]pep\f[] : A passive fabric endpoint.
|
||||
.PP
|
||||
\f[I]fid\f[] : Fabric identifier of an associated resource.
|
||||
.PP
|
||||
\f[I]context\f[] : Context associated with the endpoint or asynchronous
|
||||
operation.
|
||||
.PP
|
||||
\f[I]index\f[] : Index to retrieve a specific transmit/receive context.
|
||||
.PP
|
||||
\f[I]attr\f[] : Transmit or receive context attributes.
|
||||
.PP
|
||||
\f[I]flags\f[] : Additional flags to apply to the operation.
|
||||
.PP
|
||||
\f[I]command\f[] : Command of control operation to perform on endpoint.
|
||||
.PP
|
||||
\f[I]arg\f[] : Optional control argument
|
||||
\f[I]arg\f[] : Optional control argument.
|
||||
.PP
|
||||
\f[I]level\f[] : Protocol level at which the desired option resides.
|
||||
.PP
|
||||
@ -156,8 +159,10 @@ operation.
|
||||
.PP
|
||||
Endpoints are transport level communication portals.
|
||||
There are two types of endpoints: active and passive.
|
||||
Passive endpoints belong to a fabric domain and are used to listen for
|
||||
incoming connection requests.
|
||||
Passive endpoints belong to a fabric domain and are most often used to
|
||||
listen for incoming connection requests.
|
||||
However, a passive endpoint may be used to reserve a fabric address that
|
||||
can be granted to an active endpoint.
|
||||
Active endpoints belong to access domains and can perform data
|
||||
transfers.
|
||||
.PP
|
||||
@ -212,8 +217,17 @@ fi_info flags that control the operation of an endpoint are defined
|
||||
below.
|
||||
See section SCALABLE ENDPOINTS.
|
||||
.PP
|
||||
If an active endpoint is associated with a connection request, the
|
||||
fi_info connreq must reference the corresponding request.
|
||||
If an active endpoint is allocated in order to accept a connection
|
||||
request, the fi_info parameter must be the same as the fi_info structure
|
||||
provided with the connection request (FI_CONNREQ) event.
|
||||
.PP
|
||||
An active endpoint may acquire the properties of a passive endpoint by
|
||||
setting the fi_info handle field to the passive endpoint fabric
|
||||
descriptor.
|
||||
This is useful for applications that need to reserve the fabric address
|
||||
of an endpoint prior to knowing if the endpoint will be used on the
|
||||
active or passive side of a connection.
|
||||
For example, this feature is useful for simulating socket semantics.
|
||||
.SS fi_close
|
||||
.PP
|
||||
Closes an endpoint and release all resources associated with it.
|
||||
@ -258,19 +272,20 @@ The FI_SEND flag may be used interchangeably.
|
||||
the specified completion queue.
|
||||
This includes received messages.
|
||||
.PP
|
||||
\f[I]FI_COMPLETION\f[] : By default, data transfer operations generate
|
||||
completion entries into a completion queue after they have successfully
|
||||
completed.
|
||||
\f[I]FI_SELECTIVE_COMPLETION\f[] : By default, data transfer operations
|
||||
generate completion entries into a completion queue after they have
|
||||
successfully completed.
|
||||
Applications can use this bind flag to selectively enable when
|
||||
completions are generated.
|
||||
If FI_COMPLETION is specified, data transfer operations will not
|
||||
generate entries for successful completions unless FI_COMPLETION is set
|
||||
as an operational flag for the given operation.
|
||||
FI_COMPLETION must be OR\[aq]ed with FI_SEND and/or FI_RECV flags.
|
||||
If FI_SELECTIVE_COMPLETION is specified, data transfer operations will
|
||||
not generate entries for successful completions unless FI_COMPLETION is
|
||||
set as an operational flag for the given operation.
|
||||
FI_SELECTIVE_COMPLETION must be OR\[aq]ed with FI_SEND and/or FI_RECV
|
||||
flags.
|
||||
.PP
|
||||
When set the user must determine when a request that does NOT have
|
||||
FI_COMPLETION set has completed indirectly, usually based on the
|
||||
completion of a subsequent operation.
|
||||
When FI_SELECTIVE_COMPLETION is set, the user must determine when a
|
||||
request that does NOT have FI_COMPLETION set has completed indirectly,
|
||||
usually based on the completion of a subsequent operation.
|
||||
Use of this flag may improve performance by allowing the provider to
|
||||
avoid writing a completion entry for every operation.
|
||||
.PP
|
||||
@ -280,10 +295,11 @@ using the following general approach:
|
||||
.nf
|
||||
\f[C]
|
||||
\ \ fi_tx_attr::op_flags\ =\ 0;\ //\ default\ -\ no\ completion
|
||||
\ \ fi_ep_bind(ep,\ cq,\ FI_SEND\ |\ FI_COMPLETION);
|
||||
\ \ fi_ep_bind(ep,\ cq,\ FI_SEND\ |\ FI_SELECTIVE_COMPLETION);
|
||||
\ \ fi_send(ep,\ ...);\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ //\ no\ completion
|
||||
\ \ fi_sendv(ep,\ ...);\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ //\ no\ completion
|
||||
\ \ fi_sendmsg(ep,\ ...,\ FI_COMPLETION);\ //\ completion!
|
||||
\ \ fi_inject(ep,\ ...);\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ //\ no\ completion
|
||||
\f[]
|
||||
.fi
|
||||
.PP
|
||||
@ -293,10 +309,27 @@ modifying the operational flags:
|
||||
.nf
|
||||
\f[C]
|
||||
\ \ fi_tx_attr::op_flags\ =\ FI_COMPLETION;\ //\ default\ -\ completion
|
||||
\ \ fi_ep_bind(ep,\ cq,\ FI_SEND\ |\ FI_COMPLETION);
|
||||
\ \ fi_ep_bind(ep,\ cq,\ FI_SEND\ |\ FI_SELECTIVE_COMPLETION);
|
||||
\ \ fi_send(ep,\ ...);\ \ \ \ \ \ \ //\ completion
|
||||
\ \ fi_sendv(ep,\ ...);\ \ \ \ \ \ //\ completion
|
||||
\ \ fi_sendmsg(ep,\ ...,\ 0);\ //\ no\ completion!
|
||||
\ \ fi_inject(ep,\ ...);\ \ \ \ \ //\ no\ completion!
|
||||
\f[]
|
||||
.fi
|
||||
.PP
|
||||
Example: Omitting FI_SELECTIVE_COMPLETION when binding will generate
|
||||
completions for all non-fi_inject calls:
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
\ \ fi_tx_attr::op_flags\ =\ 0;
|
||||
\ \ fi_ep_bind(ep,\ cq,\ FI_SEND);\ \ //\ default\ -\ completion
|
||||
\ \ fi_send(ep,\ ...);\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ //\ completion
|
||||
\ \ fi_sendv(ep,\ ...);\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ //\ completion
|
||||
\ \ fi_sendmsg(ep,\ ...,\ 0);\ \ \ \ \ \ \ \ \ \ \ \ \ //\ completion!
|
||||
\ \ fi_sendmsg(ep,\ ...,\ FI_COMPLETION);\ //\ completion
|
||||
\ \ fi_sendmsg(ep,\ ...,\ FI_INJECT|FI_COMPLETION);\ //\ completion!
|
||||
\ \ fi_inject(ep,\ ...);\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ //\ no\ completion!
|
||||
\f[]
|
||||
.fi
|
||||
.PP
|
||||
@ -322,10 +355,14 @@ successful RMA write or atomic operation is initiated from the endpoint.
|
||||
\f[I]FI_REMOTE_READ\f[] : Increments the specified counter whenever a
|
||||
successful RMA read or atomic fetch operation is initiated from a remote
|
||||
endpoint that targets the given endpoint.
|
||||
Use of this flag requires that the endpoint be created using
|
||||
FI_RMA_EVENT.
|
||||
.PP
|
||||
\f[I]FI_REMOTE_WRITE\f[] : Increments the specified counter whenever a
|
||||
successful RMA write or atomic operation is initiated from a remote
|
||||
endpoint that targets the given endpoint.
|
||||
Use of this flag requires that the endpoint be created using
|
||||
FI_RMA_EVENT.
|
||||
.PP
|
||||
Connectionless endpoints must be bound to a single address vector.
|
||||
If an endpoint is using a shared transmit and/or receive context, the
|
||||
@ -353,11 +390,12 @@ assigned to it.
|
||||
.PP
|
||||
Calling connect or accept on an endpoint will implicitly enable an
|
||||
endpoint if it has not already been enabled.
|
||||
.PP
|
||||
Fi_enable may also be used to re-enable an endpoint that has been
|
||||
disabled as a result of experiencing an asynchronous error.
|
||||
.SS fi_cancel
|
||||
.PP
|
||||
fi_cancel attempts to cancel an outstanding asynchronous operation.
|
||||
The endpoint must have been configured to support cancelable operations
|
||||
-- see FI_CANCEL flag -- in order for this call to succeed.
|
||||
Canceling an operation causes the fabric provider to search for the
|
||||
operation and, if it is still pending, complete it as having been
|
||||
canceled.
|
||||
@ -1108,30 +1146,46 @@ generated for data transfer operations.
|
||||
.PP
|
||||
\f[I]FI_INJECT_COMPLETE\f[] : Indicates that a completion should be
|
||||
generated when the source buffer(s) may be reused.
|
||||
FI_INJECT_COMPLETE allows for the provider to complete an operation
|
||||
after all source data has been cached, and while the operation may still
|
||||
be in the process of being transmitted.
|
||||
A completion guarantees that the buffers will not be read from again and
|
||||
the application may reclaim them.
|
||||
No other guarantees are made with respect to the state of the operation.
|
||||
.PP
|
||||
\f[I]FI_TRANSMIT_COMPLETE\f[] : Indicates that a completion should not
|
||||
be generated until an operation has been successfully transmitted and is
|
||||
no longer being tracked by the provider.
|
||||
For reliable endpoints, this flag generally indicates that an operation
|
||||
will not complete until it has been accepted into the fabric and
|
||||
acknowledged by a remote service.
|
||||
For unreliable endpoints, this flag indicates that an operation will not
|
||||
complete until it has been successfully delivered into the fabric.
|
||||
For example, the corresponding message has been placed on the wire.
|
||||
FI_TRANSMIT_COMPLETE is the default completion model for all endpoints.
|
||||
Note: This flag is used to control when a completion entry is inserted
|
||||
into a completion queue.
|
||||
It does not apply to operations that do not generate a completion queue
|
||||
entry, such as the fi_inject operation.
|
||||
.PP
|
||||
Note that when set, if the target endpoint experiences an error
|
||||
receiving the transferred data, that error will often be reported back
|
||||
to the initiator of the request.
|
||||
This includes errors which may not normally be reported to the
|
||||
initiator, such as remote buffer overruns.
|
||||
\f[I]FI_TRANSMIT_COMPLETE\f[] : Indicates that a completion should be
|
||||
generated when the transmit operation has completed relative to the
|
||||
local provider.
|
||||
The exact behavior is dependent on the endpoint type.
|
||||
.PP
|
||||
\f[I]FI_COMMIT_COMPLETE\f[] : Indicates that a completion should not be
|
||||
generated until an operation has successfully been processed at the
|
||||
target, with the data placed into the specified destination buffer.
|
||||
For reliable endpoints:
|
||||
.PP
|
||||
Indicates that a completion should be generated when the operation has
|
||||
been delivered to the peer endpoint.
|
||||
A completion guarantees that the operation is no longer dependent on the
|
||||
fabric or local resources.
|
||||
The state of the operation at the peer endpoint is not defined.
|
||||
.PP
|
||||
For unreliable endpoints:
|
||||
.PP
|
||||
Indicates that a completion should be generated when the operation has
|
||||
been delivered to the fabric.
|
||||
A completion guarantees that the operation is no longer dependent on
|
||||
local resources.
|
||||
The state of the operation within the fabric is not defined.
|
||||
.PP
|
||||
\f[I]FI_DELIVERY_COMPLETE\f[] : Indicates that a completion should not
|
||||
be generated until an operation has been processed by the destination
|
||||
endpoint(s).
|
||||
A completion guarantees that the result of the operation is available.
|
||||
.PP
|
||||
This completion mode applies only to reliable endpoints.
|
||||
For operations that return data to the initiator, such as RMA read or
|
||||
atomic-fetch, the source endpoint is also considered a destination
|
||||
endpoint.
|
||||
This is the default completion mode for such operations.
|
||||
.SH NOTES
|
||||
.PP
|
||||
Users should call fi_close to release all resources allocated to the
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH fi_eq 3 "2015\-03\-24" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_eq 3 "2015\-04\-13" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
fi_eq - Event queue operations
|
||||
@ -306,6 +306,29 @@ is done through the FI_SHUTDOWN event.
|
||||
Shutdown notification uses struct fi_eq_cm_entry as declared above.
|
||||
The fid field for a shutdown notification refers to the active
|
||||
endpoint\[aq]s fid_ep.
|
||||
.PP
|
||||
\f[I]Asynchronous Error Notification\f[] : Asynchronous errors are used
|
||||
to report problems with fabric resources.
|
||||
Reported errors may be fatal or transient, based on the error, and
|
||||
result in the resource becoming disabled.
|
||||
Disabled resources will fail operations submitted against them until
|
||||
they are explicitly re-enabled by the application.
|
||||
.PP
|
||||
Asynchronous errors may be reported for completion queues and endpoints
|
||||
of all types.
|
||||
CQ errors can result when resource management has been disabled, and the
|
||||
provider has detected a queue overrun.
|
||||
Endpoint errors may be result of numerous actions, but are often
|
||||
associated with a failed operation.
|
||||
Operations may fail because of buffer overruns, invalid permissions,
|
||||
incorrect memory access keys, network routing failures, network
|
||||
reachability issues, etc.
|
||||
.PP
|
||||
Asynchronous errors are reported using struct fi_eq_err_entry, as
|
||||
defined below.
|
||||
The fabric descriptor (fid) associated with the error is provided as
|
||||
part of the error data.
|
||||
An error code is also available to determine the cause of the error.
|
||||
.SS fi_eq_sread
|
||||
.PP
|
||||
The fi_eq_sread call is the blocking (or synchronous) equivalent to
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH fi_errno 3 "2015\-01\-08" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_errno 3 "2015\-01\-08" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
fi_errno - fabric errors
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH fi_fabric 3 "2015\-03\-16" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_fabric 3 "2015\-03\-16" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
fi_fabric - Fabric domain operations
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH fi_getinfo 3 "2015\-03\-31" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_getinfo 3 "2015\-04\-23" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
fi_getinfo / fi_freeinfo - Obtain / free fabric interface information
|
||||
@ -113,9 +113,9 @@ struct\ fi_info\ {
|
||||
\ \ \ \ size_t\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ dest_addrlen;
|
||||
\ \ \ \ void\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ *src_addr;
|
||||
\ \ \ \ void\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ *dest_addr;
|
||||
\ \ \ \ fi_connreq_t\ \ \ \ \ \ \ \ \ \ connreq;
|
||||
\ \ \ \ struct\ fi_tx_attr\ *tx_attr;
|
||||
\ \ \ \ struct\ fi_rx_attr\ *rx_attr;
|
||||
\ \ \ \ fid_t\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ handle;
|
||||
\ \ \ \ struct\ fi_tx_attr\ \ \ \ \ *tx_attr;
|
||||
\ \ \ \ struct\ fi_rx_attr\ \ \ \ \ *rx_attr;
|
||||
\ \ \ \ struct\ fi_ep_attr\ \ \ \ \ *ep_attr;
|
||||
\ \ \ \ struct\ fi_domain_attr\ *domain_attr;
|
||||
\ \ \ \ struct\ fi_fabric_attr\ *fabric_attr;
|
||||
@ -165,10 +165,18 @@ destination address.
|
||||
This field will be ignored in hints unless the node and service
|
||||
parameters are NULL or FI_SOURCE is specified.
|
||||
.PP
|
||||
\f[I]connreq - connection request\f[] : References a specific connection
|
||||
request, otherwise the field must be NULL.
|
||||
\f[I]handle - provider context handle\f[] : References a provider
|
||||
specific handle.
|
||||
The use of this field is operation specific.
|
||||
Unless its use is described for a given operation, the handle field must
|
||||
be NULL.
|
||||
It is commonly used by applications that make use of connection-oriented
|
||||
endpoints.
|
||||
For other applications, the field should usually be NULL.
|
||||
.PP
|
||||
This field is used when processing connection requests and responses.
|
||||
See fi_eq(3), fi_reject(3), and fi_endpoint(3).
|
||||
It is also used to inherit endpoint\[aq]s attributes.
|
||||
See fi_eq(3), fi_reject(3), and fi_endpoint(3) .
|
||||
.PP
|
||||
\f[I]tx_attr - transmit context attributes\f[] : Optionally supplied
|
||||
transmit context attributes.
|
||||
@ -280,13 +288,6 @@ Applications can use the FI_READ, FI_WRITE, FI_REMOTE_READ, and
|
||||
FI_REMOTE_WRITE flags to restrict the types of atomic operations
|
||||
supported by an endpoint.
|
||||
.PP
|
||||
\f[I]FI_DYNAMIC_MR\f[] : The provider supports applications registering
|
||||
any range of addresses in their virtual address space, whether or not
|
||||
those addresses are back by physical pages or have been allocated to the
|
||||
app.
|
||||
Providers that lack this capability require that registered memory
|
||||
regions be backed by allocated memory pages.
|
||||
.PP
|
||||
\f[I]FI_NAMED_RX_CTX\f[] : Requests that endpoints which support
|
||||
multiple receive contexts allow an initiator to target (or name) a
|
||||
specific receive context as part of a data transfer operation.
|
||||
@ -334,10 +335,13 @@ This flag requires that FI_RMA and/or FI_ATOMIC be set.
|
||||
capable of receiving write memory operations from remote endpoints.
|
||||
This flag requires that FI_RMA and/or FI_ATOMIC be set.
|
||||
.PP
|
||||
\f[I]FI_CANCEL\f[] : Indicates that the user desires the ability to
|
||||
cancel outstanding data transfer operations.
|
||||
If FI_CANCEL is not set, a provider may optimize code paths with the
|
||||
assumption that fi_cancel will not be used by the application.
|
||||
\f[I]FI_RMA_EVENT\f[] : Requests that an endpoint support the generation
|
||||
of completion events when it is the target of an RMA and/or atomic
|
||||
operation.
|
||||
If set, the provider will support both completion queue and counter
|
||||
events.
|
||||
This flag requires that FI_REMOTE_READ and/or FI_REMOTE_WRITE be enabled
|
||||
on the endpoint.
|
||||
.PP
|
||||
\f[I]FI_TRIGGER\f[] : Indicates that the endpoint should support
|
||||
triggered operations.
|
||||
@ -368,8 +372,7 @@ Primary capabilities: FI_MSG, FI_RMA, FI_TAGGED, FI_ATOMIC,
|
||||
FI_NAMED_RX_CTX, FI_DIRECTED_RECV, FI_READ, FI_WRITE, FI_RECV, FI_SEND,
|
||||
FI_REMOTE_READ, and FI_REMOTE_WRITE.
|
||||
.PP
|
||||
Secondary capabilities: FI_DYNAMIC_MR, FI_MULTI_RECV, FI_SOURCE,
|
||||
FI_CANCEL, FI_FENCE
|
||||
Secondary capabilities: FI_MULTI_RECV, FI_SOURCE, FI_FENCE
|
||||
.SH MODE
|
||||
.PP
|
||||
The operational mode bits are used to convey requirements that an
|
||||
@ -441,23 +444,6 @@ Additionally, applications may receive provider generated packets that
|
||||
do not contain application data.
|
||||
Such received messages will indicate a transfer size of 0 bytes.
|
||||
.PP
|
||||
\f[I]FI_PROV_MR_ATTR\f[] : The provider assigns one or more attributes
|
||||
associated with a memory registration request.
|
||||
The provider will set this mode if it returns the memory registration
|
||||
keys that applications must use, or if it requires that the MR offset
|
||||
associated with a memory region be the same as the virtual address of
|
||||
the memory.
|
||||
.PP
|
||||
Applications that support provider MR attributes will need to exchange
|
||||
MR parameters with remote peers for RMA and atomic operations.
|
||||
The exchanged data should include both the address of the memory region
|
||||
as well as the MR key.
|
||||
If this mode is disabled, then applications may select the MR key
|
||||
associated with a registration request, and the resulting memory region
|
||||
will start at a base address of 0.
|
||||
Applications can request that providers select MR attributes by forcing
|
||||
this bit set after fi_getinfo returns.
|
||||
.PP
|
||||
\f[I]FI_ASYNC_IOV\f[] : Applications can reference multiple data buffers
|
||||
as part of a single transmit operation through the use of IO vectors
|
||||
(SGEs).
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH fi_mr 3 "2015\-04\-02" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_mr 3 "2015\-04\-23" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
fi_mr - Memory region operations
|
||||
@ -100,26 +100,47 @@ buffers before using them for local operations (e.g.
|
||||
send and receive data buffers), and the mem_desc parameter into data
|
||||
transfer operations is ignored.
|
||||
.PP
|
||||
Providers may support applications registering any range of addresses in
|
||||
their virtual address space, whether or not those addresses are back by
|
||||
physical pages or have been allocated to the app.
|
||||
Support for this ability is specified through the FI_DYNAMIC_MR
|
||||
capability flag.
|
||||
Providers that lack this capability require that registered memory
|
||||
regions be backed by allocated memory pages.
|
||||
Further behavior of memory registration operations is controlled based
|
||||
on the mr_mode field in the domain attribute.
|
||||
.PP
|
||||
The attributes of a registered memory region may be specified by either
|
||||
the provider or, if supported, the application.
|
||||
Relevant attributes include the MR key associated with the region and
|
||||
the address (offset) used by peer applications when accessing the region
|
||||
through RMA or atomic operations.
|
||||
The FI_PROV_MR_ATTR mode bit indicates if the provider will supply these
|
||||
attribute values, or if the application may select them.
|
||||
Provider supplied values will require that an application exchange the
|
||||
memory region attributes with peers if RMA is required.
|
||||
\f[I]Basic Memory Registration Mode\f[] : If the mr_mode field is set to
|
||||
FI_MR_BASIC, then memory registration operations are set to basic mode.
|
||||
In basic mode, registration occurs on allocated data buffers, and the MR
|
||||
attributes are selected by the provider.
|
||||
.PP
|
||||
Basic mode uses provider assigned attributes for the registered buffers.
|
||||
The local memory descriptor and remote memory key are selected by the
|
||||
provider.
|
||||
The address used to access a buffer as the target of an RMA or atomic
|
||||
operation is the same as the virtual address of the buffer.
|
||||
.PP
|
||||
Applications that support the basic registration mode will need to
|
||||
exchange MR parameters with remote peers for RMA and atomic operations.
|
||||
The exchanged data should include both the address of the memory region
|
||||
as well as the MR key.
|
||||
.PP
|
||||
\f[I]Scalable Memory Registration Mode\f[] : If the mr_mode field is set
|
||||
to FI_MR_SCALABLE, then memory registration operations are set to
|
||||
scalable mode.
|
||||
In scalable mode, registration occurs on memory address ranges, and the
|
||||
MR attributes are selected by the user.
|
||||
.PP
|
||||
Memory regions registered as the target of RMA and atomic operations are
|
||||
associated with a MR key selected by the application.
|
||||
If local registrations are required (see FI_LOCAL_MR mode), the local
|
||||
descriptor will be the same as the remote key.
|
||||
The resulting memory region will be accessible by remote peers starting
|
||||
at a base address of 0.
|
||||
Because scalable registration mode refers to memory regions, versus data
|
||||
buffers, the address ranges given for a registration request do not need
|
||||
to map to data buffers allocated by the application at the time the
|
||||
registration call is made.
|
||||
That is, an application can register any range of addresses in their
|
||||
virtual address space, whether or not those addresses are backed by
|
||||
physical pages or have been allocated.
|
||||
.PP
|
||||
The registrations functions -- fi_mr_reg, fi_mr_regv, and fi_mr_regattr
|
||||
-- are used to register one or more memory buffers with fabric
|
||||
-- are used to register one or more memory regions with fabric
|
||||
resources.
|
||||
The main difference between registration functions are the number and
|
||||
type of parameters that they accept as input.
|
||||
@ -182,20 +203,12 @@ Because MR keys must be provided by a remote process, an application can
|
||||
use the requested_key parameter to indicate that a specific key value be
|
||||
returned.
|
||||
Support for user requested keys is provider specific and is determined
|
||||
by the FI_PROV_MR_ATTR mode bit.
|
||||
Access domains must be opened with the FI_PROV_MR_ATTR mode cleared in
|
||||
order to enable support for application selectable MR keys.
|
||||
The requested_key parameter is ignored for memory registration calls
|
||||
unless the access flags include either FI_REMOTE_READ or
|
||||
FI_REMOTE_WRITE.
|
||||
by the mr_mode domain attribute.
|
||||
.PP
|
||||
Remote RMA and atomic operations indicate the location within a
|
||||
registered memory region by specifying an address.
|
||||
By default, the RMA target address is a 0-based offset between the
|
||||
registered buf address and the end of the registered memory region (buf
|
||||
+ len), unless the FI_PROV_MR_ATTR mode bit has been set.
|
||||
If the FI_PROV_MR_ATTR mode bit is enabled, the RMA target address
|
||||
defaults to the starting virtual address of buf.
|
||||
The location is referenced by adding the offset to either the base
|
||||
virtual address of the buffer or to 0, depending on the mr_mode.
|
||||
.PP
|
||||
The offset parameter is reserved for future use and must be 0.
|
||||
.PP
|
||||
@ -259,19 +272,7 @@ bitwise OR of the following flags.
|
||||
write or atomic operation modify the memory region.
|
||||
.SH FLAGS
|
||||
.PP
|
||||
The following flags are usable with fi_mr_reg, fi_mr_regv,
|
||||
fi_mr_regattr.
|
||||
.PP
|
||||
\f[I]FI_MR_KEY\f[] : Indicates that the registered memory region should
|
||||
be associated with the specified requested_key.
|
||||
If this flag is not provided, the requested_key parameter is ignored.
|
||||
It is an error to specify this flag on domains with the FI_PROV_MR_ATTR
|
||||
mode bit set.
|
||||
.PP
|
||||
\f[I]FI_MR_OFFSET\f[] : Associates the registered memory region with the
|
||||
specified offset as its base target address.
|
||||
If this flag is not provided, the offset parameter is ignored.
|
||||
When set, any overlapping registration is replaced.
|
||||
Flags are reserved for future use and must be 0.
|
||||
.SH RETURN VALUES
|
||||
.PP
|
||||
Returns 0 on success.
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH fi_msg 3 "2015\-03\-31" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_msg 3 "2015\-04\-24" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
fi_msg - Message data transfer operations
|
||||
@ -190,7 +190,7 @@ See fi_getinfo for additional details on FI_REMOTE_CQ_DATA.
|
||||
.PP
|
||||
\f[I]FI_COMPLETION\f[] : Indicates that a completion entry should be
|
||||
generated for the specified operation.
|
||||
The endpoint must be bound to an event queue with FI_COMPLETION that
|
||||
The endpoint must be bound to a completion queue with FI_COMPLETION that
|
||||
corresponds to the specified operation, or this flag is ignored.
|
||||
.PP
|
||||
\f[I]FI_MORE\f[] : Indicates that the user has additional requests that
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH fi_poll 3 "2015\-01\-29" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_poll 3 "2015\-01\-29" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
fi_poll - Polling and wait set operations
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH fi_rma 3 "2015\-03\-31" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_rma 3 "2015\-03\-31" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
fi_rma - Remote memory access operations
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH fi_tagged 3 "2015\-03\-31" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_tagged 3 "2015\-04\-17" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
fi_tagged - Tagged data transfer operations
|
||||
@ -7,15 +7,9 @@ fi_tagged - Tagged data transfer operations
|
||||
Post a buffer to receive an incoming message
|
||||
.RS
|
||||
.RE
|
||||
.PP
|
||||
fi_tsend / fi_tsendv / fi_tsendmsg
|
||||
.PD 0
|
||||
.P
|
||||
.PD
|
||||
fi_tinject / fi_tsenddata : Initiate an operation to send a message
|
||||
.TP
|
||||
.B fi_tsearch
|
||||
Initiate a search operation for a buffered receive matching a given tag
|
||||
.B fi_tsend / fi_tsendv / fi_tsendmsg / fi_tinject / fi_tsenddata
|
||||
Initiate an operation to send a message
|
||||
.RS
|
||||
.RE
|
||||
.SH SYNOPSIS
|
||||
@ -50,9 +44,6 @@ ssize_t\ fi_tinject(struct\ fid_ep\ *ep,\ const\ void\ *buf,\ size_t\ len,
|
||||
ssize_t\ fi_tsenddata(struct\ fid_ep\ *ep,\ const\ void\ *buf,\ size_t\ len,
|
||||
\ \ \ \ void\ *desc,\ uint64_t\ data,\ fi_addr_t\ dest_addr,\ uint64_t\ tag,
|
||||
\ \ \ \ void\ *context);
|
||||
|
||||
ssize_t\ fi_tsearch(struct\ fid_ep\ *ep,\ uint64_t\ *tag,\ uint64_t\ ignore,
|
||||
\ \ \ \ uint64_t\ flags,\ void\ *src_addr,\ size_t\ *len,\ void\ *context);
|
||||
\f[]
|
||||
.fi
|
||||
.SH ARGUMENTS
|
||||
@ -206,28 +197,6 @@ The fi_trecvmsg call supports posting buffers over both connected and
|
||||
unconnected endpoints, with the ability to control the receive operation
|
||||
per call through the use of flags.
|
||||
The fi_trecvmsg function takes a struct fi_msg_tagged as input.
|
||||
.SS fi_tsearch
|
||||
.PP
|
||||
The function fi_tsearch determines if a message with the specified tag
|
||||
with ignore mask from an optionally supplied source address has been
|
||||
received and is buffered by the provider.
|
||||
The fi_tsearch call is only available on endpoints with provider
|
||||
allocated buffering enabled (see fi_rx_attr total_buffered_recv).
|
||||
The fi_tsearch operation may complete asynchronously or immediately,
|
||||
depending on the underlying provider implementation.
|
||||
.PP
|
||||
By default, a single message may be matched by multiple search
|
||||
operations.
|
||||
The user can restrict a message to matching with a single fi_tsearch
|
||||
call by using the FI_CLAIM flag to control the search.
|
||||
When set, FI_CLAIM indicates that when a search successfully finds a
|
||||
matching message, the message is claimed by caller.
|
||||
Subsequent searches cannot find the same message, although they may
|
||||
match other messages that have the same tag.
|
||||
.PP
|
||||
An application can request that a buffered message be discarded by using
|
||||
the FI_DISCARD flag as part of the search.
|
||||
When set, FI_DISCARD indicates that any matching message be dropped.
|
||||
.SH FLAGS
|
||||
.PP
|
||||
The fi_trecvmsg and fi_tsendmsg calls allow the user to specify flags
|
||||
@ -274,34 +243,69 @@ Indicates that the requested operation, also known as the fenced
|
||||
operation, be deferred until all previous operations targeting the same
|
||||
target endpoint have completed.
|
||||
.PP
|
||||
The following flags may be used with fi_tsearch.
|
||||
The following flags may be used with fi_trecvmsg.
|
||||
.PP
|
||||
\f[I]FI_CLAIM\f[] : Indicates that when a search successfully finds a
|
||||
matching message, the message is claimed by caller.
|
||||
Subsequent searches cannot find the same message, although they may
|
||||
match other messages that have the same tag.
|
||||
\f[I]FI_PEEK\f[] : The peek flag may be used to see if a specified
|
||||
message has arrived.
|
||||
A peek request is often useful on endpoints that have provider allocated
|
||||
buffering enabled (see fi_rx_attr total_buffered_recv).
|
||||
Unlike standard receive operations, a receive operation with the FI_PEEK
|
||||
flag set does not remain queued with the provider until the peek
|
||||
completes successfully.
|
||||
If no data is available, the FI_PEEK receive will complete with a status
|
||||
of FI_ENOMSG.
|
||||
.PP
|
||||
\f[I]FI_DISCARD\f[] : Indicates that if a search successfully finds a
|
||||
matching message, that the message is discarded by the provider, as the
|
||||
If a peek request locates a matching message, the operation will
|
||||
complete successfully.
|
||||
The returned completion data will indicate the metadata associated with
|
||||
the message, such as the message length, completion flags, available CQ
|
||||
data, tag, and source address.
|
||||
The data available is subject to the completion entry format (e.g.
|
||||
struct fi_cq_tagged_entry).
|
||||
.PP
|
||||
An application may supply a buffer as part of the peek operation.
|
||||
If given, the provider may return a copy of the message data.
|
||||
The returned data is limited to the size of the input buffer(s) or the
|
||||
message size, if smaller.
|
||||
A provider indicates if data is available by setting the buf field of
|
||||
the CQ entry to the user\[aq]s first input buffer.
|
||||
If buf is NULL, no data was available to return.
|
||||
A provider may return NULL even if the peek operation completes
|
||||
successfully.
|
||||
Note that the CQ entry len field will reference the size of the message,
|
||||
not necessarily the size of the returned data.
|
||||
.PP
|
||||
\f[I]FI_CLAIM\f[] : If this flag is used in conjunction with FI_PEEK, it
|
||||
indicates if the peek request completes successfully -- indicating that
|
||||
a matching message was located -- the message is claimed by caller.
|
||||
Claimed messages can only be retrieved using a subsequent, paired
|
||||
receive operation with the FI_CLAIM flag set.
|
||||
A receive operation with the FI_CLAIM flag set, but FI_PEEK not set is
|
||||
used to retrieve a previously claimed message.
|
||||
.PP
|
||||
In order to use the FI_CLAIM flag, an application must supply a struct
|
||||
fi_context structure as the context for the receive operation.
|
||||
The same fi_context structure used for an FI_PEEK + FI_CLAIM operation
|
||||
must be used by the paired FI_CLAIM request.
|
||||
.PP
|
||||
\f[I]FI_DISCARD\f[] : This flag must be used in conjunction with either
|
||||
FI_PEEK or FI_CLAIM.
|
||||
If this flag is used in conjunction with FI_PEEK, it indicates if the
|
||||
peek request completes successfully -- indicating that a matching
|
||||
message was located -- the message is discarded by the provider, as the
|
||||
data is not needed by the application.
|
||||
This flag may also be used in conjunction with FI_CLAIM in order to
|
||||
retrieve and discard a message previously claimed using an FI_PEEK +
|
||||
FI_CLAIM request.
|
||||
.PP
|
||||
If this flag is set, the input buffer(s) and length parameters.
|
||||
.SH RETURN VALUE
|
||||
.PP
|
||||
The tagged send and receive calls return 0 on success.
|
||||
On error, a negative value corresponding to fabric _errno _ is returned.
|
||||
Fabric errno values are defined in \f[C]fi_errno.h\f[].
|
||||
.PP
|
||||
The fi_tsearch calls returns 0 if the search was successfully initiated
|
||||
asynchronously.
|
||||
In this case, the result of the search will be reported through the
|
||||
event collector associated with the endpoint.
|
||||
If the search completes immediately, fi_tsearch will return 1, with
|
||||
information about the matching receive returned through the len, tag,
|
||||
src_addr, and src_addrlen parameters.
|
||||
.SH ERRORS
|
||||
.PP
|
||||
\f[I]-FI_ENOMSG\f[] : Returned by fi_tsearch on an immediate completion,
|
||||
but no matching message was located.
|
||||
.PP
|
||||
\f[I]-FI_EAGAIN\f[] : Indicates that the underlying provider currently
|
||||
lacks the resources needed to initiate the requested operation.
|
||||
This may be the result of insufficient internal buffering, in the case
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH fi_trigger 3 "2015\-01\-01" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_trigger 3 "2015\-01\-01" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
fi_trigger - Triggered operations
|
||||
|
@ -1 +0,0 @@
|
||||
.so man3/fi_tagged.3
|
@ -1,4 +1,4 @@
|
||||
.TH fi_version 3 "2015\-01\-08" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_version 3 "2015\-01\-08" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
fi_version - Version of the library interfaces
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH fabric 7 "2015\-03\-27" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fabric 7 "2015\-04\-20" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
Fabric Interface Library
|
||||
@ -215,22 +215,22 @@ management of providers.
|
||||
\f[I]fabric\f[] : Provides output specific to interactions associated
|
||||
with the fabric object.
|
||||
.IP \[bu] 2
|
||||
\f[I]domain\f[] : Provides outout specific to interactions associated
|
||||
\f[I]domain\f[] : Provides output specific to interactions associated
|
||||
with the domain object.
|
||||
.IP \[bu] 2
|
||||
\f[I]ep_ctrl\f[] : Provides outout specific to endpoint non-data
|
||||
\f[I]ep_ctrl\f[] : Provides output specific to endpoint non-data
|
||||
transfer operations, such as CM operations.
|
||||
.IP \[bu] 2
|
||||
\f[I]ep_data\f[] : Provides outout specific to endpoint data transfer
|
||||
\f[I]ep_data\f[] : Provides output specific to endpoint data transfer
|
||||
operations.
|
||||
.IP \[bu] 2
|
||||
\f[I]av\f[] : Provides outout specific to address vector operations.
|
||||
\f[I]av\f[] : Provides output specific to address vector operations.
|
||||
.IP \[bu] 2
|
||||
\f[I]cq\f[] : Provides outout specific to completion queue operations.
|
||||
\f[I]cq\f[] : Provides output specific to completion queue operations.
|
||||
.IP \[bu] 2
|
||||
\f[I]eq\f[] : Provides outout specific to event queue operations.
|
||||
\f[I]eq\f[] : Provides output specific to event queue operations.
|
||||
.IP \[bu] 2
|
||||
\f[I]mr\f[] : Provides outout specific to memory registration.
|
||||
\f[I]mr\f[] : Provides output specific to memory registration.
|
||||
.SH SEE ALSO
|
||||
.PP
|
||||
\f[C]fi_provider\f[](7), \f[C]fi_getinfo\f[](3),
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH fi_direct 7 "2014\-11\-21" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_direct 7 "2015\-04\-23" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
Direct fabric provider access
|
||||
@ -64,14 +64,6 @@ See fi_getinfo for additional details.
|
||||
\f[I]FI_DIRECT_LOCAL_MR\f[] : The provider sets FI_LOCAL_MR for
|
||||
fi_info:mode.
|
||||
See fi_getinfo for additional details.
|
||||
.PP
|
||||
\f[I]FI_DIRECT_PROV_MR_ATTR\f[] : The provider sets FI_PROV_MR_ATTR for
|
||||
fi_info:mode.
|
||||
See fi_getinfo for additional details.
|
||||
.PP
|
||||
\f[I]FI_DIRECT_DYNAMIC_MR\f[] : The provider sets FI_DYNAMIC_MR for
|
||||
fi_info:caps.
|
||||
See fi_getinfo for additional details.
|
||||
.SH SEE ALSO
|
||||
.PP
|
||||
\f[C]fi_getinfo\f[](3), \f[C]fi_endpoint\f[](3), \f[C]fi_domain\f[](3)
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH fi_provider 7 "2015\-03\-31" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_provider 7 "2015\-03\-31" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
Fabric Interface Providers
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH fi_psm 7 "2015\-03\-31" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_psm 7 "2015\-04\-23" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
The PSM Fabric Provider
|
||||
@ -41,8 +41,7 @@ two endpoints with \f[I]FI_RMA\f[].
|
||||
.PP
|
||||
\f[I]FI_MULTI_RECV\f[] is supported for non-tagged message queue only.
|
||||
.PP
|
||||
Other supported capabilities include \f[I]FI_CANCEL\f[],
|
||||
\f[I]FI_TRIGGER\f[], and \f[I]FI_DYNAMIC_MR\f[].
|
||||
Other supported capabilities include \f[I]FI_TRIGGER\f[].
|
||||
.PP
|
||||
Modes : \f[I]FI_CONTEXT\f[] is required.
|
||||
That means, all the requests that generate completions must have a valid
|
||||
|
@ -1,24 +1,51 @@
|
||||
.TH fi_sockets 7 "2015\-03\-16" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_sockets 7 "2015\-04\-23" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
The Sockets Fabric Provider
|
||||
.SH OVERVIEW
|
||||
.PP
|
||||
\&...Whatever the sockets provider maintainer wants to put here...
|
||||
The sockets provider is a general purpose provider that can be used on
|
||||
any system that supports TCP sockets.
|
||||
The provider is not intended to provide performance improvements over
|
||||
regular TCP sockets, but rather to allow developers to write, test, and
|
||||
debug application code even on platforms that do not have
|
||||
high-performance fabric hardware.
|
||||
The sockets provider supports all libfabric provider requirements and
|
||||
interfaces.
|
||||
.SH SUPPORTED FEATURES
|
||||
.PP
|
||||
Suggestions:
|
||||
.IP \[bu] 2
|
||||
Document what is working
|
||||
.IP \[bu] 2
|
||||
Document what has been tested
|
||||
.IP \[bu] 2
|
||||
Document what is know to NOT be working
|
||||
.IP \[bu] 2
|
||||
Document any other things app developers and end users should know about
|
||||
this provider (e.g., run-time tunable parameters, differences in
|
||||
behavior between this and other providers, etc.)
|
||||
The sockets provider supports all the features defined for the libfabric
|
||||
API.
|
||||
Key features include:
|
||||
.PP
|
||||
\f[I]Endpoint types\f[] : The provider supports all endpoint types:
|
||||
\f[I]FI_EP_MSG\f[], \f[I]FI_EP_RDM\f[], and \f[I]FI_EP_DGRAM\f[].
|
||||
.PP
|
||||
\f[I]Endpoint capabilities\f[] : The following data transfer interface
|
||||
is supported for a all endpoint types: \f[I]fi_msg\f[].
|
||||
Additionally, these interfaces are supported for reliable endpoints
|
||||
(\f[I]FI_EP_MSG\f[] and \f[I]FI_EP_RDM\f[]): \f[I]fi_tagged\f[],
|
||||
\f[I]fi_atomic\f[], and \f[I]fi_rma\f[].
|
||||
.PP
|
||||
\f[I]Modes\f[] : The sockets provider supports all operational modes
|
||||
including \f[I]FI_CONTEXT\f[] and \f[I]FI_MSG_PREFIX\f[].
|
||||
.PP
|
||||
\f[I]Progress\f[] : Sockets provider supports both
|
||||
\f[I]FI_PROGRESS_AUTO\f[] and \f[I]FI_PROGRESS_MANUAL\f[], with a
|
||||
default set to auto.
|
||||
When progress is set to auto, a background thread runs to ensure that
|
||||
progress is made for asynchronous requests.
|
||||
.SH LIMITATIONS
|
||||
.PP
|
||||
The sockets provider attempts to emulate the entire API set, including
|
||||
all defined options.
|
||||
In order to support development on a wide range of systems, it is
|
||||
implemented over TCP sockets.
|
||||
As a result, the performance numbers are lower compared to other
|
||||
providers implemented over high-speed fabric, and lower than what an
|
||||
application might see implementing to sockets directly.
|
||||
.SH SEE ALSO
|
||||
.PP
|
||||
\f[C]fabric\f[](7), \f[C]fi_provider\f[](7),
|
||||
\f[C]fabric\f[](7), \f[C]fi_provider\f[](7), \f[C]fi_getinfo\f[](3)
|
||||
.SH AUTHORS
|
||||
OpenFabrics.
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH fi_usnic 7 "2015\-03\-31" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_usnic 7 "2015\-03\-31" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
The usNIC Fabric Provider
|
||||
|
@ -1,22 +1,69 @@
|
||||
.TH fi_verbs 7 "2015\-03\-16" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc5"
|
||||
.TH fi_verbs 7 "2015\-04\-23" "Libfabric Programmer\[aq]s Manual" "Libfabric v1.0.0rc6"
|
||||
.SH NAME
|
||||
.PP
|
||||
The Verbs Fabric Provider
|
||||
.SH OVERVIEW
|
||||
.PP
|
||||
\&...Whatever the Verbs provider maintainer wants to put here...
|
||||
The verbs provider enables applications using OFI to be run over any
|
||||
verbs hardware (Infiniband, iWARP, etc).
|
||||
It uses the Linux Verbs API for network transport and provides a
|
||||
translation OFI calls to appropriate verbs API calls.
|
||||
It uses librdmacm for communication management and libibverbs for other
|
||||
control and data transfer operations.
|
||||
.SH SUPPORTED FEATURES
|
||||
.PP
|
||||
Suggestions:
|
||||
.IP \[bu] 2
|
||||
Document what is working
|
||||
.IP \[bu] 2
|
||||
Document what has been tested
|
||||
.IP \[bu] 2
|
||||
Document what is know to NOT be working
|
||||
.IP \[bu] 2
|
||||
Document any other things app developers and end users should know about
|
||||
this provider (e.g., run-time tunable parameters, differences in
|
||||
behavior between this and other providers, etc.)
|
||||
The verbs provider supports a subset of OFI features.
|
||||
.PP
|
||||
\f[I]Endpoint types\f[] : Only FI_EP_MSG is supported.
|
||||
.PP
|
||||
\f[I]Endpoint capabilities\f[] : FI_MSG, FI_RMA, FI_ATOMIC.
|
||||
.PP
|
||||
\f[I]Modes\f[] : Verbs provider requires applications to support the
|
||||
following modes: FI_LOCAL_MR for all applications.
|
||||
FI_RX_CQ_DATA for applications that want to use RMA.
|
||||
Applications must take responsibility of posting receives for any
|
||||
incoming CQ data.
|
||||
.PP
|
||||
\f[I]Progress\f[] : Verbs provider supports FI_PROGRESS_AUTO:
|
||||
Asynchonous operations make forward progress automatically.
|
||||
.PP
|
||||
\f[I]Operation flags\f[] : Verbs provider supports FI_INJECT,
|
||||
FI_COMPLETION, FI_REMOTE_CQ_DATA.
|
||||
.PP
|
||||
\f[I]Msg Ordering\f[] : Verbs provider support the following messaging
|
||||
ordering on the TX side: * Read after Read * Read after Write * Read
|
||||
after Send * Write after Write * Write after Send * Send after Write *
|
||||
Send after Send
|
||||
.SH UNSUPPORTED FEATURES
|
||||
.PP
|
||||
\f[I]Control Interfaces\f[] : Counters and address vectors are not
|
||||
supported.
|
||||
.PP
|
||||
\f[I]Data transfer interfaces\f[] : Tagged messaging and multi-receive
|
||||
are not supported.
|
||||
.PP
|
||||
\f[I]Endpoint features\f[] : Scalable endpoints and shared contexts are
|
||||
not suppoted.
|
||||
fi_cancel, fi_tx/rx_size_left and fi_alias operations are not supported.
|
||||
.PP
|
||||
\f[I]Others\f[] : Other unsupported features include resource
|
||||
management, polling.
|
||||
.SH LIMITATIONS
|
||||
.PP
|
||||
\f[I]CQ\f[] : cq_readfrom operations are not supported.
|
||||
.PP
|
||||
\f[I]CM\f[] : fi_setname is not yet supported.
|
||||
.PP
|
||||
\f[I]EQ\f[] : fi_eq_write is not supported.
|
||||
.PP
|
||||
\f[I]Memory Regions\f[] : Adding regions via s/g list is not supported.
|
||||
Generic fi_mr_regattr is not supported.
|
||||
No support for binding memory regions to a counter.
|
||||
.PP
|
||||
\f[I]Wait objects\f[] : Only FI_WAIT_FD wait object is supported.
|
||||
Wait sets are not supported.
|
||||
.PP
|
||||
\f[I]Others\f[] : No direct inject calls yet.
|
||||
.SH SEE ALSO
|
||||
.PP
|
||||
\f[C]fabric\f[](7), \f[C]fi_provider\f[](7),
|
||||
|
@ -55,7 +55,8 @@ extern struct fi_provider psmx_prov;
|
||||
#define PSMX_TIME_OUT 120
|
||||
|
||||
#define PSMX_OP_FLAGS (FI_INJECT | FI_MULTI_RECV | FI_COMPLETION | \
|
||||
FI_TRIGGER | FI_INJECT_COMPLETE | FI_COMMIT_COMPLETE)
|
||||
FI_TRIGGER | FI_INJECT_COMPLETE | \
|
||||
FI_TRANSMIT_COMPLETE | FI_DELIVERY_COMPLETE)
|
||||
|
||||
#define PSMX_CAP_EXT (0)
|
||||
|
||||
@ -63,12 +64,15 @@ extern struct fi_provider psmx_prov;
|
||||
FI_RMA | FI_MULTI_RECV | \
|
||||
FI_READ | FI_WRITE | FI_SEND | FI_RECV | \
|
||||
FI_REMOTE_READ | FI_REMOTE_WRITE | \
|
||||
FI_CANCEL | FI_TRIGGER | \
|
||||
FI_DYNAMIC_MR | \
|
||||
FI_TRIGGER | \
|
||||
FI_RMA_EVENT | \
|
||||
PSMX_CAP_EXT)
|
||||
|
||||
#define PSMX_CAPS2 ((PSMX_CAPS | FI_DIRECTED_RECV) & ~FI_TAGGED)
|
||||
|
||||
#define PSMX_SUB_CAPS (FI_READ | FI_WRITE | FI_REMOTE_READ | FI_REMOTE_WRITE | \
|
||||
FI_SEND | FI_RECV)
|
||||
|
||||
#define PSMX_MODE (FI_CONTEXT)
|
||||
|
||||
#define PSMX_MAX_MSG_SIZE ((0x1ULL << 32) - 1)
|
||||
@ -247,6 +251,8 @@ struct psmx_fid_domain {
|
||||
struct psmx_fid_ep *rma_ep;
|
||||
struct psmx_fid_ep *atomics_ep;
|
||||
uint64_t mode;
|
||||
uint64_t caps;
|
||||
enum fi_mr_mode mr_mode;
|
||||
|
||||
int am_initialized;
|
||||
|
||||
@ -288,6 +294,18 @@ struct psmx_cq_event {
|
||||
struct slist_entry list_entry;
|
||||
};
|
||||
|
||||
struct psmx_eq_event {
|
||||
int event;
|
||||
union {
|
||||
struct fi_eq_entry data;
|
||||
struct fi_eq_cm_entry cm;
|
||||
struct fi_eq_err_entry err;
|
||||
} eqe;
|
||||
int error;
|
||||
size_t entry_size;
|
||||
struct slist_entry list_entry;
|
||||
};
|
||||
|
||||
struct psmx_fid_wait {
|
||||
struct fid_wait wait;
|
||||
struct psmx_fid_fabric *fabric;
|
||||
@ -320,12 +338,24 @@ struct psmx_fid_cq {
|
||||
size_t event_count;
|
||||
struct slist event_queue;
|
||||
struct slist free_list;
|
||||
pthread_mutex_t mutex;
|
||||
struct psmx_cq_event *pending_error;
|
||||
struct psmx_fid_wait *wait;
|
||||
int wait_cond;
|
||||
int wait_is_local;
|
||||
};
|
||||
|
||||
struct psmx_fid_eq {
|
||||
struct fid_eq eq;
|
||||
struct psmx_fid_fabric *fabric;
|
||||
struct slist event_queue;
|
||||
struct slist error_queue;
|
||||
struct slist free_list;
|
||||
pthread_mutex_t mutex;
|
||||
struct psmx_fid_wait *wait;
|
||||
int wait_is_local;
|
||||
};
|
||||
|
||||
enum psmx_triggered_op {
|
||||
PSMX_TRIGGERED_SEND,
|
||||
PSMX_TRIGGERED_RECV,
|
||||
@ -472,7 +502,9 @@ struct psmx_fid_cntr {
|
||||
struct psmx_fid_av {
|
||||
struct fid_av av;
|
||||
struct psmx_fid_domain *domain;
|
||||
struct psmx_fid_eq *eq;
|
||||
int type;
|
||||
uint64_t flags;
|
||||
size_t addrlen;
|
||||
size_t count;
|
||||
size_t last;
|
||||
@ -492,8 +524,8 @@ struct psmx_fid_ep {
|
||||
struct psmx_fid_cntr *read_cntr;
|
||||
struct psmx_fid_cntr *remote_write_cntr;
|
||||
struct psmx_fid_cntr *remote_read_cntr;
|
||||
int send_cq_event_flag:1;
|
||||
int recv_cq_event_flag:1;
|
||||
int send_selective_completion:1;
|
||||
int recv_selective_completion:1;
|
||||
uint64_t flags;
|
||||
uint64_t caps;
|
||||
struct fi_context nocomp_send_context;
|
||||
@ -558,6 +590,8 @@ int psmx_stx_ctx(struct fid_domain *domain, struct fi_tx_attr *attr,
|
||||
struct fid_stx **stx, void *context);
|
||||
int psmx_cq_open(struct fid_domain *domain, struct fi_cq_attr *attr,
|
||||
struct fid_cq **cq, void *context);
|
||||
int psmx_eq_open(struct fid_fabric *fabric, struct fi_eq_attr *attr,
|
||||
struct fid_eq **eq, void *context);
|
||||
int psmx_av_open(struct fid_domain *domain, struct fi_av_attr *attr,
|
||||
struct fid_av **av, void *context);
|
||||
int psmx_cntr_open(struct fid_domain *domain, struct fi_cntr_attr *attr,
|
||||
@ -577,6 +611,12 @@ int psmx_epid_to_epaddr(struct psmx_fid_domain *domain,
|
||||
psm_epid_t epid, psm_epaddr_t *epaddr);
|
||||
void psmx_query_mpi(void);
|
||||
|
||||
void psmx_eq_enqueue_event(struct psmx_fid_eq *eq, struct psmx_eq_event *event);
|
||||
struct psmx_eq_event *psmx_eq_create_event(struct psmx_fid_eq *eq,
|
||||
uint32_t event_num,
|
||||
void *context, uint64_t data,
|
||||
int err, int prov_errno,
|
||||
void *err_data, size_t err_data_size);
|
||||
void psmx_cq_enqueue_event(struct psmx_fid_cq *cq, struct psmx_cq_event *event);
|
||||
struct psmx_cq_event *psmx_cq_create_event(struct psmx_fid_cq *cq,
|
||||
void *op_context, void *buf,
|
||||
@ -620,8 +660,10 @@ static inline void psmx_cntr_inc(struct psmx_fid_cntr *cntr)
|
||||
|
||||
static inline void psmx_progress(struct psmx_fid_domain *domain)
|
||||
{
|
||||
psmx_cq_poll_mq(NULL, domain, NULL, 0, NULL);
|
||||
psmx_am_progress(domain);
|
||||
if (domain) {
|
||||
psmx_cq_poll_mq(NULL, domain, NULL, 0, NULL);
|
||||
psmx_am_progress(domain);
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t _psmx_send(struct fid_ep *ep, const void *buf, size_t len,
|
||||
|
@ -113,6 +113,8 @@ int psmx_am_init(struct psmx_fid_domain *domain)
|
||||
size_t size;
|
||||
int err = 0;
|
||||
|
||||
FI_INFO(&psmx_prov, FI_LOG_CORE, "\n");
|
||||
|
||||
if (!psmx_am_handlers_initialized) {
|
||||
err = psm_am_get_parameters(psm_ep, &psmx_am_param,
|
||||
sizeof(psmx_am_param), &size);
|
||||
|
@ -383,7 +383,6 @@ int psmx_am_atomic_handler(psm_am_token_t token, psm_epaddr_t epaddr,
|
||||
struct psmx_fid_cntr *cntr = NULL;
|
||||
struct psmx_fid_cntr *mr_cntr = NULL;
|
||||
void *tmp_buf;
|
||||
uint64_t cq_flags;
|
||||
|
||||
switch (args[0].u32w0 & PSMX_AM_OP_MASK) {
|
||||
case PSMX_AM_REQ_ATOMIC_WRITE:
|
||||
@ -428,12 +427,9 @@ int psmx_am_atomic_handler(psm_am_token_t token, psm_epaddr_t epaddr,
|
||||
key = args[3].u64;
|
||||
datatype = args[4].u32w0;
|
||||
op = args[4].u32w1;
|
||||
cq_flags = FI_REMOTE_WRITE | FI_ATOMIC;
|
||||
|
||||
if (op == FI_ATOMIC_READ) {
|
||||
if (op == FI_ATOMIC_READ)
|
||||
len = fi_datatype_size(datatype) * count;
|
||||
cq_flags = FI_REMOTE_READ | FI_ATOMIC;
|
||||
}
|
||||
|
||||
assert(len == fi_datatype_size(datatype) * count);
|
||||
|
||||
@ -667,7 +663,7 @@ static int psmx_atomic_self(int am_cmd,
|
||||
|
||||
gen_local_event:
|
||||
no_event = ((flags & PSMX_NO_COMPLETION) ||
|
||||
(ep->send_cq_event_flag && !(flags & FI_COMPLETION)));
|
||||
(ep->send_selective_completion && !(flags & FI_COMPLETION)));
|
||||
if (ep->send_cq && !no_event) {
|
||||
event = psmx_cq_create_event(
|
||||
ep->send_cq,
|
||||
@ -795,7 +791,7 @@ ssize_t _psmx_atomic_write(struct fid_ep *ep,
|
||||
}
|
||||
|
||||
req->no_event = (flags & PSMX_NO_COMPLETION) ||
|
||||
(ep_priv->send_cq_event_flag && !(flags & FI_COMPLETION));
|
||||
(ep_priv->send_selective_completion && !(flags & FI_COMPLETION));
|
||||
|
||||
req->op = PSMX_AM_REQ_ATOMIC_WRITE;
|
||||
req->atomic.buf = (void *)buf;
|
||||
@ -982,7 +978,7 @@ ssize_t _psmx_atomic_readwrite(struct fid_ep *ep,
|
||||
}
|
||||
|
||||
req->no_event = (flags & PSMX_NO_COMPLETION) ||
|
||||
(ep_priv->send_cq_event_flag && !(flags & FI_COMPLETION));
|
||||
(ep_priv->send_selective_completion && !(flags & FI_COMPLETION));
|
||||
|
||||
req->op = PSMX_AM_REQ_ATOMIC_READWRITE;
|
||||
req->atomic.buf = (void *)buf;
|
||||
@ -1200,7 +1196,7 @@ ssize_t _psmx_atomic_compwrite(struct fid_ep *ep,
|
||||
}
|
||||
|
||||
req->no_event = (flags & PSMX_NO_COMPLETION) ||
|
||||
(ep_priv->send_cq_event_flag && !(flags & FI_COMPLETION));
|
||||
(ep_priv->send_selective_completion && !(flags & FI_COMPLETION));
|
||||
|
||||
req->op = PSMX_AM_REQ_ATOMIC_COMPWRITE;
|
||||
req->atomic.buf = (void *)buf;
|
||||
|
@ -125,9 +125,13 @@ static int psmx_av_insert(struct fid_av *av, const void *addr, size_t count,
|
||||
int i, j;
|
||||
fi_addr_t *result = NULL;
|
||||
struct psmx_epaddr_context *epaddr_context;
|
||||
struct psmx_eq_event *event;
|
||||
|
||||
av_priv = container_of(av, struct psmx_fid_av, av);
|
||||
|
||||
if ((av_priv->flags & FI_EVENT) && !av_priv->eq)
|
||||
return -FI_ENOEQ;
|
||||
|
||||
errors = (psm_error_t *) calloc(count, sizeof *errors);
|
||||
if (!errors)
|
||||
return -FI_ENOMEM;
|
||||
@ -194,6 +198,21 @@ static int psmx_av_insert(struct fid_av *av, const void *addr, size_t count,
|
||||
"at the other side.\n");
|
||||
fi_addr[i] = FI_ADDR_NOTAVAIL;
|
||||
error_count++;
|
||||
|
||||
if (av_priv->flags & FI_EVENT) {
|
||||
event = psmx_eq_create_event(av_priv->eq,
|
||||
FI_AV_COMPLETE, /* event */
|
||||
context, /* context */
|
||||
i, /* data: failed index */
|
||||
psmx_errno(errors[i]), /* err */
|
||||
errors[i], /* prov_errno */
|
||||
NULL, /* err_data */
|
||||
0); /* err_data_size */
|
||||
if (!event)
|
||||
return -FI_ENOMEM;
|
||||
|
||||
psmx_eq_enqueue_event(av_priv->eq, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,7 +233,22 @@ static int psmx_av_insert(struct fid_av *av, const void *addr, size_t count,
|
||||
av_priv->last += count;
|
||||
}
|
||||
|
||||
return count - error_count;
|
||||
if (!(av_priv->flags & FI_EVENT))
|
||||
return count - error_count;
|
||||
|
||||
event = psmx_eq_create_event(av_priv->eq,
|
||||
FI_AV_COMPLETE, /* event */
|
||||
context, /* context */
|
||||
count - error_count, /* data: succ count */
|
||||
0, /* err */
|
||||
0, /* prov_errno */
|
||||
NULL, /* err_data */
|
||||
0); /* err_data_size */
|
||||
if (!event)
|
||||
return -FI_ENOMEM;
|
||||
|
||||
psmx_eq_enqueue_event(av_priv->eq, event);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int psmx_av_remove(struct fid_av *av, fi_addr_t *fi_addr, size_t count,
|
||||
@ -287,10 +321,33 @@ static int psmx_av_close(fid_t fid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int psmx_av_bind(struct fid *fid, struct fid *bfid, uint64_t flags)
|
||||
{
|
||||
struct psmx_fid_av *av;
|
||||
struct psmx_fid_eq *eq;
|
||||
|
||||
av = container_of(fid, struct psmx_fid_av, av.fid);
|
||||
|
||||
if (!bfid)
|
||||
return -FI_EINVAL;
|
||||
|
||||
switch (bfid->fclass) {
|
||||
case FI_CLASS_EQ:
|
||||
eq = container_of(bfid, struct psmx_fid_eq, eq.fid);
|
||||
av->eq = eq;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -FI_ENOSYS;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct fi_ops psmx_fi_ops = {
|
||||
.size = sizeof(struct fi_ops),
|
||||
.close = psmx_av_close,
|
||||
.bind = fi_no_bind,
|
||||
.bind = psmx_av_bind,
|
||||
.control = fi_no_control,
|
||||
.ops_open = fi_no_ops_open,
|
||||
};
|
||||
@ -312,6 +369,7 @@ int psmx_av_open(struct fid_domain *domain, struct fi_av_attr *attr,
|
||||
struct psmx_fid_av *av_priv;
|
||||
int type = FI_AV_MAP;
|
||||
size_t count = 64;
|
||||
uint64_t flags = 0;
|
||||
|
||||
domain_priv = container_of(domain, struct psmx_fid_domain, domain);
|
||||
|
||||
@ -329,6 +387,14 @@ int psmx_av_open(struct fid_domain *domain, struct fi_av_attr *attr,
|
||||
}
|
||||
|
||||
count = attr->count;
|
||||
flags = attr->flags;
|
||||
|
||||
if (flags & (FI_READ | FI_SYMMETRIC)) {
|
||||
FI_INFO(&psmx_prov, FI_LOG_AV,
|
||||
"attr->flags=%x, supported=%x\n",
|
||||
attr->flags, FI_EVENT);
|
||||
return -FI_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
av_priv = (struct psmx_fid_av *) calloc(1, sizeof *av_priv);
|
||||
@ -339,6 +405,7 @@ int psmx_av_open(struct fid_domain *domain, struct fi_av_attr *attr,
|
||||
av_priv->type = type;
|
||||
av_priv->addrlen = sizeof(psm_epaddr_t);
|
||||
av_priv->count = count;
|
||||
av_priv->flags = flags;
|
||||
|
||||
av_priv->av.fid.fclass = FI_CLASS_AV;
|
||||
av_priv->av.fid.context = context;
|
||||
|
@ -34,8 +34,11 @@
|
||||
|
||||
void psmx_cq_enqueue_event(struct psmx_fid_cq *cq, struct psmx_cq_event *event)
|
||||
{
|
||||
pthread_mutex_lock(&cq->mutex);
|
||||
slist_insert_tail(&event->list_entry, &cq->event_queue);
|
||||
cq->event_count++;
|
||||
pthread_mutex_unlock(&cq->mutex);
|
||||
|
||||
if (cq->wait)
|
||||
psmx_wait_signal((struct fid_wait *)cq->wait);
|
||||
}
|
||||
@ -47,8 +50,10 @@ static struct psmx_cq_event *psmx_cq_dequeue_event(struct psmx_fid_cq *cq)
|
||||
if (slist_empty(&cq->event_queue))
|
||||
return NULL;
|
||||
|
||||
pthread_mutex_lock(&cq->mutex);
|
||||
entry = slist_remove_head(&cq->event_queue);
|
||||
cq->event_count--;
|
||||
pthread_mutex_unlock(&cq->mutex);
|
||||
|
||||
return container_of(entry, struct psmx_cq_event, list_entry);
|
||||
}
|
||||
@ -177,12 +182,12 @@ static struct psmx_cq_event *psmx_cq_create_event_from_status(
|
||||
flags = FI_WRITE | FI_RMA;
|
||||
break;
|
||||
case PSMX_REMOTE_READ_CONTEXT:
|
||||
op_context = PSMX_CTXT_USER(fi_context);
|
||||
op_context = NULL;
|
||||
buf = NULL;
|
||||
flags = FI_REMOTE_READ | FI_RMA;
|
||||
break;
|
||||
case PSMX_REMOTE_WRITE_CONTEXT:
|
||||
op_context = PSMX_CTXT_USER(fi_context);
|
||||
op_context = NULL;
|
||||
buf = NULL;
|
||||
flags = FI_REMOTE_WRITE | FI_RMA | FI_REMOTE_CQ_DATA;
|
||||
break;
|
||||
@ -847,6 +852,7 @@ int psmx_cq_open(struct fid_domain *domain, struct fi_cq_attr *attr,
|
||||
|
||||
slist_init(&cq_priv->event_queue);
|
||||
slist_init(&cq_priv->free_list);
|
||||
pthread_mutex_init(&cq_priv->mutex, NULL);
|
||||
|
||||
#define PSMX_FREE_LIST_SIZE 64
|
||||
for (i=0; i<PSMX_FREE_LIST_SIZE; i++) {
|
||||
|
@ -119,7 +119,9 @@ int psmx_domain_open(struct fid_fabric *fabric, struct fi_info *info,
|
||||
domain_priv->domain.fid.ops = &psmx_fi_ops;
|
||||
domain_priv->domain.ops = &psmx_domain_ops;
|
||||
domain_priv->domain.mr = &psmx_mr_ops;
|
||||
domain_priv->mr_mode = info->domain_attr->mr_mode;
|
||||
domain_priv->mode = info->mode;
|
||||
domain_priv->caps = info->caps;
|
||||
domain_priv->fabric = fabric_priv;
|
||||
|
||||
psm_ep_open_opts_get_defaults(&opts);
|
||||
@ -127,7 +129,7 @@ int psmx_domain_open(struct fid_fabric *fabric, struct fi_info *info,
|
||||
err = psm_ep_open(fabric_priv->uuid, &opts,
|
||||
&domain_priv->psm_ep, &domain_priv->psm_epid);
|
||||
if (err != PSM_OK) {
|
||||
FI_WARN(&psmx_prov, FI_LOG_CQ,
|
||||
FI_WARN(&psmx_prov, FI_LOG_CORE,
|
||||
"psm_ep_open returns %d, errno=%d\n", err, errno);
|
||||
err = psmx_errno(err);
|
||||
goto err_out_free_domain;
|
||||
@ -136,7 +138,7 @@ int psmx_domain_open(struct fid_fabric *fabric, struct fi_info *info,
|
||||
err = psm_mq_init(domain_priv->psm_ep, PSM_MQ_ORDERMASK_ALL,
|
||||
NULL, 0, &domain_priv->psm_mq);
|
||||
if (err != PSM_OK) {
|
||||
FI_WARN(&psmx_prov, FI_LOG_CQ,
|
||||
FI_WARN(&psmx_prov, FI_LOG_CORE,
|
||||
"psm_mq_init returns %d, errno=%d\n", err, errno);
|
||||
err = psmx_errno(err);
|
||||
goto err_out_close_ep;
|
||||
@ -166,8 +168,12 @@ err_out:
|
||||
|
||||
int psmx_domain_check_features(struct psmx_fid_domain *domain, int ep_cap)
|
||||
{
|
||||
if ((ep_cap & PSMX_CAPS) != ep_cap)
|
||||
return -FI_EINVAL;
|
||||
if ((domain->caps & ep_cap & ~PSMX_SUB_CAPS) != (ep_cap & ~PSMX_SUB_CAPS)) {
|
||||
FI_INFO(&psmx_prov, FI_LOG_CORE,
|
||||
"caps mismatch: domain->caps=%llx, ep->caps=%llx, mask=%llx\n",
|
||||
domain->caps, ep_cap, ~PSMX_SUB_CAPS);
|
||||
return -FI_EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if ((ep_cap & FI_TAGGED) && domain->tagged_ep &&
|
||||
fi_recv_allowed(ep_cap))
|
||||
@ -195,6 +201,13 @@ int psmx_domain_enable_ep(struct psmx_fid_domain *domain, struct psmx_fid_ep *ep
|
||||
if (ep)
|
||||
ep_cap = ep->caps;
|
||||
|
||||
if ((domain->caps & ep_cap & ~PSMX_SUB_CAPS) != (ep_cap & ~PSMX_SUB_CAPS)) {
|
||||
FI_INFO(&psmx_prov, FI_LOG_CORE,
|
||||
"caps mismatch: domain->caps=%llx, ep->caps=%llx, mask=%llx\n",
|
||||
domain->caps, ep_cap, ~PSMX_SUB_CAPS);
|
||||
return -FI_EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (ep_cap & FI_MSG)
|
||||
domain->reserved_tag_bits |= PSMX_MSG_BIT;
|
||||
|
||||
|
@ -40,7 +40,7 @@ static void psmx_ep_optimize_ops(struct psmx_fid_ep *ep)
|
||||
FI_INFO(&psmx_prov, FI_LOG_EP_DATA,
|
||||
"generic tagged ops.\n");
|
||||
}
|
||||
else if (ep->send_cq_event_flag && ep->recv_cq_event_flag) {
|
||||
else if (ep->send_selective_completion && ep->recv_selective_completion) {
|
||||
if (ep->av && ep->av->type == FI_AV_TABLE)
|
||||
ep->ep.tagged = &psmx_tagged_ops_no_event_av_table;
|
||||
else
|
||||
@ -48,7 +48,7 @@ static void psmx_ep_optimize_ops(struct psmx_fid_ep *ep)
|
||||
FI_INFO(&psmx_prov, FI_LOG_EP_DATA,
|
||||
"tagged ops optimized for op_flags=0 and event suppression\n");
|
||||
}
|
||||
else if (ep->send_cq_event_flag) {
|
||||
else if (ep->send_selective_completion) {
|
||||
if (ep->av && ep->av->type == FI_AV_TABLE)
|
||||
ep->ep.tagged = &psmx_tagged_ops_no_send_event_av_table;
|
||||
else
|
||||
@ -56,7 +56,7 @@ static void psmx_ep_optimize_ops(struct psmx_fid_ep *ep)
|
||||
FI_INFO(&psmx_prov, FI_LOG_EP_DATA,
|
||||
"tagged ops optimized for op_flags=0 and send event suppression\n");
|
||||
}
|
||||
else if (ep->recv_cq_event_flag) {
|
||||
else if (ep->recv_selective_completion) {
|
||||
if (ep->av && ep->av->type == FI_AV_TABLE)
|
||||
ep->ep.tagged = &psmx_tagged_ops_no_recv_event_av_table;
|
||||
else
|
||||
@ -177,13 +177,13 @@ static int psmx_ep_bind(struct fid *fid, struct fid *bfid, uint64_t flags)
|
||||
return -FI_EINVAL;
|
||||
if (flags & FI_SEND) {
|
||||
ep->send_cq = cq;
|
||||
if (flags & FI_COMPLETION)
|
||||
ep->send_cq_event_flag = 1;
|
||||
if (flags & FI_SELECTIVE_COMPLETION)
|
||||
ep->send_selective_completion = 1;
|
||||
}
|
||||
if (flags & FI_RECV) {
|
||||
ep->recv_cq = cq;
|
||||
if (flags & FI_COMPLETION)
|
||||
ep->recv_cq_event_flag = 1;
|
||||
if (flags & FI_SELECTIVE_COMPLETION)
|
||||
ep->recv_selective_completion = 1;
|
||||
}
|
||||
psmx_ep_optimize_ops(ep);
|
||||
break;
|
||||
@ -276,6 +276,16 @@ static int psmx_ep_control(fid_t fid, int command, void *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t psmx_rx_size_left(struct fid_ep *ep)
|
||||
{
|
||||
return 0x7fffffff; /* a random choice */
|
||||
}
|
||||
|
||||
static ssize_t psmx_tx_size_left(struct fid_ep *ep)
|
||||
{
|
||||
return 0x7fffffff; /* a random choice */
|
||||
}
|
||||
|
||||
static struct fi_ops psmx_fi_ops = {
|
||||
.size = sizeof(struct fi_ops),
|
||||
.close = psmx_ep_close,
|
||||
@ -291,8 +301,8 @@ static struct fi_ops_ep psmx_ep_ops = {
|
||||
.setopt = psmx_ep_setopt,
|
||||
.tx_ctx = fi_no_tx_ctx,
|
||||
.rx_ctx = fi_no_rx_ctx,
|
||||
.rx_size_left = fi_no_rx_size_left,
|
||||
.tx_size_left = fi_no_tx_size_left,
|
||||
.rx_size_left = psmx_rx_size_left,
|
||||
.tx_size_left = psmx_tx_size_left,
|
||||
};
|
||||
|
||||
int psmx_ep_open(struct fid_domain *domain, struct fi_info *info,
|
||||
|
434
opal/mca/common/libfabric/libfabric/prov/psm/src/psmx_eq.c
Обычный файл
434
opal/mca/common/libfabric/libfabric/prov/psm/src/psmx_eq.c
Обычный файл
@ -0,0 +1,434 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014 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
|
||||
* 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 "psmx.h"
|
||||
|
||||
void psmx_eq_enqueue_event(struct psmx_fid_eq *eq, struct psmx_eq_event *event)
|
||||
{
|
||||
pthread_mutex_lock(&eq->mutex);
|
||||
if (event->error)
|
||||
slist_insert_tail(&event->list_entry, &eq->error_queue);
|
||||
else
|
||||
slist_insert_tail(&event->list_entry, &eq->event_queue);
|
||||
pthread_mutex_unlock(&eq->mutex);
|
||||
|
||||
if (eq->wait)
|
||||
psmx_wait_signal((struct fid_wait *)eq->wait);
|
||||
}
|
||||
|
||||
static struct psmx_eq_event *psmx_eq_dequeue_event(struct psmx_fid_eq *eq)
|
||||
{
|
||||
struct slist_entry *entry;
|
||||
|
||||
if (slist_empty(&eq->event_queue))
|
||||
return NULL;
|
||||
|
||||
pthread_mutex_lock(&eq->mutex);
|
||||
entry = slist_remove_head(&eq->event_queue);
|
||||
pthread_mutex_unlock(&eq->mutex);
|
||||
|
||||
return container_of(entry, struct psmx_eq_event, list_entry);
|
||||
}
|
||||
|
||||
static struct psmx_eq_event *psmx_eq_dequeue_error(struct psmx_fid_eq *eq)
|
||||
{
|
||||
struct slist_entry *entry;
|
||||
|
||||
if (slist_empty(&eq->error_queue))
|
||||
return NULL;
|
||||
|
||||
pthread_mutex_lock(&eq->mutex);
|
||||
entry = slist_remove_head(&eq->error_queue);
|
||||
pthread_mutex_unlock(&eq->mutex);
|
||||
|
||||
return container_of(entry, struct psmx_eq_event, list_entry);
|
||||
}
|
||||
|
||||
static struct psmx_eq_event *psmx_eq_peek_event(struct psmx_fid_eq *eq)
|
||||
{
|
||||
if (slist_empty(&eq->event_queue))
|
||||
return NULL;
|
||||
|
||||
return container_of(eq->event_queue.head, struct psmx_eq_event, list_entry);
|
||||
}
|
||||
|
||||
static struct psmx_eq_event *psmx_eq_alloc_event(struct psmx_fid_eq *eq)
|
||||
{
|
||||
struct psmx_eq_event *event;
|
||||
|
||||
if (!slist_empty(&eq->free_list)) {
|
||||
event = container_of(slist_remove_head(&eq->free_list),
|
||||
struct psmx_eq_event, list_entry);
|
||||
}
|
||||
else {
|
||||
event = calloc(1, sizeof(*event));
|
||||
if (!event) {
|
||||
FI_WARN(&psmx_prov, FI_LOG_EQ, "out of memory.\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
static void psmx_eq_free_event(struct psmx_fid_eq *eq, struct psmx_eq_event *event)
|
||||
{
|
||||
memset(event, 0, sizeof(*event));
|
||||
slist_insert_tail(&event->list_entry, &eq->free_list);
|
||||
}
|
||||
|
||||
struct psmx_eq_event *psmx_eq_create_event(struct psmx_fid_eq *eq,
|
||||
uint32_t event_num,
|
||||
void *context,
|
||||
uint64_t data,
|
||||
int err,
|
||||
int prov_errno,
|
||||
void *err_data,
|
||||
size_t err_data_size)
|
||||
{
|
||||
struct psmx_eq_event *event;
|
||||
|
||||
event = psmx_eq_alloc_event(eq);
|
||||
if (!event)
|
||||
return NULL;
|
||||
|
||||
event->event = event_num;
|
||||
event->eqe.data.fid = &eq->fabric->fabric.fid;
|
||||
|
||||
if ((event->error = !!err)) {
|
||||
event->eqe.err.context = context;
|
||||
event->eqe.err.data = data;
|
||||
event->eqe.err.err = -err;
|
||||
event->eqe.err.prov_errno = prov_errno;
|
||||
event->eqe.err.err_data = err_data;
|
||||
event->eqe.err.err_data_size = err_data_size;
|
||||
event->entry_size = sizeof(event->eqe.err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (event_num) {
|
||||
case FI_NOTIFY:
|
||||
event->eqe.data.context = context;
|
||||
event->eqe.data.data = data;
|
||||
event->entry_size = sizeof(event->eqe.data);
|
||||
break;
|
||||
|
||||
case FI_CONNREQ:
|
||||
case FI_CONNECTED:
|
||||
case FI_SHUTDOWN:
|
||||
event->eqe.cm.info = context;
|
||||
/* TODO: store event->eqe.cm.data (upto sizeof(eqe)-sizeof(eqe.cm) bytes) */
|
||||
event->entry_size = sizeof(event->eqe.cm) + 0; /* TODO: extra data size */
|
||||
break;
|
||||
|
||||
case FI_MR_COMPLETE:
|
||||
case FI_AV_COMPLETE:
|
||||
event->eqe.data.context = context;
|
||||
event->eqe.data.data = data;
|
||||
event->entry_size = sizeof(event->eqe.data);
|
||||
break;
|
||||
|
||||
default:
|
||||
psmx_eq_free_event(eq, event);
|
||||
FI_WARN(&psmx_prov, FI_LOG_EQ, "invalid event %d.\n", event_num);
|
||||
event = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
return event;
|
||||
}
|
||||
|
||||
static ssize_t psmx_eq_read(struct fid_eq *eq, uint32_t *event_num, void *buf,
|
||||
size_t len, uint64_t flags)
|
||||
{
|
||||
struct psmx_fid_eq *eq_priv;
|
||||
struct psmx_eq_event *event;
|
||||
ssize_t bytes_read = 0;
|
||||
|
||||
eq_priv = container_of(eq, struct psmx_fid_eq, eq);
|
||||
|
||||
if (slist_empty(&eq_priv->event_queue))
|
||||
psmx_progress(eq_priv->fabric->active_domain);
|
||||
|
||||
if (!slist_empty(&eq_priv->error_queue))
|
||||
return -FI_EAVAIL;
|
||||
|
||||
if (flags & FI_PEEK)
|
||||
event = psmx_eq_peek_event(eq_priv);
|
||||
else
|
||||
event = psmx_eq_dequeue_event(eq_priv);
|
||||
|
||||
if (!event)
|
||||
return -FI_EAGAIN;
|
||||
|
||||
*event_num = event->event;
|
||||
if (buf) {
|
||||
bytes_read = MIN(len, event->entry_size);
|
||||
memcpy(buf, (void *)&event->eqe, bytes_read);
|
||||
}
|
||||
|
||||
if (!(flags & FI_PEEK))
|
||||
psmx_eq_free_event(eq_priv, event);
|
||||
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
static ssize_t psmx_eq_readerr(struct fid_eq *eq, struct fi_eq_err_entry *buf,
|
||||
uint64_t flags)
|
||||
{
|
||||
struct psmx_fid_eq *eq_priv;
|
||||
struct psmx_eq_event *event;
|
||||
ssize_t bytes_read = 0;
|
||||
|
||||
eq_priv = container_of(eq, struct psmx_fid_eq, eq);
|
||||
|
||||
event = psmx_eq_dequeue_error(eq_priv);
|
||||
if (!event)
|
||||
return -FI_EAGAIN;
|
||||
|
||||
if (buf) {
|
||||
bytes_read = sizeof(*buf);
|
||||
memcpy(buf, &event->eqe.err, bytes_read);
|
||||
psmx_eq_free_event(eq_priv, event);
|
||||
}
|
||||
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
static ssize_t psmx_eq_sread(struct fid_eq *eq, uint32_t *event, void *buf,
|
||||
size_t len, int timeout, uint64_t flags)
|
||||
{
|
||||
struct psmx_fid_eq *eq_priv;
|
||||
struct timespec ts0, ts;
|
||||
int msec_passed = 0;
|
||||
ssize_t ret = -FI_EAGAIN;
|
||||
|
||||
eq_priv = container_of(eq, struct psmx_fid_eq, eq);
|
||||
|
||||
if (eq_priv->wait) {
|
||||
psmx_wait_wait((struct fid_wait *)eq_priv->wait, timeout);
|
||||
ret = psmx_eq_read(eq, event, buf, len, flags);
|
||||
}
|
||||
else {
|
||||
clock_gettime(CLOCK_REALTIME, &ts0);
|
||||
while (1) {
|
||||
ret = psmx_eq_read(eq, event, buf, len, flags);
|
||||
if (ret != -FI_EAGAIN)
|
||||
break;
|
||||
|
||||
if (timeout < 0)
|
||||
continue;
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
msec_passed = (ts.tv_sec - ts0.tv_sec) * 1000 +
|
||||
(ts.tv_nsec - ts0.tv_nsec) / 1000000;
|
||||
|
||||
if (msec_passed >= timeout)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t psmx_eq_write(struct fid_eq *eq, uint32_t event_num, const void *buf,
|
||||
size_t len, uint64_t flags)
|
||||
{
|
||||
struct psmx_fid_eq *eq_priv;
|
||||
struct psmx_eq_event *event;
|
||||
ssize_t bytes_written;
|
||||
|
||||
eq_priv = container_of(eq, struct psmx_fid_eq, eq);
|
||||
|
||||
event = psmx_eq_alloc_event(eq_priv);
|
||||
if (!event)
|
||||
return -FI_ENOMEM;
|
||||
|
||||
bytes_written = MIN(len, sizeof(event->eqe));
|
||||
|
||||
event->event = event_num;
|
||||
event->entry_size = bytes_written;
|
||||
memcpy(&event->eqe, buf, bytes_written);
|
||||
|
||||
psmx_eq_enqueue_event(eq_priv, event);
|
||||
|
||||
if (eq_priv->wait)
|
||||
psmx_wait_signal((struct fid_wait *)eq_priv->wait);
|
||||
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
static const char *psmx_eq_strerror(struct fid_eq *eq, int prov_errno,
|
||||
const void *err_data, char *buf, size_t len)
|
||||
{
|
||||
return psm_error_get_string(prov_errno);
|
||||
}
|
||||
|
||||
static int psmx_eq_close(fid_t fid)
|
||||
{
|
||||
struct psmx_fid_eq *eq;
|
||||
struct slist_entry *entry;
|
||||
struct psmx_eq_event *item;
|
||||
|
||||
eq = container_of(fid, struct psmx_fid_eq, eq.fid);
|
||||
|
||||
while (!slist_empty(&eq->free_list)) {
|
||||
entry = slist_remove_head(&eq->free_list);
|
||||
item = container_of(entry, struct psmx_eq_event, list_entry);
|
||||
free(item);
|
||||
}
|
||||
|
||||
if (eq->wait && eq->wait_is_local)
|
||||
fi_close((fid_t)eq->wait);
|
||||
|
||||
free(eq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int psmx_eq_control(struct fid *fid, int command, void *arg)
|
||||
{
|
||||
struct psmx_fid_eq *eq;
|
||||
int ret = 0;
|
||||
|
||||
eq = container_of(fid, struct psmx_fid_eq, eq.fid);
|
||||
|
||||
switch (command) {
|
||||
case FI_GETWAIT:
|
||||
ret = psmx_wait_get_obj(eq->wait, arg);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -FI_ENOSYS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct fi_ops psmx_fi_ops = {
|
||||
.size = sizeof(struct fi_ops),
|
||||
.close = psmx_eq_close,
|
||||
.bind = fi_no_bind,
|
||||
.control = psmx_eq_control,
|
||||
.ops_open = fi_no_ops_open,
|
||||
};
|
||||
|
||||
static struct fi_ops_eq psmx_eq_ops = {
|
||||
.size = sizeof(struct fi_ops_eq),
|
||||
.read = psmx_eq_read,
|
||||
.readerr = psmx_eq_readerr,
|
||||
.sread = psmx_eq_sread,
|
||||
.write = psmx_eq_write,
|
||||
.strerror = psmx_eq_strerror,
|
||||
};
|
||||
|
||||
int psmx_eq_open(struct fid_fabric *fabric, struct fi_eq_attr *attr,
|
||||
struct fid_eq **eq, void *context)
|
||||
{
|
||||
struct psmx_fid_fabric *fabric_priv;
|
||||
struct psmx_fid_eq *eq_priv;
|
||||
struct psmx_fid_wait *wait = NULL;
|
||||
struct psmx_eq_event *event;
|
||||
struct fi_wait_attr wait_attr;
|
||||
int wait_is_local = 0;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
fabric_priv = container_of(fabric, struct psmx_fid_fabric, fabric);
|
||||
|
||||
switch (attr->wait_obj) {
|
||||
case FI_WAIT_NONE:
|
||||
case FI_WAIT_UNSPEC:
|
||||
break;
|
||||
|
||||
case FI_WAIT_SET:
|
||||
if (!attr->wait_set) {
|
||||
FI_INFO(&psmx_prov, FI_LOG_EQ,
|
||||
"FI_WAIT_SET is specified but attr->wait_set is NULL\n");
|
||||
return -FI_EINVAL;
|
||||
}
|
||||
wait = (struct psmx_fid_wait *)attr->wait_set;
|
||||
break;
|
||||
|
||||
case FI_WAIT_FD:
|
||||
case FI_WAIT_MUTEX_COND:
|
||||
wait_attr.wait_obj = attr->wait_obj;
|
||||
wait_attr.flags = 0;
|
||||
err = psmx_wait_open(fabric, &wait_attr, (struct fid_wait **)&wait);
|
||||
if (err)
|
||||
return err;
|
||||
wait_is_local = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
FI_INFO(&psmx_prov, FI_LOG_EQ,
|
||||
"attr->wait_obj=%d, supported=%d...%d\n", attr->wait_obj,
|
||||
FI_WAIT_NONE, FI_WAIT_MUTEX_COND);
|
||||
return -FI_EINVAL;
|
||||
}
|
||||
|
||||
eq_priv = (struct psmx_fid_eq *) calloc(1, sizeof *eq_priv);
|
||||
if (!eq_priv) {
|
||||
if (wait)
|
||||
free(wait);
|
||||
return -FI_ENOMEM;
|
||||
}
|
||||
|
||||
eq_priv->fabric = fabric_priv;
|
||||
eq_priv->wait = wait;
|
||||
eq_priv->wait_is_local = wait_is_local;
|
||||
|
||||
eq_priv->eq.fid.fclass = FI_CLASS_EQ;
|
||||
eq_priv->eq.fid.context = context;
|
||||
eq_priv->eq.fid.ops = &psmx_fi_ops;
|
||||
eq_priv->eq.ops = &psmx_eq_ops;
|
||||
|
||||
slist_init(&eq_priv->event_queue);
|
||||
slist_init(&eq_priv->error_queue);
|
||||
slist_init(&eq_priv->free_list);
|
||||
pthread_mutex_init(&eq_priv->mutex, NULL);
|
||||
|
||||
#define PSMX_FREE_LIST_SIZE 64
|
||||
for (i=0; i<PSMX_FREE_LIST_SIZE; i++) {
|
||||
event = calloc(1, sizeof(*event));
|
||||
if (!event) {
|
||||
FI_WARN(&psmx_prov, FI_LOG_EQ, "out of memory.\n");
|
||||
exit(-1);
|
||||
}
|
||||
slist_insert_tail(&event->list_entry, &eq_priv->free_list);
|
||||
}
|
||||
|
||||
*eq = &eq_priv->eq;
|
||||
return 0;
|
||||
}
|
||||
|
@ -106,6 +106,8 @@ static int psmx_getinfo(uint32_t version, const char *node, const char *service,
|
||||
uint32_t cnt = 0;
|
||||
void *dest_addr = NULL;
|
||||
int ep_type = FI_EP_RDM;
|
||||
int av_type = FI_AV_UNSPEC;
|
||||
enum fi_mr_mode mr_mode = FI_MR_SCALABLE;
|
||||
int caps = 0;
|
||||
uint64_t max_tag_value = 0;
|
||||
int err = -FI_ENODATA;
|
||||
@ -124,6 +126,17 @@ static int psmx_getinfo(uint32_t version, const char *node, const char *service,
|
||||
dest_addr = psmx_resolve_name(node, 0);
|
||||
|
||||
if (hints) {
|
||||
switch (hints->addr_format) {
|
||||
case FI_FORMAT_UNSPEC:
|
||||
case FI_ADDR_PSMX:
|
||||
break;
|
||||
default:
|
||||
FI_INFO(&psmx_prov, FI_LOG_CORE,
|
||||
"hints->addr_format=%d, supported=%d,%d.\n",
|
||||
hints->addr_format, FI_FORMAT_UNSPEC, FI_ADDR_PSMX);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (hints->ep_attr) {
|
||||
switch (hints->ep_attr->type) {
|
||||
case FI_EP_UNSPEC:
|
||||
@ -217,12 +230,44 @@ static int psmx_getinfo(uint32_t version, const char *node, const char *service,
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (hints->domain_attr && hints->domain_attr->name &&
|
||||
strncmp(hints->domain_attr->name, PSMX_DOMAIN_NAME, PSMX_DOMAIN_NAME_LEN)) {
|
||||
FI_INFO(&psmx_prov, FI_LOG_CORE,
|
||||
"hints->domain_name=%s, supported=psm\n",
|
||||
hints->domain_attr->name);
|
||||
goto err_out;
|
||||
if (hints->domain_attr) {
|
||||
if (hints->domain_attr->name &&
|
||||
strncmp(hints->domain_attr->name, PSMX_DOMAIN_NAME,
|
||||
PSMX_DOMAIN_NAME_LEN)) {
|
||||
FI_INFO(&psmx_prov, FI_LOG_CORE,
|
||||
"hints->domain_name=%s, supported=psm\n",
|
||||
hints->domain_attr->name);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
switch (hints->domain_attr->av_type) {
|
||||
case FI_AV_UNSPEC:
|
||||
case FI_AV_MAP:
|
||||
case FI_AV_TABLE:
|
||||
av_type = hints->domain_attr->av_type;
|
||||
break;
|
||||
default:
|
||||
FI_INFO(&psmx_prov, FI_LOG_CORE,
|
||||
"hints->domain_attr->av_type=%d, supported=%d %d %d\n",
|
||||
hints->domain_attr->av_type, FI_AV_UNSPEC, FI_AV_MAP,
|
||||
FI_AV_TABLE);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
switch (hints->domain_attr->mr_mode) {
|
||||
case FI_MR_UNSPEC:
|
||||
break;
|
||||
case FI_MR_BASIC:
|
||||
case FI_MR_SCALABLE:
|
||||
mr_mode = hints->domain_attr->mr_mode;
|
||||
break;
|
||||
default:
|
||||
FI_INFO(&psmx_prov, FI_LOG_CORE,
|
||||
"hints->domain_attr->mr_mode=%d, supported=%d %d %d\n",
|
||||
hints->domain_attr->mr_mode, FI_MR_UNSPEC, FI_MR_BASIC,
|
||||
FI_MR_SCALABLE);
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
|
||||
if (hints->ep_attr) {
|
||||
@ -253,6 +298,7 @@ static int psmx_getinfo(uint32_t version, const char *node, const char *service,
|
||||
|
||||
psmx_info->ep_attr->type = ep_type;
|
||||
psmx_info->ep_attr->protocol = FI_PROTO_PSMX;
|
||||
psmx_info->ep_attr->protocol_version = PSM_VERNO;
|
||||
psmx_info->ep_attr->max_msg_size = PSMX_MAX_MSG_SIZE;
|
||||
psmx_info->ep_attr->mem_tag_format = fi_tag_format(max_tag_value);
|
||||
psmx_info->ep_attr->tx_ctx_cnt = 1;
|
||||
@ -262,6 +308,19 @@ static int psmx_getinfo(uint32_t version, const char *node, const char *service,
|
||||
psmx_info->domain_attr->control_progress = FI_PROGRESS_MANUAL;
|
||||
psmx_info->domain_attr->data_progress = FI_PROGRESS_MANUAL;
|
||||
psmx_info->domain_attr->name = strdup(PSMX_DOMAIN_NAME);
|
||||
psmx_info->domain_attr->resource_mgmt = FI_RM_ENABLED;
|
||||
psmx_info->domain_attr->av_type = av_type;
|
||||
psmx_info->domain_attr->mr_mode = mr_mode;
|
||||
psmx_info->domain_attr->mr_key_size = sizeof(uint64_t);
|
||||
psmx_info->domain_attr->cq_data_size = 4;
|
||||
psmx_info->domain_attr->cq_cnt = 65535;
|
||||
psmx_info->domain_attr->ep_cnt = 65535;
|
||||
psmx_info->domain_attr->tx_ctx_cnt = 1;
|
||||
psmx_info->domain_attr->rx_ctx_cnt = 1;
|
||||
psmx_info->domain_attr->max_ep_tx_ctx = 65535;
|
||||
psmx_info->domain_attr->max_ep_rx_ctx = 1;
|
||||
psmx_info->domain_attr->max_ep_stx_ctx = 65535;
|
||||
psmx_info->domain_attr->max_ep_srx_ctx = 0;
|
||||
|
||||
psmx_info->next = NULL;
|
||||
psmx_info->caps = (hints && hints->caps) ? hints->caps : caps;
|
||||
@ -328,7 +387,7 @@ static struct fi_ops_fabric psmx_fabric_ops = {
|
||||
.size = sizeof(struct fi_ops_fabric),
|
||||
.domain = psmx_domain_open,
|
||||
.passive_ep = fi_no_passive_ep,
|
||||
.eq_open = fi_no_eq_open,
|
||||
.eq_open = psmx_eq_open,
|
||||
.wait_open = psmx_wait_open,
|
||||
};
|
||||
|
||||
|
@ -267,9 +267,7 @@ static int psmx_mr_reg(struct fid *fid, const void *buf, size_t len,
|
||||
domain = container_of(fid, struct fid_domain, fid);
|
||||
|
||||
domain_priv = container_of(domain, struct psmx_fid_domain, domain);
|
||||
if (flags & FI_MR_KEY) {
|
||||
if (domain_priv->mode & FI_PROV_MR_ATTR)
|
||||
return -FI_EBADFLAGS;
|
||||
if (domain_priv->mr_mode == FI_MR_SCALABLE) {
|
||||
if (psmx_mr_hash_get(requested_key))
|
||||
return -FI_ENOKEY;
|
||||
}
|
||||
@ -282,10 +280,9 @@ static int psmx_mr_reg(struct fid *fid, const void *buf, size_t len,
|
||||
mr_priv->mr.fid.context = context;
|
||||
mr_priv->mr.fid.ops = &psmx_fi_ops;
|
||||
mr_priv->mr.mem_desc = mr_priv;
|
||||
if (flags & FI_MR_KEY) {
|
||||
if (domain_priv->mr_mode == FI_MR_SCALABLE) {
|
||||
key = requested_key;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
key = (uint64_t)(uintptr_t)mr_priv;
|
||||
while (psmx_mr_hash_get(key))
|
||||
key++;
|
||||
@ -297,7 +294,7 @@ static int psmx_mr_reg(struct fid *fid, const void *buf, size_t len,
|
||||
mr_priv->iov_count = 1;
|
||||
mr_priv->iov[0].iov_base = (void *)buf;
|
||||
mr_priv->iov[0].iov_len = len;
|
||||
mr_priv->offset = (flags & FI_MR_OFFSET) ?
|
||||
mr_priv->offset = (domain_priv->mr_mode == FI_MR_SCALABLE) ?
|
||||
((uint64_t)mr_priv->iov[0].iov_base - offset) :
|
||||
0;
|
||||
|
||||
@ -325,9 +322,7 @@ static int psmx_mr_regv(struct fid *fid,
|
||||
domain = container_of(fid, struct fid_domain, fid);
|
||||
|
||||
domain_priv = container_of(domain, struct psmx_fid_domain, domain);
|
||||
if (flags & FI_MR_KEY) {
|
||||
if (domain_priv->mode & FI_PROV_MR_ATTR)
|
||||
return -FI_EBADFLAGS;
|
||||
if (domain_priv->mr_mode == FI_MR_SCALABLE) {
|
||||
if (psmx_mr_hash_get(requested_key))
|
||||
return -FI_ENOKEY;
|
||||
}
|
||||
@ -345,10 +340,9 @@ static int psmx_mr_regv(struct fid *fid,
|
||||
mr_priv->mr.fid.context = context;
|
||||
mr_priv->mr.fid.ops = &psmx_fi_ops;
|
||||
mr_priv->mr.mem_desc = mr_priv;
|
||||
if (flags & FI_MR_KEY) {
|
||||
if (domain_priv->mr_mode == FI_MR_SCALABLE) {
|
||||
key = requested_key;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
key = (uint64_t)(uintptr_t)mr_priv;
|
||||
while (psmx_mr_hash_get(key))
|
||||
key++;
|
||||
@ -361,7 +355,7 @@ static int psmx_mr_regv(struct fid *fid,
|
||||
for (i=0; i<count; i++)
|
||||
mr_priv->iov[i] = iov[i];
|
||||
psmx_mr_normalize_iov(mr_priv->iov, &mr_priv->iov_count);
|
||||
mr_priv->offset = (flags & FI_MR_OFFSET) ?
|
||||
mr_priv->offset = (domain_priv->mr_mode == FI_MR_SCALABLE) ?
|
||||
((uint64_t)mr_priv->iov[0].iov_base - offset) :
|
||||
0;
|
||||
|
||||
@ -387,9 +381,7 @@ static int psmx_mr_regattr(struct fid *fid, const struct fi_mr_attr *attr,
|
||||
domain = container_of(fid, struct fid_domain, fid);
|
||||
|
||||
domain_priv = container_of(domain, struct psmx_fid_domain, domain);
|
||||
if (flags & FI_MR_KEY) {
|
||||
if (domain_priv->mode & FI_PROV_MR_ATTR)
|
||||
return -FI_EBADFLAGS;
|
||||
if (domain_priv->mr_mode == FI_MR_SCALABLE) {
|
||||
if (psmx_mr_hash_get(attr->requested_key))
|
||||
return -FI_ENOKEY;
|
||||
}
|
||||
@ -410,10 +402,9 @@ static int psmx_mr_regattr(struct fid *fid, const struct fi_mr_attr *attr,
|
||||
mr_priv->mr.fid.context = attr->context;
|
||||
mr_priv->mr.fid.ops = &psmx_fi_ops;
|
||||
mr_priv->mr.mem_desc = mr_priv;
|
||||
if (flags & FI_MR_KEY) {
|
||||
if (domain_priv->mr_mode == FI_MR_SCALABLE) {
|
||||
key = attr->requested_key;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
key = (uint64_t)(uintptr_t)mr_priv;
|
||||
while (psmx_mr_hash_get(key))
|
||||
key++;
|
||||
@ -426,7 +417,7 @@ static int psmx_mr_regattr(struct fid *fid, const struct fi_mr_attr *attr,
|
||||
for (i=0; i<attr->iov_count; i++)
|
||||
mr_priv->iov[i] = attr->mr_iov[i];
|
||||
psmx_mr_normalize_iov(mr_priv->iov, &mr_priv->iov_count);
|
||||
mr_priv->offset = (flags & FI_MR_OFFSET) ?
|
||||
mr_priv->offset = (domain_priv->mr_mode == FI_MR_SCALABLE) ?
|
||||
((uint64_t)mr_priv->iov[0].iov_base - attr->offset) :
|
||||
0;
|
||||
|
||||
|
@ -90,7 +90,7 @@ ssize_t _psmx_recv(struct fid_ep *ep, void *buf, size_t len,
|
||||
psm_tagsel = PSMX_MSG_BIT;
|
||||
}
|
||||
|
||||
if (ep_priv->recv_cq_event_flag && !(flags & FI_COMPLETION) && !context) {
|
||||
if (ep_priv->recv_selective_completion && !(flags & FI_COMPLETION) && !context) {
|
||||
fi_context = &ep_priv->nocomp_recv_context;
|
||||
}
|
||||
else {
|
||||
@ -245,7 +245,7 @@ ssize_t _psmx_send(struct fid_ep *ep, const void *buf, size_t len,
|
||||
psm_tag = ep_priv->domain->psm_epid | PSMX_MSG_BIT;
|
||||
|
||||
if ((flags & PSMX_NO_COMPLETION) ||
|
||||
(ep_priv->send_cq_event_flag && !(flags & FI_COMPLETION)))
|
||||
(ep_priv->send_selective_completion && !(flags & FI_COMPLETION)))
|
||||
no_completion = 1;
|
||||
|
||||
if (flags & FI_INJECT) {
|
||||
|
@ -332,7 +332,7 @@ int psmx_am_process_send(struct psmx_fid_domain *domain, struct psmx_am_request
|
||||
err = psm_am_request_short((psm_epaddr_t) req->send.dest_addr,
|
||||
PSMX_AM_MSG_HANDLER, args, 4,
|
||||
req->send.buf+offset, chunk_size,
|
||||
am_flags | PSM_AM_FLAG_NOREPLY, NULL, NULL);
|
||||
am_flags, NULL, NULL);
|
||||
|
||||
len -= chunk_size;
|
||||
offset += chunk_size;
|
||||
@ -395,7 +395,7 @@ static ssize_t _psmx_recv2(struct fid_ep *ep, void *buf, size_t len,
|
||||
req->ep = ep_priv;
|
||||
req->cq_flags = FI_RECV | FI_MSG;
|
||||
|
||||
if (ep_priv->recv_cq_event_flag && !(flags & FI_COMPLETION))
|
||||
if (ep_priv->recv_selective_completion && !(flags & FI_COMPLETION))
|
||||
req->no_event = 1;
|
||||
|
||||
unexp = psmx_am_search_and_dequeue_unexp(ep_priv->domain,
|
||||
@ -553,7 +553,7 @@ static ssize_t _psmx_send2(struct fid_ep *ep, const void *buf, size_t len,
|
||||
req->cq_flags = FI_SEND | FI_MSG;
|
||||
|
||||
if ((flags & PSMX_NO_COMPLETION) ||
|
||||
(ep_priv->send_cq_event_flag && !(flags & FI_COMPLETION)))
|
||||
(ep_priv->send_selective_completion && !(flags & FI_COMPLETION)))
|
||||
req->no_event = 1;
|
||||
|
||||
args[0].u32w0 = PSMX_AM_REQ_SEND | (msg_size == len ? PSMX_AM_EOM : 0);
|
||||
|
@ -50,7 +50,7 @@ static inline void psmx_am_enqueue_rma(struct psmx_fid_domain *domain,
|
||||
* args[2].u64 addr
|
||||
* args[3].u64 key
|
||||
* args[4].u64 data (optional) / tag(long protocol)
|
||||
* args[5].u64 <unused> / data (optional, long protocol)
|
||||
* payload <unused> / data (optional, long protocol)
|
||||
*
|
||||
* Write REP:
|
||||
* args[0].u32w0 cmd, flag
|
||||
@ -146,7 +146,7 @@ int psmx_am_rma_handler(psm_am_token_t token, psm_epaddr_t epaddr,
|
||||
key = args[3].u64;
|
||||
mr = psmx_mr_hash_get(key);
|
||||
op_error = mr ?
|
||||
psmx_mr_validate(mr, (uint64_t)rma_addr, len, FI_REMOTE_WRITE) :
|
||||
psmx_mr_validate(mr, (uint64_t)rma_addr, rma_len, FI_REMOTE_WRITE) :
|
||||
-FI_EINVAL;
|
||||
if (op_error) {
|
||||
rep_args[0].u32w0 = PSMX_AM_REP_WRITE | eom;
|
||||
@ -172,7 +172,7 @@ int psmx_am_rma_handler(psm_am_token_t token, psm_epaddr_t epaddr,
|
||||
req->write.context = (void *)args[4].u64;
|
||||
req->write.peer_context = (void *)args[1].u64;
|
||||
req->write.peer_addr = (void *)epaddr;
|
||||
req->write.data = has_data ? args[5].u64 : 0;
|
||||
req->write.data = has_data ? *(uint64_t *)src: 0;
|
||||
req->cq_flags = FI_REMOTE_WRITE | FI_RMA | (has_data ? FI_REMOTE_CQ_DATA : 0),
|
||||
PSMX_CTXT_TYPE(&req->fi_context) = PSMX_REMOTE_WRITE_CONTEXT;
|
||||
PSMX_CTXT_USER(&req->fi_context) = mr;
|
||||
@ -217,7 +217,7 @@ int psmx_am_rma_handler(psm_am_token_t token, psm_epaddr_t epaddr,
|
||||
key = args[3].u64;
|
||||
mr = psmx_mr_hash_get(key);
|
||||
op_error = mr ?
|
||||
psmx_mr_validate(mr, (uint64_t)rma_addr, len, FI_REMOTE_WRITE) :
|
||||
psmx_mr_validate(mr, (uint64_t)rma_addr, rma_len, FI_REMOTE_READ) :
|
||||
-FI_EINVAL;
|
||||
if (op_error) {
|
||||
rep_args[0].u32w0 = PSMX_AM_REP_READ | eom;
|
||||
@ -401,7 +401,7 @@ static ssize_t psmx_rma_self(int am_cmd,
|
||||
}
|
||||
|
||||
no_event = (flags & PSMX_NO_COMPLETION) ||
|
||||
(ep->send_cq_event_flag && !(flags & FI_COMPLETION));
|
||||
(ep->send_selective_completion && !(flags & FI_COMPLETION));
|
||||
|
||||
if (ep->send_cq && !no_event) {
|
||||
event = psmx_cq_create_event(
|
||||
@ -551,7 +551,7 @@ ssize_t _psmx_read(struct fid_ep *ep, void *buf, size_t len,
|
||||
PSMX_CTXT_USER(&req->fi_context) = context;
|
||||
PSMX_CTXT_EP(&req->fi_context) = ep_priv;
|
||||
|
||||
if (ep_priv->send_cq_event_flag && !(flags & FI_COMPLETION)) {
|
||||
if (ep_priv->send_selective_completion && !(flags & FI_COMPLETION)) {
|
||||
PSMX_CTXT_TYPE(&req->fi_context) = PSMX_NOCOMP_READ_CONTEXT;
|
||||
req->no_event = 1;
|
||||
}
|
||||
@ -571,7 +571,7 @@ ssize_t _psmx_read(struct fid_ep *ep, void *buf, size_t len,
|
||||
args[4].u64 = psm_tag;
|
||||
psm_am_request_short((psm_epaddr_t) src_addr,
|
||||
PSMX_AM_RMA_HANDLER, args, 5, NULL, 0,
|
||||
PSM_AM_FLAG_NOREPLY, NULL, NULL);
|
||||
0, NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -708,7 +708,7 @@ ssize_t _psmx_write(struct fid_ep *ep, const void *buf, size_t len,
|
||||
addr, key, context, flags, data);
|
||||
|
||||
no_event = (flags & PSMX_NO_COMPLETION) ||
|
||||
(ep_priv->send_cq_event_flag && !(flags & FI_COMPLETION));
|
||||
(ep_priv->send_selective_completion && !(flags & FI_COMPLETION));
|
||||
|
||||
if (flags & FI_INJECT) {
|
||||
if (len > PSMX_INJECT_SIZE)
|
||||
@ -747,6 +747,9 @@ ssize_t _psmx_write(struct fid_ep *ep, const void *buf, size_t len,
|
||||
chunk_size = MIN(PSMX_AM_CHUNK_SIZE, psmx_am_param.max_request_short);
|
||||
|
||||
if (psmx_env.tagged_rma && len > chunk_size) {
|
||||
void *payload = NULL;
|
||||
int payload_len = 0;
|
||||
|
||||
psm_tag = PSMX_RMA_BIT | ep_priv->domain->psm_epid;
|
||||
args[0].u32w0 = PSMX_AM_REQ_WRITE_LONG;
|
||||
args[0].u32w1 = len;
|
||||
@ -756,12 +759,13 @@ ssize_t _psmx_write(struct fid_ep *ep, const void *buf, size_t len,
|
||||
args[4].u64 = psm_tag;
|
||||
nargs = 5;
|
||||
if (flags & FI_REMOTE_CQ_DATA) {
|
||||
args[5].u64 = data;
|
||||
args[0].u32w0 |= PSMX_AM_DATA;
|
||||
nargs++;
|
||||
payload = &data;
|
||||
payload_len = sizeof(data);
|
||||
am_flags = 0;
|
||||
}
|
||||
|
||||
if (flags & FI_COMMIT_COMPLETE) {
|
||||
if (flags & FI_DELIVERY_COMPLETE) {
|
||||
args[0].u32w0 |= PSMX_AM_FORCE_ACK;
|
||||
psm_context = NULL;
|
||||
}
|
||||
@ -769,9 +773,14 @@ ssize_t _psmx_write(struct fid_ep *ep, const void *buf, size_t len,
|
||||
psm_context = (void *)&req->fi_context;
|
||||
}
|
||||
|
||||
/* NOTE: if nargs is greater than 5, the following psm_mq_isend
|
||||
* would hang if the destination is on the same node (i.e. going
|
||||
* through the shared memory path). As the result, the immediate
|
||||
* data is sent as payload instead of args[5].
|
||||
*/
|
||||
psm_am_request_short((psm_epaddr_t) dest_addr,
|
||||
PSMX_AM_RMA_HANDLER, args, nargs,
|
||||
NULL, 0, am_flags | PSM_AM_FLAG_NOREPLY,
|
||||
payload, payload_len, am_flags,
|
||||
NULL, NULL);
|
||||
|
||||
psm_mq_isend(ep_priv->domain->psm_mq, (psm_epaddr_t) dest_addr,
|
||||
@ -790,7 +799,7 @@ ssize_t _psmx_write(struct fid_ep *ep, const void *buf, size_t len,
|
||||
psm_am_request_short((psm_epaddr_t) dest_addr,
|
||||
PSMX_AM_RMA_HANDLER, args, nargs,
|
||||
(void *)buf, chunk_size,
|
||||
am_flags | PSM_AM_FLAG_NOREPLY, NULL, NULL);
|
||||
am_flags, NULL, NULL);
|
||||
buf += chunk_size;
|
||||
addr += chunk_size;
|
||||
len -= chunk_size;
|
||||
|
@ -32,6 +32,64 @@
|
||||
|
||||
#include "psmx.h"
|
||||
|
||||
ssize_t _psmx_tagged_peek(struct fid_ep *ep, void *buf, size_t len,
|
||||
void *desc, fi_addr_t src_addr,
|
||||
uint64_t tag, uint64_t ignore,
|
||||
void *context, uint64_t flags)
|
||||
{
|
||||
struct psmx_fid_ep *ep_priv;
|
||||
psm_mq_status_t psm_status;
|
||||
uint64_t psm_tag, psm_tagsel;
|
||||
struct psmx_cq_event *event;
|
||||
int err;
|
||||
|
||||
ep_priv = container_of(ep, struct psmx_fid_ep, ep);
|
||||
|
||||
if (tag & ep_priv->domain->reserved_tag_bits) {
|
||||
FI_WARN(&psmx_prov, FI_LOG_EP_DATA,
|
||||
"using reserved tag bits."
|
||||
"tag=%lx. reserved_bits=%lx.\n", tag,
|
||||
ep_priv->domain->reserved_tag_bits);
|
||||
}
|
||||
|
||||
psm_tag = tag & (~ep_priv->domain->reserved_tag_bits);
|
||||
psm_tagsel = (~ignore) | ep_priv->domain->reserved_tag_bits;
|
||||
|
||||
if (flags & (FI_CLAIM | FI_DISCARD))
|
||||
return -FI_EOPNOTSUPP;
|
||||
|
||||
err = psm_mq_iprobe(ep_priv->domain->psm_mq, psm_tag, psm_tagsel,
|
||||
&psm_status);
|
||||
switch (err) {
|
||||
case PSM_OK:
|
||||
if (ep_priv->recv_cq) {
|
||||
event = psmx_cq_create_event(
|
||||
ep_priv->recv_cq,
|
||||
context, /* op_context */
|
||||
NULL, /* buf */
|
||||
flags|FI_RECV|FI_TAGGED,/* flags */
|
||||
psm_status.msg_length, /* len */
|
||||
0, /* data */
|
||||
psm_status.msg_tag, /* tag */
|
||||
psm_status.msg_length, /* olen */
|
||||
0); /* err */
|
||||
if (event)
|
||||
psmx_cq_enqueue_event(ep_priv->recv_cq, event);
|
||||
else
|
||||
return -FI_ENOMEM;
|
||||
|
||||
/* TODO: set message source to FI_ADDR_NOTAVAIL? */
|
||||
}
|
||||
return 0;
|
||||
|
||||
case PSM_MQ_NO_COMPLETIONS:
|
||||
return -FI_ENOMSG;
|
||||
|
||||
default:
|
||||
return psmx_errno(err);
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t _psmx_tagged_recv(struct fid_ep *ep, void *buf, size_t len,
|
||||
void *desc, fi_addr_t src_addr,
|
||||
uint64_t tag, uint64_t ignore,
|
||||
@ -45,6 +103,10 @@ ssize_t _psmx_tagged_recv(struct fid_ep *ep, void *buf, size_t len,
|
||||
|
||||
ep_priv = container_of(ep, struct psmx_fid_ep, ep);
|
||||
|
||||
if (flags & FI_PEEK)
|
||||
return _psmx_tagged_peek(ep, buf, len, desc, src_addr,
|
||||
tag, ignore, context, flags);
|
||||
|
||||
if (flags & FI_TRIGGER) {
|
||||
struct psmx_trigger *trigger;
|
||||
struct fi_triggered_context *ctxt = context;
|
||||
@ -81,7 +143,7 @@ ssize_t _psmx_tagged_recv(struct fid_ep *ep, void *buf, size_t len,
|
||||
psm_tag = tag & (~ep_priv->domain->reserved_tag_bits);
|
||||
psm_tagsel = (~ignore) | ep_priv->domain->reserved_tag_bits;
|
||||
|
||||
if (ep_priv->recv_cq_event_flag && !(flags & FI_COMPLETION) && !context) {
|
||||
if (ep_priv->recv_selective_completion && !(flags & FI_COMPLETION) && !context) {
|
||||
fi_context = &ep_priv->nocomp_recv_context;
|
||||
}
|
||||
else {
|
||||
@ -414,7 +476,7 @@ ssize_t _psmx_tagged_send(struct fid_ep *ep, const void *buf, size_t len,
|
||||
psm_tag = tag & (~ep_priv->domain->reserved_tag_bits);
|
||||
|
||||
if ((flags & PSMX_NO_COMPLETION) ||
|
||||
(ep_priv->send_cq_event_flag && !(flags & FI_COMPLETION)))
|
||||
(ep_priv->send_selective_completion && !(flags & FI_COMPLETION)))
|
||||
no_completion = 1;
|
||||
|
||||
if (flags & FI_INJECT) {
|
||||
@ -835,48 +897,6 @@ static ssize_t psmx_tagged_inject(struct fid_ep *ep, const void *buf, size_t len
|
||||
ep_priv->flags | FI_INJECT | PSMX_NO_COMPLETION);
|
||||
}
|
||||
|
||||
static ssize_t psmx_tagged_search(struct fid_ep *ep, uint64_t *tag, uint64_t ignore,
|
||||
uint64_t flags, fi_addr_t *src_addr, size_t *len,
|
||||
void *context)
|
||||
{
|
||||
struct psmx_fid_ep *ep_priv;
|
||||
psm_mq_status_t psm_status;
|
||||
uint64_t psm_tag, psm_tagsel;
|
||||
int err;
|
||||
|
||||
ep_priv = container_of(ep, struct psmx_fid_ep, ep);
|
||||
|
||||
if ((*tag) & ep_priv->domain->reserved_tag_bits) {
|
||||
FI_WARN(&psmx_prov, FI_LOG_EP_DATA,
|
||||
"using reserved tag bits."
|
||||
"tag=%lx. reserved_bits=%lx.\n", *tag,
|
||||
ep_priv->domain->reserved_tag_bits);
|
||||
}
|
||||
|
||||
psm_tag = *tag & (~ep_priv->domain->reserved_tag_bits);
|
||||
psm_tagsel = (~ignore) | ep_priv->domain->reserved_tag_bits;
|
||||
|
||||
if (flags & FI_CLAIM)
|
||||
return -FI_EOPNOTSUPP;
|
||||
|
||||
err = psm_mq_iprobe(ep_priv->domain->psm_mq, psm_tag, psm_tagsel,
|
||||
&psm_status);
|
||||
switch (err) {
|
||||
case PSM_OK:
|
||||
*tag = psm_status.msg_tag;
|
||||
*len = psm_status.msg_length;
|
||||
if (src_addr)
|
||||
*src_addr = FI_ADDR_NOTAVAIL;
|
||||
return 1;
|
||||
|
||||
case PSM_MQ_NO_COMPLETIONS:
|
||||
return -FI_ENOMSG;
|
||||
|
||||
default:
|
||||
return psmx_errno(err);
|
||||
}
|
||||
}
|
||||
|
||||
/* general case */
|
||||
struct fi_ops_tagged psmx_tagged_ops = {
|
||||
.size = sizeof(struct fi_ops_tagged),
|
||||
@ -889,7 +909,6 @@ struct fi_ops_tagged psmx_tagged_ops = {
|
||||
.inject = psmx_tagged_inject,
|
||||
.senddata = fi_no_tagged_senddata,
|
||||
.injectdata = fi_no_tagged_injectdata,
|
||||
.search = psmx_tagged_search,
|
||||
};
|
||||
|
||||
/* op_flags=0, no event suppression, FI_AV_MAP */
|
||||
@ -904,7 +923,6 @@ struct fi_ops_tagged psmx_tagged_ops_no_flag_av_map = {
|
||||
.inject = psmx_tagged_inject_no_flag_av_map,
|
||||
.senddata = fi_no_tagged_senddata,
|
||||
.injectdata = fi_no_tagged_injectdata,
|
||||
.search = psmx_tagged_search,
|
||||
};
|
||||
|
||||
/* op_flags=0, no event suppression, FI_AV_TABLE */
|
||||
@ -919,7 +937,6 @@ struct fi_ops_tagged psmx_tagged_ops_no_flag_av_table = {
|
||||
.inject = psmx_tagged_inject_no_flag_av_table,
|
||||
.senddata = fi_no_tagged_senddata,
|
||||
.injectdata = fi_no_tagged_injectdata,
|
||||
.search = psmx_tagged_search,
|
||||
};
|
||||
|
||||
/* op_flags=0, event suppression, FI_AV_MAP */
|
||||
@ -934,7 +951,6 @@ struct fi_ops_tagged psmx_tagged_ops_no_event_av_map = {
|
||||
.inject = psmx_tagged_inject_no_flag_av_map,
|
||||
.senddata = fi_no_tagged_senddata,
|
||||
.injectdata = fi_no_tagged_injectdata,
|
||||
.search = psmx_tagged_search,
|
||||
};
|
||||
|
||||
/* op_flags=0, event suppression, FI_AV_TABLE */
|
||||
@ -949,7 +965,6 @@ struct fi_ops_tagged psmx_tagged_ops_no_event_av_table = {
|
||||
.inject = psmx_tagged_inject_no_flag_av_table,
|
||||
.senddata = fi_no_tagged_senddata,
|
||||
.injectdata = fi_no_tagged_injectdata,
|
||||
.search = psmx_tagged_search,
|
||||
};
|
||||
|
||||
/* op_flags=0, send event suppression, FI_AV_MAP */
|
||||
@ -964,7 +979,6 @@ struct fi_ops_tagged psmx_tagged_ops_no_send_event_av_map = {
|
||||
.inject = psmx_tagged_inject_no_flag_av_map,
|
||||
.senddata = fi_no_tagged_senddata,
|
||||
.injectdata = fi_no_tagged_injectdata,
|
||||
.search = psmx_tagged_search,
|
||||
};
|
||||
|
||||
/* op_flags=0, send event suppression, FI_AV_TABLE */
|
||||
@ -979,7 +993,6 @@ struct fi_ops_tagged psmx_tagged_ops_no_send_event_av_table = {
|
||||
.inject = psmx_tagged_inject_no_flag_av_table,
|
||||
.senddata = fi_no_tagged_senddata,
|
||||
.injectdata = fi_no_tagged_injectdata,
|
||||
.search = psmx_tagged_search,
|
||||
};
|
||||
|
||||
/* op_flags=0, recv event suppression, FI_AV_MAP */
|
||||
@ -994,7 +1007,6 @@ struct fi_ops_tagged psmx_tagged_ops_no_recv_event_av_map = {
|
||||
.inject = psmx_tagged_inject_no_flag_av_map,
|
||||
.senddata = fi_no_tagged_senddata,
|
||||
.injectdata = fi_no_tagged_injectdata,
|
||||
.search = psmx_tagged_search,
|
||||
};
|
||||
|
||||
/* op_flags=0, recv event suppression, FI_AV_TABLE */
|
||||
@ -1009,6 +1021,4 @@ struct fi_ops_tagged psmx_tagged_ops_no_recv_event_av_table = {
|
||||
.inject = psmx_tagged_inject_no_flag_av_table,
|
||||
.senddata = fi_no_tagged_senddata,
|
||||
.injectdata = fi_no_tagged_injectdata,
|
||||
.search = psmx_tagged_search,
|
||||
};
|
||||
|
||||
|
@ -55,7 +55,8 @@ static void *psmx_wait_progress(void *args)
|
||||
|
||||
while (1) {
|
||||
pthread_mutex_lock(&psmx_wait_mutex);
|
||||
pthread_cond_wait(&psmx_wait_cond, &psmx_wait_mutex);
|
||||
if (!psmx_wait_thread_enabled)
|
||||
pthread_cond_wait(&psmx_wait_cond, &psmx_wait_mutex);
|
||||
pthread_mutex_unlock(&psmx_wait_mutex);
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
||||
|
||||
|
@ -66,6 +66,7 @@
|
||||
#define SOCK_EP_MAX_ORDER_WAW_SZ SOCK_EP_MAX_MSG_SZ
|
||||
#define SOCK_EP_MEM_TAG_FMT (0)
|
||||
#define SOCK_EP_MAX_EP_CNT (128)
|
||||
#define SOCK_EP_MAX_CQ_CNT (32)
|
||||
#define SOCK_EP_MAX_TX_CNT (16)
|
||||
#define SOCK_EP_MAX_RX_CNT (16)
|
||||
#define SOCK_EP_MAX_IOV_LIMIT (8)
|
||||
@ -76,10 +77,12 @@
|
||||
#define SOCK_EP_MIN_MULTI_RECV (64)
|
||||
#define SOCK_EP_MAX_ATOMIC_SZ (256)
|
||||
#define SOCK_EP_MAX_CTX_BITS (16)
|
||||
#define SOCK_EP_MSG_PREFIX_SZ (0)
|
||||
|
||||
#define SOCK_PE_POLL_TIMEOUT (100000)
|
||||
#define SOCK_PE_MAX_ENTRIES (128)
|
||||
#define SOCK_PE_MIN_ENTRIES (1)
|
||||
#define SOCK_PE_WAITTIME (10)
|
||||
|
||||
#define SOCK_EQ_DEF_SZ (1<<8)
|
||||
#define SOCK_CQ_DEF_SZ (1<<8)
|
||||
@ -94,34 +97,43 @@
|
||||
#define SOCK_EP_MAX_CM_DATA_SZ (256)
|
||||
|
||||
#define SOCK_EP_RDM_CAP (FI_MSG | FI_RMA | FI_TAGGED | FI_ATOMICS | \
|
||||
FI_DYNAMIC_MR | FI_NAMED_RX_CTX | \
|
||||
FI_NAMED_RX_CTX | \
|
||||
FI_DIRECTED_RECV | FI_MULTI_RECV | \
|
||||
FI_SOURCE | FI_READ | FI_WRITE | FI_RECV | FI_SEND | \
|
||||
FI_REMOTE_READ | FI_REMOTE_WRITE | \
|
||||
FI_COMPLETION | \
|
||||
FI_MORE | FI_CANCEL | FI_FENCE)
|
||||
FI_RMA_EVENT | \
|
||||
FI_MORE | FI_FENCE)
|
||||
|
||||
#define SOCK_EP_MSG_CAP SOCK_EP_RDM_CAP
|
||||
|
||||
#define SOCK_EP_DGRAM_CAP (FI_MSG | FI_TAGGED | FI_DYNAMIC_MR | \
|
||||
#define SOCK_EP_DGRAM_CAP (FI_MSG | FI_TAGGED | \
|
||||
FI_NAMED_RX_CTX | FI_DIRECTED_RECV | \
|
||||
FI_MULTI_RECV | FI_SOURCE | FI_RECV | FI_SEND | \
|
||||
FI_COMPLETION | \
|
||||
FI_MORE | FI_CANCEL | FI_FENCE)
|
||||
FI_MORE | FI_FENCE)
|
||||
|
||||
#define SOCK_EP_MSG_ORDER (FI_ORDER_RAR | FI_ORDER_RAW | FI_ORDER_RAS| \
|
||||
FI_ORDER_WAR | FI_ORDER_WAW | FI_ORDER_WAS | \
|
||||
FI_ORDER_SAR | FI_ORDER_SAW | FI_ORDER_SAS)
|
||||
|
||||
#define SOCK_EP_COMP_ORDER (FI_ORDER_STRICT | FI_ORDER_DATA)
|
||||
|
||||
#define SOCK_MODE (0)
|
||||
#define SOCK_NO_COMPLETION (1ULL << 60)
|
||||
#define SOCK_USE_OP_FLAGS (1ULL << 61)
|
||||
|
||||
#define SOCK_COMM_BUF_SZ (1<<20)
|
||||
#define SOCK_COMM_THRESHOLD (128 * 1024)
|
||||
|
||||
enum {
|
||||
SOCK_SIGNAL_RD_FD = 0,
|
||||
SOCK_SIGNAL_WR_FD
|
||||
};
|
||||
|
||||
#define SOCK_MAJOR_VERSION 1
|
||||
#define SOCK_MINOR_VERSION 0
|
||||
|
||||
#define SOCK_WIRE_PROTO_VERSION (0)
|
||||
|
||||
struct sock_service_entry {
|
||||
int service;
|
||||
struct dlist_entry entry;
|
||||
@ -130,7 +142,11 @@ struct sock_service_entry {
|
||||
struct sock_fabric {
|
||||
struct fid_fabric fab_fid;
|
||||
atomic_t ref;
|
||||
#if ENABLE_DEBUG
|
||||
uint64_t num_send_msg;
|
||||
#endif
|
||||
struct dlist_entry service_list;
|
||||
struct dlist_entry fab_list_entry;
|
||||
fastlock_t lock;
|
||||
};
|
||||
|
||||
@ -166,6 +182,8 @@ struct sock_domain {
|
||||
struct index_map mr_idm;
|
||||
struct sock_pe *pe;
|
||||
struct sock_conn_map r_cmap;
|
||||
struct dlist_entry dom_list_entry;
|
||||
struct fi_domain_attr attr;
|
||||
};
|
||||
|
||||
struct sock_cntr {
|
||||
@ -196,10 +214,9 @@ struct sock_mr {
|
||||
uint64_t key;
|
||||
uint64_t flags;
|
||||
size_t iov_count;
|
||||
struct iovec mr_iov[1];
|
||||
|
||||
struct sock_cntr *cntr;
|
||||
struct sock_cq *cq;
|
||||
struct iovec mr_iov[1];
|
||||
};
|
||||
|
||||
struct sock_av_addr {
|
||||
@ -306,6 +323,8 @@ struct sock_op_send {
|
||||
uint64_t context;
|
||||
uint64_t dest_addr;
|
||||
uint64_t buf;
|
||||
uint64_t tag;
|
||||
uint64_t data;
|
||||
struct sock_ep *ep;
|
||||
struct sock_conn *conn;
|
||||
};
|
||||
@ -396,6 +415,7 @@ struct sock_cm_entry {
|
||||
struct sock_conn_listener {
|
||||
int sock;
|
||||
int do_listen;
|
||||
int is_ready;
|
||||
int signal_fds[2];
|
||||
pthread_t listener_thread;
|
||||
char service[NI_MAXSERV];
|
||||
@ -551,8 +571,6 @@ struct sock_tx_ctx {
|
||||
struct fi_tx_attr attr;
|
||||
};
|
||||
|
||||
#define SOCK_WIRE_PROTO_VERSION (0)
|
||||
|
||||
struct sock_msg_hdr {
|
||||
uint8_t version;
|
||||
uint8_t op_type;
|
||||
@ -598,7 +616,8 @@ struct sock_atomic_req {
|
||||
struct sock_msg_response {
|
||||
struct sock_msg_hdr msg_hdr;
|
||||
uint16_t pe_entry_id;
|
||||
uint8_t reserved[6];
|
||||
int32_t err;
|
||||
uint8_t reserved[2];
|
||||
};
|
||||
|
||||
struct sock_rma_read_req {
|
||||
@ -635,10 +654,8 @@ struct sock_tx_pe_entry {
|
||||
uint8_t reserved[6];
|
||||
|
||||
struct sock_tx_ctx *tx_ctx;
|
||||
union {
|
||||
struct sock_tx_iov tx_iov[SOCK_EP_MAX_IOV_LIMIT];
|
||||
char inject[SOCK_EP_MAX_INJECT_SZ];
|
||||
} data;
|
||||
struct sock_tx_iov tx_iov[SOCK_EP_MAX_IOV_LIMIT];
|
||||
char inject[SOCK_EP_MAX_INJECT_SZ];
|
||||
};
|
||||
|
||||
struct sock_rx_pe_entry {
|
||||
@ -678,11 +695,13 @@ struct sock_pe_entry {
|
||||
|
||||
uint8_t type;
|
||||
uint8_t is_complete;
|
||||
uint8_t reserved[6];
|
||||
uint8_t is_error;
|
||||
uint8_t reserved[5];
|
||||
|
||||
uint64_t done_len;
|
||||
uint64_t total_len;
|
||||
uint64_t data_len;
|
||||
uint64_t rem;
|
||||
struct sock_ep *ep;
|
||||
struct sock_conn *conn;
|
||||
struct sock_comp *comp;
|
||||
@ -697,6 +716,8 @@ struct sock_pe {
|
||||
struct sock_pe_entry pe_table[SOCK_PE_MAX_ENTRIES];
|
||||
fastlock_t lock;
|
||||
pthread_mutex_t list_lock;
|
||||
int signal_fds[2];
|
||||
uint64_t waittime;
|
||||
|
||||
struct dlist_entry free_list;
|
||||
struct dlist_entry busy_list;
|
||||
@ -781,6 +802,11 @@ enum {
|
||||
SOCK_CONN_ACK
|
||||
};
|
||||
|
||||
struct sock_conn_req_handle {
|
||||
struct fid handle;
|
||||
struct sock_conn_req *req;
|
||||
};
|
||||
|
||||
int sock_verify_info(struct fi_info *hints);
|
||||
int sock_verify_fabric_attr(struct fi_fabric_attr *attr);
|
||||
int sock_verify_domain_attr(struct fi_domain_attr *attr);
|
||||
@ -812,6 +838,15 @@ void sock_fabric_add_service(struct sock_fabric *fab, int service);
|
||||
void sock_fabric_remove_service(struct sock_fabric *fab, int service);
|
||||
int sock_fabric_check_service(struct sock_fabric *fab, int service);
|
||||
|
||||
void sock_dom_add_to_list(struct sock_domain *domain);
|
||||
int sock_dom_check_list(struct sock_domain *domain);
|
||||
void sock_dom_remove_from_list(struct sock_domain *domain);
|
||||
struct sock_domain *sock_dom_list_head(void);
|
||||
|
||||
void sock_fab_add_to_list(struct sock_fabric *fabric);
|
||||
int sock_fab_check_list(struct sock_fabric *fabric);
|
||||
void sock_fab_remove_from_list(struct sock_fabric *fabric);
|
||||
struct sock_fabric *sock_fab_list_head(void);
|
||||
|
||||
int sock_alloc_endpoint(struct fid_domain *domain, struct fi_info *info,
|
||||
struct sock_ep **ep, void *context, size_t fclass);
|
||||
@ -936,6 +971,7 @@ int sock_conn_map_init(struct sock_conn_map *map, int init_size);
|
||||
struct sock_pe *sock_pe_init(struct sock_domain *domain);
|
||||
void sock_pe_add_tx_ctx(struct sock_pe *pe, struct sock_tx_ctx *ctx);
|
||||
void sock_pe_add_rx_ctx(struct sock_pe *pe, struct sock_rx_ctx *ctx);
|
||||
void sock_pe_signal(struct sock_pe *pe);
|
||||
int sock_pe_progress_rx_ctx(struct sock_pe *pe, struct sock_rx_ctx *rx_ctx);
|
||||
int sock_pe_progress_tx_ctx(struct sock_pe *pe, struct sock_tx_ctx *tx_ctx);
|
||||
void sock_pe_remove_tx_ctx(struct sock_tx_ctx *tx_ctx);
|
||||
@ -948,7 +984,17 @@ struct sock_rx_entry *sock_rx_new_buffered_entry(struct sock_rx_ctx *rx_ctx,
|
||||
size_t len);
|
||||
struct sock_rx_entry *sock_rx_get_entry(struct sock_rx_ctx *rx_ctx,
|
||||
uint64_t addr, uint64_t tag,
|
||||
uint8_t op_type);
|
||||
uint8_t is_tagged);
|
||||
struct sock_rx_entry *sock_rx_get_buffered_entry(struct sock_rx_ctx *rx_ctx,
|
||||
uint64_t addr, uint64_t tag,
|
||||
uint64_t ignore, uint8_t is_tagged);
|
||||
ssize_t sock_rx_peek_recv(struct sock_rx_ctx *rx_ctx, fi_addr_t addr,
|
||||
uint64_t tag, uint64_t ignore, void *context, uint64_t flags,
|
||||
uint8_t is_tagged);
|
||||
ssize_t sock_rx_claim_recv(struct sock_rx_ctx *rx_ctx, void *context,
|
||||
uint64_t flags, uint64_t tag, uint64_t ignore,
|
||||
uint8_t is_tagged, const struct iovec *msg_iov,
|
||||
size_t iov_count);
|
||||
size_t sock_rx_avail_len(struct sock_rx_entry *rx_entry);
|
||||
void sock_rx_release_entry(struct sock_rx_entry *rx_entry);
|
||||
|
||||
@ -958,6 +1004,7 @@ void sock_comm_buffer_finalize(struct sock_conn *conn);
|
||||
ssize_t sock_comm_send(struct sock_conn *conn, const void *buf, size_t len);
|
||||
ssize_t sock_comm_recv(struct sock_conn *conn, void *buf, size_t len);
|
||||
ssize_t sock_comm_peek(struct sock_conn *conn, void *buf, size_t len);
|
||||
ssize_t sock_comm_discard(struct sock_conn *conn, size_t len);
|
||||
ssize_t sock_comm_data_avail(struct sock_conn *conn);
|
||||
ssize_t sock_comm_flush(struct sock_conn *conn);
|
||||
|
||||
|
@ -34,7 +34,6 @@
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
@ -89,10 +88,13 @@ static ssize_t sock_ep_tx_atomic(struct fid_ep *ep,
|
||||
return -FI_EINVAL;
|
||||
}
|
||||
|
||||
assert(tx_ctx->enabled &&
|
||||
msg->iov_count <= SOCK_EP_MAX_IOV_LIMIT &&
|
||||
msg->rma_iov_count <= SOCK_EP_MAX_IOV_LIMIT);
|
||||
if (msg->iov_count > SOCK_EP_MAX_IOV_LIMIT ||
|
||||
msg->rma_iov_count > SOCK_EP_MAX_IOV_LIMIT)
|
||||
return -FI_EINVAL;
|
||||
|
||||
if (!tx_ctx->enabled)
|
||||
return -FI_EOPBADSTATE;
|
||||
|
||||
if (sock_ep->connected) {
|
||||
conn = sock_ep_lookup_conn(sock_ep);
|
||||
} else {
|
||||
@ -102,19 +104,24 @@ static ssize_t sock_ep_tx_atomic(struct fid_ep *ep,
|
||||
if (!conn)
|
||||
return -FI_EAGAIN;
|
||||
|
||||
if (flags & SOCK_USE_OP_FLAGS)
|
||||
flags |= tx_ctx->attr.op_flags;
|
||||
|
||||
src_len = 0;
|
||||
datatype_sz = fi_datatype_size(msg->datatype);
|
||||
if (flags & FI_INJECT) {
|
||||
for (i=0; i< msg->iov_count; i++) {
|
||||
src_len += (msg->msg_iov[i].count * datatype_sz);
|
||||
}
|
||||
assert(src_len <= SOCK_EP_MAX_INJECT_SZ);
|
||||
if (src_len > SOCK_EP_MAX_INJECT_SZ) {
|
||||
return -FI_EINVAL;
|
||||
}
|
||||
total_len = src_len;
|
||||
} else {
|
||||
total_len = msg->iov_count * sizeof(union sock_iov);
|
||||
}
|
||||
|
||||
total_len += (sizeof(tx_op) +
|
||||
total_len += (sizeof(struct sock_op_send) +
|
||||
(msg->rma_iov_count * sizeof(union sock_iov)) +
|
||||
(result_count * sizeof (union sock_iov)));
|
||||
|
||||
@ -124,7 +131,6 @@ static ssize_t sock_ep_tx_atomic(struct fid_ep *ep,
|
||||
goto err;
|
||||
}
|
||||
|
||||
flags |= tx_ctx->attr.op_flags;
|
||||
memset(&tx_op, 0, sizeof(tx_op));
|
||||
tx_op.op = SOCK_OP_ATOMIC;
|
||||
tx_op.dest_iov_len = msg->rma_iov_count;
|
||||
@ -161,7 +167,11 @@ static ssize_t sock_ep_tx_atomic(struct fid_ep *ep,
|
||||
src_len += (tx_iov.ioc.count * datatype_sz);
|
||||
}
|
||||
}
|
||||
assert(src_len <= SOCK_EP_MAX_ATOMIC_SZ);
|
||||
|
||||
if (src_len > SOCK_EP_MAX_ATOMIC_SZ) {
|
||||
ret = -FI_EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
dst_len = 0;
|
||||
for (i = 0; i< msg->rma_iov_count; i++) {
|
||||
@ -210,7 +220,6 @@ static ssize_t sock_ep_tx_atomic(struct fid_ep *ep,
|
||||
return 0;
|
||||
|
||||
err:
|
||||
SOCK_LOG_INFO("Not enough space for TX entry, try again\n");
|
||||
sock_tx_ctx_abort(tx_ctx);
|
||||
return ret;
|
||||
}
|
||||
@ -251,7 +260,7 @@ static ssize_t sock_ep_atomic_write(struct fid_ep *ep,
|
||||
msg.context = context;
|
||||
msg.data = 0;
|
||||
|
||||
return sock_ep_atomic_writemsg(ep, &msg, 0);
|
||||
return sock_ep_atomic_writemsg(ep, &msg, SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_atomic_writev(struct fid_ep *ep,
|
||||
@ -279,7 +288,7 @@ static ssize_t sock_ep_atomic_writev(struct fid_ep *ep,
|
||||
msg.context = context;
|
||||
msg.data = 0;
|
||||
|
||||
return sock_ep_atomic_writemsg(ep, &msg, 0);
|
||||
return sock_ep_atomic_writemsg(ep, &msg, SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_atomic_inject(struct fid_ep *ep, const void *buf, size_t count,
|
||||
@ -306,7 +315,8 @@ static ssize_t sock_ep_atomic_inject(struct fid_ep *ep, const void *buf, size_t
|
||||
msg.op = op;
|
||||
msg.data = 0;
|
||||
|
||||
return sock_ep_atomic_writemsg(ep, &msg, FI_INJECT | SOCK_NO_COMPLETION);
|
||||
return sock_ep_atomic_writemsg(ep, &msg, FI_INJECT |
|
||||
SOCK_NO_COMPLETION | SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_atomic_readwritemsg(struct fid_ep *ep,
|
||||
@ -351,7 +361,7 @@ static ssize_t sock_ep_atomic_readwrite(struct fid_ep *ep,
|
||||
resultv.count = 1;
|
||||
|
||||
return sock_ep_atomic_readwritemsg(ep, &msg,
|
||||
&resultv, &result_desc, 1, 0);
|
||||
&resultv, &result_desc, 1, SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_atomic_readwritev(struct fid_ep *ep,
|
||||
@ -379,7 +389,8 @@ static ssize_t sock_ep_atomic_readwritev(struct fid_ep *ep,
|
||||
msg.context = context;
|
||||
|
||||
return sock_ep_atomic_readwritemsg(ep, &msg,
|
||||
resultv, result_desc, result_count, 0);
|
||||
resultv, result_desc, result_count,
|
||||
SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_atomic_compwritemsg(struct fid_ep *ep,
|
||||
@ -429,7 +440,8 @@ static ssize_t sock_ep_atomic_compwrite(struct fid_ep *ep,
|
||||
comparev.count = 1;
|
||||
|
||||
return sock_ep_atomic_compwritemsg(ep, &msg, &comparev, &compare_desc, 1,
|
||||
&resultv, &result_desc, 1, 0);
|
||||
&resultv, &result_desc, 1,
|
||||
SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_atomic_compwritev(struct fid_ep *ep,
|
||||
@ -458,7 +470,8 @@ static ssize_t sock_ep_atomic_compwritev(struct fid_ep *ep,
|
||||
msg.context = context;
|
||||
|
||||
return sock_ep_atomic_compwritemsg(ep, &msg, comparev, compare_desc, 1,
|
||||
resultv, result_desc, 1, 0);
|
||||
resultv, result_desc, 1,
|
||||
SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static int sock_ep_atomic_valid(struct fid_ep *ep, enum fi_datatype datatype,
|
||||
|
@ -149,13 +149,13 @@ static inline void sock_av_report_success(struct sock_av *av, void *context,
|
||||
}
|
||||
|
||||
static inline void sock_av_report_error(struct sock_av *av,
|
||||
void *context, int index)
|
||||
void *context, int index, int err)
|
||||
{
|
||||
if (!av->eq)
|
||||
return;
|
||||
|
||||
sock_eq_report_error(av->eq, &av->av_fid.fid,
|
||||
context, index, FI_EINVAL, -FI_EINVAL, NULL, 0);
|
||||
context, index, err, -err, NULL, 0);
|
||||
}
|
||||
|
||||
static int sock_av_is_valid_address(struct sockaddr_in *addr)
|
||||
@ -167,10 +167,11 @@ static int sock_check_table_in(struct sock_av *_av, struct sockaddr_in *addr,
|
||||
fi_addr_t *fi_addr, int count, uint64_t flags,
|
||||
void *context, int index)
|
||||
{
|
||||
void *new_addr;
|
||||
int i, j, ret = 0;
|
||||
char sa_ip[INET_ADDRSTRLEN];
|
||||
struct sock_av_addr *av_addr;
|
||||
size_t new_count, table_sz;
|
||||
size_t new_count, table_sz, old_sz;
|
||||
|
||||
if ((_av->attr.flags & FI_EVENT) && !_av->eq)
|
||||
return -FI_ENOEQ;
|
||||
@ -182,7 +183,7 @@ static int sock_check_table_in(struct sock_av *_av, struct sockaddr_in *addr,
|
||||
if (!sock_av_is_valid_address(&addr[i])) {
|
||||
if (fi_addr)
|
||||
fi_addr[i] = FI_ADDR_NOTAVAIL;
|
||||
sock_av_report_error(_av, context, i);
|
||||
sock_av_report_error(_av, context, i, FI_EINVAL);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -194,7 +195,7 @@ static int sock_check_table_in(struct sock_av *_av, struct sockaddr_in *addr,
|
||||
if (idm_set(&_av->addr_idm, _av->key[j], av_addr) < 0) {
|
||||
if (fi_addr)
|
||||
fi_addr[i] = FI_ADDR_NOTAVAIL;
|
||||
sock_av_report_error(_av, context, i);
|
||||
sock_av_report_error(_av, context, i, FI_EINVAL);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -206,28 +207,53 @@ static int sock_check_table_in(struct sock_av *_av, struct sockaddr_in *addr,
|
||||
}
|
||||
}
|
||||
sock_av_report_success(_av, context, ret, flags);
|
||||
return ret;
|
||||
return (_av->attr.flags & FI_EVENT) ? 0 : ret;
|
||||
}
|
||||
|
||||
for (i = 0, ret = 0; i < count; i++) {
|
||||
|
||||
if (_av->table_hdr->stored == _av->table_hdr->size) {
|
||||
if (_av->table_hdr->req_sz) {
|
||||
if (fi_addr)
|
||||
fi_addr[i] = FI_ADDR_NOTAVAIL;
|
||||
sock_av_report_error(_av, context, i, FI_ENOSPC);
|
||||
SOCK_LOG_ERROR("Cannot insert to AV table\n");
|
||||
return -FI_EINVAL;
|
||||
continue;
|
||||
} else{
|
||||
new_count = _av->table_hdr->size * 2;
|
||||
_av->key = realloc(_av->key,
|
||||
sizeof(uint16_t) * new_count);
|
||||
if (!_av->key)
|
||||
return -FI_ENOMEM;
|
||||
if (!_av->key) {
|
||||
if (fi_addr)
|
||||
fi_addr[i] = FI_ADDR_NOTAVAIL;
|
||||
sock_av_report_error(_av, context, i, FI_ENOMEM);
|
||||
continue;
|
||||
}
|
||||
|
||||
table_sz = sizeof(struct sock_av_table_hdr) +
|
||||
new_count * sizeof(struct sock_av_addr);
|
||||
old_sz = sizeof(struct sock_av_table_hdr) +
|
||||
_av->table_hdr->size * sizeof(struct sock_av_addr);
|
||||
|
||||
_av->table_hdr = realloc(_av->table_hdr, table_sz);
|
||||
if (!_av->table_hdr)
|
||||
return -FI_ENOMEM;
|
||||
if (_av->attr.name) {
|
||||
new_addr = sock_mremap(_av->table_hdr,
|
||||
old_sz, table_sz);
|
||||
if (new_addr == ((void*) -1)) {
|
||||
if (fi_addr)
|
||||
fi_addr[i] = FI_ADDR_NOTAVAIL;
|
||||
sock_av_report_error(_av, context, i, FI_ENOMEM);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
new_addr = realloc(_av->table_hdr, table_sz);
|
||||
if (!new_addr) {
|
||||
if (fi_addr)
|
||||
fi_addr[i] = FI_ADDR_NOTAVAIL;
|
||||
sock_av_report_error(_av, context, i, FI_ENOMEM);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
_av->table_hdr = new_addr;
|
||||
_av->table_hdr->size = new_count;
|
||||
_av->table = (struct sock_av_addr*)((char*)_av->table_hdr +
|
||||
sizeof(struct sock_av_table_hdr));
|
||||
@ -237,7 +263,7 @@ static int sock_check_table_in(struct sock_av *_av, struct sockaddr_in *addr,
|
||||
if (!sock_av_is_valid_address(&addr[i])) {
|
||||
if (fi_addr)
|
||||
fi_addr[i] = FI_ADDR_NOTAVAIL;
|
||||
sock_av_report_error(_av, context, i);
|
||||
sock_av_report_error(_av, context, i, FI_EINVAL);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -251,7 +277,7 @@ static int sock_check_table_in(struct sock_av *_av, struct sockaddr_in *addr,
|
||||
if (idm_set(&_av->addr_idm, _av->table_hdr->stored, av_addr) < 0) {
|
||||
if (fi_addr)
|
||||
fi_addr[i] = FI_ADDR_NOTAVAIL;
|
||||
sock_av_report_error(_av, context, i);
|
||||
sock_av_report_error(_av, context, i, FI_EINVAL);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -263,7 +289,7 @@ static int sock_check_table_in(struct sock_av *_av, struct sockaddr_in *addr,
|
||||
ret++;
|
||||
}
|
||||
sock_av_report_success(_av, context, ret, flags);
|
||||
return ret;
|
||||
return (_av->attr.flags & FI_EVENT) ? 0 : ret;
|
||||
}
|
||||
|
||||
static int sock_av_insert(struct fid_av *av, const void *addr, size_t count,
|
||||
@ -304,11 +330,6 @@ static int _sock_av_insertsvc(struct fid_av *av, const char *node,
|
||||
struct addrinfo *result = NULL;
|
||||
struct sock_av *_av;
|
||||
|
||||
if (!service) {
|
||||
SOCK_LOG_ERROR("Port not provided\n");
|
||||
return -FI_EINVAL;
|
||||
}
|
||||
|
||||
_av = container_of(av, struct sock_av, av_fid);
|
||||
memset(&sock_hints, 0, sizeof(struct addrinfo));
|
||||
sock_hints.ai_family = AF_INET;
|
||||
@ -317,7 +338,7 @@ static int _sock_av_insertsvc(struct fid_av *av, const char *node,
|
||||
ret = getaddrinfo(node, service, &sock_hints, &result);
|
||||
if (ret) {
|
||||
if (_av->eq) {
|
||||
sock_av_report_error(_av, context, 0);
|
||||
sock_av_report_error(_av, context, 0, FI_EINVAL);
|
||||
sock_av_report_success(_av, context, 0, flags);
|
||||
}
|
||||
return -ret;
|
||||
@ -333,6 +354,11 @@ static int sock_av_insertsvc(struct fid_av *av, const char *node,
|
||||
const char *service, fi_addr_t *fi_addr,
|
||||
uint64_t flags, void *context)
|
||||
{
|
||||
if (!service) {
|
||||
SOCK_LOG_ERROR("Port not provided\n");
|
||||
return -FI_EINVAL;
|
||||
}
|
||||
|
||||
return _sock_av_insertsvc(av, node, service, fi_addr, flags, context, 0);
|
||||
}
|
||||
|
||||
@ -340,7 +366,7 @@ static int sock_av_insertsym(struct fid_av *av, const char *node, size_t nodecnt
|
||||
const char *service, size_t svccnt, fi_addr_t *fi_addr,
|
||||
uint64_t flags, void *context)
|
||||
{
|
||||
int ret = 0;
|
||||
int ret = 0, success = 0, err_code = 0;
|
||||
int var_port, var_host;
|
||||
char base_host[FI_NAME_MAX] = {0};
|
||||
char tmp_host[FI_NAME_MAX] = {0};
|
||||
@ -369,13 +395,15 @@ static int sock_av_insertsym(struct fid_av *av, const char *node, size_t nodecnt
|
||||
for (j = 0; j < svccnt; j++) {
|
||||
sprintf(tmp_host, "%s%0*d", base_host, fmt, var_host + i);
|
||||
sprintf(tmp_port, "%d", var_port + j);
|
||||
|
||||
if (_sock_av_insertsvc(av, node, service, fi_addr, flags,
|
||||
context, i * nodecnt + j) == 1)
|
||||
ret++;
|
||||
if ((ret = _sock_av_insertsvc(av, node, service, fi_addr, flags,
|
||||
context, i * nodecnt + j)) == 1) {
|
||||
success++;
|
||||
} else {
|
||||
err_code = ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
return success > 0 ? success : err_code;
|
||||
}
|
||||
|
||||
|
||||
@ -514,6 +542,10 @@ int sock_av_open(struct fid_domain *domain, struct fi_av_attr *attr,
|
||||
return -FI_EINVAL;
|
||||
|
||||
dom = container_of(domain, struct sock_domain, dom_fid);
|
||||
if (dom->attr.av_type != FI_AV_UNSPEC && attr &&
|
||||
dom->attr.av_type != attr->type)
|
||||
return -FI_EINVAL;
|
||||
|
||||
_av = calloc(1, sizeof(*_av));
|
||||
if (!_av)
|
||||
return -FI_ENOMEM;
|
||||
@ -607,7 +639,7 @@ int sock_av_open(struct fid_domain *domain, struct fi_av_attr *attr,
|
||||
goto err;
|
||||
}
|
||||
|
||||
atomic_init(&_av->ref, 0);
|
||||
atomic_initialize(&_av->ref, 0);
|
||||
atomic_inc(&dom->ref);
|
||||
_av->domain = dom;
|
||||
switch (dom->info.addr_format) {
|
||||
|
@ -56,8 +56,7 @@ int sock_cntr_progress(struct sock_cntr *cntr)
|
||||
struct sock_rx_ctx *rx_ctx;
|
||||
struct dlist_entry *entry;
|
||||
|
||||
if (cntr->domain->progress_mode == FI_PROGRESS_AUTO &&
|
||||
!sock_progress_thread_wait)
|
||||
if (cntr->domain->progress_mode == FI_PROGRESS_AUTO)
|
||||
return 0;
|
||||
|
||||
fastlock_acquire(&cntr->list_lock);
|
||||
@ -359,11 +358,11 @@ int sock_cntr_open(struct fid_domain *domain, struct fi_cntr_attr *attr,
|
||||
pthread_mutex_init(&_cntr->mut, NULL);
|
||||
fastlock_init(&_cntr->list_lock);
|
||||
|
||||
atomic_init(&_cntr->ref, 0);
|
||||
atomic_init(&_cntr->err_cnt, 0);
|
||||
atomic_initialize(&_cntr->ref, 0);
|
||||
atomic_initialize(&_cntr->err_cnt, 0);
|
||||
|
||||
atomic_init(&_cntr->value, 0);
|
||||
atomic_init(&_cntr->threshold, ~0);
|
||||
atomic_initialize(&_cntr->value, 0);
|
||||
atomic_initialize(&_cntr->threshold, ~0);
|
||||
|
||||
dlist_init(&_cntr->tx_list);
|
||||
dlist_init(&_cntr->rx_list);
|
||||
|
@ -201,6 +201,12 @@ ssize_t sock_comm_peek(struct sock_conn *conn, void *buf, size_t len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t sock_comm_discard(struct sock_conn *conn, size_t len)
|
||||
{
|
||||
sock_comm_recv_buffer(conn);
|
||||
return rbdiscard(&conn->inbuf, len);
|
||||
}
|
||||
|
||||
ssize_t sock_comm_data_avail(struct sock_conn *conn)
|
||||
{
|
||||
sock_comm_recv_buffer(conn);
|
||||
|
@ -140,6 +140,7 @@ static int sock_conn_map_insert(struct sock_conn_map *map,
|
||||
map->table[index].ep = ep;
|
||||
sock_comm_buffer_init(&map->table[index]);
|
||||
map->used++;
|
||||
sock_pe_signal(ep->domain->pe);
|
||||
return index + 1;
|
||||
}
|
||||
|
||||
@ -157,13 +158,20 @@ int fd_set_nonblock(int fd)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void sock_set_sockopts(int sock)
|
||||
static void sock_set_sockopt_reuseaddr(int sock)
|
||||
{
|
||||
int optval;
|
||||
optval = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval))
|
||||
SOCK_LOG_ERROR("setsockopt reuseaddr failed\n");
|
||||
}
|
||||
|
||||
void sock_set_sockopts(int sock)
|
||||
{
|
||||
int optval;
|
||||
optval = 1;
|
||||
|
||||
sock_set_sockopt_reuseaddr(sock);
|
||||
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof optval))
|
||||
SOCK_LOG_ERROR("setsockopt nodelay failed\n");
|
||||
|
||||
@ -180,15 +188,27 @@ uint16_t sock_conn_map_connect(struct sock_ep *ep,
|
||||
struct timeval tv;
|
||||
socklen_t optlen;
|
||||
fd_set fds;
|
||||
struct sockaddr_in src_addr;
|
||||
|
||||
conn_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (conn_fd < 0) {
|
||||
SOCK_LOG_ERROR("failed to create conn_fd, errno: %d\n", errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(&src_addr, ep->src_addr, sizeof src_addr);
|
||||
src_addr.sin_port = 0;
|
||||
optlen = sizeof src_addr;
|
||||
|
||||
sock_set_sockopt_reuseaddr(conn_fd);
|
||||
if (bind(conn_fd, (struct sockaddr*) &src_addr, optlen)) {
|
||||
SOCK_LOG_ERROR("bind failed : %s\n", strerror(errno));
|
||||
close(conn_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SOCK_LOG_INFO("Connecting to: %s:%d\n", inet_ntoa(addr->sin_addr),
|
||||
ntohs(addr->sin_port));
|
||||
SOCK_LOG_INFO("Connecting to: %s:%d from %s\n", inet_ntoa(addr->sin_addr),
|
||||
ntohs(addr->sin_port), inet_ntoa(src_addr.sin_addr));
|
||||
|
||||
if (connect(conn_fd, (struct sockaddr *) addr, sizeof *addr) < 0) {
|
||||
if (errno == EINPROGRESS) {
|
||||
@ -291,6 +311,7 @@ static void *_sock_conn_listen(void *arg)
|
||||
poll_fds[0].fd = listener->sock;
|
||||
poll_fds[1].fd = listener->signal_fds[1];
|
||||
poll_fds[0].events = poll_fds[1].events = POLLIN;
|
||||
listener->is_ready = 1;
|
||||
|
||||
while (listener->do_listen) {
|
||||
if (poll(poll_fds, 2, -1) > 0) {
|
||||
@ -433,8 +454,13 @@ int sock_conn_listen(struct sock_ep *ep)
|
||||
goto err;
|
||||
|
||||
fd_set_nonblock(listener->signal_fds[1]);
|
||||
return pthread_create(&listener->listener_thread, 0,
|
||||
_sock_conn_listen, ep);
|
||||
if (pthread_create(&listener->listener_thread, 0,
|
||||
_sock_conn_listen, ep)) {
|
||||
SOCK_LOG_ERROR("failed to create conn listener thread\n");
|
||||
goto err;
|
||||
}
|
||||
while (!*((volatile int*)&listener->is_ready));
|
||||
return 0;
|
||||
err:
|
||||
if (listen_fd >= 0)
|
||||
close(listen_fd);
|
||||
|
@ -57,8 +57,7 @@ int sock_cq_progress(struct sock_cq *cq)
|
||||
struct sock_rx_ctx *rx_ctx;
|
||||
struct dlist_entry *entry;
|
||||
|
||||
if (cq->domain->progress_mode == FI_PROGRESS_AUTO &&
|
||||
!sock_progress_thread_wait)
|
||||
if (cq->domain->progress_mode == FI_PROGRESS_AUTO)
|
||||
return 0;
|
||||
|
||||
fastlock_acquire(&cq->list_lock);
|
||||
@ -230,8 +229,11 @@ static ssize_t sock_cq_sreadfrom(struct fid_cq *cq, void *buf, size_t count,
|
||||
ssize_t cq_entry_len, avail;
|
||||
|
||||
sock_cq = container_of(cq, struct sock_cq, cq_fid);
|
||||
cq_entry_len = sock_cq->cq_entry_size;
|
||||
if (rbused(&sock_cq->cqerr_rb)) {
|
||||
return -FI_EAVAIL;
|
||||
}
|
||||
|
||||
cq_entry_len = sock_cq->cq_entry_size;
|
||||
if (sock_cq->attr.wait_cond == FI_CQ_COND_THRESHOLD) {
|
||||
threshold = MIN((uintptr_t) cond, count);
|
||||
}else{
|
||||
@ -459,7 +461,7 @@ int sock_cq_open(struct fid_domain *domain, struct fi_cq_attr *attr,
|
||||
if (!sock_cq)
|
||||
return -FI_ENOMEM;
|
||||
|
||||
atomic_init(&sock_cq->ref, 0);
|
||||
atomic_initialize(&sock_cq->ref, 0);
|
||||
sock_cq->cq_fid.fid.fclass = FI_CLASS_CQ;
|
||||
sock_cq->cq_fid.fid.context = context;
|
||||
sock_cq->cq_fid.fid.ops = &sock_cq_fi_ops;
|
||||
@ -574,7 +576,7 @@ int sock_cq_report_error(struct sock_cq *cq, struct sock_pe_entry *entry,
|
||||
if (entry->type == SOCK_PE_RX) {
|
||||
err_entry.buf = (void *) (uintptr_t) entry->pe.rx.rx_iov[0].iov.addr;
|
||||
}else {
|
||||
err_entry.buf = (void *) (uintptr_t) entry->pe.tx.data.tx_iov[0].src.iov.addr;
|
||||
err_entry.buf = (void *) (uintptr_t) entry->pe.tx.tx_iov[0].src.iov.addr;
|
||||
}
|
||||
|
||||
rbwrite(&cq->cqerr_rb, &err_entry, sizeof(err_entry));
|
||||
|
@ -34,7 +34,6 @@
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -50,13 +49,17 @@ const struct fi_domain_attr sock_domain_attr = {
|
||||
.control_progress = FI_PROGRESS_AUTO,
|
||||
.data_progress = FI_PROGRESS_AUTO,
|
||||
.resource_mgmt = FI_RM_ENABLED,
|
||||
.mr_mode = FI_MR_SCALABLE,
|
||||
.mr_key_size = sizeof(uint16_t),
|
||||
.cq_data_size = sizeof(uint64_t),
|
||||
.cq_cnt = SOCK_EP_MAX_CQ_CNT,
|
||||
.ep_cnt = SOCK_EP_MAX_EP_CNT,
|
||||
.tx_ctx_cnt = SOCK_EP_MAX_TX_CNT,
|
||||
.rx_ctx_cnt = SOCK_EP_MAX_RX_CNT,
|
||||
.max_ep_tx_ctx = SOCK_EP_MAX_TX_CNT,
|
||||
.max_ep_rx_ctx = SOCK_EP_MAX_RX_CNT,
|
||||
.max_ep_stx_ctx = SOCK_EP_MAX_EP_CNT,
|
||||
.max_ep_srx_ctx = SOCK_EP_MAX_EP_CNT,
|
||||
};
|
||||
|
||||
int sock_verify_domain_attr(struct fi_domain_attr *attr)
|
||||
@ -114,10 +117,37 @@ int sock_verify_domain_attr(struct fi_domain_attr *attr)
|
||||
SOCK_LOG_INFO("Resource mgmt not supported!\n");
|
||||
return -FI_ENODATA;
|
||||
}
|
||||
|
||||
switch (attr->av_type) {
|
||||
case FI_AV_UNSPEC:
|
||||
case FI_AV_MAP:
|
||||
case FI_AV_TABLE:
|
||||
break;
|
||||
|
||||
default:
|
||||
SOCK_LOG_INFO("AV type not supported!\n");
|
||||
return -FI_ENODATA;
|
||||
}
|
||||
|
||||
switch (attr->mr_mode) {
|
||||
case FI_MR_UNSPEC:
|
||||
case FI_MR_BASIC:
|
||||
case FI_MR_SCALABLE:
|
||||
break;
|
||||
default:
|
||||
SOCK_LOG_INFO("MR mode not supported\n");
|
||||
return -FI_ENODATA;
|
||||
}
|
||||
|
||||
if(attr->mr_key_size > sock_domain_attr.mr_key_size)
|
||||
return -FI_ENODATA;
|
||||
|
||||
if(attr->cq_data_size > sock_domain_attr.cq_data_size)
|
||||
return -FI_ENODATA;
|
||||
|
||||
if(attr->cq_cnt > sock_domain_attr.cq_cnt)
|
||||
return -FI_ENODATA;
|
||||
|
||||
if(attr->ep_cnt > sock_domain_attr.ep_cnt)
|
||||
return -FI_ENODATA;
|
||||
|
||||
@ -144,6 +174,7 @@ static int sock_dom_close(struct fid *fid)
|
||||
|
||||
sock_pe_finalize(dom->pe);
|
||||
fastlock_destroy(&dom->lock);
|
||||
sock_dom_remove_from_list(dom);
|
||||
free(dom);
|
||||
return 0;
|
||||
}
|
||||
@ -184,14 +215,18 @@ static int sock_mr_bind(struct fid *fid, struct fid *bfid, uint64_t flags)
|
||||
switch (bfid->fclass) {
|
||||
case FI_CLASS_CQ:
|
||||
cq = container_of(bfid, struct sock_cq, cq_fid.fid);
|
||||
assert(mr->domain == cq->domain);
|
||||
if (mr->domain != cq->domain)
|
||||
return -FI_EINVAL;
|
||||
|
||||
if (flags & FI_REMOTE_WRITE)
|
||||
mr->cq = cq;
|
||||
break;
|
||||
|
||||
case FI_CLASS_CNTR:
|
||||
cntr = container_of(bfid, struct sock_cntr, cntr_fid.fid);
|
||||
assert(mr->domain == cntr->domain);
|
||||
if (mr->domain != cntr->domain)
|
||||
return -FI_EINVAL;
|
||||
|
||||
if (flags & FI_REMOTE_WRITE)
|
||||
mr->cntr = cntr;
|
||||
break;
|
||||
@ -225,7 +260,7 @@ struct sock_mr *sock_mr_verify_key(struct sock_domain *domain, uint16_t key,
|
||||
if (!mr)
|
||||
return NULL;
|
||||
|
||||
if (mr->flags & FI_MR_OFFSET)
|
||||
if (domain->attr.mr_mode == FI_MR_SCALABLE)
|
||||
buf = (char*)buf + mr->offset;
|
||||
|
||||
for (i = 0; i < mr->iov_count; i++) {
|
||||
@ -256,20 +291,19 @@ static int sock_regattr(struct fid *fid, const struct fi_mr_attr *attr,
|
||||
uint64_t key;
|
||||
struct fid_domain *domain;
|
||||
|
||||
if (fid->fclass != FI_CLASS_DOMAIN) {
|
||||
SOCK_LOG_ERROR("memory registration only supported "
|
||||
"for struct fid_domain\n");
|
||||
if (fid->fclass != FI_CLASS_DOMAIN || !attr || attr->iov_count <= 0) {
|
||||
return -FI_EINVAL;
|
||||
}
|
||||
|
||||
domain = container_of(fid, struct fid_domain, fid);
|
||||
|
||||
dom = container_of(domain, struct sock_domain, dom_fid);
|
||||
if (!(dom->info.mode & FI_PROV_MR_ATTR) &&
|
||||
if ((dom->attr.mr_mode == FI_MR_SCALABLE) &&
|
||||
((attr->requested_key > IDX_MAX_INDEX) ||
|
||||
idm_lookup(&dom->mr_idm, (int) attr->requested_key)))
|
||||
idm_lookup(&dom->mr_idm, (int) attr->requested_key)))
|
||||
return -FI_ENOKEY;
|
||||
|
||||
_mr = calloc(1, sizeof(*_mr) + sizeof(_mr->mr_iov) * (attr->iov_count - 1));
|
||||
|
||||
_mr = calloc(1, sizeof(*_mr) +
|
||||
sizeof(_mr->mr_iov) * (attr->iov_count - 1));
|
||||
if (!_mr)
|
||||
return -FI_ENOMEM;
|
||||
|
||||
@ -280,13 +314,13 @@ static int sock_regattr(struct fid *fid, const struct fi_mr_attr *attr,
|
||||
_mr->domain = dom;
|
||||
_mr->access = attr->access;
|
||||
_mr->flags = flags;
|
||||
_mr->offset = (flags & FI_MR_OFFSET) ?
|
||||
_mr->offset = (dom->attr.mr_mode == FI_MR_SCALABLE) ?
|
||||
(uintptr_t) attr->mr_iov[0].iov_base + attr->offset :
|
||||
(uintptr_t) attr->mr_iov[0].iov_base;
|
||||
|
||||
fastlock_acquire(&dom->lock);
|
||||
key = (dom->info.mode & FI_PROV_MR_ATTR) ?
|
||||
sock_get_mr_key(dom) : (uint16_t) attr->requested_key;
|
||||
key = (dom->attr.mr_mode == FI_MR_BASIC) ?
|
||||
sock_get_mr_key(dom) : (uint16_t) attr->requested_key;
|
||||
if (idm_set(&dom->mr_idm, key, _mr) < 0)
|
||||
goto err;
|
||||
_mr->mr_fid.key = key;
|
||||
@ -434,9 +468,9 @@ int sock_domain(struct fid_fabric *fabric, struct fi_info *info,
|
||||
sock_domain = calloc(1, sizeof *sock_domain);
|
||||
if (!sock_domain)
|
||||
return -FI_ENOMEM;
|
||||
|
||||
|
||||
fastlock_init(&sock_domain->lock);
|
||||
atomic_init(&sock_domain->ref, 0);
|
||||
atomic_initialize(&sock_domain->ref, 0);
|
||||
|
||||
if (info) {
|
||||
sock_domain->info = *info;
|
||||
@ -471,6 +505,13 @@ int sock_domain(struct fid_fabric *fabric, struct fi_info *info,
|
||||
|
||||
sock_domain->fab = fab;
|
||||
*dom = &sock_domain->dom_fid;
|
||||
|
||||
if (info->domain_attr)
|
||||
sock_domain->attr = *(info->domain_attr);
|
||||
else
|
||||
sock_domain->attr = sock_domain_attr;
|
||||
|
||||
sock_dom_add_to_list(sock_domain);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
|
@ -34,7 +34,6 @@
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -59,18 +58,22 @@ extern const struct fi_fabric_attr sock_fabric_attr;
|
||||
|
||||
const struct fi_tx_attr sock_stx_attr = {
|
||||
.caps = SOCK_EP_RDM_CAP,
|
||||
.mode = SOCK_MODE,
|
||||
.op_flags = FI_TRANSMIT_COMPLETE,
|
||||
.msg_order = SOCK_EP_MSG_ORDER,
|
||||
.inject_size = SOCK_EP_MAX_INJECT_SZ,
|
||||
.size = SOCK_EP_TX_SZ,
|
||||
.iov_limit = SOCK_EP_MAX_IOV_LIMIT,
|
||||
.rma_iov_limit = SOCK_EP_MAX_IOV_LIMIT,
|
||||
};
|
||||
|
||||
const struct fi_rx_attr sock_srx_attr = {
|
||||
.caps = SOCK_EP_RDM_CAP,
|
||||
.mode = SOCK_MODE,
|
||||
.op_flags = 0,
|
||||
.msg_order = SOCK_EP_MSG_ORDER,
|
||||
.total_buffered_recv = SOCK_EP_MAX_BUFF_RECV,
|
||||
.comp_order = SOCK_EP_COMP_ORDER,
|
||||
.total_buffered_recv = 0,
|
||||
.size = SOCK_EP_MAX_MSG_SZ,
|
||||
.iov_limit = SOCK_EP_MAX_IOV_LIMIT,
|
||||
};
|
||||
@ -84,7 +87,7 @@ static int sock_ctx_close(struct fid *fid)
|
||||
case FI_CLASS_TX_CTX:
|
||||
tx_ctx = container_of(fid, struct sock_tx_ctx, fid.ctx.fid);
|
||||
sock_pe_remove_tx_ctx(tx_ctx);
|
||||
atomic_dec(&tx_ctx->ep->num_rx_ctx);
|
||||
atomic_dec(&tx_ctx->ep->num_tx_ctx);
|
||||
atomic_dec(&tx_ctx->domain->ref);
|
||||
sock_tx_ctx_free(tx_ctx);
|
||||
break;
|
||||
@ -130,19 +133,19 @@ static int sock_ctx_bind_cq(struct fid *fid, struct fid *bfid, uint64_t flags)
|
||||
tx_ctx = container_of(fid, struct sock_tx_ctx, fid.ctx);
|
||||
if (flags & FI_SEND) {
|
||||
tx_ctx->comp.send_cq = sock_cq;
|
||||
if (flags & FI_COMPLETION)
|
||||
if (flags & FI_SELECTIVE_COMPLETION)
|
||||
tx_ctx->comp.send_cq_event = 1;
|
||||
}
|
||||
|
||||
if (flags & FI_READ) {
|
||||
tx_ctx->comp.read_cq = sock_cq;
|
||||
if (flags & FI_COMPLETION)
|
||||
if (flags & FI_SELECTIVE_COMPLETION)
|
||||
tx_ctx->comp.read_cq_event = 1;
|
||||
}
|
||||
|
||||
if (flags & FI_WRITE) {
|
||||
tx_ctx->comp.write_cq = sock_cq;
|
||||
if (flags & FI_COMPLETION)
|
||||
if (flags & FI_SELECTIVE_COMPLETION)
|
||||
tx_ctx->comp.write_cq_event = 1;
|
||||
}
|
||||
|
||||
@ -155,7 +158,7 @@ static int sock_ctx_bind_cq(struct fid *fid, struct fid *bfid, uint64_t flags)
|
||||
rx_ctx = container_of(fid, struct sock_rx_ctx, ctx.fid);
|
||||
if (flags & FI_RECV) {
|
||||
rx_ctx->comp.recv_cq = sock_cq;
|
||||
if (flags & FI_COMPLETION)
|
||||
if (flags & FI_SELECTIVE_COMPLETION)
|
||||
rx_ctx->comp.recv_cq_event = 1;
|
||||
}
|
||||
|
||||
@ -168,19 +171,19 @@ static int sock_ctx_bind_cq(struct fid *fid, struct fid *bfid, uint64_t flags)
|
||||
tx_ctx = container_of(fid, struct sock_tx_ctx, fid.stx.fid);
|
||||
if (flags & FI_SEND) {
|
||||
tx_ctx->comp.send_cq = sock_cq;
|
||||
if (flags & FI_COMPLETION)
|
||||
if (flags & FI_SELECTIVE_COMPLETION)
|
||||
tx_ctx->comp.send_cq_event = 1;
|
||||
}
|
||||
|
||||
if (flags & FI_READ) {
|
||||
tx_ctx->comp.read_cq = sock_cq;
|
||||
if (flags & FI_COMPLETION)
|
||||
if (flags & FI_SELECTIVE_COMPLETION)
|
||||
tx_ctx->comp.read_cq_event = 1;
|
||||
}
|
||||
|
||||
if (flags & FI_WRITE) {
|
||||
tx_ctx->comp.write_cq = sock_cq;
|
||||
if (flags & FI_COMPLETION)
|
||||
if (flags & FI_SELECTIVE_COMPLETION)
|
||||
tx_ctx->comp.write_cq_event = 1;
|
||||
}
|
||||
|
||||
@ -292,6 +295,10 @@ static int sock_ctx_enable(struct fid_ep *ep)
|
||||
sock_pe_add_rx_ctx(rx_ctx->domain->pe, rx_ctx);
|
||||
rx_ctx->progress = 1;
|
||||
}
|
||||
if (!rx_ctx->ep->listener.listener_thread &&
|
||||
sock_conn_listen(rx_ctx->ep)) {
|
||||
SOCK_LOG_ERROR("failed to create listener\n");
|
||||
}
|
||||
return 0;
|
||||
|
||||
case FI_CLASS_TX_CTX:
|
||||
@ -301,6 +308,10 @@ static int sock_ctx_enable(struct fid_ep *ep)
|
||||
sock_pe_add_tx_ctx(tx_ctx->domain->pe, tx_ctx);
|
||||
tx_ctx->progress = 1;
|
||||
}
|
||||
if (!tx_ctx->ep->listener.listener_thread &&
|
||||
sock_conn_listen(tx_ctx->ep)) {
|
||||
SOCK_LOG_ERROR("failed to create listener\n");
|
||||
}
|
||||
return 0;
|
||||
|
||||
default:
|
||||
@ -479,10 +490,6 @@ static ssize_t sock_ep_cancel(fid_t fid, void *context)
|
||||
return -FI_EINVAL;
|
||||
}
|
||||
|
||||
if (!(sock_ep->info.caps & FI_CANCEL)) {
|
||||
return -FI_EINVAL;
|
||||
}
|
||||
|
||||
return sock_rx_ctx_cancel(rx_ctx, context);
|
||||
}
|
||||
|
||||
@ -592,7 +599,8 @@ static int sock_ep_close(struct fid *fid)
|
||||
SOCK_LOG_INFO("Failed to signal\n");
|
||||
}
|
||||
|
||||
if (pthread_join(sock_ep->listener.listener_thread, NULL)) {
|
||||
if (sock_ep->listener.listener_thread &&
|
||||
pthread_join(sock_ep->listener.listener_thread, NULL)) {
|
||||
SOCK_LOG_ERROR("pthread join failed (%d)\n", errno);
|
||||
}
|
||||
|
||||
@ -661,29 +669,30 @@ static int sock_ep_bind(struct fid *fid, struct fid *bfid, uint64_t flags)
|
||||
|
||||
case FI_CLASS_CQ:
|
||||
cq = container_of(bfid, struct sock_cq, cq_fid.fid);
|
||||
assert(ep->domain == cq->domain);
|
||||
if (ep->domain != cq->domain)
|
||||
return -FI_EINVAL;
|
||||
|
||||
if (flags & FI_SEND) {
|
||||
ep->comp.send_cq = cq;
|
||||
if (flags & FI_COMPLETION)
|
||||
if (flags & FI_SELECTIVE_COMPLETION)
|
||||
ep->comp.send_cq_event = 1;
|
||||
}
|
||||
|
||||
if (flags & FI_READ) {
|
||||
ep->comp.read_cq = cq;
|
||||
if (flags & FI_COMPLETION)
|
||||
if (flags & FI_SELECTIVE_COMPLETION)
|
||||
ep->comp.read_cq_event = 1;
|
||||
}
|
||||
|
||||
if (flags & FI_WRITE) {
|
||||
ep->comp.write_cq = cq;
|
||||
if (flags & FI_COMPLETION)
|
||||
if (flags & FI_SELECTIVE_COMPLETION)
|
||||
ep->comp.write_cq_event = 1;
|
||||
}
|
||||
|
||||
if (flags & FI_RECV) {
|
||||
ep->comp.recv_cq = cq;
|
||||
if (flags & FI_COMPLETION)
|
||||
if (flags & FI_SELECTIVE_COMPLETION)
|
||||
ep->comp.recv_cq_event = 1;
|
||||
}
|
||||
|
||||
@ -710,7 +719,7 @@ static int sock_ep_bind(struct fid *fid, struct fid *bfid, uint64_t flags)
|
||||
if (rx_ctx->ctx.fid.fclass == FI_CLASS_SRX_CTX) {
|
||||
if (flags & FI_RECV) {
|
||||
ep->comp.recv_cq = cq;
|
||||
if (flags & FI_COMPLETION)
|
||||
if (flags & FI_SELECTIVE_COMPLETION)
|
||||
ep->comp.recv_cq_event = 1;
|
||||
}
|
||||
|
||||
@ -729,7 +738,8 @@ static int sock_ep_bind(struct fid *fid, struct fid *bfid, uint64_t flags)
|
||||
|
||||
case FI_CLASS_CNTR:
|
||||
cntr = container_of(bfid, struct sock_cntr, cntr_fid.fid);
|
||||
assert(ep->domain == cntr->domain);
|
||||
if (ep->domain != cntr->domain)
|
||||
return -FI_EINVAL;
|
||||
|
||||
if (flags & FI_SEND)
|
||||
ep->comp.send_cntr = cntr;
|
||||
@ -796,7 +806,8 @@ static int sock_ep_bind(struct fid *fid, struct fid *bfid, uint64_t flags)
|
||||
|
||||
case FI_CLASS_AV:
|
||||
av = container_of(bfid, struct sock_av, av_fid.fid);
|
||||
assert(ep->domain == av->domain);
|
||||
if (ep->domain != av->domain)
|
||||
return -FI_EINVAL;
|
||||
|
||||
ep->av = av;
|
||||
av->cmap = &av->domain->r_cmap;
|
||||
@ -944,6 +955,10 @@ int sock_ep_enable(struct fid_ep *ep)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sock_ep->ep_type != FI_EP_MSG &&
|
||||
!sock_ep->listener.listener_thread && sock_conn_listen(sock_ep))
|
||||
SOCK_LOG_ERROR("cannot start connection thread\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1033,7 +1048,7 @@ static int sock_ep_tx_ctx(struct fid_ep *ep, int index, struct fi_tx_attr *attr,
|
||||
struct sock_tx_ctx *tx_ctx;
|
||||
|
||||
sock_ep = container_of(ep, struct sock_ep, ep);
|
||||
if (index >= sock_ep->ep_attr.tx_ctx_cnt)
|
||||
if (sock_ep->fclass != FI_CLASS_SEP || index >= sock_ep->ep_attr.tx_ctx_cnt)
|
||||
return -FI_EINVAL;
|
||||
|
||||
tx_ctx = sock_tx_ctx_alloc(&sock_ep->tx_attr, context);
|
||||
@ -1043,6 +1058,7 @@ static int sock_ep_tx_ctx(struct fid_ep *ep, int index, struct fi_tx_attr *attr,
|
||||
tx_ctx->tx_id = index;
|
||||
tx_ctx->ep = sock_ep;
|
||||
tx_ctx->domain = sock_ep->domain;
|
||||
tx_ctx->av = sock_ep->av;
|
||||
dlist_insert_tail(&sock_ep->tx_ctx_entry, &tx_ctx->ep_list);
|
||||
|
||||
tx_ctx->fid.ctx.fid.ops = &sock_ctx_ops;
|
||||
@ -1066,19 +1082,17 @@ static int sock_ep_rx_ctx(struct fid_ep *ep, int index, struct fi_rx_attr *attr,
|
||||
struct sock_rx_ctx *rx_ctx;
|
||||
|
||||
sock_ep = container_of(ep, struct sock_ep, ep);
|
||||
if (index >= sock_ep->ep_attr.rx_ctx_cnt)
|
||||
if (sock_ep->fclass != FI_CLASS_SEP || index >= sock_ep->ep_attr.rx_ctx_cnt)
|
||||
return -FI_EINVAL;
|
||||
|
||||
rx_ctx = sock_rx_ctx_alloc(attr, context);
|
||||
rx_ctx = sock_rx_ctx_alloc(attr ? attr : &sock_ep->rx_attr, context);
|
||||
if (!rx_ctx)
|
||||
return -FI_ENOMEM;
|
||||
|
||||
rx_ctx->attr.total_buffered_recv = rx_ctx->attr.total_buffered_recv ?
|
||||
rx_ctx->attr.total_buffered_recv : SOCK_EP_MAX_BUFF_RECV;
|
||||
|
||||
rx_ctx->rx_id = index;
|
||||
rx_ctx->ep = sock_ep;
|
||||
rx_ctx->domain = sock_ep->domain;
|
||||
rx_ctx->av = sock_ep->av;
|
||||
dlist_insert_tail(&sock_ep->rx_ctx_entry, &rx_ctx->ep_list);
|
||||
|
||||
rx_ctx->ctx.fid.ops = &sock_ctx_ops;
|
||||
@ -1119,6 +1133,9 @@ static int sock_verify_tx_attr(const struct fi_tx_attr *attr)
|
||||
if (attr->iov_limit > SOCK_EP_MAX_IOV_LIMIT)
|
||||
return -FI_ENODATA;
|
||||
|
||||
if (attr->rma_iov_limit > SOCK_EP_MAX_IOV_LIMIT)
|
||||
return -FI_ENODATA;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1153,6 +1170,12 @@ static int sock_verify_rx_attr(const struct fi_rx_attr *attr)
|
||||
if (!attr)
|
||||
return 0;
|
||||
|
||||
if ((attr->msg_order | SOCK_EP_MSG_ORDER) != SOCK_EP_MSG_ORDER)
|
||||
return -FI_ENODATA;
|
||||
|
||||
if ((attr->comp_order | SOCK_EP_COMP_ORDER) != SOCK_EP_COMP_ORDER)
|
||||
return -FI_ENODATA;
|
||||
|
||||
if (attr->total_buffered_recv > SOCK_EP_MAX_BUFF_RECV)
|
||||
return -FI_ENODATA;
|
||||
|
||||
@ -1188,15 +1211,79 @@ int sock_srx_ctx(struct fid_domain *domain,
|
||||
rx_ctx->ctx.tagged = &sock_ep_tagged;
|
||||
|
||||
/* default config */
|
||||
rx_ctx->min_multi_recv = SOCK_EP_MIN_MULTI_RECV;
|
||||
rx_ctx->attr.total_buffered_recv = rx_ctx->attr.total_buffered_recv ?
|
||||
rx_ctx->attr.total_buffered_recv : SOCK_EP_MAX_BUFF_RECV;
|
||||
|
||||
rx_ctx->min_multi_recv = SOCK_EP_MIN_MULTI_RECV;
|
||||
*srx = &rx_ctx->ctx;
|
||||
atomic_inc(&dom->ref);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sock_set_fabric_attr(const struct fi_fabric_attr *hint_attr,
|
||||
struct fi_fabric_attr *attr)
|
||||
{
|
||||
struct sock_fabric *fabric;
|
||||
|
||||
*attr = sock_fabric_attr;
|
||||
if (hint_attr && hint_attr->fabric) {
|
||||
attr->fabric = hint_attr->fabric;
|
||||
} else {
|
||||
fabric = sock_fab_list_head();
|
||||
attr->fabric = fabric ? &fabric->fab_fid : NULL;
|
||||
}
|
||||
attr->name = strdup(sock_fab_name);
|
||||
attr->prov_name = strdup(sock_prov_name);
|
||||
}
|
||||
|
||||
static void sock_set_domain_attr(const struct fi_domain_attr *hint_attr,
|
||||
struct fi_domain_attr *attr)
|
||||
{
|
||||
struct sock_domain *domain;
|
||||
|
||||
domain = sock_dom_list_head();
|
||||
attr->domain = domain ? &domain->dom_fid : NULL;
|
||||
if (!hint_attr) {
|
||||
*attr = sock_domain_attr;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (hint_attr->domain) {
|
||||
domain = container_of(hint_attr->domain,
|
||||
struct sock_domain, dom_fid);
|
||||
*attr = domain->attr;
|
||||
attr->domain = hint_attr->domain;
|
||||
goto out;
|
||||
}
|
||||
|
||||
*attr = *hint_attr;
|
||||
if (attr->threading == FI_THREAD_UNSPEC)
|
||||
attr->threading = sock_domain_attr.threading;
|
||||
if (attr->control_progress == FI_PROGRESS_UNSPEC)
|
||||
attr->control_progress = sock_domain_attr.control_progress;
|
||||
if (attr->data_progress == FI_PROGRESS_UNSPEC)
|
||||
attr->data_progress = sock_domain_attr.data_progress;
|
||||
if (attr->mr_mode == FI_MR_UNSPEC)
|
||||
attr->mr_mode = sock_domain_attr.mr_mode;
|
||||
|
||||
if (attr->cq_cnt == 0)
|
||||
attr->cq_cnt = sock_domain_attr.cq_cnt;
|
||||
if (attr->ep_cnt == 0)
|
||||
attr->ep_cnt = sock_domain_attr.ep_cnt;
|
||||
if (attr->tx_ctx_cnt == 0)
|
||||
attr->tx_ctx_cnt = sock_domain_attr.tx_ctx_cnt;
|
||||
if (attr->rx_ctx_cnt == 0)
|
||||
attr->rx_ctx_cnt = sock_domain_attr.rx_ctx_cnt;
|
||||
if (attr->max_ep_tx_ctx == 0)
|
||||
attr->max_ep_tx_ctx = sock_domain_attr.max_ep_tx_ctx;
|
||||
if (attr->max_ep_rx_ctx == 0)
|
||||
attr->max_ep_rx_ctx = sock_domain_attr.max_ep_rx_ctx;
|
||||
|
||||
attr->mr_key_size = sock_domain_attr.mr_key_size;
|
||||
attr->cq_data_size = sock_domain_attr.cq_data_size;
|
||||
attr->resource_mgmt = sock_domain_attr.resource_mgmt;
|
||||
out:
|
||||
attr->name = strdup(sock_dom_name);
|
||||
}
|
||||
|
||||
|
||||
struct fi_info *sock_fi_info(enum fi_ep_type ep_type, struct fi_info *hints,
|
||||
void *src_addr, void *dest_addr)
|
||||
{
|
||||
@ -1233,16 +1320,15 @@ struct fi_info *sock_fi_info(enum fi_ep_type ep_type, struct fi_info *hints,
|
||||
|
||||
if (hints->rx_attr)
|
||||
*(info->rx_attr) = *(hints->rx_attr);
|
||||
|
||||
sock_set_domain_attr(hints->domain_attr, info->domain_attr);
|
||||
sock_set_fabric_attr(hints->fabric_attr, info->fabric_attr);
|
||||
} else {
|
||||
sock_set_domain_attr(NULL, info->domain_attr);
|
||||
sock_set_fabric_attr(NULL, info->fabric_attr);
|
||||
}
|
||||
|
||||
info->ep_attr->type = ep_type;
|
||||
*(info->domain_attr) = sock_domain_attr;
|
||||
*(info->fabric_attr) = sock_fabric_attr;
|
||||
|
||||
info->domain_attr->name = strdup(sock_dom_name);
|
||||
info->fabric_attr->name = strdup(sock_fab_name);
|
||||
info->fabric_attr->prov_name = strdup(sock_prov_name);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
@ -1332,17 +1418,13 @@ int sock_alloc_endpoint(struct fid_domain *domain, struct fi_info *info,
|
||||
if (info->rx_attr) {
|
||||
sock_ep->rx_attr = *info->rx_attr;
|
||||
sock_ep->op_flags |= info->rx_attr->op_flags;
|
||||
sock_ep->rx_attr.total_buffered_recv =
|
||||
sock_ep->rx_attr.total_buffered_recv ?
|
||||
sock_ep->rx_attr.total_buffered_recv :
|
||||
SOCK_EP_MAX_BUFF_RECV;
|
||||
}
|
||||
sock_ep->info.connreq = info->connreq;
|
||||
sock_ep->info.handle = info->handle;
|
||||
}
|
||||
|
||||
atomic_init(&sock_ep->ref, 0);
|
||||
atomic_init(&sock_ep->num_tx_ctx, 0);
|
||||
atomic_init(&sock_ep->num_rx_ctx, 0);
|
||||
atomic_initialize(&sock_ep->ref, 0);
|
||||
atomic_initialize(&sock_ep->num_tx_ctx, 0);
|
||||
atomic_initialize(&sock_ep->num_rx_ctx, 0);
|
||||
|
||||
if (sock_ep->ep_attr.tx_ctx_cnt == FI_SHARED_CONTEXT)
|
||||
sock_ep->tx_shared = 1;
|
||||
@ -1392,9 +1474,6 @@ int sock_alloc_endpoint(struct fid_domain *domain, struct fi_info *info,
|
||||
}
|
||||
|
||||
sock_ep->domain = sock_dom;
|
||||
if (sock_conn_listen(sock_ep))
|
||||
goto err;
|
||||
|
||||
fastlock_init(&sock_ep->cm.lock);
|
||||
if (sock_ep->ep_type == FI_EP_MSG) {
|
||||
dlist_init(&sock_ep->cm.msg_list);
|
||||
|
@ -61,7 +61,9 @@
|
||||
const struct fi_ep_attr sock_dgram_ep_attr = {
|
||||
.type = FI_EP_DGRAM,
|
||||
.protocol = FI_PROTO_SOCK_TCP,
|
||||
.protocol_version = SOCK_WIRE_PROTO_VERSION,
|
||||
.max_msg_size = SOCK_EP_MAX_MSG_SZ,
|
||||
.msg_prefix_size = SOCK_EP_MSG_PREFIX_SZ,
|
||||
.max_order_raw_size = SOCK_EP_MAX_ORDER_RAW_SZ,
|
||||
.max_order_war_size = SOCK_EP_MAX_ORDER_WAR_SZ,
|
||||
.max_order_waw_size = SOCK_EP_MAX_ORDER_WAW_SZ,
|
||||
@ -72,17 +74,21 @@ const struct fi_ep_attr sock_dgram_ep_attr = {
|
||||
|
||||
const struct fi_tx_attr sock_dgram_tx_attr = {
|
||||
.caps = SOCK_EP_DGRAM_CAP,
|
||||
.mode = SOCK_MODE,
|
||||
.op_flags = FI_TRANSMIT_COMPLETE,
|
||||
.msg_order = SOCK_EP_MSG_ORDER,
|
||||
.inject_size = SOCK_EP_MAX_INJECT_SZ,
|
||||
.size = SOCK_EP_TX_SZ,
|
||||
.iov_limit = SOCK_EP_MAX_IOV_LIMIT,
|
||||
.rma_iov_limit = 0,
|
||||
};
|
||||
|
||||
const struct fi_rx_attr sock_dgram_rx_attr = {
|
||||
.caps = SOCK_EP_DGRAM_CAP,
|
||||
.mode = SOCK_MODE,
|
||||
.op_flags = 0,
|
||||
.msg_order = SOCK_EP_MSG_ORDER,
|
||||
.comp_order = SOCK_EP_COMP_ORDER,
|
||||
.total_buffered_recv = SOCK_EP_MAX_BUFF_RECV,
|
||||
.size = SOCK_EP_RX_SZ,
|
||||
.iov_limit = SOCK_EP_MAX_IOV_LIMIT,
|
||||
@ -99,6 +105,9 @@ static int sock_dgram_verify_rx_attr(const struct fi_rx_attr *attr)
|
||||
if ((attr->msg_order | SOCK_EP_MSG_ORDER) != SOCK_EP_MSG_ORDER)
|
||||
return -FI_ENODATA;
|
||||
|
||||
if ((attr->comp_order | SOCK_EP_COMP_ORDER) != SOCK_EP_COMP_ORDER)
|
||||
return -FI_ENODATA;
|
||||
|
||||
if (attr->total_buffered_recv > sock_dgram_rx_attr.total_buffered_recv)
|
||||
return -FI_ENODATA;
|
||||
|
||||
@ -131,6 +140,9 @@ static int sock_dgram_verify_tx_attr(const struct fi_tx_attr *attr)
|
||||
if (attr->iov_limit > sock_dgram_tx_attr.iov_limit)
|
||||
return -FI_ENODATA;
|
||||
|
||||
if (attr->rma_iov_limit > sock_dgram_tx_attr.rma_iov_limit)
|
||||
return -FI_ENODATA;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -147,9 +159,15 @@ int sock_dgram_verify_ep_attr(struct fi_ep_attr *ep_attr,
|
||||
return -FI_ENODATA;
|
||||
}
|
||||
|
||||
if (ep_attr->protocol_version != sock_dgram_ep_attr.protocol_version)
|
||||
return -FI_ENODATA;
|
||||
|
||||
if (ep_attr->max_msg_size > sock_dgram_ep_attr.max_msg_size)
|
||||
return -FI_ENODATA;
|
||||
|
||||
if (ep_attr->msg_prefix_size > sock_dgram_ep_attr.msg_prefix_size)
|
||||
return -FI_ENODATA;
|
||||
|
||||
if (ep_attr->max_order_raw_size >
|
||||
sock_dgram_ep_attr.max_order_raw_size)
|
||||
return -FI_ENODATA;
|
||||
@ -188,6 +206,21 @@ int sock_dgram_fi_info(void *src_addr, void *dest_addr, struct fi_info *hints,
|
||||
*(*info)->rx_attr = sock_dgram_rx_attr;
|
||||
*(*info)->ep_attr = sock_dgram_ep_attr;
|
||||
|
||||
if (hints && hints->ep_attr) {
|
||||
if (hints->ep_attr->rx_ctx_cnt)
|
||||
(*info)->ep_attr->rx_ctx_cnt = hints->ep_attr->rx_ctx_cnt;
|
||||
if (hints->ep_attr->tx_ctx_cnt)
|
||||
(*info)->ep_attr->tx_ctx_cnt = hints->ep_attr->tx_ctx_cnt;
|
||||
}
|
||||
|
||||
if (hints && hints->rx_attr) {
|
||||
(*info)->rx_attr->op_flags |= hints->rx_attr->op_flags;
|
||||
}
|
||||
|
||||
if (hints && hints->tx_attr) {
|
||||
(*info)->tx_attr->op_flags |= hints->tx_attr->op_flags;
|
||||
}
|
||||
|
||||
(*info)->caps = SOCK_EP_DGRAM_CAP|
|
||||
(*info)->rx_attr->caps | (*info)->tx_attr->caps;
|
||||
return 0;
|
||||
|
@ -63,7 +63,9 @@
|
||||
static const struct fi_ep_attr sock_msg_ep_attr = {
|
||||
.type = FI_EP_MSG,
|
||||
.protocol = FI_PROTO_SOCK_TCP,
|
||||
.protocol_version = SOCK_WIRE_PROTO_VERSION,
|
||||
.max_msg_size = SOCK_EP_MAX_MSG_SZ,
|
||||
.msg_prefix_size = SOCK_EP_MSG_PREFIX_SZ,
|
||||
.max_order_raw_size = SOCK_EP_MAX_ORDER_RAW_SZ,
|
||||
.max_order_war_size = SOCK_EP_MAX_ORDER_WAR_SZ,
|
||||
.max_order_waw_size = SOCK_EP_MAX_ORDER_WAW_SZ,
|
||||
@ -74,17 +76,21 @@ static const struct fi_ep_attr sock_msg_ep_attr = {
|
||||
|
||||
static const struct fi_tx_attr sock_msg_tx_attr = {
|
||||
.caps = SOCK_EP_MSG_CAP,
|
||||
.mode = SOCK_MODE,
|
||||
.op_flags = FI_TRANSMIT_COMPLETE,
|
||||
.msg_order = SOCK_EP_MSG_ORDER,
|
||||
.inject_size = SOCK_EP_MAX_INJECT_SZ,
|
||||
.size = SOCK_EP_TX_SZ,
|
||||
.iov_limit = SOCK_EP_MAX_IOV_LIMIT,
|
||||
.rma_iov_limit = SOCK_EP_MAX_IOV_LIMIT,
|
||||
};
|
||||
|
||||
static const struct fi_rx_attr sock_msg_rx_attr = {
|
||||
.caps = SOCK_EP_MSG_CAP,
|
||||
.mode = SOCK_MODE,
|
||||
.op_flags = 0,
|
||||
.msg_order = SOCK_EP_MSG_ORDER,
|
||||
.comp_order = SOCK_EP_COMP_ORDER,
|
||||
.total_buffered_recv = SOCK_EP_MAX_BUFF_RECV,
|
||||
.size = SOCK_EP_RX_SZ,
|
||||
.iov_limit = SOCK_EP_MAX_IOV_LIMIT,
|
||||
@ -101,6 +107,9 @@ static int sock_msg_verify_rx_attr(const struct fi_rx_attr *attr)
|
||||
if ((attr->msg_order | SOCK_EP_MSG_ORDER) != SOCK_EP_MSG_ORDER)
|
||||
return -FI_ENODATA;
|
||||
|
||||
if ((attr->comp_order | SOCK_EP_COMP_ORDER) != SOCK_EP_COMP_ORDER)
|
||||
return -FI_ENODATA;
|
||||
|
||||
if (attr->total_buffered_recv > sock_msg_rx_attr.total_buffered_recv)
|
||||
return -FI_ENODATA;
|
||||
|
||||
@ -133,6 +142,9 @@ static int sock_msg_verify_tx_attr(const struct fi_tx_attr *attr)
|
||||
if (attr->iov_limit > sock_msg_tx_attr.iov_limit)
|
||||
return -FI_ENODATA;
|
||||
|
||||
if (attr->rma_iov_limit > sock_msg_tx_attr.rma_iov_limit)
|
||||
return -FI_ENODATA;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -149,9 +161,15 @@ int sock_msg_verify_ep_attr(struct fi_ep_attr *ep_attr,
|
||||
return -FI_ENODATA;
|
||||
}
|
||||
|
||||
if (ep_attr->protocol_version != sock_msg_ep_attr.protocol_version)
|
||||
return -FI_ENODATA;
|
||||
|
||||
if (ep_attr->max_msg_size > sock_msg_ep_attr.max_msg_size)
|
||||
return -FI_ENODATA;
|
||||
|
||||
if (ep_attr->msg_prefix_size > sock_msg_ep_attr.msg_prefix_size)
|
||||
return -FI_ENODATA;
|
||||
|
||||
if (ep_attr->max_order_raw_size >
|
||||
sock_msg_ep_attr.max_order_raw_size)
|
||||
return -FI_ENODATA;
|
||||
@ -190,6 +208,21 @@ int sock_msg_fi_info(void *src_addr, void *dest_addr, struct fi_info *hints,
|
||||
*(*info)->rx_attr = sock_msg_rx_attr;
|
||||
*(*info)->ep_attr = sock_msg_ep_attr;
|
||||
|
||||
if (hints && hints->ep_attr) {
|
||||
if (hints->ep_attr->rx_ctx_cnt)
|
||||
(*info)->ep_attr->rx_ctx_cnt = hints->ep_attr->rx_ctx_cnt;
|
||||
if (hints->ep_attr->tx_ctx_cnt)
|
||||
(*info)->ep_attr->tx_ctx_cnt = hints->ep_attr->tx_ctx_cnt;
|
||||
}
|
||||
|
||||
if (hints && hints->rx_attr) {
|
||||
(*info)->rx_attr->op_flags |= hints->rx_attr->op_flags;
|
||||
}
|
||||
|
||||
if (hints && hints->tx_attr) {
|
||||
(*info)->tx_attr->op_flags |= hints->tx_attr->op_flags;
|
||||
}
|
||||
|
||||
(*info)->caps = SOCK_EP_MSG_CAP |
|
||||
(*info)->rx_attr->caps | (*info)->tx_attr->caps;
|
||||
return 0;
|
||||
@ -224,6 +257,35 @@ static int sock_ep_cm_getname(fid_t fid, void *addr, size_t *addrlen)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sock_ep_cm_setnmae(fid_t fid, void *addr, size_t addrlen)
|
||||
{
|
||||
struct sock_ep *sock_ep = NULL;
|
||||
struct sock_pep *sock_pep = NULL;
|
||||
|
||||
if (addrlen != sizeof(struct sockaddr_in))
|
||||
return -FI_EINVAL;
|
||||
|
||||
switch(fid->fclass) {
|
||||
case FI_CLASS_EP:
|
||||
case FI_CLASS_SEP:
|
||||
sock_ep = container_of(fid, struct sock_ep, ep.fid);
|
||||
if (sock_ep->listener.listener_thread)
|
||||
return -FI_EINVAL;
|
||||
memcpy(sock_ep->src_addr, addr, addrlen);
|
||||
break;
|
||||
case FI_CLASS_PEP:
|
||||
sock_pep = container_of(fid, struct sock_pep, pep.fid);
|
||||
if (sock_pep->cm.listener_thread)
|
||||
return -FI_EINVAL;
|
||||
memcpy(&sock_pep->src_addr, addr, addrlen);
|
||||
break;
|
||||
default:
|
||||
SOCK_LOG_ERROR("Invalid argument\n");
|
||||
return -FI_EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sock_ep_cm_getpeer(struct fid_ep *ep, void *addr, size_t *addrlen)
|
||||
{
|
||||
struct sock_ep *sock_ep;
|
||||
@ -397,15 +459,35 @@ static void sock_ep_cm_handle_ack(struct sock_cm_entry *cm,
|
||||
msg_hdr = (struct sock_conn_hdr*)msg_entry->msg;
|
||||
|
||||
if (msg_hdr->msg_id == hdr->msg_id) {
|
||||
if (msg_hdr->type == SOCK_CONN_SHUTDOWN) {
|
||||
switch (msg_hdr->type) {
|
||||
case SOCK_CONN_SHUTDOWN:
|
||||
SOCK_LOG_INFO("Got ack for SOCK_CONN_SHUTDOWN\n");
|
||||
memset(&cm_entry, 0, sizeof cm_entry);
|
||||
cm_entry.fid = &sock_ep->ep.fid;
|
||||
if (sock_ep->cm.shutdown_received)
|
||||
break;
|
||||
|
||||
if (sock_eq_report_event(sock_ep->eq, FI_SHUTDOWN, &cm_entry,
|
||||
|
||||
if (sock_eq_report_event(sock_ep->eq, FI_SHUTDOWN,
|
||||
&cm_entry,
|
||||
sizeof(cm_entry), 0))
|
||||
SOCK_LOG_ERROR("Error in writing to EQ\n");
|
||||
break;
|
||||
|
||||
case SOCK_CONN_ACCEPT:
|
||||
SOCK_LOG_INFO("Got ack for SOCK_CONN_ACCEPT\n");
|
||||
memset(&cm_entry, 0, sizeof cm_entry);
|
||||
cm_entry.fid = &sock_ep->ep.fid;
|
||||
sock_ep->connected = 1;
|
||||
sock_ep_enable(&sock_ep->ep);
|
||||
|
||||
if (sock_eq_report_event(sock_ep->eq, FI_CONNECTED,
|
||||
&cm_entry,
|
||||
sizeof(cm_entry), 0))
|
||||
SOCK_LOG_ERROR("Error in writing to EQ\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
dlist_remove(entry);
|
||||
free(msg_entry);
|
||||
@ -577,6 +659,9 @@ static int sock_ep_cm_connect(struct fid_ep *ep, const void *addr,
|
||||
if (!_eq || paramlen > SOCK_EP_MAX_CM_DATA_SZ)
|
||||
return -FI_EINVAL;
|
||||
|
||||
if (!_ep->listener.listener_thread && sock_conn_listen(_ep))
|
||||
return -FI_EINVAL;
|
||||
|
||||
req = calloc(1, sizeof(*req) + paramlen);
|
||||
if (!req)
|
||||
return -FI_ENOMEM;
|
||||
@ -615,33 +700,35 @@ err:
|
||||
|
||||
static int sock_ep_cm_accept(struct fid_ep *ep, const void *param, size_t paramlen)
|
||||
{
|
||||
struct sock_conn_req_handle *handle;
|
||||
struct sock_conn_req *req;
|
||||
struct fi_eq_cm_entry cm_entry;
|
||||
struct sock_conn_response *response;
|
||||
struct sockaddr_in *addr;
|
||||
struct sock_ep *_ep;
|
||||
struct sock_eq *_eq;
|
||||
int ret = 0;
|
||||
|
||||
_ep = container_of(ep, struct sock_ep, ep);
|
||||
_eq = _ep->eq;
|
||||
if (!_eq || paramlen > SOCK_EP_MAX_CM_DATA_SZ)
|
||||
if (!_ep->eq || paramlen > SOCK_EP_MAX_CM_DATA_SZ)
|
||||
return -FI_EINVAL;
|
||||
|
||||
if (_ep->is_disabled || _ep->cm.shutdown_received)
|
||||
return -FI_EINVAL;
|
||||
|
||||
if (!_ep->listener.listener_thread && sock_conn_listen(_ep))
|
||||
return -FI_EINVAL;
|
||||
|
||||
response = calloc(1, sizeof(*response) + paramlen);
|
||||
if (!response)
|
||||
return -FI_ENOMEM;
|
||||
|
||||
req = (struct sock_conn_req *) _ep->info.connreq;
|
||||
if (!req) {
|
||||
SOCK_LOG_ERROR("invalid connreq for cm_accept\n");
|
||||
handle = container_of(_ep->info.handle, struct sock_conn_req_handle, handle);
|
||||
if (!handle || handle->handle.fclass != FI_CLASS_CONNREQ) {
|
||||
SOCK_LOG_ERROR("invalid handle for cm_accept\n");
|
||||
free(response);
|
||||
return -FI_EINVAL;
|
||||
}
|
||||
|
||||
|
||||
req = handle->req;
|
||||
memcpy(&response->hdr, &req->hdr, sizeof(response->hdr));
|
||||
if (param && paramlen)
|
||||
memcpy(&response->user_data, param, paramlen);
|
||||
@ -660,16 +747,11 @@ static int sock_ep_cm_accept(struct fid_ep *ep, const void *param, size_t paraml
|
||||
goto out;
|
||||
}
|
||||
|
||||
sock_ep_enable(ep);
|
||||
memset(&cm_entry, 0, sizeof(cm_entry));
|
||||
cm_entry.fid = &ep->fid;
|
||||
_ep->connected = 1;
|
||||
ret = sock_eq_report_event(_eq, FI_CONNECTED, &cm_entry,
|
||||
sizeof(cm_entry), 0);
|
||||
out:
|
||||
free(handle);
|
||||
free(req);
|
||||
free(response);
|
||||
_ep->info.connreq = NULL;
|
||||
_ep->info.handle = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -695,6 +777,7 @@ static int sock_ep_cm_shutdown(struct fid_ep *ep, uint64_t flags)
|
||||
|
||||
struct fi_ops_cm sock_ep_cm_ops = {
|
||||
.size = sizeof(struct fi_ops_cm),
|
||||
.setname = sock_ep_cm_setnmae,
|
||||
.getname = sock_ep_cm_getname,
|
||||
.getpeer = sock_ep_cm_getpeer,
|
||||
.connect = sock_ep_cm_connect,
|
||||
@ -842,9 +925,10 @@ static struct fi_info * sock_ep_msg_process_info(struct sock_conn_req *req)
|
||||
req->info.dest_addr, req->info.src_addr);
|
||||
}
|
||||
|
||||
static void *sock_pep_listener_thread (void *data)
|
||||
static void *sock_pep_listener_thread(void *data)
|
||||
{
|
||||
struct sock_pep *pep = (struct sock_pep *)data;
|
||||
struct sock_pep *pep = (struct sock_pep *) data;
|
||||
struct sock_conn_req_handle *handle = NULL;
|
||||
struct sock_conn_req *conn_req = NULL;
|
||||
struct fi_eq_cm_entry *cm_entry;
|
||||
struct sockaddr_in from_addr;
|
||||
@ -864,7 +948,7 @@ static void *sock_pep_listener_thread (void *data)
|
||||
poll_fds[0].fd = pep->cm.sock;
|
||||
poll_fds[1].fd = pep->cm.signal_fds[1];
|
||||
poll_fds[0].events = poll_fds[1].events = POLLIN;
|
||||
while(*((volatile int*)&pep->cm.do_listen)) {
|
||||
while (*((volatile int*)&pep->cm.do_listen)) {
|
||||
timeout = dlist_empty(&pep->cm.msg_list) ? -1 : SOCK_CM_COMM_TIMEOUT;
|
||||
if (poll(poll_fds, 2, timeout) > 0) {
|
||||
if (poll_fds[1].revents & POLLIN) {
|
||||
@ -883,6 +967,12 @@ static void *sock_pep_listener_thread (void *data)
|
||||
}
|
||||
}
|
||||
|
||||
if (handle == NULL) {
|
||||
handle = calloc(1, sizeof *handle);
|
||||
if (!handle)
|
||||
break;
|
||||
}
|
||||
|
||||
if (conn_req == NULL) {
|
||||
conn_req = calloc(1, sizeof(*conn_req) + SOCK_EP_MAX_CM_DATA_SZ);
|
||||
if (!conn_req) {
|
||||
@ -891,6 +981,9 @@ static void *sock_pep_listener_thread (void *data)
|
||||
}
|
||||
}
|
||||
|
||||
handle->handle.fclass = FI_CLASS_CONNREQ;
|
||||
handle->req = conn_req;
|
||||
|
||||
addr_len = sizeof(struct sockaddr_in);
|
||||
ret = recvfrom(pep->cm.sock, (char*)conn_req,
|
||||
sizeof(*conn_req) + SOCK_EP_MAX_CM_DATA_SZ, 0,
|
||||
@ -925,10 +1018,11 @@ static void *sock_pep_listener_thread (void *data)
|
||||
|
||||
cm_entry->fid = &pep->pep.fid;
|
||||
cm_entry->info = sock_ep_msg_process_info(conn_req);
|
||||
cm_entry->info->connreq = (fi_connreq_t) conn_req;
|
||||
cm_entry->info->handle = &handle->handle;
|
||||
|
||||
memcpy(&cm_entry->data, &conn_req->user_data,
|
||||
user_data_sz);
|
||||
handle = NULL;
|
||||
conn_req = NULL;
|
||||
|
||||
if (sock_eq_report_event(pep->eq, FI_CONNREQ, cm_entry,
|
||||
@ -945,6 +1039,8 @@ static void *sock_pep_listener_thread (void *data)
|
||||
out:
|
||||
if (conn_req)
|
||||
free(conn_req);
|
||||
if (handle)
|
||||
free(handle);
|
||||
free(cm_entry);
|
||||
close(pep->cm.sock);
|
||||
return NULL;
|
||||
@ -1028,9 +1124,10 @@ static int sock_pep_listen(struct fid_pep *pep)
|
||||
return sock_pep_create_listener_thread(_pep);
|
||||
}
|
||||
|
||||
static int sock_pep_reject(struct fid_pep *pep, fi_connreq_t connreq,
|
||||
static int sock_pep_reject(struct fid_pep *pep, fid_t handle,
|
||||
const void *param, size_t paramlen)
|
||||
{
|
||||
struct sock_conn_req_handle *hreq;
|
||||
struct sock_conn_req *req;
|
||||
struct sockaddr_in *addr;
|
||||
struct sock_pep *_pep;
|
||||
@ -1038,9 +1135,10 @@ static int sock_pep_reject(struct fid_pep *pep, fi_connreq_t connreq,
|
||||
int ret = 0;
|
||||
|
||||
_pep = container_of(pep, struct sock_pep, pep);
|
||||
req = (struct sock_conn_req *)connreq;
|
||||
if (!req)
|
||||
return 0;
|
||||
hreq = container_of(handle, struct sock_conn_req_handle, handle);
|
||||
req = hreq->req;
|
||||
if (!req || hreq->handle.fclass != FI_CLASS_CONNREQ)
|
||||
return -FI_EINVAL;
|
||||
|
||||
response = (struct sock_conn_response*)
|
||||
calloc(1, sizeof(*response) + paramlen);
|
||||
@ -1064,6 +1162,7 @@ static int sock_pep_reject(struct fid_pep *pep, fi_connreq_t connreq,
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
free(hreq);
|
||||
free(req);
|
||||
free(response);
|
||||
return ret;
|
||||
@ -1071,6 +1170,7 @@ out:
|
||||
|
||||
static struct fi_ops_cm sock_pep_cm_ops = {
|
||||
.size = sizeof(struct fi_ops_cm),
|
||||
.setname = sock_ep_cm_setnmae,
|
||||
.getname = sock_ep_cm_getname,
|
||||
.getpeer = fi_no_getpeer,
|
||||
.connect = fi_no_connect,
|
||||
|
@ -62,7 +62,9 @@
|
||||
const struct fi_ep_attr sock_rdm_ep_attr = {
|
||||
.type = FI_EP_RDM,
|
||||
.protocol = FI_PROTO_SOCK_TCP,
|
||||
.protocol_version = SOCK_WIRE_PROTO_VERSION,
|
||||
.max_msg_size = SOCK_EP_MAX_MSG_SZ,
|
||||
.msg_prefix_size = SOCK_EP_MSG_PREFIX_SZ,
|
||||
.max_order_raw_size = SOCK_EP_MAX_ORDER_RAW_SZ,
|
||||
.max_order_war_size = SOCK_EP_MAX_ORDER_WAR_SZ,
|
||||
.max_order_waw_size = SOCK_EP_MAX_ORDER_WAW_SZ,
|
||||
@ -73,17 +75,21 @@ const struct fi_ep_attr sock_rdm_ep_attr = {
|
||||
|
||||
const struct fi_tx_attr sock_rdm_tx_attr = {
|
||||
.caps = SOCK_EP_RDM_CAP,
|
||||
.mode = SOCK_MODE,
|
||||
.op_flags = FI_TRANSMIT_COMPLETE,
|
||||
.msg_order = SOCK_EP_MSG_ORDER,
|
||||
.inject_size = SOCK_EP_MAX_INJECT_SZ,
|
||||
.size = SOCK_EP_TX_SZ,
|
||||
.iov_limit = SOCK_EP_MAX_IOV_LIMIT,
|
||||
.rma_iov_limit = SOCK_EP_MAX_IOV_LIMIT,
|
||||
};
|
||||
|
||||
const struct fi_rx_attr sock_rdm_rx_attr = {
|
||||
.caps = SOCK_EP_RDM_CAP,
|
||||
.mode = SOCK_MODE,
|
||||
.op_flags = 0,
|
||||
.msg_order = SOCK_EP_MSG_ORDER,
|
||||
.comp_order = SOCK_EP_COMP_ORDER,
|
||||
.total_buffered_recv = SOCK_EP_MAX_BUFF_RECV,
|
||||
.size = SOCK_EP_RX_SZ,
|
||||
.iov_limit = SOCK_EP_MAX_IOV_LIMIT,
|
||||
@ -104,6 +110,11 @@ static int sock_rdm_verify_rx_attr(const struct fi_rx_attr *attr)
|
||||
return -FI_ENODATA;
|
||||
}
|
||||
|
||||
if ((attr->comp_order | SOCK_EP_COMP_ORDER) != SOCK_EP_COMP_ORDER) {
|
||||
SOCK_LOG_INFO("Unsuported rx completion order\n");
|
||||
return -FI_ENODATA;
|
||||
}
|
||||
|
||||
if (attr->total_buffered_recv > sock_rdm_rx_attr.total_buffered_recv) {
|
||||
SOCK_LOG_INFO("Buffered receive size too large\n");
|
||||
return -FI_ENODATA;
|
||||
@ -152,6 +163,11 @@ static int sock_rdm_verify_tx_attr(const struct fi_tx_attr *attr)
|
||||
return -FI_ENODATA;
|
||||
}
|
||||
|
||||
if (attr->rma_iov_limit > sock_rdm_tx_attr.rma_iov_limit) {
|
||||
SOCK_LOG_INFO("RMA iov limit too large\n");
|
||||
return -FI_ENODATA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -171,11 +187,21 @@ int sock_rdm_verify_ep_attr(struct fi_ep_attr *ep_attr,
|
||||
return -FI_ENODATA;
|
||||
}
|
||||
|
||||
if (ep_attr->protocol_version != sock_rdm_ep_attr.protocol_version) {
|
||||
SOCK_LOG_INFO("Invalid protocol version\n");
|
||||
return -FI_ENODATA;
|
||||
}
|
||||
|
||||
if (ep_attr->max_msg_size > sock_rdm_ep_attr.max_msg_size) {
|
||||
SOCK_LOG_INFO("Message size too large\n");
|
||||
return -FI_ENODATA;
|
||||
}
|
||||
|
||||
if (ep_attr->msg_prefix_size > sock_rdm_ep_attr.msg_prefix_size) {
|
||||
SOCK_LOG_INFO("Msg prefix size not supported\n");
|
||||
return -FI_ENODATA;
|
||||
}
|
||||
|
||||
if (ep_attr->max_order_raw_size >
|
||||
sock_rdm_ep_attr.max_order_raw_size) {
|
||||
SOCK_LOG_INFO("RAW order size too large\n");
|
||||
@ -225,6 +251,21 @@ int sock_rdm_fi_info(void *src_addr, void *dest_addr, struct fi_info *hints,
|
||||
*(*info)->rx_attr = sock_rdm_rx_attr;
|
||||
*(*info)->ep_attr = sock_rdm_ep_attr;
|
||||
|
||||
if (hints && hints->ep_attr) {
|
||||
if (hints->ep_attr->rx_ctx_cnt)
|
||||
(*info)->ep_attr->rx_ctx_cnt = hints->ep_attr->rx_ctx_cnt;
|
||||
if (hints->ep_attr->tx_ctx_cnt)
|
||||
(*info)->ep_attr->tx_ctx_cnt = hints->ep_attr->tx_ctx_cnt;
|
||||
}
|
||||
|
||||
if (hints && hints->rx_attr) {
|
||||
(*info)->rx_attr->op_flags |= hints->rx_attr->op_flags;
|
||||
}
|
||||
|
||||
if (hints && hints->tx_attr) {
|
||||
(*info)->tx_attr->op_flags |= hints->tx_attr->op_flags;
|
||||
}
|
||||
|
||||
(*info)->caps = SOCK_EP_RDM_CAP |
|
||||
(*info)->rx_attr->caps | (*info)->tx_attr->caps;
|
||||
return 0;
|
||||
|
@ -50,11 +50,13 @@
|
||||
#define SOCK_LOG_INFO(...) _SOCK_LOG_INFO(FI_LOG_FABRIC, __VA_ARGS__)
|
||||
#define SOCK_LOG_ERROR(...) _SOCK_LOG_ERROR(FI_LOG_FABRIC, __VA_ARGS__)
|
||||
|
||||
int sock_pe_waittime = SOCK_PE_WAITTIME;
|
||||
const char sock_fab_name[] = "IP";
|
||||
const char sock_dom_name[] = "sockets";
|
||||
const char sock_prov_name[] = "sockets";
|
||||
|
||||
useconds_t sock_progress_thread_wait = 0;
|
||||
#if ENABLE_DEBUG
|
||||
int sock_dgram_drop_rate = 0;
|
||||
#endif
|
||||
|
||||
const struct fi_fabric_attr sock_fabric_attr = {
|
||||
.fabric = NULL,
|
||||
@ -63,6 +65,116 @@ const struct fi_fabric_attr sock_fabric_attr = {
|
||||
.prov_version = FI_VERSION(SOCK_MAJOR_VERSION, SOCK_MINOR_VERSION),
|
||||
};
|
||||
|
||||
static struct dlist_entry sock_fab_list;
|
||||
static struct dlist_entry sock_dom_list;
|
||||
static fastlock_t sock_list_lock;
|
||||
|
||||
void sock_dom_add_to_list(struct sock_domain *domain)
|
||||
{
|
||||
fastlock_acquire(&sock_list_lock);
|
||||
dlist_insert_tail(&domain->dom_list_entry, &sock_dom_list);
|
||||
fastlock_release(&sock_list_lock);
|
||||
}
|
||||
|
||||
static inline int sock_dom_check_list_internal(struct sock_domain *domain)
|
||||
{
|
||||
struct dlist_entry *entry;
|
||||
struct sock_domain *dom_entry;
|
||||
for (entry = sock_dom_list.next; entry != &sock_dom_list;
|
||||
entry = entry->next) {
|
||||
dom_entry = container_of(entry, struct sock_domain,
|
||||
dom_list_entry);
|
||||
if (dom_entry == domain)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sock_dom_check_list(struct sock_domain *domain)
|
||||
{
|
||||
int found;
|
||||
fastlock_acquire(&sock_list_lock);
|
||||
found = sock_dom_check_list_internal(domain);
|
||||
fastlock_release(&sock_list_lock);
|
||||
return found;
|
||||
}
|
||||
|
||||
void sock_dom_remove_from_list(struct sock_domain *domain)
|
||||
{
|
||||
fastlock_acquire(&sock_list_lock);
|
||||
if (sock_dom_check_list_internal(domain)) {
|
||||
dlist_remove(&domain->dom_list_entry);
|
||||
}
|
||||
fastlock_release(&sock_list_lock);
|
||||
}
|
||||
|
||||
struct sock_domain *sock_dom_list_head(void)
|
||||
{
|
||||
struct sock_domain *domain;
|
||||
fastlock_acquire(&sock_list_lock);
|
||||
if (dlist_empty(&sock_dom_list)) {
|
||||
domain = NULL;
|
||||
} else {
|
||||
domain = container_of(sock_dom_list.next,
|
||||
struct sock_domain, dom_list_entry);
|
||||
}
|
||||
fastlock_release(&sock_list_lock);
|
||||
return domain;
|
||||
}
|
||||
|
||||
void sock_fab_add_to_list(struct sock_fabric *fabric)
|
||||
{
|
||||
fastlock_acquire(&sock_list_lock);
|
||||
dlist_insert_tail(&fabric->fab_list_entry, &sock_fab_list);
|
||||
fastlock_release(&sock_list_lock);
|
||||
}
|
||||
|
||||
static inline int sock_fab_check_list_internal(struct sock_fabric *fabric)
|
||||
{
|
||||
struct dlist_entry *entry;
|
||||
struct sock_fabric *fab_entry;
|
||||
for (entry = sock_fab_list.next; entry != &sock_fab_list;
|
||||
entry = entry->next) {
|
||||
fab_entry = container_of(entry, struct sock_fabric,
|
||||
fab_list_entry);
|
||||
if (fab_entry == fabric)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sock_fab_check_list(struct sock_fabric *fabric)
|
||||
{
|
||||
int found;
|
||||
fastlock_acquire(&sock_list_lock);
|
||||
found = sock_fab_check_list_internal(fabric);
|
||||
fastlock_release(&sock_list_lock);
|
||||
return found;
|
||||
}
|
||||
|
||||
void sock_fab_remove_from_list(struct sock_fabric *fabric)
|
||||
{
|
||||
fastlock_acquire(&sock_list_lock);
|
||||
if (sock_fab_check_list_internal(fabric)) {
|
||||
dlist_remove(&fabric->fab_list_entry);
|
||||
}
|
||||
fastlock_release(&sock_list_lock);
|
||||
}
|
||||
|
||||
struct sock_fabric *sock_fab_list_head(void)
|
||||
{
|
||||
struct sock_fabric *fabric;
|
||||
fastlock_acquire(&sock_list_lock);
|
||||
if (dlist_empty(&sock_fab_list)) {
|
||||
fabric = NULL;
|
||||
} else {
|
||||
fabric = container_of(sock_fab_list.next,
|
||||
struct sock_fabric, fab_list_entry);
|
||||
}
|
||||
fastlock_release(&sock_list_lock);
|
||||
return fabric;
|
||||
}
|
||||
|
||||
int sock_verify_fabric_attr(struct fi_fabric_attr *attr)
|
||||
{
|
||||
if (!attr)
|
||||
@ -86,6 +198,8 @@ int sock_verify_info(struct fi_info *hints)
|
||||
uint64_t caps;
|
||||
enum fi_ep_type ep_type;
|
||||
int ret;
|
||||
struct sock_domain *domain;
|
||||
struct sock_fabric *fabric;
|
||||
|
||||
if (!hints)
|
||||
return 0;
|
||||
@ -131,10 +245,26 @@ int sock_verify_info(struct fi_info *hints)
|
||||
return -FI_ENODATA;
|
||||
}
|
||||
|
||||
if (hints->domain_attr && hints->domain_attr->domain) {
|
||||
domain = container_of(hints->domain_attr->domain,
|
||||
struct sock_domain, dom_fid);
|
||||
if (!sock_dom_check_list(domain)) {
|
||||
SOCK_LOG_INFO("no matching domain\n");
|
||||
return -FI_ENODATA;
|
||||
}
|
||||
}
|
||||
ret = sock_verify_domain_attr(hints->domain_attr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (hints->fabric_attr && hints->fabric_attr->fabric) {
|
||||
fabric = container_of(hints->fabric_attr->fabric,
|
||||
struct sock_fabric, fab_fid);
|
||||
if (!sock_fab_check_list(fabric)) {
|
||||
SOCK_LOG_INFO("no matching fabric\n");
|
||||
return -FI_ENODATA;
|
||||
}
|
||||
}
|
||||
ret = sock_verify_fabric_attr(hints->fabric_attr);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -154,11 +284,11 @@ static int sock_fabric_close(fid_t fid)
|
||||
{
|
||||
struct sock_fabric *fab;
|
||||
fab = container_of(fid, struct sock_fabric, fab_fid);
|
||||
|
||||
if (atomic_get(&fab->ref)) {
|
||||
return -FI_EBUSY;
|
||||
}
|
||||
|
||||
sock_fab_remove_from_list(fab);
|
||||
fastlock_destroy(&fab->lock);
|
||||
free(fab);
|
||||
return 0;
|
||||
@ -192,7 +322,11 @@ static int sock_fabric(struct fi_fabric_attr *attr,
|
||||
fab->fab_fid.fid.ops = &sock_fab_fi_ops;
|
||||
fab->fab_fid.ops = &sock_fab_ops;
|
||||
*fabric = &fab->fab_fid;
|
||||
atomic_init(&fab->ref, 0);
|
||||
atomic_initialize(&fab->ref, 0);
|
||||
#if ENABLE_DEBUG
|
||||
fab->num_send_msg = 0;
|
||||
#endif
|
||||
sock_fab_add_to_list(fab);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -213,7 +347,6 @@ static struct sock_service_entry *sock_fabric_find_service(struct sock_fabric *f
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int sock_fabric_check_service(struct sock_fabric *fab, int service)
|
||||
{
|
||||
struct sock_service_entry *entry;
|
||||
@ -243,8 +376,10 @@ void sock_fabric_remove_service(struct sock_fabric *fab, int service)
|
||||
struct sock_service_entry *service_entry;
|
||||
fastlock_acquire(&fab->lock);
|
||||
service_entry = sock_fabric_find_service(fab, service);
|
||||
dlist_remove(&service_entry->entry);
|
||||
free(service_entry);
|
||||
if (service_entry) {
|
||||
dlist_remove(&service_entry->entry);
|
||||
free(service_entry);
|
||||
}
|
||||
fastlock_release(&fab->lock);
|
||||
}
|
||||
|
||||
@ -413,16 +548,22 @@ static int sock_getinfo(uint32_t version, const char *node, const char *service,
|
||||
for (tail = cur; tail->next; tail = tail->next)
|
||||
;
|
||||
}
|
||||
if (!*info) {
|
||||
ret = -FI_ENODATA;
|
||||
goto err_no_free;
|
||||
}
|
||||
return 0;
|
||||
|
||||
err:
|
||||
fi_freeinfo(*info);
|
||||
*info = NULL;
|
||||
err_no_free:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void fi_sockets_fini(void)
|
||||
{
|
||||
fastlock_destroy(&sock_list_lock);
|
||||
}
|
||||
|
||||
struct fi_provider sock_prov = {
|
||||
@ -436,11 +577,22 @@ struct fi_provider sock_prov = {
|
||||
|
||||
SOCKETS_INI
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
tmp = getenv("OFI_SOCK_PROGRESS_YIELD_TIME");
|
||||
if (tmp)
|
||||
sock_progress_thread_wait = atoi(tmp);
|
||||
char *value;
|
||||
|
||||
if ((value = getenv("SOCK_PE_WAITTIME"))) {
|
||||
sock_pe_waittime = atoi(value);
|
||||
SOCK_LOG_INFO("SOCK_PE_WAITTIME = %d\n", sock_pe_waittime);
|
||||
}
|
||||
|
||||
fastlock_init(&sock_list_lock);
|
||||
dlist_init(&sock_fab_list);
|
||||
dlist_init(&sock_dom_list);
|
||||
#if ENABLE_DEBUG
|
||||
if(getenv("SOCK_DGRAM_DROP_RATE") != NULL) {
|
||||
sock_dgram_drop_rate = strtol(getenv("SOCK_DGRAM_DROP_RATE"), NULL, 10);
|
||||
if(sock_dgram_drop_rate)
|
||||
SOCK_LOG_INFO("SOCK_DGRAM_DROP_RATE = %d\n", sock_dgram_drop_rate);
|
||||
}
|
||||
#endif
|
||||
return (&sock_prov);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Intel Corporation, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2015 Intel Corporation, 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
|
||||
@ -34,7 +34,6 @@
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
@ -82,13 +81,28 @@ static ssize_t sock_ep_recvmsg(struct fid_ep *ep, const struct fi_msg *msg,
|
||||
return -FI_EINVAL;
|
||||
}
|
||||
|
||||
assert(rx_ctx->enabled && msg->iov_count <= SOCK_EP_MAX_IOV_LIMIT);
|
||||
if (msg->iov_count > SOCK_EP_MAX_IOV_LIMIT)
|
||||
return -FI_EINVAL;
|
||||
|
||||
if (!rx_ctx->enabled)
|
||||
return -FI_EOPBADSTATE;
|
||||
|
||||
if (flags & SOCK_USE_OP_FLAGS)
|
||||
flags |= rx_ctx->attr.op_flags;
|
||||
|
||||
if (flags & FI_PEEK) {
|
||||
return sock_rx_peek_recv(rx_ctx, msg->addr, 0L, ~0ULL,
|
||||
msg->context, flags, 0);
|
||||
} else if (flags & FI_CLAIM) {
|
||||
return sock_rx_claim_recv(rx_ctx, msg->context, flags,
|
||||
0L, ~0ULL, 0,
|
||||
msg->msg_iov, msg->iov_count);
|
||||
}
|
||||
|
||||
rx_entry = sock_rx_new_entry(rx_ctx);
|
||||
if (!rx_entry)
|
||||
return -FI_ENOMEM;
|
||||
|
||||
flags |= rx_ctx->attr.op_flags;
|
||||
rx_entry->rx_op.op = SOCK_OP_RECV;
|
||||
rx_entry->rx_op.dest_iov_len = msg->iov_count;
|
||||
|
||||
@ -128,7 +142,7 @@ static ssize_t sock_ep_recv(struct fid_ep *ep, void *buf, size_t len, void *desc
|
||||
msg.addr = src_addr;
|
||||
msg.context = context;
|
||||
msg.data = 0;
|
||||
return sock_ep_recvmsg(ep, &msg, 0);
|
||||
return sock_ep_recvmsg(ep, &msg, SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_recvv(struct fid_ep *ep, const struct iovec *iov,
|
||||
@ -143,7 +157,7 @@ static ssize_t sock_ep_recvv(struct fid_ep *ep, const struct iovec *iov,
|
||||
msg.addr = src_addr;
|
||||
msg.context = context;
|
||||
msg.data = 0;
|
||||
return sock_ep_recvmsg(ep, &msg, 0);
|
||||
return sock_ep_recvmsg(ep, &msg, SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_sendmsg(struct fid_ep *ep, const struct fi_msg *msg,
|
||||
@ -171,7 +185,15 @@ static ssize_t sock_ep_sendmsg(struct fid_ep *ep, const struct fi_msg *msg,
|
||||
return -FI_EINVAL;
|
||||
}
|
||||
|
||||
assert(tx_ctx->enabled && msg->iov_count <= SOCK_EP_MAX_IOV_LIMIT);
|
||||
if (msg->iov_count > SOCK_EP_MAX_IOV_LIMIT)
|
||||
return -FI_EINVAL;
|
||||
|
||||
if (!tx_ctx->enabled)
|
||||
return -FI_EOPBADSTATE;
|
||||
|
||||
if(sock_drop_packet(sock_ep))
|
||||
return 0;
|
||||
|
||||
if (sock_ep->connected) {
|
||||
conn = sock_ep_lookup_conn(sock_ep);
|
||||
} else {
|
||||
@ -179,11 +201,12 @@ static ssize_t sock_ep_sendmsg(struct fid_ep *ep, const struct fi_msg *msg,
|
||||
}
|
||||
if (!conn)
|
||||
return -FI_EAGAIN;
|
||||
|
||||
|
||||
SOCK_LOG_INFO("New sendmsg on TX: %p using conn: %p\n",
|
||||
tx_ctx, conn);
|
||||
|
||||
flags |= tx_ctx->attr.op_flags;
|
||||
if (flags & SOCK_USE_OP_FLAGS)
|
||||
flags |= tx_ctx->attr.op_flags;
|
||||
memset(&tx_op, 0, sizeof(struct sock_op));
|
||||
tx_op.op = SOCK_OP_SEND;
|
||||
|
||||
@ -192,7 +215,10 @@ static ssize_t sock_ep_sendmsg(struct fid_ep *ep, const struct fi_msg *msg,
|
||||
for (i=0; i< msg->iov_count; i++) {
|
||||
total_len += msg->msg_iov[i].iov_len;
|
||||
}
|
||||
assert(total_len <= SOCK_EP_MAX_INJECT_SZ);
|
||||
if (total_len > SOCK_EP_MAX_INJECT_SZ) {
|
||||
ret = -FI_EINVAL;
|
||||
goto err;
|
||||
}
|
||||
tx_op.src_iov_len = total_len;
|
||||
} else {
|
||||
tx_op.src_iov_len = msg->iov_count;
|
||||
@ -235,7 +261,6 @@ static ssize_t sock_ep_sendmsg(struct fid_ep *ep, const struct fi_msg *msg,
|
||||
return 0;
|
||||
|
||||
err:
|
||||
SOCK_LOG_INFO("Not enough space for TX entry, try again\n");
|
||||
sock_tx_ctx_abort(tx_ctx);
|
||||
return ret;
|
||||
}
|
||||
@ -254,7 +279,7 @@ static ssize_t sock_ep_send(struct fid_ep *ep, const void *buf, size_t len,
|
||||
msg.addr = dest_addr;
|
||||
msg.context = context;
|
||||
|
||||
return sock_ep_sendmsg(ep, &msg, 0);
|
||||
return sock_ep_sendmsg(ep, &msg, SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_sendv(struct fid_ep *ep, const struct iovec *iov,
|
||||
@ -268,7 +293,7 @@ static ssize_t sock_ep_sendv(struct fid_ep *ep, const struct iovec *iov,
|
||||
msg.iov_count = count;
|
||||
msg.addr = dest_addr;
|
||||
msg.context = context;
|
||||
return sock_ep_sendmsg(ep, &msg, 0);
|
||||
return sock_ep_sendmsg(ep, &msg, SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_senddata(struct fid_ep *ep, const void *buf, size_t len,
|
||||
@ -288,7 +313,7 @@ static ssize_t sock_ep_senddata(struct fid_ep *ep, const void *buf, size_t len,
|
||||
msg.context = context;
|
||||
msg.data = data;
|
||||
|
||||
return sock_ep_sendmsg(ep, &msg, FI_REMOTE_CQ_DATA);
|
||||
return sock_ep_sendmsg(ep, &msg, FI_REMOTE_CQ_DATA | SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_inject(struct fid_ep *ep, const void *buf, size_t len,
|
||||
@ -304,7 +329,8 @@ static ssize_t sock_ep_inject(struct fid_ep *ep, const void *buf, size_t len,
|
||||
msg.iov_count = 1;
|
||||
msg.addr = dest_addr;
|
||||
|
||||
return sock_ep_sendmsg(ep, &msg, FI_INJECT | SOCK_NO_COMPLETION);
|
||||
return sock_ep_sendmsg(ep, &msg, FI_INJECT |
|
||||
SOCK_NO_COMPLETION | SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_injectdata(struct fid_ep *ep, const void *buf, size_t len,
|
||||
@ -323,7 +349,7 @@ static ssize_t sock_ep_injectdata(struct fid_ep *ep, const void *buf, size_t len
|
||||
msg.data = data;
|
||||
|
||||
return sock_ep_sendmsg(ep, &msg, FI_REMOTE_CQ_DATA | FI_INJECT |
|
||||
SOCK_NO_COMPLETION);
|
||||
SOCK_NO_COMPLETION | SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
struct fi_ops_msg sock_ep_msg_ops = {
|
||||
@ -361,14 +387,29 @@ static ssize_t sock_ep_trecvmsg(struct fid_ep *ep,
|
||||
return -FI_EINVAL;
|
||||
}
|
||||
|
||||
assert(rx_ctx->enabled && msg->iov_count <= SOCK_EP_MAX_IOV_LIMIT);
|
||||
if (msg->iov_count > SOCK_EP_MAX_IOV_LIMIT)
|
||||
return -FI_EINVAL;
|
||||
|
||||
if (!rx_ctx->enabled)
|
||||
return -FI_EOPBADSTATE;
|
||||
|
||||
if (flags & SOCK_USE_OP_FLAGS)
|
||||
flags |= rx_ctx->attr.op_flags;
|
||||
flags &= ~FI_MULTI_RECV;
|
||||
if (flags & FI_PEEK) {
|
||||
return sock_rx_peek_recv(rx_ctx, msg->addr,
|
||||
msg->tag, msg->ignore,
|
||||
msg->context, flags, 1);
|
||||
} else if (flags & FI_CLAIM) {
|
||||
return sock_rx_claim_recv(rx_ctx, msg->context, flags,
|
||||
msg->tag, msg->ignore, 1,
|
||||
msg->msg_iov, msg->iov_count);
|
||||
}
|
||||
|
||||
rx_entry = sock_rx_new_entry(rx_ctx);
|
||||
if (!rx_entry)
|
||||
return -FI_ENOMEM;
|
||||
|
||||
flags |= rx_ctx->attr.op_flags;
|
||||
flags &= ~FI_MULTI_RECV;
|
||||
rx_entry->rx_op.op = SOCK_OP_TRECV;
|
||||
rx_entry->rx_op.dest_iov_len = msg->iov_count;
|
||||
|
||||
@ -412,7 +453,7 @@ static ssize_t sock_ep_trecv(struct fid_ep *ep, void *buf, size_t len, void *des
|
||||
msg.tag = tag;
|
||||
msg.ignore = ignore;
|
||||
msg.data = 0;
|
||||
return sock_ep_trecvmsg(ep, &msg, 0);
|
||||
return sock_ep_trecvmsg(ep, &msg, SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_trecvv(struct fid_ep *ep, const struct iovec *iov,
|
||||
@ -430,7 +471,7 @@ static ssize_t sock_ep_trecvv(struct fid_ep *ep, const struct iovec *iov,
|
||||
msg.tag = tag;
|
||||
msg.ignore = ignore;
|
||||
msg.data = 0;
|
||||
return sock_ep_trecvmsg(ep, &msg, 0);
|
||||
return sock_ep_trecvmsg(ep, &msg, SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_tsendmsg(struct fid_ep *ep,
|
||||
@ -458,7 +499,15 @@ static ssize_t sock_ep_tsendmsg(struct fid_ep *ep,
|
||||
return -FI_EINVAL;
|
||||
}
|
||||
|
||||
assert(tx_ctx->enabled && msg->iov_count <= SOCK_EP_MAX_IOV_LIMIT);
|
||||
if (msg->iov_count > SOCK_EP_MAX_IOV_LIMIT)
|
||||
return -FI_EINVAL;
|
||||
|
||||
if (!tx_ctx->enabled)
|
||||
return -FI_EOPBADSTATE;
|
||||
|
||||
if(sock_drop_packet(sock_ep))
|
||||
return 0;
|
||||
|
||||
if (sock_ep->connected) {
|
||||
conn = sock_ep_lookup_conn(sock_ep);
|
||||
} else {
|
||||
@ -466,6 +515,9 @@ static ssize_t sock_ep_tsendmsg(struct fid_ep *ep,
|
||||
}
|
||||
if (!conn)
|
||||
return -FI_EAGAIN;
|
||||
|
||||
if (flags & SOCK_USE_OP_FLAGS)
|
||||
flags |= tx_ctx->attr.op_flags;
|
||||
|
||||
memset(&tx_op, 0, sizeof(tx_op));
|
||||
tx_op.op = SOCK_OP_TSEND;
|
||||
@ -476,7 +528,10 @@ static ssize_t sock_ep_tsendmsg(struct fid_ep *ep,
|
||||
total_len += msg->msg_iov[i].iov_len;
|
||||
}
|
||||
tx_op.src_iov_len = total_len;
|
||||
assert(total_len <= SOCK_EP_MAX_INJECT_SZ);
|
||||
if (total_len > SOCK_EP_MAX_INJECT_SZ) {
|
||||
ret = -FI_EINVAL;
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
total_len = msg->iov_count * sizeof(union sock_iov);
|
||||
tx_op.src_iov_len = msg->iov_count;
|
||||
@ -492,7 +547,6 @@ static ssize_t sock_ep_tsendmsg(struct fid_ep *ep,
|
||||
goto err;
|
||||
}
|
||||
|
||||
flags |= tx_ctx->attr.op_flags;
|
||||
sock_tx_ctx_write_op_tsend(tx_ctx, &tx_op, flags, (uintptr_t) msg->context,
|
||||
msg->addr, (uintptr_t) msg->msg_iov[0].iov_base,
|
||||
sock_ep, conn, msg->tag);
|
||||
@ -518,7 +572,6 @@ static ssize_t sock_ep_tsendmsg(struct fid_ep *ep,
|
||||
return 0;
|
||||
|
||||
err:
|
||||
SOCK_LOG_INFO("Not enough space for TX entry, try again\n");
|
||||
sock_tx_ctx_abort(tx_ctx);
|
||||
return ret;
|
||||
}
|
||||
@ -539,7 +592,7 @@ static ssize_t sock_ep_tsend(struct fid_ep *ep, const void *buf, size_t len,
|
||||
msg.context = context;
|
||||
msg.tag = tag;
|
||||
|
||||
return sock_ep_tsendmsg(ep, &msg, 0);
|
||||
return sock_ep_tsendmsg(ep, &msg, SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_tsendv(struct fid_ep *ep, const struct iovec *iov,
|
||||
@ -555,7 +608,7 @@ static ssize_t sock_ep_tsendv(struct fid_ep *ep, const struct iovec *iov,
|
||||
msg.addr = dest_addr;
|
||||
msg.context = context;
|
||||
msg.tag = tag;
|
||||
return sock_ep_tsendmsg(ep, &msg, 0);
|
||||
return sock_ep_tsendmsg(ep, &msg, SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_tsenddata(struct fid_ep *ep, const void *buf, size_t len,
|
||||
@ -576,7 +629,7 @@ static ssize_t sock_ep_tsenddata(struct fid_ep *ep, const void *buf, size_t len,
|
||||
msg.data = data;
|
||||
msg.tag = tag;
|
||||
|
||||
return sock_ep_tsendmsg(ep, &msg, FI_REMOTE_CQ_DATA);
|
||||
return sock_ep_tsendmsg(ep, &msg, FI_REMOTE_CQ_DATA | SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_tinject(struct fid_ep *ep, const void *buf, size_t len,
|
||||
@ -592,7 +645,8 @@ static ssize_t sock_ep_tinject(struct fid_ep *ep, const void *buf, size_t len,
|
||||
msg.iov_count = 1;
|
||||
msg.addr = dest_addr;
|
||||
msg.tag = tag;
|
||||
return sock_ep_tsendmsg(ep, &msg, FI_INJECT | SOCK_NO_COMPLETION);
|
||||
return sock_ep_tsendmsg(ep, &msg, FI_INJECT |
|
||||
SOCK_NO_COMPLETION | SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_tinjectdata(struct fid_ep *ep, const void *buf, size_t len,
|
||||
@ -612,68 +666,10 @@ static ssize_t sock_ep_tinjectdata(struct fid_ep *ep, const void *buf, size_t le
|
||||
msg.tag = tag;
|
||||
|
||||
return sock_ep_tsendmsg(ep, &msg, FI_REMOTE_CQ_DATA | FI_INJECT |
|
||||
SOCK_NO_COMPLETION);
|
||||
SOCK_NO_COMPLETION | SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
|
||||
static ssize_t sock_ep_tsearch(struct fid_ep *ep, uint64_t *tag, uint64_t ignore,
|
||||
uint64_t flags, fi_addr_t *src_addr, size_t *len,
|
||||
void *context)
|
||||
{
|
||||
ssize_t ret;
|
||||
struct dlist_entry *entry;
|
||||
struct sock_rx_ctx *rx_ctx;
|
||||
struct sock_rx_entry *rx_entry;
|
||||
struct sock_ep *sock_ep;
|
||||
|
||||
switch (ep->fid.fclass) {
|
||||
case FI_CLASS_EP:
|
||||
sock_ep = container_of(ep, struct sock_ep, ep);
|
||||
rx_ctx = sock_ep->rx_ctx;
|
||||
break;
|
||||
|
||||
case FI_CLASS_RX_CTX:
|
||||
case FI_CLASS_SRX_CTX:
|
||||
rx_ctx = container_of(ep, struct sock_rx_ctx, ctx);
|
||||
break;
|
||||
|
||||
default:
|
||||
SOCK_LOG_ERROR("Invalid ep type\n");
|
||||
return -FI_EINVAL;
|
||||
}
|
||||
|
||||
ret = -FI_ENOMSG;
|
||||
fastlock_acquire(&rx_ctx->lock);
|
||||
for (entry = rx_ctx->rx_buffered_list.next;
|
||||
entry != &rx_ctx->rx_buffered_list; entry = entry->next) {
|
||||
|
||||
rx_entry = container_of(entry, struct sock_rx_entry, entry);
|
||||
if (rx_entry->is_busy || rx_entry->is_claimed)
|
||||
continue;
|
||||
|
||||
if (((rx_entry->tag & ~rx_entry->ignore) ==
|
||||
(*tag & ~rx_entry->ignore)) &&
|
||||
(rx_entry->addr == FI_ADDR_UNSPEC ||
|
||||
(src_addr == NULL) ||
|
||||
(src_addr &&
|
||||
((*src_addr == FI_ADDR_UNSPEC) ||
|
||||
(rx_entry->addr == *src_addr))))) {
|
||||
|
||||
if (flags & FI_CLAIM)
|
||||
rx_entry->is_claimed = 1;
|
||||
*tag = rx_entry->tag;
|
||||
if (src_addr)
|
||||
*src_addr = rx_entry->addr;
|
||||
*len = rx_entry->used;
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fastlock_release(&rx_ctx->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct fi_ops_tagged sock_ep_tagged = {
|
||||
.size = sizeof(struct fi_ops_tagged),
|
||||
.recv = sock_ep_trecv,
|
||||
@ -685,6 +681,5 @@ struct fi_ops_tagged sock_ep_tagged = {
|
||||
.inject = sock_ep_tinject,
|
||||
.senddata = sock_ep_tsenddata,
|
||||
.injectdata = sock_ep_tinjectdata,
|
||||
.search = sock_ep_tsearch,
|
||||
};
|
||||
|
||||
|
@ -100,7 +100,7 @@ static int sock_poll_poll(struct fid_poll *pollset, void **context, int count)
|
||||
cq = container_of(list_item->fid, struct sock_cq, cq_fid);
|
||||
sock_cq_progress(cq);
|
||||
fastlock_acquire(&cq->lock);
|
||||
if (rbfdused(&cq->cq_rbfd)) {
|
||||
if (rbfdused(&cq->cq_rbfd) || rbused(&cq->cqerr_rb)) {
|
||||
*context++ = cq->cq_fid.fid.context;
|
||||
ret_count++;
|
||||
}
|
||||
@ -121,7 +121,7 @@ static int sock_poll_poll(struct fid_poll *pollset, void **context, int count)
|
||||
case FI_CLASS_EQ:
|
||||
eq = container_of(list_item->fid, struct sock_eq, eq);
|
||||
fastlock_acquire(&eq->lock);
|
||||
if (!dlistfd_empty(&eq->list)) {
|
||||
if (!dlistfd_empty(&eq->list) || !dlistfd_empty(&eq->err_list)) {
|
||||
*context++ = eq->eq.fid.context;
|
||||
ret_count++;
|
||||
}
|
||||
|
@ -105,18 +105,32 @@ static inline ssize_t sock_pe_recv_field(struct sock_pe_entry *pe_entry,
|
||||
return (ret == data_len) ? 0 : -1;
|
||||
}
|
||||
|
||||
static inline void sock_pe_discard_field(struct sock_pe_entry *pe_entry)
|
||||
{
|
||||
size_t ret;
|
||||
if (!pe_entry->rem)
|
||||
return;
|
||||
|
||||
SOCK_LOG_INFO("Remaining for %p: %ld\n", pe_entry, pe_entry->rem);
|
||||
ret = sock_comm_discard(pe_entry->conn, pe_entry->rem);
|
||||
SOCK_LOG_INFO("Discarded %ld\n", ret);
|
||||
|
||||
pe_entry->rem -= ret;
|
||||
if (pe_entry->done_len == pe_entry->total_len && !pe_entry->rem) {
|
||||
SOCK_LOG_INFO("Discard complete for %p\n", pe_entry);
|
||||
pe_entry->is_complete = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void sock_pe_release_entry(struct sock_pe *pe,
|
||||
struct sock_pe_entry *pe_entry)
|
||||
{
|
||||
dlist_remove(&pe_entry->ctx_entry);
|
||||
|
||||
if (pe_entry->type == SOCK_PE_TX) {
|
||||
if (pe_entry->conn->tx_pe_entry == pe_entry)
|
||||
pe_entry->conn->tx_pe_entry = NULL;
|
||||
} else {
|
||||
if (pe_entry->conn->rx_pe_entry == pe_entry)
|
||||
pe_entry->conn->rx_pe_entry = NULL;
|
||||
}
|
||||
if (pe_entry->conn->tx_pe_entry == pe_entry)
|
||||
pe_entry->conn->tx_pe_entry = NULL;
|
||||
if (pe_entry->conn->rx_pe_entry == pe_entry)
|
||||
pe_entry->conn->rx_pe_entry = NULL;
|
||||
|
||||
pe->num_free_entries++;
|
||||
pe_entry->conn = NULL;
|
||||
@ -126,8 +140,9 @@ static void sock_pe_release_entry(struct sock_pe *pe,
|
||||
memset(&pe_entry->msg_hdr, 0, sizeof(pe_entry->msg_hdr));
|
||||
memset(&pe_entry->response, 0, sizeof(pe_entry->response));
|
||||
|
||||
pe_entry->type =0;
|
||||
pe_entry->type = 0;
|
||||
pe_entry->is_complete = 0;
|
||||
pe_entry->is_error = 0;
|
||||
pe_entry->done_len = 0;
|
||||
pe_entry->total_len = 0;
|
||||
pe_entry->data_len = 0;
|
||||
@ -243,7 +258,7 @@ static void sock_pe_report_remote_write(struct sock_rx_ctx *rx_ctx,
|
||||
pe_entry->data_len = pe_entry->pe.rx.rx_iov[0].iov.len;
|
||||
|
||||
if ((!pe_entry->comp->rem_write_cq && !pe_entry->comp->rem_write_cntr &&
|
||||
!(rx_ctx->attr.op_flags & FI_REMOTE_WRITE)))
|
||||
!(pe_entry->msg_hdr.flags & FI_REMOTE_WRITE)))
|
||||
return;
|
||||
|
||||
if (pe_entry->comp->rem_write_cq) {
|
||||
@ -289,7 +304,7 @@ static void sock_pe_report_remote_read(struct sock_rx_ctx *rx_ctx,
|
||||
pe_entry->data_len = pe_entry->pe.rx.rx_iov[0].iov.len;
|
||||
|
||||
if ((!pe_entry->comp->rem_read_cq && !pe_entry->comp->rem_read_cntr &&
|
||||
!(rx_ctx->attr.op_flags & FI_REMOTE_READ)))
|
||||
!(pe_entry->msg_hdr.flags & FI_REMOTE_READ)))
|
||||
return;
|
||||
|
||||
if (pe_entry->comp->rem_read_cq) {
|
||||
@ -328,13 +343,31 @@ static void sock_pe_report_read_completion(struct sock_pe_entry *pe_entry)
|
||||
sock_cntr_inc(pe_entry->comp->read_cntr);
|
||||
}
|
||||
|
||||
static void sock_pe_report_error(struct sock_pe_entry *pe_entry, int rem)
|
||||
static void sock_pe_report_rx_error(struct sock_pe_entry *pe_entry, int rem)
|
||||
{
|
||||
if (pe_entry->comp->recv_cntr)
|
||||
sock_cntr_err_inc(pe_entry->comp->recv_cntr);
|
||||
if (pe_entry->comp->recv_cq)
|
||||
sock_cq_report_error(pe_entry->comp->recv_cq, pe_entry, rem,
|
||||
-FI_ENOSPC, -FI_ENOSPC, NULL);
|
||||
FI_ENOSPC, -FI_ENOSPC, NULL);
|
||||
}
|
||||
|
||||
static void sock_pe_report_tx_rma_read_err(struct sock_pe_entry *pe_entry, int err)
|
||||
{
|
||||
if (pe_entry->comp->read_cntr)
|
||||
sock_cntr_err_inc(pe_entry->comp->read_cntr);
|
||||
if (pe_entry->comp->read_cq)
|
||||
sock_cq_report_error(pe_entry->comp->read_cq, pe_entry, 0,
|
||||
err, -err, NULL);
|
||||
}
|
||||
|
||||
static void sock_pe_report_tx_rma_write_err(struct sock_pe_entry *pe_entry, int err)
|
||||
{
|
||||
if (pe_entry->comp->write_cntr)
|
||||
sock_cntr_err_inc(pe_entry->comp->write_cntr);
|
||||
if (pe_entry->comp->write_cq)
|
||||
sock_cq_report_error(pe_entry->comp->write_cq, pe_entry, 0,
|
||||
err, -err, NULL);
|
||||
}
|
||||
|
||||
static void sock_pe_progress_pending_ack(struct sock_pe *pe,
|
||||
@ -389,7 +422,7 @@ static void sock_pe_progress_pending_ack(struct sock_pe *pe,
|
||||
break;
|
||||
}
|
||||
|
||||
if (pe_entry->total_len == pe_entry->done_len) {
|
||||
if (pe_entry->total_len == pe_entry->done_len && !pe_entry->rem) {
|
||||
pe_entry->is_complete = 1;
|
||||
pe_entry->pe.rx.pending_send = 0;
|
||||
sock_comm_flush(pe_entry->conn);
|
||||
@ -400,12 +433,13 @@ static void sock_pe_progress_pending_ack(struct sock_pe *pe,
|
||||
static void sock_pe_send_response(struct sock_pe *pe,
|
||||
struct sock_rx_ctx *rx_ctx,
|
||||
struct sock_pe_entry *pe_entry,
|
||||
size_t data_len, uint8_t op_type)
|
||||
size_t data_len, uint8_t op_type, int err)
|
||||
{
|
||||
struct sock_msg_response *response = &pe_entry->response;
|
||||
memset(response, 0, sizeof(struct sock_msg_response));
|
||||
|
||||
response->pe_entry_id = htons(pe_entry->msg_hdr.pe_entry_id);
|
||||
response->err = htonl(err);
|
||||
response->msg_hdr.dest_iov_len = 0;
|
||||
response->msg_hdr.flags = 0;
|
||||
response->msg_hdr.msg_len = sizeof(*response) + data_len;
|
||||
@ -437,6 +471,7 @@ inline static int sock_pe_read_response(struct sock_pe_entry *pe_entry)
|
||||
data_len, len)))
|
||||
return ret;
|
||||
pe_entry->response.pe_entry_id = ntohs(pe_entry->response.pe_entry_id);
|
||||
pe_entry->response.err = ntohl(pe_entry->response.err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -461,6 +496,40 @@ static int sock_pe_handle_ack(struct sock_pe *pe, struct sock_pe_entry *pe_entry
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sock_pe_handle_error(struct sock_pe *pe, struct sock_pe_entry *pe_entry)
|
||||
{
|
||||
struct sock_pe_entry *waiting_entry;
|
||||
struct sock_msg_response *response;
|
||||
|
||||
if (sock_pe_read_response(pe_entry))
|
||||
return 0;
|
||||
|
||||
response = &pe_entry->response;
|
||||
assert(response->pe_entry_id <= SOCK_PE_MAX_ENTRIES);
|
||||
waiting_entry = &pe->pe_table[response->pe_entry_id];
|
||||
SOCK_LOG_INFO("Received error for PE entry %p (index: %d)\n",
|
||||
waiting_entry, response->pe_entry_id);
|
||||
|
||||
assert(waiting_entry->type == SOCK_PE_TX);
|
||||
|
||||
switch (pe_entry->msg_hdr.op_type) {
|
||||
case SOCK_OP_READ_ERROR:
|
||||
sock_pe_report_tx_rma_read_err(waiting_entry,
|
||||
pe_entry->response.err);
|
||||
break;
|
||||
case SOCK_OP_WRITE_ERROR:
|
||||
case SOCK_OP_ATOMIC_ERROR:
|
||||
sock_pe_report_tx_rma_write_err(waiting_entry,
|
||||
pe_entry->response.err);
|
||||
break;
|
||||
default:
|
||||
SOCK_LOG_ERROR("Invalid op type\n");
|
||||
}
|
||||
waiting_entry->is_complete = 1;
|
||||
pe_entry->is_complete = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sock_pe_handle_read_complete(struct sock_pe *pe,
|
||||
struct sock_pe_entry *pe_entry)
|
||||
{
|
||||
@ -484,10 +553,10 @@ static int sock_pe_handle_read_complete(struct sock_pe *pe,
|
||||
for (i=0; i < waiting_entry->pe.tx.tx_op.dest_iov_len; i++) {
|
||||
if (sock_pe_recv_field(
|
||||
pe_entry,
|
||||
(char *) (uintptr_t) waiting_entry->pe.tx.data.tx_iov[i].dst.iov.addr,
|
||||
waiting_entry->pe.tx.data.tx_iov[i].dst.iov.len, len))
|
||||
(char *) (uintptr_t) waiting_entry->pe.tx.tx_iov[i].dst.iov.addr,
|
||||
waiting_entry->pe.tx.tx_iov[i].dst.iov.len, len))
|
||||
return 0;
|
||||
len += waiting_entry->pe.tx.data.tx_iov[i].dst.iov.len;
|
||||
len += waiting_entry->pe.tx.tx_iov[i].dst.iov.len;
|
||||
}
|
||||
|
||||
sock_pe_report_read_completion(waiting_entry);
|
||||
@ -543,11 +612,11 @@ static int sock_pe_handle_atomic_complete(struct sock_pe *pe,
|
||||
for (i=0; i < waiting_entry->pe.tx.tx_op.atomic.res_iov_len; i++) {
|
||||
if (sock_pe_recv_field(
|
||||
pe_entry,
|
||||
(char *) (uintptr_t) waiting_entry->pe.tx.data.tx_iov[i].res.ioc.addr,
|
||||
waiting_entry->pe.tx.data.tx_iov[i].res.ioc.count * datatype_sz,
|
||||
(char *) (uintptr_t) waiting_entry->pe.tx.tx_iov[i].res.ioc.addr,
|
||||
waiting_entry->pe.tx.tx_iov[i].res.ioc.count * datatype_sz,
|
||||
len))
|
||||
return 0;
|
||||
len += (waiting_entry->pe.tx.data.tx_iov[i].res.ioc.count * datatype_sz);
|
||||
len += (waiting_entry->pe.tx.tx_iov[i].res.ioc.count * datatype_sz);
|
||||
}
|
||||
|
||||
if (waiting_entry->pe.rx.rx_op.atomic.res_iov_len)
|
||||
@ -588,22 +657,24 @@ static int sock_pe_process_rx_read(struct sock_pe *pe, struct sock_rx_ctx *rx_ct
|
||||
(void *) (uintptr_t) pe_entry->pe.rx.rx_iov[i].iov.addr,
|
||||
pe_entry->pe.rx.rx_iov[i].iov.len,
|
||||
pe_entry->pe.rx.rx_iov[i].iov.key);
|
||||
pe_entry->is_error = 1;
|
||||
pe_entry->rem = pe_entry->total_len - pe_entry->done_len;
|
||||
sock_pe_send_response(pe, rx_ctx, pe_entry, 0,
|
||||
SOCK_OP_READ_ERROR);
|
||||
return -FI_EINVAL;
|
||||
SOCK_OP_READ_ERROR, FI_EACCES);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mr->flags & FI_MR_OFFSET)
|
||||
if (mr->domain->attr.mr_mode == FI_MR_SCALABLE)
|
||||
pe_entry->pe.rx.rx_iov[i].iov.addr += mr->offset;
|
||||
data_len += pe_entry->pe.rx.rx_iov[i].iov.len;
|
||||
}
|
||||
|
||||
pe_entry->buf = pe_entry->pe.rx.rx_iov[0].iov.addr;
|
||||
pe_entry->data_len = data_len;
|
||||
|
||||
pe_entry->flags |= (FI_RMA | FI_REMOTE_READ);
|
||||
sock_pe_report_remote_read(rx_ctx, pe_entry);
|
||||
sock_pe_send_response(pe, rx_ctx, pe_entry, data_len,
|
||||
SOCK_OP_READ_COMPLETE);
|
||||
SOCK_OP_READ_COMPLETE, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -641,12 +712,14 @@ static int sock_pe_process_rx_write(struct sock_pe *pe, struct sock_rx_ctx *rx_c
|
||||
(void *) (uintptr_t) pe_entry->pe.rx.rx_iov[i].iov.addr,
|
||||
pe_entry->pe.rx.rx_iov[i].iov.len,
|
||||
pe_entry->pe.rx.rx_iov[i].iov.key);
|
||||
pe_entry->is_error = 1;
|
||||
pe_entry->rem = pe_entry->total_len - pe_entry->done_len;
|
||||
sock_pe_send_response(pe, rx_ctx, pe_entry, 0,
|
||||
SOCK_OP_WRITE_ERROR);
|
||||
break;
|
||||
SOCK_OP_WRITE_ERROR, FI_EACCES);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mr->flags & FI_MR_OFFSET)
|
||||
if (mr->domain->attr.mr_mode == FI_MR_SCALABLE)
|
||||
pe_entry->pe.rx.rx_iov[i].iov.addr += mr->offset;
|
||||
}
|
||||
|
||||
@ -665,7 +738,7 @@ static int sock_pe_process_rx_write(struct sock_pe *pe, struct sock_rx_ctx *rx_c
|
||||
|
||||
/* report error, if any */
|
||||
if (rem) {
|
||||
sock_pe_report_error(pe_entry, rem);
|
||||
sock_pe_report_rx_error(pe_entry, rem);
|
||||
goto out;
|
||||
} else {
|
||||
if (pe_entry->flags & FI_REMOTE_CQ_DATA) {
|
||||
@ -674,10 +747,11 @@ static int sock_pe_process_rx_write(struct sock_pe *pe, struct sock_rx_ctx *rx_c
|
||||
}
|
||||
|
||||
out:
|
||||
pe_entry->flags |= (FI_RMA | FI_REMOTE_WRITE);
|
||||
sock_pe_report_remote_write(rx_ctx, pe_entry);
|
||||
sock_pe_report_mr_completion(rx_ctx->domain, pe_entry);
|
||||
sock_pe_send_response(pe, rx_ctx, pe_entry, 0,
|
||||
SOCK_OP_WRITE_COMPLETE);
|
||||
SOCK_OP_WRITE_COMPLETE, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1042,26 +1116,27 @@ static int sock_pe_process_rx_atomic(struct sock_pe *pe, struct sock_rx_ctx *rx_
|
||||
entry_len, len))
|
||||
return 0;
|
||||
len += entry_len;
|
||||
}
|
||||
|
||||
/* compare */
|
||||
for (i = 0; i < pe_entry->pe.rx.rx_op.dest_iov_len; i++) {
|
||||
mr = sock_mr_verify_key(rx_ctx->domain,
|
||||
pe_entry->pe.rx.rx_iov[i].ioc.key,
|
||||
(void *) (uintptr_t) pe_entry->pe.rx.rx_iov[i].ioc.addr,
|
||||
pe_entry->pe.rx.rx_iov[i].ioc.count * datatype_sz,
|
||||
FI_REMOTE_WRITE);
|
||||
if (!mr) {
|
||||
SOCK_LOG_ERROR("Remote memory access error: %p, %lu, %" PRIu64 "\n",
|
||||
(void *) (uintptr_t) pe_entry->pe.rx.rx_iov[i].ioc.addr,
|
||||
pe_entry->pe.rx.rx_iov[i].ioc.count * datatype_sz,
|
||||
pe_entry->pe.rx.rx_iov[i].ioc.key);
|
||||
sock_pe_send_response(pe, rx_ctx, pe_entry, 0,
|
||||
SOCK_OP_ATOMIC_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if (mr->flags & FI_MR_OFFSET)
|
||||
pe_entry->pe.rx.rx_iov[i].ioc.addr += mr->offset;
|
||||
for (i = 0; i < pe_entry->pe.rx.rx_op.dest_iov_len; i++) {
|
||||
mr = sock_mr_verify_key(rx_ctx->domain,
|
||||
pe_entry->pe.rx.rx_iov[i].ioc.key,
|
||||
(void *) (uintptr_t) pe_entry->pe.rx.rx_iov[i].ioc.addr,
|
||||
pe_entry->pe.rx.rx_iov[i].ioc.count * datatype_sz,
|
||||
FI_REMOTE_WRITE);
|
||||
if (!mr) {
|
||||
SOCK_LOG_ERROR("Remote memory access error: %p, %lu, %" PRIu64 "\n",
|
||||
(void *) (uintptr_t) pe_entry->pe.rx.rx_iov[i].ioc.addr,
|
||||
pe_entry->pe.rx.rx_iov[i].ioc.count * datatype_sz,
|
||||
pe_entry->pe.rx.rx_iov[i].ioc.key);
|
||||
pe_entry->is_error = 1;
|
||||
pe_entry->rem = pe_entry->total_len - pe_entry->done_len;
|
||||
sock_pe_send_response(pe, rx_ctx, pe_entry, 0,
|
||||
SOCK_OP_ATOMIC_ERROR, FI_EACCES);
|
||||
return 0;
|
||||
}
|
||||
if (mr->domain->attr.mr_mode == FI_MR_SCALABLE)
|
||||
pe_entry->pe.rx.rx_iov[i].ioc.addr += mr->offset;
|
||||
}
|
||||
|
||||
/* src data */
|
||||
@ -1088,17 +1163,120 @@ static int sock_pe_process_rx_atomic(struct sock_pe *pe, struct sock_rx_ctx *rx_
|
||||
if (pe_entry->flags & FI_REMOTE_CQ_DATA) {
|
||||
sock_pe_report_rx_completion(pe_entry);
|
||||
}
|
||||
|
||||
|
||||
pe_entry->flags |= FI_ATOMIC;
|
||||
if (pe_entry->pe.rx.rx_op.atomic.op == FI_ATOMIC_READ)
|
||||
pe_entry->flags |= FI_REMOTE_READ;
|
||||
else
|
||||
pe_entry->flags |= FI_REMOTE_WRITE;
|
||||
sock_pe_report_remote_write(rx_ctx, pe_entry);
|
||||
sock_pe_report_mr_completion(rx_ctx->domain, pe_entry);
|
||||
sock_pe_send_response(pe, rx_ctx, pe_entry,
|
||||
pe_entry->pe.rx.rx_op.atomic.res_iov_len ?
|
||||
entry_len : 0, SOCK_OP_ATOMIC_COMPLETE);
|
||||
entry_len : 0, SOCK_OP_ATOMIC_COMPLETE, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t sock_rx_peek_recv(struct sock_rx_ctx *rx_ctx, fi_addr_t addr,
|
||||
uint64_t tag, uint64_t ignore, void *context,
|
||||
uint64_t flags, uint8_t is_tagged)
|
||||
{
|
||||
ssize_t ret = 0;
|
||||
struct sock_rx_entry *rx_buffered;
|
||||
struct sock_pe_entry pe_entry;
|
||||
|
||||
fastlock_acquire(&rx_ctx->lock);
|
||||
rx_buffered = sock_rx_get_buffered_entry(rx_ctx,
|
||||
(rx_ctx->attr.caps & FI_DIRECTED_RECV) ?
|
||||
addr : FI_ADDR_UNSPEC,
|
||||
tag, ignore, is_tagged);
|
||||
if (rx_buffered) {
|
||||
memset(&pe_entry, 0, sizeof pe_entry);
|
||||
pe_entry.comp = &rx_ctx->comp;
|
||||
pe_entry.data_len = rx_buffered->total_len;
|
||||
pe_entry.tag = rx_buffered->tag;
|
||||
pe_entry.context = rx_buffered->context = (uintptr_t)context;
|
||||
pe_entry.flags = (flags | FI_MSG | FI_RECV);
|
||||
if (is_tagged)
|
||||
pe_entry.flags |= FI_TAGGED;
|
||||
|
||||
if (flags & FI_CLAIM)
|
||||
rx_buffered->is_claimed = 1;
|
||||
|
||||
if (flags & FI_DISCARD) {
|
||||
dlist_remove(&rx_buffered->entry);
|
||||
sock_rx_release_entry(rx_buffered);
|
||||
}
|
||||
sock_pe_report_rx_completion(&pe_entry);
|
||||
} else {
|
||||
ret = -FI_ENOMSG;
|
||||
}
|
||||
fastlock_release(&rx_ctx->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t sock_rx_claim_recv(struct sock_rx_ctx *rx_ctx, void *context, uint64_t flags,
|
||||
uint64_t tag, uint64_t ignore, uint8_t is_tagged,
|
||||
const struct iovec *msg_iov, size_t iov_count)
|
||||
{
|
||||
ssize_t ret = 0;
|
||||
size_t rem = 0, i, offset, len;
|
||||
struct dlist_entry *entry;
|
||||
struct sock_pe_entry pe_entry;
|
||||
struct sock_rx_entry *rx_buffered = NULL;
|
||||
|
||||
err:
|
||||
sock_pe_report_error(pe_entry, 0);
|
||||
return -FI_EINVAL;
|
||||
fastlock_acquire(&rx_ctx->lock);
|
||||
for (entry = rx_ctx->rx_buffered_list.next;
|
||||
entry != &rx_ctx->rx_buffered_list; entry = entry->next) {
|
||||
rx_buffered = container_of(entry, struct sock_rx_entry, entry);
|
||||
if (rx_buffered->is_claimed &&
|
||||
(uintptr_t)rx_buffered->context == (uintptr_t)context &&
|
||||
is_tagged == rx_buffered->is_tagged &&
|
||||
(tag & ~ignore) == (rx_buffered->tag & ~ignore))
|
||||
break;
|
||||
else
|
||||
rx_buffered = NULL;
|
||||
}
|
||||
|
||||
if (rx_buffered) {
|
||||
memset(&pe_entry, 0, sizeof pe_entry);
|
||||
pe_entry.comp = &rx_ctx->comp;
|
||||
pe_entry.data_len = rx_buffered->total_len;
|
||||
pe_entry.tag = rx_buffered->tag;
|
||||
pe_entry.context = rx_buffered->context;
|
||||
pe_entry.flags = (flags | FI_MSG | FI_RECV);
|
||||
if (is_tagged)
|
||||
pe_entry.flags |= FI_TAGGED;
|
||||
|
||||
if (!(flags & FI_DISCARD)) {
|
||||
pe_entry.buf = (uintptr_t)msg_iov[0].iov_base;
|
||||
offset = 0;
|
||||
rem = rx_buffered->total_len;
|
||||
for (i = 0; i < iov_count && rem > 0; i++) {
|
||||
len = MIN(msg_iov[i].iov_len, rem);
|
||||
memcpy(msg_iov[i].iov_base,
|
||||
(char *) (uintptr_t)
|
||||
rx_buffered->iov[0].iov.addr + offset, len);
|
||||
rem -= len;
|
||||
offset += len;
|
||||
}
|
||||
}
|
||||
|
||||
if (rem) {
|
||||
SOCK_LOG_INFO("Not enough space in posted recv buffer\n");
|
||||
sock_pe_report_rx_error(&pe_entry, rem);
|
||||
} else {
|
||||
sock_pe_report_rx_completion(&pe_entry);
|
||||
}
|
||||
|
||||
dlist_remove(&rx_buffered->entry);
|
||||
sock_rx_release_entry(rx_buffered);
|
||||
} else {
|
||||
ret = -FI_ENOMSG;
|
||||
}
|
||||
|
||||
fastlock_release(&rx_ctx->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sock_pe_progress_buffered_rx(struct sock_rx_ctx *rx_ctx)
|
||||
@ -1118,7 +1296,7 @@ static int sock_pe_progress_buffered_rx(struct sock_rx_ctx *rx_ctx)
|
||||
rx_buffered = container_of(entry, struct sock_rx_entry, entry);
|
||||
entry = entry->next;
|
||||
|
||||
if (!rx_buffered->is_complete)
|
||||
if (!rx_buffered->is_complete || rx_buffered->is_claimed)
|
||||
continue;
|
||||
|
||||
rx_posted = sock_rx_get_entry(rx_ctx, rx_buffered->addr,
|
||||
@ -1164,6 +1342,9 @@ static int sock_pe_progress_buffered_rx(struct sock_rx_ctx *rx_ctx)
|
||||
pe_entry.type = SOCK_PE_RX;
|
||||
pe_entry.comp = rx_buffered->comp;
|
||||
pe_entry.flags = rx_posted->flags;
|
||||
pe_entry.flags |= (FI_MSG | FI_RECV);
|
||||
if (rx_buffered->is_tagged)
|
||||
pe_entry.flags |= FI_TAGGED;
|
||||
pe_entry.flags &= ~FI_MULTI_RECV;
|
||||
|
||||
if (rx_posted->flags & FI_MULTI_RECV) {
|
||||
@ -1177,7 +1358,7 @@ static int sock_pe_progress_buffered_rx(struct sock_rx_ctx *rx_ctx)
|
||||
|
||||
if (rem) {
|
||||
SOCK_LOG_INFO("Not enough space in posted recv buffer\n");
|
||||
sock_pe_report_error(&pe_entry, rem);
|
||||
sock_pe_report_rx_error(&pe_entry, rem);
|
||||
return 0;
|
||||
} else {
|
||||
sock_pe_report_rx_completion(&pe_entry);
|
||||
@ -1225,7 +1406,8 @@ static int sock_pe_process_rx_send(struct sock_pe *pe, struct sock_rx_ctx *rx_ct
|
||||
fastlock_acquire(&rx_ctx->lock);
|
||||
sock_pe_progress_buffered_rx(rx_ctx);
|
||||
|
||||
rx_entry = sock_rx_get_entry(rx_ctx, pe_entry->addr, pe_entry->tag, pe_entry->msg_hdr.op_type);
|
||||
rx_entry = sock_rx_get_entry(rx_ctx, pe_entry->addr, pe_entry->tag,
|
||||
pe_entry->msg_hdr.op_type == SOCK_OP_TSEND ? 1 : 0);
|
||||
SOCK_LOG_INFO("Consuming posted entry: %p\n", rx_entry);
|
||||
|
||||
if (!rx_entry) {
|
||||
@ -1292,7 +1474,12 @@ static int sock_pe_process_rx_send(struct sock_pe *pe, struct sock_rx_ctx *rx_ct
|
||||
pe_entry->is_complete = 1;
|
||||
rx_entry->is_complete = 1;
|
||||
rx_entry->is_busy = 0;
|
||||
|
||||
pe_entry->flags = rx_entry->flags;
|
||||
if (pe_entry->msg_hdr.op_type == SOCK_OP_TSEND)
|
||||
pe_entry->flags |= FI_TAGGED;
|
||||
pe_entry->flags |= (FI_MSG | FI_RECV);
|
||||
|
||||
if (pe_entry->msg_hdr.flags & FI_REMOTE_CQ_DATA)
|
||||
pe_entry->flags |= FI_REMOTE_CQ_DATA;
|
||||
pe_entry->flags &= ~FI_MULTI_RECV;
|
||||
@ -1312,7 +1499,9 @@ static int sock_pe_process_rx_send(struct sock_pe *pe, struct sock_rx_ctx *rx_ct
|
||||
/* report error, if any */
|
||||
if (rem) {
|
||||
SOCK_LOG_ERROR("Not enough space in posted recv buffer\n");
|
||||
sock_pe_report_error(pe_entry, rem);
|
||||
sock_pe_report_rx_error(pe_entry, rem);
|
||||
pe_entry->is_error = 1;
|
||||
pe_entry->rem = pe_entry->total_len - pe_entry->done_len;
|
||||
goto out;
|
||||
} else {
|
||||
if (!rx_entry->is_buffered)
|
||||
@ -1322,7 +1511,7 @@ static int sock_pe_process_rx_send(struct sock_pe *pe, struct sock_rx_ctx *rx_ct
|
||||
out:
|
||||
if (pe_entry->msg_hdr.flags & FI_TRANSMIT_COMPLETE) {
|
||||
sock_pe_send_response(pe, rx_ctx, pe_entry, 0,
|
||||
SOCK_OP_SEND_COMPLETE);
|
||||
SOCK_OP_SEND_COMPLETE, 0);
|
||||
}
|
||||
|
||||
if (!rx_entry->is_buffered &&
|
||||
@ -1378,7 +1567,7 @@ static int sock_pe_process_recv(struct sock_pe *pe, struct sock_rx_ctx *rx_ctx,
|
||||
case SOCK_OP_WRITE_ERROR:
|
||||
case SOCK_OP_READ_ERROR:
|
||||
case SOCK_OP_ATOMIC_ERROR:
|
||||
ret = sock_pe_handle_ack(pe, pe_entry);
|
||||
ret = sock_pe_handle_error(pe, pe_entry);
|
||||
break;
|
||||
default:
|
||||
ret = -FI_ENOSYS;
|
||||
@ -1449,6 +1638,7 @@ static int sock_pe_read_hdr(struct sock_pe *pe, struct sock_rx_ctx *rx_ctx,
|
||||
msg_hdr->pe_entry_id = ntohs(msg_hdr->pe_entry_id);
|
||||
pe_entry->pe.rx.header_read = 1;
|
||||
pe_entry->flags = msg_hdr->flags;
|
||||
pe_entry->total_len = msg_hdr->msg_len;
|
||||
|
||||
SOCK_LOG_INFO("PE RX (Hdr read): MsgLen: %" PRIu64 ", TX-ID: %d, Type: %d\n",
|
||||
msg_hdr->msg_len, msg_hdr->rx_id, msg_hdr->op_type);
|
||||
@ -1482,9 +1672,9 @@ static int sock_pe_progress_tx_atomic(struct sock_pe *pe,
|
||||
/* dest iocs */
|
||||
entry_len = sizeof(union sock_iov) * pe_entry->pe.tx.tx_op.dest_iov_len;
|
||||
for (i=0; i < pe_entry->pe.tx.tx_op.dest_iov_len; i++) {
|
||||
iov[i].ioc.addr = pe_entry->pe.tx.data.tx_iov[i].dst.ioc.addr;
|
||||
iov[i].ioc.count = pe_entry->pe.tx.data.tx_iov[i].dst.ioc.count;
|
||||
iov[i].ioc.key = pe_entry->pe.tx.data.tx_iov[i].dst.ioc.key;
|
||||
iov[i].ioc.addr = pe_entry->pe.tx.tx_iov[i].dst.ioc.addr;
|
||||
iov[i].ioc.count = pe_entry->pe.tx.tx_iov[i].dst.ioc.count;
|
||||
iov[i].ioc.key = pe_entry->pe.tx.tx_iov[i].dst.ioc.key;
|
||||
}
|
||||
|
||||
if (sock_pe_send_field(pe_entry, &iov[0], entry_len, len))
|
||||
@ -1495,28 +1685,28 @@ static int sock_pe_progress_tx_atomic(struct sock_pe *pe,
|
||||
datatype_sz = fi_datatype_size(pe_entry->pe.tx.tx_op.atomic.datatype);
|
||||
for (i=0; i < pe_entry->pe.tx.tx_op.atomic.cmp_iov_len; i++) {
|
||||
if (sock_pe_send_field(pe_entry,
|
||||
(void *) (uintptr_t) pe_entry->pe.tx.data.tx_iov[i].cmp.ioc.addr,
|
||||
pe_entry->pe.tx.data.tx_iov[i].cmp.ioc.count *
|
||||
(void *) (uintptr_t) pe_entry->pe.tx.tx_iov[i].cmp.ioc.addr,
|
||||
pe_entry->pe.tx.tx_iov[i].cmp.ioc.count *
|
||||
datatype_sz, len))
|
||||
return 0;
|
||||
len += (pe_entry->pe.tx.data.tx_iov[i].cmp.ioc.count * datatype_sz);
|
||||
len += (pe_entry->pe.tx.tx_iov[i].cmp.ioc.count * datatype_sz);
|
||||
}
|
||||
|
||||
/* data */
|
||||
if (pe_entry->flags & FI_INJECT) {
|
||||
if (sock_pe_send_field(pe_entry,
|
||||
&pe_entry->pe.tx.data.inject[0],
|
||||
&pe_entry->pe.tx.inject[0],
|
||||
pe_entry->pe.tx.tx_op.src_iov_len, len))
|
||||
return 0;
|
||||
len += pe_entry->pe.tx.tx_op.src_iov_len;
|
||||
} else {
|
||||
for (i=0; i < pe_entry->pe.tx.tx_op.src_iov_len; i++) {
|
||||
if (sock_pe_send_field(pe_entry,
|
||||
(void *) (uintptr_t) pe_entry->pe.tx.data.tx_iov[i].src.ioc.addr,
|
||||
pe_entry->pe.tx.data.tx_iov[i].src.ioc.count *
|
||||
(void *) (uintptr_t) pe_entry->pe.tx.tx_iov[i].src.ioc.addr,
|
||||
pe_entry->pe.tx.tx_iov[i].src.ioc.count *
|
||||
datatype_sz, len))
|
||||
return 0;
|
||||
len += (pe_entry->pe.tx.data.tx_iov[i].src.ioc.count * datatype_sz);
|
||||
len += (pe_entry->pe.tx.tx_iov[i].src.ioc.count * datatype_sz);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1526,6 +1716,12 @@ static int sock_pe_progress_tx_atomic(struct sock_pe *pe,
|
||||
SOCK_LOG_INFO("Send complete\n");
|
||||
}
|
||||
sock_comm_flush(pe_entry->conn);
|
||||
|
||||
pe_entry->flags |= FI_ATOMIC;
|
||||
if (pe_entry->pe.tx.tx_op.atomic.op == FI_ATOMIC_READ)
|
||||
pe_entry->flags |= FI_READ;
|
||||
else
|
||||
pe_entry->flags |= FI_WRITE;
|
||||
pe_entry->msg_hdr.flags = pe_entry->flags;
|
||||
return 0;
|
||||
}
|
||||
@ -1551,9 +1747,9 @@ static int sock_pe_progress_tx_write(struct sock_pe *pe,
|
||||
/* dest iovs */
|
||||
dest_iov_len = sizeof(union sock_iov) * pe_entry->pe.tx.tx_op.dest_iov_len;
|
||||
for (i=0; i < pe_entry->pe.tx.tx_op.dest_iov_len; i++) {
|
||||
dest_iov[i].iov.addr = pe_entry->pe.tx.data.tx_iov[i].dst.iov.addr;
|
||||
dest_iov[i].iov.len = pe_entry->pe.tx.data.tx_iov[i].dst.iov.len;
|
||||
dest_iov[i].iov.key = pe_entry->pe.tx.data.tx_iov[i].dst.iov.key;
|
||||
dest_iov[i].iov.addr = pe_entry->pe.tx.tx_iov[i].dst.iov.addr;
|
||||
dest_iov[i].iov.len = pe_entry->pe.tx.tx_iov[i].dst.iov.len;
|
||||
dest_iov[i].iov.key = pe_entry->pe.tx.tx_iov[i].dst.iov.key;
|
||||
}
|
||||
if (sock_pe_send_field(pe_entry, &dest_iov[0], dest_iov_len, len))
|
||||
return 0;
|
||||
@ -1561,7 +1757,7 @@ static int sock_pe_progress_tx_write(struct sock_pe *pe,
|
||||
|
||||
/* data */
|
||||
if (pe_entry->flags & FI_INJECT) {
|
||||
if (sock_pe_send_field(pe_entry, &pe_entry->pe.tx.data.inject[0],
|
||||
if (sock_pe_send_field(pe_entry, &pe_entry->pe.tx.inject[0],
|
||||
pe_entry->pe.tx.tx_op.src_iov_len, len))
|
||||
return 0;
|
||||
len += pe_entry->pe.tx.tx_op.src_iov_len;
|
||||
@ -1571,11 +1767,11 @@ static int sock_pe_progress_tx_write(struct sock_pe *pe,
|
||||
for (i=0; i < pe_entry->pe.tx.tx_op.src_iov_len; i++) {
|
||||
if (sock_pe_send_field(
|
||||
pe_entry,
|
||||
(void *) (uintptr_t) pe_entry->pe.tx.data.tx_iov[i].src.iov.addr,
|
||||
pe_entry->pe.tx.data.tx_iov[i].src.iov.len, len))
|
||||
(void *) (uintptr_t) pe_entry->pe.tx.tx_iov[i].src.iov.addr,
|
||||
pe_entry->pe.tx.tx_iov[i].src.iov.len, len))
|
||||
return 0;
|
||||
len += pe_entry->pe.tx.data.tx_iov[i].src.iov.len;
|
||||
pe_entry->data_len += pe_entry->pe.tx.data.tx_iov[i].src.iov.len;
|
||||
len += pe_entry->pe.tx.tx_iov[i].src.iov.len;
|
||||
pe_entry->data_len += pe_entry->pe.tx.tx_iov[i].src.iov.len;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1585,6 +1781,7 @@ static int sock_pe_progress_tx_write(struct sock_pe *pe,
|
||||
SOCK_LOG_INFO("Send complete\n");
|
||||
}
|
||||
sock_comm_flush(pe_entry->conn);
|
||||
pe_entry->flags |= (FI_RMA | FI_WRITE);
|
||||
pe_entry->msg_hdr.flags = pe_entry->flags;
|
||||
return 0;
|
||||
}
|
||||
@ -1605,10 +1802,10 @@ static int sock_pe_progress_tx_read(struct sock_pe *pe,
|
||||
src_iov_len = sizeof(union sock_iov) * pe_entry->pe.tx.tx_op.src_iov_len;
|
||||
pe_entry->data_len = 0;
|
||||
for (i=0; i < pe_entry->pe.tx.tx_op.src_iov_len; i++) {
|
||||
src_iov[i].iov.addr = pe_entry->pe.tx.data.tx_iov[i].src.iov.addr;
|
||||
src_iov[i].iov.len = pe_entry->pe.tx.data.tx_iov[i].src.iov.len;
|
||||
src_iov[i].iov.key = pe_entry->pe.tx.data.tx_iov[i].src.iov.key;
|
||||
pe_entry->data_len += pe_entry->pe.tx.data.tx_iov[i].src.iov.len;
|
||||
src_iov[i].iov.addr = pe_entry->pe.tx.tx_iov[i].src.iov.addr;
|
||||
src_iov[i].iov.len = pe_entry->pe.tx.tx_iov[i].src.iov.len;
|
||||
src_iov[i].iov.key = pe_entry->pe.tx.tx_iov[i].src.iov.key;
|
||||
pe_entry->data_len += pe_entry->pe.tx.tx_iov[i].src.iov.len;
|
||||
}
|
||||
|
||||
if (sock_pe_send_field(pe_entry, &src_iov[0], src_iov_len, len))
|
||||
@ -1621,6 +1818,7 @@ static int sock_pe_progress_tx_read(struct sock_pe *pe,
|
||||
SOCK_LOG_INFO("Send complete\n");
|
||||
}
|
||||
sock_comm_flush(pe_entry->conn);
|
||||
pe_entry->flags |= (FI_RMA | FI_READ);
|
||||
pe_entry->msg_hdr.flags = pe_entry->flags;
|
||||
return 0;
|
||||
}
|
||||
@ -1650,7 +1848,7 @@ static int sock_pe_progress_tx_send(struct sock_pe *pe,
|
||||
}
|
||||
|
||||
if (pe_entry->flags & FI_INJECT) {
|
||||
if (sock_pe_send_field(pe_entry, pe_entry->pe.tx.data.inject,
|
||||
if (sock_pe_send_field(pe_entry, pe_entry->pe.tx.inject,
|
||||
pe_entry->pe.tx.tx_op.src_iov_len, len))
|
||||
return 0;
|
||||
len += pe_entry->pe.tx.tx_op.src_iov_len;
|
||||
@ -1659,15 +1857,19 @@ static int sock_pe_progress_tx_send(struct sock_pe *pe,
|
||||
pe_entry->data_len = 0;
|
||||
for (i = 0; i < pe_entry->pe.tx.tx_op.src_iov_len; i++) {
|
||||
if (sock_pe_send_field(pe_entry,
|
||||
(void *) (uintptr_t) pe_entry->pe.tx.data.tx_iov[i].src.iov.addr,
|
||||
pe_entry->pe.tx.data.tx_iov[i].src.iov.len, len))
|
||||
(void *) (uintptr_t) pe_entry->pe.tx.tx_iov[i].src.iov.addr,
|
||||
pe_entry->pe.tx.tx_iov[i].src.iov.len, len))
|
||||
return 0;
|
||||
len += pe_entry->pe.tx.data.tx_iov[i].src.iov.len;
|
||||
pe_entry->data_len += pe_entry->pe.tx.data.tx_iov[i].src.iov.len;
|
||||
len += pe_entry->pe.tx.tx_iov[i].src.iov.len;
|
||||
pe_entry->data_len += pe_entry->pe.tx.tx_iov[i].src.iov.len;
|
||||
}
|
||||
}
|
||||
|
||||
sock_comm_flush(pe_entry->conn);
|
||||
if (pe_entry->pe.tx.tx_op.op == SOCK_OP_TSEND)
|
||||
pe_entry->flags |= FI_TAGGED;
|
||||
pe_entry->flags |= (FI_MSG | FI_SEND);
|
||||
|
||||
pe_entry->msg_hdr.flags = pe_entry->flags;
|
||||
if (pe_entry->done_len == pe_entry->total_len) {
|
||||
pe_entry->pe.tx.send_done = 1;
|
||||
@ -1751,6 +1953,9 @@ static int sock_pe_progress_rx_pe_entry(struct sock_pe *pe,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (pe_entry->is_error)
|
||||
goto out;
|
||||
|
||||
if (!pe_entry->pe.rx.header_read) {
|
||||
if (sock_pe_read_hdr(pe, rx_ctx, pe_entry) == -1) {
|
||||
sock_pe_release_entry(pe, pe_entry);
|
||||
@ -1765,6 +1970,9 @@ static int sock_pe_progress_rx_pe_entry(struct sock_pe *pe,
|
||||
}
|
||||
|
||||
out:
|
||||
if (pe_entry->is_error)
|
||||
sock_pe_discard_field(pe_entry);
|
||||
|
||||
if (pe_entry->is_complete && !pe_entry->pe.rx.pending_send) {
|
||||
sock_pe_release_entry(pe, pe_entry);
|
||||
SOCK_LOG_INFO("[%p] RX done\n", pe_entry);
|
||||
@ -1871,80 +2079,80 @@ static int sock_pe_new_tx_entry(struct sock_pe *pe, struct sock_tx_ctx *tx_ctx)
|
||||
case SOCK_OP_SEND:
|
||||
case SOCK_OP_TSEND:
|
||||
if (pe_entry->flags & FI_INJECT) {
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.data.inject[0],
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.inject[0],
|
||||
pe_entry->pe.tx.tx_op.src_iov_len);
|
||||
msg_hdr->msg_len += pe_entry->pe.tx.tx_op.src_iov_len;
|
||||
} else {
|
||||
for (i = 0; i < pe_entry->pe.tx.tx_op.src_iov_len; i++) {
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.data.tx_iov[i].src,
|
||||
sizeof(pe_entry->pe.tx.data.tx_iov[i].src));
|
||||
msg_hdr->msg_len += pe_entry->pe.tx.data.tx_iov[i].src.iov.len;
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.tx_iov[i].src,
|
||||
sizeof(pe_entry->pe.tx.tx_iov[i].src));
|
||||
msg_hdr->msg_len += pe_entry->pe.tx.tx_iov[i].src.iov.len;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SOCK_OP_WRITE:
|
||||
if (pe_entry->flags & FI_INJECT) {
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.data.inject[0],
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.inject[0],
|
||||
pe_entry->pe.tx.tx_op.src_iov_len);
|
||||
msg_hdr->msg_len += pe_entry->pe.tx.tx_op.src_iov_len;
|
||||
} else {
|
||||
for (i = 0; i < pe_entry->pe.tx.tx_op.src_iov_len; i++) {
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.data.tx_iov[i].src,
|
||||
sizeof(pe_entry->pe.tx.data.tx_iov[i].src));
|
||||
msg_hdr->msg_len += pe_entry->pe.tx.data.tx_iov[i].src.iov.len;
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.tx_iov[i].src,
|
||||
sizeof(pe_entry->pe.tx.tx_iov[i].src));
|
||||
msg_hdr->msg_len += pe_entry->pe.tx.tx_iov[i].src.iov.len;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < pe_entry->pe.tx.tx_op.dest_iov_len; i++) {
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.data.tx_iov[i].dst,
|
||||
sizeof(pe_entry->pe.tx.data.tx_iov[i].dst));
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.tx_iov[i].dst,
|
||||
sizeof(pe_entry->pe.tx.tx_iov[i].dst));
|
||||
}
|
||||
msg_hdr->msg_len += sizeof(union sock_iov) * i;
|
||||
break;
|
||||
case SOCK_OP_READ:
|
||||
for (i = 0; i < pe_entry->pe.tx.tx_op.src_iov_len; i++) {
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.data.tx_iov[i].src,
|
||||
sizeof(pe_entry->pe.tx.data.tx_iov[i].src));
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.tx_iov[i].src,
|
||||
sizeof(pe_entry->pe.tx.tx_iov[i].src));
|
||||
}
|
||||
msg_hdr->msg_len += sizeof(union sock_iov) * i;
|
||||
|
||||
for (i = 0; i <pe_entry->pe.tx.tx_op.dest_iov_len; i++) {
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.data.tx_iov[i].dst,
|
||||
sizeof(pe_entry->pe.tx.data.tx_iov[i].dst));
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.tx_iov[i].dst,
|
||||
sizeof(pe_entry->pe.tx.tx_iov[i].dst));
|
||||
}
|
||||
break;
|
||||
case SOCK_OP_ATOMIC:
|
||||
msg_hdr->msg_len += sizeof(struct sock_op);
|
||||
datatype_sz = fi_datatype_size(pe_entry->pe.tx.tx_op.atomic.datatype);
|
||||
if (pe_entry->flags & FI_INJECT) {
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.data.inject[0],
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.inject[0],
|
||||
pe_entry->pe.tx.tx_op.src_iov_len);
|
||||
msg_hdr->msg_len += pe_entry->pe.tx.tx_op.src_iov_len;
|
||||
} else {
|
||||
for (i = 0; i < pe_entry->pe.tx.tx_op.src_iov_len; i++) {
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.data.tx_iov[i].src,
|
||||
sizeof(pe_entry->pe.tx.data.tx_iov[i].src));
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.tx_iov[i].src,
|
||||
sizeof(pe_entry->pe.tx.tx_iov[i].src));
|
||||
msg_hdr->msg_len += datatype_sz *
|
||||
pe_entry->pe.tx.data.tx_iov[i].src.ioc.count;
|
||||
pe_entry->pe.tx.tx_iov[i].src.ioc.count;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < pe_entry->pe.tx.tx_op.dest_iov_len; i++) {
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.data.tx_iov[i].dst,
|
||||
sizeof(pe_entry->pe.tx.data.tx_iov[i].dst));
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.tx_iov[i].dst,
|
||||
sizeof(pe_entry->pe.tx.tx_iov[i].dst));
|
||||
}
|
||||
msg_hdr->msg_len += sizeof(union sock_iov) * i;
|
||||
|
||||
for (i = 0; i < pe_entry->pe.tx.tx_op.atomic.res_iov_len; i++) {
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.data.tx_iov[i].res,
|
||||
sizeof(pe_entry->pe.tx.data.tx_iov[i].res));
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.tx_iov[i].res,
|
||||
sizeof(pe_entry->pe.tx.tx_iov[i].res));
|
||||
}
|
||||
|
||||
for (i = 0; i < pe_entry->pe.tx.tx_op.atomic.cmp_iov_len; i++) {
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.data.tx_iov[i].cmp,
|
||||
sizeof(pe_entry->pe.tx.data.tx_iov[i].cmp));
|
||||
rbfdread(&tx_ctx->rbfd, &pe_entry->pe.tx.tx_iov[i].cmp,
|
||||
sizeof(pe_entry->pe.tx.tx_iov[i].cmp));
|
||||
msg_hdr->msg_len += datatype_sz *
|
||||
pe_entry->pe.tx.data.tx_iov[i].cmp.ioc.count;
|
||||
pe_entry->pe.tx.tx_iov[i].cmp.ioc.count;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -1977,10 +2185,19 @@ static int sock_pe_new_tx_entry(struct sock_pe *pe, struct sock_tx_ctx *tx_ctx)
|
||||
return sock_pe_progress_tx_entry(pe, tx_ctx, pe_entry);
|
||||
}
|
||||
|
||||
void sock_pe_signal(struct sock_pe *pe)
|
||||
{
|
||||
char c = 0;
|
||||
if (write(pe->signal_fds[SOCK_SIGNAL_WR_FD], &c, 1) != 1) {
|
||||
SOCK_LOG_ERROR("Failed to signal\n");
|
||||
}
|
||||
}
|
||||
|
||||
void sock_pe_add_tx_ctx(struct sock_pe *pe, struct sock_tx_ctx *ctx)
|
||||
{
|
||||
pthread_mutex_lock(&pe->list_lock);
|
||||
dlistfd_insert_tail(&ctx->pe_entry, &pe->tx_list);
|
||||
sock_pe_signal(pe);
|
||||
pthread_mutex_unlock(&pe->list_lock);
|
||||
SOCK_LOG_INFO("TX ctx added to PE\n");
|
||||
}
|
||||
@ -1989,6 +2206,7 @@ void sock_pe_add_rx_ctx(struct sock_pe *pe, struct sock_rx_ctx *ctx)
|
||||
{
|
||||
pthread_mutex_lock(&pe->list_lock);
|
||||
dlistfd_insert_tail(&ctx->pe_entry, &pe->rx_list);
|
||||
sock_pe_signal(pe);
|
||||
pthread_mutex_unlock(&pe->list_lock);
|
||||
SOCK_LOG_INFO("RX ctx added to PE\n");
|
||||
}
|
||||
@ -2008,15 +2226,16 @@ void sock_pe_remove_rx_ctx(struct sock_rx_ctx *rx_ctx)
|
||||
}
|
||||
|
||||
static int sock_pe_progress_rx_ep(struct sock_pe *pe, struct sock_ep *ep,
|
||||
struct sock_rx_ctx *rx_ctx)
|
||||
struct sock_rx_ctx *rx_ctx)
|
||||
{
|
||||
struct sock_conn *conn;
|
||||
struct sock_conn_map *map;
|
||||
int i, ret, data_avail;
|
||||
int i, ret = 0, data_avail;
|
||||
|
||||
map = &ep->domain->r_cmap;
|
||||
assert(map != NULL);
|
||||
|
||||
fastlock_acquire(&map->lock);
|
||||
for (i = 0; i < map->used; i++) {
|
||||
conn = &map->table[i];
|
||||
|
||||
@ -2034,7 +2253,7 @@ static int sock_pe_progress_rx_ep(struct sock_pe *pe, struct sock_ep *ep,
|
||||
if (ret < 0 && errno != EINTR) {
|
||||
SOCK_LOG_INFO("Error polling fd: %d\n",
|
||||
conn->sock_fd);
|
||||
return ret;
|
||||
goto out;
|
||||
}
|
||||
data_avail = (ret == 1 && sock_comm_data_avail(conn));
|
||||
}
|
||||
@ -2044,10 +2263,13 @@ static int sock_pe_progress_rx_ep(struct sock_pe *pe, struct sock_ep *ep,
|
||||
/* new RX PE entry */
|
||||
ret = sock_pe_new_rx_entry(pe, rx_ctx, ep, conn, i);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
ret = 0;
|
||||
out:
|
||||
fastlock_release(&map->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sock_pe_progress_rx_ctx(struct sock_pe *pe, struct sock_rx_ctx *rx_ctx)
|
||||
@ -2143,6 +2365,87 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sock_pe_poll(struct sock_pe *pe)
|
||||
{
|
||||
char tmp;
|
||||
fd_set rfds;
|
||||
int i, max_fds = 0;
|
||||
struct dlist_entry *entry;
|
||||
struct sock_tx_ctx *tx_ctx;
|
||||
struct sock_rx_ctx *rx_ctx;
|
||||
struct sock_conn_map *map;
|
||||
struct sock_conn *conn;
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
if (dlistfd_empty(&pe->tx_list) && dlistfd_empty(&pe->rx_list))
|
||||
goto do_wait;
|
||||
|
||||
pthread_mutex_lock(&pe->list_lock);
|
||||
if (!dlistfd_empty(&pe->tx_list)) {
|
||||
for (entry = pe->tx_list.list.next;
|
||||
entry != &pe->tx_list.list; entry = entry->next) {
|
||||
tx_ctx = container_of(entry, struct sock_tx_ctx, pe_entry);
|
||||
if (!rbfdempty(&tx_ctx->rbfd) ||
|
||||
!dlist_empty(&tx_ctx->pe_entry_list)) {
|
||||
pthread_mutex_unlock(&pe->list_lock);
|
||||
return;
|
||||
}
|
||||
FD_SET(tx_ctx->rbfd.fd[RB_READ_FD], &rfds);
|
||||
max_fds = MAX(tx_ctx->rbfd.fd[RB_READ_FD], max_fds);
|
||||
}
|
||||
}
|
||||
|
||||
if (!dlistfd_empty(&pe->rx_list)) {
|
||||
for (entry = pe->rx_list.list.next;
|
||||
entry != &pe->rx_list.list; entry = entry->next) {
|
||||
rx_ctx = container_of(entry, struct sock_rx_ctx, pe_entry);
|
||||
if (!dlist_empty(&rx_ctx->rx_buffered_list) ||
|
||||
!dlist_empty(&rx_ctx->pe_entry_list)) {
|
||||
pthread_mutex_unlock(&pe->list_lock);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&pe->list_lock);
|
||||
|
||||
map = &pe->domain->r_cmap;
|
||||
fastlock_acquire(&map->lock);
|
||||
for (i = 0; i < map->used; i++) {
|
||||
conn = &map->table[i];
|
||||
if (rbused(&conn->outbuf) || rbused(&conn->inbuf)) {
|
||||
sock_comm_flush(conn);
|
||||
fastlock_release(&map->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
FD_SET(conn->sock_fd, &rfds);
|
||||
max_fds = MAX(conn->sock_fd, max_fds);
|
||||
}
|
||||
fastlock_release(&map->lock);
|
||||
|
||||
do_wait:
|
||||
if (!pe->waittime) {
|
||||
pe->waittime = fi_gettime_ms();
|
||||
return;
|
||||
}
|
||||
|
||||
if (fi_gettime_ms() - pe->waittime < sock_pe_waittime)
|
||||
return;
|
||||
|
||||
pe->waittime = 0;
|
||||
FD_SET(pe->signal_fds[SOCK_SIGNAL_RD_FD], &rfds);
|
||||
max_fds = MAX(pe->signal_fds[SOCK_SIGNAL_RD_FD], max_fds);
|
||||
|
||||
if (select(max_fds + 1, &rfds, NULL, NULL, NULL) < 0) {
|
||||
SOCK_LOG_ERROR ("select failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (FD_ISSET(pe->signal_fds[SOCK_SIGNAL_RD_FD], &rfds)) {
|
||||
while (read(pe->signal_fds[SOCK_SIGNAL_RD_FD], &tmp, 1) == 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void *sock_pe_progress_thread(void *data)
|
||||
{
|
||||
int ret;
|
||||
@ -2154,12 +2457,9 @@ static void *sock_pe_progress_thread(void *data)
|
||||
SOCK_LOG_INFO("Progress thread started\n");
|
||||
while (*((volatile int*)&pe->do_progress)) {
|
||||
|
||||
/* FIXME */
|
||||
if (sock_progress_thread_wait) {
|
||||
pthread_yield();
|
||||
usleep(sock_progress_thread_wait * 1000);
|
||||
}
|
||||
|
||||
if (pe->domain->progress_mode == FI_PROGRESS_AUTO)
|
||||
sock_pe_poll(pe);
|
||||
|
||||
pthread_mutex_lock(&pe->list_lock);
|
||||
if (!dlistfd_empty(&pe->tx_list)) {
|
||||
for (entry = pe->tx_list.list.next;
|
||||
@ -2229,17 +2529,24 @@ struct sock_pe *sock_pe_init(struct sock_domain *domain)
|
||||
pe->domain = domain;
|
||||
|
||||
if (domain->progress_mode == FI_PROGRESS_AUTO) {
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pe->signal_fds) < 0) {
|
||||
goto err1;
|
||||
}
|
||||
fd_set_nonblock(pe->signal_fds[SOCK_SIGNAL_RD_FD]);
|
||||
pe->do_progress = 1;
|
||||
if (pthread_create(&pe->progress_thread, NULL,
|
||||
sock_pe_progress_thread, (void *)pe)) {
|
||||
SOCK_LOG_ERROR("Couldn't create progress thread\n");
|
||||
goto err;
|
||||
goto err2;
|
||||
}
|
||||
}
|
||||
SOCK_LOG_INFO("PE init: OK\n");
|
||||
return pe;
|
||||
|
||||
err:
|
||||
err2:
|
||||
close(pe->signal_fds[0]);
|
||||
close(pe->signal_fds[1]);
|
||||
err1:
|
||||
fastlock_destroy(&pe->lock);
|
||||
dlistfd_head_free(&pe->tx_list);
|
||||
dlistfd_head_free(&pe->rx_list);
|
||||
@ -2251,7 +2558,10 @@ void sock_pe_finalize(struct sock_pe *pe)
|
||||
{
|
||||
if (pe->domain->progress_mode == FI_PROGRESS_AUTO) {
|
||||
pe->do_progress = 0;
|
||||
sock_pe_signal(pe);
|
||||
pthread_join(pe->progress_thread, NULL);
|
||||
close(pe->signal_fds[0]);
|
||||
close(pe->signal_fds[1]);
|
||||
}
|
||||
|
||||
fastlock_destroy(&pe->lock);
|
||||
|
@ -34,7 +34,6 @@
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
@ -88,9 +87,12 @@ static ssize_t sock_ep_rma_readmsg(struct fid_ep *ep,
|
||||
return -FI_EINVAL;
|
||||
}
|
||||
|
||||
assert(tx_ctx->enabled &&
|
||||
msg->iov_count <= SOCK_EP_MAX_IOV_LIMIT &&
|
||||
msg->rma_iov_count <= SOCK_EP_MAX_IOV_LIMIT);
|
||||
if (msg->iov_count > SOCK_EP_MAX_IOV_LIMIT ||
|
||||
msg->rma_iov_count > SOCK_EP_MAX_IOV_LIMIT)
|
||||
return -FI_EINVAL;
|
||||
|
||||
if (!tx_ctx->enabled)
|
||||
return -FI_EOPBADSTATE;
|
||||
|
||||
if (sock_ep->connected) {
|
||||
conn = sock_ep_lookup_conn(sock_ep);
|
||||
@ -111,7 +113,8 @@ static ssize_t sock_ep_rma_readmsg(struct fid_ep *ep,
|
||||
goto err;
|
||||
}
|
||||
|
||||
flags |= tx_ctx->attr.op_flags;
|
||||
if (flags & SOCK_USE_OP_FLAGS)
|
||||
flags |= tx_ctx->attr.op_flags;
|
||||
memset(&tx_op, 0, sizeof(struct sock_op));
|
||||
tx_op.op = SOCK_OP_READ;
|
||||
tx_op.src_iov_len = msg->rma_iov_count;
|
||||
@ -121,10 +124,6 @@ static ssize_t sock_ep_rma_readmsg(struct fid_ep *ep,
|
||||
msg->addr, (uintptr_t) msg->msg_iov[0].iov_base,
|
||||
sock_ep, conn);
|
||||
|
||||
if (flags & FI_REMOTE_CQ_DATA) {
|
||||
sock_tx_ctx_write(tx_ctx, &msg->data, sizeof(msg->data));
|
||||
}
|
||||
|
||||
src_len = 0;
|
||||
for (i = 0; i< msg->rma_iov_count; i++) {
|
||||
tx_iov.iov.addr = msg->rma_iov[i].addr;
|
||||
@ -153,7 +152,6 @@ static ssize_t sock_ep_rma_readmsg(struct fid_ep *ep,
|
||||
return 0;
|
||||
|
||||
err:
|
||||
SOCK_LOG_INFO("Not enough space for TX entry, try again\n");
|
||||
sock_tx_ctx_abort(tx_ctx);
|
||||
return ret;
|
||||
}
|
||||
@ -182,7 +180,7 @@ static ssize_t sock_ep_rma_read(struct fid_ep *ep, void *buf, size_t len,
|
||||
msg.addr = src_addr;
|
||||
msg.context = context;
|
||||
|
||||
return sock_ep_rma_readmsg(ep, &msg, 0);
|
||||
return sock_ep_rma_readmsg(ep, &msg, SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_rma_readv(struct fid_ep *ep, const struct iovec *iov,
|
||||
@ -210,7 +208,7 @@ static ssize_t sock_ep_rma_readv(struct fid_ep *ep, const struct iovec *iov,
|
||||
msg.addr = src_addr;
|
||||
msg.context = context;
|
||||
|
||||
return sock_ep_rma_readmsg(ep, &msg, 0);
|
||||
return sock_ep_rma_readmsg(ep, &msg, SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_rma_writemsg(struct fid_ep *ep,
|
||||
@ -241,9 +239,13 @@ static ssize_t sock_ep_rma_writemsg(struct fid_ep *ep,
|
||||
return -FI_EINVAL;
|
||||
}
|
||||
|
||||
assert(tx_ctx->enabled &&
|
||||
msg->iov_count <= SOCK_EP_MAX_IOV_LIMIT &&
|
||||
msg->rma_iov_count <= SOCK_EP_MAX_IOV_LIMIT);
|
||||
if (msg->iov_count > SOCK_EP_MAX_IOV_LIMIT ||
|
||||
msg->rma_iov_count > SOCK_EP_MAX_IOV_LIMIT)
|
||||
return -FI_EINVAL;
|
||||
|
||||
if (!tx_ctx->enabled)
|
||||
return -FI_EOPBADSTATE;
|
||||
|
||||
if (sock_ep->connected) {
|
||||
conn = sock_ep_lookup_conn(sock_ep);
|
||||
} else {
|
||||
@ -253,7 +255,8 @@ static ssize_t sock_ep_rma_writemsg(struct fid_ep *ep,
|
||||
if (!conn)
|
||||
return -FI_EAGAIN;
|
||||
|
||||
flags |= tx_ctx->attr.op_flags;
|
||||
if (flags & SOCK_USE_OP_FLAGS)
|
||||
flags |= tx_ctx->attr.op_flags;
|
||||
memset(&tx_op, 0, sizeof(struct sock_op));
|
||||
tx_op.op = SOCK_OP_WRITE;
|
||||
tx_op.dest_iov_len = msg->rma_iov_count;
|
||||
@ -263,7 +266,10 @@ static ssize_t sock_ep_rma_writemsg(struct fid_ep *ep,
|
||||
for (i=0; i< msg->iov_count; i++) {
|
||||
total_len += msg->msg_iov[i].iov_len;
|
||||
}
|
||||
assert(total_len <= SOCK_EP_MAX_INJECT_SZ);
|
||||
if (total_len > SOCK_EP_MAX_INJECT_SZ) {
|
||||
ret = -FI_EINVAL;
|
||||
goto err;
|
||||
}
|
||||
tx_op.src_iov_len = total_len;
|
||||
} else {
|
||||
total_len += msg->iov_count * sizeof(union sock_iov);
|
||||
@ -323,7 +329,6 @@ static ssize_t sock_ep_rma_writemsg(struct fid_ep *ep,
|
||||
return 0;
|
||||
|
||||
err:
|
||||
SOCK_LOG_INFO("Not enough space for TX entry, try again\n");
|
||||
sock_tx_ctx_abort(tx_ctx);
|
||||
return ret;
|
||||
}
|
||||
@ -354,7 +359,7 @@ static ssize_t sock_ep_rma_write(struct fid_ep *ep, const void *buf,
|
||||
msg.addr = dest_addr;
|
||||
msg.context = context;
|
||||
|
||||
return sock_ep_rma_writemsg(ep, &msg, 0);
|
||||
return sock_ep_rma_writemsg(ep, &msg, SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_rma_writev(struct fid_ep *ep,
|
||||
@ -384,7 +389,7 @@ static ssize_t sock_ep_rma_writev(struct fid_ep *ep,
|
||||
msg.context = context;
|
||||
msg.addr = dest_addr;
|
||||
|
||||
return sock_ep_rma_writemsg(ep, &msg, 0);
|
||||
return sock_ep_rma_writemsg(ep, &msg, SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_rma_writedata(struct fid_ep *ep, const void *buf,
|
||||
@ -413,7 +418,7 @@ static ssize_t sock_ep_rma_writedata(struct fid_ep *ep, const void *buf,
|
||||
msg.context = context;
|
||||
msg.data = data;
|
||||
|
||||
return sock_ep_rma_writemsg(ep, &msg, FI_REMOTE_CQ_DATA);
|
||||
return sock_ep_rma_writemsg(ep, &msg, FI_REMOTE_CQ_DATA | SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_rma_inject(struct fid_ep *ep, const void *buf,
|
||||
@ -439,7 +444,8 @@ static ssize_t sock_ep_rma_inject(struct fid_ep *ep, const void *buf,
|
||||
msg.msg_iov = &msg_iov;
|
||||
msg.addr = dest_addr;
|
||||
|
||||
return sock_ep_rma_writemsg(ep, &msg, FI_INJECT | SOCK_NO_COMPLETION);
|
||||
return sock_ep_rma_writemsg(ep, &msg, FI_INJECT |
|
||||
SOCK_NO_COMPLETION | SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
static ssize_t sock_ep_rma_injectdata(struct fid_ep *ep, const void *buf,
|
||||
@ -466,7 +472,7 @@ static ssize_t sock_ep_rma_injectdata(struct fid_ep *ep, const void *buf,
|
||||
msg.addr = dest_addr;
|
||||
msg.data = data;
|
||||
return sock_ep_rma_writemsg(ep, &msg, FI_INJECT | FI_REMOTE_CQ_DATA |
|
||||
SOCK_NO_COMPLETION);
|
||||
SOCK_NO_COMPLETION | SOCK_USE_OP_FLAGS);
|
||||
}
|
||||
|
||||
|
||||
|
@ -81,8 +81,7 @@ struct sock_rx_entry *sock_rx_new_buffered_entry(struct sock_rx_ctx *rx_ctx,
|
||||
struct sock_rx_entry *rx_entry;
|
||||
|
||||
if (rx_ctx->buffered_len + len >= rx_ctx->attr.total_buffered_recv) {
|
||||
SOCK_LOG_ERROR("Reached max buffered recv limit\n");
|
||||
return NULL;
|
||||
SOCK_LOG_ERROR("Exceeded buffered recv limit\n");
|
||||
}
|
||||
|
||||
rx_entry = calloc(1, sizeof(*rx_entry) + len);
|
||||
@ -114,7 +113,7 @@ inline size_t sock_rx_avail_len(struct sock_rx_entry *rx_entry)
|
||||
|
||||
struct sock_rx_entry *sock_rx_get_entry(struct sock_rx_ctx *rx_ctx,
|
||||
uint64_t addr, uint64_t tag,
|
||||
uint8_t op_type)
|
||||
uint8_t is_tagged)
|
||||
{
|
||||
struct dlist_entry *entry;
|
||||
struct sock_rx_entry *rx_entry;
|
||||
@ -123,7 +122,7 @@ struct sock_rx_entry *sock_rx_get_entry(struct sock_rx_ctx *rx_ctx,
|
||||
entry != &rx_ctx->rx_entry_list; entry = entry->next) {
|
||||
|
||||
rx_entry = container_of(entry, struct sock_rx_entry, entry);
|
||||
if (rx_entry->is_busy || (op_type != rx_entry->is_tagged))
|
||||
if (rx_entry->is_busy || (is_tagged != rx_entry->is_tagged))
|
||||
continue;
|
||||
|
||||
if (((rx_entry->tag & ~rx_entry->ignore) == (tag & ~rx_entry->ignore)) &&
|
||||
@ -137,3 +136,29 @@ struct sock_rx_entry *sock_rx_get_entry(struct sock_rx_ctx *rx_ctx,
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct sock_rx_entry *sock_rx_get_buffered_entry(struct sock_rx_ctx *rx_ctx,
|
||||
uint64_t addr, uint64_t tag,
|
||||
uint64_t ignore, uint8_t is_tagged)
|
||||
{
|
||||
struct dlist_entry *entry;
|
||||
struct sock_rx_entry *rx_entry;
|
||||
|
||||
for (entry = rx_ctx->rx_buffered_list.next;
|
||||
entry != &rx_ctx->rx_buffered_list; entry = entry->next) {
|
||||
|
||||
rx_entry = container_of(entry, struct sock_rx_entry, entry);
|
||||
if (rx_entry->is_busy || (is_tagged != rx_entry->is_tagged) ||
|
||||
rx_entry->is_claimed)
|
||||
continue;
|
||||
|
||||
if (((rx_entry->tag & ~ignore) == (tag & ~ignore)) &&
|
||||
(rx_entry->addr == FI_ADDR_UNSPEC || addr == FI_ADDR_UNSPEC ||
|
||||
rx_entry->addr == addr ||
|
||||
(rx_ctx->av &&
|
||||
!sock_av_compare_addr(rx_ctx->av, addr, rx_entry->addr)))) {
|
||||
return rx_entry;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -33,16 +33,43 @@
|
||||
#ifndef _SOCK_UTIL_H_
|
||||
#define _SOCK_UTIL_H_
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <rdma/fi_log.h>
|
||||
|
||||
extern useconds_t sock_progress_thread_wait;
|
||||
#include "sock.h"
|
||||
|
||||
extern const char sock_fab_name[];
|
||||
extern const char sock_dom_name[];
|
||||
extern const char sock_prov_name[];
|
||||
extern struct fi_provider sock_prov;
|
||||
extern int sock_pe_waittime;
|
||||
#if ENABLE_DEBUG
|
||||
extern int sock_dgram_drop_rate;
|
||||
#endif
|
||||
|
||||
#define _SOCK_LOG_INFO(subsys, ...) FI_INFO(&sock_prov, subsys, __VA_ARGS__);
|
||||
#define _SOCK_LOG_ERROR(subsys, ...) FI_WARN(&sock_prov, subsys, __VA_ARGS__);
|
||||
|
||||
static inline int sock_drop_packet(struct sock_ep *sock_ep)
|
||||
{
|
||||
#if ENABLE_DEBUG
|
||||
if(sock_ep->ep_type == FI_EP_DGRAM && sock_dgram_drop_rate > 0) {
|
||||
sock_ep->domain->fab->num_send_msg++;
|
||||
if(!(sock_ep->domain->fab->num_send_msg % sock_dgram_drop_rate))
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void *sock_mremap(void *old_address, size_t old_size,
|
||||
size_t new_size)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
return (void*) -1;
|
||||
#else
|
||||
return mremap(old_address, old_size, new_size, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -132,6 +132,9 @@ static int sock_wait_wait(struct fid_wait *wait_fid, int timeout)
|
||||
cq = container_of(list_item->fid,
|
||||
struct sock_cq, cq_fid);
|
||||
sock_cq_progress(cq);
|
||||
if (rbused(&cq->cqerr_rb)) {
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case FI_CLASS_CNTR:
|
||||
|
@ -52,9 +52,20 @@
|
||||
|
||||
extern struct fi_provider usdf_ops;
|
||||
|
||||
#define USDF_WARN(...) FI_WARN(&usdf_ops, FI_LOG_CORE, __VA_ARGS__ )
|
||||
#define USDF_INFO(...) FI_INFO(&usdf_ops, FI_LOG_CORE, __VA_ARGS__ )
|
||||
#define USDF_DEBUG(...) FI_DBG(&usdf_ops, FI_LOG_CORE, __VA_ARGS__ )
|
||||
#define USDF_WARN_SYS(subsys, ...) \
|
||||
FI_WARN(&usdf_ops, FI_LOG_ ## subsys, __VA_ARGS__)
|
||||
#define USDF_TRACE_SYS(subsys, ...) \
|
||||
FI_TRACE(&usdf_ops, FI_LOG_ ## subsys, __VA_ARGS__)
|
||||
#define USDF_INFO_SYS(subsys, ...) \
|
||||
FI_INFO(&usdf_ops, FI_LOG_ ## subsys, __VA_ARGS__)
|
||||
#define USDF_DBG_SYS(subsys, ...) \
|
||||
FI_DBG(&usdf_ops, FI_LOG_ ## subsys, __VA_ARGS__)
|
||||
|
||||
/* default to "FI_LOG_FABRIC" */
|
||||
#define USDF_WARN(...) USDF_WARN_SYS(FABRIC, __VA_ARGS__)
|
||||
#define USDF_TRACE(...) USDF_TRACE_SYS(FABRIC, __VA_ARGS__)
|
||||
#define USDF_INFO(...) USDF_INFO_SYS(FABRIC, __VA_ARGS__)
|
||||
#define USDF_DBG(...) USDF_DBG_SYS(FABRIC, __VA_ARGS__)
|
||||
|
||||
#define USDF_HDR_BUF_ENTRY 64
|
||||
#define USDF_EP_CAP_PIO (1ULL << 63)
|
||||
@ -182,19 +193,23 @@ struct usdf_tx {
|
||||
struct {
|
||||
struct usdf_cq_hard *tx_hcq;
|
||||
|
||||
uint8_t *tx_inject_bufs;
|
||||
struct usdf_msg_qe *tx_wqe_buf;
|
||||
TAILQ_HEAD(,usdf_msg_qe) tx_free_wqe;
|
||||
TAILQ_HEAD(,usdf_ep) tx_ep_ready;
|
||||
TAILQ_HEAD(,usdf_ep) tx_ep_have_acks;
|
||||
size_t tx_num_free_wqe;
|
||||
} msg;
|
||||
struct {
|
||||
struct usdf_cq_hard *tx_hcq;
|
||||
|
||||
atomic_t tx_next_msg_id;
|
||||
struct usdf_rdm_qe *tx_wqe_buf;
|
||||
uint8_t *tx_inject_bufs;
|
||||
TAILQ_HEAD(,usdf_rdm_qe) tx_free_wqe;
|
||||
TAILQ_HEAD(,usdf_rdm_connection) tx_rdc_ready;
|
||||
TAILQ_HEAD(,usdf_rdm_connection) tx_rdc_have_acks;
|
||||
size_t tx_num_free_wqe;
|
||||
} rdm;
|
||||
} t;
|
||||
};
|
||||
@ -219,6 +234,7 @@ struct usdf_rx {
|
||||
struct usdf_msg_qe *rx_rqe_buf;
|
||||
TAILQ_HEAD(,usdf_msg_qe) rx_free_rqe;
|
||||
TAILQ_HEAD(,usdf_msg_qe) rx_posted_rqe;
|
||||
size_t rx_num_free_rqe;
|
||||
} msg;
|
||||
struct {
|
||||
int rx_sock;
|
||||
@ -229,6 +245,7 @@ struct usdf_rx {
|
||||
struct usdf_rdm_qe *rx_rqe_buf;
|
||||
TAILQ_HEAD(,usdf_rdm_qe) rx_free_rqe;
|
||||
TAILQ_HEAD(,usdf_rdm_qe) rx_posted_rqe;
|
||||
size_t rx_num_free_rqe;
|
||||
} rdm;
|
||||
} r;
|
||||
};
|
||||
@ -244,6 +261,9 @@ struct usdf_ep {
|
||||
uint64_t ep_caps;
|
||||
uint64_t ep_mode;
|
||||
|
||||
uint8_t ep_tx_dflt_signal_comp;
|
||||
uint8_t ep_rx_dflt_signal_comp;
|
||||
|
||||
uint32_t ep_wqe; /* requested queue sizes */
|
||||
uint32_t ep_rqe;
|
||||
|
||||
|
@ -233,6 +233,8 @@ usdf_am_insert_async(struct fid_av *fav, const void *addr, size_t count,
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
USDF_TRACE_SYS(AV, "\n");
|
||||
|
||||
if ((flags & ~FI_MORE) != 0) {
|
||||
return -FI_EBADFLAGS;
|
||||
}
|
||||
@ -313,7 +315,7 @@ usdf_am_insert_async(struct fid_av *fav, const void *addr, size_t count,
|
||||
/* resolve all addresses we can */
|
||||
usdf_av_insert_progress(insert);
|
||||
|
||||
return count;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (insert != NULL) {
|
||||
@ -337,6 +339,8 @@ usdf_am_insert_sync(struct fid_av *fav, const void *addr, size_t count,
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
USDF_TRACE_SYS(AV, "\n");
|
||||
|
||||
if ((flags & ~FI_MORE) != 0) {
|
||||
return -FI_EBADFLAGS;
|
||||
}
|
||||
@ -378,6 +382,8 @@ usdf_am_remove(struct fid_av *fav, fi_addr_t *fi_addr, size_t count,
|
||||
struct usdf_dest *dest;
|
||||
struct usdf_av *av;
|
||||
|
||||
USDF_TRACE_SYS(AV, "\n");
|
||||
|
||||
av = av_ftou(fav);
|
||||
|
||||
if (av->av_flags & FI_READ) {
|
||||
@ -399,6 +405,8 @@ usdf_am_lookup(struct fid_av *av, fi_addr_t fi_addr, void *addr,
|
||||
struct sockaddr_in sin = { 0 };
|
||||
size_t copylen;
|
||||
|
||||
USDF_TRACE_SYS(AV, "\n");
|
||||
|
||||
dest = (struct usdf_dest *)(uintptr_t)fi_addr;
|
||||
|
||||
if (*addrlen < sizeof(sin)) {
|
||||
@ -436,6 +444,8 @@ usdf_av_bind(struct fid *fid, struct fid *bfid, uint64_t flags)
|
||||
{
|
||||
struct usdf_av *av;
|
||||
|
||||
USDF_TRACE_SYS(AV, "\n");
|
||||
|
||||
av = av_fidtou(fid);
|
||||
|
||||
switch (bfid->fclass) {
|
||||
@ -458,6 +468,8 @@ usdf_av_close(struct fid *fid)
|
||||
{
|
||||
struct usdf_av *av;
|
||||
|
||||
USDF_TRACE_SYS(AV, "\n");
|
||||
|
||||
av = container_of(fid, struct usdf_av, av_fid.fid);
|
||||
if (atomic_get(&av->av_refcnt) > 0) {
|
||||
return -FI_EBUSY;
|
||||
@ -488,6 +500,8 @@ usdf_am_get_distance(struct fid_av *fav, void *addr, int *metric_o)
|
||||
struct sockaddr_in *sin;
|
||||
int ret;
|
||||
|
||||
USDF_TRACE_SYS(DOMAIN, "\n");
|
||||
|
||||
av = av_ftou(fav);
|
||||
udp = av->av_domain;
|
||||
sin = addr;
|
||||
@ -498,7 +512,7 @@ usdf_am_get_distance(struct fid_av *fav, void *addr, int *metric_o)
|
||||
}
|
||||
|
||||
static struct fi_usnic_ops_av usdf_usnic_ops_av = {
|
||||
.size = sizeof(struct fi_usnic_ops_fabric),
|
||||
.size = sizeof(struct fi_usnic_ops_av),
|
||||
.get_distance = usdf_am_get_distance,
|
||||
};
|
||||
|
||||
@ -506,6 +520,8 @@ static int
|
||||
usdf_av_ops_open(struct fid *fid, const char *ops_name, uint64_t flags,
|
||||
void **ops, void *context)
|
||||
{
|
||||
USDF_TRACE_SYS(AV, "\n");
|
||||
|
||||
if (strcmp(ops_name, FI_USNIC_AV_OPS_1) == 0) {
|
||||
*ops = &usdf_usnic_ops_av;
|
||||
} else {
|
||||
@ -550,6 +566,8 @@ usdf_av_open(struct fid_domain *domain, struct fi_av_attr *attr,
|
||||
struct usdf_domain *udp;
|
||||
struct usdf_av *av;
|
||||
|
||||
USDF_TRACE_SYS(AV, "\n");
|
||||
|
||||
if ((attr->flags & ~(FI_EVENT | FI_READ)) != 0) {
|
||||
return -FI_ENOSYS;
|
||||
}
|
||||
@ -572,9 +590,9 @@ usdf_av_open(struct fid_domain *domain, struct fi_av_attr *attr,
|
||||
av->av_flags = attr->flags;
|
||||
|
||||
pthread_spin_init(&av->av_lock, PTHREAD_PROCESS_PRIVATE);
|
||||
atomic_init(&av->av_active_inserts, 0);
|
||||
atomic_initialize(&av->av_active_inserts, 0);
|
||||
|
||||
atomic_init(&av->av_refcnt, 0);
|
||||
atomic_initialize(&av->av_refcnt, 0);
|
||||
atomic_inc(&udp->dom_refcnt);
|
||||
av->av_domain = udp;
|
||||
|
||||
|
@ -137,6 +137,11 @@ usdf_cm_msg_accept(struct fid_ep *fep, const void *param, size_t paramlen)
|
||||
int ret;
|
||||
int n;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
if (paramlen > USDF_MAX_CONN_DATA)
|
||||
return -FI_EINVAL;
|
||||
|
||||
ep = ep_ftou(fep);
|
||||
udp = ep->ep_domain;
|
||||
fp = udp->dom_fabric;
|
||||
@ -372,6 +377,11 @@ usdf_cm_msg_connect(struct fid_ep *fep, const void *addr,
|
||||
struct usd_qp_impl *qp;
|
||||
int ret;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
if (paramlen > USDF_MAX_CONN_DATA)
|
||||
return -FI_EINVAL;
|
||||
|
||||
ep = ep_ftou(fep);
|
||||
udp = ep->ep_domain;
|
||||
fp = udp->dom_fabric;
|
||||
@ -385,6 +395,7 @@ usdf_cm_msg_connect(struct fid_ep *fep, const void *addr,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
crp->handle.fclass = FI_CLASS_CONNREQ;
|
||||
crp->cr_sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (crp->cr_sockfd == -1) {
|
||||
ret = -errno;
|
||||
@ -461,19 +472,10 @@ fail:
|
||||
int
|
||||
usdf_cm_msg_shutdown(struct fid_ep *ep, uint64_t flags)
|
||||
{
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
return -FI_ENOSYS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check a message CQ for completions and progress the send engine as needed,
|
||||
* create completions for the app if anything needs to be percolated up
|
||||
*/
|
||||
int
|
||||
usdf_cq_msg_poll(struct usd_cq *ucq, struct usd_completion *comp)
|
||||
{
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return local address of an EP
|
||||
*/
|
||||
@ -484,6 +486,8 @@ int usdf_cm_rdm_getname(fid_t fid, void *addr, size_t *addrlen)
|
||||
struct sockaddr_in sin;
|
||||
size_t copylen;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
ep = ep_fidtou(fid);
|
||||
rx = ep->ep_rx;
|
||||
|
||||
|
@ -53,6 +53,7 @@ struct usdf_connreq_msg {
|
||||
} __attribute__((packed));
|
||||
|
||||
struct usdf_connreq {
|
||||
struct fid handle;
|
||||
int cr_sockfd;
|
||||
struct usdf_pep *cr_pep;
|
||||
struct usdf_ep *cr_ep;
|
||||
|
@ -66,12 +66,29 @@
|
||||
#include "usdf_progress.h"
|
||||
#include "usdf_cq.h"
|
||||
|
||||
static inline int usdf_cqe_to_flags(struct usd_completion *comp)
|
||||
{
|
||||
switch (comp->uc_type) {
|
||||
case USD_COMPTYPE_SEND:
|
||||
return (FI_MSG | FI_SEND);
|
||||
case USD_COMPTYPE_RECV:
|
||||
return (FI_MSG | FI_RECV);
|
||||
default:
|
||||
USDF_DBG_SYS(CQ, "WARNING: unknown completion type! (%d)\n",
|
||||
comp->uc_type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
usdf_cq_readerr(struct fid_cq *fcq, struct fi_cq_err_entry *entry,
|
||||
uint64_t flags)
|
||||
{
|
||||
struct usdf_cq *cq;
|
||||
|
||||
USDF_TRACE_SYS(CQ, "\n");
|
||||
|
||||
cq = container_of(fcq, struct usdf_cq, cq_fid);
|
||||
|
||||
// If top entry has no error, return 0
|
||||
@ -109,6 +126,7 @@ static ssize_t
|
||||
usdf_cq_sread(struct fid_cq *cq, void *buf, size_t count, const void *cond,
|
||||
int timeout)
|
||||
{
|
||||
USDF_TRACE_SYS(CQ, "\n"); /* XXX delete once implemented */
|
||||
return -FI_ENOSYS;
|
||||
}
|
||||
|
||||
@ -171,13 +189,13 @@ usdf_cq_read_common(struct fid_cq *fcq, void *buf, size_t count,
|
||||
case FI_CQ_FORMAT_MSG:
|
||||
msg_entry = (struct fi_cq_msg_entry *)entry;
|
||||
msg_entry->op_context = cq->cq_comp.uc_context;
|
||||
msg_entry->flags = 0;
|
||||
msg_entry->flags = usdf_cqe_to_flags(&cq->cq_comp);
|
||||
msg_entry->len = cq->cq_comp.uc_bytes;
|
||||
break;
|
||||
case FI_CQ_FORMAT_DATA:
|
||||
data_entry = (struct fi_cq_data_entry *)entry;
|
||||
data_entry->op_context = cq->cq_comp.uc_context;
|
||||
data_entry->flags = 0;
|
||||
data_entry->flags = usdf_cqe_to_flags(&cq->cq_comp);
|
||||
data_entry->len = cq->cq_comp.uc_bytes;
|
||||
data_entry->buf = 0; /* XXX */
|
||||
data_entry->data = 0;
|
||||
@ -600,6 +618,7 @@ usdf_cq_strerror(struct fid_cq *eq, int prov_errno, const void *err_data,
|
||||
static int
|
||||
usdf_cq_control(fid_t fid, int command, void *arg)
|
||||
{
|
||||
USDF_TRACE_SYS(CQ, "\n");
|
||||
return -FI_ENOSYS;
|
||||
}
|
||||
|
||||
@ -610,6 +629,8 @@ usdf_cq_close(fid_t fid)
|
||||
struct usdf_cq_hard *hcq;
|
||||
int ret;
|
||||
|
||||
USDF_TRACE_SYS(CQ, "\n");
|
||||
|
||||
cq = container_of(fid, struct usdf_cq, cq_fid.fid);
|
||||
if (atomic_get(&cq->cq_refcnt) > 0) {
|
||||
return -FI_EBUSY;
|
||||
@ -804,7 +825,7 @@ usdf_cq_make_soft(struct usdf_cq *cq)
|
||||
hcq->cqh_ucq = ucq;
|
||||
hcq->cqh_progress = rtn;
|
||||
|
||||
atomic_init(&hcq->cqh_refcnt,
|
||||
atomic_initialize(&hcq->cqh_refcnt,
|
||||
atomic_get(&cq->cq_refcnt));
|
||||
TAILQ_INSERT_HEAD(&cq->c.soft.cq_list, hcq, cqh_link);
|
||||
}
|
||||
@ -853,6 +874,8 @@ usdf_cq_open(struct fid_domain *domain, struct fi_cq_attr *attr,
|
||||
struct usdf_domain *udp;
|
||||
int ret;
|
||||
|
||||
USDF_TRACE_SYS(CQ, "\n");
|
||||
|
||||
udp = dom_ftou(domain);
|
||||
ret = usdf_cq_process_attr(attr, udp);
|
||||
if (ret != 0) {
|
||||
@ -868,7 +891,7 @@ usdf_cq_open(struct fid_domain *domain, struct fi_cq_attr *attr,
|
||||
cq->cq_fid.fid.fclass = FI_CLASS_CQ;
|
||||
cq->cq_fid.fid.context = context;
|
||||
cq->cq_fid.fid.ops = &usdf_cq_fi_ops;
|
||||
atomic_init(&cq->cq_refcnt, 0);
|
||||
atomic_initialize(&cq->cq_refcnt, 0);
|
||||
|
||||
switch (attr->format) {
|
||||
case FI_CQ_FORMAT_CONTEXT:
|
||||
|
@ -162,6 +162,7 @@ usdf_dgram_senddata(struct fid_ep *fep, const void *buf, size_t len,
|
||||
void *desc, uint64_t data, fi_addr_t dest_addr,
|
||||
void *context)
|
||||
{
|
||||
USDF_TRACE_SYS(EP_DATA, "\n"); /* XXX delete once implemented */
|
||||
return -FI_ENOSYS;
|
||||
}
|
||||
|
||||
@ -265,6 +266,7 @@ usdf_dgram_sendv(struct fid_ep *fep, const struct iovec *iov, void **desc,
|
||||
ssize_t
|
||||
usdf_dgram_sendmsg(struct fid_ep *fep, const struct fi_msg *msg, uint64_t flags)
|
||||
{
|
||||
USDF_DBG_SYS(EP_DATA, "flags ignored!");
|
||||
return usdf_dgram_sendv(fep, msg->msg_iov, msg->desc, msg->iov_count,
|
||||
(fi_addr_t)msg->addr, msg->context);
|
||||
}
|
||||
@ -319,6 +321,8 @@ ssize_t usdf_dgram_rx_size_left(struct fid_ep *fep)
|
||||
{
|
||||
struct usdf_ep *ep;
|
||||
|
||||
USDF_DBG_SYS(EP_DATA, "\n");
|
||||
|
||||
if (fep == NULL)
|
||||
return -FI_EINVAL;
|
||||
|
||||
@ -341,6 +345,8 @@ ssize_t usdf_dgram_tx_size_left(struct fid_ep *fep)
|
||||
{
|
||||
struct usdf_ep *ep;
|
||||
|
||||
USDF_DBG_SYS(EP_DATA, "\n");
|
||||
|
||||
if (fep == NULL)
|
||||
return -FI_EINVAL;
|
||||
|
||||
@ -524,6 +530,8 @@ ssize_t usdf_dgram_prefix_rx_size_left(struct fid_ep *fep)
|
||||
{
|
||||
struct usdf_ep *ep;
|
||||
|
||||
USDF_DBG_SYS(EP_DATA, "\n");
|
||||
|
||||
if (fep == NULL)
|
||||
return -FI_EINVAL;
|
||||
|
||||
@ -542,6 +550,8 @@ ssize_t usdf_dgram_prefix_tx_size_left(struct fid_ep *fep)
|
||||
{
|
||||
struct usdf_ep *ep;
|
||||
|
||||
USDF_DBG_SYS(EP_DATA, "\n");
|
||||
|
||||
if (fep == NULL)
|
||||
return -FI_EINVAL;
|
||||
|
||||
|
@ -63,6 +63,8 @@ usdf_domain_bind(struct fid *fid, struct fid *bfid, uint64_t flags)
|
||||
{
|
||||
struct usdf_domain *udp;
|
||||
|
||||
USDF_TRACE_SYS(DOMAIN, "\n");
|
||||
|
||||
udp = dom_fidtou(fid);
|
||||
|
||||
switch (bfid->fclass) {
|
||||
@ -130,7 +132,7 @@ usdf_dom_rdc_alloc_data(struct usdf_domain *udp)
|
||||
return -FI_ENOMEM;
|
||||
}
|
||||
SLIST_INIT(&udp->dom_rdc_free);
|
||||
atomic_init(&udp->dom_rdc_free_cnt, 0);
|
||||
atomic_initialize(&udp->dom_rdc_free_cnt, 0);
|
||||
for (i = 0; i < USDF_RDM_FREE_BLOCK; ++i) {
|
||||
rdc = calloc(1, sizeof(*rdc));
|
||||
if (rdc == NULL) {
|
||||
@ -161,6 +163,8 @@ usdf_domain_close(fid_t fid)
|
||||
struct usdf_domain *udp;
|
||||
int ret;
|
||||
|
||||
USDF_TRACE_SYS(DOMAIN, "\n");
|
||||
|
||||
udp = container_of(fid, struct usdf_domain, dom_fid.fid);
|
||||
if (atomic_get(&udp->dom_refcnt) > 0) {
|
||||
return -FI_EBUSY;
|
||||
@ -222,16 +226,31 @@ usdf_domain_open(struct fid_fabric *fabric, struct fi_info *info,
|
||||
size_t addrlen;
|
||||
int ret;
|
||||
|
||||
USDF_TRACE_SYS(DOMAIN, "\n");
|
||||
|
||||
if (info->domain_attr != NULL) {
|
||||
switch (info->domain_attr->mr_mode) {
|
||||
case FI_MR_UNSPEC:
|
||||
case FI_MR_BASIC:
|
||||
break;
|
||||
default:
|
||||
/* the caller ignored our fi_getinfo results */
|
||||
USDF_WARN_SYS(DOMAIN, "MR mode (%d) not supported\n",
|
||||
info->domain_attr->mr_mode);
|
||||
return -FI_ENODATA;
|
||||
}
|
||||
}
|
||||
|
||||
udp = calloc(1, sizeof *udp);
|
||||
if (udp == NULL) {
|
||||
USDF_DEBUG("unable to alloc mem for domain\n");
|
||||
USDF_DBG("unable to alloc mem for domain\n");
|
||||
ret = -FI_ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fp = fab_fidtou(fabric);
|
||||
|
||||
USDF_DEBUG("uda_devname=%s\n", fp->fab_dev_attrs->uda_devname);
|
||||
USDF_DBG("uda_devname=%s\n", fp->fab_dev_attrs->uda_devname);
|
||||
|
||||
/*
|
||||
* Make sure address format is good and matches this fabric
|
||||
@ -291,7 +310,7 @@ usdf_domain_open(struct fid_fabric *fabric, struct fi_info *info,
|
||||
|
||||
udp->dom_fabric = fp;
|
||||
LIST_INSERT_HEAD(&fp->fab_domain_list, udp, dom_link);
|
||||
atomic_init(&udp->dom_refcnt, 0);
|
||||
atomic_initialize(&udp->dom_refcnt, 0);
|
||||
atomic_inc(&fp->fab_refcnt);
|
||||
|
||||
*domain = &udp->dom_fid;
|
||||
|
@ -68,6 +68,8 @@ usdf_ep_port_bind(struct usdf_ep *ep, struct fi_info *info)
|
||||
socklen_t addrlen;
|
||||
int ret;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
sin = (struct sockaddr_in *)info->src_addr;
|
||||
ret = bind(ep->e.dg.ep_sock, (struct sockaddr *)sin, sizeof(*sin));
|
||||
if (ret == -1) {
|
||||
@ -87,6 +89,8 @@ int
|
||||
usdf_endpoint_open(struct fid_domain *domain, struct fi_info *info,
|
||||
struct fid_ep **ep_o, void *context)
|
||||
{
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
switch (info->ep_attr->type) {
|
||||
case FI_EP_DGRAM:
|
||||
return usdf_ep_dgram_open(domain, info, ep_o, context);
|
||||
|
@ -74,6 +74,8 @@ usdf_ep_dgram_enable(struct fid_ep *fep)
|
||||
struct usd_qp_impl *uqp;
|
||||
int ret;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
ep = ep_ftou(fep);
|
||||
|
||||
if (ep->e.dg.ep_wcq == NULL) {
|
||||
@ -158,6 +160,8 @@ usdf_ep_dgram_bind(struct fid *fid, struct fid *bfid, uint64_t flags)
|
||||
struct usdf_cq *cq;
|
||||
int ret;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
ep = ep_fidtou(fid);
|
||||
|
||||
switch (bfid->fclass) {
|
||||
@ -256,6 +260,8 @@ usdf_ep_dgram_close(fid_t fid)
|
||||
{
|
||||
struct usdf_ep *ep;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
ep = ep_fidtou(fid);
|
||||
|
||||
if (atomic_get(&ep->ep_refcnt) > 0) {
|
||||
@ -330,6 +336,7 @@ static struct fi_ops_msg usdf_dgram_prefix_ops = {
|
||||
|
||||
static struct fi_ops_cm usdf_cm_dgram_ops = {
|
||||
.size = sizeof(struct fi_ops_cm),
|
||||
.setname = fi_no_setname,
|
||||
.getname = fi_no_getname,
|
||||
.getpeer = fi_no_getpeer,
|
||||
.connect = fi_no_connect,
|
||||
@ -343,6 +350,8 @@ static int usdf_ep_dgram_control(struct fid *fid, int command, void *arg)
|
||||
{
|
||||
struct fid_ep *ep;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
switch (fid->fclass) {
|
||||
case FI_CLASS_EP:
|
||||
ep = container_of(fid, struct fid_ep, fid);
|
||||
@ -375,6 +384,8 @@ usdf_ep_dgram_open(struct fid_domain *domain, struct fi_info *info,
|
||||
struct usdf_ep *ep;
|
||||
int ret;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
if ((info->caps & ~USDF_DGRAM_CAPS) != 0) {
|
||||
return -FI_EBADF;
|
||||
}
|
||||
@ -434,7 +445,7 @@ usdf_ep_dgram_open(struct fid_domain *domain, struct fi_info *info,
|
||||
ep->ep_fid.ops = &usdf_base_dgram_ops;
|
||||
ep->ep_fid.msg = &usdf_dgram_ops;
|
||||
}
|
||||
atomic_init(&ep->ep_refcnt, 0);
|
||||
atomic_initialize(&ep->ep_refcnt, 0);
|
||||
atomic_inc(&udp->dom_refcnt);
|
||||
|
||||
*ep_o = ep_utof(ep);
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include "usnic_direct.h"
|
||||
#include "usd.h"
|
||||
#include "usdf.h"
|
||||
#include "usdf_cm.h"
|
||||
#include "usdf_endpoint.h"
|
||||
#include "usdf_rudp.h"
|
||||
#include "usdf_msg.h"
|
||||
@ -112,13 +113,24 @@ usdf_tx_msg_enable(struct usdf_tx *tx)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = usd_alloc_mr(tx->tx_domain->dom_dev,
|
||||
tx->tx_attr.size * USDF_MSG_MAX_INJECT_SIZE,
|
||||
(void **)&tx->t.msg.tx_inject_bufs);
|
||||
if (ret) {
|
||||
USDF_INFO("usd_alloc_mr failed (%s)\n", strerror(-ret));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* populate free list */
|
||||
TAILQ_INIT(&tx->t.msg.tx_free_wqe);
|
||||
wqe = tx->t.msg.tx_wqe_buf;
|
||||
for (i = 0; i < tx->tx_attr.size; ++i) {
|
||||
wqe->ms_inject_buf =
|
||||
&tx->t.msg.tx_inject_bufs[USDF_MSG_MAX_INJECT_SIZE * i];
|
||||
TAILQ_INSERT_TAIL(&tx->t.msg.tx_free_wqe, wqe, ms_link);
|
||||
++wqe;
|
||||
}
|
||||
tx->t.msg.tx_num_free_wqe = tx->tx_attr.size;
|
||||
|
||||
return 0;
|
||||
|
||||
@ -127,7 +139,14 @@ fail:
|
||||
free(tx->t.msg.tx_wqe_buf);
|
||||
tx->t.msg.tx_wqe_buf = NULL;
|
||||
TAILQ_INIT(&tx->t.msg.tx_free_wqe);
|
||||
tx->t.msg.tx_num_free_wqe = 0;
|
||||
}
|
||||
|
||||
if (tx->t.msg.tx_inject_bufs != NULL) {
|
||||
usd_free_mr(tx->t.msg.tx_inject_bufs);
|
||||
tx->t.msg.tx_inject_bufs = NULL;
|
||||
}
|
||||
|
||||
if (tx->tx_qp != NULL) {
|
||||
usd_destroy_qp(tx->tx_qp);
|
||||
}
|
||||
@ -207,6 +226,7 @@ usdf_rx_msg_enable(struct usdf_rx *rx)
|
||||
TAILQ_INSERT_TAIL(&rx->r.msg.rx_free_rqe, rqe, ms_link);
|
||||
++rqe;
|
||||
}
|
||||
rx->r.msg.rx_num_free_rqe = rx->rx_attr.size;
|
||||
|
||||
return 0;
|
||||
|
||||
@ -215,6 +235,7 @@ fail:
|
||||
free(rx->r.msg.rx_rqe_buf);
|
||||
rx->r.msg.rx_rqe_buf = NULL;
|
||||
TAILQ_INIT(&rx->r.msg.rx_free_rqe);
|
||||
rx->r.msg.rx_num_free_rqe = 0;
|
||||
}
|
||||
if (rx->r.msg.rx_bufs != NULL) {
|
||||
usd_free_mr(rx->r.msg.rx_bufs);
|
||||
@ -287,10 +308,19 @@ usdf_ep_msg_getopt(fid_t fid, int level, int optname,
|
||||
void *optval, size_t *optlen)
|
||||
{
|
||||
struct usdf_ep *ep;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
ep = ep_fidtou(fid);
|
||||
(void)ep;
|
||||
|
||||
switch (level) {
|
||||
case FI_OPT_CM_DATA_SIZE:
|
||||
if (*optlen < sizeof(size_t))
|
||||
return -FI_ETOOSMALL;
|
||||
*((size_t *) optval) = USDF_MAX_CONN_DATA;
|
||||
*optlen = sizeof(size_t);
|
||||
return 0;
|
||||
case FI_OPT_ENDPOINT:
|
||||
return -FI_ENOPROTOOPT;
|
||||
default:
|
||||
@ -304,6 +334,9 @@ usdf_ep_msg_setopt(fid_t fid, int level, int optname,
|
||||
const void *optval, size_t optlen)
|
||||
{
|
||||
struct usdf_ep *ep;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
ep = ep_fidtou(fid);
|
||||
(void)ep;
|
||||
|
||||
@ -319,6 +352,8 @@ usdf_ep_msg_setopt(fid_t fid, int level, int optname,
|
||||
static ssize_t
|
||||
usdf_ep_msg_cancel(fid_t fid, void *context)
|
||||
{
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
/* XXX should this have a non-empty implementation? */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -336,6 +371,13 @@ usdf_msg_fill_tx_attr(struct fi_tx_attr *txattr)
|
||||
if (txattr->iov_limit == 0) {
|
||||
txattr->iov_limit = USDF_MSG_DFLT_SGE;
|
||||
}
|
||||
|
||||
if (txattr->op_flags & ~USDF_MSG_SUPP_SENDMSG_FLAGS) {
|
||||
USDF_WARN("one or more flags in 0x%llx not supported\n",
|
||||
txattr->op_flags);
|
||||
return -FI_EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -418,7 +460,7 @@ usdf_ep_msg_bind_cq(struct usdf_ep *ep, struct usdf_cq *cq, uint64_t flags)
|
||||
goto fail;
|
||||
}
|
||||
hcq->cqh_cq = cq;
|
||||
atomic_init(&hcq->cqh_refcnt, 0);
|
||||
atomic_initialize(&hcq->cqh_refcnt, 0);
|
||||
hcq->cqh_progress = usdf_msg_hcq_progress;
|
||||
switch (cq->cq_attr.format) {
|
||||
default:
|
||||
@ -456,6 +498,8 @@ usdf_ep_msg_bind(struct fid *fid, struct fid *bfid, uint64_t flags)
|
||||
struct usdf_ep *ep;
|
||||
struct usdf_cq *cq;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
ep = ep_fidtou(fid);
|
||||
|
||||
switch (bfid->fclass) {
|
||||
@ -463,11 +507,19 @@ usdf_ep_msg_bind(struct fid *fid, struct fid *bfid, uint64_t flags)
|
||||
case FI_CLASS_CQ:
|
||||
if (flags & FI_SEND) {
|
||||
cq = cq_fidtou(bfid);
|
||||
if (flags & FI_SELECTIVE_COMPLETION)
|
||||
ep->ep_tx_dflt_signal_comp = 0;
|
||||
else
|
||||
ep->ep_tx_dflt_signal_comp = 1;
|
||||
usdf_ep_msg_bind_cq(ep, cq, FI_SEND);
|
||||
}
|
||||
|
||||
if (flags & FI_RECV) {
|
||||
cq = cq_fidtou(bfid);
|
||||
if (flags & FI_SELECTIVE_COMPLETION)
|
||||
ep->ep_rx_dflt_signal_comp = 0;
|
||||
else
|
||||
ep->ep_rx_dflt_signal_comp = 1;
|
||||
usdf_ep_msg_bind_cq(ep, cq, FI_RECV);
|
||||
}
|
||||
break;
|
||||
@ -535,6 +587,7 @@ usdf_msg_tx_ctx_close(fid_t fid)
|
||||
}
|
||||
|
||||
if (tx->tx_qp != NULL) {
|
||||
usd_free_mr(tx->t.msg.tx_inject_bufs);
|
||||
free(tx->t.msg.tx_wqe_buf);
|
||||
usd_destroy_qp(tx->tx_qp);
|
||||
}
|
||||
@ -550,6 +603,8 @@ usdf_ep_msg_close(fid_t fid)
|
||||
{
|
||||
struct usdf_ep *ep;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
ep = ep_fidtou(fid);
|
||||
|
||||
if (atomic_get(&ep->ep_refcnt) > 0) {
|
||||
@ -587,12 +642,13 @@ static struct fi_ops_ep usdf_base_msg_ops = {
|
||||
.setopt = usdf_ep_msg_setopt,
|
||||
.tx_ctx = fi_no_tx_ctx,
|
||||
.rx_ctx = fi_no_rx_ctx,
|
||||
.rx_size_left = fi_no_rx_size_left,
|
||||
.tx_size_left = fi_no_tx_size_left,
|
||||
.rx_size_left = usdf_msg_rx_size_left,
|
||||
.tx_size_left = usdf_msg_tx_size_left,
|
||||
};
|
||||
|
||||
static struct fi_ops_cm usdf_cm_msg_ops = {
|
||||
.size = sizeof(struct fi_ops_cm),
|
||||
.setname = fi_no_setname,
|
||||
.getname = fi_no_getname,
|
||||
.getpeer = fi_no_getpeer,
|
||||
.connect = usdf_cm_msg_connect,
|
||||
@ -619,6 +675,8 @@ static int usdf_ep_msg_control(struct fid *fid, int command, void *arg)
|
||||
{
|
||||
struct fid_ep *ep;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
switch (fid->fclass) {
|
||||
case FI_CLASS_EP:
|
||||
ep = container_of(fid, struct fid_ep, fid);
|
||||
@ -654,6 +712,8 @@ usdf_ep_msg_open(struct fid_domain *domain, struct fi_info *info,
|
||||
struct usdf_ep *ep;
|
||||
int ret;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
ep = NULL;
|
||||
rx = NULL;
|
||||
tx = NULL;
|
||||
@ -688,7 +748,9 @@ usdf_ep_msg_open(struct fid_domain *domain, struct fi_info *info,
|
||||
ep->ep_domain = udp;
|
||||
ep->ep_caps = info->caps;
|
||||
ep->ep_mode = info->mode;
|
||||
ep->e.msg.ep_connreq = (struct usdf_connreq *)info->connreq;
|
||||
ep->e.msg.ep_connreq = (struct usdf_connreq *)info->handle;
|
||||
ep->ep_tx_dflt_signal_comp = 1;
|
||||
ep->ep_rx_dflt_signal_comp = 1;
|
||||
|
||||
ep->e.msg.ep_seq_credits = USDF_RUDP_SEQ_CREDITS;
|
||||
TAILQ_INIT(&ep->e.msg.ep_posted_wqe);
|
||||
@ -710,7 +772,7 @@ usdf_ep_msg_open(struct fid_domain *domain, struct fi_info *info,
|
||||
goto fail;
|
||||
}
|
||||
tx->tx_fid.fid.fclass = FI_CLASS_TX_CTX;
|
||||
atomic_init(&tx->tx_refcnt, 0);
|
||||
atomic_initialize(&tx->tx_refcnt, 0);
|
||||
tx->tx_domain = udp;
|
||||
tx->tx_progress = usdf_msg_tx_progress;
|
||||
atomic_inc(&udp->dom_refcnt);
|
||||
@ -732,7 +794,6 @@ usdf_ep_msg_open(struct fid_domain *domain, struct fi_info *info,
|
||||
|
||||
ep->ep_tx = tx;
|
||||
atomic_inc(&tx->tx_refcnt);
|
||||
atomic_inc(&udp->dom_refcnt);
|
||||
}
|
||||
TAILQ_INIT(&ep->e.msg.ep_posted_wqe);
|
||||
|
||||
@ -745,7 +806,7 @@ usdf_ep_msg_open(struct fid_domain *domain, struct fi_info *info,
|
||||
goto fail;
|
||||
}
|
||||
rx->rx_fid.fid.fclass = FI_CLASS_RX_CTX;
|
||||
atomic_init(&rx->rx_refcnt, 0);
|
||||
atomic_initialize(&rx->rx_refcnt, 0);
|
||||
rx->rx_domain = udp;
|
||||
atomic_inc(&udp->dom_refcnt);
|
||||
if (info->rx_attr != NULL) {
|
||||
@ -764,7 +825,7 @@ usdf_ep_msg_open(struct fid_domain *domain, struct fi_info *info,
|
||||
atomic_inc(&rx->rx_refcnt);
|
||||
}
|
||||
|
||||
atomic_init(&ep->ep_refcnt, 0);
|
||||
atomic_initialize(&ep->ep_refcnt, 0);
|
||||
atomic_inc(&udp->dom_refcnt);
|
||||
|
||||
*ep_o = ep_utof(ep);
|
||||
|
@ -78,6 +78,8 @@ usdf_tx_rdm_enable(struct usdf_tx *tx)
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
udp = tx->tx_domain;
|
||||
|
||||
hcq = tx->t.rdm.tx_hcq;
|
||||
@ -110,13 +112,24 @@ usdf_tx_rdm_enable(struct usdf_tx *tx)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = usd_alloc_mr(tx->tx_domain->dom_dev,
|
||||
tx->tx_attr.size * USDF_RDM_MAX_INJECT_SIZE,
|
||||
(void **)&tx->t.rdm.tx_inject_bufs);
|
||||
if (ret) {
|
||||
USDF_INFO("usd_alloc_mr failed (%s)\n", strerror(-ret));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* populate free list */
|
||||
TAILQ_INIT(&tx->t.rdm.tx_free_wqe);
|
||||
wqe = tx->t.rdm.tx_wqe_buf;
|
||||
for (i = 0; i < tx->tx_attr.size; ++i) {
|
||||
wqe->rd_inject_buf =
|
||||
&tx->t.rdm.tx_inject_bufs[USDF_RDM_MAX_INJECT_SIZE * i];
|
||||
TAILQ_INSERT_TAIL(&tx->t.rdm.tx_free_wqe, wqe, rd_link);
|
||||
++wqe;
|
||||
}
|
||||
tx->t.rdm.tx_num_free_wqe = tx->tx_attr.size;
|
||||
|
||||
return 0;
|
||||
|
||||
@ -125,7 +138,14 @@ fail:
|
||||
free(tx->t.rdm.tx_wqe_buf);
|
||||
tx->t.rdm.tx_wqe_buf = NULL;
|
||||
TAILQ_INIT(&tx->t.rdm.tx_free_wqe);
|
||||
tx->t.rdm.tx_num_free_wqe = 0;
|
||||
}
|
||||
|
||||
if (tx->t.rdm.tx_inject_bufs != NULL) {
|
||||
usd_free_mr(tx->t.rdm.tx_inject_bufs);
|
||||
tx->t.rdm.tx_inject_bufs = NULL;
|
||||
}
|
||||
|
||||
if (tx->tx_qp != NULL) {
|
||||
usd_destroy_qp(tx->tx_qp);
|
||||
}
|
||||
@ -145,6 +165,8 @@ usdf_rx_rdm_enable(struct usdf_rx *rx)
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
udp = rx->rx_domain;
|
||||
|
||||
hcq = rx->r.rdm.rx_hcq;
|
||||
@ -201,6 +223,7 @@ usdf_rx_rdm_enable(struct usdf_rx *rx)
|
||||
TAILQ_INSERT_TAIL(&rx->r.rdm.rx_free_rqe, rqe, rd_link);
|
||||
++rqe;
|
||||
}
|
||||
rx->r.rdm.rx_num_free_rqe = rx->rx_attr.size;
|
||||
|
||||
return 0;
|
||||
|
||||
@ -209,6 +232,7 @@ fail:
|
||||
free(rx->r.rdm.rx_rqe_buf);
|
||||
rx->r.rdm.rx_rqe_buf = NULL;
|
||||
TAILQ_INIT(&rx->r.rdm.rx_free_rqe);
|
||||
rx->r.rdm.rx_num_free_rqe = 0;
|
||||
}
|
||||
if (rx->r.rdm.rx_bufs != NULL) {
|
||||
usd_free_mr(rx->r.rdm.rx_bufs);
|
||||
@ -272,6 +296,9 @@ usdf_ep_rdm_getopt(fid_t fid, int level, int optname,
|
||||
void *optval, size_t *optlen)
|
||||
{
|
||||
struct usdf_ep *ep;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
ep = ep_fidtou(fid);
|
||||
(void)ep;
|
||||
|
||||
@ -289,6 +316,9 @@ usdf_ep_rdm_setopt(fid_t fid, int level, int optname,
|
||||
const void *optval, size_t optlen)
|
||||
{
|
||||
struct usdf_ep *ep;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
ep = ep_fidtou(fid);
|
||||
(void)ep;
|
||||
|
||||
@ -304,6 +334,8 @@ usdf_ep_rdm_setopt(fid_t fid, int level, int optname,
|
||||
static ssize_t
|
||||
usdf_ep_rdm_cancel(fid_t fid, void *context)
|
||||
{
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
/* XXX should this have a non-empty implementation? */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -321,6 +353,13 @@ usdf_rdm_fill_tx_attr(struct fi_tx_attr *txattr)
|
||||
if (txattr->iov_limit == 0) {
|
||||
txattr->iov_limit = USDF_RDM_DFLT_SGE;
|
||||
}
|
||||
|
||||
if (txattr->op_flags & ~USDF_RDM_SUPP_SENDMSG_FLAGS) {
|
||||
USDF_WARN("one or more flags in 0x%llx not supported\n",
|
||||
txattr->op_flags);
|
||||
return -FI_EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -403,7 +442,7 @@ usdf_ep_rdm_bind_cq(struct usdf_ep *ep, struct usdf_cq *cq, uint64_t flags)
|
||||
goto fail;
|
||||
}
|
||||
hcq->cqh_cq = cq;
|
||||
atomic_init(&hcq->cqh_refcnt, 0);
|
||||
atomic_initialize(&hcq->cqh_refcnt, 0);
|
||||
hcq->cqh_progress = usdf_rdm_hcq_progress;
|
||||
switch (cq->cq_attr.format) {
|
||||
default:
|
||||
@ -441,6 +480,8 @@ usdf_ep_rdm_bind(struct fid *fid, struct fid *bfid, uint64_t flags)
|
||||
struct usdf_ep *ep;
|
||||
struct usdf_cq *cq;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
ep = ep_fidtou(fid);
|
||||
|
||||
switch (bfid->fclass) {
|
||||
@ -456,11 +497,19 @@ usdf_ep_rdm_bind(struct fid *fid, struct fid *bfid, uint64_t flags)
|
||||
case FI_CLASS_CQ:
|
||||
if (flags & FI_SEND) {
|
||||
cq = cq_fidtou(bfid);
|
||||
if (flags & FI_SELECTIVE_COMPLETION)
|
||||
ep->ep_tx_dflt_signal_comp = 0;
|
||||
else
|
||||
ep->ep_tx_dflt_signal_comp = 1;
|
||||
usdf_ep_rdm_bind_cq(ep, cq, FI_SEND);
|
||||
}
|
||||
|
||||
if (flags & FI_RECV) {
|
||||
cq = cq_fidtou(bfid);
|
||||
if (flags & FI_SELECTIVE_COMPLETION)
|
||||
ep->ep_rx_dflt_signal_comp = 0;
|
||||
else
|
||||
ep->ep_rx_dflt_signal_comp = 1;
|
||||
usdf_ep_rdm_bind_cq(ep, cq, FI_RECV);
|
||||
}
|
||||
break;
|
||||
@ -488,6 +537,8 @@ usdf_rdm_rx_ctx_close(fid_t fid)
|
||||
struct usdf_rx *rx;
|
||||
struct usdf_cq_hard *hcq;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
rx = rx_fidtou(fid);
|
||||
|
||||
if (atomic_get(&rx->rx_refcnt) > 0) {
|
||||
@ -524,6 +575,8 @@ usdf_rdm_tx_ctx_close(fid_t fid)
|
||||
struct usdf_tx *tx;
|
||||
struct usdf_cq_hard *hcq;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
tx = tx_fidtou(fid);
|
||||
|
||||
if (atomic_get(&tx->tx_refcnt) > 0) {
|
||||
@ -537,6 +590,7 @@ usdf_rdm_tx_ctx_close(fid_t fid)
|
||||
}
|
||||
|
||||
if (tx->tx_qp != NULL) {
|
||||
usd_free_mr(tx->t.rdm.tx_inject_bufs);
|
||||
free(tx->t.rdm.tx_wqe_buf);
|
||||
usd_destroy_qp(tx->tx_qp);
|
||||
}
|
||||
@ -592,6 +646,8 @@ usdf_ep_rdm_close(fid_t fid)
|
||||
{
|
||||
struct usdf_ep *ep;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
ep = ep_fidtou(fid);
|
||||
|
||||
if (atomic_get(&ep->ep_refcnt) > 0) {
|
||||
@ -628,12 +684,13 @@ static struct fi_ops_ep usdf_base_rdm_ops = {
|
||||
.setopt = usdf_ep_rdm_setopt,
|
||||
.tx_ctx = fi_no_tx_ctx,
|
||||
.rx_ctx = fi_no_rx_ctx,
|
||||
.rx_size_left = fi_no_rx_size_left,
|
||||
.tx_size_left = fi_no_tx_size_left,
|
||||
.rx_size_left = usdf_rdm_rx_size_left,
|
||||
.tx_size_left = usdf_rdm_tx_size_left,
|
||||
};
|
||||
|
||||
static struct fi_ops_cm usdf_cm_rdm_ops = {
|
||||
.size = sizeof(struct fi_ops_cm),
|
||||
.setname = fi_no_setname,
|
||||
.getname = usdf_cm_rdm_getname,
|
||||
.getpeer = fi_no_getpeer,
|
||||
.connect = fi_no_connect,
|
||||
@ -660,6 +717,8 @@ static int usdf_ep_rdm_control(struct fid *fid, int command, void *arg)
|
||||
{
|
||||
struct fid_ep *ep;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
switch (fid->fclass) {
|
||||
case FI_CLASS_EP:
|
||||
ep = container_of(fid, struct fid_ep, fid);
|
||||
@ -694,6 +753,8 @@ usdf_ep_rdm_open(struct fid_domain *domain, struct fi_info *info,
|
||||
struct usdf_ep *ep;
|
||||
int ret;
|
||||
|
||||
USDF_TRACE_SYS(EP_CTRL, "\n");
|
||||
|
||||
ep = NULL;
|
||||
rx = NULL;
|
||||
tx = NULL;
|
||||
@ -727,6 +788,8 @@ usdf_ep_rdm_open(struct fid_domain *domain, struct fi_info *info,
|
||||
ep->ep_domain = udp;
|
||||
ep->ep_caps = info->caps;
|
||||
ep->ep_mode = info->mode;
|
||||
ep->ep_tx_dflt_signal_comp = 1;
|
||||
ep->ep_rx_dflt_signal_comp = 1;
|
||||
|
||||
/* implicitly create TX context if not to be shared */
|
||||
if (info->ep_attr == NULL ||
|
||||
@ -737,10 +800,10 @@ usdf_ep_rdm_open(struct fid_domain *domain, struct fi_info *info,
|
||||
goto fail;
|
||||
}
|
||||
tx->tx_fid.fid.fclass = FI_CLASS_TX_CTX;
|
||||
atomic_init(&tx->tx_refcnt, 0);
|
||||
atomic_initialize(&tx->tx_refcnt, 0);
|
||||
tx->tx_domain = udp;
|
||||
tx->tx_progress = usdf_rdm_tx_progress;
|
||||
atomic_init(&tx->t.rdm.tx_next_msg_id, 1);
|
||||
atomic_initialize(&tx->t.rdm.tx_next_msg_id, 1);
|
||||
atomic_inc(&udp->dom_refcnt);
|
||||
|
||||
if (info->tx_attr != NULL) {
|
||||
@ -773,7 +836,7 @@ usdf_ep_rdm_open(struct fid_domain *domain, struct fi_info *info,
|
||||
}
|
||||
|
||||
rx->rx_fid.fid.fclass = FI_CLASS_RX_CTX;
|
||||
atomic_init(&rx->rx_refcnt, 0);
|
||||
atomic_initialize(&rx->rx_refcnt, 0);
|
||||
rx->rx_domain = udp;
|
||||
rx->r.rdm.rx_tx = tx;
|
||||
rx->r.rdm.rx_sock = -1;
|
||||
@ -803,7 +866,7 @@ usdf_ep_rdm_open(struct fid_domain *domain, struct fi_info *info,
|
||||
atomic_inc(&rx->rx_refcnt);
|
||||
}
|
||||
|
||||
atomic_init(&ep->ep_refcnt, 0);
|
||||
atomic_initialize(&ep->ep_refcnt, 0);
|
||||
atomic_inc(&udp->dom_refcnt);
|
||||
|
||||
*ep_o = ep_utof(ep);
|
||||
|
@ -164,6 +164,8 @@ usdf_eq_readerr(struct fid_eq *feq, struct fi_eq_err_entry *entry,
|
||||
uint64_t val;
|
||||
int ret;
|
||||
|
||||
USDF_TRACE_SYS(EQ, "\n");
|
||||
|
||||
eq = eq_ftou(feq);
|
||||
pthread_spin_lock(&eq->eq_lock);
|
||||
|
||||
@ -437,6 +439,8 @@ usdf_eq_control(fid_t fid, int command, void *arg)
|
||||
{
|
||||
struct usdf_eq *eq;
|
||||
|
||||
USDF_TRACE_SYS(EQ, "\n");
|
||||
|
||||
eq = eq_fidtou(fid);
|
||||
|
||||
switch (command) {
|
||||
@ -459,6 +463,8 @@ usdf_eq_close(fid_t fid)
|
||||
{
|
||||
struct usdf_eq *eq;
|
||||
|
||||
USDF_TRACE_SYS(EQ, "\n");
|
||||
|
||||
eq = eq_fidtou(fid);
|
||||
|
||||
if (atomic_get(&eq->eq_refcnt) > 0) {
|
||||
@ -505,6 +511,8 @@ usdf_eq_open(struct fid_fabric *fabric, struct fi_eq_attr *attr,
|
||||
struct usdf_fabric *fab;
|
||||
int ret;
|
||||
|
||||
USDF_TRACE_SYS(EQ, "\n");
|
||||
|
||||
fab = fab_ftou(fabric);
|
||||
|
||||
eq = calloc(1, sizeof(*eq));
|
||||
@ -521,7 +529,7 @@ usdf_eq_open(struct fid_fabric *fabric, struct fi_eq_attr *attr,
|
||||
eq->eq_wait_obj = attr->wait_obj;
|
||||
|
||||
eq->eq_fabric = fab;
|
||||
atomic_init(&eq->eq_refcnt, 0);
|
||||
atomic_initialize(&eq->eq_refcnt, 0);
|
||||
ret = pthread_spin_init(&eq->eq_lock, PTHREAD_PROCESS_PRIVATE);
|
||||
if (ret != 0) {
|
||||
ret = -ret;
|
||||
@ -580,7 +588,7 @@ usdf_eq_open(struct fid_fabric *fabric, struct fi_eq_attr *attr,
|
||||
eq->eq_ev_tail = eq->eq_ev_ring;
|
||||
eq->eq_ev_ring_size = attr->size;
|
||||
eq->eq_ev_end = eq->eq_ev_ring + eq->eq_ev_ring_size;
|
||||
atomic_init(&eq->eq_num_events, 0);
|
||||
atomic_initialize(&eq->eq_num_events, 0);
|
||||
|
||||
atomic_inc(&eq->eq_fabric->fab_refcnt);
|
||||
*feq = eq_utof(eq);
|
||||
|
@ -182,6 +182,80 @@ fail:
|
||||
return ret; // fi_freeinfo() in caller frees all
|
||||
}
|
||||
|
||||
static int usdf_fill_domain_attr_dgram(
|
||||
struct fi_domain_attr *dhints,
|
||||
struct fi_domain_attr *dattrp)
|
||||
{
|
||||
switch (dhints ? dhints->threading : FI_THREAD_UNSPEC) {
|
||||
case FI_THREAD_UNSPEC:
|
||||
case FI_THREAD_ENDPOINT:
|
||||
/* this is our natural thread safety level */
|
||||
dattrp->threading = FI_THREAD_ENDPOINT;
|
||||
break;
|
||||
case FI_THREAD_FID:
|
||||
case FI_THREAD_COMPLETION:
|
||||
case FI_THREAD_DOMAIN:
|
||||
/* subsets of _ENDPOINT, so supported */
|
||||
dattrp->threading = dhints->threading;
|
||||
break;
|
||||
default:
|
||||
USDF_INFO("cannot support threading=%d\n",
|
||||
dhints->threading);
|
||||
return -FI_ENODATA;
|
||||
}
|
||||
|
||||
switch (dhints ? dhints->control_progress : FI_PROGRESS_UNSPEC) {
|
||||
case FI_PROGRESS_UNSPEC:
|
||||
case FI_PROGRESS_AUTO:
|
||||
dattrp->control_progress = FI_PROGRESS_AUTO;
|
||||
break;
|
||||
case FI_PROGRESS_MANUAL:
|
||||
/* we still behave the same as _AUTO, but we answer _MANUAL as
|
||||
* requested by the user */
|
||||
dattrp->control_progress = FI_PROGRESS_MANUAL;
|
||||
break;
|
||||
default:
|
||||
USDF_INFO("cannot support control_progress=%d\n",
|
||||
dhints->control_progress);
|
||||
return -FI_ENODATA;
|
||||
}
|
||||
|
||||
switch (dhints ? dhints->data_progress : FI_PROGRESS_UNSPEC) {
|
||||
case FI_PROGRESS_UNSPEC:
|
||||
case FI_PROGRESS_MANUAL:
|
||||
dattrp->data_progress = FI_PROGRESS_MANUAL;
|
||||
break;
|
||||
default:
|
||||
USDF_INFO("cannot support data_progress=%d\n",
|
||||
dhints->data_progress);
|
||||
return -FI_ENODATA;
|
||||
}
|
||||
|
||||
switch (dhints ? dhints->resource_mgmt : FI_RM_UNSPEC) {
|
||||
case FI_RM_UNSPEC:
|
||||
case FI_RM_DISABLED:
|
||||
dattrp->resource_mgmt = FI_RM_DISABLED;
|
||||
break;
|
||||
default:
|
||||
USDF_INFO("cannot support resource_mgmt=%d\n",
|
||||
dhints->resource_mgmt);
|
||||
return -FI_ENODATA;
|
||||
}
|
||||
|
||||
switch (dhints ? dhints->mr_mode : FI_MR_UNSPEC) {
|
||||
case FI_MR_UNSPEC:
|
||||
case FI_MR_BASIC:
|
||||
dattrp->mr_mode = FI_MR_BASIC;
|
||||
break;
|
||||
default:
|
||||
USDF_INFO("cannot support mr_mode=%d\n",
|
||||
dhints->mr_mode);
|
||||
return -FI_ENODATA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
usdf_fill_info_dgram(
|
||||
struct fi_info *hints,
|
||||
@ -193,7 +267,6 @@ usdf_fill_info_dgram(
|
||||
{
|
||||
struct fi_info *fi;
|
||||
struct fi_fabric_attr *fattrp;
|
||||
struct fi_domain_attr *dattrp;
|
||||
struct fi_tx_attr *txattr;
|
||||
struct fi_rx_attr *rxattr;
|
||||
struct fi_ep_attr *eattrp;
|
||||
@ -325,11 +398,10 @@ usdf_fill_info_dgram(
|
||||
eattrp->rx_ctx_cnt = 1;
|
||||
|
||||
/* domain attrs */
|
||||
dattrp = fi->domain_attr;
|
||||
dattrp->threading = FI_THREAD_UNSPEC;
|
||||
dattrp->control_progress = FI_PROGRESS_AUTO;
|
||||
dattrp->data_progress = FI_PROGRESS_MANUAL;
|
||||
dattrp->resource_mgmt = FI_RM_DISABLED;
|
||||
ret = usdf_fill_domain_attr_dgram(hints ? hints->domain_attr : NULL,
|
||||
fi->domain_attr);
|
||||
if (ret != 0)
|
||||
goto fail;
|
||||
|
||||
/* add to tail of list */
|
||||
if (*fi_first == NULL) {
|
||||
@ -436,6 +508,7 @@ usdf_fill_info_msg(
|
||||
dattrp->control_progress = FI_PROGRESS_AUTO;
|
||||
dattrp->data_progress = FI_PROGRESS_MANUAL;
|
||||
dattrp->resource_mgmt = FI_RM_DISABLED;
|
||||
dattrp->mr_mode = FI_MR_BASIC;
|
||||
|
||||
/* add to tail of list */
|
||||
if (*fi_first == NULL) {
|
||||
@ -540,6 +613,7 @@ usdf_fill_info_rdm(
|
||||
dattrp->control_progress = FI_PROGRESS_AUTO;
|
||||
dattrp->data_progress = FI_PROGRESS_MANUAL;
|
||||
dattrp->resource_mgmt = FI_RM_DISABLED;
|
||||
dattrp->mr_mode = FI_MR_BASIC;
|
||||
|
||||
/* add to tail of list */
|
||||
if (*fi_first == NULL) {
|
||||
@ -615,6 +689,8 @@ usdf_get_distance(
|
||||
uint32_t nh_ip_addr;
|
||||
int ret;
|
||||
|
||||
USDF_TRACE("\n");
|
||||
|
||||
ret = usnic_nl_rt_lookup(dap->uda_ipaddr_be, daddr_be,
|
||||
dap->uda_ifindex, &nh_ip_addr);
|
||||
if (ret != 0) {
|
||||
@ -646,6 +722,8 @@ usdf_getinfo(uint32_t version, const char *node, const char *service,
|
||||
int d;
|
||||
int ret;
|
||||
|
||||
USDF_TRACE("\n");
|
||||
|
||||
fi_first = NULL;
|
||||
fi_last = NULL;
|
||||
ai = NULL;
|
||||
@ -670,7 +748,8 @@ usdf_getinfo(uint32_t version, const char *node, const char *service,
|
||||
if (node != NULL || service != NULL) {
|
||||
ret = getaddrinfo(node, service, NULL, &ai);
|
||||
if (ret != 0) {
|
||||
return -errno;
|
||||
ret = -errno;
|
||||
goto fail;
|
||||
}
|
||||
if (flags & FI_SOURCE) {
|
||||
src = (struct sockaddr_in *)ai->ai_addr;
|
||||
@ -693,7 +772,7 @@ usdf_getinfo(uint32_t version, const char *node, const char *service,
|
||||
|
||||
/* skip this device if it has some problem */
|
||||
if (!dep->ue_dev_ok) {
|
||||
USDF_DEBUG("skipping %s/%s\n", dap->uda_devname,
|
||||
USDF_DBG("skipping %s/%s\n", dap->uda_devname,
|
||||
dap->uda_ifname);
|
||||
continue;
|
||||
}
|
||||
@ -706,7 +785,7 @@ usdf_getinfo(uint32_t version, const char *node, const char *service,
|
||||
goto fail;
|
||||
}
|
||||
if (metric == -1) {
|
||||
USDF_DEBUG("dest %s unreachable from %s/%s, skipping\n",
|
||||
USDF_DBG("dest %s unreachable from %s/%s, skipping\n",
|
||||
inet_ntoa(dest->sin_addr),
|
||||
dap->uda_devname, dap->uda_ifname);
|
||||
continue;
|
||||
@ -717,7 +796,7 @@ usdf_getinfo(uint32_t version, const char *node, const char *service,
|
||||
if (hints != NULL) {
|
||||
ret = usdf_validate_hints(hints, dap);
|
||||
if (ret != 0) {
|
||||
USDF_DEBUG("hints do not match for %s/%s, skipping\n",
|
||||
USDF_DBG("hints do not match for %s/%s, skipping\n",
|
||||
dap->uda_devname, dap->uda_ifname);
|
||||
continue;
|
||||
}
|
||||
@ -780,6 +859,8 @@ usdf_fabric_close(fid_t fid)
|
||||
int ret;
|
||||
void *rv;
|
||||
|
||||
USDF_TRACE("\n");
|
||||
|
||||
fp = fab_fidtou(fid);
|
||||
if (atomic_get(&fp->fab_refcnt) > 0) {
|
||||
return -FI_EBUSY;
|
||||
@ -816,6 +897,8 @@ usdf_usnic_getinfo(uint32_t version, struct fid_fabric *fabric,
|
||||
struct usdf_fabric *fp;
|
||||
struct usd_device_attrs *dap;
|
||||
|
||||
USDF_TRACE("\n");
|
||||
|
||||
fp = fab_ftou(fabric);
|
||||
dap = fp->fab_dev_attrs;
|
||||
|
||||
@ -842,6 +925,8 @@ static int
|
||||
usdf_fabric_ops_open(struct fid *fid, const char *ops_name, uint64_t flags,
|
||||
void **ops, void *context)
|
||||
{
|
||||
USDF_TRACE("\n");
|
||||
|
||||
if (strcmp(ops_name, FI_USNIC_FABRIC_OPS_1) == 0) {
|
||||
*ops = &usdf_usnic_ops_fabric;
|
||||
} else {
|
||||
@ -880,6 +965,8 @@ usdf_fabric_open(struct fi_fabric_attr *fattrp, struct fid_fabric **fabric,
|
||||
int ret;
|
||||
int d;
|
||||
|
||||
USDF_TRACE("\n");
|
||||
|
||||
/* Make sure this fabric exists */
|
||||
dp = __usdf_devinfo;
|
||||
for (d = 0; d < dp->uu_num_devs; ++d) {
|
||||
@ -975,7 +1062,7 @@ usdf_fabric_open(struct fi_fabric_attr *fattrp, struct fid_fabric **fabric,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
atomic_init(&fp->fab_refcnt, 0);
|
||||
atomic_initialize(&fp->fab_refcnt, 0);
|
||||
fattrp->fabric = fab_utof(fp);
|
||||
fattrp->prov_version = USDF_PROV_VERSION;
|
||||
*fabric = fab_utof(fp);
|
||||
@ -986,12 +1073,13 @@ usdf_fabric_open(struct fi_fabric_attr *fattrp, struct fid_fabric **fabric,
|
||||
fail:
|
||||
ff = fab_utof(fp);
|
||||
usdf_fabric_close(&ff->fid);
|
||||
USDF_DEBUG("returning %d (%s)\n", ret, fi_strerror(-ret));
|
||||
USDF_DBG("returning %d (%s)\n", ret, fi_strerror(-ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void usdf_fini(void)
|
||||
{
|
||||
USDF_TRACE("\n");
|
||||
}
|
||||
|
||||
struct fi_provider usdf_ops = {
|
||||
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче
Block a user