Merge tag 'upstream/0.7.2'

Upstream version 0.7.2
This commit is contained in:
Aron Xu 2017-10-06 19:01:12 +08:00
commit 56c48f7490
76 changed files with 3938 additions and 1338 deletions

2
META
View File

@ -1,7 +1,7 @@
Meta: 1 Meta: 1
Name: spl Name: spl
Branch: 1.0 Branch: 1.0
Version: 0.6.5.11 Version: 0.7.2
Release: 1 Release: 1
Release-Tags: relext Release-Tags: relext
License: GPL License: GPL

View File

@ -1,11 +1 @@
include $(top_srcdir)/config/Rules.am SUBDIRS = splat splslab
DEFAULT_INCLUDES += \
-I$(top_srcdir)/lib
sbin_PROGRAMS = splat
splat_SOURCES = splat.c
splat_LDFLAGS = $(top_builddir)/lib/libcommon.la
EXTRA_DIST = splat.h

View File

@ -14,15 +14,6 @@
# PARTICULAR PURPOSE. # PARTICULAR PURPOSE.
@SET_MAKE@ @SET_MAKE@
###############################################################################
# Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
# Copyright (C) 2007 The Regents of the University of California.
# Written by Brian Behlendorf <behlendorf1@llnl.gov>.
###############################################################################
# Common rules for user space components.
###############################################################################
VPATH = @srcdir@ VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@ pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@
@ -43,10 +34,8 @@ POST_UNINSTALL = :
build_triplet = @build@ build_triplet = @build@
host_triplet = @host@ host_triplet = @host@
target_triplet = @target@ target_triplet = @target@
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(top_srcdir)/config/Rules.am
sbin_PROGRAMS = splat$(EXEEXT)
subdir = cmd subdir = cmd
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \ am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
$(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltoptions.m4 \
@ -61,47 +50,55 @@ mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/spl_config.h CONFIG_HEADER = $(top_builddir)/spl_config.h
CONFIG_CLEAN_FILES = CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES = CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(sbindir)"
PROGRAMS = $(sbin_PROGRAMS)
am_splat_OBJECTS = splat.$(OBJEXT)
splat_OBJECTS = $(am_splat_OBJECTS)
splat_LDADD = $(LDADD)
AM_V_lt = $(am__v_lt_$(V))
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
am__v_lt_0 = --silent
splat_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(splat_LDFLAGS) $(LDFLAGS) -o $@
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_$(V))
am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
am__v_CC_0 = @echo " CC " $@;
AM_V_at = $(am__v_at_$(V))
am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
am__v_at_0 = @
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_$(V))
am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
am__v_CCLD_0 = @echo " CCLD " $@;
AM_V_GEN = $(am__v_GEN_$(V)) AM_V_GEN = $(am__v_GEN_$(V))
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_0 = @echo " GEN " $@;
SOURCES = $(splat_SOURCES) AM_V_at = $(am__v_at_$(V))
DIST_SOURCES = $(splat_SOURCES) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
am__v_at_0 = @
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-dvi-recursive install-exec-recursive \
install-html-recursive install-info-recursive \
install-pdf-recursive install-ps-recursive install-recursive \
installcheck-recursive installdirs-recursive pdf-recursive \
ps-recursive uninstall-recursive
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
distdir
ETAGS = etags ETAGS = etags
CTAGS = ctags CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
sed_rest='s,^[^/]*/*,,'; \
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
sed_butlast='s,/*[^/]*$$,,'; \
while test -n "$$dir1"; do \
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
if test "$$first" != "."; then \
if test "$$first" = ".."; then \
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
else \
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
if test "$$first2" = "$$first"; then \
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
else \
dir2="../$$dir2"; \
fi; \
dir0="$$dir0"/"$$first"; \
fi; \
fi; \
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
done; \
reldir="$$dir2"
ACLOCAL = @ACLOCAL@ ACLOCAL = @ACLOCAL@
ALIEN = @ALIEN@ ALIEN = @ALIEN@
ALIEN_VERSION = @ALIEN_VERSION@ ALIEN_VERSION = @ALIEN_VERSION@
@ -266,20 +263,11 @@ target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@ top_srcdir = @top_srcdir@
DEFAULT_INCLUDES = -include ${top_builddir}/spl_config.h \ SUBDIRS = splat splslab
-I$(top_srcdir)/lib all: all-recursive
AM_LIBTOOLFLAGS = --silent
AM_CPPFLAGS = -D__USE_LARGEFILE64
AM_CFLAGS = -Wall -Wshadow -Wstrict-prototypes -fno-strict-aliasing \
${DEBUG_CFLAGS}
splat_SOURCES = splat.c
splat_LDFLAGS = $(top_builddir)/lib/libcommon.la
EXTRA_DIST = splat.h
all: all-am
.SUFFIXES: .SUFFIXES:
.SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/config/Rules.am $(am__configure_deps)
@for dep in $?; do \ @for dep in $?; do \
case '$(am__configure_deps)' in \ case '$(am__configure_deps)' in \
*$$dep*) \ *$$dep*) \
@ -309,84 +297,6 @@ $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps): $(am__aclocal_m4_deps):
install-sbinPROGRAMS: $(sbin_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)"
@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
for p in $$list; do echo "$$p $$p"; done | \
sed 's/$(EXEEXT)$$//' | \
while read p p1; do if test -f $$p || test -f $$p1; \
then echo "$$p"; echo "$$p"; else :; fi; \
done | \
sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
-e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
sed 'N;N;N;s,\n, ,g' | \
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
{ d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
if ($$2 == $$4) files[d] = files[d] " " $$1; \
else { print "f", $$3 "/" $$4, $$1; } } \
END { for (d in files) print "f", d, files[d] }' | \
while read type dir files; do \
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
test -z "$$files" || { \
echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
$(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
} \
; done
uninstall-sbinPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
files=`for p in $$list; do echo "$$p"; done | \
sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
-e 's/$$/$(EXEEXT)/' `; \
test -n "$$list" || exit 0; \
echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(sbindir)" && rm -f $$files
clean-sbinPROGRAMS:
@list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
echo " rm -f" $$list; \
rm -f $$list || exit $$?; \
test -n "$(EXEEXT)" || exit 0; \
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
splat$(EXEEXT): $(splat_OBJECTS) $(splat_DEPENDENCIES)
@rm -f splat$(EXEEXT)
$(AM_V_CCLD)$(splat_LINK) $(splat_OBJECTS) $(splat_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splat.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
mostlyclean-libtool: mostlyclean-libtool:
-rm -f *.lo -rm -f *.lo
@ -394,6 +304,76 @@ mostlyclean-libtool:
clean-libtool: clean-libtool:
-rm -rf .libs _libs -rm -rf .libs _libs
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
$(RECURSIVE_CLEAN_TARGETS):
@fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \ unique=`for i in $$list; do \
@ -404,10 +384,23 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
mkid -fID $$unique mkid -fID $$unique
tags: TAGS tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP) $(TAGS_FILES) $(LISP)
set x; \ set x; \
here=`pwd`; \ here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \ unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
@ -426,7 +419,7 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
fi; \ fi; \
fi fi
ctags: CTAGS ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP) $(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \ unique=`for i in $$list; do \
@ -476,22 +469,48 @@ distdir: $(DISTFILES)
|| exit 1; \ || exit 1; \
fi; \ fi; \
done done
check-am: all-am @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
check: check-am if test "$$subdir" = .; then :; else \
all-am: Makefile $(PROGRAMS) test -d "$(distdir)/$$subdir" \
installdirs: || $(MKDIR_P) "$(distdir)/$$subdir" \
for dir in "$(DESTDIR)$(sbindir)"; do \ || exit 1; \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \ fi; \
done done
install: install-am @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
install-exec: install-exec-am if test "$$subdir" = .; then :; else \
install-data: install-data-am dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
uninstall: uninstall-am $(am__relativize); \
new_distdir=$$reldir; \
dir1=$$subdir; dir2="$(top_distdir)"; \
$(am__relativize); \
new_top_distdir=$$reldir; \
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
($(am__cd) $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$new_top_distdir" \
distdir="$$new_distdir" \
am__remove_distdir=: \
am__skip_length_check=: \
am__skip_mode_fix=: \
distdir) \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-recursive
all-am: Makefile
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am installcheck: installcheck-recursive
install-strip: install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
@ -508,92 +527,88 @@ distclean-generic:
maintainer-clean-generic: maintainer-clean-generic:
@echo "This command is intended for maintainers to use" @echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild." @echo "it deletes files that may require special tools to rebuild."
clean: clean-am clean: clean-recursive
clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ clean-am: clean-generic clean-libtool mostlyclean-am
mostlyclean-am
distclean: distclean-am distclean: distclean-recursive
-rm -rf ./$(DEPDIR)
-rm -f Makefile -rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \ distclean-am: clean-am distclean-generic distclean-tags
distclean-tags
dvi: dvi-am dvi: dvi-recursive
dvi-am: dvi-am:
html: html-am html: html-recursive
html-am: html-am:
info: info-am info: info-recursive
info-am: info-am:
install-data-am: install-data-am:
install-dvi: install-dvi-am install-dvi: install-dvi-recursive
install-dvi-am: install-dvi-am:
install-exec-am: install-sbinPROGRAMS install-exec-am:
install-html: install-html-am install-html: install-html-recursive
install-html-am: install-html-am:
install-info: install-info-am install-info: install-info-recursive
install-info-am: install-info-am:
install-man: install-man:
install-pdf: install-pdf-am install-pdf: install-pdf-recursive
install-pdf-am: install-pdf-am:
install-ps: install-ps-am install-ps: install-ps-recursive
install-ps-am: install-ps-am:
installcheck-am: installcheck-am:
maintainer-clean: maintainer-clean-am maintainer-clean: maintainer-clean-recursive
-rm -rf ./$(DEPDIR)
-rm -f Makefile -rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-am: mostlyclean-generic mostlyclean-libtool
mostlyclean-libtool
pdf: pdf-am pdf: pdf-recursive
pdf-am: pdf-am:
ps: ps-am ps: ps-recursive
ps-am: ps-am:
uninstall-am: uninstall-sbinPROGRAMS uninstall-am:
.MAKE: install-am install-strip .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
install-am install-strip tags-recursive
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
clean-libtool clean-sbinPROGRAMS ctags distclean \ all all-am check check-am clean clean-generic clean-libtool \
distclean-compile distclean-generic distclean-libtool \ ctags ctags-recursive distclean distclean-generic \
distclean-tags distdir dvi dvi-am html html-am info info-am \ distclean-libtool distclean-tags distdir dvi dvi-am html \
install install-am install-data install-data-am install-dvi \ html-am info info-am install install-am install-data \
install-dvi-am install-exec install-exec-am install-html \ install-data-am install-dvi install-dvi-am install-exec \
install-html-am install-info install-info-am install-man \ install-exec-am install-html install-html-am install-info \
install-pdf install-pdf-am install-ps install-ps-am \ install-info-am install-man install-pdf install-pdf-am \
install-sbinPROGRAMS install-strip installcheck \ install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \ installcheck-am installdirs installdirs-am maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \ maintainer-clean-generic mostlyclean mostlyclean-generic \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
tags uninstall uninstall-am uninstall-sbinPROGRAMS uninstall uninstall-am
# Tell versions [3.59,3.63) of GNU make to not export all variables. # Tell versions [3.59,3.63) of GNU make to not export all variables.

11
cmd/splat/Makefile.am Normal file
View File

@ -0,0 +1,11 @@
include $(top_srcdir)/config/Rules.am
DEFAULT_INCLUDES += \
-I$(top_srcdir)/lib
sbin_PROGRAMS = splat
splat_SOURCES = splat.c
splat_LDFLAGS = $(top_builddir)/lib/libcommon.la
EXTRA_DIST = splat.h

601
cmd/splat/Makefile.in Normal file
View File

@ -0,0 +1,601 @@
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
###############################################################################
# Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
# Copyright (C) 2007 The Regents of the University of California.
# Written by Brian Behlendorf <behlendorf1@llnl.gov>.
###############################################################################
# Common rules for user space components.
###############################################################################
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(top_srcdir)/config/Rules.am
sbin_PROGRAMS = splat$(EXEEXT)
subdir = cmd/splat
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
$(top_srcdir)/config/ltoptions.m4 \
$(top_srcdir)/config/ltsugar.m4 \
$(top_srcdir)/config/ltversion.m4 \
$(top_srcdir)/config/lt~obsolete.m4 \
$(top_srcdir)/config/spl-build.m4 \
$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/spl_config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(sbindir)"
PROGRAMS = $(sbin_PROGRAMS)
am_splat_OBJECTS = splat.$(OBJEXT)
splat_OBJECTS = $(am_splat_OBJECTS)
splat_LDADD = $(LDADD)
AM_V_lt = $(am__v_lt_$(V))
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
am__v_lt_0 = --silent
splat_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(splat_LDFLAGS) $(LDFLAGS) -o $@
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_$(V))
am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
am__v_CC_0 = @echo " CC " $@;
AM_V_at = $(am__v_at_$(V))
am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
am__v_at_0 = @
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_$(V))
am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
am__v_CCLD_0 = @echo " CCLD " $@;
AM_V_GEN = $(am__v_GEN_$(V))
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
am__v_GEN_0 = @echo " GEN " $@;
SOURCES = $(splat_SOURCES)
DIST_SOURCES = $(splat_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALIEN = @ALIEN@
ALIEN_VERSION = @ALIEN_VERSION@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEBUG_CFLAGS = @DEBUG_CFLAGS@
DEBUG_KMEM = @DEBUG_KMEM@
DEBUG_KMEM_TRACKING = @DEBUG_KMEM_TRACKING@
DEBUG_SPL = @DEBUG_SPL@
DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DPKG = @DPKG@
DPKGBUILD = @DPKGBUILD@
DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
DPKG_VERSION = @DPKG_VERSION@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
HAVE_ALIEN = @HAVE_ALIEN@
HAVE_DPKG = @HAVE_DPKG@
HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
HAVE_RPM = @HAVE_RPM@
HAVE_RPMBUILD = @HAVE_RPMBUILD@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
KERNELCPPFLAGS = @KERNELCPPFLAGS@
KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LINUX = @LINUX@
LINUX_OBJ = @LINUX_OBJ@
LINUX_SYMBOLS = @LINUX_SYMBOLS@
LINUX_VERSION = @LINUX_VERSION@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
RPM = @RPM@
RPMBUILD = @RPMBUILD@
RPMBUILD_VERSION = @RPMBUILD_VERSION@
RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
RPM_SPEC_DIR = @RPM_SPEC_DIR@
RPM_VERSION = @RPM_VERSION@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SPL_CONFIG = @SPL_CONFIG@
SPL_META_ALIAS = @SPL_META_ALIAS@
SPL_META_AUTHOR = @SPL_META_AUTHOR@
SPL_META_DATA = @SPL_META_DATA@
SPL_META_LICENSE = @SPL_META_LICENSE@
SPL_META_LT_AGE = @SPL_META_LT_AGE@
SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
SPL_META_NAME = @SPL_META_NAME@
SPL_META_RELEASE = @SPL_META_RELEASE@
SPL_META_VERSION = @SPL_META_VERSION@
SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
STRIP = @STRIP@
VENDOR = @VENDOR@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
DEFAULT_INCLUDES = -include ${top_builddir}/spl_config.h \
-I$(top_srcdir)/lib
AM_LIBTOOLFLAGS = --silent
AM_CPPFLAGS = -D__USE_LARGEFILE64
AM_CFLAGS = -Wall -Wshadow -Wstrict-prototypes -fno-strict-aliasing \
${DEBUG_CFLAGS}
splat_SOURCES = splat.c
splat_LDFLAGS = $(top_builddir)/lib/libcommon.la
EXTRA_DIST = splat.h
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/config/Rules.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cmd/splat/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu cmd/splat/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-sbinPROGRAMS: $(sbin_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)"
@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
for p in $$list; do echo "$$p $$p"; done | \
sed 's/$(EXEEXT)$$//' | \
while read p p1; do if test -f $$p || test -f $$p1; \
then echo "$$p"; echo "$$p"; else :; fi; \
done | \
sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
-e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
sed 'N;N;N;s,\n, ,g' | \
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
{ d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
if ($$2 == $$4) files[d] = files[d] " " $$1; \
else { print "f", $$3 "/" $$4, $$1; } } \
END { for (d in files) print "f", d, files[d] }' | \
while read type dir files; do \
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
test -z "$$files" || { \
echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
$(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
} \
; done
uninstall-sbinPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
files=`for p in $$list; do echo "$$p"; done | \
sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
-e 's/$$/$(EXEEXT)/' `; \
test -n "$$list" || exit 0; \
echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(sbindir)" && rm -f $$files
clean-sbinPROGRAMS:
@list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
echo " rm -f" $$list; \
rm -f $$list || exit $$?; \
test -n "$(EXEEXT)" || exit 0; \
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
splat$(EXEEXT): $(splat_OBJECTS) $(splat_DEPENDENCIES)
@rm -f splat$(EXEEXT)
$(AM_V_CCLD)$(splat_LINK) $(splat_OBJECTS) $(splat_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splat.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(PROGRAMS)
installdirs:
for dir in "$(DESTDIR)$(sbindir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-sbinPROGRAMS
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-sbinPROGRAMS
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool clean-sbinPROGRAMS ctags distclean \
distclean-compile distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-sbinPROGRAMS install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-sbinPROGRAMS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

2
cmd/splslab/Makefile.am Normal file
View File

@ -0,0 +1,2 @@
bin_SCRIPTS = splslab.py
EXTRA_DIST = $(bin_SCRIPTS)

477
cmd/splslab/Makefile.in Normal file
View File

@ -0,0 +1,477 @@
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = cmd/splslab
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
$(top_srcdir)/config/ltoptions.m4 \
$(top_srcdir)/config/ltsugar.m4 \
$(top_srcdir)/config/ltversion.m4 \
$(top_srcdir)/config/lt~obsolete.m4 \
$(top_srcdir)/config/spl-build.m4 \
$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/spl_config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(bindir)"
SCRIPTS = $(bin_SCRIPTS)
AM_V_GEN = $(am__v_GEN_$(V))
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
am__v_GEN_0 = @echo " GEN " $@;
AM_V_at = $(am__v_at_$(V))
am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
am__v_at_0 = @
SOURCES =
DIST_SOURCES =
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALIEN = @ALIEN@
ALIEN_VERSION = @ALIEN_VERSION@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEBUG_CFLAGS = @DEBUG_CFLAGS@
DEBUG_KMEM = @DEBUG_KMEM@
DEBUG_KMEM_TRACKING = @DEBUG_KMEM_TRACKING@
DEBUG_SPL = @DEBUG_SPL@
DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DPKG = @DPKG@
DPKGBUILD = @DPKGBUILD@
DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
DPKG_VERSION = @DPKG_VERSION@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
HAVE_ALIEN = @HAVE_ALIEN@
HAVE_DPKG = @HAVE_DPKG@
HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
HAVE_RPM = @HAVE_RPM@
HAVE_RPMBUILD = @HAVE_RPMBUILD@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
KERNELCPPFLAGS = @KERNELCPPFLAGS@
KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LINUX = @LINUX@
LINUX_OBJ = @LINUX_OBJ@
LINUX_SYMBOLS = @LINUX_SYMBOLS@
LINUX_VERSION = @LINUX_VERSION@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
RPM = @RPM@
RPMBUILD = @RPMBUILD@
RPMBUILD_VERSION = @RPMBUILD_VERSION@
RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
RPM_SPEC_DIR = @RPM_SPEC_DIR@
RPM_VERSION = @RPM_VERSION@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SPL_CONFIG = @SPL_CONFIG@
SPL_META_ALIAS = @SPL_META_ALIAS@
SPL_META_AUTHOR = @SPL_META_AUTHOR@
SPL_META_DATA = @SPL_META_DATA@
SPL_META_LICENSE = @SPL_META_LICENSE@
SPL_META_LT_AGE = @SPL_META_LT_AGE@
SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
SPL_META_NAME = @SPL_META_NAME@
SPL_META_RELEASE = @SPL_META_RELEASE@
SPL_META_VERSION = @SPL_META_VERSION@
SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
STRIP = @STRIP@
VENDOR = @VENDOR@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
bin_SCRIPTS = splslab.py
EXTRA_DIST = $(bin_SCRIPTS)
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cmd/splslab/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu cmd/splslab/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-binSCRIPTS: $(bin_SCRIPTS)
@$(NORMAL_INSTALL)
test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
done | \
sed -e 'p;s,.*/,,;n' \
-e 'h;s|.*|.|' \
-e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
{ d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
if ($$2 == $$4) { files[d] = files[d] " " $$1; \
if (++n[d] == $(am__install_max)) { \
print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
else { print "f", d "/" $$4, $$1 } } \
END { for (d in files) print "f", d, files[d] }' | \
while read type dir files; do \
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
test -z "$$files" || { \
echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
$(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
} \
; done
uninstall-binSCRIPTS:
@$(NORMAL_UNINSTALL)
@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
files=`for p in $$list; do echo "$$p"; done | \
sed -e 's,.*/,,;$(transform)'`; \
test -n "$$list" || exit 0; \
echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(bindir)" && rm -f $$files
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
tags: TAGS
TAGS:
ctags: CTAGS
CTAGS:
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(SCRIPTS)
installdirs:
for dir in "$(DESTDIR)$(bindir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-binSCRIPTS
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-binSCRIPTS
.MAKE: install-am install-strip
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
distclean distclean-generic distclean-libtool distdir dvi \
dvi-am html html-am info info-am install install-am \
install-binSCRIPTS install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
uninstall uninstall-am uninstall-binSCRIPTS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

202
cmd/splslab/splslab.py Executable file
View File

@ -0,0 +1,202 @@
#!/usr/bin/python
import sys
import time
import getopt
import re
import signal
from collections import defaultdict
class Stat:
# flag definitions based on the kmem.h
NOTOUCH = 1
NODEBUG = 2
KMEM = 32
VMEM = 64
SLAB = 128
OFFSLAB = 256
NOEMERGENCY = 512
DEADLOCKED = 16384
GROWING = 32768
REAPING = 65536
DESTROY = 131072
fdefs = {
NOTOUCH : "NTCH",
NODEBUG : "NDBG",
KMEM : "KMEM",
VMEM : "VMEM",
SLAB : "SLAB",
OFFSLAB : "OFSL",
NOEMERGENCY : "NEMG",
DEADLOCKED : "DDLK",
GROWING : "GROW",
REAPING : "REAP",
DESTROY : "DSTR"
}
def __init__(self, name, flags, size, alloc, slabsize, objsize):
self._name = name
self._flags = self.f2str(flags)
self._size = size
self._alloc = alloc
self._slabsize = slabsize
self._objsize = objsize
def f2str(self, flags):
fstring = ''
for k in Stat.fdefs.keys():
if flags & k:
fstring = fstring + Stat.fdefs[k] + '|'
fstring = fstring[:-1]
return fstring
class CumulativeStat:
def __init__(self, skey="a"):
self._size = 0
self._alloc = 0
self._pct = 0
self._skey = skey
self._regexp = \
re.compile('(\w+)\s+(\w+)\s+(\w+)\s+(\w+)\s+(\w+)\s+(\w+)\s+');
self._stats = defaultdict(list)
# Add another stat to the dictionary and re-calculate the totals
def add(self, s):
key = 0
if self._skey == "a":
key = s._alloc
else:
key = s._size
self._stats[key].append(s)
self._size = self._size + s._size
self._alloc = self._alloc + s._alloc
if self._size:
self._pct = self._alloc * 100 / self._size
else:
self._pct = 0
# Parse the slab info in the procfs
# Calculate cumulative stats
def slab_update(self):
k = [line.strip() for line in open('/proc/spl/kmem/slab')]
if not k:
sys.stderr.write("No SPL slab stats found\n")
sys.exit(1)
del k[0:2]
for s in k:
if not s:
continue
m = self._regexp.match(s)
if m:
self.add(Stat(m.group(1), int(m.group(2),16), int(m.group(3)),
int(m.group(4)), int(m.group(5)), int(m.group(6))))
else:
sys.stderr.write("Error: unexpected input format\n" % s)
exit(-1)
def show_header(self):
sys.stdout.write("\n%25s %20s %15s %15s %15s %15s\n\n" % \
("cache name", "flags", "size", "alloc", "slabsize", "objsize"))
# Show up to the number of 'rows' of output sorted in descending order
# by the key specified earlier; if rows == 0, all rows are shown
def show(self, rows):
self.show_header()
i = 1
done = False
for k in reversed(sorted(self._stats.keys())):
for s in self._stats[k]:
sys.stdout.write("%25s %20s %15d %15d %15d %15d\n" % \
(s._name, s._flags, s._size, s._alloc, \
s._slabsize, s._objsize))
i = i + 1
if rows != 0 and i > rows:
done = True
break
if done:
break
sys.stdout.write("%25s %36d %15d (%d%%)\n\n" % \
("Totals:", self._size, self._alloc, self._pct))
def usage():
cmd = "Usage: splslab.py [-n|--num-rows] number [-s|--sort-by] " + \
"[interval] [count]";
sys.stderr.write("%s\n" % cmd)
sys.stderr.write("\t-h : print help\n")
sys.stderr.write("\t-n : --num-rows N : limit output to N top " +
"largest slabs (default: all)\n")
sys.stderr.write("\t-s : --sort-by key : sort output in descending " +
"order by total size (s)\n\t\tor allocated size (a) " +
"(default: a)\n")
sys.stderr.write("\tinterval : repeat every interval seconds\n")
sys.stderr.write("\tcount : output statistics count times and exit\n")
def main():
rows = 0
count = 0
skey = "a"
interval = 1
signal.signal(signal.SIGINT, signal.SIG_DFL)
try:
opts, args = getopt.getopt(
sys.argv[1:],
"n:s:h",
[
"num-rows",
"sort-by",
"help"
]
)
except getopt.error as e:
sys.stderr.write("Error: %s\n" % e.msg)
usage()
exit(-1)
i = 1
for opt, arg in opts:
if opt in ('-n', '--num-rows'):
rows = int(arg)
i = i + 2
elif opt in ('-s', '--sort-by'):
if arg != "s" and arg != "a":
sys.stderr.write("Error: invalid sorting key \"%s\"\n" % arg)
usage()
exit(-1)
skey = arg
i = i + 2
elif opt in ('-h', '--help'):
usage()
exit(0)
else:
break
args = sys.argv[i:]
interval = int(args[0]) if len(args) else interval
count = int(args[1]) if len(args) > 1 else count
i = 0
while True:
cs = CumulativeStat(skey)
cs.slab_update()
cs.show(rows)
i = i + 1
if count and i >= count:
break
time.sleep(interval)
return 0
if __name__ == '__main__':
main()

View File

@ -50,8 +50,10 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
SPL_AC_KMEM_CACHE_ALLOCFLAGS SPL_AC_KMEM_CACHE_ALLOCFLAGS
SPL_AC_WAIT_ON_BIT SPL_AC_WAIT_ON_BIT
SPL_AC_INODE_LOCK SPL_AC_INODE_LOCK
SPL_AC_MUTEX_OWNER
SPL_AC_GROUP_INFO_GID SPL_AC_GROUP_INFO_GID
SPL_AC_KMEM_CACHE_CREATE_USERCOPY
SPL_AC_WAIT_QUEUE_ENTRY_T
SPL_AC_WAIT_QUEUE_HEAD_ENTRY
]) ])
AC_DEFUN([SPL_AC_MODULE_SYMVERS], [ AC_DEFUN([SPL_AC_MODULE_SYMVERS], [
@ -112,6 +114,7 @@ AC_DEFUN([SPL_AC_KERNEL], [
if test "$kernelsrc" = "NONE"; then if test "$kernelsrc" = "NONE"; then
kernsrcver=NONE kernsrcver=NONE
fi fi
withlinux=yes
fi fi
AC_MSG_RESULT([$kernelsrc]) AC_MSG_RESULT([$kernelsrc])
@ -124,7 +127,7 @@ AC_DEFUN([SPL_AC_KERNEL], [
AC_MSG_CHECKING([kernel build directory]) AC_MSG_CHECKING([kernel build directory])
if test -z "$kernelbuild"; then if test -z "$kernelbuild"; then
if test -e "/lib/modules/$(uname -r)/build"; then if test x$withlinux != xyes -a -e "/lib/modules/$(uname -r)/build"; then
kernelbuild=`readlink -f /lib/modules/$(uname -r)/build` kernelbuild=`readlink -f /lib/modules/$(uname -r)/build`
elif test -d ${kernelsrc}-obj/${target_cpu}/${target_cpu}; then elif test -d ${kernelsrc}-obj/${target_cpu}/${target_cpu}; then
kernelbuild=${kernelsrc}-obj/${target_cpu}/${target_cpu} kernelbuild=${kernelsrc}-obj/${target_cpu}/${target_cpu}
@ -1582,35 +1585,6 @@ AC_DEFUN([SPL_AC_INODE_LOCK], [
EXTRA_KCFLAGS="$tmp_flags" EXTRA_KCFLAGS="$tmp_flags"
]) ])
dnl #
dnl # Check whether mutex has owner with task_struct type.
dnl #
dnl # Note that before Linux 3.0, mutex owner is of type thread_info.
dnl #
dnl # Note that in Linux 3.18, the condition for owner is changed from
dnl # defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP) to
dnl # defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_MUTEX_SPIN_ON_OWNER)
dnl #
AC_DEFUN([SPL_AC_MUTEX_OWNER], [
AC_MSG_CHECKING([whether mutex has owner])
tmp_flags="$EXTRA_KCFLAGS"
EXTRA_KCFLAGS="-Werror"
SPL_LINUX_TRY_COMPILE([
#include <linux/mutex.h>
#include <linux/spinlock.h>
],[
DEFINE_MUTEX(m);
struct task_struct *t __attribute__ ((unused));
t = m.owner;
],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_MUTEX_OWNER, 1, [yes])
],[
AC_MSG_RESULT(no)
])
EXTRA_KCFLAGS="$tmp_flags"
])
dnl # dnl #
dnl # 4.9 API change dnl # 4.9 API change
dnl # group_info changed from 2d array via >blocks to 1d array via ->gid dnl # group_info changed from 2d array via >blocks to 1d array via ->gid
@ -1632,3 +1606,92 @@ AC_DEFUN([SPL_AC_GROUP_INFO_GID], [
]) ])
EXTRA_KCFLAGS="$tmp_flags" EXTRA_KCFLAGS="$tmp_flags"
]) ])
dnl #
dnl # grsecurity API change,
dnl # kmem_cache_create() with SLAB_USERCOPY flag replaced by
dnl # kmem_cache_create_usercopy().
dnl #
AC_DEFUN([SPL_AC_KMEM_CACHE_CREATE_USERCOPY], [
AC_MSG_CHECKING([whether kmem_cache_create_usercopy() exists])
tmp_flags="$EXTRA_KCFLAGS"
EXTRA_KCFLAGS="-Werror"
SPL_LINUX_TRY_COMPILE([
#include <linux/slab.h>
static void ctor(void *foo)
{
// fake ctor
}
],[
struct kmem_cache *skc_linux_cache;
const char *name = "test";
size_t size = 4096;
size_t align = 8;
unsigned long flags = 0;
size_t useroffset = 0;
size_t usersize = size - useroffset;
skc_linux_cache = kmem_cache_create_usercopy(
name, size, align, flags, useroffset, usersize, ctor);
],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_KMEM_CACHE_CREATE_USERCOPY, 1,
[kmem_cache_create_usercopy() exists])
],[
AC_MSG_RESULT(no)
])
EXTRA_KCFLAGS="$tmp_flags"
])
dnl #
dnl # 4.13 API change
dnl # Renamed struct wait_queue -> struct wait_queue_entry.
dnl #
AC_DEFUN([SPL_AC_WAIT_QUEUE_ENTRY_T], [
AC_MSG_CHECKING([whether wait_queue_entry_t exists])
SPL_LINUX_TRY_COMPILE([
#include <linux/wait.h>
],[
wait_queue_entry_t *entry __attribute__ ((unused));
],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_WAIT_QUEUE_ENTRY_T, 1,
[wait_queue_entry_t exists])
],[
AC_MSG_RESULT(no)
])
])
dnl #
dnl # 4.13 API change
dnl # Renamed wait_queue_head::task_list -> wait_queue_head::head
dnl # Renamed wait_queue_entry::task_list -> wait_queue_entry::entry
dnl #
AC_DEFUN([SPL_AC_WAIT_QUEUE_HEAD_ENTRY], [
AC_MSG_CHECKING([whether wq_head->head and wq_entry->entry exist])
SPL_LINUX_TRY_COMPILE([
#include <linux/wait.h>
#ifdef HAVE_WAIT_QUEUE_ENTRY_T
typedef wait_queue_head_t spl_wait_queue_head_t;
typedef wait_queue_entry_t spl_wait_queue_entry_t;
#else
typedef wait_queue_head_t spl_wait_queue_head_t;
typedef wait_queue_t spl_wait_queue_entry_t;
#endif
],[
spl_wait_queue_head_t wq_head;
spl_wait_queue_entry_t wq_entry;
struct list_head *head __attribute__ ((unused));
struct list_head *entry __attribute__ ((unused));
head = &wq_head.head;
entry = &wq_entry.entry;
],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_WAIT_QUEUE_HEAD_ENTRY, 1,
[wq_head->head and wq_entry->entry exist])
],[
AC_MSG_RESULT(no)
])
])

View File

@ -63,6 +63,14 @@ AC_DEFUN([SPL_AC_META], [
if test -n "${_release}"; then if test -n "${_release}"; then
SPL_META_RELEASE=${_release} SPL_META_RELEASE=${_release}
_spl_ac_meta_type="git describe" _spl_ac_meta_type="git describe"
else
_match="${SPL_META_NAME}-${SPL_META_VERSION}-${SPL_META_RELEASE}"
_alias=$(git describe --match=${_match} 2>/dev/null)
_release=$(echo ${_alias}|cut -f3- -d'-'|sed 's/-/_/g')
if test -n "${_release}"; then
SPL_META_RELEASE=${_release}
_spl_ac_meta_type="git describe"
fi
fi fi
fi fi

674
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.63 for spl 0.6.5.11. # Generated by GNU Autoconf 2.63 for spl 0.7.2.
# #
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package. # Identity of this package.
PACKAGE_NAME='spl' PACKAGE_NAME='spl'
PACKAGE_TARNAME='spl' PACKAGE_TARNAME='spl'
PACKAGE_VERSION='0.6.5.11' PACKAGE_VERSION='0.7.2'
PACKAGE_STRING='spl 0.6.5.11' PACKAGE_STRING='spl 0.7.2'
PACKAGE_BUGREPORT='' PACKAGE_BUGREPORT=''
# Factoring default headers for most tests. # Factoring default headers for most tests.
@ -1535,7 +1535,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures spl 0.6.5.11 to adapt to many kinds of systems. \`configure' configures spl 0.7.2 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1606,7 +1606,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of spl 0.6.5.11:";; short | recursive ) echo "Configuration of spl 0.7.2:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1720,7 +1720,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
spl configure 0.6.5.11 spl configure 0.7.2
generated by GNU Autoconf 2.63 generated by GNU Autoconf 2.63
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@ -1734,7 +1734,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by spl $as_me 0.6.5.11, which was It was created by spl $as_me 0.7.2, which was
generated by GNU Autoconf 2.63. Invocation command line was generated by GNU Autoconf 2.63. Invocation command line was
$ $0 $@ $ $0 $@
@ -2187,6 +2187,14 @@ _ACEOF
if test -n "${_release}"; then if test -n "${_release}"; then
SPL_META_RELEASE=${_release} SPL_META_RELEASE=${_release}
_spl_ac_meta_type="git describe" _spl_ac_meta_type="git describe"
else
_match="${SPL_META_NAME}-${SPL_META_VERSION}-${SPL_META_RELEASE}"
_alias=$(git describe --match=${_match} 2>/dev/null)
_release=$(echo ${_alias}|cut -f3- -d'-'|sed 's/-/_/g')
if test -n "${_release}"; then
SPL_META_RELEASE=${_release}
_spl_ac_meta_type="git describe"
fi
fi fi
fi fi
@ -2880,7 +2888,7 @@ fi
# Define the identity of the package. # Define the identity of the package.
PACKAGE='spl' PACKAGE='spl'
VERSION='0.6.5.11' VERSION='0.7.2'
cat >>confdefs.h <<_ACEOF cat >>confdefs.h <<_ACEOF
@ -4757,13 +4765,13 @@ if test "${lt_cv_nm_interface+set}" = set; then
else else
lt_cv_nm_interface="BSD nm" lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext echo "int some_variable = 0;" > conftest.$ac_ext
(eval echo "\"\$as_me:4760: $ac_compile\"" >&5) (eval echo "\"\$as_me:4768: $ac_compile\"" >&5)
(eval "$ac_compile" 2>conftest.err) (eval "$ac_compile" 2>conftest.err)
cat conftest.err >&5 cat conftest.err >&5
(eval echo "\"\$as_me:4763: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval echo "\"\$as_me:4771: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&5 cat conftest.err >&5
(eval echo "\"\$as_me:4766: output\"" >&5) (eval echo "\"\$as_me:4774: output\"" >&5)
cat conftest.out >&5 cat conftest.out >&5
if $GREP 'External.*some_variable' conftest.out > /dev/null; then if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin" lt_cv_nm_interface="MS dumpbin"
@ -5969,7 +5977,7 @@ ia64-*-hpux*)
;; ;;
*-*-irix6*) *-*-irix6*)
# Find out which ABI we are using. # Find out which ABI we are using.
echo '#line 5972 "configure"' > conftest.$ac_ext echo '#line 5980 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5 (eval $ac_compile) 2>&5
ac_status=$? ac_status=$?
@ -7826,11 +7834,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7829: $lt_compile\"" >&5) (eval echo "\"\$as_me:7837: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err) (eval "$lt_compile" 2>conftest.err)
ac_status=$? ac_status=$?
cat conftest.err >&5 cat conftest.err >&5
echo "$as_me:7833: \$? = $ac_status" >&5 echo "$as_me:7841: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output. # So say no if there are warnings other than the usual output.
@ -8165,11 +8173,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:8168: $lt_compile\"" >&5) (eval echo "\"\$as_me:8176: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err) (eval "$lt_compile" 2>conftest.err)
ac_status=$? ac_status=$?
cat conftest.err >&5 cat conftest.err >&5
echo "$as_me:8172: \$? = $ac_status" >&5 echo "$as_me:8180: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output. # So say no if there are warnings other than the usual output.
@ -8270,11 +8278,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:8273: $lt_compile\"" >&5) (eval echo "\"\$as_me:8281: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err) (eval "$lt_compile" 2>out/conftest.err)
ac_status=$? ac_status=$?
cat out/conftest.err >&5 cat out/conftest.err >&5
echo "$as_me:8277: \$? = $ac_status" >&5 echo "$as_me:8285: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext if (exit $ac_status) && test -s out/conftest2.$ac_objext
then then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
@ -8325,11 +8333,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:8328: $lt_compile\"" >&5) (eval echo "\"\$as_me:8336: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err) (eval "$lt_compile" 2>out/conftest.err)
ac_status=$? ac_status=$?
cat out/conftest.err >&5 cat out/conftest.err >&5
echo "$as_me:8332: \$? = $ac_status" >&5 echo "$as_me:8340: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext if (exit $ac_status) && test -s out/conftest2.$ac_objext
then then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
@ -11128,7 +11136,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF cat > conftest.$ac_ext <<_LT_EOF
#line 11131 "configure" #line 11139 "configure"
#include "confdefs.h" #include "confdefs.h"
#if HAVE_DLFCN_H #if HAVE_DLFCN_H
@ -11224,7 +11232,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF cat > conftest.$ac_ext <<_LT_EOF
#line 11227 "configure" #line 11235 "configure"
#include "confdefs.h" #include "confdefs.h"
#if HAVE_DLFCN_H #if HAVE_DLFCN_H
@ -11733,6 +11741,7 @@ $as_echo_n "checking kernel source directory... " >&6; }
if test "$kernelsrc" = "NONE"; then if test "$kernelsrc" = "NONE"; then
kernsrcver=NONE kernsrcver=NONE
fi fi
withlinux=yes
fi fi
{ $as_echo "$as_me:$LINENO: result: $kernelsrc" >&5 { $as_echo "$as_me:$LINENO: result: $kernelsrc" >&5
@ -11752,7 +11761,7 @@ $as_echo "$as_me: error:
{ $as_echo "$as_me:$LINENO: checking kernel build directory" >&5 { $as_echo "$as_me:$LINENO: checking kernel build directory" >&5
$as_echo_n "checking kernel build directory... " >&6; } $as_echo_n "checking kernel build directory... " >&6; }
if test -z "$kernelbuild"; then if test -z "$kernelbuild"; then
if test -e "/lib/modules/$(uname -r)/build"; then if test x$withlinux != xyes -a -e "/lib/modules/$(uname -r)/build"; then
kernelbuild=`readlink -f /lib/modules/$(uname -r)/build` kernelbuild=`readlink -f /lib/modules/$(uname -r)/build`
elif test -d ${kernelsrc}-obj/${target_cpu}/${target_cpu}; then elif test -d ${kernelsrc}-obj/${target_cpu}/${target_cpu}; then
kernelbuild=${kernelsrc}-obj/${target_cpu}/${target_cpu} kernelbuild=${kernelsrc}-obj/${target_cpu}/${target_cpu}
@ -14958,79 +14967,6 @@ $as_echo "no" >&6; }
fi
rm -Rf build
EXTRA_KCFLAGS="$tmp_flags"
{ $as_echo "$as_me:$LINENO: checking whether mutex has owner" >&5
$as_echo_n "checking whether mutex has owner... " >&6; }
tmp_flags="$EXTRA_KCFLAGS"
EXTRA_KCFLAGS="-Werror"
cat confdefs.h - <<_ACEOF >conftest.c
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <linux/mutex.h>
#include <linux/spinlock.h>
int
main (void)
{
DEFINE_MUTEX(m);
struct task_struct *t __attribute__ ((unused));
t = m.owner;
;
return 0;
}
_ACEOF
rm -Rf build && mkdir -p build && touch build/conftest.mod.c
echo "obj-m := conftest.o" >build/Makefile
modpost_flag=''
test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
{ $as_echo "$as_me:$LINENO: result: yes" >&5
$as_echo "yes" >&6; }
cat >>confdefs.h <<\_ACEOF
#define HAVE_MUTEX_OWNER 1
_ACEOF
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ $as_echo "$as_me:$LINENO: result: no" >&5
$as_echo "no" >&6; }
fi fi
rm -Rf build rm -Rf build
@ -15109,6 +15045,237 @@ fi
EXTRA_KCFLAGS="$tmp_flags" EXTRA_KCFLAGS="$tmp_flags"
{ $as_echo "$as_me:$LINENO: checking whether kmem_cache_create_usercopy() exists" >&5
$as_echo_n "checking whether kmem_cache_create_usercopy() exists... " >&6; }
tmp_flags="$EXTRA_KCFLAGS"
EXTRA_KCFLAGS="-Werror"
cat confdefs.h - <<_ACEOF >conftest.c
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <linux/slab.h>
static void ctor(void *foo)
{
// fake ctor
}
int
main (void)
{
struct kmem_cache *skc_linux_cache;
const char *name = "test";
size_t size = 4096;
size_t align = 8;
unsigned long flags = 0;
size_t useroffset = 0;
size_t usersize = size - useroffset;
skc_linux_cache = kmem_cache_create_usercopy(
name, size, align, flags, useroffset, usersize, ctor);
;
return 0;
}
_ACEOF
rm -Rf build && mkdir -p build && touch build/conftest.mod.c
echo "obj-m := conftest.o" >build/Makefile
modpost_flag=''
test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
{ $as_echo "$as_me:$LINENO: result: yes" >&5
$as_echo "yes" >&6; }
cat >>confdefs.h <<\_ACEOF
#define HAVE_KMEM_CACHE_CREATE_USERCOPY 1
_ACEOF
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ $as_echo "$as_me:$LINENO: result: no" >&5
$as_echo "no" >&6; }
fi
rm -Rf build
EXTRA_KCFLAGS="$tmp_flags"
{ $as_echo "$as_me:$LINENO: checking whether wait_queue_entry_t exists" >&5
$as_echo_n "checking whether wait_queue_entry_t exists... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.c
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <linux/wait.h>
int
main (void)
{
wait_queue_entry_t *entry __attribute__ ((unused));
;
return 0;
}
_ACEOF
rm -Rf build && mkdir -p build && touch build/conftest.mod.c
echo "obj-m := conftest.o" >build/Makefile
modpost_flag=''
test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
{ $as_echo "$as_me:$LINENO: result: yes" >&5
$as_echo "yes" >&6; }
cat >>confdefs.h <<\_ACEOF
#define HAVE_WAIT_QUEUE_ENTRY_T 1
_ACEOF
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ $as_echo "$as_me:$LINENO: result: no" >&5
$as_echo "no" >&6; }
fi
rm -Rf build
{ $as_echo "$as_me:$LINENO: checking whether wq_head->head and wq_entry->entry exist" >&5
$as_echo_n "checking whether wq_head->head and wq_entry->entry exist... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.c
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <linux/wait.h>
#ifdef HAVE_WAIT_QUEUE_ENTRY_T
typedef wait_queue_head_t spl_wait_queue_head_t;
typedef wait_queue_entry_t spl_wait_queue_entry_t;
#else
typedef wait_queue_head_t spl_wait_queue_head_t;
typedef wait_queue_t spl_wait_queue_entry_t;
#endif
int
main (void)
{
spl_wait_queue_head_t wq_head;
spl_wait_queue_entry_t wq_entry;
struct list_head *head __attribute__ ((unused));
struct list_head *entry __attribute__ ((unused));
head = &wq_head.head;
entry = &wq_entry.entry;
;
return 0;
}
_ACEOF
rm -Rf build && mkdir -p build && touch build/conftest.mod.c
echo "obj-m := conftest.o" >build/Makefile
modpost_flag=''
test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
{ $as_echo "$as_me:$LINENO: result: yes" >&5
$as_echo "yes" >&6; }
cat >>confdefs.h <<\_ACEOF
#define HAVE_WAIT_QUEUE_HEAD_ENTRY 1
_ACEOF
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ $as_echo "$as_me:$LINENO: result: no" >&5
$as_echo "no" >&6; }
fi
rm -Rf build
;; ;;
user) ;; user) ;;
all) all)
@ -15151,6 +15318,7 @@ $as_echo_n "checking kernel source directory... " >&6; }
if test "$kernelsrc" = "NONE"; then if test "$kernelsrc" = "NONE"; then
kernsrcver=NONE kernsrcver=NONE
fi fi
withlinux=yes
fi fi
{ $as_echo "$as_me:$LINENO: result: $kernelsrc" >&5 { $as_echo "$as_me:$LINENO: result: $kernelsrc" >&5
@ -15170,7 +15338,7 @@ $as_echo "$as_me: error:
{ $as_echo "$as_me:$LINENO: checking kernel build directory" >&5 { $as_echo "$as_me:$LINENO: checking kernel build directory" >&5
$as_echo_n "checking kernel build directory... " >&6; } $as_echo_n "checking kernel build directory... " >&6; }
if test -z "$kernelbuild"; then if test -z "$kernelbuild"; then
if test -e "/lib/modules/$(uname -r)/build"; then if test x$withlinux != xyes -a -e "/lib/modules/$(uname -r)/build"; then
kernelbuild=`readlink -f /lib/modules/$(uname -r)/build` kernelbuild=`readlink -f /lib/modules/$(uname -r)/build`
elif test -d ${kernelsrc}-obj/${target_cpu}/${target_cpu}; then elif test -d ${kernelsrc}-obj/${target_cpu}/${target_cpu}; then
kernelbuild=${kernelsrc}-obj/${target_cpu}/${target_cpu} kernelbuild=${kernelsrc}-obj/${target_cpu}/${target_cpu}
@ -18376,79 +18544,6 @@ $as_echo "no" >&6; }
fi
rm -Rf build
EXTRA_KCFLAGS="$tmp_flags"
{ $as_echo "$as_me:$LINENO: checking whether mutex has owner" >&5
$as_echo_n "checking whether mutex has owner... " >&6; }
tmp_flags="$EXTRA_KCFLAGS"
EXTRA_KCFLAGS="-Werror"
cat confdefs.h - <<_ACEOF >conftest.c
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <linux/mutex.h>
#include <linux/spinlock.h>
int
main (void)
{
DEFINE_MUTEX(m);
struct task_struct *t __attribute__ ((unused));
t = m.owner;
;
return 0;
}
_ACEOF
rm -Rf build && mkdir -p build && touch build/conftest.mod.c
echo "obj-m := conftest.o" >build/Makefile
modpost_flag=''
test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
{ $as_echo "$as_me:$LINENO: result: yes" >&5
$as_echo "yes" >&6; }
cat >>confdefs.h <<\_ACEOF
#define HAVE_MUTEX_OWNER 1
_ACEOF
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ $as_echo "$as_me:$LINENO: result: no" >&5
$as_echo "no" >&6; }
fi fi
rm -Rf build rm -Rf build
@ -18528,6 +18623,237 @@ fi
EXTRA_KCFLAGS="$tmp_flags" EXTRA_KCFLAGS="$tmp_flags"
{ $as_echo "$as_me:$LINENO: checking whether kmem_cache_create_usercopy() exists" >&5
$as_echo_n "checking whether kmem_cache_create_usercopy() exists... " >&6; }
tmp_flags="$EXTRA_KCFLAGS"
EXTRA_KCFLAGS="-Werror"
cat confdefs.h - <<_ACEOF >conftest.c
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <linux/slab.h>
static void ctor(void *foo)
{
// fake ctor
}
int
main (void)
{
struct kmem_cache *skc_linux_cache;
const char *name = "test";
size_t size = 4096;
size_t align = 8;
unsigned long flags = 0;
size_t useroffset = 0;
size_t usersize = size - useroffset;
skc_linux_cache = kmem_cache_create_usercopy(
name, size, align, flags, useroffset, usersize, ctor);
;
return 0;
}
_ACEOF
rm -Rf build && mkdir -p build && touch build/conftest.mod.c
echo "obj-m := conftest.o" >build/Makefile
modpost_flag=''
test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
{ $as_echo "$as_me:$LINENO: result: yes" >&5
$as_echo "yes" >&6; }
cat >>confdefs.h <<\_ACEOF
#define HAVE_KMEM_CACHE_CREATE_USERCOPY 1
_ACEOF
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ $as_echo "$as_me:$LINENO: result: no" >&5
$as_echo "no" >&6; }
fi
rm -Rf build
EXTRA_KCFLAGS="$tmp_flags"
{ $as_echo "$as_me:$LINENO: checking whether wait_queue_entry_t exists" >&5
$as_echo_n "checking whether wait_queue_entry_t exists... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.c
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <linux/wait.h>
int
main (void)
{
wait_queue_entry_t *entry __attribute__ ((unused));
;
return 0;
}
_ACEOF
rm -Rf build && mkdir -p build && touch build/conftest.mod.c
echo "obj-m := conftest.o" >build/Makefile
modpost_flag=''
test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
{ $as_echo "$as_me:$LINENO: result: yes" >&5
$as_echo "yes" >&6; }
cat >>confdefs.h <<\_ACEOF
#define HAVE_WAIT_QUEUE_ENTRY_T 1
_ACEOF
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ $as_echo "$as_me:$LINENO: result: no" >&5
$as_echo "no" >&6; }
fi
rm -Rf build
{ $as_echo "$as_me:$LINENO: checking whether wq_head->head and wq_entry->entry exist" >&5
$as_echo_n "checking whether wq_head->head and wq_entry->entry exist... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.c
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <linux/wait.h>
#ifdef HAVE_WAIT_QUEUE_ENTRY_T
typedef wait_queue_head_t spl_wait_queue_head_t;
typedef wait_queue_entry_t spl_wait_queue_entry_t;
#else
typedef wait_queue_head_t spl_wait_queue_head_t;
typedef wait_queue_t spl_wait_queue_entry_t;
#endif
int
main (void)
{
spl_wait_queue_head_t wq_head;
spl_wait_queue_entry_t wq_entry;
struct list_head *head __attribute__ ((unused));
struct list_head *entry __attribute__ ((unused));
head = &wq_head.head;
entry = &wq_entry.entry;
;
return 0;
}
_ACEOF
rm -Rf build && mkdir -p build && touch build/conftest.mod.c
echo "obj-m := conftest.o" >build/Makefile
modpost_flag=''
test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
{ $as_echo "$as_me:$LINENO: result: yes" >&5
$as_echo "yes" >&6; }
cat >>confdefs.h <<\_ACEOF
#define HAVE_WAIT_QUEUE_HEAD_ENTRY 1
_ACEOF
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ $as_echo "$as_me:$LINENO: result: no" >&5
$as_echo "no" >&6; }
fi
rm -Rf build
;; ;;
srpm) ;; srpm) ;;
*) *)
@ -18559,7 +18885,7 @@ fi
ac_config_files="$ac_config_files Makefile man/Makefile man/man1/Makefile man/man5/Makefile lib/Makefile cmd/Makefile module/Makefile module/spl/Makefile module/splat/Makefile include/Makefile include/fs/Makefile include/linux/Makefile include/rpc/Makefile include/sharefs/Makefile include/sys/Makefile include/sys/fm/Makefile include/sys/fs/Makefile include/sys/sysevent/Makefile include/util/Makefile include/vm/Makefile scripts/Makefile rpm/Makefile rpm/redhat/Makefile rpm/redhat/spl.spec rpm/redhat/spl-kmod.spec rpm/redhat/spl-dkms.spec rpm/generic/Makefile rpm/generic/spl.spec rpm/generic/spl-kmod.spec rpm/generic/spl-dkms.spec spl.release" ac_config_files="$ac_config_files Makefile man/Makefile man/man1/Makefile man/man5/Makefile lib/Makefile cmd/Makefile cmd/splat/Makefile cmd/splslab/Makefile module/Makefile module/spl/Makefile module/splat/Makefile include/Makefile include/fs/Makefile include/linux/Makefile include/rpc/Makefile include/sharefs/Makefile include/sys/Makefile include/sys/fm/Makefile include/sys/fs/Makefile include/sys/sysevent/Makefile include/util/Makefile include/vm/Makefile scripts/Makefile rpm/Makefile rpm/redhat/Makefile rpm/redhat/spl.spec rpm/redhat/spl-kmod.spec rpm/redhat/spl-dkms.spec rpm/generic/Makefile rpm/generic/spl.spec rpm/generic/spl-kmod.spec rpm/generic/spl-dkms.spec spl.release"
cat >confcache <<\_ACEOF cat >confcache <<\_ACEOF
@ -19024,7 +19350,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by spl $as_me 0.6.5.11, which was This file was extended by spl $as_me 0.7.2, which was
generated by GNU Autoconf 2.63. Invocation command line was generated by GNU Autoconf 2.63. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -19087,7 +19413,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\ ac_cs_version="\\
spl config.status 0.6.5.11 spl config.status 0.7.2
configured by $0, generated by GNU Autoconf 2.63, configured by $0, generated by GNU Autoconf 2.63,
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
@ -19474,6 +19800,8 @@ do
"man/man5/Makefile") CONFIG_FILES="$CONFIG_FILES man/man5/Makefile" ;; "man/man5/Makefile") CONFIG_FILES="$CONFIG_FILES man/man5/Makefile" ;;
"lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;; "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;;
"cmd/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/Makefile" ;; "cmd/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/Makefile" ;;
"cmd/splat/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/splat/Makefile" ;;
"cmd/splslab/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/splslab/Makefile" ;;
"module/Makefile") CONFIG_FILES="$CONFIG_FILES module/Makefile" ;; "module/Makefile") CONFIG_FILES="$CONFIG_FILES module/Makefile" ;;
"module/spl/Makefile") CONFIG_FILES="$CONFIG_FILES module/spl/Makefile" ;; "module/spl/Makefile") CONFIG_FILES="$CONFIG_FILES module/spl/Makefile" ;;
"module/splat/Makefile") CONFIG_FILES="$CONFIG_FILES module/splat/Makefile" ;; "module/splat/Makefile") CONFIG_FILES="$CONFIG_FILES module/splat/Makefile" ;;

View File

@ -54,6 +54,8 @@ AC_CONFIG_FILES([
man/man5/Makefile man/man5/Makefile
lib/Makefile lib/Makefile
cmd/Makefile cmd/Makefile
cmd/splat/Makefile
cmd/splslab/Makefile
module/Makefile module/Makefile
module/spl/Makefile module/spl/Makefile
module/splat/Makefile module/splat/Makefile

View File

@ -27,7 +27,10 @@
#include <linux/rwsem.h> #include <linux/rwsem.h>
#ifdef CONFIG_RWSEM_GENERIC_SPINLOCK #if defined(CONFIG_PREEMPT_RT_FULL)
#define SPL_RWSEM_SINGLE_READER_VALUE (1)
#define SPL_RWSEM_SINGLE_WRITER_VALUE (0)
#elif defined(CONFIG_RWSEM_GENERIC_SPINLOCK)
#define SPL_RWSEM_SINGLE_READER_VALUE (1) #define SPL_RWSEM_SINGLE_READER_VALUE (1)
#define SPL_RWSEM_SINGLE_WRITER_VALUE (-1) #define SPL_RWSEM_SINGLE_WRITER_VALUE (-1)
#else #else
@ -36,7 +39,9 @@
#endif #endif
/* Linux 3.16 changed activity to count for rwsem-spinlock */ /* Linux 3.16 changed activity to count for rwsem-spinlock */
#if defined(HAVE_RWSEM_ACTIVITY) #if defined(CONFIG_PREEMPT_RT_FULL)
#define RWSEM_COUNT(sem) sem->read_depth
#elif defined(HAVE_RWSEM_ACTIVITY)
#define RWSEM_COUNT(sem) sem->activity #define RWSEM_COUNT(sem) sem->activity
/* Linux 4.8 changed count to an atomic_long_t for !rwsem-spinlock */ /* Linux 4.8 changed count to an atomic_long_t for !rwsem-spinlock */
#elif defined(HAVE_RWSEM_ATOMIC_LONG_COUNT) #elif defined(HAVE_RWSEM_ATOMIC_LONG_COUNT)

View File

@ -26,6 +26,7 @@
#define _SPL_WAIT_COMPAT_H #define _SPL_WAIT_COMPAT_H
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/wait.h>
#ifndef HAVE_WAIT_ON_BIT_ACTION #ifndef HAVE_WAIT_ON_BIT_ACTION
# define spl_wait_on_bit(word, bit, mode) wait_on_bit(word, bit, mode) # define spl_wait_on_bit(word, bit, mode) wait_on_bit(word, bit, mode)
@ -43,4 +44,12 @@ spl_bit_wait(void *word)
#endif /* HAVE_WAIT_ON_BIT_ACTION */ #endif /* HAVE_WAIT_ON_BIT_ACTION */
#ifdef HAVE_WAIT_QUEUE_ENTRY_T
typedef wait_queue_head_t spl_wait_queue_head_t;
typedef wait_queue_entry_t spl_wait_queue_entry_t;
#else
typedef wait_queue_head_t spl_wait_queue_head_t;
typedef wait_queue_t spl_wait_queue_entry_t;
#endif
#endif /* SPL_WAIT_COMPAT_H */ #endif /* SPL_WAIT_COMPAT_H */

View File

@ -29,6 +29,7 @@ KERNEL_H = \
$(top_srcdir)/include/sys/dirent.h \ $(top_srcdir)/include/sys/dirent.h \
$(top_srcdir)/include/sys/disp.h \ $(top_srcdir)/include/sys/disp.h \
$(top_srcdir)/include/sys/dkio.h \ $(top_srcdir)/include/sys/dkio.h \
$(top_srcdir)/include/sys/dkioc_free_util.h \
$(top_srcdir)/include/sys/dklabel.h \ $(top_srcdir)/include/sys/dklabel.h \
$(top_srcdir)/include/sys/dnlc.h \ $(top_srcdir)/include/sys/dnlc.h \
$(top_srcdir)/include/sys/dumphdr.h \ $(top_srcdir)/include/sys/dumphdr.h \

View File

@ -93,6 +93,7 @@ am__kernel_HEADERS_DIST = $(top_srcdir)/include/sys/acl.h \
$(top_srcdir)/include/sys/dirent.h \ $(top_srcdir)/include/sys/dirent.h \
$(top_srcdir)/include/sys/disp.h \ $(top_srcdir)/include/sys/disp.h \
$(top_srcdir)/include/sys/dkio.h \ $(top_srcdir)/include/sys/dkio.h \
$(top_srcdir)/include/sys/dkioc_free_util.h \
$(top_srcdir)/include/sys/dklabel.h \ $(top_srcdir)/include/sys/dklabel.h \
$(top_srcdir)/include/sys/dnlc.h \ $(top_srcdir)/include/sys/dnlc.h \
$(top_srcdir)/include/sys/dumphdr.h \ $(top_srcdir)/include/sys/dumphdr.h \
@ -415,6 +416,7 @@ KERNEL_H = \
$(top_srcdir)/include/sys/dirent.h \ $(top_srcdir)/include/sys/dirent.h \
$(top_srcdir)/include/sys/disp.h \ $(top_srcdir)/include/sys/disp.h \
$(top_srcdir)/include/sys/dkio.h \ $(top_srcdir)/include/sys/dkio.h \
$(top_srcdir)/include/sys/dkioc_free_util.h \
$(top_srcdir)/include/sys/dklabel.h \ $(top_srcdir)/include/sys/dklabel.h \
$(top_srcdir)/include/sys/dnlc.h \ $(top_srcdir)/include/sys/dnlc.h \
$(top_srcdir)/include/sys/dumphdr.h \ $(top_srcdir)/include/sys/dumphdr.h \

View File

@ -26,6 +26,7 @@
#define _SPL_BYTEORDER_H #define _SPL_BYTEORDER_H
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <sys/isa_defs.h>
#define LE_16(x) cpu_to_le16(x) #define LE_16(x) cpu_to_le16(x)
#define LE_32(x) cpu_to_le32(x) #define LE_32(x) cpu_to_le32(x)
@ -43,4 +44,26 @@
#define BE_IN32(xa) \ #define BE_IN32(xa) \
(((uint32_t)BE_IN16(xa) << 16) | BE_IN16((uint8_t *)(xa)+2)) (((uint32_t)BE_IN16(xa) << 16) | BE_IN16((uint8_t *)(xa)+2))
#ifdef _BIG_ENDIAN
static __inline__ uint64_t
htonll(uint64_t n) {
return (n);
}
static __inline__ uint64_t
ntohll(uint64_t n) {
return (n);
}
#else
static __inline__ uint64_t
htonll(uint64_t n) {
return ((((uint64_t)htonl(n)) << 32) + htonl(n >> 32));
}
static __inline__ uint64_t
ntohll(uint64_t n) {
return ((((uint64_t)ntohl(n)) << 32) + ntohl(n >> 32));
}
#endif
#endif /* SPL_BYTEORDER_H */ #endif /* SPL_BYTEORDER_H */

View File

@ -26,7 +26,7 @@
#define _SPL_CONDVAR_H #define _SPL_CONDVAR_H
#include <linux/module.h> #include <linux/module.h>
#include <linux/wait.h> #include <linux/wait_compat.h>
#include <linux/delay_compat.h> #include <linux/delay_compat.h>
#include <sys/kmem.h> #include <sys/kmem.h>
#include <sys/mutex.h> #include <sys/mutex.h>
@ -41,8 +41,8 @@
typedef struct { typedef struct {
int cv_magic; int cv_magic;
wait_queue_head_t cv_event; spl_wait_queue_head_t cv_event;
wait_queue_head_t cv_destroy; spl_wait_queue_head_t cv_destroy;
atomic_t cv_refs; atomic_t cv_refs;
atomic_t cv_waiters; atomic_t cv_waiters;
kmutex_t *cv_mutex; kmutex_t *cv_mutex;
@ -59,6 +59,8 @@ extern clock_t __cv_timedwait(kcondvar_t *, kmutex_t *, clock_t);
extern clock_t __cv_timedwait_sig(kcondvar_t *, kmutex_t *, clock_t); extern clock_t __cv_timedwait_sig(kcondvar_t *, kmutex_t *, clock_t);
extern clock_t cv_timedwait_hires(kcondvar_t *, kmutex_t *, hrtime_t, extern clock_t cv_timedwait_hires(kcondvar_t *, kmutex_t *, hrtime_t,
hrtime_t res, int flag); hrtime_t res, int flag);
extern clock_t cv_timedwait_sig_hires(kcondvar_t *, kmutex_t *, hrtime_t,
hrtime_t res, int flag);
extern void __cv_signal(kcondvar_t *); extern void __cv_signal(kcondvar_t *);
extern void __cv_broadcast(kcondvar_t *c); extern void __cv_broadcast(kcondvar_t *c);

View File

@ -41,18 +41,6 @@ typedef struct cred cred_t;
#ifdef HAVE_KUIDGID_T #ifdef HAVE_KUIDGID_T
/*
* Linux 3.8+ uses typedefs to redefine uid_t and gid_t. We have to rename the
* typedefs to recover the original types. We then can use them provided that
* we are careful about translating from k{g,u}id_t to the original versions
* and vice versa.
*/
#define uid_t xuid_t
#define gid_t xgid_t
#include <linux/uidgid.h>
#undef uid_t
#undef gid_t
#define KUID_TO_SUID(x) (__kuid_val(x)) #define KUID_TO_SUID(x) (__kuid_val(x))
#define KGID_TO_SGID(x) (__kgid_val(x)) #define KGID_TO_SGID(x) (__kgid_val(x))
#define SUID_TO_KUID(x) (KUIDT_INIT(x)) #define SUID_TO_KUID(x) (KUIDT_INIT(x))

View File

@ -31,11 +31,13 @@
* PANIC() - Panic the node and print message. * PANIC() - Panic the node and print message.
* ASSERT() - Assert X is true, if not panic. * ASSERT() - Assert X is true, if not panic.
* ASSERTV() - Wraps a variable declaration which is only used by ASSERT(). * ASSERTV() - Wraps a variable declaration which is only used by ASSERT().
* ASSERT3B() - Assert boolean X OP Y is true, if not panic.
* ASSERT3S() - Assert signed X OP Y is true, if not panic. * ASSERT3S() - Assert signed X OP Y is true, if not panic.
* ASSERT3U() - Assert unsigned X OP Y is true, if not panic. * ASSERT3U() - Assert unsigned X OP Y is true, if not panic.
* ASSERT3P() - Assert pointer X OP Y is true, if not panic. * ASSERT3P() - Assert pointer X OP Y is true, if not panic.
* ASSERT0() - Assert value is zero, if not panic. * ASSERT0() - Assert value is zero, if not panic.
* VERIFY() - Verify X is true, if not panic. * VERIFY() - Verify X is true, if not panic.
* VERIFY3B() - Verify boolean X OP Y is true, if not panic.
* VERIFY3S() - Verify signed X OP Y is true, if not panic. * VERIFY3S() - Verify signed X OP Y is true, if not panic.
* VERIFY3U() - Verify unsigned X OP Y is true, if not panic. * VERIFY3U() - Verify unsigned X OP Y is true, if not panic.
* VERIFY3P() - Verify pointer X OP Y is true, if not panic. * VERIFY3P() - Verify pointer X OP Y is true, if not panic.
@ -67,6 +69,7 @@ void spl_dumpstack(void);
"failed (" FMT " " #OP " " FMT ")\n", \ "failed (" FMT " " #OP " " FMT ")\n", \
CAST (LEFT), CAST (RIGHT))) CAST (LEFT), CAST (RIGHT)))
#define VERIFY3B(x,y,z) VERIFY3_IMPL(x, y, z, boolean_t, "%d", (boolean_t))
#define VERIFY3S(x,y,z) VERIFY3_IMPL(x, y, z, int64_t, "%lld", (long long)) #define VERIFY3S(x,y,z) VERIFY3_IMPL(x, y, z, int64_t, "%lld", (long long))
#define VERIFY3U(x,y,z) VERIFY3_IMPL(x, y, z, uint64_t, "%llu", \ #define VERIFY3U(x,y,z) VERIFY3_IMPL(x, y, z, uint64_t, "%llu", \
(unsigned long long)) (unsigned long long))
@ -88,6 +91,7 @@ void spl_dumpstack(void);
#define SPL_DEBUG_STR "" #define SPL_DEBUG_STR ""
#define ASSERT(x) ((void)0) #define ASSERT(x) ((void)0)
#define ASSERTV(x) #define ASSERTV(x)
#define ASSERT3B(x,y,z) ((void)0)
#define ASSERT3S(x,y,z) ((void)0) #define ASSERT3S(x,y,z) ((void)0)
#define ASSERT3U(x,y,z) ((void)0) #define ASSERT3U(x,y,z) ((void)0)
#define ASSERT3P(x,y,z) ((void)0) #define ASSERT3P(x,y,z) ((void)0)
@ -103,6 +107,7 @@ void spl_dumpstack(void);
#define SPL_DEBUG_STR " (DEBUG mode)" #define SPL_DEBUG_STR " (DEBUG mode)"
#define ASSERT(cond) VERIFY(cond) #define ASSERT(cond) VERIFY(cond)
#define ASSERTV(x) x #define ASSERTV(x) x
#define ASSERT3B(x,y,z) VERIFY3B(x, y, z)
#define ASSERT3S(x,y,z) VERIFY3S(x, y, z) #define ASSERT3S(x,y,z) VERIFY3S(x, y, z)
#define ASSERT3U(x,y,z) VERIFY3U(x, y, z) #define ASSERT3U(x,y,z) VERIFY3U(x, y, z)
#define ASSERT3P(x,y,z) VERIFY3P(x, y, z) #define ASSERT3P(x,y,z) VERIFY3P(x, y, z)

View File

@ -25,14 +25,16 @@
#ifndef _SPL_DKIO_H #ifndef _SPL_DKIO_H
#define _SPL_DKIO_H #define _SPL_DKIO_H
struct dk_callback { #define DFL_SZ(num_exts) \
void (*dkc_callback)(void *dkc_cookie, int error); (sizeof (dkioc_free_list_t) + (num_exts - 1) * 16)
void *dkc_cookie;
int dkc_flag;
};
#define DKIOC (0x04 << 8) #define DKIOC (0x04 << 8)
#define DKIOCFLUSHWRITECACHE (DKIOC | 34) #define DKIOCFLUSHWRITECACHE (DKIOC|34) /* flush cache to phys medium */
#define DKIOCTRIM (DKIOC | 35)
/*
* ioctl to free space (e.g. SCSI UNMAP) off a disk.
* Pass a dkioc_free_list_t containing a list of extents to be freed.
*/
#define DKIOCFREE (DKIOC|50)
#endif /* _SPL_DKIO_H */ #endif /* _SPL_DKIO_H */

View File

@ -0,0 +1,58 @@
/*****************************************************************************\
* Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
* Copyright (C) 2007 The Regents of the University of California.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Written by Brian Behlendorf <behlendorf1@llnl.gov>.
* UCRL-CODE-235197
*
* This file is part of the SPL, Solaris Porting Layer.
* For details, see <http://zfsonlinux.org/>.
*
* The SPL is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* The SPL 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 the SPL. If not, see <http://www.gnu.org/licenses/>.
\*****************************************************************************/
#ifndef _SPL_DKIOC_UTIL_H
#define _SPL_DKIOC_UTIL_H
#include <sys/dkio.h>
typedef struct dkioc_free_list_ext_s {
uint64_t dfle_start;
uint64_t dfle_length;
} dkioc_free_list_ext_t;
typedef struct dkioc_free_list_s {
uint64_t dfl_flags;
uint64_t dfl_num_exts;
int64_t dfl_offset;
/*
* N.B. this is only an internal debugging API! This is only called
* from debug builds of sd for pre-release checking. Remove before GA!
*/
void (*dfl_ck_func)(uint64_t, uint64_t, void *);
void *dfl_ck_arg;
dkioc_free_list_ext_t dfl_exts[1];
} dkioc_free_list_t;
static inline void dfl_free(dkioc_free_list_t *dfl) {
vmem_free(dfl, DFL_SZ(dfl->dfl_num_exts));
}
static inline dkioc_free_list_t *dfl_alloc(uint64_t dfl_num_exts, int flags) {
return vmem_zalloc(DFL_SZ(dfl_num_exts), flags);
}
#endif /* _SPL_DKIOC_UTIL_H */

View File

@ -44,6 +44,9 @@
#define _LP64 #define _LP64
#endif #endif
#define _ALIGNMENT_REQUIRED 1
/* i386 arch specific defines */ /* i386 arch specific defines */
#elif defined(__i386) || defined(__i386__) #elif defined(__i386) || defined(__i386__)
@ -59,6 +62,8 @@
#define _ILP32 #define _ILP32
#endif #endif
#define _ALIGNMENT_REQUIRED 0
/* powerpc (ppc64) arch specific defines */ /* powerpc (ppc64) arch specific defines */
#elif defined(__powerpc) || defined(__powerpc__) || defined(__powerpc64__) #elif defined(__powerpc) || defined(__powerpc__) || defined(__powerpc64__)
@ -80,6 +85,12 @@
#endif #endif
#endif #endif
/*
* Illumos doesn't define _ALIGNMENT_REQUIRED for PPC, so default to 1
* out of paranoia.
*/
#define _ALIGNMENT_REQUIRED 1
/* arm arch specific defines */ /* arm arch specific defines */
#elif defined(__arm) || defined(__arm__) || defined(__aarch64__) #elif defined(__arm) || defined(__arm__) || defined(__aarch64__)
@ -107,6 +118,12 @@
#define _BIG_ENDIAN #define _BIG_ENDIAN
#endif #endif
/*
* Illumos doesn't define _ALIGNMENT_REQUIRED for ARM, so default to 1
* out of paranoia.
*/
#define _ALIGNMENT_REQUIRED 1
/* sparc arch specific defines */ /* sparc arch specific defines */
#elif defined(__sparc) || defined(__sparc__) #elif defined(__sparc) || defined(__sparc__)
@ -130,6 +147,7 @@
#define _BIG_ENDIAN #define _BIG_ENDIAN
#define _SUNOS_VTOC_16 #define _SUNOS_VTOC_16
#define _ALIGNMENT_REQUIRED 1
/* s390 arch specific defines */ /* s390 arch specific defines */
#elif defined(__s390__) #elif defined(__s390__)
@ -145,6 +163,12 @@
#define _BIG_ENDIAN #define _BIG_ENDIAN
/*
* Illumos doesn't define _ALIGNMENT_REQUIRED for s390, so default to 1
* out of paranoia.
*/
#define _ALIGNMENT_REQUIRED 1
/* MIPS arch specific defines */ /* MIPS arch specific defines */
#elif defined(__mips__) #elif defined(__mips__)
@ -162,6 +186,12 @@
#define _SUNOS_VTOC_16 #define _SUNOS_VTOC_16
/*
* Illumos doesn't define _ALIGNMENT_REQUIRED for MIPS, so default to 1
* out of paranoia.
*/
#define _ALIGNMENT_REQUIRED 1
#else #else
/* /*
* Currently supported: * Currently supported:

View File

@ -193,7 +193,7 @@ typedef struct spl_kmem_cache {
struct list_head skc_partial_list; /* Partially alloc'ed */ struct list_head skc_partial_list; /* Partially alloc'ed */
struct rb_root skc_emergency_tree; /* Min sized objects */ struct rb_root skc_emergency_tree; /* Min sized objects */
spinlock_t skc_lock; /* Cache lock */ spinlock_t skc_lock; /* Cache lock */
wait_queue_head_t skc_waitq; /* Allocation waiters */ spl_wait_queue_head_t skc_waitq; /* Allocation waiters */
uint64_t skc_slab_fail; /* Slab alloc failures */ uint64_t skc_slab_fail; /* Slab alloc failures */
uint64_t skc_slab_create; /* Slab creates */ uint64_t skc_slab_create; /* Slab creates */
uint64_t skc_slab_destroy; /* Slab destroys */ uint64_t skc_slab_destroy; /* Slab destroys */

View File

@ -35,8 +35,8 @@ typedef struct _buf buf_t;
extern struct _buf *kobj_open_file(const char *name); extern struct _buf *kobj_open_file(const char *name);
extern void kobj_close_file(struct _buf *file); extern void kobj_close_file(struct _buf *file);
extern int kobj_read_file(struct _buf *file, char *buf, extern int kobj_read_file(struct _buf *file, char *buf, unsigned size,
ssize_t size, offset_t off); unsigned off);
extern int kobj_get_filesize(struct _buf *file, uint64_t *size); extern int kobj_get_filesize(struct _buf *file, uint64_t *size);
#endif /* SPL_KOBJ_H */ #endif /* SPL_KOBJ_H */

View File

@ -28,20 +28,22 @@
#include <sys/types.h> #include <sys/types.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/compiler_compat.h> #include <linux/compiler_compat.h>
#include <linux/lockdep.h>
typedef enum { typedef enum {
MUTEX_DEFAULT = 0, MUTEX_DEFAULT = 0,
MUTEX_SPIN = 1, MUTEX_SPIN = 1,
MUTEX_ADAPTIVE = 2 MUTEX_ADAPTIVE = 2,
MUTEX_NOLOCKDEP = 3
} kmutex_type_t; } kmutex_type_t;
typedef struct { typedef struct {
struct mutex m_mutex; struct mutex m_mutex;
spinlock_t m_lock; /* used for serializing mutex_exit */ spinlock_t m_lock; /* used for serializing mutex_exit */
#ifndef HAVE_MUTEX_OWNER
/* only when kernel doesn't have owner */
kthread_t *m_owner; kthread_t *m_owner;
#endif #ifdef CONFIG_LOCKDEP
kmutex_type_t m_type;
#endif /* CONFIG_LOCKDEP */
} kmutex_t; } kmutex_t;
#define MUTEX(mp) (&((mp)->m_mutex)) #define MUTEX(mp) (&((mp)->m_mutex))
@ -49,32 +51,44 @@ typedef struct {
static inline void static inline void
spl_mutex_set_owner(kmutex_t *mp) spl_mutex_set_owner(kmutex_t *mp)
{ {
/*
* kernel will handle its owner, so we don't need to do anything if it
* is defined.
*/
#ifndef HAVE_MUTEX_OWNER
mp->m_owner = current; mp->m_owner = current;
#endif
} }
static inline void static inline void
spl_mutex_clear_owner(kmutex_t *mp) spl_mutex_clear_owner(kmutex_t *mp)
{ {
#ifndef HAVE_MUTEX_OWNER
mp->m_owner = NULL; mp->m_owner = NULL;
#endif
} }
#ifdef HAVE_MUTEX_OWNER
#define mutex_owner(mp) (ACCESS_ONCE(MUTEX(mp)->owner))
#else
#define mutex_owner(mp) (ACCESS_ONCE((mp)->m_owner)) #define mutex_owner(mp) (ACCESS_ONCE((mp)->m_owner))
#endif
#define mutex_owned(mp) (mutex_owner(mp) == current) #define mutex_owned(mp) (mutex_owner(mp) == current)
#define MUTEX_HELD(mp) mutex_owned(mp) #define MUTEX_HELD(mp) mutex_owned(mp)
#define MUTEX_NOT_HELD(mp) (!MUTEX_HELD(mp)) #define MUTEX_NOT_HELD(mp) (!MUTEX_HELD(mp))
#ifdef CONFIG_LOCKDEP
static inline void
spl_mutex_set_type(kmutex_t *mp, kmutex_type_t type)
{
mp->m_type = type;
}
static inline void
spl_mutex_lockdep_off_maybe(kmutex_t *mp) \
{ \
if (mp && mp->m_type == MUTEX_NOLOCKDEP) \
lockdep_off(); \
}
static inline void
spl_mutex_lockdep_on_maybe(kmutex_t *mp) \
{ \
if (mp && mp->m_type == MUTEX_NOLOCKDEP) \
lockdep_on(); \
}
#else /* CONFIG_LOCKDEP */
#define spl_mutex_set_type(mp, type)
#define spl_mutex_lockdep_off_maybe(mp)
#define spl_mutex_lockdep_on_maybe(mp)
#endif /* CONFIG_LOCKDEP */
/* /*
* The following functions must be a #define and not static inline. * The following functions must be a #define and not static inline.
* This ensures that the native linux mutex functions (lock/unlock) * This ensures that the native linux mutex functions (lock/unlock)
@ -85,11 +99,12 @@ spl_mutex_clear_owner(kmutex_t *mp)
#define mutex_init(mp, name, type, ibc) \ #define mutex_init(mp, name, type, ibc) \
{ \ { \
static struct lock_class_key __key; \ static struct lock_class_key __key; \
ASSERT(type == MUTEX_DEFAULT); \ ASSERT(type == MUTEX_DEFAULT || type == MUTEX_NOLOCKDEP); \
\ \
__mutex_init(MUTEX(mp), (name) ? (#name) : (#mp), &__key); \ __mutex_init(MUTEX(mp), (name) ? (#name) : (#mp), &__key); \
spin_lock_init(&(mp)->m_lock); \ spin_lock_init(&(mp)->m_lock); \
spl_mutex_clear_owner(mp); \ spl_mutex_clear_owner(mp); \
spl_mutex_set_type(mp, type); \
} }
#undef mutex_destroy #undef mutex_destroy
@ -102,8 +117,10 @@ spl_mutex_clear_owner(kmutex_t *mp)
({ \ ({ \
int _rc_; \ int _rc_; \
\ \
spl_mutex_lockdep_off_maybe(mp); \
if ((_rc_ = mutex_trylock(MUTEX(mp))) == 1) \ if ((_rc_ = mutex_trylock(MUTEX(mp))) == 1) \
spl_mutex_set_owner(mp); \ spl_mutex_set_owner(mp); \
spl_mutex_lockdep_on_maybe(mp); \
\ \
_rc_; \ _rc_; \
}) })
@ -112,14 +129,18 @@ spl_mutex_clear_owner(kmutex_t *mp)
#define mutex_enter_nested(mp, subclass) \ #define mutex_enter_nested(mp, subclass) \
{ \ { \
ASSERT3P(mutex_owner(mp), !=, current); \ ASSERT3P(mutex_owner(mp), !=, current); \
spl_mutex_lockdep_off_maybe(mp); \
mutex_lock_nested(MUTEX(mp), (subclass)); \ mutex_lock_nested(MUTEX(mp), (subclass)); \
spl_mutex_lockdep_on_maybe(mp); \
spl_mutex_set_owner(mp); \ spl_mutex_set_owner(mp); \
} }
#else /* CONFIG_DEBUG_LOCK_ALLOC */ #else /* CONFIG_DEBUG_LOCK_ALLOC */
#define mutex_enter_nested(mp, subclass) \ #define mutex_enter_nested(mp, subclass) \
{ \ { \
ASSERT3P(mutex_owner(mp), !=, current); \ ASSERT3P(mutex_owner(mp), !=, current); \
spl_mutex_lockdep_off_maybe(mp); \
mutex_lock(MUTEX(mp)); \ mutex_lock(MUTEX(mp)); \
spl_mutex_lockdep_on_maybe(mp); \
spl_mutex_set_owner(mp); \ spl_mutex_set_owner(mp); \
} }
#endif /* CONFIG_DEBUG_LOCK_ALLOC */ #endif /* CONFIG_DEBUG_LOCK_ALLOC */
@ -147,10 +168,13 @@ spl_mutex_clear_owner(kmutex_t *mp)
*/ */
#define mutex_exit(mp) \ #define mutex_exit(mp) \
{ \ { \
spin_lock(&(mp)->m_lock); \
spl_mutex_clear_owner(mp); \ spl_mutex_clear_owner(mp); \
spin_lock(&(mp)->m_lock); \
spl_mutex_lockdep_off_maybe(mp); \
mutex_unlock(MUTEX(mp)); \ mutex_unlock(MUTEX(mp)); \
spl_mutex_lockdep_on_maybe(mp); \
spin_unlock(&(mp)->m_lock); \ spin_unlock(&(mp)->m_lock); \
/* NOTE: do not dereference mp after this point */ \
} }
int spl_mutex_init(void); int spl_mutex_init(void);

View File

@ -35,11 +35,6 @@ random_get_bytes(uint8_t *ptr, size_t len)
return 0; return 0;
} }
static __inline__ int extern int random_get_pseudo_bytes(uint8_t *ptr, size_t len);
random_get_pseudo_bytes(uint8_t *ptr, size_t len)
{
get_random_bytes((void *)ptr,(int)len);
return 0;
}
#endif /* _SPL_RANDOM_H */ #endif /* _SPL_RANDOM_H */

View File

@ -30,56 +30,87 @@
#include <linux/rwsem_compat.h> #include <linux/rwsem_compat.h>
typedef enum { typedef enum {
RW_DRIVER = 2, RW_DRIVER = 2,
RW_DEFAULT = 4 RW_DEFAULT = 4,
RW_NOLOCKDEP = 5
} krw_type_t; } krw_type_t;
typedef enum { typedef enum {
RW_NONE = 0, RW_NONE = 0,
RW_WRITER = 1, RW_WRITER = 1,
RW_READER = 2 RW_READER = 2
} krw_t; } krw_t;
/*
* If CONFIG_RWSEM_SPIN_ON_OWNER is defined, rw_semaphore will have an owner
* field, so we don't need our own.
*/
typedef struct { typedef struct {
struct rw_semaphore rw_rwlock; struct rw_semaphore rw_rwlock;
kthread_t *rw_owner; #ifndef CONFIG_RWSEM_SPIN_ON_OWNER
kthread_t *rw_owner;
#endif
#ifdef CONFIG_LOCKDEP
krw_type_t rw_type;
#endif /* CONFIG_LOCKDEP */
} krwlock_t; } krwlock_t;
#define SEM(rwp) ((struct rw_semaphore *)(rwp)) #define SEM(rwp) (&(rwp)->rw_rwlock)
static inline void static inline void
spl_rw_set_owner(krwlock_t *rwp) spl_rw_set_owner(krwlock_t *rwp)
{ {
unsigned long flags; /*
* If CONFIG_RWSEM_SPIN_ON_OWNER is defined, down_write, up_write,
spl_rwsem_lock_irqsave(&SEM(rwp)->wait_lock, flags); * downgrade_write and __init_rwsem will set/clear owner for us.
rwp->rw_owner = current; */
spl_rwsem_unlock_irqrestore(&SEM(rwp)->wait_lock, flags); #ifndef CONFIG_RWSEM_SPIN_ON_OWNER
rwp->rw_owner = current;
#endif
} }
static inline void static inline void
spl_rw_clear_owner(krwlock_t *rwp) spl_rw_clear_owner(krwlock_t *rwp)
{ {
unsigned long flags; #ifndef CONFIG_RWSEM_SPIN_ON_OWNER
rwp->rw_owner = NULL;
spl_rwsem_lock_irqsave(&SEM(rwp)->wait_lock, flags); #endif
rwp->rw_owner = NULL;
spl_rwsem_unlock_irqrestore(&SEM(rwp)->wait_lock, flags);
} }
static inline kthread_t * static inline kthread_t *
rw_owner(krwlock_t *rwp) rw_owner(krwlock_t *rwp)
{ {
unsigned long flags; #ifdef CONFIG_RWSEM_SPIN_ON_OWNER
kthread_t *owner; return SEM(rwp)->owner;
#else
spl_rwsem_lock_irqsave(&SEM(rwp)->wait_lock, flags); return rwp->rw_owner;
owner = rwp->rw_owner; #endif
spl_rwsem_unlock_irqrestore(&SEM(rwp)->wait_lock, flags);
return owner;
} }
#ifdef CONFIG_LOCKDEP
static inline void
spl_rw_set_type(krwlock_t *rwp, krw_type_t type)
{
rwp->rw_type = type;
}
static inline void
spl_rw_lockdep_off_maybe(krwlock_t *rwp) \
{ \
if (rwp && rwp->rw_type == RW_NOLOCKDEP) \
lockdep_off(); \
}
static inline void
spl_rw_lockdep_on_maybe(krwlock_t *rwp) \
{ \
if (rwp && rwp->rw_type == RW_NOLOCKDEP) \
lockdep_on(); \
}
#else /* CONFIG_LOCKDEP */
#define spl_rw_set_type(rwp, type)
#define spl_rw_lockdep_off_maybe(rwp)
#define spl_rw_lockdep_on_maybe(rwp)
#endif /* CONFIG_LOCKDEP */
static inline int static inline int
RW_READ_HELD(krwlock_t *rwp) RW_READ_HELD(krwlock_t *rwp)
{ {
@ -94,7 +125,7 @@ RW_READ_HELD(krwlock_t *rwp)
static inline int static inline int
RW_WRITE_HELD(krwlock_t *rwp) RW_WRITE_HELD(krwlock_t *rwp)
{ {
return (spl_rwsem_is_locked(SEM(rwp)) && rw_owner(rwp) == current); return (rw_owner(rwp) == current);
} }
static inline int static inline int
@ -109,77 +140,79 @@ RW_LOCK_HELD(krwlock_t *rwp)
* will be correctly located in the users code which is important * will be correctly located in the users code which is important
* for the built in kernel lock analysis tools * for the built in kernel lock analysis tools
*/ */
#define rw_init(rwp, name, type, arg) \ #define rw_init(rwp, name, type, arg) \
({ \ ({ \
static struct lock_class_key __key; \ static struct lock_class_key __key; \
\ ASSERT(type == RW_DEFAULT || type == RW_NOLOCKDEP); \
__init_rwsem(SEM(rwp), #rwp, &__key); \ \
spl_rw_clear_owner(rwp); \ __init_rwsem(SEM(rwp), #rwp, &__key); \
spl_rw_clear_owner(rwp); \
spl_rw_set_type(rwp, type); \
}) })
#define rw_destroy(rwp) \ #define rw_destroy(rwp) \
({ \ ({ \
VERIFY(!RW_LOCK_HELD(rwp)); \ VERIFY(!RW_LOCK_HELD(rwp)); \
}) })
#define rw_tryenter(rwp, rw) \ #define rw_tryenter(rwp, rw) \
({ \ ({ \
int _rc_ = 0; \ int _rc_ = 0; \
\ \
switch (rw) { \ spl_rw_lockdep_off_maybe(rwp); \
case RW_READER: \ switch (rw) { \
_rc_ = down_read_trylock(SEM(rwp)); \ case RW_READER: \
break; \ _rc_ = down_read_trylock(SEM(rwp)); \
case RW_WRITER: \ break; \
if ((_rc_ = down_write_trylock(SEM(rwp)))) \ case RW_WRITER: \
spl_rw_set_owner(rwp); \ if ((_rc_ = down_write_trylock(SEM(rwp)))) \
break; \ spl_rw_set_owner(rwp); \
default: \ break; \
VERIFY(0); \ default: \
} \ VERIFY(0); \
_rc_; \ } \
spl_rw_lockdep_on_maybe(rwp); \
_rc_; \
}) })
#define rw_enter(rwp, rw) \ #define rw_enter(rwp, rw) \
({ \ ({ \
switch (rw) { \ spl_rw_lockdep_off_maybe(rwp); \
case RW_READER: \ switch (rw) { \
down_read(SEM(rwp)); \ case RW_READER: \
break; \ down_read(SEM(rwp)); \
case RW_WRITER: \ break; \
down_write(SEM(rwp)); \ case RW_WRITER: \
spl_rw_set_owner(rwp); \ down_write(SEM(rwp)); \
break; \ spl_rw_set_owner(rwp); \
default: \ break; \
VERIFY(0); \ default: \
} \ VERIFY(0); \
} \
spl_rw_lockdep_on_maybe(rwp); \
}) })
#define rw_exit(rwp) \ #define rw_exit(rwp) \
({ \ ({ \
if (RW_WRITE_HELD(rwp)) { \ spl_rw_lockdep_off_maybe(rwp); \
spl_rw_clear_owner(rwp); \ if (RW_WRITE_HELD(rwp)) { \
up_write(SEM(rwp)); \ spl_rw_clear_owner(rwp); \
} else { \ up_write(SEM(rwp)); \
ASSERT(RW_READ_HELD(rwp)); \ } else { \
up_read(SEM(rwp)); \ ASSERT(RW_READ_HELD(rwp)); \
} \ up_read(SEM(rwp)); \
} \
spl_rw_lockdep_on_maybe(rwp); \
}) })
#define rw_downgrade(rwp) \ #define rw_downgrade(rwp) \
({ \ ({ \
spl_rw_clear_owner(rwp); \ spl_rw_lockdep_off_maybe(rwp); \
downgrade_write(SEM(rwp)); \ spl_rw_clear_owner(rwp); \
downgrade_write(SEM(rwp)); \
spl_rw_lockdep_on_maybe(rwp); \
}) })
/*
* This implementation of rw_tryupgrade() behaves slightly differently
* from its counterparts on other platforms. It drops the RW_READER lock
* and then acquires the RW_WRITER lock leaving a small window where no
* lock is held. On other platforms the lock is never released during
* the upgrade process. This is necessary under Linux because the kernel
* does not provide an upgrade function.
*/
#define rw_tryupgrade(rwp) \ #define rw_tryupgrade(rwp) \
({ \ ({ \
int _rc_ = 0; \ int _rc_ = 0; \
@ -187,8 +220,10 @@ RW_LOCK_HELD(krwlock_t *rwp)
if (RW_WRITE_HELD(rwp)) { \ if (RW_WRITE_HELD(rwp)) { \
_rc_ = 1; \ _rc_ = 1; \
} else { \ } else { \
spl_rw_lockdep_off_maybe(rwp); \
if ((_rc_ = rwsem_tryupgrade(SEM(rwp)))) \ if ((_rc_ = rwsem_tryupgrade(SEM(rwp)))) \
spl_rw_set_owner(rwp); \ spl_rw_set_owner(rwp); \
spl_rw_lockdep_on_maybe(rwp); \
} \ } \
_rc_; \ _rc_; \
}) })

View File

@ -34,23 +34,4 @@
#define SECTOR_SIZE 512 #define SECTOR_SIZE 512
typedef struct modlinkage {
int ml_rev;
struct modlfs *ml_modlfs;
struct modldrv *ml_modldrv;
major_t ml_major;
unsigned ml_minors;
void *pad1;
} modlinkage_t;
typedef struct ldi_ident {
char li_modname[MAXNAMELEN];
dev_t li_dev;
} *ldi_ident_t;
typedef struct block_device *ldi_handle_t;
extern int ldi_ident_from_mod(struct modlinkage *modlp, ldi_ident_t *lip);
extern void ldi_ident_release(ldi_ident_t li);
#endif /* SPL_SUNLDI_H */ #endif /* SPL_SUNLDI_H */

View File

@ -32,6 +32,7 @@
#include <sys/varargs.h> #include <sys/varargs.h>
#include <sys/zone.h> #include <sys/zone.h>
#include <sys/signal.h> #include <sys/signal.h>
#include <asm/page.h>
#ifdef HAVE_SCHED_RT_HEADER #ifdef HAVE_SCHED_RT_HEADER
#include <linux/sched/rt.h> #include <linux/sched/rt.h>
@ -111,6 +112,10 @@
#define PAGESIZE PAGE_SIZE #define PAGESIZE PAGE_SIZE
#endif #endif
#ifndef PAGESHIFT
#define PAGESHIFT PAGE_SHIFT
#endif
/* from Solaris sys/byteorder.h */ /* from Solaris sys/byteorder.h */
#define BSWAP_8(x) ((x) & 0xff) #define BSWAP_8(x) ((x) & 0xff)
#define BSWAP_16(x) ((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8)) #define BSWAP_16(x) ((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8))
@ -158,6 +163,9 @@ extern uint32_t zone_get_hostid(void *zone);
extern void spl_setup(void); extern void spl_setup(void);
extern void spl_cleanup(void); extern void spl_cleanup(void);
#define highbit(x) __fls(x)
#define lowbit(x) __ffs(x)
#define highbit64(x) fls64(x) #define highbit64(x) fls64(x)
#define makedevice(maj,min) makedev(maj,min) #define makedevice(maj,min) makedev(maj,min)

View File

@ -1,4 +1,4 @@
/*****************************************************************************\ /*
* Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC. * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
* Copyright (C) 2007 The Regents of the University of California. * Copyright (C) 2007 The Regents of the University of California.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
@ -20,72 +20,91 @@
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License along
* with the SPL. If not, see <http://www.gnu.org/licenses/>. * with the SPL. If not, see <http://www.gnu.org/licenses/>.
\*****************************************************************************/ */
#ifndef _SPL_TASKQ_H #ifndef _SPL_TASKQ_H
#define _SPL_TASKQ_H #define _SPL_TASKQ_H
#include <linux/module.h> #include <linux/module.h>
#include <linux/gfp.h> #include <linux/gfp.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/wait_compat.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/thread.h> #include <sys/thread.h>
#include <sys/rwlock.h>
#define TASKQ_NAMELEN 31 #define TASKQ_NAMELEN 31
#define TASKQ_PREPOPULATE 0x00000001 #define TASKQ_PREPOPULATE 0x00000001
#define TASKQ_CPR_SAFE 0x00000002 #define TASKQ_CPR_SAFE 0x00000002
#define TASKQ_DYNAMIC 0x00000004 #define TASKQ_DYNAMIC 0x00000004
#define TASKQ_THREADS_CPU_PCT 0x00000008 #define TASKQ_THREADS_CPU_PCT 0x00000008
#define TASKQ_DC_BATCH 0x00000010 #define TASKQ_DC_BATCH 0x00000010
#define TASKQ_ACTIVE 0x80000000 #define TASKQ_ACTIVE 0x80000000
/* /*
* Flags for taskq_dispatch. TQ_SLEEP/TQ_NOSLEEP should be same as * Flags for taskq_dispatch. TQ_SLEEP/TQ_NOSLEEP should be same as
* KM_SLEEP/KM_NOSLEEP. TQ_NOQUEUE/TQ_NOALLOC are set particularly * KM_SLEEP/KM_NOSLEEP. TQ_NOQUEUE/TQ_NOALLOC are set particularly
* large so as not to conflict with already used GFP_* defines. * large so as not to conflict with already used GFP_* defines.
*/ */
#define TQ_SLEEP 0x00000000 #define TQ_SLEEP 0x00000000
#define TQ_NOSLEEP 0x00000001 #define TQ_NOSLEEP 0x00000001
#define TQ_PUSHPAGE 0x00000002 #define TQ_PUSHPAGE 0x00000002
#define TQ_NOQUEUE 0x01000000 #define TQ_NOQUEUE 0x01000000
#define TQ_NOALLOC 0x02000000 #define TQ_NOALLOC 0x02000000
#define TQ_NEW 0x04000000 #define TQ_NEW 0x04000000
#define TQ_FRONT 0x08000000 #define TQ_FRONT 0x08000000
/*
* Reserved taskqid values.
*/
#define TASKQID_INVALID ((taskqid_t)0)
#define TASKQID_INITIAL ((taskqid_t)1)
/*
* spin_lock(lock) and spin_lock_nested(lock,0) are equivalent,
* so TQ_LOCK_DYNAMIC must not evaluate to 0
*/
typedef enum tq_lock_role {
TQ_LOCK_GENERAL = 0,
TQ_LOCK_DYNAMIC = 1,
} tq_lock_role_t;
typedef unsigned long taskqid_t; typedef unsigned long taskqid_t;
typedef void (task_func_t)(void *); typedef void (task_func_t)(void *);
typedef struct taskq { typedef struct taskq {
spinlock_t tq_lock; /* protects taskq_t */ spinlock_t tq_lock; /* protects taskq_t */
unsigned long tq_lock_flags; /* interrupt state */ char *tq_name; /* taskq name */
char *tq_name; /* taskq name */ int tq_instance; /* instance of tq_name */
struct list_head tq_thread_list;/* list of all threads */ struct list_head tq_thread_list; /* list of all threads */
struct list_head tq_active_list;/* list of active threads */ struct list_head tq_active_list; /* list of active threads */
int tq_nactive; /* # of active threads */ int tq_nactive; /* # of active threads */
int tq_nthreads; /* # of existing threads */ int tq_nthreads; /* # of existing threads */
int tq_nspawn; /* # of threads being spawned */ int tq_nspawn; /* # of threads being spawned */
int tq_maxthreads; /* # of threads maximum */ int tq_maxthreads; /* # of threads maximum */
int tq_pri; /* priority */ int tq_pri; /* priority */
int tq_minalloc; /* min task_t pool size */ int tq_minalloc; /* min taskq_ent_t pool size */
int tq_maxalloc; /* max task_t pool size */ int tq_maxalloc; /* max taskq_ent_t pool size */
int tq_nalloc; /* cur task_t pool size */ int tq_nalloc; /* cur taskq_ent_t pool size */
uint_t tq_flags; /* flags */ uint_t tq_flags; /* flags */
taskqid_t tq_next_id; /* next pend/work id */ taskqid_t tq_next_id; /* next pend/work id */
taskqid_t tq_lowest_id; /* lowest pend/work id */ taskqid_t tq_lowest_id; /* lowest pend/work id */
struct list_head tq_free_list; /* free task_t's */ struct list_head tq_free_list; /* free taskq_ent_t's */
struct list_head tq_pend_list; /* pending task_t's */ struct list_head tq_pend_list; /* pending taskq_ent_t's */
struct list_head tq_prio_list; /* priority pending task_t's */ struct list_head tq_prio_list; /* priority pending taskq_ent_t's */
struct list_head tq_delay_list; /* delayed task_t's */ struct list_head tq_delay_list; /* delayed taskq_ent_t's */
wait_queue_head_t tq_work_waitq; /* new work waitq */ struct list_head tq_taskqs; /* all taskq_t's */
wait_queue_head_t tq_wait_waitq; /* wait waitq */ spl_wait_queue_head_t tq_work_waitq; /* new work waitq */
spl_wait_queue_head_t tq_wait_waitq; /* wait waitq */
tq_lock_role_t tq_lock_class; /* class when taking tq_lock */
} taskq_t; } taskq_t;
typedef struct taskq_ent { typedef struct taskq_ent {
spinlock_t tqent_lock; spinlock_t tqent_lock;
wait_queue_head_t tqent_waitq; spl_wait_queue_head_t tqent_waitq;
struct timer_list tqent_timer; struct timer_list tqent_timer;
struct list_head tqent_list; struct list_head tqent_list;
taskqid_t tqent_id; taskqid_t tqent_id;
@ -93,10 +112,11 @@ typedef struct taskq_ent {
void *tqent_arg; void *tqent_arg;
taskq_t *tqent_taskq; taskq_t *tqent_taskq;
uintptr_t tqent_flags; uintptr_t tqent_flags;
unsigned long tqent_birth;
} taskq_ent_t; } taskq_ent_t;
#define TQENT_FLAG_PREALLOC 0x1 #define TQENT_FLAG_PREALLOC 0x1
#define TQENT_FLAG_CANCEL 0x2 #define TQENT_FLAG_CANCEL 0x2
typedef struct taskq_thread { typedef struct taskq_thread {
struct list_head tqt_thread_list; struct list_head tqt_thread_list;
@ -110,6 +130,12 @@ typedef struct taskq_thread {
/* Global system-wide dynamic task queue available for all consumers */ /* Global system-wide dynamic task queue available for all consumers */
extern taskq_t *system_taskq; extern taskq_t *system_taskq;
/* Global dynamic task queue for long delay */
extern taskq_t *system_delay_taskq;
/* List of all taskqs */
extern struct list_head tq_list;
extern struct rw_semaphore tq_list_sem;
extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t); extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t);
extern taskqid_t taskq_dispatch_delay(taskq_t *, task_func_t, void *, extern taskqid_t taskq_dispatch_delay(taskq_t *, task_func_t, void *,
@ -124,11 +150,11 @@ extern void taskq_wait_id(taskq_t *, taskqid_t);
extern void taskq_wait_outstanding(taskq_t *, taskqid_t); extern void taskq_wait_outstanding(taskq_t *, taskqid_t);
extern void taskq_wait(taskq_t *); extern void taskq_wait(taskq_t *);
extern int taskq_cancel_id(taskq_t *, taskqid_t); extern int taskq_cancel_id(taskq_t *, taskqid_t);
extern int taskq_member(taskq_t *, void *); extern int taskq_member(taskq_t *, kthread_t *);
#define taskq_create_proc(name, nthreads, pri, min, max, proc, flags) \ #define taskq_create_proc(name, nthreads, pri, min, max, proc, flags) \
taskq_create(name, nthreads, pri, min, max, flags) taskq_create(name, nthreads, pri, min, max, flags)
#define taskq_create_sysdc(name, nthreads, min, max, proc, dc, flags) \ #define taskq_create_sysdc(name, nthreads, min, max, proc, dc, flags) \
taskq_create(name, nthreads, maxclsyspri, min, max, flags) taskq_create(name, nthreads, maxclsyspri, min, max, flags)
int spl_taskq_init(void); int spl_taskq_init(void);

View File

@ -46,6 +46,12 @@
#define MSEC2NSEC(m) ((hrtime_t)(m) * (NANOSEC / MILLISEC)) #define MSEC2NSEC(m) ((hrtime_t)(m) * (NANOSEC / MILLISEC))
#define NSEC2MSEC(n) ((n) / (NANOSEC / MILLISEC)) #define NSEC2MSEC(n) ((n) / (NANOSEC / MILLISEC))
#define USEC2NSEC(m) ((hrtime_t)(m) * (NANOSEC / MICROSEC))
#define NSEC2USEC(n) ((n) / (NANOSEC / MICROSEC))
#define NSEC2SEC(n) ((n) / (NANOSEC / SEC))
#define SEC2NSEC(m) ((hrtime_t)(m) * (NANOSEC / SEC))
static const int hz = HZ; static const int hz = HZ;
#define TIMESPEC_OVERFLOW(ts) \ #define TIMESPEC_OVERFLOW(ts) \

View File

@ -35,6 +35,7 @@ typedef void (*dtor_func_t)(void *);
extern int tsd_set(uint_t, void *); extern int tsd_set(uint_t, void *);
extern void *tsd_get(uint_t); extern void *tsd_get(uint_t);
extern void *tsd_get_by_thread(uint_t, kthread_t *);
extern void tsd_create(uint_t *, dtor_func_t); extern void tsd_create(uint_t *, dtor_func_t);
extern void tsd_destroy(uint_t *); extern void tsd_destroy(uint_t *);
extern void tsd_exit(void); extern void tsd_exit(void);

View File

@ -30,8 +30,8 @@
* about the Linux task_struct. Since this is internal to our compatibility * about the Linux task_struct. Since this is internal to our compatibility
* layer, we make it an opaque type. * layer, we make it an opaque type.
* *
* XXX: If the descriptor changes under us, we would get an incorrect * XXX: If the descriptor changes under us and we do not do a getf() between
* reference. * the change and using it, we would get an incorrect reference.
*/ */
struct uf_info; struct uf_info;

View File

@ -41,6 +41,20 @@ concurrently.
Default value: \fB0x02\fR Default value: \fB0x02\fR
.RE .RE
.sp
.ne 2
.na
\fBspl_kmem_cache_kmem_threads\fR (uint)
.ad
.RS 12n
The number of threads created for the spl_kmem_cache task queue. This task
queue is responsible for allocating new slabs for use by the kmem caches.
For the majority of systems and workloads only a small number of threads are
required.
.sp
Default value: \fB4\fR
.RE
.sp .sp
.ne 2 .ne 2
.na .na
@ -236,6 +250,20 @@ may be overridden for non-standard configurations.
Default value: \fB/etc/hostid\fR Default value: \fB/etc/hostid\fR
.RE .RE
.sp
.ne 2
.na
\fBspl_taskq_kick\fR (uint)
.ad
.RS 12n
Kick stuck taskq to spawn threads. When writing a non-zero value to it, it will
scan all the taskqs. If any of them have a pending task more than 5 seconds old,
it will kick it to spawn more threads. This can be used if you find a rare
deadlock occurs because one or more taskqs didn't spawn a thread when it should.
.sp
Default value: \fB0\fR
.RE
.sp .sp
.ne 2 .ne 2
.na .na
@ -298,3 +326,18 @@ configurations.
.sp .sp
Default value: \fB4\fR Default value: \fB4\fR
.RE .RE
.sp
.ne 2
.na
\fBspl_max_show_tasks\fR (uint)
.ad
.RS 12n
The maximum number of tasks per pending list in each taskq shown in
/proc/spl/{taskq,taskq-all}. Write 0 to turn off the limit. The proc file will
walk the lists with lock held, reading it could cause a lock up if the list
grow too large without limiting the output. "(truncated)" will be shown if the
list is larger than the limit.
.sp
Default value: \fB512\fR
.RE

View File

@ -26,6 +26,7 @@
#include <sys/condvar.h> #include <sys/condvar.h>
#include <sys/time.h> #include <sys/time.h>
#include <linux/hrtimer.h>
void void
__cv_init(kcondvar_t *cvp, char *name, kcv_type_t type, void *arg) __cv_init(kcondvar_t *cvp, char *name, kcv_type_t type, void *arg)
@ -165,22 +166,19 @@ __cv_timedwait_common(kcondvar_t *cvp, kmutex_t *mp, clock_t expire_time,
ASSERT(mp); ASSERT(mp);
ASSERT(cvp->cv_magic == CV_MAGIC); ASSERT(cvp->cv_magic == CV_MAGIC);
ASSERT(mutex_owned(mp)); ASSERT(mutex_owned(mp));
atomic_inc(&cvp->cv_refs);
/* XXX - Does not handle jiffie wrap properly */
time_left = expire_time - jiffies;
if (time_left <= 0)
return (-1);
atomic_inc(&cvp->cv_refs);
m = ACCESS_ONCE(cvp->cv_mutex); m = ACCESS_ONCE(cvp->cv_mutex);
if (!m) if (!m)
m = xchg(&cvp->cv_mutex, mp); m = xchg(&cvp->cv_mutex, mp);
/* Ensure the same mutex is used by all callers */ /* Ensure the same mutex is used by all callers */
ASSERT(m == NULL || m == mp); ASSERT(m == NULL || m == mp);
/* XXX - Does not handle jiffie wrap properly */
time_left = expire_time - jiffies;
if (time_left <= 0) {
/* XXX - doesn't reset cv_mutex */
atomic_dec(&cvp->cv_refs);
return (-1);
}
prepare_to_wait_exclusive(&cvp->cv_event, &wait, state); prepare_to_wait_exclusive(&cvp->cv_event, &wait, state);
atomic_inc(&cvp->cv_waiters); atomic_inc(&cvp->cv_waiters);
@ -237,29 +235,25 @@ __cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t expire_time,
{ {
DEFINE_WAIT(wait); DEFINE_WAIT(wait);
kmutex_t *m; kmutex_t *m;
hrtime_t time_left, now; hrtime_t time_left;
unsigned long time_left_us; ktime_t ktime_left;
ASSERT(cvp); ASSERT(cvp);
ASSERT(mp); ASSERT(mp);
ASSERT(cvp->cv_magic == CV_MAGIC); ASSERT(cvp->cv_magic == CV_MAGIC);
ASSERT(mutex_owned(mp)); ASSERT(mutex_owned(mp));
atomic_inc(&cvp->cv_refs);
time_left = expire_time - gethrtime();
if (time_left <= 0)
return (-1);
atomic_inc(&cvp->cv_refs);
m = ACCESS_ONCE(cvp->cv_mutex); m = ACCESS_ONCE(cvp->cv_mutex);
if (!m) if (!m)
m = xchg(&cvp->cv_mutex, mp); m = xchg(&cvp->cv_mutex, mp);
/* Ensure the same mutex is used by all callers */ /* Ensure the same mutex is used by all callers */
ASSERT(m == NULL || m == mp); ASSERT(m == NULL || m == mp);
now = gethrtime();
time_left = expire_time - now;
if (time_left <= 0) {
atomic_dec(&cvp->cv_refs);
return (-1);
}
time_left_us = time_left / NSEC_PER_USEC;
prepare_to_wait_exclusive(&cvp->cv_event, &wait, state); prepare_to_wait_exclusive(&cvp->cv_event, &wait, state);
atomic_inc(&cvp->cv_waiters); atomic_inc(&cvp->cv_waiters);
@ -273,7 +267,9 @@ __cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t expire_time,
* Allow a 100 us range to give kernel an opportunity to coalesce * Allow a 100 us range to give kernel an opportunity to coalesce
* interrupts * interrupts
*/ */
usleep_range(time_left_us, time_left_us + 100); ktime_left = ktime_set(0, time_left);
schedule_hrtimeout_range(&ktime_left, 100 * NSEC_PER_USEC,
HRTIMER_MODE_REL);
/* No more waiters a different mutex could be used */ /* No more waiters a different mutex could be used */
if (atomic_dec_and_test(&cvp->cv_waiters)) { if (atomic_dec_and_test(&cvp->cv_waiters)) {
@ -290,15 +286,15 @@ __cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t expire_time,
mutex_enter(mp); mutex_enter(mp);
time_left = expire_time - gethrtime(); time_left = expire_time - gethrtime();
return (time_left > 0 ? time_left : -1); return (time_left > 0 ? NSEC_TO_TICK(time_left) : -1);
} }
/* /*
* Compatibility wrapper for the cv_timedwait_hires() Illumos interface. * Compatibility wrapper for the cv_timedwait_hires() Illumos interface.
*/ */
clock_t static clock_t
cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim, hrtime_t res, cv_timedwait_hires_common(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim, hrtime_t res,
int flag) int flag, int state)
{ {
if (res > 1) { if (res > 1) {
/* /*
@ -312,10 +308,27 @@ cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim, hrtime_t res,
if (!(flag & CALLOUT_FLAG_ABSOLUTE)) if (!(flag & CALLOUT_FLAG_ABSOLUTE))
tim += gethrtime(); tim += gethrtime();
return (__cv_timedwait_hires(cvp, mp, tim, TASK_UNINTERRUPTIBLE)); return (__cv_timedwait_hires(cvp, mp, tim, state));
}
clock_t
cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim, hrtime_t res,
int flag)
{
return (cv_timedwait_hires_common(cvp, mp, tim, res, flag,
TASK_UNINTERRUPTIBLE));
} }
EXPORT_SYMBOL(cv_timedwait_hires); EXPORT_SYMBOL(cv_timedwait_hires);
clock_t
cv_timedwait_sig_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim, hrtime_t res,
int flag)
{
return (cv_timedwait_hires_common(cvp, mp, tim, res, flag,
TASK_INTERRUPTIBLE));
}
EXPORT_SYMBOL(cv_timedwait_sig_hires);
void void
__cv_signal(kcondvar_t *cvp) __cv_signal(kcondvar_t *cvp)
{ {

View File

@ -28,6 +28,17 @@
#include <sys/cmn_err.h> #include <sys/cmn_err.h>
#include <linux/ratelimit.h> #include <linux/ratelimit.h>
/*
* It is often useful to actually have the panic crash the node so you
* can then get notified of the event, get the crashdump for later
* analysis and other such goodies.
* But we would still default to the current default of not to do that.
*/
unsigned int spl_panic_halt;
module_param(spl_panic_halt, uint, 0644);
MODULE_PARM_DESC(spl_panic_halt,
"Cause kernel panic on assertion failures");
/* /*
* Limit the number of stack traces dumped to not more than 5 every * Limit the number of stack traces dumped to not more than 5 every
* 60 seconds to prevent denial-of-service attacks from debug code. * 60 seconds to prevent denial-of-service attacks from debug code.
@ -62,6 +73,9 @@ spl_panic(const char *file, const char *func, int line, const char *fmt, ...) {
printk(KERN_EMERG "%s", msg); printk(KERN_EMERG "%s", msg);
printk(KERN_EMERG "PANIC at %s:%d:%s()\n", newfile, line, func); printk(KERN_EMERG "PANIC at %s:%d:%s()\n", newfile, line, func);
if (spl_panic_halt)
panic("%s", msg);
spl_dumpstack(); spl_dumpstack();
/* Halt the thread to facilitate further debugging */ /* Halt the thread to facilitate further debugging */

View File

@ -41,6 +41,8 @@
#include <sys/kstat.h> #include <sys/kstat.h>
#include <sys/file.h> #include <sys/file.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <sys/disp.h>
#include <sys/random.h>
#include <linux/kmod.h> #include <linux/kmod.h>
#include <linux/math64_compat.h> #include <linux/math64_compat.h>
#include <linux/proc_compat.h> #include <linux/proc_compat.h>
@ -56,6 +58,112 @@ MODULE_PARM_DESC(spl_hostid, "The system hostid.");
proc_t p0; proc_t p0;
EXPORT_SYMBOL(p0); EXPORT_SYMBOL(p0);
/*
* Xorshift Pseudo Random Number Generator based on work by Sebastiano Vigna
*
* "Further scramblings of Marsaglia's xorshift generators"
* http://vigna.di.unimi.it/ftp/papers/xorshiftplus.pdf
*
* random_get_pseudo_bytes() is an API function on Illumos whose sole purpose
* is to provide bytes containing random numbers. It is mapped to /dev/urandom
* on Illumos, which uses a "FIPS 186-2 algorithm". No user of the SPL's
* random_get_pseudo_bytes() needs bytes that are of cryptographic quality, so
* we can implement it using a fast PRNG that we seed using Linux' actual
* equivalent to random_get_pseudo_bytes(). We do this by providing each CPU
* with an independent seed so that all calls to random_get_pseudo_bytes() are
* free of atomic instructions.
*
* A consequence of using a fast PRNG is that using random_get_pseudo_bytes()
* to generate words larger than 128 bits will paradoxically be limited to
* `2^128 - 1` possibilities. This is because we have a sequence of `2^128 - 1`
* 128-bit words and selecting the first will implicitly select the second. If
* a caller finds this behavior undesireable, random_get_bytes() should be used
* instead.
*
* XXX: Linux interrupt handlers that trigger within the critical section
* formed by `s[1] = xp[1];` and `xp[0] = s[0];` and call this function will
* see the same numbers. Nothing in the code currently calls this in an
* interrupt handler, so this is considered to be okay. If that becomes a
* problem, we could create a set of per-cpu variables for interrupt handlers
* and use them when in_interrupt() from linux/preempt_mask.h evaluates to
* true.
*/
static DEFINE_PER_CPU(uint64_t[2], spl_pseudo_entropy);
/*
* spl_rand_next()/spl_rand_jump() are copied from the following CC-0 licensed
* file:
*
* http://xorshift.di.unimi.it/xorshift128plus.c
*/
static inline uint64_t
spl_rand_next(uint64_t *s) {
uint64_t s1 = s[0];
const uint64_t s0 = s[1];
s[0] = s0;
s1 ^= s1 << 23; // a
s[1] = s1 ^ s0 ^ (s1 >> 18) ^ (s0 >> 5); // b, c
return (s[1] + s0);
}
static inline void
spl_rand_jump(uint64_t *s) {
static const uint64_t JUMP[] = { 0x8a5cd789635d2dff, 0x121fd2155c472f96 };
uint64_t s0 = 0;
uint64_t s1 = 0;
int i, b;
for(i = 0; i < sizeof JUMP / sizeof *JUMP; i++)
for(b = 0; b < 64; b++) {
if (JUMP[i] & 1ULL << b) {
s0 ^= s[0];
s1 ^= s[1];
}
(void) spl_rand_next(s);
}
s[0] = s0;
s[1] = s1;
}
int
random_get_pseudo_bytes(uint8_t *ptr, size_t len)
{
uint64_t *xp, s[2];
ASSERT(ptr);
xp = get_cpu_var(spl_pseudo_entropy);
s[0] = xp[0];
s[1] = xp[1];
while (len) {
union {
uint64_t ui64;
uint8_t byte[sizeof (uint64_t)];
}entropy;
int i = MIN(len, sizeof (uint64_t));
len -= i;
entropy.ui64 = spl_rand_next(s);
while (i--)
*ptr++ = entropy.byte[i];
}
xp[0] = s[0];
xp[1] = s[1];
put_cpu_var(spl_pseudo_entropy);
return (0);
}
EXPORT_SYMBOL(random_get_pseudo_bytes);
#if BITS_PER_LONG == 32 #if BITS_PER_LONG == 32
/* /*
* Support 64/64 => 64 division on a 32-bit platform. While the kernel * Support 64/64 => 64 division on a 32-bit platform. While the kernel
@ -169,6 +277,49 @@ __umoddi3(uint64_t dividend, uint64_t divisor)
} }
EXPORT_SYMBOL(__umoddi3); EXPORT_SYMBOL(__umoddi3);
/*
* Implementation of 64-bit unsigned division/modulo for 32-bit machines.
*/
uint64_t
__udivmoddi4(uint64_t n, uint64_t d, uint64_t *r)
{
uint64_t q = __udivdi3(n, d);
if (r)
*r = n - d * q;
return (q);
}
EXPORT_SYMBOL(__udivmoddi4);
/*
* Implementation of 64-bit signed division/modulo for 32-bit machines.
*/
int64_t
__divmoddi4(int64_t n, int64_t d, int64_t *r)
{
int64_t q, rr;
boolean_t nn = B_FALSE;
boolean_t nd = B_FALSE;
if (n < 0) {
nn = B_TRUE;
n = -n;
}
if (d < 0) {
nd = B_TRUE;
d = -d;
}
q = __udivmoddi4(n, d, (uint64_t *)&rr);
if (nn != nd)
q = -q;
if (nn)
rr = -rr;
if (r)
*r = rr;
return (q);
}
EXPORT_SYMBOL(__divmoddi4);
#if defined(__arm) || defined(__arm__) #if defined(__arm) || defined(__arm__)
/* /*
* Implementation of 64-bit (un)signed division for 32-bit arm machines. * Implementation of 64-bit (un)signed division for 32-bit arm machines.
@ -391,80 +542,63 @@ module_param(spl_hostid_path, charp, 0444);
MODULE_PARM_DESC(spl_hostid_path, "The system hostid file (/etc/hostid)"); MODULE_PARM_DESC(spl_hostid_path, "The system hostid file (/etc/hostid)");
static int static int
hostid_read(void) hostid_read(uint32_t *hostid)
{ {
int result;
uint64_t size; uint64_t size;
struct _buf *file; struct _buf *file;
uint32_t hostid = 0; uint32_t value = 0;
int error;
file = kobj_open_file(spl_hostid_path); file = kobj_open_file(spl_hostid_path);
if (file == (struct _buf *)-1) if (file == (struct _buf *)-1)
return -1; return (ENOENT);
result = kobj_get_filesize(file, &size); error = kobj_get_filesize(file, &size);
if (error) {
if (result != 0) {
printk(KERN_WARNING
"SPL: kobj_get_filesize returned %i on %s\n",
result, spl_hostid_path);
kobj_close_file(file); kobj_close_file(file);
return -2; return (error);
} }
if (size < sizeof(HW_HOSTID_MASK)) { if (size < sizeof(HW_HOSTID_MASK)) {
printk(KERN_WARNING
"SPL: Ignoring the %s file because it is %llu bytes; "
"expecting %lu bytes instead.\n", spl_hostid_path,
size, (unsigned long)sizeof(HW_HOSTID_MASK));
kobj_close_file(file); kobj_close_file(file);
return -3; return (EINVAL);
} }
/* Read directly into the variable like eglibc does. */ /*
/* Short reads are okay; native behavior is preserved. */ * Read directly into the variable like eglibc does.
result = kobj_read_file(file, (char *)&hostid, sizeof(hostid), 0); * Short reads are okay; native behavior is preserved.
*/
if (result < 0) { error = kobj_read_file(file, (char *)&value, sizeof(value), 0);
printk(KERN_WARNING if (error < 0) {
"SPL: kobj_read_file returned %i on %s\n",
result, spl_hostid_path);
kobj_close_file(file); kobj_close_file(file);
return -4; return (EIO);
} }
/* Mask down to 32 bits like coreutils does. */ /* Mask down to 32 bits like coreutils does. */
spl_hostid = hostid & HW_HOSTID_MASK; *hostid = (value & HW_HOSTID_MASK);
kobj_close_file(file); kobj_close_file(file);
return 0; return 0;
} }
/*
* Return the system hostid. Preferentially use the spl_hostid module option
* when set, otherwise use the value in the /etc/hostid file.
*/
uint32_t uint32_t
zone_get_hostid(void *zone) zone_get_hostid(void *zone)
{ {
static int first = 1; uint32_t hostid;
/* Only the global zone is supported */ ASSERT3P(zone, ==, NULL);
ASSERT(zone == NULL);
if (first) { if (spl_hostid != 0)
first = 0; return ((uint32_t)(spl_hostid & HW_HOSTID_MASK));
spl_hostid &= HW_HOSTID_MASK; if (hostid_read(&hostid) == 0)
/* return (hostid);
* Get the hostid if it was not passed as a module parameter.
* Try reading the /etc/hostid file directly.
*/
if (spl_hostid == 0 && hostid_read())
spl_hostid = 0;
return (0);
printk(KERN_NOTICE "SPL: using hostid 0x%08x\n",
(unsigned int) spl_hostid);
}
return spl_hostid;
} }
EXPORT_SYMBOL(zone_get_hostid); EXPORT_SYMBOL(zone_get_hostid);
@ -475,29 +609,58 @@ spl_kvmem_init(void)
rc = spl_kmem_init(); rc = spl_kmem_init();
if (rc) if (rc)
goto out1; return (rc);
rc = spl_vmem_init(); rc = spl_vmem_init();
if (rc) if (rc) {
goto out2; spl_kmem_fini();
return (rc);
rc = spl_kmem_cache_init(); }
if (rc)
goto out3;
return (rc); return (rc);
out3: }
spl_vmem_fini();
out2: /*
spl_kmem_fini(); * We initialize the random number generator with 128 bits of entropy from the
out1: * system random number generator. In the improbable case that we have a zero
return (rc); * seed, we fallback to the system jiffies, unless it is also zero, in which
* situation we use a preprogrammed seed. We step forward by 2^64 iterations to
* initialize each of the per-cpu seeds so that the sequences generated on each
* CPU are guaranteed to never overlap in practice.
*/
static void __init
spl_random_init(void)
{
uint64_t s[2];
int i;
get_random_bytes(s, sizeof (s));
if (s[0] == 0 && s[1] == 0) {
if (jiffies != 0) {
s[0] = jiffies;
s[1] = ~0 - jiffies;
} else {
(void) memcpy(s, "improbable seed", sizeof (s));
}
printk("SPL: get_random_bytes() returned 0 "
"when generating random seed. Setting initial seed to "
"0x%016llx%016llx.", cpu_to_be64(s[0]), cpu_to_be64(s[1]));
}
for_each_possible_cpu(i) {
uint64_t *wordp = per_cpu(spl_pseudo_entropy, i);
spl_rand_jump(s);
wordp[0] = s[0];
wordp[1] = s[1];
}
} }
static void static void
spl_kvmem_fini(void) spl_kvmem_fini(void)
{ {
spl_kmem_cache_fini();
spl_vmem_fini(); spl_vmem_fini();
spl_kmem_fini(); spl_kmem_fini();
} }
@ -508,6 +671,7 @@ spl_init(void)
int rc = 0; int rc = 0;
bzero(&p0, sizeof (proc_t)); bzero(&p0, sizeof (proc_t));
spl_random_init();
if ((rc = spl_kvmem_init())) if ((rc = spl_kvmem_init()))
goto out1; goto out1;
@ -518,38 +682,43 @@ spl_init(void)
if ((rc = spl_rw_init())) if ((rc = spl_rw_init()))
goto out3; goto out3;
if ((rc = spl_taskq_init())) if ((rc = spl_tsd_init()))
goto out4; goto out4;
if ((rc = spl_vn_init())) if ((rc = spl_taskq_init()))
goto out5; goto out5;
if ((rc = spl_proc_init())) if ((rc = spl_kmem_cache_init()))
goto out6; goto out6;
if ((rc = spl_kstat_init())) if ((rc = spl_vn_init()))
goto out7; goto out7;
if ((rc = spl_tsd_init())) if ((rc = spl_proc_init()))
goto out8; goto out8;
if ((rc = spl_zlib_init())) if ((rc = spl_kstat_init()))
goto out9; goto out9;
if ((rc = spl_zlib_init()))
goto out10;
printk(KERN_NOTICE "SPL: Loaded module v%s-%s%s\n", SPL_META_VERSION, printk(KERN_NOTICE "SPL: Loaded module v%s-%s%s\n", SPL_META_VERSION,
SPL_META_RELEASE, SPL_DEBUG_STR); SPL_META_RELEASE, SPL_DEBUG_STR);
return (rc); return (rc);
out9: out10:
spl_tsd_fini();
out8:
spl_kstat_fini(); spl_kstat_fini();
out7: out9:
spl_proc_fini(); spl_proc_fini();
out6: out8:
spl_vn_fini(); spl_vn_fini();
out5: out7:
spl_kmem_cache_fini();
out6:
spl_taskq_fini(); spl_taskq_fini();
out5:
spl_tsd_fini();
out4: out4:
spl_rw_fini(); spl_rw_fini();
out3: out3:
@ -570,11 +739,12 @@ spl_fini(void)
printk(KERN_NOTICE "SPL: Unloaded module v%s-%s%s\n", printk(KERN_NOTICE "SPL: Unloaded module v%s-%s%s\n",
SPL_META_VERSION, SPL_META_RELEASE, SPL_DEBUG_STR); SPL_META_VERSION, SPL_META_RELEASE, SPL_DEBUG_STR);
spl_zlib_fini(); spl_zlib_fini();
spl_tsd_fini();
spl_kstat_fini(); spl_kstat_fini();
spl_proc_fini(); spl_proc_fini();
spl_vn_fini(); spl_vn_fini();
spl_kmem_cache_fini();
spl_taskq_fini(); spl_taskq_fini();
spl_tsd_fini();
spl_rw_fini(); spl_rw_fini();
spl_mutex_fini(); spl_mutex_fini();
spl_kvmem_fini(); spl_kvmem_fini();

View File

@ -88,7 +88,7 @@ MODULE_PARM_DESC(spl_kmem_cache_expire, "By age (0x1) or low memory (0x2)");
unsigned int spl_kmem_cache_magazine_size = 0; unsigned int spl_kmem_cache_magazine_size = 0;
module_param(spl_kmem_cache_magazine_size, uint, 0444); module_param(spl_kmem_cache_magazine_size, uint, 0444);
MODULE_PARM_DESC(spl_kmem_cache_magazine_size, MODULE_PARM_DESC(spl_kmem_cache_magazine_size,
"Default magazine size (2-256), set automatically (0)\n"); "Default magazine size (2-256), set automatically (0)");
/* /*
* The default behavior is to report the number of objects remaining in the * The default behavior is to report the number of objects remaining in the
@ -1001,8 +1001,17 @@ spl_kmem_cache_create(char *name, size_t size, size_t align,
slabflags |= SLAB_USERCOPY; slabflags |= SLAB_USERCOPY;
#endif #endif
skc->skc_linux_cache = kmem_cache_create( #if defined(HAVE_KMEM_CACHE_CREATE_USERCOPY)
skc->skc_name, size, align, slabflags, NULL); /*
* Newer grsec patchset uses kmem_cache_create_usercopy()
* instead of SLAB_USERCOPY flag
*/
skc->skc_linux_cache = kmem_cache_create_usercopy(
skc->skc_name, size, align, slabflags, 0, size, NULL);
#else
skc->skc_linux_cache = kmem_cache_create(
skc->skc_name, size, align, slabflags, NULL);
#endif
if (skc->skc_linux_cache == NULL) { if (skc->skc_linux_cache == NULL) {
rc = ENOMEM; rc = ENOMEM;
goto out; goto out;
@ -1149,15 +1158,13 @@ spl_cache_obj(spl_kmem_cache_t *skc, spl_kmem_slab_t *sks)
* It is responsible for allocating a new slab, linking it in to the list * It is responsible for allocating a new slab, linking it in to the list
* of partial slabs, and then waking any waiters. * of partial slabs, and then waking any waiters.
*/ */
static void static int
spl_cache_grow_work(void *data) __spl_cache_grow(spl_kmem_cache_t *skc, int flags)
{ {
spl_kmem_alloc_t *ska = (spl_kmem_alloc_t *)data;
spl_kmem_cache_t *skc = ska->ska_cache;
spl_kmem_slab_t *sks; spl_kmem_slab_t *sks;
fstrans_cookie_t cookie = spl_fstrans_mark(); fstrans_cookie_t cookie = spl_fstrans_mark();
sks = spl_slab_alloc(skc, ska->ska_flags); sks = spl_slab_alloc(skc, flags);
spl_fstrans_unmark(cookie); spl_fstrans_unmark(cookie);
spin_lock(&skc->skc_lock); spin_lock(&skc->skc_lock);
@ -1165,15 +1172,29 @@ spl_cache_grow_work(void *data)
skc->skc_slab_total++; skc->skc_slab_total++;
skc->skc_obj_total += sks->sks_objs; skc->skc_obj_total += sks->sks_objs;
list_add_tail(&sks->sks_list, &skc->skc_partial_list); list_add_tail(&sks->sks_list, &skc->skc_partial_list);
smp_mb__before_atomic();
clear_bit(KMC_BIT_DEADLOCKED, &skc->skc_flags);
smp_mb__after_atomic();
wake_up_all(&skc->skc_waitq);
} }
spin_unlock(&skc->skc_lock);
return (sks == NULL ? -ENOMEM : 0);
}
static void
spl_cache_grow_work(void *data)
{
spl_kmem_alloc_t *ska = (spl_kmem_alloc_t *)data;
spl_kmem_cache_t *skc = ska->ska_cache;
(void)__spl_cache_grow(skc, ska->ska_flags);
atomic_dec(&skc->skc_ref); atomic_dec(&skc->skc_ref);
smp_mb__before_atomic(); smp_mb__before_atomic();
clear_bit(KMC_BIT_GROWING, &skc->skc_flags); clear_bit(KMC_BIT_GROWING, &skc->skc_flags);
clear_bit(KMC_BIT_DEADLOCKED, &skc->skc_flags);
smp_mb__after_atomic(); smp_mb__after_atomic();
wake_up_all(&skc->skc_waitq);
spin_unlock(&skc->skc_lock);
kfree(ska); kfree(ska);
} }
@ -1213,6 +1234,21 @@ spl_cache_grow(spl_kmem_cache_t *skc, int flags, void **obj)
return (rc ? rc : -EAGAIN); return (rc ? rc : -EAGAIN);
} }
/*
* To reduce the overhead of context switch and improve NUMA locality,
* it tries to allocate a new slab in the current process context with
* KM_NOSLEEP flag. If it fails, it will launch a new taskq to do the
* allocation.
*
* However, this can't be applied to KVM_VMEM due to a bug that
* __vmalloc() doesn't honor gfp flags in page table allocation.
*/
if (!(skc->skc_flags & KMC_VMEM)) {
rc = __spl_cache_grow(skc, flags | KM_NOSLEEP);
if (rc == 0)
return (0);
}
/* /*
* This is handled by dispatching a work request to the global work * This is handled by dispatching a work request to the global work
* queue. This allows us to asynchronously allocate a new slab while * queue. This allows us to asynchronously allocate a new slab while

View File

@ -35,7 +35,7 @@
* rate limited warning will be printed to the console for any kmem_alloc() * rate limited warning will be printed to the console for any kmem_alloc()
* which exceeds a reasonable threshold. * which exceeds a reasonable threshold.
* *
* The default warning threshold is set to eight pages but capped at 32K to * The default warning threshold is set to sixteen pages but capped at 64K to
* accommodate systems using large pages. This value was selected to be small * accommodate systems using large pages. This value was selected to be small
* enough to ensure the largest allocations are quickly noticed and fixed. * enough to ensure the largest allocations are quickly noticed and fixed.
* But large enough to avoid logging any warnings when a allocation size is * But large enough to avoid logging any warnings when a allocation size is
@ -44,7 +44,7 @@
* allocations are quickly caught. These warnings may be disabled by setting * allocations are quickly caught. These warnings may be disabled by setting
* the threshold to zero. * the threshold to zero.
*/ */
unsigned int spl_kmem_alloc_warn = MAX(8 * PAGE_SIZE, 32 * 1024); unsigned int spl_kmem_alloc_warn = MIN(16 * PAGE_SIZE, 64 * 1024);
module_param(spl_kmem_alloc_warn, uint, 0644); module_param(spl_kmem_alloc_warn, uint, 0644);
MODULE_PARM_DESC(spl_kmem_alloc_warn, MODULE_PARM_DESC(spl_kmem_alloc_warn,
"Warning threshold in bytes for a kmem_alloc()"); "Warning threshold in bytes for a kmem_alloc()");

View File

@ -57,10 +57,15 @@ kobj_close_file(struct _buf *file)
EXPORT_SYMBOL(kobj_close_file); EXPORT_SYMBOL(kobj_close_file);
int int
kobj_read_file(struct _buf *file, char *buf, ssize_t size, offset_t off) kobj_read_file(struct _buf *file, char *buf, unsigned size, unsigned off)
{ {
return (vn_rdwr(UIO_READ, file->vp, buf, size, off, ssize_t resid;
UIO_SYSSPACE, 0, RLIM64_INFINITY, 0, NULL));
if (vn_rdwr(UIO_READ, file->vp, buf, size, (offset_t)off,
UIO_SYSSPACE, 0, 0, 0, &resid) != 0)
return (-1);
return (size - resid);
} /* kobj_read_file() */ } /* kobj_read_file() */
EXPORT_SYMBOL(kobj_read_file); EXPORT_SYMBOL(kobj_read_file);

View File

@ -27,6 +27,7 @@
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <sys/kstat.h> #include <sys/kstat.h>
#include <sys/vmem.h> #include <sys/vmem.h>
#include <sys/cmn_err.h>
#ifndef HAVE_PDE_DATA #ifndef HAVE_PDE_DATA
#define PDE_DATA(x) (PDE(x)->data) #define PDE_DATA(x) (PDE(x)->data)
@ -608,6 +609,29 @@ __kstat_create(const char *ks_module, int ks_instance, const char *ks_name,
} }
EXPORT_SYMBOL(__kstat_create); EXPORT_SYMBOL(__kstat_create);
static int
kstat_detect_collision(kstat_t *ksp)
{
kstat_module_t *module;
kstat_t *tmp;
char parent[KSTAT_STRLEN+1];
char *cp;
(void) strlcpy(parent, ksp->ks_module, sizeof(parent));
if ((cp = strrchr(parent, '/')) == NULL)
return (0);
cp[0] = '\0';
if ((module = kstat_find_module(parent)) != NULL) {
list_for_each_entry(tmp, &module->ksm_kstat_list, ks_list)
if (strncmp(tmp->ks_name, cp+1, KSTAT_STRLEN) == 0)
return (EEXIST);
}
return (0);
}
void void
__kstat_install(kstat_t *ksp) __kstat_install(kstat_t *ksp)
{ {
@ -620,6 +644,11 @@ __kstat_install(kstat_t *ksp)
module = kstat_find_module(ksp->ks_module); module = kstat_find_module(ksp->ks_module);
if (module == NULL) { if (module == NULL) {
if (kstat_detect_collision(ksp) != 0) {
cmn_err(CE_WARN, "kstat_create('%s', '%s'): namespace" \
" collision", ksp->ks_module, ksp->ks_name);
goto out;
}
module = kstat_create_module(ksp->ks_module); module = kstat_create_module(ksp->ks_module);
if (module == NULL) if (module == NULL)
goto out; goto out;

View File

@ -29,6 +29,7 @@
#include <sys/kmem.h> #include <sys/kmem.h>
#include <sys/kmem_cache.h> #include <sys/kmem_cache.h>
#include <sys/vmem.h> #include <sys/vmem.h>
#include <sys/taskq.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/kmod.h> #include <linux/kmod.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
@ -49,6 +50,8 @@ static struct ctl_table_header *spl_header = NULL;
static struct proc_dir_entry *proc_spl = NULL; static struct proc_dir_entry *proc_spl = NULL;
static struct proc_dir_entry *proc_spl_kmem = NULL; static struct proc_dir_entry *proc_spl_kmem = NULL;
static struct proc_dir_entry *proc_spl_kmem_slab = NULL; static struct proc_dir_entry *proc_spl_kmem_slab = NULL;
static struct proc_dir_entry *proc_spl_taskq_all = NULL;
static struct proc_dir_entry *proc_spl_taskq = NULL;
struct proc_dir_entry *proc_spl_kstat = NULL; struct proc_dir_entry *proc_spl_kstat = NULL;
static int static int
@ -200,7 +203,8 @@ proc_dohostid(struct ctl_table *table, int write,
return (-EINVAL); return (-EINVAL);
} else { } else {
len = snprintf(str, sizeof(str), "%lx", spl_hostid); len = snprintf(str, sizeof(str), "%lx",
(unsigned long) zone_get_hostid(NULL));
if (*ppos >= len) if (*ppos >= len)
rc = 0; rc = 0;
else else
@ -215,6 +219,193 @@ proc_dohostid(struct ctl_table *table, int write,
return (rc); return (rc);
} }
static void
taskq_seq_show_headers(struct seq_file *f)
{
seq_printf(f, "%-25s %5s %5s %5s %5s %5s %5s %12s %5s %10s\n",
"taskq", "act", "nthr", "spwn", "maxt", "pri",
"mina", "maxa", "cura", "flags");
}
/* indices into the lheads array below */
#define LHEAD_PEND 0
#define LHEAD_PRIO 1
#define LHEAD_DELAY 2
#define LHEAD_WAIT 3
#define LHEAD_ACTIVE 4
#define LHEAD_SIZE 5
static unsigned int spl_max_show_tasks = 512;
module_param(spl_max_show_tasks, uint, 0644);
MODULE_PARM_DESC(spl_max_show_tasks, "Max number of tasks shown in taskq proc");
static int
taskq_seq_show_impl(struct seq_file *f, void *p, boolean_t allflag)
{
taskq_t *tq = p;
taskq_thread_t *tqt;
spl_wait_queue_entry_t *wq;
struct task_struct *tsk;
taskq_ent_t *tqe;
char name[100];
struct list_head *lheads[LHEAD_SIZE], *lh;
static char *list_names[LHEAD_SIZE] =
{"pend", "prio", "delay", "wait", "active" };
int i, j, have_lheads = 0;
unsigned long wflags, flags;
spin_lock_irqsave_nested(&tq->tq_lock, flags, tq->tq_lock_class);
spin_lock_irqsave(&tq->tq_wait_waitq.lock, wflags);
/* get the various lists and check whether they're empty */
lheads[LHEAD_PEND] = &tq->tq_pend_list;
lheads[LHEAD_PRIO] = &tq->tq_prio_list;
lheads[LHEAD_DELAY] = &tq->tq_delay_list;
#ifdef HAVE_WAIT_QUEUE_HEAD_ENTRY
lheads[LHEAD_WAIT] = &tq->tq_wait_waitq.head;
#else
lheads[LHEAD_WAIT] = &tq->tq_wait_waitq.task_list;
#endif
lheads[LHEAD_ACTIVE] = &tq->tq_active_list;
for (i = 0; i < LHEAD_SIZE; ++i) {
if (list_empty(lheads[i]))
lheads[i] = NULL;
else
++have_lheads;
}
/* early return in non-"all" mode if lists are all empty */
if (!allflag && !have_lheads) {
spin_unlock_irqrestore(&tq->tq_wait_waitq.lock, wflags);
spin_unlock_irqrestore(&tq->tq_lock, flags);
return (0);
}
/* unlock the waitq quickly */
if (!lheads[LHEAD_WAIT])
spin_unlock_irqrestore(&tq->tq_wait_waitq.lock, wflags);
/* show the base taskq contents */
snprintf(name, sizeof(name), "%s/%d", tq->tq_name, tq->tq_instance);
seq_printf(f, "%-25s ", name);
seq_printf(f, "%5d %5d %5d %5d %5d %5d %12d %5d %10x\n",
tq->tq_nactive, tq->tq_nthreads, tq->tq_nspawn,
tq->tq_maxthreads, tq->tq_pri, tq->tq_minalloc, tq->tq_maxalloc,
tq->tq_nalloc, tq->tq_flags);
/* show the active list */
if (lheads[LHEAD_ACTIVE]) {
j = 0;
list_for_each_entry(tqt, &tq->tq_active_list, tqt_active_list) {
if (j == 0)
seq_printf(f, "\t%s:", list_names[LHEAD_ACTIVE]);
else if (j == 2) {
seq_printf(f, "\n\t ");
j = 0;
}
seq_printf(f, " [%d]%pf(%ps)",
tqt->tqt_thread->pid,
tqt->tqt_task->tqent_func,
tqt->tqt_task->tqent_arg);
++j;
}
seq_printf(f, "\n");
}
for (i = LHEAD_PEND; i <= LHEAD_WAIT; ++i)
if (lheads[i]) {
j = 0;
list_for_each(lh, lheads[i]) {
if (spl_max_show_tasks != 0 &&
j >= spl_max_show_tasks) {
seq_printf(f, "\n\t(truncated)");
break;
}
/* show the wait waitq list */
if (i == LHEAD_WAIT) {
#ifdef HAVE_WAIT_QUEUE_HEAD_ENTRY
wq = list_entry(lh,
spl_wait_queue_entry_t, entry);
#else
wq = list_entry(lh,
spl_wait_queue_entry_t, task_list);
#endif
if (j == 0)
seq_printf(f, "\t%s:",
list_names[i]);
else if (j % 8 == 0)
seq_printf(f, "\n\t ");
tsk = wq->private;
seq_printf(f, " %d", tsk->pid);
/* pend, prio and delay lists */
} else {
tqe = list_entry(lh, taskq_ent_t,
tqent_list);
if (j == 0)
seq_printf(f, "\t%s:",
list_names[i]);
else if (j % 2 == 0)
seq_printf(f, "\n\t ");
seq_printf(f, " %pf(%ps)",
tqe->tqent_func,
tqe->tqent_arg);
}
++j;
}
seq_printf(f, "\n");
}
if (lheads[LHEAD_WAIT])
spin_unlock_irqrestore(&tq->tq_wait_waitq.lock, wflags);
spin_unlock_irqrestore(&tq->tq_lock, flags);
return (0);
}
static int
taskq_all_seq_show(struct seq_file *f, void *p)
{
return (taskq_seq_show_impl(f, p, B_TRUE));
}
static int
taskq_seq_show(struct seq_file *f, void *p)
{
return (taskq_seq_show_impl(f, p, B_FALSE));
}
static void *
taskq_seq_start(struct seq_file *f, loff_t *pos)
{
struct list_head *p;
loff_t n = *pos;
down_read(&tq_list_sem);
if (!n)
taskq_seq_show_headers(f);
p = tq_list.next;
while (n--) {
p = p->next;
if (p == &tq_list)
return (NULL);
}
return (list_entry(p, taskq_t, tq_taskqs));
}
static void *
taskq_seq_next(struct seq_file *f, void *p, loff_t *pos)
{
taskq_t *tq = p;
++*pos;
return ((tq->tq_taskqs.next == &tq_list) ?
NULL : list_entry(tq->tq_taskqs.next, taskq_t, tq_taskqs));
}
static void static void
slab_seq_show_headers(struct seq_file *f) slab_seq_show_headers(struct seq_file *f)
{ {
@ -325,6 +516,52 @@ static struct file_operations proc_slab_operations = {
.release = seq_release, .release = seq_release,
}; };
static void
taskq_seq_stop(struct seq_file *f, void *v)
{
up_read(&tq_list_sem);
}
static struct seq_operations taskq_all_seq_ops = {
.show = taskq_all_seq_show,
.start = taskq_seq_start,
.next = taskq_seq_next,
.stop = taskq_seq_stop,
};
static struct seq_operations taskq_seq_ops = {
.show = taskq_seq_show,
.start = taskq_seq_start,
.next = taskq_seq_next,
.stop = taskq_seq_stop,
};
static int
proc_taskq_all_open(struct inode *inode, struct file *filp)
{
return seq_open(filp, &taskq_all_seq_ops);
}
static int
proc_taskq_open(struct inode *inode, struct file *filp)
{
return seq_open(filp, &taskq_seq_ops);
}
static struct file_operations proc_taskq_all_operations = {
.open = proc_taskq_all_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
static struct file_operations proc_taskq_operations = {
.open = proc_taskq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
static struct ctl_table spl_kmem_table[] = { static struct ctl_table spl_kmem_table[] = {
#ifdef DEBUG_KMEM #ifdef DEBUG_KMEM
{ {
@ -402,11 +639,11 @@ static struct ctl_table spl_kmem_table[] = {
.mode = 0444, .mode = 0444,
.proc_handler = &proc_doslab, .proc_handler = &proc_doslab,
}, },
{0}, {},
}; };
static struct ctl_table spl_kstat_table[] = { static struct ctl_table spl_kstat_table[] = {
{0}, {},
}; };
static struct ctl_table spl_table[] = { static struct ctl_table spl_table[] = {
@ -437,7 +674,7 @@ static struct ctl_table spl_table[] = {
.mode = 0555, .mode = 0555,
.child = spl_kstat_table, .child = spl_kstat_table,
}, },
{ 0 }, {},
}; };
static struct ctl_table spl_dir[] = { static struct ctl_table spl_dir[] = {
@ -446,7 +683,7 @@ static struct ctl_table spl_dir[] = {
.mode = 0555, .mode = 0555,
.child = spl_table, .child = spl_table,
}, },
{ 0 } {}
}; };
static struct ctl_table spl_root[] = { static struct ctl_table spl_root[] = {
@ -458,7 +695,7 @@ static struct ctl_table spl_root[] = {
.mode = 0555, .mode = 0555,
.child = spl_dir, .child = spl_dir,
}, },
{ 0 } {}
}; };
int int
@ -476,6 +713,20 @@ spl_proc_init(void)
goto out; goto out;
} }
proc_spl_taskq_all = proc_create_data("taskq-all", 0444,
proc_spl, &proc_taskq_all_operations, NULL);
if (proc_spl_taskq_all == NULL) {
rc = -EUNATCH;
goto out;
}
proc_spl_taskq = proc_create_data("taskq", 0444,
proc_spl, &proc_taskq_operations, NULL);
if (proc_spl_taskq == NULL) {
rc = -EUNATCH;
goto out;
}
proc_spl_kmem = proc_mkdir("kmem", proc_spl); proc_spl_kmem = proc_mkdir("kmem", proc_spl);
if (proc_spl_kmem == NULL) { if (proc_spl_kmem == NULL) {
rc = -EUNATCH; rc = -EUNATCH;
@ -499,6 +750,8 @@ out:
remove_proc_entry("kstat", proc_spl); remove_proc_entry("kstat", proc_spl);
remove_proc_entry("slab", proc_spl_kmem); remove_proc_entry("slab", proc_spl_kmem);
remove_proc_entry("kmem", proc_spl); remove_proc_entry("kmem", proc_spl);
remove_proc_entry("taskq-all", proc_spl);
remove_proc_entry("taskq", proc_spl);
remove_proc_entry("spl", NULL); remove_proc_entry("spl", NULL);
unregister_sysctl_table(spl_header); unregister_sysctl_table(spl_header);
} }
@ -512,6 +765,8 @@ spl_proc_fini(void)
remove_proc_entry("kstat", proc_spl); remove_proc_entry("kstat", proc_spl);
remove_proc_entry("slab", proc_spl_kmem); remove_proc_entry("slab", proc_spl_kmem);
remove_proc_entry("kmem", proc_spl); remove_proc_entry("kmem", proc_spl);
remove_proc_entry("taskq-all", proc_spl);
remove_proc_entry("taskq", proc_spl);
remove_proc_entry("spl", NULL); remove_proc_entry("spl", NULL);
ASSERT(spl_header != NULL); ASSERT(spl_header != NULL);

View File

@ -32,7 +32,41 @@
#define DEBUG_SUBSYSTEM S_RWLOCK #define DEBUG_SUBSYSTEM S_RWLOCK
#if defined(CONFIG_RWSEM_GENERIC_SPINLOCK) #if defined(CONFIG_PREEMPT_RT_FULL)
#include <linux/rtmutex.h>
#define RT_MUTEX_OWNER_MASKALL 1UL
static int
__rwsem_tryupgrade(struct rw_semaphore *rwsem)
{
ASSERT((struct task_struct *)
((unsigned long)rwsem->lock.owner & ~RT_MUTEX_OWNER_MASKALL) ==
current);
/*
* Under the realtime patch series, rwsem is implemented as a
* single mutex held by readers and writers alike. However,
* this implementation would prevent a thread from taking a
* read lock twice, as the mutex would already be locked on
* the second attempt. Therefore the implementation allows a
* single thread to take a rwsem as read lock multiple times
* tracking that nesting as read_depth counter.
*/
if (rwsem->read_depth <= 1) {
/*
* In case, the current thread has not taken the lock
* more than once as read lock, we can allow an
* upgrade to a write lock. rwsem_rt.h implements
* write locks as read_depth == 0.
*/
rwsem->read_depth = 0;
return (1);
}
return (0);
}
#elif defined(CONFIG_RWSEM_GENERIC_SPINLOCK)
static int static int
__rwsem_tryupgrade(struct rw_semaphore *rwsem) __rwsem_tryupgrade(struct rw_semaphore *rwsem)
{ {

View File

@ -1,4 +1,4 @@
/*****************************************************************************\ /*
* Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC. * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
* Copyright (C) 2007 The Regents of the University of California. * Copyright (C) 2007 The Regents of the University of California.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
@ -20,50 +20,76 @@
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License along
* with the SPL. If not, see <http://www.gnu.org/licenses/>. * with the SPL. If not, see <http://www.gnu.org/licenses/>.
***************************************************************************** *
* Solaris Porting Layer (SPL) Task Queue Implementation. * Solaris Porting Layer (SPL) Task Queue Implementation.
\*****************************************************************************/ */
#include <sys/taskq.h> #include <sys/taskq.h>
#include <sys/kmem.h> #include <sys/kmem.h>
#include <sys/tsd.h>
int spl_taskq_thread_bind = 0; int spl_taskq_thread_bind = 0;
module_param(spl_taskq_thread_bind, int, 0644); module_param(spl_taskq_thread_bind, int, 0644);
MODULE_PARM_DESC(spl_taskq_thread_bind, "Bind taskq thread to CPU by default"); MODULE_PARM_DESC(spl_taskq_thread_bind, "Bind taskq thread to CPU by default");
int spl_taskq_thread_dynamic = 0; int spl_taskq_thread_dynamic = 1;
module_param(spl_taskq_thread_dynamic, int, 0644); module_param(spl_taskq_thread_dynamic, int, 0644);
MODULE_PARM_DESC(spl_taskq_thread_dynamic, "Allow dynamic taskq threads"); MODULE_PARM_DESC(spl_taskq_thread_dynamic, "Allow dynamic taskq threads");
int spl_taskq_thread_priority = 1; int spl_taskq_thread_priority = 1;
module_param(spl_taskq_thread_priority, int, 0644); module_param(spl_taskq_thread_priority, int, 0644);
MODULE_PARM_DESC(spl_taskq_thread_priority, MODULE_PARM_DESC(spl_taskq_thread_priority,
"Allow non-default priority for taskq threads"); "Allow non-default priority for taskq threads");
int spl_taskq_thread_sequential = 4; int spl_taskq_thread_sequential = 4;
module_param(spl_taskq_thread_sequential, int, 0644); module_param(spl_taskq_thread_sequential, int, 0644);
MODULE_PARM_DESC(spl_taskq_thread_sequential, MODULE_PARM_DESC(spl_taskq_thread_sequential,
"Create new taskq threads after N sequential tasks"); "Create new taskq threads after N sequential tasks");
/* Global system-wide dynamic task queue available for all consumers */ /* Global system-wide dynamic task queue available for all consumers */
taskq_t *system_taskq; taskq_t *system_taskq;
EXPORT_SYMBOL(system_taskq); EXPORT_SYMBOL(system_taskq);
/* Global dynamic task queue for long delay */
taskq_t *system_delay_taskq;
EXPORT_SYMBOL(system_delay_taskq);
/* Private dedicated taskq for creating new taskq threads on demand. */ /* Private dedicated taskq for creating new taskq threads on demand. */
static taskq_t *dynamic_taskq; static taskq_t *dynamic_taskq;
static taskq_thread_t *taskq_thread_create(taskq_t *); static taskq_thread_t *taskq_thread_create(taskq_t *);
/* List of all taskqs */
LIST_HEAD(tq_list);
DECLARE_RWSEM(tq_list_sem);
static uint_t taskq_tsd;
static int static int
task_km_flags(uint_t flags) task_km_flags(uint_t flags)
{ {
if (flags & TQ_NOSLEEP) if (flags & TQ_NOSLEEP)
return KM_NOSLEEP; return (KM_NOSLEEP);
if (flags & TQ_PUSHPAGE) if (flags & TQ_PUSHPAGE)
return KM_PUSHPAGE; return (KM_PUSHPAGE);
return KM_SLEEP; return (KM_SLEEP);
}
/*
* taskq_find_by_name - Find the largest instance number of a named taskq.
*/
static int
taskq_find_by_name(const char *name)
{
struct list_head *tql;
taskq_t *tq;
list_for_each_prev(tql, &tq_list) {
tq = list_entry(tql, taskq_t, tq_taskqs);
if (strcmp(name, tq->tq_name) == 0)
return tq->tq_instance;
}
return (-1);
} }
/* /*
@ -71,7 +97,7 @@ task_km_flags(uint_t flags)
* is not attached to the free, work, or pending taskq lists. * is not attached to the free, work, or pending taskq lists.
*/ */
static taskq_ent_t * static taskq_ent_t *
task_alloc(taskq_t *tq, uint_t flags) task_alloc(taskq_t *tq, uint_t flags, unsigned long *irqflags)
{ {
taskq_ent_t *t; taskq_ent_t *t;
int count = 0; int count = 0;
@ -111,18 +137,19 @@ retry:
* end up delaying the task allocation by one second, thereby * end up delaying the task allocation by one second, thereby
* throttling the task dispatch rate. * throttling the task dispatch rate.
*/ */
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); spin_unlock_irqrestore(&tq->tq_lock, *irqflags);
schedule_timeout(HZ / 100); schedule_timeout(HZ / 100);
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); spin_lock_irqsave_nested(&tq->tq_lock, *irqflags,
tq->tq_lock_class);
if (count < 100) { if (count < 100) {
count++; count++;
goto retry; goto retry;
} }
} }
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); spin_unlock_irqrestore(&tq->tq_lock, *irqflags);
t = kmem_alloc(sizeof(taskq_ent_t), task_km_flags(flags)); t = kmem_alloc(sizeof (taskq_ent_t), task_km_flags(flags));
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); spin_lock_irqsave_nested(&tq->tq_lock, *irqflags, tq->tq_lock_class);
if (t) { if (t) {
taskq_init_ent(t); taskq_init_ent(t);
@ -145,7 +172,7 @@ task_free(taskq_t *tq, taskq_ent_t *t)
ASSERT(list_empty(&t->tqent_list)); ASSERT(list_empty(&t->tqent_list));
ASSERT(!timer_pending(&t->tqent_timer)); ASSERT(!timer_pending(&t->tqent_timer));
kmem_free(t, sizeof(taskq_ent_t)); kmem_free(t, sizeof (taskq_ent_t));
tq->tq_nalloc--; tq->tq_nalloc--;
} }
@ -166,7 +193,7 @@ task_done(taskq_t *tq, taskq_ent_t *t)
list_del_init(&t->tqent_list); list_del_init(&t->tqent_list);
if (tq->tq_nalloc <= tq->tq_minalloc) { if (tq->tq_nalloc <= tq->tq_minalloc) {
t->tqent_id = 0; t->tqent_id = TASKQID_INVALID;
t->tqent_func = NULL; t->tqent_func = NULL;
t->tqent_arg = NULL; t->tqent_arg = NULL;
t->tqent_flags = 0; t->tqent_flags = 0;
@ -187,15 +214,17 @@ task_expire(unsigned long data)
taskq_ent_t *w, *t = (taskq_ent_t *)data; taskq_ent_t *w, *t = (taskq_ent_t *)data;
taskq_t *tq = t->tqent_taskq; taskq_t *tq = t->tqent_taskq;
struct list_head *l; struct list_head *l;
unsigned long flags;
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); spin_lock_irqsave_nested(&tq->tq_lock, flags, tq->tq_lock_class);
if (t->tqent_flags & TQENT_FLAG_CANCEL) { if (t->tqent_flags & TQENT_FLAG_CANCEL) {
ASSERT(list_empty(&t->tqent_list)); ASSERT(list_empty(&t->tqent_list));
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); spin_unlock_irqrestore(&tq->tq_lock, flags);
return; return;
} }
t->tqent_birth = jiffies;
/* /*
* The priority list must be maintained in strict task id order * The priority list must be maintained in strict task id order
* from lowest to highest for lowest_id to be easily calculable. * from lowest to highest for lowest_id to be easily calculable.
@ -211,7 +240,7 @@ task_expire(unsigned long data)
if (l == &tq->tq_prio_list) if (l == &tq->tq_prio_list)
list_add(&t->tqent_list, &tq->tq_prio_list); list_add(&t->tqent_list, &tq->tq_prio_list);
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); spin_unlock_irqrestore(&tq->tq_lock, flags);
wake_up(&tq->tq_work_waitq); wake_up(&tq->tq_work_waitq);
} }
@ -250,7 +279,7 @@ taskq_lowest_id(taskq_t *tq)
if (!list_empty(&tq->tq_active_list)) { if (!list_empty(&tq->tq_active_list)) {
tqt = list_entry(tq->tq_active_list.next, taskq_thread_t, tqt = list_entry(tq->tq_active_list.next, taskq_thread_t,
tqt_active_list); tqt_active_list);
ASSERT(tqt->tqt_id != 0); ASSERT(tqt->tqt_id != TASKQID_INVALID);
lowest_id = MIN(lowest_id, tqt->tqt_id); lowest_id = MIN(lowest_id, tqt->tqt_id);
} }
@ -378,10 +407,11 @@ taskq_wait_id_check(taskq_t *tq, taskqid_t id)
{ {
int active = 0; int active = 0;
int rc; int rc;
unsigned long flags;
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); spin_lock_irqsave_nested(&tq->tq_lock, flags, tq->tq_lock_class);
rc = (taskq_find(tq, id, &active) == NULL); rc = (taskq_find(tq, id, &active) == NULL);
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); spin_unlock_irqrestore(&tq->tq_lock, flags);
return (rc); return (rc);
} }
@ -401,10 +431,11 @@ static int
taskq_wait_outstanding_check(taskq_t *tq, taskqid_t id) taskq_wait_outstanding_check(taskq_t *tq, taskqid_t id)
{ {
int rc; int rc;
unsigned long flags;
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); spin_lock_irqsave_nested(&tq->tq_lock, flags, tq->tq_lock_class);
rc = (id < tq->tq_lowest_id); rc = (id < tq->tq_lowest_id);
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); spin_unlock_irqrestore(&tq->tq_lock, flags);
return (rc); return (rc);
} }
@ -428,10 +459,11 @@ static int
taskq_wait_check(taskq_t *tq) taskq_wait_check(taskq_t *tq)
{ {
int rc; int rc;
unsigned long flags;
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); spin_lock_irqsave_nested(&tq->tq_lock, flags, tq->tq_lock_class);
rc = (tq->tq_lowest_id == tq->tq_next_id); rc = (tq->tq_lowest_id == tq->tq_next_id);
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); spin_unlock_irqrestore(&tq->tq_lock, flags);
return (rc); return (rc);
} }
@ -448,37 +480,10 @@ taskq_wait(taskq_t *tq)
} }
EXPORT_SYMBOL(taskq_wait); EXPORT_SYMBOL(taskq_wait);
static int
taskq_member_impl(taskq_t *tq, void *t)
{
struct list_head *l;
taskq_thread_t *tqt;
int found = 0;
ASSERT(tq);
ASSERT(t);
ASSERT(spin_is_locked(&tq->tq_lock));
list_for_each(l, &tq->tq_thread_list) {
tqt = list_entry(l, taskq_thread_t, tqt_thread_list);
if (tqt->tqt_thread == (struct task_struct *)t) {
found = 1;
break;
}
}
return (found);
}
int int
taskq_member(taskq_t *tq, void *t) taskq_member(taskq_t *tq, kthread_t *t)
{ {
int found; return (tq == (taskq_t *)tsd_get_by_thread(taskq_tsd, t));
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
found = taskq_member_impl(tq, t);
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
return (found);
} }
EXPORT_SYMBOL(taskq_member); EXPORT_SYMBOL(taskq_member);
@ -494,10 +499,11 @@ taskq_cancel_id(taskq_t *tq, taskqid_t id)
taskq_ent_t *t; taskq_ent_t *t;
int active = 0; int active = 0;
int rc = ENOENT; int rc = ENOENT;
unsigned long flags;
ASSERT(tq); ASSERT(tq);
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); spin_lock_irqsave_nested(&tq->tq_lock, flags, tq->tq_lock_class);
t = taskq_find(tq, id, &active); t = taskq_find(tq, id, &active);
if (t && !active) { if (t && !active) {
list_del_init(&t->tqent_list); list_del_init(&t->tqent_list);
@ -517,9 +523,10 @@ taskq_cancel_id(taskq_t *tq, taskqid_t id)
* drop the lock before synchronously cancelling the timer. * drop the lock before synchronously cancelling the timer.
*/ */
if (timer_pending(&t->tqent_timer)) { if (timer_pending(&t->tqent_timer)) {
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); spin_unlock_irqrestore(&tq->tq_lock, flags);
del_timer_sync(&t->tqent_timer); del_timer_sync(&t->tqent_timer);
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); spin_lock_irqsave_nested(&tq->tq_lock, flags,
tq->tq_lock_class);
} }
if (!(t->tqent_flags & TQENT_FLAG_PREALLOC)) if (!(t->tqent_flags & TQENT_FLAG_PREALLOC))
@ -527,7 +534,7 @@ taskq_cancel_id(taskq_t *tq, taskqid_t id)
rc = 0; rc = 0;
} }
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); spin_unlock_irqrestore(&tq->tq_lock, flags);
if (active) { if (active) {
taskq_wait_id(tq, id); taskq_wait_id(tq, id);
@ -544,12 +551,13 @@ taskqid_t
taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t flags) taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t flags)
{ {
taskq_ent_t *t; taskq_ent_t *t;
taskqid_t rc = 0; taskqid_t rc = TASKQID_INVALID;
unsigned long irqflags;
ASSERT(tq); ASSERT(tq);
ASSERT(func); ASSERT(func);
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); spin_lock_irqsave_nested(&tq->tq_lock, irqflags, tq->tq_lock_class);
/* Taskq being destroyed and all tasks drained */ /* Taskq being destroyed and all tasks drained */
if (!(tq->tq_flags & TASKQ_ACTIVE)) if (!(tq->tq_flags & TASKQ_ACTIVE))
@ -557,16 +565,22 @@ taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t flags)
/* Do not queue the task unless there is idle thread for it */ /* Do not queue the task unless there is idle thread for it */
ASSERT(tq->tq_nactive <= tq->tq_nthreads); ASSERT(tq->tq_nactive <= tq->tq_nthreads);
if ((flags & TQ_NOQUEUE) && (tq->tq_nactive == tq->tq_nthreads)) if ((flags & TQ_NOQUEUE) && (tq->tq_nactive == tq->tq_nthreads)) {
goto out; /* Dynamic taskq may be able to spawn another thread */
if (!(tq->tq_flags & TASKQ_DYNAMIC) || taskq_thread_spawn(tq) == 0)
goto out;
}
if ((t = task_alloc(tq, flags)) == NULL) if ((t = task_alloc(tq, flags, &irqflags)) == NULL)
goto out; goto out;
spin_lock(&t->tqent_lock); spin_lock(&t->tqent_lock);
/* Queue to the front of the list to enforce TQ_NOQUEUE semantics */
if (flags & TQ_NOQUEUE)
list_add(&t->tqent_list, &tq->tq_prio_list);
/* Queue to the priority list instead of the pending list */ /* Queue to the priority list instead of the pending list */
if (flags & TQ_FRONT) else if (flags & TQ_FRONT)
list_add_tail(&t->tqent_list, &tq->tq_prio_list); list_add_tail(&t->tqent_list, &tq->tq_prio_list);
else else
list_add_tail(&t->tqent_list, &tq->tq_pend_list); list_add_tail(&t->tqent_list, &tq->tq_pend_list);
@ -579,6 +593,7 @@ taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t flags)
t->tqent_timer.data = 0; t->tqent_timer.data = 0;
t->tqent_timer.function = NULL; t->tqent_timer.function = NULL;
t->tqent_timer.expires = 0; t->tqent_timer.expires = 0;
t->tqent_birth = jiffies;
ASSERT(!(t->tqent_flags & TQENT_FLAG_PREALLOC)); ASSERT(!(t->tqent_flags & TQENT_FLAG_PREALLOC));
@ -587,10 +602,10 @@ taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t flags)
wake_up(&tq->tq_work_waitq); wake_up(&tq->tq_work_waitq);
out: out:
/* Spawn additional taskq threads if required. */ /* Spawn additional taskq threads if required. */
if (tq->tq_nactive == tq->tq_nthreads) if (!(flags & TQ_NOQUEUE) && tq->tq_nactive == tq->tq_nthreads)
(void) taskq_thread_spawn(tq); (void) taskq_thread_spawn(tq);
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); spin_unlock_irqrestore(&tq->tq_lock, irqflags);
return (rc); return (rc);
} }
EXPORT_SYMBOL(taskq_dispatch); EXPORT_SYMBOL(taskq_dispatch);
@ -599,19 +614,20 @@ taskqid_t
taskq_dispatch_delay(taskq_t *tq, task_func_t func, void *arg, taskq_dispatch_delay(taskq_t *tq, task_func_t func, void *arg,
uint_t flags, clock_t expire_time) uint_t flags, clock_t expire_time)
{ {
taskqid_t rc = 0; taskqid_t rc = TASKQID_INVALID;
taskq_ent_t *t; taskq_ent_t *t;
unsigned long irqflags;
ASSERT(tq); ASSERT(tq);
ASSERT(func); ASSERT(func);
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); spin_lock_irqsave_nested(&tq->tq_lock, irqflags, tq->tq_lock_class);
/* Taskq being destroyed and all tasks drained */ /* Taskq being destroyed and all tasks drained */
if (!(tq->tq_flags & TASKQ_ACTIVE)) if (!(tq->tq_flags & TASKQ_ACTIVE))
goto out; goto out;
if ((t = task_alloc(tq, flags)) == NULL) if ((t = task_alloc(tq, flags, &irqflags)) == NULL)
goto out; goto out;
spin_lock(&t->tqent_lock); spin_lock(&t->tqent_lock);
@ -636,28 +652,43 @@ out:
/* Spawn additional taskq threads if required. */ /* Spawn additional taskq threads if required. */
if (tq->tq_nactive == tq->tq_nthreads) if (tq->tq_nactive == tq->tq_nthreads)
(void) taskq_thread_spawn(tq); (void) taskq_thread_spawn(tq);
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); spin_unlock_irqrestore(&tq->tq_lock, irqflags);
return (rc); return (rc);
} }
EXPORT_SYMBOL(taskq_dispatch_delay); EXPORT_SYMBOL(taskq_dispatch_delay);
void void
taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags, taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags,
taskq_ent_t *t) taskq_ent_t *t)
{ {
unsigned long irqflags;
ASSERT(tq); ASSERT(tq);
ASSERT(func); ASSERT(func);
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); spin_lock_irqsave_nested(&tq->tq_lock, irqflags,
tq->tq_lock_class);
/* Taskq being destroyed and all tasks drained */ /* Taskq being destroyed and all tasks drained */
if (!(tq->tq_flags & TASKQ_ACTIVE)) { if (!(tq->tq_flags & TASKQ_ACTIVE)) {
t->tqent_id = 0; t->tqent_id = TASKQID_INVALID;
goto out; goto out;
} }
if ((flags & TQ_NOQUEUE) && (tq->tq_nactive == tq->tq_nthreads)) {
/* Dynamic taskq may be able to spawn another thread */
if (!(tq->tq_flags & TASKQ_DYNAMIC) || taskq_thread_spawn(tq) == 0)
goto out2;
flags |= TQ_FRONT;
}
spin_lock(&t->tqent_lock); spin_lock(&t->tqent_lock);
/*
* Make sure the entry is not on some other taskq; it is important to
* ASSERT() under lock
*/
ASSERT(taskq_empty_ent(t));
/* /*
* Mark it as a prealloc'd task. This is important * Mark it as a prealloc'd task. This is important
* to ensure that we don't free it later. * to ensure that we don't free it later.
@ -675,6 +706,7 @@ taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags,
t->tqent_func = func; t->tqent_func = func;
t->tqent_arg = arg; t->tqent_arg = arg;
t->tqent_taskq = tq; t->tqent_taskq = tq;
t->tqent_birth = jiffies;
spin_unlock(&t->tqent_lock); spin_unlock(&t->tqent_lock);
@ -683,14 +715,15 @@ out:
/* Spawn additional taskq threads if required. */ /* Spawn additional taskq threads if required. */
if (tq->tq_nactive == tq->tq_nthreads) if (tq->tq_nactive == tq->tq_nthreads)
(void) taskq_thread_spawn(tq); (void) taskq_thread_spawn(tq);
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); out2:
spin_unlock_irqrestore(&tq->tq_lock, irqflags);
} }
EXPORT_SYMBOL(taskq_dispatch_ent); EXPORT_SYMBOL(taskq_dispatch_ent);
int int
taskq_empty_ent(taskq_ent_t *t) taskq_empty_ent(taskq_ent_t *t)
{ {
return list_empty(&t->tqent_list); return (list_empty(&t->tqent_list));
} }
EXPORT_SYMBOL(taskq_empty_ent); EXPORT_SYMBOL(taskq_empty_ent);
@ -737,17 +770,18 @@ static void
taskq_thread_spawn_task(void *arg) taskq_thread_spawn_task(void *arg)
{ {
taskq_t *tq = (taskq_t *)arg; taskq_t *tq = (taskq_t *)arg;
unsigned long flags;
if (taskq_thread_create(tq) == NULL) { if (taskq_thread_create(tq) == NULL) {
/* restore spawning count if failed */ /* restore spawning count if failed */
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); spin_lock_irqsave_nested(&tq->tq_lock, flags, tq->tq_lock_class);
tq->tq_nspawn--; tq->tq_nspawn--;
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); spin_unlock_irqrestore(&tq->tq_lock, flags);
} }
} }
/* /*
* Spawn addition threads for dynamic taskqs (TASKQ_DYNMAIC) the current * Spawn addition threads for dynamic taskqs (TASKQ_DYNAMIC) the current
* number of threads is insufficient to handle the pending tasks. These * number of threads is insufficient to handle the pending tasks. These
* new threads must be created by the dedicated dynamic_taskq to avoid * new threads must be created by the dedicated dynamic_taskq to avoid
* deadlocks between thread creation and memory reclaim. The system_taskq * deadlocks between thread creation and memory reclaim. The system_taskq
@ -797,7 +831,7 @@ taskq_thread_should_stop(taskq_t *tq, taskq_thread_t *tqt)
(tq->tq_nactive == 0) && /* No threads are handling tasks */ (tq->tq_nactive == 0) && /* No threads are handling tasks */
(tq->tq_nthreads > 1) && /* More than 1 thread is running */ (tq->tq_nthreads > 1) && /* More than 1 thread is running */
(!taskq_next_ent(tq)) && /* There are no pending tasks */ (!taskq_next_ent(tq)) && /* There are no pending tasks */
(spl_taskq_thread_dynamic));/* Dynamic taskqs are allowed */ (spl_taskq_thread_dynamic)); /* Dynamic taskqs are allowed */
} }
static int static int
@ -809,8 +843,10 @@ taskq_thread(void *args)
taskq_t *tq; taskq_t *tq;
taskq_ent_t *t; taskq_ent_t *t;
int seq_tasks = 0; int seq_tasks = 0;
unsigned long flags;
ASSERT(tqt); ASSERT(tqt);
ASSERT(tqt->tqt_tq);
tq = tqt->tqt_tq; tq = tqt->tqt_tq;
current->flags |= PF_NOFREEZE; current->flags |= PF_NOFREEZE;
@ -820,7 +856,8 @@ taskq_thread(void *args)
sigprocmask(SIG_BLOCK, &blocked, NULL); sigprocmask(SIG_BLOCK, &blocked, NULL);
flush_signals(current); flush_signals(current);
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); tsd_set(taskq_tsd, tq);
spin_lock_irqsave_nested(&tq->tq_lock, flags, tq->tq_lock_class);
/* /*
* If we are dynamically spawned, decrease spawning count. Note that * If we are dynamically spawned, decrease spawning count. Note that
* we could be created during taskq_create, in which case we shouldn't * we could be created during taskq_create, in which case we shouldn't
@ -850,12 +887,13 @@ taskq_thread(void *args)
} }
add_wait_queue_exclusive(&tq->tq_work_waitq, &wait); add_wait_queue_exclusive(&tq->tq_work_waitq, &wait);
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); spin_unlock_irqrestore(&tq->tq_lock, flags);
schedule(); schedule();
seq_tasks = 0; seq_tasks = 0;
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); spin_lock_irqsave_nested(&tq->tq_lock, flags,
tq->tq_lock_class);
remove_wait_queue(&tq->tq_work_waitq, &wait); remove_wait_queue(&tq->tq_work_waitq, &wait);
} else { } else {
__set_current_state(TASK_RUNNING); __set_current_state(TASK_RUNNING);
@ -864,27 +902,32 @@ taskq_thread(void *args)
if ((t = taskq_next_ent(tq)) != NULL) { if ((t = taskq_next_ent(tq)) != NULL) {
list_del_init(&t->tqent_list); list_del_init(&t->tqent_list);
/* In order to support recursively dispatching a /*
* In order to support recursively dispatching a
* preallocated taskq_ent_t, tqent_id must be * preallocated taskq_ent_t, tqent_id must be
* stored prior to executing tqent_func. */ * stored prior to executing tqent_func.
*/
tqt->tqt_id = t->tqent_id; tqt->tqt_id = t->tqent_id;
tqt->tqt_task = t; tqt->tqt_task = t;
/* We must store a copy of the flags prior to /*
* We must store a copy of the flags prior to
* servicing the task (servicing a prealloc'd task * servicing the task (servicing a prealloc'd task
* returns the ownership of the tqent back to * returns the ownership of the tqent back to
* the caller of taskq_dispatch). Thus, * the caller of taskq_dispatch). Thus,
* tqent_flags _may_ change within the call. */ * tqent_flags _may_ change within the call.
*/
tqt->tqt_flags = t->tqent_flags; tqt->tqt_flags = t->tqent_flags;
taskq_insert_in_order(tq, tqt); taskq_insert_in_order(tq, tqt);
tq->tq_nactive++; tq->tq_nactive++;
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); spin_unlock_irqrestore(&tq->tq_lock, flags);
/* Perform the requested task */ /* Perform the requested task */
t->tqent_func(t->tqent_arg); t->tqent_func(t->tqent_arg);
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); spin_lock_irqsave_nested(&tq->tq_lock, flags,
tq->tq_lock_class);
tq->tq_nactive--; tq->tq_nactive--;
list_del_init(&tqt->tqt_active_list); list_del_init(&tqt->tqt_active_list);
tqt->tqt_task = NULL; tqt->tqt_task = NULL;
@ -893,8 +936,10 @@ taskq_thread(void *args)
if (!(tqt->tqt_flags & TQENT_FLAG_PREALLOC)) if (!(tqt->tqt_flags & TQENT_FLAG_PREALLOC))
task_done(tq, t); task_done(tq, t);
/* When the current lowest outstanding taskqid is /*
* done calculate the new lowest outstanding id */ * When the current lowest outstanding taskqid is
* done calculate the new lowest outstanding id
*/
if (tq->tq_lowest_id == tqt->tqt_id) { if (tq->tq_lowest_id == tqt->tqt_id) {
tq->tq_lowest_id = taskq_lowest_id(tq); tq->tq_lowest_id = taskq_lowest_id(tq);
ASSERT3S(tq->tq_lowest_id, >, tqt->tqt_id); ASSERT3S(tq->tq_lowest_id, >, tqt->tqt_id);
@ -905,7 +950,7 @@ taskq_thread(void *args)
taskq_thread_spawn(tq)) taskq_thread_spawn(tq))
seq_tasks = 0; seq_tasks = 0;
tqt->tqt_id = 0; tqt->tqt_id = TASKQID_INVALID;
tqt->tqt_flags = 0; tqt->tqt_flags = 0;
wake_up_all(&tq->tq_wait_waitq); wake_up_all(&tq->tq_wait_waitq);
} else { } else {
@ -922,7 +967,9 @@ taskq_thread(void *args)
list_del_init(&tqt->tqt_thread_list); list_del_init(&tqt->tqt_thread_list);
error: error:
kmem_free(tqt, sizeof (taskq_thread_t)); kmem_free(tqt, sizeof (taskq_thread_t));
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); spin_unlock_irqrestore(&tq->tq_lock, flags);
tsd_set(taskq_tsd, NULL);
return (0); return (0);
} }
@ -937,7 +984,7 @@ taskq_thread_create(taskq_t *tq)
INIT_LIST_HEAD(&tqt->tqt_thread_list); INIT_LIST_HEAD(&tqt->tqt_thread_list);
INIT_LIST_HEAD(&tqt->tqt_active_list); INIT_LIST_HEAD(&tqt->tqt_active_list);
tqt->tqt_tq = tq; tqt->tqt_tq = tq;
tqt->tqt_id = 0; tqt->tqt_id = TASKQID_INVALID;
tqt->tqt_thread = spl_kthread_create(taskq_thread, tqt, tqt->tqt_thread = spl_kthread_create(taskq_thread, tqt,
"%s", tq->tq_name); "%s", tq->tq_name);
@ -966,6 +1013,7 @@ taskq_create(const char *name, int nthreads, pri_t pri,
taskq_t *tq; taskq_t *tq;
taskq_thread_t *tqt; taskq_thread_t *tqt;
int count = 0, rc = 0, i; int count = 0, rc = 0, i;
unsigned long irqflags;
ASSERT(name != NULL); ASSERT(name != NULL);
ASSERT(minalloc >= 0); ASSERT(minalloc >= 0);
@ -988,32 +1036,36 @@ taskq_create(const char *name, int nthreads, pri_t pri,
spin_lock_init(&tq->tq_lock); spin_lock_init(&tq->tq_lock);
INIT_LIST_HEAD(&tq->tq_thread_list); INIT_LIST_HEAD(&tq->tq_thread_list);
INIT_LIST_HEAD(&tq->tq_active_list); INIT_LIST_HEAD(&tq->tq_active_list);
tq->tq_name = strdup(name); tq->tq_name = strdup(name);
tq->tq_nactive = 0; tq->tq_nactive = 0;
tq->tq_nthreads = 0; tq->tq_nthreads = 0;
tq->tq_nspawn = 0; tq->tq_nspawn = 0;
tq->tq_maxthreads = nthreads; tq->tq_maxthreads = nthreads;
tq->tq_pri = pri; tq->tq_pri = pri;
tq->tq_minalloc = minalloc; tq->tq_minalloc = minalloc;
tq->tq_maxalloc = maxalloc; tq->tq_maxalloc = maxalloc;
tq->tq_nalloc = 0; tq->tq_nalloc = 0;
tq->tq_flags = (flags | TASKQ_ACTIVE); tq->tq_flags = (flags | TASKQ_ACTIVE);
tq->tq_next_id = 1; tq->tq_next_id = TASKQID_INITIAL;
tq->tq_lowest_id = 1; tq->tq_lowest_id = TASKQID_INITIAL;
INIT_LIST_HEAD(&tq->tq_free_list); INIT_LIST_HEAD(&tq->tq_free_list);
INIT_LIST_HEAD(&tq->tq_pend_list); INIT_LIST_HEAD(&tq->tq_pend_list);
INIT_LIST_HEAD(&tq->tq_prio_list); INIT_LIST_HEAD(&tq->tq_prio_list);
INIT_LIST_HEAD(&tq->tq_delay_list); INIT_LIST_HEAD(&tq->tq_delay_list);
init_waitqueue_head(&tq->tq_work_waitq); init_waitqueue_head(&tq->tq_work_waitq);
init_waitqueue_head(&tq->tq_wait_waitq); init_waitqueue_head(&tq->tq_wait_waitq);
tq->tq_lock_class = TQ_LOCK_GENERAL;
INIT_LIST_HEAD(&tq->tq_taskqs);
if (flags & TASKQ_PREPOPULATE) { if (flags & TASKQ_PREPOPULATE) {
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); spin_lock_irqsave_nested(&tq->tq_lock, irqflags,
tq->tq_lock_class);
for (i = 0; i < minalloc; i++) for (i = 0; i < minalloc; i++)
task_done(tq, task_alloc(tq, TQ_PUSHPAGE | TQ_NEW)); task_done(tq, task_alloc(tq, TQ_PUSHPAGE | TQ_NEW,
&irqflags));
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); spin_unlock_irqrestore(&tq->tq_lock, irqflags);
} }
if ((flags & TASKQ_DYNAMIC) && spl_taskq_thread_dynamic) if ((flags & TASKQ_DYNAMIC) && spl_taskq_thread_dynamic)
@ -1038,6 +1090,11 @@ taskq_create(const char *name, int nthreads, pri_t pri,
if (rc) { if (rc) {
taskq_destroy(tq); taskq_destroy(tq);
tq = NULL; tq = NULL;
} else {
down_write(&tq_list_sem);
tq->tq_instance = taskq_find_by_name(name) + 1;
list_add_tail(&tq->tq_taskqs, &tq_list);
up_write(&tq_list_sem);
} }
return (tq); return (tq);
@ -1050,11 +1107,12 @@ taskq_destroy(taskq_t *tq)
struct task_struct *thread; struct task_struct *thread;
taskq_thread_t *tqt; taskq_thread_t *tqt;
taskq_ent_t *t; taskq_ent_t *t;
unsigned long flags;
ASSERT(tq); ASSERT(tq);
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); spin_lock_irqsave_nested(&tq->tq_lock, flags, tq->tq_lock_class);
tq->tq_flags &= ~TASKQ_ACTIVE; tq->tq_flags &= ~TASKQ_ACTIVE;
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); spin_unlock_irqrestore(&tq->tq_lock, flags);
/* /*
* When TASKQ_ACTIVE is clear new tasks may not be added nor may * When TASKQ_ACTIVE is clear new tasks may not be added nor may
@ -1065,12 +1123,17 @@ taskq_destroy(taskq_t *tq)
taskq_wait(tq); taskq_wait(tq);
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); /* remove taskq from global list used by the kstats */
down_write(&tq_list_sem);
list_del(&tq->tq_taskqs);
up_write(&tq_list_sem);
spin_lock_irqsave_nested(&tq->tq_lock, flags, tq->tq_lock_class);
/* wait for spawning threads to insert themselves to the list */ /* wait for spawning threads to insert themselves to the list */
while (tq->tq_nspawn) { while (tq->tq_nspawn) {
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); spin_unlock_irqrestore(&tq->tq_lock, flags);
schedule_timeout_interruptible(1); schedule_timeout_interruptible(1);
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); spin_lock_irqsave_nested(&tq->tq_lock, flags, tq->tq_lock_class);
} }
/* /*
@ -1083,11 +1146,12 @@ taskq_destroy(taskq_t *tq)
tqt = list_entry(tq->tq_thread_list.next, tqt = list_entry(tq->tq_thread_list.next,
taskq_thread_t, tqt_thread_list); taskq_thread_t, tqt_thread_list);
thread = tqt->tqt_thread; thread = tqt->tqt_thread;
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); spin_unlock_irqrestore(&tq->tq_lock, flags);
kthread_stop(thread); kthread_stop(thread);
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); spin_lock_irqsave_nested(&tq->tq_lock, flags,
tq->tq_lock_class);
} }
while (!list_empty(&tq->tq_free_list)) { while (!list_empty(&tq->tq_free_list)) {
@ -1109,28 +1173,102 @@ taskq_destroy(taskq_t *tq)
ASSERT(list_empty(&tq->tq_prio_list)); ASSERT(list_empty(&tq->tq_prio_list));
ASSERT(list_empty(&tq->tq_delay_list)); ASSERT(list_empty(&tq->tq_delay_list));
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); spin_unlock_irqrestore(&tq->tq_lock, flags);
strfree(tq->tq_name); strfree(tq->tq_name);
kmem_free(tq, sizeof (taskq_t)); kmem_free(tq, sizeof (taskq_t));
} }
EXPORT_SYMBOL(taskq_destroy); EXPORT_SYMBOL(taskq_destroy);
static unsigned int spl_taskq_kick = 0;
/*
* 2.6.36 API Change
* module_param_cb is introduced to take kernel_param_ops and
* module_param_call is marked as obsolete. Also set and get operations
* were changed to take a 'const struct kernel_param *'.
*/
static int
#ifdef module_param_cb
param_set_taskq_kick(const char *val, const struct kernel_param *kp)
#else
param_set_taskq_kick(const char *val, struct kernel_param *kp)
#endif
{
int ret;
taskq_t *tq;
taskq_ent_t *t;
unsigned long flags;
ret = param_set_uint(val, kp);
if (ret < 0 || !spl_taskq_kick)
return (ret);
/* reset value */
spl_taskq_kick = 0;
down_read(&tq_list_sem);
list_for_each_entry(tq, &tq_list, tq_taskqs) {
spin_lock_irqsave_nested(&tq->tq_lock, flags,
tq->tq_lock_class);
/* Check if the first pending is older than 5 seconds */
t = taskq_next_ent(tq);
if (t && time_after(jiffies, t->tqent_birth + 5*HZ)) {
(void) taskq_thread_spawn(tq);
printk(KERN_INFO "spl: Kicked taskq %s/%d\n",
tq->tq_name, tq->tq_instance);
}
spin_unlock_irqrestore(&tq->tq_lock, flags);
}
up_read(&tq_list_sem);
return (ret);
}
#ifdef module_param_cb
static const struct kernel_param_ops param_ops_taskq_kick = {
.set = param_set_taskq_kick,
.get = param_get_uint,
};
module_param_cb(spl_taskq_kick, &param_ops_taskq_kick, &spl_taskq_kick, 0644);
#else
module_param_call(spl_taskq_kick, param_set_taskq_kick, param_get_uint,
&spl_taskq_kick, 0644);
#endif
MODULE_PARM_DESC(spl_taskq_kick,
"Write nonzero to kick stuck taskqs to spawn more threads");
int int
spl_taskq_init(void) spl_taskq_init(void)
{ {
tsd_create(&taskq_tsd, NULL);
system_taskq = taskq_create("spl_system_taskq", MAX(boot_ncpus, 64), system_taskq = taskq_create("spl_system_taskq", MAX(boot_ncpus, 64),
maxclsyspri, boot_ncpus, INT_MAX, TASKQ_PREPOPULATE|TASKQ_DYNAMIC); maxclsyspri, boot_ncpus, INT_MAX, TASKQ_PREPOPULATE|TASKQ_DYNAMIC);
if (system_taskq == NULL) if (system_taskq == NULL)
return (1); return (1);
system_delay_taskq = taskq_create("spl_delay_taskq", MAX(boot_ncpus, 4),
maxclsyspri, boot_ncpus, INT_MAX, TASKQ_PREPOPULATE|TASKQ_DYNAMIC);
if (system_delay_taskq == NULL) {
taskq_destroy(system_taskq);
return (1);
}
dynamic_taskq = taskq_create("spl_dynamic_taskq", 1, dynamic_taskq = taskq_create("spl_dynamic_taskq", 1,
maxclsyspri, boot_ncpus, INT_MAX, TASKQ_PREPOPULATE); maxclsyspri, boot_ncpus, INT_MAX, TASKQ_PREPOPULATE);
if (dynamic_taskq == NULL) { if (dynamic_taskq == NULL) {
taskq_destroy(system_taskq); taskq_destroy(system_taskq);
taskq_destroy(system_delay_taskq);
return (1); return (1);
} }
/*
* This is used to annotate tq_lock, so
* taskq_dispatch -> taskq_thread_spawn -> taskq_dispatch
* does not trigger a lockdep warning re: possible recursive locking
*/
dynamic_taskq->tq_lock_class = TQ_LOCK_DYNAMIC;
return (0); return (0);
} }
@ -1140,6 +1278,11 @@ spl_taskq_fini(void)
taskq_destroy(dynamic_taskq); taskq_destroy(dynamic_taskq);
dynamic_taskq = NULL; dynamic_taskq = NULL;
taskq_destroy(system_delay_taskq);
system_delay_taskq = NULL;
taskq_destroy(system_taskq); taskq_destroy(system_taskq);
system_taskq = NULL; system_taskq = NULL;
tsd_destroy(&taskq_tsd);
} }

View File

@ -527,6 +527,33 @@ tsd_get(uint_t key)
} }
EXPORT_SYMBOL(tsd_get); EXPORT_SYMBOL(tsd_get);
/*
* tsd_get_by_thread - get thread specific data for specified thread
* @key: lookup key
* @thread: thread to lookup
*
* Caller must prevent racing tsd_create() or tsd_destroy(). This
* implementation is designed to be fast and scalable, it does not
* lock the entire table only a single hash bin.
*/
void *
tsd_get_by_thread(uint_t key, kthread_t *thread)
{
tsd_hash_entry_t *entry;
ASSERT3P(tsd_hash_table, !=, NULL);
if ((key == 0) || (key > TSD_KEYS_MAX))
return (NULL);
entry = tsd_hash_search(tsd_hash_table, key, thread->pid);
if (entry == NULL)
return (NULL);
return (entry->he_value);
}
EXPORT_SYMBOL(tsd_get_by_thread);
/* /*
* tsd_create - create thread specific data key * tsd_create - create thread specific data key
* @keyp: lookup key address * @keyp: lookup key address

View File

@ -24,6 +24,7 @@
#include <sys/debug.h> #include <sys/debug.h>
#include <sys/vmem.h> #include <sys/vmem.h>
#include <sys/kmem_cache.h>
#include <linux/mm_compat.h> #include <linux/mm_compat.h>
#include <linux/module.h> #include <linux/module.h>
@ -36,14 +37,39 @@ EXPORT_SYMBOL(zio_alloc_arena);
vmem_t *zio_arena = NULL; vmem_t *zio_arena = NULL;
EXPORT_SYMBOL(zio_arena); EXPORT_SYMBOL(zio_arena);
#define VMEM_FLOOR_SIZE (4 * 1024 * 1024) /* 4MB floor */
/*
* Return approximate virtual memory usage based on these assumptions:
*
* 1) The major SPL consumer of virtual memory is the kmem cache.
* 2) Memory allocated with vmem_alloc() is short lived and can be ignored.
* 3) Allow a 4MB floor as a generous pad given normal consumption.
* 4) The spl_kmem_cache_sem only contends with cache create/destroy.
*/
size_t size_t
vmem_size(vmem_t *vmp, int typemask) vmem_size(vmem_t *vmp, int typemask)
{ {
ASSERT3P(vmp, ==, NULL); spl_kmem_cache_t *skc;
ASSERT3S(typemask & VMEM_ALLOC, ==, VMEM_ALLOC); size_t alloc = VMEM_FLOOR_SIZE;
ASSERT3S(typemask & VMEM_FREE, ==, VMEM_FREE);
return (VMALLOC_TOTAL); if ((typemask & VMEM_ALLOC) && (typemask & VMEM_FREE))
return (VMALLOC_TOTAL);
down_read(&spl_kmem_cache_sem);
list_for_each_entry(skc, &spl_kmem_cache_list, skc_list) {
if (skc->skc_flags & KMC_VMEM)
alloc += skc->skc_slab_size * skc->skc_slab_total;
}
up_read(&spl_kmem_cache_sem);
if (typemask & VMEM_ALLOC)
return (MIN(alloc, VMALLOC_TOTAL));
else if (typemask & VMEM_FREE)
return (MAX(VMALLOC_TOTAL - alloc, 0));
else
return (0);
} }
EXPORT_SYMBOL(vmem_size); EXPORT_SYMBOL(vmem_size);

View File

@ -63,9 +63,6 @@ vn_mode_to_vtype(mode_t mode)
if (S_ISSOCK(mode)) if (S_ISSOCK(mode))
return VSOCK; return VSOCK;
if (S_ISCHR(mode))
return VCHR;
return VNON; return VNON;
} /* vn_mode_to_vtype() */ } /* vn_mode_to_vtype() */
EXPORT_SYMBOL(vn_mode_to_vtype); EXPORT_SYMBOL(vn_mode_to_vtype);
@ -224,7 +221,6 @@ vn_rdwr(uio_rw_t uio, vnode_t *vp, void *addr, ssize_t len, offset_t off,
ASSERT(vp->v_file); ASSERT(vp->v_file);
ASSERT(seg == UIO_SYSSPACE); ASSERT(seg == UIO_SYSSPACE);
ASSERT((ioflag & ~FAPPEND) == 0); ASSERT((ioflag & ~FAPPEND) == 0);
ASSERT(x2 == RLIM64_INFINITY);
fp = vp->v_file; fp = vp->v_file;
@ -677,6 +673,19 @@ vn_getf(int fd)
fp = file_find(fd, current); fp = file_find(fd, current);
if (fp) { if (fp) {
lfp = fget(fd);
fput(fp->f_file);
/*
* areleasef() can cause us to see a stale reference when
* userspace has reused a file descriptor before areleasef()
* has run. fput() the stale reference and replace it. We
* retain the original reference count such that the concurrent
* areleasef() will decrement its reference and terminate.
*/
if (lfp != fp->f_file) {
fp->f_file = lfp;
fp->f_vnode->v_file = lfp;
}
atomic_inc(&fp->f_ref); atomic_inc(&fp->f_ref);
spin_unlock(&vn_file_lock); spin_unlock(&vn_file_lock);
return (fp); return (fp);

View File

@ -28,6 +28,7 @@
#include <sys/thread.h> #include <sys/thread.h>
#include <sys/mutex.h> #include <sys/mutex.h>
#include <linux/mm_compat.h> #include <linux/mm_compat.h>
#include <linux/wait_compat.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "splat-internal.h" #include "splat-internal.h"
@ -55,7 +56,7 @@ typedef struct atomic_priv {
unsigned long ap_magic; unsigned long ap_magic;
struct file *ap_file; struct file *ap_file;
kmutex_t ap_lock; kmutex_t ap_lock;
wait_queue_head_t ap_waitq; spl_wait_queue_head_t ap_waitq;
volatile uint64_t ap_atomic; volatile uint64_t ap_atomic;
volatile uint64_t ap_atomic_exited; volatile uint64_t ap_atomic_exited;
atomic_op_t ap_op; atomic_op_t ap_op;
@ -211,7 +212,7 @@ splat_atomic_init(void)
spin_lock_init(&sub->test_lock); spin_lock_init(&sub->test_lock);
sub->desc.id = SPLAT_SUBSYSTEM_ATOMIC; sub->desc.id = SPLAT_SUBSYSTEM_ATOMIC;
SPLAT_TEST_INIT(sub, SPLAT_ATOMIC_TEST1_NAME, SPLAT_ATOMIC_TEST1_DESC, splat_test_init(sub, SPLAT_ATOMIC_TEST1_NAME, SPLAT_ATOMIC_TEST1_DESC,
SPLAT_ATOMIC_TEST1_ID, splat_atomic_test1); SPLAT_ATOMIC_TEST1_ID, splat_atomic_test1);
return sub; return sub;
@ -221,7 +222,7 @@ void
splat_atomic_fini(splat_subsystem_t *sub) splat_atomic_fini(splat_subsystem_t *sub)
{ {
ASSERT(sub); ASSERT(sub);
SPLAT_TEST_FINI(sub, SPLAT_ATOMIC_TEST1_ID); splat_test_fini(sub, SPLAT_ATOMIC_TEST1_ID);
kfree(sub); kfree(sub);
} }

View File

@ -478,15 +478,15 @@ splat_condvar_init(void)
spin_lock_init(&sub->test_lock); spin_lock_init(&sub->test_lock);
sub->desc.id = SPLAT_SUBSYSTEM_CONDVAR; sub->desc.id = SPLAT_SUBSYSTEM_CONDVAR;
SPLAT_TEST_INIT(sub, SPLAT_CONDVAR_TEST1_NAME, SPLAT_CONDVAR_TEST1_DESC, splat_test_init(sub, SPLAT_CONDVAR_TEST1_NAME, SPLAT_CONDVAR_TEST1_DESC,
SPLAT_CONDVAR_TEST1_ID, splat_condvar_test1); SPLAT_CONDVAR_TEST1_ID, splat_condvar_test1);
SPLAT_TEST_INIT(sub, SPLAT_CONDVAR_TEST2_NAME, SPLAT_CONDVAR_TEST2_DESC, splat_test_init(sub, SPLAT_CONDVAR_TEST2_NAME, SPLAT_CONDVAR_TEST2_DESC,
SPLAT_CONDVAR_TEST2_ID, splat_condvar_test2); SPLAT_CONDVAR_TEST2_ID, splat_condvar_test2);
SPLAT_TEST_INIT(sub, SPLAT_CONDVAR_TEST3_NAME, SPLAT_CONDVAR_TEST3_DESC, splat_test_init(sub, SPLAT_CONDVAR_TEST3_NAME, SPLAT_CONDVAR_TEST3_DESC,
SPLAT_CONDVAR_TEST3_ID, splat_condvar_test3); SPLAT_CONDVAR_TEST3_ID, splat_condvar_test3);
SPLAT_TEST_INIT(sub, SPLAT_CONDVAR_TEST4_NAME, SPLAT_CONDVAR_TEST4_DESC, splat_test_init(sub, SPLAT_CONDVAR_TEST4_NAME, SPLAT_CONDVAR_TEST4_DESC,
SPLAT_CONDVAR_TEST4_ID, splat_condvar_test4); SPLAT_CONDVAR_TEST4_ID, splat_condvar_test4);
SPLAT_TEST_INIT(sub, SPLAT_CONDVAR_TEST5_NAME, SPLAT_CONDVAR_TEST5_DESC, splat_test_init(sub, SPLAT_CONDVAR_TEST5_NAME, SPLAT_CONDVAR_TEST5_DESC,
SPLAT_CONDVAR_TEST5_ID, splat_condvar_test5); SPLAT_CONDVAR_TEST5_ID, splat_condvar_test5);
return sub; return sub;
@ -496,11 +496,11 @@ void
splat_condvar_fini(splat_subsystem_t *sub) splat_condvar_fini(splat_subsystem_t *sub)
{ {
ASSERT(sub); ASSERT(sub);
SPLAT_TEST_FINI(sub, SPLAT_CONDVAR_TEST5_ID); splat_test_fini(sub, SPLAT_CONDVAR_TEST5_ID);
SPLAT_TEST_FINI(sub, SPLAT_CONDVAR_TEST4_ID); splat_test_fini(sub, SPLAT_CONDVAR_TEST4_ID);
SPLAT_TEST_FINI(sub, SPLAT_CONDVAR_TEST3_ID); splat_test_fini(sub, SPLAT_CONDVAR_TEST3_ID);
SPLAT_TEST_FINI(sub, SPLAT_CONDVAR_TEST2_ID); splat_test_fini(sub, SPLAT_CONDVAR_TEST2_ID);
SPLAT_TEST_FINI(sub, SPLAT_CONDVAR_TEST1_ID); splat_test_fini(sub, SPLAT_CONDVAR_TEST1_ID);
kfree(sub); kfree(sub);
} }

View File

@ -270,11 +270,11 @@ splat_cred_init(void)
spin_lock_init(&sub->test_lock); spin_lock_init(&sub->test_lock);
sub->desc.id = SPLAT_SUBSYSTEM_CRED; sub->desc.id = SPLAT_SUBSYSTEM_CRED;
SPLAT_TEST_INIT(sub, SPLAT_CRED_TEST1_NAME, SPLAT_CRED_TEST1_DESC, splat_test_init(sub, SPLAT_CRED_TEST1_NAME, SPLAT_CRED_TEST1_DESC,
SPLAT_CRED_TEST1_ID, splat_cred_test1); SPLAT_CRED_TEST1_ID, splat_cred_test1);
SPLAT_TEST_INIT(sub, SPLAT_CRED_TEST2_NAME, SPLAT_CRED_TEST2_DESC, splat_test_init(sub, SPLAT_CRED_TEST2_NAME, SPLAT_CRED_TEST2_DESC,
SPLAT_CRED_TEST2_ID, splat_cred_test2); SPLAT_CRED_TEST2_ID, splat_cred_test2);
SPLAT_TEST_INIT(sub, SPLAT_CRED_TEST3_NAME, SPLAT_CRED_TEST3_DESC, splat_test_init(sub, SPLAT_CRED_TEST3_NAME, SPLAT_CRED_TEST3_DESC,
SPLAT_CRED_TEST3_ID, splat_cred_test3); SPLAT_CRED_TEST3_ID, splat_cred_test3);
return sub; return sub;
@ -285,9 +285,9 @@ splat_cred_fini(splat_subsystem_t *sub)
{ {
ASSERT(sub); ASSERT(sub);
SPLAT_TEST_FINI(sub, SPLAT_CRED_TEST3_ID); splat_test_fini(sub, SPLAT_CRED_TEST3_ID);
SPLAT_TEST_FINI(sub, SPLAT_CRED_TEST2_ID); splat_test_fini(sub, SPLAT_CRED_TEST2_ID);
SPLAT_TEST_FINI(sub, SPLAT_CRED_TEST1_ID); splat_test_fini(sub, SPLAT_CRED_TEST1_ID);
kfree(sub); kfree(sub);
} /* splat_cred_fini() */ } /* splat_cred_fini() */

View File

@ -33,10 +33,10 @@
* the kmem interfaces have been implemented correctly. When the splat * the kmem interfaces have been implemented correctly. When the splat
* module is loaded splat_*_init() will be called for each subsystems * module is loaded splat_*_init() will be called for each subsystems
* tests. It is the responsibility of splat_*_init() to register all * tests. It is the responsibility of splat_*_init() to register all
* the tests for this subsystem using the SPLAT_TEST_INIT() macro. * the tests for this subsystem using the splat_test_init().
* Similarly splat_*_fini() is called when the splat module is removed * Similarly splat_*_fini() is called when the splat module is removed
* and is responsible for unregistering its tests via the SPLAT_TEST_FINI * and is responsible for unregistering its tests via the splat_test_fini.
* macro. Once a test is registered it can then be run with an ioctl() * Once a test is registered it can then be run with an ioctl()
* call which specifies the subsystem and test to be run. The provided * call which specifies the subsystem and test to be run. The provided
* splat command line tool can be used to display all available * splat command line tool can be used to display all available
* subsystems and tests. It can also be used to run the full suite * subsystems and tests. It can also be used to run the full suite
@ -599,6 +599,88 @@ static struct miscdevice splat_misc = {
.fops = &splat_fops, .fops = &splat_fops,
}; };
static void splat_subsystem_init(const char *name,
splat_subsystem_t *(*init)(void))
{
splat_subsystem_t *sub;
sub = init();
if (sub == NULL) {
printk(KERN_ERR "splat: Error initializing: %s\n", name);
return;
}
spin_lock(&splat_module_lock);
list_add_tail(&sub->subsystem_list, &splat_module_list);
spin_unlock(&splat_module_lock);
}
static void splat_subsystem_fini(const char *name,
int (*id_func)(void), void (*fini)(splat_subsystem_t *))
{
splat_subsystem_t *sub, *tmp;
int id, flag = 0;
id = id_func();
spin_lock(&splat_module_lock);
list_for_each_entry_safe(sub, tmp, &splat_module_list, subsystem_list) {
if (sub->desc.id == id) {
list_del_init(&sub->subsystem_list);
flag = 1;
break;
}
}
spin_unlock(&splat_module_lock);
if (flag == 0)
printk(KERN_ERR "splat: Error finalizing: %s\n", name);
else
fini(sub);
}
#define SPLAT_SUBSYSTEM_INIT(type) \
splat_subsystem_init(#type, splat_##type##_init)
#define SPLAT_SUBSYSTEM_FINI(type) \
splat_subsystem_fini(#type, splat_##type##_id, splat_##type##_fini)
void splat_test_init(splat_subsystem_t *sub, const char *name,
const char *desc, unsigned int tid, splat_test_func_t func)
{
splat_test_t *test;
test = kmalloc(sizeof (splat_test_t), GFP_KERNEL);
if (test == NULL) {
printk(KERN_ERR "splat: Error initializing: %s/%u\n",
name, tid);
return;
}
memset(test, 0, sizeof (splat_test_t));
strncpy(test->desc.name, name, SPLAT_NAME_SIZE-1);
strncpy(test->desc.desc, desc, SPLAT_DESC_SIZE-1);
test->desc.id = tid;
test->test = func;
INIT_LIST_HEAD(&test->test_list);
spin_lock(&sub->test_lock);
list_add_tail(&test->test_list, &sub->test_list);
spin_unlock(&sub->test_lock);
}
void splat_test_fini(splat_subsystem_t *sub, unsigned int tid)
{
splat_test_t *test, *tmp;
int flag = 0;
spin_lock(&sub->test_lock);
list_for_each_entry_safe(test, tmp, &sub->test_list, test_list) {
if (test->desc.id == tid) {
list_del_init(&test->test_list);
kfree(test);
flag = 1;
break;
}
}
spin_unlock(&sub->test_lock);
if (flag == 0)
printk(KERN_ERR "splat: Error finalizing: %u\n", tid);
}
static int __init static int __init
splat_init(void) splat_init(void)
{ {

View File

@ -329,17 +329,17 @@ splat_generic_init(void)
spin_lock_init(&sub->test_lock); spin_lock_init(&sub->test_lock);
sub->desc.id = SPLAT_SUBSYSTEM_GENERIC; sub->desc.id = SPLAT_SUBSYSTEM_GENERIC;
SPLAT_TEST_INIT(sub, SPLAT_GENERIC_TEST1_NAME, SPLAT_GENERIC_TEST1_DESC, splat_test_init(sub, SPLAT_GENERIC_TEST1_NAME, SPLAT_GENERIC_TEST1_DESC,
SPLAT_GENERIC_TEST1_ID, splat_generic_test_strtoul); SPLAT_GENERIC_TEST1_ID, splat_generic_test_strtoul);
SPLAT_TEST_INIT(sub, SPLAT_GENERIC_TEST2_NAME, SPLAT_GENERIC_TEST2_DESC, splat_test_init(sub, SPLAT_GENERIC_TEST2_NAME, SPLAT_GENERIC_TEST2_DESC,
SPLAT_GENERIC_TEST2_ID, splat_generic_test_strtol); SPLAT_GENERIC_TEST2_ID, splat_generic_test_strtol);
SPLAT_TEST_INIT(sub, SPLAT_GENERIC_TEST3_NAME, SPLAT_GENERIC_TEST3_DESC, splat_test_init(sub, SPLAT_GENERIC_TEST3_NAME, SPLAT_GENERIC_TEST3_DESC,
SPLAT_GENERIC_TEST3_ID, splat_generic_test_strtoull); SPLAT_GENERIC_TEST3_ID, splat_generic_test_strtoull);
SPLAT_TEST_INIT(sub, SPLAT_GENERIC_TEST4_NAME, SPLAT_GENERIC_TEST4_DESC, splat_test_init(sub, SPLAT_GENERIC_TEST4_NAME, SPLAT_GENERIC_TEST4_DESC,
SPLAT_GENERIC_TEST4_ID, splat_generic_test_strtoll); SPLAT_GENERIC_TEST4_ID, splat_generic_test_strtoll);
SPLAT_TEST_INIT(sub, SPLAT_GENERIC_TEST5_NAME, SPLAT_GENERIC_TEST5_DESC, splat_test_init(sub, SPLAT_GENERIC_TEST5_NAME, SPLAT_GENERIC_TEST5_DESC,
SPLAT_GENERIC_TEST5_ID, splat_generic_test_udivdi3); SPLAT_GENERIC_TEST5_ID, splat_generic_test_udivdi3);
SPLAT_TEST_INIT(sub, SPLAT_GENERIC_TEST6_NAME, SPLAT_GENERIC_TEST6_DESC, splat_test_init(sub, SPLAT_GENERIC_TEST6_NAME, SPLAT_GENERIC_TEST6_DESC,
SPLAT_GENERIC_TEST6_ID, splat_generic_test_divdi3); SPLAT_GENERIC_TEST6_ID, splat_generic_test_divdi3);
return sub; return sub;
@ -350,12 +350,12 @@ splat_generic_fini(splat_subsystem_t *sub)
{ {
ASSERT(sub); ASSERT(sub);
SPLAT_TEST_FINI(sub, SPLAT_GENERIC_TEST6_ID); splat_test_fini(sub, SPLAT_GENERIC_TEST6_ID);
SPLAT_TEST_FINI(sub, SPLAT_GENERIC_TEST5_ID); splat_test_fini(sub, SPLAT_GENERIC_TEST5_ID);
SPLAT_TEST_FINI(sub, SPLAT_GENERIC_TEST4_ID); splat_test_fini(sub, SPLAT_GENERIC_TEST4_ID);
SPLAT_TEST_FINI(sub, SPLAT_GENERIC_TEST3_ID); splat_test_fini(sub, SPLAT_GENERIC_TEST3_ID);
SPLAT_TEST_FINI(sub, SPLAT_GENERIC_TEST2_ID); splat_test_fini(sub, SPLAT_GENERIC_TEST2_ID);
SPLAT_TEST_FINI(sub, SPLAT_GENERIC_TEST1_ID); splat_test_fini(sub, SPLAT_GENERIC_TEST1_ID);
kfree(sub); kfree(sub);
} }

View File

@ -30,80 +30,6 @@
#include <linux/file_compat.h> #include <linux/file_compat.h>
#include <linux/version.h> #include <linux/version.h>
#define SPLAT_SUBSYSTEM_INIT(type) \
({ splat_subsystem_t *_sub_; \
\
_sub_ = (splat_subsystem_t *)splat_##type##_init(); \
if (_sub_ == NULL) { \
printk(KERN_ERR "splat: Error initializing: " #type "\n"); \
} else { \
spin_lock(&splat_module_lock); \
list_add_tail(&(_sub_->subsystem_list), \
&splat_module_list); \
spin_unlock(&splat_module_lock); \
} \
})
#define SPLAT_SUBSYSTEM_FINI(type) \
({ splat_subsystem_t *_sub_, *_tmp_; \
int _id_, _flag_ = 0; \
\
_id_ = splat_##type##_id(); \
spin_lock(&splat_module_lock); \
list_for_each_entry_safe(_sub_, _tmp_, &splat_module_list, \
subsystem_list) { \
if (_sub_->desc.id == _id_) { \
list_del_init(&(_sub_->subsystem_list)); \
spin_unlock(&splat_module_lock); \
splat_##type##_fini(_sub_); \
spin_lock(&splat_module_lock); \
_flag_ = 1; \
} \
} \
spin_unlock(&splat_module_lock); \
\
if (!_flag_) \
printk(KERN_ERR "splat: Error finalizing: " #type "\n"); \
})
#define SPLAT_TEST_INIT(sub, n, d, tid, func) \
({ splat_test_t *_test_; \
\
_test_ = (splat_test_t *)kmalloc(sizeof(*_test_), GFP_KERNEL); \
if (_test_ == NULL) { \
printk(KERN_ERR "splat: Error initializing: " n "/" #tid" \n");\
} else { \
memset(_test_, 0, sizeof(*_test_)); \
strncpy(_test_->desc.name, n, SPLAT_NAME_SIZE-1); \
strncpy(_test_->desc.desc, d, SPLAT_DESC_SIZE-1); \
_test_->desc.id = tid; \
_test_->test = func; \
INIT_LIST_HEAD(&(_test_->test_list)); \
spin_lock(&((sub)->test_lock)); \
list_add_tail(&(_test_->test_list),&((sub)->test_list));\
spin_unlock(&((sub)->test_lock)); \
} \
})
#define SPLAT_TEST_FINI(sub, tid) \
({ splat_test_t *_test_, *_tmp_; \
int _flag_ = 0; \
\
spin_lock(&((sub)->test_lock)); \
list_for_each_entry_safe(_test_, _tmp_, \
&((sub)->test_list), test_list) { \
if (_test_->desc.id == tid) { \
list_del_init(&(_test_->test_list)); \
kfree(_test_); \
_flag_ = 1; \
} \
} \
spin_unlock(&((sub)->test_lock)); \
\
if (!_flag_) \
printk(KERN_ERR "splat: Error finalizing: " #tid "\n"); \
})
typedef int (*splat_test_func_t)(struct file *, void *); typedef int (*splat_test_func_t)(struct file *, void *);
typedef struct splat_test { typedef struct splat_test {
@ -119,6 +45,10 @@ typedef struct splat_subsystem {
struct list_head test_list; struct list_head test_list;
} splat_subsystem_t; } splat_subsystem_t;
void splat_test_init(splat_subsystem_t *sub, const char *name,
const char *desc, unsigned int tid, splat_test_func_t func);
void splat_test_fini(splat_subsystem_t *sub, unsigned int tid);
#define SPLAT_INFO_BUFFER_SIZE 65536 #define SPLAT_INFO_BUFFER_SIZE 65536
#define SPLAT_INFO_BUFFER_REDZONE 256 #define SPLAT_INFO_BUFFER_REDZONE 256

View File

@ -275,8 +275,8 @@ typedef struct kmem_cache_priv {
struct file *kcp_file; struct file *kcp_file;
kmem_cache_t *kcp_cache; kmem_cache_t *kcp_cache;
spinlock_t kcp_lock; spinlock_t kcp_lock;
wait_queue_head_t kcp_ctl_waitq; spl_wait_queue_head_t kcp_ctl_waitq;
wait_queue_head_t kcp_thr_waitq; spl_wait_queue_head_t kcp_thr_waitq;
int kcp_flags; int kcp_flags;
int kcp_kct_count; int kcp_kct_count;
kmem_cache_thread_t *kcp_kct[SPLAT_KMEM_THREADS]; kmem_cache_thread_t *kcp_kct[SPLAT_KMEM_THREADS];
@ -590,6 +590,9 @@ splat_kmem_cache_test(struct file *file, void *arg, char *name,
kmem_cache_data_t **kcd = NULL; kmem_cache_data_t **kcd = NULL;
int i, rc = 0, objs = 0; int i, rc = 0, objs = 0;
/* Limit size for low memory machines (1/128 of memory) */
size = MIN(size, (physmem * PAGE_SIZE) >> 7);
splat_vprint(file, name, splat_vprint(file, name,
"Testing size=%d, align=%d, flags=0x%04x\n", "Testing size=%d, align=%d, flags=0x%04x\n",
size, align, flags); size, align, flags);
@ -619,7 +622,7 @@ splat_kmem_cache_test(struct file *file, void *arg, char *name,
* it to a single slab for the purposes of this test. * it to a single slab for the purposes of this test.
*/ */
#ifdef _LP64 #ifdef _LP64
objs = SPL_KMEM_CACHE_OBJ_PER_SLAB * 4; objs = kcp->kcp_cache->skc_slab_objs * 4;
#else #else
objs = 1; objs = 1;
#endif #endif
@ -1128,9 +1131,15 @@ out:
static int static int
splat_kmem_test10(struct file *file, void *arg) splat_kmem_test10(struct file *file, void *arg)
{ {
uint64_t size, alloc, rc = 0; uint64_t size, alloc, maxsize, limit, rc = 0;
for (size = 32; size <= 1024*1024; size *= 2) { #if defined(CONFIG_64BIT)
maxsize = (1024 * 1024);
#else
maxsize = (128 * 1024);
#endif
for (size = 32; size <= maxsize; size *= 2) {
splat_vprint(file, SPLAT_KMEM_TEST10_NAME, "%-22s %s", "name", splat_vprint(file, SPLAT_KMEM_TEST10_NAME, "%-22s %s", "name",
"time (sec)\tslabs \tobjs \thash\n"); "time (sec)\tslabs \tobjs \thash\n");
@ -1139,8 +1148,10 @@ splat_kmem_test10(struct file *file, void *arg)
for (alloc = 1; alloc <= 1024; alloc *= 2) { for (alloc = 1; alloc <= 1024; alloc *= 2) {
/* Skip tests which exceed 1/2 of physical memory. */ /* Skip tests which exceed 1/2 of memory. */
if (size * alloc * SPLAT_KMEM_THREADS > physmem / 2) limit = MIN(physmem * PAGE_SIZE,
vmem_size(NULL, VMEM_ALLOC | VMEM_FREE)) / 2;
if (size * alloc * SPLAT_KMEM_THREADS > limit)
continue; continue;
rc = splat_kmem_cache_thread_test(file, arg, rc = splat_kmem_cache_thread_test(file, arg,
@ -1220,7 +1231,8 @@ splat_kmem_test13(struct file *file, void *arg)
int i, rc = 0, max_time = 10; int i, rc = 0, max_time = 10;
size = 128 * 1024; size = 128 * 1024;
count = ((physmem * PAGE_SIZE) / 4 / size); count = MIN(physmem * PAGE_SIZE, vmem_size(NULL,
VMEM_ALLOC | VMEM_FREE)) / 4 / size;
kcp = splat_kmem_cache_test_kcp_alloc(file, SPLAT_KMEM_TEST13_NAME, kcp = splat_kmem_cache_test_kcp_alloc(file, SPLAT_KMEM_TEST13_NAME,
size, 0, 0); size, 0, 0);
@ -1340,31 +1352,31 @@ splat_kmem_init(void)
spin_lock_init(&sub->test_lock); spin_lock_init(&sub->test_lock);
sub->desc.id = SPLAT_SUBSYSTEM_KMEM; sub->desc.id = SPLAT_SUBSYSTEM_KMEM;
SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST1_NAME, SPLAT_KMEM_TEST1_DESC, splat_test_init(sub, SPLAT_KMEM_TEST1_NAME, SPLAT_KMEM_TEST1_DESC,
SPLAT_KMEM_TEST1_ID, splat_kmem_test1); SPLAT_KMEM_TEST1_ID, splat_kmem_test1);
SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST2_NAME, SPLAT_KMEM_TEST2_DESC, splat_test_init(sub, SPLAT_KMEM_TEST2_NAME, SPLAT_KMEM_TEST2_DESC,
SPLAT_KMEM_TEST2_ID, splat_kmem_test2); SPLAT_KMEM_TEST2_ID, splat_kmem_test2);
SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST3_NAME, SPLAT_KMEM_TEST3_DESC, splat_test_init(sub, SPLAT_KMEM_TEST3_NAME, SPLAT_KMEM_TEST3_DESC,
SPLAT_KMEM_TEST3_ID, splat_kmem_test3); SPLAT_KMEM_TEST3_ID, splat_kmem_test3);
SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST4_NAME, SPLAT_KMEM_TEST4_DESC, splat_test_init(sub, SPLAT_KMEM_TEST4_NAME, SPLAT_KMEM_TEST4_DESC,
SPLAT_KMEM_TEST4_ID, splat_kmem_test4); SPLAT_KMEM_TEST4_ID, splat_kmem_test4);
SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST5_NAME, SPLAT_KMEM_TEST5_DESC, splat_test_init(sub, SPLAT_KMEM_TEST5_NAME, SPLAT_KMEM_TEST5_DESC,
SPLAT_KMEM_TEST5_ID, splat_kmem_test5); SPLAT_KMEM_TEST5_ID, splat_kmem_test5);
SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST6_NAME, SPLAT_KMEM_TEST6_DESC, splat_test_init(sub, SPLAT_KMEM_TEST6_NAME, SPLAT_KMEM_TEST6_DESC,
SPLAT_KMEM_TEST6_ID, splat_kmem_test6); SPLAT_KMEM_TEST6_ID, splat_kmem_test6);
SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST7_NAME, SPLAT_KMEM_TEST7_DESC, splat_test_init(sub, SPLAT_KMEM_TEST7_NAME, SPLAT_KMEM_TEST7_DESC,
SPLAT_KMEM_TEST7_ID, splat_kmem_test7); SPLAT_KMEM_TEST7_ID, splat_kmem_test7);
SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST8_NAME, SPLAT_KMEM_TEST8_DESC, splat_test_init(sub, SPLAT_KMEM_TEST8_NAME, SPLAT_KMEM_TEST8_DESC,
SPLAT_KMEM_TEST8_ID, splat_kmem_test8); SPLAT_KMEM_TEST8_ID, splat_kmem_test8);
SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST9_NAME, SPLAT_KMEM_TEST9_DESC, splat_test_init(sub, SPLAT_KMEM_TEST9_NAME, SPLAT_KMEM_TEST9_DESC,
SPLAT_KMEM_TEST9_ID, splat_kmem_test9); SPLAT_KMEM_TEST9_ID, splat_kmem_test9);
SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST10_NAME, SPLAT_KMEM_TEST10_DESC, splat_test_init(sub, SPLAT_KMEM_TEST10_NAME, SPLAT_KMEM_TEST10_DESC,
SPLAT_KMEM_TEST10_ID, splat_kmem_test10); SPLAT_KMEM_TEST10_ID, splat_kmem_test10);
#if 0 #if 0
SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST11_NAME, SPLAT_KMEM_TEST11_DESC, splat_test_init(sub, SPLAT_KMEM_TEST11_NAME, SPLAT_KMEM_TEST11_DESC,
SPLAT_KMEM_TEST11_ID, splat_kmem_test11); SPLAT_KMEM_TEST11_ID, splat_kmem_test11);
#endif #endif
SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST13_NAME, SPLAT_KMEM_TEST13_DESC, splat_test_init(sub, SPLAT_KMEM_TEST13_NAME, SPLAT_KMEM_TEST13_DESC,
SPLAT_KMEM_TEST13_ID, splat_kmem_test13); SPLAT_KMEM_TEST13_ID, splat_kmem_test13);
return sub; return sub;
@ -1374,20 +1386,20 @@ void
splat_kmem_fini(splat_subsystem_t *sub) splat_kmem_fini(splat_subsystem_t *sub)
{ {
ASSERT(sub); ASSERT(sub);
SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST13_ID); splat_test_fini(sub, SPLAT_KMEM_TEST13_ID);
#if 0 #if 0
SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST11_ID); splat_test_fini(sub, SPLAT_KMEM_TEST11_ID);
#endif #endif
SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST10_ID); splat_test_fini(sub, SPLAT_KMEM_TEST10_ID);
SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST9_ID); splat_test_fini(sub, SPLAT_KMEM_TEST9_ID);
SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST8_ID); splat_test_fini(sub, SPLAT_KMEM_TEST8_ID);
SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST7_ID); splat_test_fini(sub, SPLAT_KMEM_TEST7_ID);
SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST6_ID); splat_test_fini(sub, SPLAT_KMEM_TEST6_ID);
SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST5_ID); splat_test_fini(sub, SPLAT_KMEM_TEST5_ID);
SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST4_ID); splat_test_fini(sub, SPLAT_KMEM_TEST4_ID);
SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST3_ID); splat_test_fini(sub, SPLAT_KMEM_TEST3_ID);
SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST2_ID); splat_test_fini(sub, SPLAT_KMEM_TEST2_ID);
SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST1_ID); splat_test_fini(sub, SPLAT_KMEM_TEST1_ID);
kfree(sub); kfree(sub);
} }

View File

@ -140,9 +140,9 @@ splat_kobj_init(void)
spin_lock_init(&sub->test_lock); spin_lock_init(&sub->test_lock);
sub->desc.id = SPLAT_SUBSYSTEM_KOBJ; sub->desc.id = SPLAT_SUBSYSTEM_KOBJ;
SPLAT_TEST_INIT(sub, SPLAT_KOBJ_TEST1_NAME, SPLAT_KOBJ_TEST1_DESC, splat_test_init(sub, SPLAT_KOBJ_TEST1_NAME, SPLAT_KOBJ_TEST1_DESC,
SPLAT_KOBJ_TEST1_ID, splat_kobj_test1); SPLAT_KOBJ_TEST1_ID, splat_kobj_test1);
SPLAT_TEST_INIT(sub, SPLAT_KOBJ_TEST2_NAME, SPLAT_KOBJ_TEST2_DESC, splat_test_init(sub, SPLAT_KOBJ_TEST2_NAME, SPLAT_KOBJ_TEST2_DESC,
SPLAT_KOBJ_TEST2_ID, splat_kobj_test2); SPLAT_KOBJ_TEST2_ID, splat_kobj_test2);
return sub; return sub;
@ -153,8 +153,8 @@ splat_kobj_fini(splat_subsystem_t *sub)
{ {
ASSERT(sub); ASSERT(sub);
SPLAT_TEST_FINI(sub, SPLAT_KOBJ_TEST2_ID); splat_test_fini(sub, SPLAT_KOBJ_TEST2_ID);
SPLAT_TEST_FINI(sub, SPLAT_KOBJ_TEST1_ID); splat_test_fini(sub, SPLAT_KOBJ_TEST1_ID);
kfree(sub); kfree(sub);
} /* splat_kobj_fini() */ } /* splat_kobj_fini() */

View File

@ -216,7 +216,7 @@ splat_linux_init(void)
spin_lock_init(&sub->test_lock); spin_lock_init(&sub->test_lock);
sub->desc.id = SPLAT_SUBSYSTEM_LINUX; sub->desc.id = SPLAT_SUBSYSTEM_LINUX;
SPLAT_TEST_INIT(sub, SPLAT_LINUX_TEST1_NAME, SPLAT_LINUX_TEST1_DESC, splat_test_init(sub, SPLAT_LINUX_TEST1_NAME, SPLAT_LINUX_TEST1_DESC,
SPLAT_LINUX_TEST1_ID, splat_linux_test1); SPLAT_LINUX_TEST1_ID, splat_linux_test1);
return sub; return sub;
@ -226,7 +226,7 @@ void
splat_linux_fini(splat_subsystem_t *sub) splat_linux_fini(splat_subsystem_t *sub)
{ {
ASSERT(sub); ASSERT(sub);
SPLAT_TEST_FINI(sub, SPLAT_LINUX_TEST1_ID); splat_test_fini(sub, SPLAT_LINUX_TEST1_ID);
kfree(sub); kfree(sub);
} }

View File

@ -434,19 +434,19 @@ splat_list_init(void)
spin_lock_init(&sub->test_lock); spin_lock_init(&sub->test_lock);
sub->desc.id = SPLAT_SUBSYSTEM_LIST; sub->desc.id = SPLAT_SUBSYSTEM_LIST;
SPLAT_TEST_INIT(sub, SPLAT_LIST_TEST1_NAME, SPLAT_LIST_TEST1_DESC, splat_test_init(sub, SPLAT_LIST_TEST1_NAME, SPLAT_LIST_TEST1_DESC,
SPLAT_LIST_TEST1_ID, splat_list_test1); SPLAT_LIST_TEST1_ID, splat_list_test1);
SPLAT_TEST_INIT(sub, SPLAT_LIST_TEST2_NAME, SPLAT_LIST_TEST2_DESC, splat_test_init(sub, SPLAT_LIST_TEST2_NAME, SPLAT_LIST_TEST2_DESC,
SPLAT_LIST_TEST2_ID, splat_list_test2); SPLAT_LIST_TEST2_ID, splat_list_test2);
SPLAT_TEST_INIT(sub, SPLAT_LIST_TEST3_NAME, SPLAT_LIST_TEST3_DESC, splat_test_init(sub, SPLAT_LIST_TEST3_NAME, SPLAT_LIST_TEST3_DESC,
SPLAT_LIST_TEST3_ID, splat_list_test3); SPLAT_LIST_TEST3_ID, splat_list_test3);
SPLAT_TEST_INIT(sub, SPLAT_LIST_TEST4_NAME, SPLAT_LIST_TEST4_DESC, splat_test_init(sub, SPLAT_LIST_TEST4_NAME, SPLAT_LIST_TEST4_DESC,
SPLAT_LIST_TEST4_ID, splat_list_test4); SPLAT_LIST_TEST4_ID, splat_list_test4);
SPLAT_TEST_INIT(sub, SPLAT_LIST_TEST5_NAME, SPLAT_LIST_TEST5_DESC, splat_test_init(sub, SPLAT_LIST_TEST5_NAME, SPLAT_LIST_TEST5_DESC,
SPLAT_LIST_TEST5_ID, splat_list_test5); SPLAT_LIST_TEST5_ID, splat_list_test5);
SPLAT_TEST_INIT(sub, SPLAT_LIST_TEST6_NAME, SPLAT_LIST_TEST6_DESC, splat_test_init(sub, SPLAT_LIST_TEST6_NAME, SPLAT_LIST_TEST6_DESC,
SPLAT_LIST_TEST6_ID, splat_list_test6); SPLAT_LIST_TEST6_ID, splat_list_test6);
SPLAT_TEST_INIT(sub, SPLAT_LIST_TEST7_NAME, SPLAT_LIST_TEST7_DESC, splat_test_init(sub, SPLAT_LIST_TEST7_NAME, SPLAT_LIST_TEST7_DESC,
SPLAT_LIST_TEST7_ID, splat_list_test7); SPLAT_LIST_TEST7_ID, splat_list_test7);
return sub; return sub;
@ -457,13 +457,13 @@ splat_list_fini(splat_subsystem_t *sub)
{ {
ASSERT(sub); ASSERT(sub);
SPLAT_TEST_FINI(sub, SPLAT_LIST_TEST7_ID); splat_test_fini(sub, SPLAT_LIST_TEST7_ID);
SPLAT_TEST_FINI(sub, SPLAT_LIST_TEST6_ID); splat_test_fini(sub, SPLAT_LIST_TEST6_ID);
SPLAT_TEST_FINI(sub, SPLAT_LIST_TEST5_ID); splat_test_fini(sub, SPLAT_LIST_TEST5_ID);
SPLAT_TEST_FINI(sub, SPLAT_LIST_TEST4_ID); splat_test_fini(sub, SPLAT_LIST_TEST4_ID);
SPLAT_TEST_FINI(sub, SPLAT_LIST_TEST3_ID); splat_test_fini(sub, SPLAT_LIST_TEST3_ID);
SPLAT_TEST_FINI(sub, SPLAT_LIST_TEST2_ID); splat_test_fini(sub, SPLAT_LIST_TEST2_ID);
SPLAT_TEST_FINI(sub, SPLAT_LIST_TEST1_ID); splat_test_fini(sub, SPLAT_LIST_TEST1_ID);
kfree(sub); kfree(sub);
} }

View File

@ -81,7 +81,8 @@ splat_mutex_test1(struct file *file, void *arg)
{ {
mutex_priv_t *mp; mutex_priv_t *mp;
taskq_t *tq; taskq_t *tq;
int id, rc = 0; taskqid_t id;
int rc = 0;
mp = (mutex_priv_t *)kmalloc(sizeof(*mp), GFP_KERNEL); mp = (mutex_priv_t *)kmalloc(sizeof(*mp), GFP_KERNEL);
if (mp == NULL) if (mp == NULL)
@ -105,8 +106,8 @@ splat_mutex_test1(struct file *file, void *arg)
* function will indicate this status in the passed private data. * function will indicate this status in the passed private data.
*/ */
mp->mp_rc = -EINVAL; mp->mp_rc = -EINVAL;
id = taskq_dispatch(tq, splat_mutex_test1_func, mp, TQ_SLEEP); id = taskq_dispatch(tq, splat_mutex_test1_func, mp, TQ_SLEEP);
if (id == 0) { if (id == TASKQID_INVALID) {
mutex_exit(&mp->mp_mtx); mutex_exit(&mp->mp_mtx);
splat_vprint(file, SPLAT_MUTEX_TEST1_NAME, "%s", splat_vprint(file, SPLAT_MUTEX_TEST1_NAME, "%s",
"taskq_dispatch() failed\n"); "taskq_dispatch() failed\n");
@ -120,8 +121,8 @@ splat_mutex_test1(struct file *file, void *arg)
/* Task function successfully acquired mutex, very bad! */ /* Task function successfully acquired mutex, very bad! */
if (mp->mp_rc != -EBUSY) { if (mp->mp_rc != -EBUSY) {
splat_vprint(file, SPLAT_MUTEX_TEST1_NAME, splat_vprint(file, SPLAT_MUTEX_TEST1_NAME,
"mutex_trylock() incorrectly succeeded when " "mutex_trylock() incorrectly succeeded when "
"the mutex was held, %d/%d\n", id, mp->mp_rc); "the mutex was held, %d/%d\n", (int)id, mp->mp_rc);
rc = -EINVAL; rc = -EINVAL;
goto out; goto out;
} else { } else {
@ -136,8 +137,8 @@ splat_mutex_test1(struct file *file, void *arg)
* can be verified by checking the private data. * can be verified by checking the private data.
*/ */
mp->mp_rc = -EINVAL; mp->mp_rc = -EINVAL;
id = taskq_dispatch(tq, splat_mutex_test1_func, mp, TQ_SLEEP); id = taskq_dispatch(tq, splat_mutex_test1_func, mp, TQ_SLEEP);
if (id == 0) { if (id == TASKQID_INVALID) {
splat_vprint(file, SPLAT_MUTEX_TEST1_NAME, "%s", splat_vprint(file, SPLAT_MUTEX_TEST1_NAME, "%s",
"taskq_dispatch() failed\n"); "taskq_dispatch() failed\n");
rc = -EINVAL; rc = -EINVAL;
@ -149,8 +150,8 @@ splat_mutex_test1(struct file *file, void *arg)
/* Task function failed to acquire mutex, very bad! */ /* Task function failed to acquire mutex, very bad! */
if (mp->mp_rc != 0) { if (mp->mp_rc != 0) {
splat_vprint(file, SPLAT_MUTEX_TEST1_NAME, splat_vprint(file, SPLAT_MUTEX_TEST1_NAME,
"mutex_trylock() incorrectly failed when " "mutex_trylock() incorrectly failed when the mutex "
"the mutex was not held, %d/%d\n", id, mp->mp_rc); "was not held, %d/%d\n", (int)id, mp->mp_rc);
rc = -EINVAL; rc = -EINVAL;
} else { } else {
splat_vprint(file, SPLAT_MUTEX_TEST1_NAME, "%s", splat_vprint(file, SPLAT_MUTEX_TEST1_NAME, "%s",
@ -188,6 +189,7 @@ splat_mutex_test2(struct file *file, void *arg)
{ {
mutex_priv_t *mp; mutex_priv_t *mp;
taskq_t *tq; taskq_t *tq;
taskqid_t id;
int i, rc = 0; int i, rc = 0;
mp = (mutex_priv_t *)kmalloc(sizeof(*mp), GFP_KERNEL); mp = (mutex_priv_t *)kmalloc(sizeof(*mp), GFP_KERNEL);
@ -218,7 +220,8 @@ splat_mutex_test2(struct file *file, void *arg)
* mutex is implemented right this will never happy, that's a pass. * mutex is implemented right this will never happy, that's a pass.
*/ */
for (i = 0; i < SPLAT_MUTEX_TEST_COUNT; i++) { for (i = 0; i < SPLAT_MUTEX_TEST_COUNT; i++) {
if (!taskq_dispatch(tq, splat_mutex_test2_func, mp, TQ_SLEEP)) { id = taskq_dispatch(tq, splat_mutex_test2_func, mp, TQ_SLEEP);
if (id == TASKQID_INVALID) {
splat_vprint(file, SPLAT_MUTEX_TEST2_NAME, splat_vprint(file, SPLAT_MUTEX_TEST2_NAME,
"Failed to queue task %d\n", i); "Failed to queue task %d\n", i);
rc = -EINVAL; rc = -EINVAL;
@ -260,6 +263,7 @@ splat_mutex_test3(struct file *file, void *arg)
{ {
mutex_priv_t mp; mutex_priv_t mp;
taskq_t *tq; taskq_t *tq;
taskqid_t id;
int rc = 0; int rc = 0;
mp.mp_magic = SPLAT_MUTEX_TEST_MAGIC; mp.mp_magic = SPLAT_MUTEX_TEST_MAGIC;
@ -283,7 +287,8 @@ splat_mutex_test3(struct file *file, void *arg)
goto out_exit; goto out_exit;
} }
if (taskq_dispatch(tq, splat_mutex_owned, &mp, TQ_SLEEP) == 0) { id = taskq_dispatch(tq, splat_mutex_owned, &mp, TQ_SLEEP);
if (id == TASKQID_INVALID) {
splat_vprint(file, SPLAT_MUTEX_TEST3_NAME, "Failed to " splat_vprint(file, SPLAT_MUTEX_TEST3_NAME, "Failed to "
"dispatch function '%s' to taskq\n", "dispatch function '%s' to taskq\n",
sym2str(splat_mutex_owned)); sym2str(splat_mutex_owned));
@ -310,7 +315,8 @@ splat_mutex_test3(struct file *file, void *arg)
goto out; goto out;
} }
if (taskq_dispatch(tq, splat_mutex_owned, &mp, TQ_SLEEP) == 0) { id = taskq_dispatch(tq, splat_mutex_owned, &mp, TQ_SLEEP);
if (id == TASKQID_INVALID) {
splat_vprint(file, SPLAT_MUTEX_TEST3_NAME, "Failed to " splat_vprint(file, SPLAT_MUTEX_TEST3_NAME, "Failed to "
"dispatch function '%s' to taskq\n", "dispatch function '%s' to taskq\n",
sym2str(splat_mutex_owned)); sym2str(splat_mutex_owned));
@ -411,13 +417,13 @@ splat_mutex_init(void)
spin_lock_init(&sub->test_lock); spin_lock_init(&sub->test_lock);
sub->desc.id = SPLAT_SUBSYSTEM_MUTEX; sub->desc.id = SPLAT_SUBSYSTEM_MUTEX;
SPLAT_TEST_INIT(sub, SPLAT_MUTEX_TEST1_NAME, SPLAT_MUTEX_TEST1_DESC, splat_test_init(sub, SPLAT_MUTEX_TEST1_NAME, SPLAT_MUTEX_TEST1_DESC,
SPLAT_MUTEX_TEST1_ID, splat_mutex_test1); SPLAT_MUTEX_TEST1_ID, splat_mutex_test1);
SPLAT_TEST_INIT(sub, SPLAT_MUTEX_TEST2_NAME, SPLAT_MUTEX_TEST2_DESC, splat_test_init(sub, SPLAT_MUTEX_TEST2_NAME, SPLAT_MUTEX_TEST2_DESC,
SPLAT_MUTEX_TEST2_ID, splat_mutex_test2); SPLAT_MUTEX_TEST2_ID, splat_mutex_test2);
SPLAT_TEST_INIT(sub, SPLAT_MUTEX_TEST3_NAME, SPLAT_MUTEX_TEST3_DESC, splat_test_init(sub, SPLAT_MUTEX_TEST3_NAME, SPLAT_MUTEX_TEST3_DESC,
SPLAT_MUTEX_TEST3_ID, splat_mutex_test3); SPLAT_MUTEX_TEST3_ID, splat_mutex_test3);
SPLAT_TEST_INIT(sub, SPLAT_MUTEX_TEST4_NAME, SPLAT_MUTEX_TEST4_DESC, splat_test_init(sub, SPLAT_MUTEX_TEST4_NAME, SPLAT_MUTEX_TEST4_DESC,
SPLAT_MUTEX_TEST4_ID, splat_mutex_test4); SPLAT_MUTEX_TEST4_ID, splat_mutex_test4);
return sub; return sub;
@ -427,10 +433,10 @@ void
splat_mutex_fini(splat_subsystem_t *sub) splat_mutex_fini(splat_subsystem_t *sub)
{ {
ASSERT(sub); ASSERT(sub);
SPLAT_TEST_FINI(sub, SPLAT_MUTEX_TEST4_ID); splat_test_fini(sub, SPLAT_MUTEX_TEST4_ID);
SPLAT_TEST_FINI(sub, SPLAT_MUTEX_TEST3_ID); splat_test_fini(sub, SPLAT_MUTEX_TEST3_ID);
SPLAT_TEST_FINI(sub, SPLAT_MUTEX_TEST2_ID); splat_test_fini(sub, SPLAT_MUTEX_TEST2_ID);
SPLAT_TEST_FINI(sub, SPLAT_MUTEX_TEST1_ID); splat_test_fini(sub, SPLAT_MUTEX_TEST1_ID);
kfree(sub); kfree(sub);
} }

View File

@ -108,7 +108,7 @@ splat_krng_init(void)
spin_lock_init(&sub->test_lock); spin_lock_init(&sub->test_lock);
sub->desc.id = SPLAT_SUBSYSTEM_KRNG; sub->desc.id = SPLAT_SUBSYSTEM_KRNG;
SPLAT_TEST_INIT(sub, SPLAT_KRNG_TEST1_NAME, SPLAT_KRNG_TEST1_DESC, splat_test_init(sub, SPLAT_KRNG_TEST1_NAME, SPLAT_KRNG_TEST1_DESC,
SPLAT_KRNG_TEST1_ID, splat_krng_test1); SPLAT_KRNG_TEST1_ID, splat_krng_test1);
return sub; return sub;
@ -119,7 +119,7 @@ splat_krng_fini(splat_subsystem_t *sub)
{ {
ASSERT(sub); ASSERT(sub);
SPLAT_TEST_FINI(sub, SPLAT_KRNG_TEST1_ID); splat_test_fini(sub, SPLAT_KRNG_TEST1_ID);
kfree(sub); kfree(sub);
} }

View File

@ -76,7 +76,7 @@ typedef struct rw_priv {
struct file *rw_file; struct file *rw_file;
krwlock_t rw_rwlock; krwlock_t rw_rwlock;
spinlock_t rw_lock; spinlock_t rw_lock;
wait_queue_head_t rw_waitq; spl_wait_queue_head_t rw_waitq;
int rw_completed; int rw_completed;
int rw_holders; int rw_holders;
int rw_waiters; int rw_waiters;
@ -106,6 +106,17 @@ void splat_init_rw_priv(rw_priv_t *rwp, struct file *file)
rwp->rw_type = 0; rwp->rw_type = 0;
} }
#if defined(CONFIG_PREEMPT_RT_FULL)
static int
splat_rwlock_test1(struct file *file, void *arg)
{
/*
* This test will never succeed on PREEMPT_RT_FULL because these
* kernels only allow a single thread to hold the lock.
*/
return 0;
}
#else
static int static int
splat_rwlock_wr_thr(void *arg) splat_rwlock_wr_thr(void *arg)
{ {
@ -297,6 +308,7 @@ splat_rwlock_test1(struct file *file, void *arg)
return rc; return rc;
} }
#endif
static void static void
splat_rwlock_test2_func(void *arg) splat_rwlock_test2_func(void *arg)
@ -348,7 +360,8 @@ splat_rwlock_test2(struct file *file, void *arg)
* rwlock is implemented right this will never happy, that's a pass. * rwlock is implemented right this will never happy, that's a pass.
*/ */
for (i = 0; i < tq_count; i++) { for (i = 0; i < tq_count; i++) {
if (!taskq_dispatch(tq,splat_rwlock_test2_func,rwp,TQ_SLEEP)) { if (taskq_dispatch(tq, splat_rwlock_test2_func, rwp,
TQ_SLEEP) == TASKQID_INVALID) {
splat_vprint(file, SPLAT_RWLOCK_TEST2_NAME, splat_vprint(file, SPLAT_RWLOCK_TEST2_NAME,
"Failed to queue task %d\n", i); "Failed to queue task %d\n", i);
rc = -EINVAL; rc = -EINVAL;
@ -469,7 +482,7 @@ splat_rwlock_test4_type(taskq_t *tq, rw_priv_t *rwp, int expected_rc,
rw_enter(&rwp->rw_rwlock, holder_type); rw_enter(&rwp->rw_rwlock, holder_type);
id = taskq_dispatch(tq, splat_rwlock_test4_func, rwp, TQ_SLEEP); id = taskq_dispatch(tq, splat_rwlock_test4_func, rwp, TQ_SLEEP);
if (id == 0) { if (id == TASKQID_INVALID) {
splat_vprint(rwp->rw_file, SPLAT_RWLOCK_TEST4_NAME, "%s", splat_vprint(rwp->rw_file, SPLAT_RWLOCK_TEST4_NAME, "%s",
"taskq_dispatch() failed\n"); "taskq_dispatch() failed\n");
rc = -EINVAL; rc = -EINVAL;
@ -513,11 +526,22 @@ splat_rwlock_test4(struct file *file, void *arg)
splat_init_rw_priv(rwp, file); splat_init_rw_priv(rwp, file);
/* Validate all combinations of rw_tryenter() contention */ /*
* Validate all combinations of rw_tryenter() contention.
*
* The concurrent reader test is modified for PREEMPT_RT_FULL
* kernels which do not permit concurrent read locks to be taken
* from different threads. The same thread is allowed to take
* the read lock multiple times.
*/
rc1 = splat_rwlock_test4_type(tq, rwp, -EBUSY, RW_WRITER, RW_WRITER); rc1 = splat_rwlock_test4_type(tq, rwp, -EBUSY, RW_WRITER, RW_WRITER);
rc2 = splat_rwlock_test4_type(tq, rwp, -EBUSY, RW_WRITER, RW_READER); rc2 = splat_rwlock_test4_type(tq, rwp, -EBUSY, RW_WRITER, RW_READER);
rc3 = splat_rwlock_test4_type(tq, rwp, -EBUSY, RW_READER, RW_WRITER); rc3 = splat_rwlock_test4_type(tq, rwp, -EBUSY, RW_READER, RW_WRITER);
#if defined(CONFIG_PREEMPT_RT_FULL)
rc4 = splat_rwlock_test4_type(tq, rwp, -EBUSY, RW_READER, RW_READER);
#else
rc4 = splat_rwlock_test4_type(tq, rwp, 0, RW_READER, RW_READER); rc4 = splat_rwlock_test4_type(tq, rwp, 0, RW_READER, RW_READER);
#endif
rc5 = splat_rwlock_test4_type(tq, rwp, 0, RW_NONE, RW_WRITER); rc5 = splat_rwlock_test4_type(tq, rwp, 0, RW_NONE, RW_WRITER);
rc6 = splat_rwlock_test4_type(tq, rwp, 0, RW_NONE, RW_READER); rc6 = splat_rwlock_test4_type(tq, rwp, 0, RW_NONE, RW_READER);
@ -685,19 +709,19 @@ splat_rwlock_init(void)
spin_lock_init(&sub->test_lock); spin_lock_init(&sub->test_lock);
sub->desc.id = SPLAT_SUBSYSTEM_RWLOCK; sub->desc.id = SPLAT_SUBSYSTEM_RWLOCK;
SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST1_NAME, SPLAT_RWLOCK_TEST1_DESC, splat_test_init(sub, SPLAT_RWLOCK_TEST1_NAME, SPLAT_RWLOCK_TEST1_DESC,
SPLAT_RWLOCK_TEST1_ID, splat_rwlock_test1); SPLAT_RWLOCK_TEST1_ID, splat_rwlock_test1);
SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST2_NAME, SPLAT_RWLOCK_TEST2_DESC, splat_test_init(sub, SPLAT_RWLOCK_TEST2_NAME, SPLAT_RWLOCK_TEST2_DESC,
SPLAT_RWLOCK_TEST2_ID, splat_rwlock_test2); SPLAT_RWLOCK_TEST2_ID, splat_rwlock_test2);
SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST3_NAME, SPLAT_RWLOCK_TEST3_DESC, splat_test_init(sub, SPLAT_RWLOCK_TEST3_NAME, SPLAT_RWLOCK_TEST3_DESC,
SPLAT_RWLOCK_TEST3_ID, splat_rwlock_test3); SPLAT_RWLOCK_TEST3_ID, splat_rwlock_test3);
SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST4_NAME, SPLAT_RWLOCK_TEST4_DESC, splat_test_init(sub, SPLAT_RWLOCK_TEST4_NAME, SPLAT_RWLOCK_TEST4_DESC,
SPLAT_RWLOCK_TEST4_ID, splat_rwlock_test4); SPLAT_RWLOCK_TEST4_ID, splat_rwlock_test4);
SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST5_NAME, SPLAT_RWLOCK_TEST5_DESC, splat_test_init(sub, SPLAT_RWLOCK_TEST5_NAME, SPLAT_RWLOCK_TEST5_DESC,
SPLAT_RWLOCK_TEST5_ID, splat_rwlock_test5); SPLAT_RWLOCK_TEST5_ID, splat_rwlock_test5);
SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST6_NAME, SPLAT_RWLOCK_TEST6_DESC, splat_test_init(sub, SPLAT_RWLOCK_TEST6_NAME, SPLAT_RWLOCK_TEST6_DESC,
SPLAT_RWLOCK_TEST6_ID, splat_rwlock_test6); SPLAT_RWLOCK_TEST6_ID, splat_rwlock_test6);
SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST7_NAME, SPLAT_RWLOCK_TEST7_DESC, splat_test_init(sub, SPLAT_RWLOCK_TEST7_NAME, SPLAT_RWLOCK_TEST7_DESC,
SPLAT_RWLOCK_TEST7_ID, splat_rwlock_test7); SPLAT_RWLOCK_TEST7_ID, splat_rwlock_test7);
return sub; return sub;
@ -707,13 +731,13 @@ void
splat_rwlock_fini(splat_subsystem_t *sub) splat_rwlock_fini(splat_subsystem_t *sub)
{ {
ASSERT(sub); ASSERT(sub);
SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST7_ID); splat_test_fini(sub, SPLAT_RWLOCK_TEST7_ID);
SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST6_ID); splat_test_fini(sub, SPLAT_RWLOCK_TEST6_ID);
SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST5_ID); splat_test_fini(sub, SPLAT_RWLOCK_TEST5_ID);
SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST4_ID); splat_test_fini(sub, SPLAT_RWLOCK_TEST4_ID);
SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST3_ID); splat_test_fini(sub, SPLAT_RWLOCK_TEST3_ID);
SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST2_ID); splat_test_fini(sub, SPLAT_RWLOCK_TEST2_ID);
SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST1_ID); splat_test_fini(sub, SPLAT_RWLOCK_TEST1_ID);
kfree(sub); kfree(sub);
} }

View File

@ -160,7 +160,7 @@ splat_taskq_test1_impl(struct file *file, void *arg, boolean_t prealloc)
&tq_arg, TQ_SLEEP); &tq_arg, TQ_SLEEP);
} }
if (id == 0) { if (id == TASKQID_INVALID) {
splat_vprint(file, SPLAT_TASKQ_TEST1_NAME, splat_vprint(file, SPLAT_TASKQ_TEST1_NAME,
"Taskq '%s' function '%s' dispatch failed\n", "Taskq '%s' function '%s' dispatch failed\n",
tq_arg.name, sym2str(splat_taskq_test13_func)); tq_arg.name, sym2str(splat_taskq_test13_func));
@ -296,7 +296,7 @@ splat_taskq_test2_impl(struct file *file, void *arg, boolean_t prealloc) {
tq_args[i], TQ_SLEEP); tq_args[i], TQ_SLEEP);
} }
if (id == 0) { if (id == TASKQID_INVALID) {
splat_vprint(file, SPLAT_TASKQ_TEST2_NAME, splat_vprint(file, SPLAT_TASKQ_TEST2_NAME,
"Taskq '%s/%d' function '%s' dispatch " "Taskq '%s/%d' function '%s' dispatch "
"failed\n", tq_args[i]->name, tq_args[i]->id, "failed\n", tq_args[i]->name, tq_args[i]->id,
@ -318,7 +318,7 @@ splat_taskq_test2_impl(struct file *file, void *arg, boolean_t prealloc) {
tq_args[i], TQ_SLEEP); tq_args[i], TQ_SLEEP);
} }
if (id == 0) { if (id == TASKQID_INVALID) {
splat_vprint(file, SPLAT_TASKQ_TEST2_NAME, "Taskq " splat_vprint(file, SPLAT_TASKQ_TEST2_NAME, "Taskq "
"'%s/%d' function '%s' dispatch failed\n", "'%s/%d' function '%s' dispatch failed\n",
tq_args[i]->name, tq_args[i]->id, tq_args[i]->name, tq_args[i]->id,
@ -420,7 +420,7 @@ splat_taskq_test3_impl(struct file *file, void *arg, boolean_t prealloc)
tq_arg, TQ_SLEEP); tq_arg, TQ_SLEEP);
} }
if (id == 0) { if (id == TASKQID_INVALID) {
splat_vprint(file, SPLAT_TASKQ_TEST3_NAME, splat_vprint(file, SPLAT_TASKQ_TEST3_NAME,
"Taskq '%s' function '%s' dispatch failed\n", "Taskq '%s' function '%s' dispatch failed\n",
tq_arg->name, sym2str(splat_taskq_test13_func)); tq_arg->name, sym2str(splat_taskq_test13_func));
@ -525,7 +525,7 @@ splat_taskq_test4_common(struct file *file, void *arg, int minalloc,
&tq_arg, TQ_SLEEP); &tq_arg, TQ_SLEEP);
} }
if (id == 0) { if (id == TASKQID_INVALID) {
splat_vprint(file, SPLAT_TASKQ_TEST4_NAME, splat_vprint(file, SPLAT_TASKQ_TEST4_NAME,
"Taskq '%s' function '%s' dispatch " "Taskq '%s' function '%s' dispatch "
"%d failed\n", tq_arg.name, "%d failed\n", tq_arg.name,
@ -741,7 +741,7 @@ splat_taskq_test5_impl(struct file *file, void *arg, boolean_t prealloc)
&tq_id[i], TQ_SLEEP); &tq_id[i], TQ_SLEEP);
} }
if (id == 0) { if (id == TASKQID_INVALID) {
splat_vprint(file, SPLAT_TASKQ_TEST5_NAME, splat_vprint(file, SPLAT_TASKQ_TEST5_NAME,
"Taskq '%s' function '%s' dispatch failed\n", "Taskq '%s' function '%s' dispatch failed\n",
tq_arg.name, sym2str(splat_taskq_test5_func)); tq_arg.name, sym2str(splat_taskq_test5_func));
@ -905,7 +905,7 @@ splat_taskq_test6_impl(struct file *file, void *arg, boolean_t prealloc)
&tq_id[i], tflags); &tq_id[i], tflags);
} }
if (id == 0) { if (id == TASKQID_INVALID) {
splat_vprint(file, SPLAT_TASKQ_TEST6_NAME, splat_vprint(file, SPLAT_TASKQ_TEST6_NAME,
"Taskq '%s' function '%s' dispatch failed\n", "Taskq '%s' function '%s' dispatch failed\n",
tq_arg.name, sym2str(splat_taskq_test6_func)); tq_arg.name, sym2str(splat_taskq_test6_func));
@ -983,7 +983,7 @@ splat_taskq_test7_func(void *arg)
tq_arg, TQ_SLEEP); tq_arg, TQ_SLEEP);
} }
if (id == 0) { if (id == TASKQID_INVALID) {
splat_vprint(tq_arg->file, SPLAT_TASKQ_TEST7_NAME, splat_vprint(tq_arg->file, SPLAT_TASKQ_TEST7_NAME,
"Taskq '%s' function '%s' dispatch failed " "Taskq '%s' function '%s' dispatch failed "
"(depth = %u)\n", tq_arg->name, "(depth = %u)\n", tq_arg->name,
@ -1040,11 +1040,12 @@ splat_taskq_test7_impl(struct file *file, void *arg, boolean_t prealloc)
error = (tq_arg->depth == SPLAT_TASKQ_DEPTH_MAX ? 0 : -EINVAL); error = (tq_arg->depth == SPLAT_TASKQ_DEPTH_MAX ? 0 : -EINVAL);
splat_vprint(file, SPLAT_TASKQ_TEST7_NAME,
"Taskq '%s' destroying\n", tq_arg->name);
kmem_free(tqe, sizeof (taskq_ent_t)); kmem_free(tqe, sizeof (taskq_ent_t));
kmem_free(tq_arg, sizeof (splat_taskq_arg_t)); kmem_free(tq_arg, sizeof (splat_taskq_arg_t));
splat_vprint(file, SPLAT_TASKQ_TEST7_NAME,
"Taskq '%s' destroying\n", tq_arg->name);
taskq_destroy(tq); taskq_destroy(tq);
return (error); return (error);
@ -1120,7 +1121,7 @@ splat_taskq_throughput(struct file *file, void *arg, const char *name,
&tq_arg, TQ_SLEEP, tqes[i]); &tq_arg, TQ_SLEEP, tqes[i]);
id = tqes[i]->tqent_id; id = tqes[i]->tqent_id;
if (id == 0) { if (id == TASKQID_INVALID) {
splat_vprint(file, name, "Taskq '%s' function '%s' " splat_vprint(file, name, "Taskq '%s' function '%s' "
"dispatch %d failed\n", tq_arg.name, "dispatch %d failed\n", tq_arg.name,
sym2str(splat_taskq_throughput_func), i); sym2str(splat_taskq_throughput_func), i);
@ -1234,7 +1235,7 @@ splat_taskq_test9(struct file *file, void *arg)
id = taskq_dispatch_delay(tq, splat_taskq_test9_func, id = taskq_dispatch_delay(tq, splat_taskq_test9_func,
tq_arg, TQ_SLEEP, ddi_get_lbolt() + rnd); tq_arg, TQ_SLEEP, ddi_get_lbolt() + rnd);
if (id == 0) { if (id == TASKQID_INVALID) {
splat_vprint(file, SPLAT_TASKQ_TEST9_NAME, splat_vprint(file, SPLAT_TASKQ_TEST9_NAME,
"Taskq '%s' delay dispatch failed\n", "Taskq '%s' delay dispatch failed\n",
SPLAT_TASKQ_TEST9_NAME); SPLAT_TASKQ_TEST9_NAME);
@ -1343,7 +1344,7 @@ splat_taskq_test10(struct file *file, void *arg)
tq_arg, TQ_SLEEP, ddi_get_lbolt() + rnd); tq_arg, TQ_SLEEP, ddi_get_lbolt() + rnd);
} }
if (tq_arg->id == 0) { if (tq_arg->id == TASKQID_INVALID) {
splat_vprint(file, SPLAT_TASKQ_TEST10_NAME, splat_vprint(file, SPLAT_TASKQ_TEST10_NAME,
"Taskq '%s' dispatch failed\n", "Taskq '%s' dispatch failed\n",
SPLAT_TASKQ_TEST10_NAME); SPLAT_TASKQ_TEST10_NAME);
@ -1472,8 +1473,8 @@ splat_taskq_test11(struct file *file, void *arg)
dynamic.tv_sec, dynamic.tv_nsec); dynamic.tv_sec, dynamic.tv_nsec);
/* A 10x increase in runtime is used to indicate a core problem. */ /* A 10x increase in runtime is used to indicate a core problem. */
if ((dynamic.tv_sec * NANOSEC + dynamic.tv_nsec) > if (((int64_t)dynamic.tv_sec * NANOSEC + (int64_t)dynamic.tv_nsec) >
((normal.tv_sec * NANOSEC + normal.tv_nsec) * 10)) (((int64_t)normal.tv_sec * NANOSEC + (int64_t)normal.tv_nsec) * 10))
error = -ETIME; error = -ETIME;
return (error); return (error);
@ -1496,27 +1497,27 @@ splat_taskq_init(void)
spin_lock_init(&sub->test_lock); spin_lock_init(&sub->test_lock);
sub->desc.id = SPLAT_SUBSYSTEM_TASKQ; sub->desc.id = SPLAT_SUBSYSTEM_TASKQ;
SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST1_NAME, SPLAT_TASKQ_TEST1_DESC, splat_test_init(sub, SPLAT_TASKQ_TEST1_NAME, SPLAT_TASKQ_TEST1_DESC,
SPLAT_TASKQ_TEST1_ID, splat_taskq_test1); SPLAT_TASKQ_TEST1_ID, splat_taskq_test1);
SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST2_NAME, SPLAT_TASKQ_TEST2_DESC, splat_test_init(sub, SPLAT_TASKQ_TEST2_NAME, SPLAT_TASKQ_TEST2_DESC,
SPLAT_TASKQ_TEST2_ID, splat_taskq_test2); SPLAT_TASKQ_TEST2_ID, splat_taskq_test2);
SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST3_NAME, SPLAT_TASKQ_TEST3_DESC, splat_test_init(sub, SPLAT_TASKQ_TEST3_NAME, SPLAT_TASKQ_TEST3_DESC,
SPLAT_TASKQ_TEST3_ID, splat_taskq_test3); SPLAT_TASKQ_TEST3_ID, splat_taskq_test3);
SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST4_NAME, SPLAT_TASKQ_TEST4_DESC, splat_test_init(sub, SPLAT_TASKQ_TEST4_NAME, SPLAT_TASKQ_TEST4_DESC,
SPLAT_TASKQ_TEST4_ID, splat_taskq_test4); SPLAT_TASKQ_TEST4_ID, splat_taskq_test4);
SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST5_NAME, SPLAT_TASKQ_TEST5_DESC, splat_test_init(sub, SPLAT_TASKQ_TEST5_NAME, SPLAT_TASKQ_TEST5_DESC,
SPLAT_TASKQ_TEST5_ID, splat_taskq_test5); SPLAT_TASKQ_TEST5_ID, splat_taskq_test5);
SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST6_NAME, SPLAT_TASKQ_TEST6_DESC, splat_test_init(sub, SPLAT_TASKQ_TEST6_NAME, SPLAT_TASKQ_TEST6_DESC,
SPLAT_TASKQ_TEST6_ID, splat_taskq_test6); SPLAT_TASKQ_TEST6_ID, splat_taskq_test6);
SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST7_NAME, SPLAT_TASKQ_TEST7_DESC, splat_test_init(sub, SPLAT_TASKQ_TEST7_NAME, SPLAT_TASKQ_TEST7_DESC,
SPLAT_TASKQ_TEST7_ID, splat_taskq_test7); SPLAT_TASKQ_TEST7_ID, splat_taskq_test7);
SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST8_NAME, SPLAT_TASKQ_TEST8_DESC, splat_test_init(sub, SPLAT_TASKQ_TEST8_NAME, SPLAT_TASKQ_TEST8_DESC,
SPLAT_TASKQ_TEST8_ID, splat_taskq_test8); SPLAT_TASKQ_TEST8_ID, splat_taskq_test8);
SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST9_NAME, SPLAT_TASKQ_TEST9_DESC, splat_test_init(sub, SPLAT_TASKQ_TEST9_NAME, SPLAT_TASKQ_TEST9_DESC,
SPLAT_TASKQ_TEST9_ID, splat_taskq_test9); SPLAT_TASKQ_TEST9_ID, splat_taskq_test9);
SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST10_NAME, SPLAT_TASKQ_TEST10_DESC, splat_test_init(sub, SPLAT_TASKQ_TEST10_NAME, SPLAT_TASKQ_TEST10_DESC,
SPLAT_TASKQ_TEST10_ID, splat_taskq_test10); SPLAT_TASKQ_TEST10_ID, splat_taskq_test10);
SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST11_NAME, SPLAT_TASKQ_TEST11_DESC, splat_test_init(sub, SPLAT_TASKQ_TEST11_NAME, SPLAT_TASKQ_TEST11_DESC,
SPLAT_TASKQ_TEST11_ID, splat_taskq_test11); SPLAT_TASKQ_TEST11_ID, splat_taskq_test11);
return sub; return sub;
@ -1526,17 +1527,17 @@ void
splat_taskq_fini(splat_subsystem_t *sub) splat_taskq_fini(splat_subsystem_t *sub)
{ {
ASSERT(sub); ASSERT(sub);
SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST11_ID); splat_test_fini(sub, SPLAT_TASKQ_TEST11_ID);
SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST10_ID); splat_test_fini(sub, SPLAT_TASKQ_TEST10_ID);
SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST9_ID); splat_test_fini(sub, SPLAT_TASKQ_TEST9_ID);
SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST8_ID); splat_test_fini(sub, SPLAT_TASKQ_TEST8_ID);
SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST7_ID); splat_test_fini(sub, SPLAT_TASKQ_TEST7_ID);
SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST6_ID); splat_test_fini(sub, SPLAT_TASKQ_TEST6_ID);
SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST5_ID); splat_test_fini(sub, SPLAT_TASKQ_TEST5_ID);
SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST4_ID); splat_test_fini(sub, SPLAT_TASKQ_TEST4_ID);
SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST3_ID); splat_test_fini(sub, SPLAT_TASKQ_TEST3_ID);
SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST2_ID); splat_test_fini(sub, SPLAT_TASKQ_TEST2_ID);
SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST1_ID); splat_test_fini(sub, SPLAT_TASKQ_TEST1_ID);
kfree(sub); kfree(sub);
} }

View File

@ -28,6 +28,7 @@
#include <sys/random.h> #include <sys/random.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mm_compat.h> #include <linux/mm_compat.h>
#include <linux/wait_compat.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "splat-internal.h" #include "splat-internal.h"
@ -54,7 +55,7 @@ typedef struct thread_priv {
unsigned long tp_magic; unsigned long tp_magic;
struct file *tp_file; struct file *tp_file;
spinlock_t tp_lock; spinlock_t tp_lock;
wait_queue_head_t tp_waitq; spl_wait_queue_head_t tp_waitq;
uint_t tp_keys[SPLAT_THREAD_TEST_KEYS]; uint_t tp_keys[SPLAT_THREAD_TEST_KEYS];
int tp_rc; int tp_rc;
int tp_count; int tp_count;
@ -362,11 +363,11 @@ splat_thread_init(void)
spin_lock_init(&sub->test_lock); spin_lock_init(&sub->test_lock);
sub->desc.id = SPLAT_SUBSYSTEM_THREAD; sub->desc.id = SPLAT_SUBSYSTEM_THREAD;
SPLAT_TEST_INIT(sub, SPLAT_THREAD_TEST1_NAME, SPLAT_THREAD_TEST1_DESC, splat_test_init(sub, SPLAT_THREAD_TEST1_NAME, SPLAT_THREAD_TEST1_DESC,
SPLAT_THREAD_TEST1_ID, splat_thread_test1); SPLAT_THREAD_TEST1_ID, splat_thread_test1);
SPLAT_TEST_INIT(sub, SPLAT_THREAD_TEST2_NAME, SPLAT_THREAD_TEST2_DESC, splat_test_init(sub, SPLAT_THREAD_TEST2_NAME, SPLAT_THREAD_TEST2_DESC,
SPLAT_THREAD_TEST2_ID, splat_thread_test2); SPLAT_THREAD_TEST2_ID, splat_thread_test2);
SPLAT_TEST_INIT(sub, SPLAT_THREAD_TEST3_NAME, SPLAT_THREAD_TEST3_DESC, splat_test_init(sub, SPLAT_THREAD_TEST3_NAME, SPLAT_THREAD_TEST3_DESC,
SPLAT_THREAD_TEST3_ID, splat_thread_test3); SPLAT_THREAD_TEST3_ID, splat_thread_test3);
return sub; return sub;
@ -376,9 +377,9 @@ void
splat_thread_fini(splat_subsystem_t *sub) splat_thread_fini(splat_subsystem_t *sub)
{ {
ASSERT(sub); ASSERT(sub);
SPLAT_TEST_FINI(sub, SPLAT_THREAD_TEST3_ID); splat_test_fini(sub, SPLAT_THREAD_TEST3_ID);
SPLAT_TEST_FINI(sub, SPLAT_THREAD_TEST2_ID); splat_test_fini(sub, SPLAT_THREAD_TEST2_ID);
SPLAT_TEST_FINI(sub, SPLAT_THREAD_TEST1_ID); splat_test_fini(sub, SPLAT_THREAD_TEST1_ID);
kfree(sub); kfree(sub);
} }

View File

@ -93,9 +93,9 @@ splat_time_init(void)
spin_lock_init(&sub->test_lock); spin_lock_init(&sub->test_lock);
sub->desc.id = SPLAT_SUBSYSTEM_TIME; sub->desc.id = SPLAT_SUBSYSTEM_TIME;
SPLAT_TEST_INIT(sub, SPLAT_TIME_TEST1_NAME, SPLAT_TIME_TEST1_DESC, splat_test_init(sub, SPLAT_TIME_TEST1_NAME, SPLAT_TIME_TEST1_DESC,
SPLAT_TIME_TEST1_ID, splat_time_test1); SPLAT_TIME_TEST1_ID, splat_time_test1);
SPLAT_TEST_INIT(sub, SPLAT_TIME_TEST2_NAME, SPLAT_TIME_TEST2_DESC, splat_test_init(sub, SPLAT_TIME_TEST2_NAME, SPLAT_TIME_TEST2_DESC,
SPLAT_TIME_TEST2_ID, splat_time_test2); SPLAT_TIME_TEST2_ID, splat_time_test2);
return sub; return sub;
@ -106,8 +106,8 @@ splat_time_fini(splat_subsystem_t *sub)
{ {
ASSERT(sub); ASSERT(sub);
SPLAT_TEST_FINI(sub, SPLAT_TIME_TEST2_ID); splat_test_fini(sub, SPLAT_TIME_TEST2_ID);
SPLAT_TEST_FINI(sub, SPLAT_TIME_TEST1_ID); splat_test_fini(sub, SPLAT_TIME_TEST1_ID);
kfree(sub); kfree(sub);
} }

View File

@ -409,19 +409,19 @@ splat_vnode_init(void)
spin_lock_init(&sub->test_lock); spin_lock_init(&sub->test_lock);
sub->desc.id = SPLAT_SUBSYSTEM_VNODE; sub->desc.id = SPLAT_SUBSYSTEM_VNODE;
SPLAT_TEST_INIT(sub, SPLAT_VNODE_TEST1_NAME, SPLAT_VNODE_TEST1_DESC, splat_test_init(sub, SPLAT_VNODE_TEST1_NAME, SPLAT_VNODE_TEST1_DESC,
SPLAT_VNODE_TEST1_ID, splat_vnode_test1); SPLAT_VNODE_TEST1_ID, splat_vnode_test1);
SPLAT_TEST_INIT(sub, SPLAT_VNODE_TEST2_NAME, SPLAT_VNODE_TEST2_DESC, splat_test_init(sub, SPLAT_VNODE_TEST2_NAME, SPLAT_VNODE_TEST2_DESC,
SPLAT_VNODE_TEST2_ID, splat_vnode_test2); SPLAT_VNODE_TEST2_ID, splat_vnode_test2);
SPLAT_TEST_INIT(sub, SPLAT_VNODE_TEST3_NAME, SPLAT_VNODE_TEST3_DESC, splat_test_init(sub, SPLAT_VNODE_TEST3_NAME, SPLAT_VNODE_TEST3_DESC,
SPLAT_VNODE_TEST3_ID, splat_vnode_test3); SPLAT_VNODE_TEST3_ID, splat_vnode_test3);
#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,1,0) #if LINUX_VERSION_CODE <= KERNEL_VERSION(4,1,0)
SPLAT_TEST_INIT(sub, SPLAT_VNODE_TEST4_NAME, SPLAT_VNODE_TEST4_DESC, splat_test_init(sub, SPLAT_VNODE_TEST4_NAME, SPLAT_VNODE_TEST4_DESC,
SPLAT_VNODE_TEST4_ID, splat_vnode_test4); SPLAT_VNODE_TEST4_ID, splat_vnode_test4);
#endif #endif
SPLAT_TEST_INIT(sub, SPLAT_VNODE_TEST5_NAME, SPLAT_VNODE_TEST5_DESC, splat_test_init(sub, SPLAT_VNODE_TEST5_NAME, SPLAT_VNODE_TEST5_DESC,
SPLAT_VNODE_TEST5_ID, splat_vnode_test5); SPLAT_VNODE_TEST5_ID, splat_vnode_test5);
SPLAT_TEST_INIT(sub, SPLAT_VNODE_TEST6_NAME, SPLAT_VNODE_TEST6_DESC, splat_test_init(sub, SPLAT_VNODE_TEST6_NAME, SPLAT_VNODE_TEST6_DESC,
SPLAT_VNODE_TEST6_ID, splat_vnode_test6); SPLAT_VNODE_TEST6_ID, splat_vnode_test6);
return sub; return sub;
@ -432,14 +432,14 @@ splat_vnode_fini(splat_subsystem_t *sub)
{ {
ASSERT(sub); ASSERT(sub);
SPLAT_TEST_FINI(sub, SPLAT_VNODE_TEST6_ID); splat_test_fini(sub, SPLAT_VNODE_TEST6_ID);
SPLAT_TEST_FINI(sub, SPLAT_VNODE_TEST5_ID); splat_test_fini(sub, SPLAT_VNODE_TEST5_ID);
#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,1,0) #if LINUX_VERSION_CODE <= KERNEL_VERSION(4,1,0)
SPLAT_TEST_FINI(sub, SPLAT_VNODE_TEST4_ID); splat_test_fini(sub, SPLAT_VNODE_TEST4_ID);
#endif #endif
SPLAT_TEST_FINI(sub, SPLAT_VNODE_TEST3_ID); splat_test_fini(sub, SPLAT_VNODE_TEST3_ID);
SPLAT_TEST_FINI(sub, SPLAT_VNODE_TEST2_ID); splat_test_fini(sub, SPLAT_VNODE_TEST2_ID);
SPLAT_TEST_FINI(sub, SPLAT_VNODE_TEST1_ID); splat_test_fini(sub, SPLAT_VNODE_TEST1_ID);
kfree(sub); kfree(sub);
} /* splat_vnode_fini() */ } /* splat_vnode_fini() */

View File

@ -144,7 +144,7 @@ splat_zlib_init(void)
spin_lock_init(&sub->test_lock); spin_lock_init(&sub->test_lock);
sub->desc.id = SPLAT_SUBSYSTEM_ZLIB; sub->desc.id = SPLAT_SUBSYSTEM_ZLIB;
SPLAT_TEST_INIT(sub, SPLAT_ZLIB_TEST1_NAME, SPLAT_ZLIB_TEST1_DESC, splat_test_init(sub, SPLAT_ZLIB_TEST1_NAME, SPLAT_ZLIB_TEST1_DESC,
SPLAT_ZLIB_TEST1_ID, splat_zlib_test1); SPLAT_ZLIB_TEST1_ID, splat_zlib_test1);
return sub; return sub;
@ -155,7 +155,7 @@ splat_zlib_fini(splat_subsystem_t *sub)
{ {
ASSERT(sub); ASSERT(sub);
SPLAT_TEST_FINI(sub, SPLAT_ZLIB_TEST1_ID); splat_test_fini(sub, SPLAT_ZLIB_TEST1_ID);
kfree(sub); kfree(sub);
} }

View File

@ -62,8 +62,15 @@ echo -e "support or upgrade DKMS to a more current version."
exit 1 exit 1
%preun %preun
echo -e "Uninstall of %{module} module (version %{version}) beginning:" CONFIG_H="/var/lib/dkms/%{module}/%{version}/*/*/%{module}_config.h"
dkms remove -m %{module} -v %{version} --all --rpm_safe_upgrade SPEC_META_ALIAS="@PACKAGE@-@VERSION@-@RELEASE@"
DKMS_META_ALIAS=`cat $CONFIG_H 2>/dev/null |
awk -F'"' '/META_ALIAS/ { print $2; exit 0 }'`
if [ "$SPEC_META_ALIAS" = "$DKMS_META_ALIAS" ]; then
echo -e
echo -e "Uninstall of %{module} module ($SPEC_META_ALIAS) beginning:"
dkms remove -m %{module} -v %{version} --all --rpm_safe_upgrade
fi
exit 0 exit 0
%changelog %changelog

View File

@ -53,8 +53,8 @@ BuildRequires: %{_bindir}/kmodtool
%endif %endif
%endif %endif
# LDFLAGS are not sanitized by arch/powerpc/Makefile (unlike other arches) # LDFLAGS are not sanitized by arch/*/Makefile for these architectures.
%ifarch ppc ppc64 ppc64le %ifarch ppc ppc64 ppc64le aarch64
%global __global_ldflags %{nil} %global __global_ldflags %{nil}
%endif %endif
@ -167,73 +167,12 @@ chmod u+x ${RPM_BUILD_ROOT}%{kmodinstdir_prefix}/*/extra/*/*/*
rm -rf $RPM_BUILD_ROOT rm -rf $RPM_BUILD_ROOT
%changelog %changelog
* Mon Jul 10 2017 Tony Hutter <hutter2@llnl.gov> - 0.6.5.11-1 * Fri Sep 22 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.2-1
- Fix RWSEM_SPINLOCK_IS_RAW check failed zfsonlinux/zfs#622 - Released 0.7.2-1, detailed release notes are available at:
* Mon Jun 12 2017 Tony Hutter <hutter2@llnl.gov> - 0.6.5.10-1 - https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.2
- Linux 4.12 compat: PF_FSTRANS was removed zfsonlinux/spl#614 * Tue Aug 8 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.1-1
- Clear PF_FSTRANS over spl_filp_fallocate() zfsonlinux/splzfsonlinux/zfs#4529 - Released 0.7.1-1, detailed release notes are available at:
- glibc 2.25 compat: remove assert(X=Y) zfsonlinux/spl#610 - https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.1
- Linux 4.11 compat: remove stub for __put_task_struct zfsonlinux/spl#608 * Wed Jul 26 2017 Brian Behlendorf <behlendorf1@llnl.gov> - 0.7.0-1
- Linux 4.11 compat: add linux/sched/signal.h zfsonlinux/spl#608 - Released 0.7.0-1, detailed release notes are available at:
- Linux 4.11 compat: vfs_getattr() takes 4 args zfsonlinux/spl#608 - https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.0
- Fix powerpc build zfsonlinux/spl#607
- Linux 4.11 compat: set_task_state() removed zfsonlinux/spl#603
* Fri Feb 3 2017 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.5.9-1
- Use kernel slab for vn_cache and vn_file_cache zfsonlinux/spl#599
- Fix splat-cred.c cred usage zfsonlinux/spl#556
- Fix splat memleak zfsonlinux/spl#590
- Fix p0 initializer zfsonlinux/spl#576
- Fix aarch64 type warning zfsonlinux/spl#574
- Linux 4.8 compat: Fix RW_READ_HELD zfsonlinux/zfs#5233
- Linux 4.9 compat: group_info changes zfsonlinux/spl#581
- Fix crgetgroups out-of-bound and misc cred fix zfsonlinux/spl#556
* Fri Sep 9 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.8-1
- Fix HAVE_MUTEX_OWNER test for kernels prior to 4.6 zfsonlinux/spl#566
- Add handling for kernel 4.7's CONFIG_TRIM_UNUSED_KSYMS zfsonlinux/spl#565
- Linux 4.8 compat: rw_semaphore atomic_long_t count zfsonlinux/spl#563
- Implement a proper rw_tryupgrade zfsonlinux/spl#554
- Add rw_tryupgrade() zfsonlinux/spl#534 zfsonlinux/zfs#4388
- Fix taskq_wait_outstanding re-evaluate tq_next_id zfsonlinux/spl#553
- Fix race between taskq_destroy and dynamic spawning thread zfsonlinux/spl#553 zfsonlinux/spl#550
- Use kernel provided mutex owner zfsonlinux/spl#553 zfsonlinux/spl#550
- Add isa_defs for MIPS zfsonlinux/spl#558
- Linux 4.7 compat: inode_lock() and friends zfsonlinux/spl#549
- Fix: handle NULL case in spl_kmem_free_track() zfsonlinux/spl#567
* Thu May 12 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.7-1
- Fix PPC build failure zfsonlinux/spl#516
* Tue Mar 22 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.6-1
- Remove artificial architecture restrictions in packaging
- Add support for s390[x] zfsonlinux/spl#537
* Wed Mar 9 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.5-1
- Linux 4.5 compatibility zfsonlinux/spl#524
- Create working debuginfo packages on Red Hat zfsonlinux/zfs#4224
- Allow copy-builtin to run multiple times zfsonlinux/spl#526
- Use safer flags for in-kernel memory allocations zfsonlinux/spl#523
- Fix potential deadlock in cv_wait() zfsonlinux/zfs#4106
- Fix livelock in shrinker zfsonlinux/zfs#3936
* Fri Jan 8 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.4-1
- Build fixes on SPARC and some kernels
- Fix taskq dynamic spawning deadlock
- Fix builtin kernel builds
- Fix crash due to overflow in P2ROUNDUP macro
- Fix deadlock during direct memory reclaim
* Tue Oct 13 2015 Ned Bass <bass6@llnl.gov> - 0.6.5.3-1
- Fix CPU hotplug zfsonlinux/spl#482
- Disable dynamic taskqs by default to avoid deadlock zfsonlinux/spl#484
* Tue Sep 29 2015 Ned Bass <bass6@llnl.gov> - 0.6.5.2-1
- Released 0.6.5.2-1
- Fix PAX Patch/Grsec SLAB_USERCOPY panic zfsonlinux/zfs#3796
- Always remove during dkms uninstall/update zfsonlinux/spl#476
* Thu Sep 19 2015 Ned Bass <bass6@llnl.gov> - 0.6.5.1-1
- Released 0.6.5.1-1, no changes from spl-0.6.5
* Thu Sep 10 2015 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.5-1
- Released 0.6.5-1, detailed release notes are available at:
- https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.6.5
* Wed Apr 8 2015 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.4-1
- Released 0.6.4-1
* Thu Jun 12 2014 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.3-1
- Released 0.6.3-1
* Wed Aug 21 2013 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.2-1
- Released 0.6.2-1
* Fri Mar 22 2013 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.1-1
- First official stable release.

View File

@ -28,78 +28,18 @@ make install DESTDIR=%{?buildroot}
%files %files
%doc AUTHORS COPYING DISCLAIMER %doc AUTHORS COPYING DISCLAIMER
%{_bindir}/*
%{_sbindir}/* %{_sbindir}/*
%{_mandir}/man1/* %{_mandir}/man1/*
%{_mandir}/man5/* %{_mandir}/man5/*
%changelog %changelog
* Mon Jul 10 2017 Tony Hutter <hutter2@llnl.gov> - 0.6.5.11-1 * Fri Sep 22 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.2-1
- Fix RWSEM_SPINLOCK_IS_RAW check failed zfsonlinux/zfs#622 - Released 0.7.2-1, detailed release notes are available at:
* Mon Jun 12 2017 Tony Hutter <hutter2@llnl.gov> - 0.6.5.10-1 - https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.2
- Linux 4.12 compat: PF_FSTRANS was removed zfsonlinux/spl#614 * Tue Aug 8 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.1-1
- Clear PF_FSTRANS over spl_filp_fallocate() zfsonlinux/splzfsonlinux/zfs#4529 - Released 0.7.1-1, detailed release notes are available at:
- glibc 2.25 compat: remove assert(X=Y) zfsonlinux/spl#610 - https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.1
- Linux 4.11 compat: remove stub for __put_task_struct zfsonlinux/spl#608 * Wed Jul 26 2017 Brian Behlendorf <behlendorf1@llnl.gov> - 0.7.0-1
- Linux 4.11 compat: add linux/sched/signal.h zfsonlinux/spl#608 - Released 0.7.0-1, detailed release notes are available at:
- Linux 4.11 compat: vfs_getattr() takes 4 args zfsonlinux/spl#608 - https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.0
- Fix powerpc build zfsonlinux/spl#607
- Linux 4.11 compat: set_task_state() removed zfsonlinux/spl#603
* Fri Feb 3 2017 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.5.9-1
- Use kernel slab for vn_cache and vn_file_cache zfsonlinux/spl#599
- Fix splat-cred.c cred usage zfsonlinux/spl#556
- Fix splat memleak zfsonlinux/spl#590
- Fix p0 initializer zfsonlinux/spl#576
- Fix aarch64 type warning zfsonlinux/spl#574
- Linux 4.8 compat: Fix RW_READ_HELD zfsonlinux/zfs#5233
- Linux 4.9 compat: group_info changes zfsonlinux/spl#581
- Fix crgetgroups out-of-bound and misc cred fix zfsonlinux/spl#556
* Fri Sep 9 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.8-1
- Fix HAVE_MUTEX_OWNER test for kernels prior to 4.6 zfsonlinux/spl#566
- Add handling for kernel 4.7's CONFIG_TRIM_UNUSED_KSYMS zfsonlinux/spl#565
- Linux 4.8 compat: rw_semaphore atomic_long_t count zfsonlinux/spl#563
- Implement a proper rw_tryupgrade zfsonlinux/spl#554
- Add rw_tryupgrade() zfsonlinux/spl#534 zfsonlinux/zfs#4388
- Fix taskq_wait_outstanding re-evaluate tq_next_id zfsonlinux/spl#553
- Fix race between taskq_destroy and dynamic spawning thread zfsonlinux/spl#553 zfsonlinux/spl#550
- Use kernel provided mutex owner zfsonlinux/spl#553 zfsonlinux/spl#550
- Add isa_defs for MIPS zfsonlinux/spl#558
- Linux 4.7 compat: inode_lock() and friends zfsonlinux/spl#549
- Fix: handle NULL case in spl_kmem_free_track() zfsonlinux/spl#567
* Thu May 12 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.7-1
- Fix PPC build failure zfsonlinux/spl#516
* Tue Mar 22 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.6-1
- Remove artificial architecture restrictions in packaging
- Add support for s390[x] zfsonlinux/spl#537
* Wed Mar 9 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.5-1
- Linux 4.5 compatibility zfsonlinux/spl#524
- Create working debuginfo packages on Red Hat zfsonlinux/zfs#4224
- Allow copy-builtin to run multiple times zfsonlinux/spl#526
- Use safer flags for in-kernel memory allocations zfsonlinux/spl#523
- Fix potential deadlock in cv_wait() zfsonlinux/zfs#4106
- Fix livelock in shrinker zfsonlinux/zfs#3936
* Fri Jan 8 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.4-1
- Build fixes on SPARC and some kernels
- Fix taskq dynamic spawning deadlock
- Fix builtin kernel builds
- Fix crash due to overflow in P2ROUNDUP macro
- Fix deadlock during direct memory reclaim
* Tue Oct 13 2015 Ned Bass <bass6@llnl.gov> - 0.6.5.3-1
- Fix CPU hotplug zfsonlinux/spl#482
- Disable dynamic taskqs by default to avoid deadlock zfsonlinux/spl#484
* Tue Sep 29 2015 Ned Bass <bass6@llnl.gov> - 0.6.5.2-1
- Released 0.6.5.2-1
- Fix PAX Patch/Grsec SLAB_USERCOPY panic zfsonlinux/zfs#3796
- Always remove during dkms uninstall/update zfsonlinux/spl#476
* Thu Sep 19 2015 Ned Bass <bass6@llnl.gov> - 0.6.5.1-1
- Released 0.6.5.1-1, no changes from spl-0.6.5
* Thu Sep 10 2015 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.5-1
- Released 0.6.5-1, detailed release notes are available at:
- https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.6.5
* Wed Apr 8 2015 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.4-1
- Released 0.6.4-1
* Thu Jun 12 2014 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.3-1
- Released 0.6.3-1
* Wed Aug 21 2013 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.2-1
- Released 0.6.2-1
* Fri Mar 22 2013 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.1-1
- First official stable release.

View File

@ -62,8 +62,15 @@ echo -e "support or upgrade DKMS to a more current version."
exit 1 exit 1
%preun %preun
echo -e "Uninstall of %{module} module (version %{version}) beginning:" CONFIG_H="/var/lib/dkms/%{module}/%{version}/*/*/%{module}_config.h"
dkms remove -m %{module} -v %{version} --all --rpm_safe_upgrade SPEC_META_ALIAS="@PACKAGE@-@VERSION@-@RELEASE@"
DKMS_META_ALIAS=`cat $CONFIG_H 2>/dev/null |
awk -F'"' '/META_ALIAS/ { print $2; exit 0 }'`
if [ "$SPEC_META_ALIAS" = "$DKMS_META_ALIAS" ]; then
echo -e
echo -e "Uninstall of %{module} module ($SPEC_META_ALIAS) beginning:"
dkms remove -m %{module} -v %{version} --all --rpm_safe_upgrade
fi
exit 0 exit 0
%changelog %changelog

View File

@ -22,8 +22,8 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
Requires: @PACKAGE@ = %{version}\n\ Requires: @PACKAGE@ = %{version}\n\
Conflicts: @PACKAGE@-dkms\n\n" > %{_sourcedir}/kmod-preamble) Conflicts: @PACKAGE@-dkms\n\n" > %{_sourcedir}/kmod-preamble)
# LDFLAGS are not sanitized by arch/powerpc/Makefile (unlike other arches) # LDFLAGS are not sanitized by arch/*/Makefile for these architectures.
%ifarch ppc ppc64 ppc64le %ifarch ppc ppc64 ppc64le aarch64
%global __global_ldflags %{nil} %global __global_ldflags %{nil}
%endif %endif

View File

@ -28,78 +28,18 @@ make install DESTDIR=%{?buildroot}
%files %files
%doc AUTHORS COPYING DISCLAIMER %doc AUTHORS COPYING DISCLAIMER
%{_bindir}/*
%{_sbindir}/* %{_sbindir}/*
%{_mandir}/man1/* %{_mandir}/man1/*
%{_mandir}/man5/* %{_mandir}/man5/*
%changelog %changelog
* Mon Jul 10 2017 Tony Hutter <hutter2@llnl.gov> - 0.6.5.11-1 * Fri Sep 22 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.2-1
- Fix RWSEM_SPINLOCK_IS_RAW check failed zfsonlinux/zfs#622 - Released 0.7.2-1, detailed release notes are available at:
* Mon Jun 12 2017 Tony Hutter <hutter2@llnl.gov> - 0.6.5.10-1 - https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.2
- Linux 4.12 compat: PF_FSTRANS was removed zfsonlinux/spl#614 * Tue Aug 8 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.1-1
- Clear PF_FSTRANS over spl_filp_fallocate() zfsonlinux/splzfsonlinux/zfs#4529 - Released 0.7.1-1, detailed release notes are available at:
- glibc 2.25 compat: remove assert(X=Y) zfsonlinux/spl#610 - https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.1
- Linux 4.11 compat: remove stub for __put_task_struct zfsonlinux/spl#608 * Wed Jul 26 2017 Brian Behlendorf <behlendorf1@llnl.gov> - 0.7.0-1
- Linux 4.11 compat: add linux/sched/signal.h zfsonlinux/spl#608 - Released 0.7.0-1, detailed release notes are available at:
- Linux 4.11 compat: vfs_getattr() takes 4 args zfsonlinux/spl#608 - https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.0
- Fix powerpc build zfsonlinux/spl#607
- Linux 4.11 compat: set_task_state() removed zfsonlinux/spl#603
* Fri Feb 3 2017 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.5.9-1
- Use kernel slab for vn_cache and vn_file_cache zfsonlinux/spl#599
- Fix splat-cred.c cred usage zfsonlinux/spl#556
- Fix splat memleak zfsonlinux/spl#590
- Fix p0 initializer zfsonlinux/spl#576
- Fix aarch64 type warning zfsonlinux/spl#574
- Linux 4.8 compat: Fix RW_READ_HELD zfsonlinux/zfs#5233
- Linux 4.9 compat: group_info changes zfsonlinux/spl#581
- Fix crgetgroups out-of-bound and misc cred fix zfsonlinux/spl#556
* Fri Sep 9 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.8-1
- Fix HAVE_MUTEX_OWNER test for kernels prior to 4.6 zfsonlinux/spl#566
- Add handling for kernel 4.7's CONFIG_TRIM_UNUSED_KSYMS zfsonlinux/spl#565
- Linux 4.8 compat: rw_semaphore atomic_long_t count zfsonlinux/spl#563
- Implement a proper rw_tryupgrade zfsonlinux/spl#554
- Add rw_tryupgrade() zfsonlinux/spl#534 zfsonlinux/zfs#4388
- Fix taskq_wait_outstanding re-evaluate tq_next_id zfsonlinux/spl#553
- Fix race between taskq_destroy and dynamic spawning thread zfsonlinux/spl#553 zfsonlinux/spl#550
- Use kernel provided mutex owner zfsonlinux/spl#553 zfsonlinux/spl#550
- Add isa_defs for MIPS zfsonlinux/spl#558
- Linux 4.7 compat: inode_lock() and friends zfsonlinux/spl#549
- Fix: handle NULL case in spl_kmem_free_track() zfsonlinux/spl#567
* Thu May 12 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.7-1
- Fix PPC build failure zfsonlinux/spl#516
* Tue Mar 22 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.6-1
- Remove artificial architecture restrictions in packaging
- Add support for s390[x] zfsonlinux/spl#537
* Wed Mar 9 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.5-1
- Linux 4.5 compatibility zfsonlinux/spl#524
- Create working debuginfo packages on Red Hat zfsonlinux/zfs#4224
- Allow copy-builtin to run multiple times zfsonlinux/spl#526
- Use safer flags for in-kernel memory allocations zfsonlinux/spl#523
- Fix potential deadlock in cv_wait() zfsonlinux/zfs#4106
- Fix livelock in shrinker zfsonlinux/zfs#3936
* Fri Jan 8 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.4-1
- Build fixes on SPARC and some kernels
- Fix taskq dynamic spawning deadlock
- Fix builtin kernel builds
- Fix crash due to overflow in P2ROUNDUP macro
- Fix deadlock during direct memory reclaim
* Tue Oct 13 2015 Ned Bass <bass6@llnl.gov> - 0.6.5.3-1
- Fix CPU hotplug zfsonlinux/spl#482
- Disable dynamic taskqs by default to avoid deadlock zfsonlinux/spl#484
* Tue Sep 29 2015 Ned Bass <bass6@llnl.gov> - 0.6.5.2-1
- Released 0.6.5.2-1
- Fix PAX Patch/Grsec SLAB_USERCOPY panic zfsonlinux/zfs#3796
- Always remove during dkms uninstall/update zfsonlinux/spl#476
* Thu Sep 19 2015 Ned Bass <bass6@llnl.gov> - 0.6.5.1-1
- Released 0.6.5.1-1, no changes from spl-0.6.5
* Thu Sep 10 2015 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.5-1
- Released 0.6.5-1, detailed release notes are available at:
- https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.6.5
* Wed Apr 8 2015 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.4-1
- Released 0.6.4-1
* Thu Jun 12 2014 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.3-1
- Released 0.6.3-1
* Wed Aug 21 2013 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.2-1
- Released 0.6.2-1
* Fri Mar 22 2013 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.1-1
- First official stable release.

View File

@ -28,7 +28,7 @@
prog=check.sh prog=check.sh
spl_module=../module/spl/spl.ko spl_module=../module/spl/spl.ko
splat_module=../module/splat/splat.ko splat_module=../module/splat/splat.ko
splat_cmd=../cmd/splat splat_cmd=../cmd/splat/splat
verbose= verbose=
die() { die() {

View File

@ -81,6 +81,9 @@
/* struct kmem_cache has allocflags */ /* struct kmem_cache has allocflags */
#undef HAVE_KMEM_CACHE_ALLOCFLAGS #undef HAVE_KMEM_CACHE_ALLOCFLAGS
/* kmem_cache_create_usercopy() exists */
#undef HAVE_KMEM_CACHE_CREATE_USERCOPY
/* struct kmem_cache has gfpflags */ /* struct kmem_cache has gfpflags */
#undef HAVE_KMEM_CACHE_GFPFLAGS #undef HAVE_KMEM_CACHE_GFPFLAGS
@ -90,9 +93,6 @@
/* Define to 1 if you have the <memory.h> header file. */ /* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H #undef HAVE_MEMORY_H
/* yes */
#undef HAVE_MUTEX_OWNER
/* yes */ /* yes */
#undef HAVE_PDE_DATA #undef HAVE_PDE_DATA
@ -144,6 +144,12 @@
/* yes */ /* yes */
#undef HAVE_WAIT_ON_BIT_ACTION #undef HAVE_WAIT_ON_BIT_ACTION
/* wait_queue_entry_t exists */
#undef HAVE_WAIT_QUEUE_ENTRY_T
/* wq_head->head and wq_entry->entry exist */
#undef HAVE_WAIT_QUEUE_HEAD_ENTRY
/* Define to the sub-directory in which libtool stores uninstalled libraries. /* Define to the sub-directory in which libtool stores uninstalled libraries.
*/ */
#undef LT_OBJDIR #undef LT_OBJDIR