1
1

Merge pull request #556 from jsquyres/pr/libfabric-1.0rc6

Update embedded libfabric to 1.0rc6
Этот коммит содержится в:
Jeff Squyres 2015-04-27 13:40:58 -04:00
родитель 60127b1caa df5043bc3f
Коммит 5114f7f37a
112 изменённых файлов: 4449 добавлений и 24520 удалений

Просмотреть файл

@ -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.

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -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:

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -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])])

Просмотреть файл

@ -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
])

Просмотреть файл

@ -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)
])

Просмотреть файл

@ -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,9 +165,17 @@ 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.
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
@ -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,9 +660,11 @@ static inline void psmx_cntr_inc(struct psmx_fid_cntr *cntr)
static inline void psmx_progress(struct psmx_fid_domain *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,
void *desc, fi_addr_t dest_addr, void *context,

Просмотреть файл

@ -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;
}
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,

Просмотреть файл

@ -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,14 +230,46 @@ 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)) {
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) {
if (hints->ep_attr->max_msg_size > PSMX_MAX_MSG_SIZE) {
FI_INFO(&psmx_prov, FI_LOG_CORE,
@ -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,6 +55,7 @@ static void *psmx_wait_progress(void *args)
while (1) {
pthread_mutex_lock(&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_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,9 +88,12 @@ 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);
@ -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,6 +188,7 @@ 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) {
@ -187,8 +196,19 @@ uint16_t sock_conn_map_connect(struct sock_ep *ep,
return 0;
}
SOCK_LOG_INFO("Connecting to: %s:%d\n", inet_ntoa(addr->sin_addr),
ntohs(addr->sin_port));
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 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)
@ -115,9 +118,36 @@ int sock_verify_domain_attr(struct fi_domain_attr *attr)
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);
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)))
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,12 +314,12 @@ 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) ?
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;
@ -436,7 +470,7 @@ int sock_domain(struct fid_fabric *fabric, struct fi_info *info,
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;
@ -1189,14 +1212,78 @@ int sock_srx_ctx(struct fid_domain *domain,
/* 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;
*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,
@ -845,6 +928,7 @@ static struct fi_info * sock_ep_msg_process_info(struct sock_conn_req *req)
static void *sock_pep_listener_thread(void *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;
@ -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);
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;
char *value;
tmp = getenv("OFI_SOCK_PROGRESS_YIELD_TIME");
if (tmp)
sock_progress_thread_wait = atoi(tmp);
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 {
@ -183,6 +205,7 @@ static ssize_t sock_ep_sendmsg(struct fid_ep *ep, const struct fi_msg *msg,
SOCK_LOG_INFO("New sendmsg on TX: %p using conn: %p\n",
tx_ctx, conn);
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 {
@ -467,6 +516,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;
}
pe->num_free_entries++;
pe_entry->conn = NULL;
@ -128,6 +142,7 @@ static void sock_pe_release_entry(struct sock_pe *pe,
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,8 +1116,8 @@ 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,
@ -1055,14 +1129,15 @@ static int sock_pe_process_rx_atomic(struct sock_pe *pe, struct sock_rx_ctx *rx_
(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);
goto err;
SOCK_OP_ATOMIC_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].ioc.addr += mr->offset;
}
}
/* src data */
if (sock_pe_recv_field(pe_entry, &pe_entry->pe.rx.atomic_src[0],
@ -1089,16 +1164,119 @@ static int sock_pe_process_rx_atomic(struct sock_pe *pe, struct sock_rx_ctx *rx_
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;
}
err:
sock_pe_report_error(pe_entry, 0);
return -FI_EINVAL;
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;
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");
}
@ -2012,11 +2230,12 @@ static int sock_pe_progress_rx_ep(struct sock_pe *pe, struct sock_ep *ep,
{
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,11 +2263,14 @@ 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)
goto out;
}
}
ret = 0;
out:
fastlock_release(&map->lock);
return ret;
}
}
return 0;
}
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,11 +2457,8 @@ 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)) {
@ -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,6 +113,7 @@ static ssize_t sock_ep_rma_readmsg(struct fid_ep *ep,
goto err;
}
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;
@ -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,6 +255,7 @@ static ssize_t sock_ep_rma_writemsg(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(struct sock_op));
tx_op.op = SOCK_OP_WRITE;
@ -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 = {

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше