Retire legacy debugging infrastructure
When the SPL was originally written Linux tracepoints were still in their infancy. Therefore, an entire debugging subsystem was added to facilite tracing which served us well for many years. Now that Linux tracepoints have matured they provide all the functionality of the previous tracing subsystem. Rather than maintain parallel functionality it makes sense to fully adopt tracepoints. Therefore, this patch retires the legacy debugging infrastructure. See zfsonlinux/zfs@bc9f413 for the tracepoint changes. Signed-off-by: Ned Bass <bass6@llnl.gov> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #408
This commit is contained in:
parent
917fef2732
commit
8d9a23e82c
|
@ -3,11 +3,8 @@ include $(top_srcdir)/config/Rules.am
|
||||||
DEFAULT_INCLUDES += \
|
DEFAULT_INCLUDES += \
|
||||||
-I$(top_srcdir)/lib
|
-I$(top_srcdir)/lib
|
||||||
|
|
||||||
noinst_PROGRAMS = spl
|
|
||||||
sbin_PROGRAMS = splat
|
sbin_PROGRAMS = splat
|
||||||
|
|
||||||
spl_SOURCES = spl.c
|
|
||||||
|
|
||||||
splat_SOURCES = splat.c
|
splat_SOURCES = splat.c
|
||||||
splat_LDFLAGS = $(top_builddir)/lib/libcommon.la
|
splat_LDFLAGS = $(top_builddir)/lib/libcommon.la
|
||||||
|
|
||||||
|
|
243
cmd/spl.c
243
cmd/spl.c
|
@ -1,243 +0,0 @@
|
||||||
/*****************************************************************************\
|
|
||||||
* 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/>.
|
|
||||||
*****************************************************************************
|
|
||||||
* Solaris Porting Layer (SPL) User Space Interface.
|
|
||||||
\*****************************************************************************/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include "../include/spl-ctl.h"
|
|
||||||
|
|
||||||
static int spl_debug_mask = ~0;
|
|
||||||
static int spl_debug_subsystem = ~0;
|
|
||||||
|
|
||||||
/* all strings nul-terminated; only the struct and hdr need to be freed */
|
|
||||||
struct dbg_line {
|
|
||||||
struct spl_debug_header *hdr;
|
|
||||||
char *file;
|
|
||||||
char *fn;
|
|
||||||
char *text;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
|
||||||
cmp_rec(const void *p1, const void *p2)
|
|
||||||
{
|
|
||||||
struct dbg_line *d1 = *(struct dbg_line **)p1;
|
|
||||||
struct dbg_line *d2 = *(struct dbg_line **)p2;
|
|
||||||
|
|
||||||
if (d1->hdr->ph_sec < d2->hdr->ph_sec)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (d1->hdr->ph_sec == d2->hdr->ph_sec &&
|
|
||||||
d1->hdr->ph_usec < d2->hdr->ph_usec)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (d1->hdr->ph_sec == d2->hdr->ph_sec &&
|
|
||||||
d1->hdr->ph_usec == d2->hdr->ph_usec)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
print_rec(struct dbg_line **linev, int used, FILE *out)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < used; i++) {
|
|
||||||
struct dbg_line *line = linev[i];
|
|
||||||
struct spl_debug_header *hdr = line->hdr;
|
|
||||||
|
|
||||||
fprintf(out, "%08x:%08x:%u:%u.%06llu:%u:%u:%u:(%s:%u:%s()) %s",
|
|
||||||
hdr->ph_subsys, hdr->ph_mask, hdr->ph_cpu_id,
|
|
||||||
hdr->ph_sec, (unsigned long long)hdr->ph_usec,
|
|
||||||
hdr->ph_stack, hdr->ph_pid, hdr->ph_stack, line->file,
|
|
||||||
hdr->ph_line_num, line->fn, line->text);
|
|
||||||
free(line->hdr);
|
|
||||||
free(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(linev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
add_rec(struct dbg_line *line, struct dbg_line ***linevp, int *lenp, int used)
|
|
||||||
{
|
|
||||||
struct dbg_line **linev = *linevp;
|
|
||||||
|
|
||||||
if (used == *lenp) {
|
|
||||||
int nlen = *lenp + 512;
|
|
||||||
int nsize = nlen * sizeof(struct dbg_line *);
|
|
||||||
|
|
||||||
linev = *linevp ? realloc(*linevp, nsize) : malloc(nsize);
|
|
||||||
if (!linev)
|
|
||||||
return 0;
|
|
||||||
*linevp = linev;
|
|
||||||
*lenp = nlen;
|
|
||||||
}
|
|
||||||
linev[used] = line;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
parse_buffer(FILE *in, FILE *out)
|
|
||||||
{
|
|
||||||
struct dbg_line *line;
|
|
||||||
struct spl_debug_header *hdr;
|
|
||||||
char buf[4097], *p;
|
|
||||||
unsigned long dropped = 0, kept = 0;
|
|
||||||
struct dbg_line **linev = NULL;
|
|
||||||
const int phl = sizeof(hdr->ph_len);
|
|
||||||
const int phf = sizeof(hdr->ph_flags);
|
|
||||||
int rc, linev_len = 0;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
rc = fread(buf, phl + phf, 1, in);
|
|
||||||
if (rc <= 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
hdr = (void *)buf;
|
|
||||||
if (hdr->ph_len == 0)
|
|
||||||
break;
|
|
||||||
if (hdr->ph_len > 4094) {
|
|
||||||
fprintf(stderr, "unexpected large record: %d bytes. "
|
|
||||||
"aborting.\n", hdr->ph_len);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = fread(buf + phl + phf, 1, hdr->ph_len - phl - phf, in);
|
|
||||||
if (rc <= 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (hdr->ph_mask &&
|
|
||||||
(!(spl_debug_subsystem & hdr->ph_subsys) ||
|
|
||||||
(!(spl_debug_mask & hdr->ph_mask)))) {
|
|
||||||
dropped++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
line = malloc(sizeof(*line));
|
|
||||||
if (line == NULL) {
|
|
||||||
fprintf(stderr, "malloc failed; printing accumulated "
|
|
||||||
"records and exiting.\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
line->hdr = malloc(hdr->ph_len + 1);
|
|
||||||
if (line->hdr == NULL) {
|
|
||||||
free(line);
|
|
||||||
fprintf(stderr, "malloc failed; printing accumulated "
|
|
||||||
"records and exiting.\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = (void *)line->hdr;
|
|
||||||
memcpy(line->hdr, buf, hdr->ph_len);
|
|
||||||
p[hdr->ph_len] = '\0';
|
|
||||||
|
|
||||||
p += sizeof(*hdr);
|
|
||||||
line->file = p;
|
|
||||||
p += strlen(line->file) + 1;
|
|
||||||
line->fn = p;
|
|
||||||
p += strlen(line->fn) + 1;
|
|
||||||
line->text = p;
|
|
||||||
|
|
||||||
if (!add_rec(line, &linev, &linev_len, kept)) {
|
|
||||||
fprintf(stderr, "malloc failed; printing accumulated "
|
|
||||||
"records and exiting.\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
kept++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (linev) {
|
|
||||||
qsort(linev, kept, sizeof(struct dbg_line *), cmp_rec);
|
|
||||||
print_rec(linev, kept, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Debug log: %lu lines, %lu kept, %lu dropped.\n",
|
|
||||||
dropped + kept, kept, dropped);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int fdin, fdout;
|
|
||||||
FILE *in, *out = stdout;
|
|
||||||
int rc, o_lf = 0;
|
|
||||||
|
|
||||||
if (argc > 3 || argc < 2) {
|
|
||||||
fprintf(stderr, "usage: %s <input> [output]\n", argv[0]);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __USE_LARGEFILE64
|
|
||||||
o_lf = O_LARGEFILE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fdin = open(argv[1], O_RDONLY | o_lf);
|
|
||||||
if (fdin == -1) {
|
|
||||||
fprintf(stderr, "open(%s) failed: %s\n", argv[1],
|
|
||||||
strerror(errno));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
in = fdopen(fdin, "r");
|
|
||||||
if (in == NULL) {
|
|
||||||
fprintf(stderr, "fopen(%s) failed: %s\n", argv[1],
|
|
||||||
strerror(errno));
|
|
||||||
close(fdin);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (argc > 2) {
|
|
||||||
fdout = open(argv[2], O_CREAT | O_TRUNC | O_WRONLY | o_lf, 0600);
|
|
||||||
if (fdout == -1) {
|
|
||||||
fprintf(stderr, "open(%s) failed: %s\n", argv[2],
|
|
||||||
strerror(errno));
|
|
||||||
fclose(in);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
out = fdopen(fdout, "w");
|
|
||||||
if (out == NULL) {
|
|
||||||
fprintf(stderr, "fopen(%s) failed: %s\n", argv[2],
|
|
||||||
strerror(errno));
|
|
||||||
fclose(in);
|
|
||||||
close(fdout);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = parse_buffer(in, out);
|
|
||||||
|
|
||||||
fclose(in);
|
|
||||||
if (out != stdout)
|
|
||||||
fclose(out);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
|
@ -18,7 +18,6 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
|
||||||
AC_SUBST(KERNELCPPFLAGS)
|
AC_SUBST(KERNELCPPFLAGS)
|
||||||
|
|
||||||
SPL_AC_DEBUG
|
SPL_AC_DEBUG
|
||||||
SPL_AC_DEBUG_LOG
|
|
||||||
SPL_AC_DEBUG_KMEM
|
SPL_AC_DEBUG_KMEM
|
||||||
SPL_AC_DEBUG_KMEM_TRACKING
|
SPL_AC_DEBUG_KMEM_TRACKING
|
||||||
SPL_AC_TEST_MODULE
|
SPL_AC_TEST_MODULE
|
||||||
|
@ -219,7 +218,7 @@ AC_DEFUN([SPL_AC_RPM], [
|
||||||
AC_MSG_RESULT([$HAVE_RPMBUILD])
|
AC_MSG_RESULT([$HAVE_RPMBUILD])
|
||||||
])
|
])
|
||||||
|
|
||||||
RPM_DEFINE_COMMON='--define "$(DEBUG_SPL) 1" --define "$(DEBUG_LOG) 1" --define "$(DEBUG_KMEM) 1" --define "$(DEBUG_KMEM_TRACKING) 1"'
|
RPM_DEFINE_COMMON='--define "$(DEBUG_SPL) 1" --define "$(DEBUG_KMEM) 1" --define "$(DEBUG_KMEM_TRACKING) 1"'
|
||||||
RPM_DEFINE_UTIL=
|
RPM_DEFINE_UTIL=
|
||||||
RPM_DEFINE_KMOD='--define "kernels $(LINUX_VERSION)"'
|
RPM_DEFINE_KMOD='--define "kernels $(LINUX_VERSION)"'
|
||||||
RPM_DEFINE_DKMS=
|
RPM_DEFINE_DKMS=
|
||||||
|
@ -452,39 +451,6 @@ AC_DEFUN([SPL_AC_DEBUG], [
|
||||||
AC_MSG_RESULT([$enable_debug])
|
AC_MSG_RESULT([$enable_debug])
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl #
|
|
||||||
dnl # Enabled by default it provides a basic debug log infrastructure.
|
|
||||||
dnl # Each subsystem registers itself with a name and logs messages
|
|
||||||
dnl # using predefined types. If the debug mask it set to allow the
|
|
||||||
dnl # message type it will be written to the internal log. The log
|
|
||||||
dnl # can be dumped to a file by echoing 1 to the 'dump' proc entry,
|
|
||||||
dnl # after dumping the log it must be decoded using the spl utility.
|
|
||||||
dnl #
|
|
||||||
dnl # echo 1 >/proc/sys/kernel/spl/debug/dump
|
|
||||||
dnl # spl /tmp/spl-log.xxx.yyy /tmp/spl-log.xxx.yyy.txt
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([SPL_AC_DEBUG_LOG], [
|
|
||||||
AC_ARG_ENABLE([debug-log],
|
|
||||||
[AS_HELP_STRING([--enable-debug-log],
|
|
||||||
[Enable basic debug logging @<:@default=yes@:>@])],
|
|
||||||
[],
|
|
||||||
[enable_debug_log=yes])
|
|
||||||
|
|
||||||
AS_IF([test "x$enable_debug_log" = xyes],
|
|
||||||
[
|
|
||||||
KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_LOG"
|
|
||||||
DEBUG_LOG="_with_debug_log"
|
|
||||||
AC_DEFINE([DEBUG_LOG], [1],
|
|
||||||
[Define to 1 to enable basic debug logging])
|
|
||||||
], [
|
|
||||||
DEBUG_LOG="_without_debug_log"
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_SUBST(DEBUG_LOG)
|
|
||||||
AC_MSG_CHECKING([whether basic debug logging is enabled])
|
|
||||||
AC_MSG_RESULT([$enable_debug_log])
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # Enabled by default it provides a minimal level of memory tracking.
|
dnl # Enabled by default it provides a minimal level of memory tracking.
|
||||||
dnl # A total count of bytes allocated is kept for each alloc and free.
|
dnl # A total count of bytes allocated is kept for each alloc and free.
|
||||||
|
|
|
@ -5,8 +5,6 @@ COMMON_H =
|
||||||
KERNEL_H = \
|
KERNEL_H = \
|
||||||
$(top_srcdir)/include/splat-ctl.h \
|
$(top_srcdir)/include/splat-ctl.h \
|
||||||
$(top_srcdir)/include/spl-ctl.h \
|
$(top_srcdir)/include/spl-ctl.h \
|
||||||
$(top_srcdir)/include/spl-debug.h \
|
|
||||||
$(top_srcdir)/include/spl-trace.h \
|
|
||||||
$(top_srcdir)/include/strings.h \
|
$(top_srcdir)/include/strings.h \
|
||||||
$(top_srcdir)/include/unistd.h
|
$(top_srcdir)/include/unistd.h
|
||||||
|
|
||||||
|
|
|
@ -1,276 +0,0 @@
|
||||||
/*****************************************************************************\
|
|
||||||
* 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/>.
|
|
||||||
\*****************************************************************************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Available debug functions. These function should be used by any
|
|
||||||
* package which needs to integrate with the SPL log infrastructure.
|
|
||||||
*
|
|
||||||
* SDEBUG() - Log debug message with specified mask.
|
|
||||||
* SDEBUG_LIMIT() - Log just 1 debug message with specified mask.
|
|
||||||
* SWARN() - Log a warning message.
|
|
||||||
* SERROR() - Log an error message.
|
|
||||||
* SEMERG() - Log an emergency error message.
|
|
||||||
* SCONSOLE() - Log a generic message to the console.
|
|
||||||
*
|
|
||||||
* SENTRY - Log entry point to a function.
|
|
||||||
* SEXIT - Log exit point from a function.
|
|
||||||
* SRETURN(x) - Log return from a function.
|
|
||||||
* SGOTO(x, y) - Log goto within a function.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _SPL_DEBUG_INTERNAL_H
|
|
||||||
#define _SPL_DEBUG_INTERNAL_H
|
|
||||||
|
|
||||||
#include <linux/limits.h>
|
|
||||||
#include <linux/sched.h>
|
|
||||||
|
|
||||||
#define SS_UNDEFINED 0x00000001
|
|
||||||
#define SS_ATOMIC 0x00000002
|
|
||||||
#define SS_KOBJ 0x00000004
|
|
||||||
#define SS_VNODE 0x00000008
|
|
||||||
#define SS_TIME 0x00000010
|
|
||||||
#define SS_RWLOCK 0x00000020
|
|
||||||
#define SS_THREAD 0x00000040
|
|
||||||
#define SS_CONDVAR 0x00000080
|
|
||||||
#define SS_MUTEX 0x00000100
|
|
||||||
#define SS_RNG 0x00000200
|
|
||||||
#define SS_TASKQ 0x00000400
|
|
||||||
#define SS_KMEM 0x00000800
|
|
||||||
#define SS_DEBUG 0x00001000
|
|
||||||
#define SS_GENERIC 0x00002000
|
|
||||||
#define SS_PROC 0x00004000
|
|
||||||
#define SS_MODULE 0x00008000
|
|
||||||
#define SS_CRED 0x00010000
|
|
||||||
#define SS_KSTAT 0x00020000
|
|
||||||
#define SS_XDR 0x00040000
|
|
||||||
#define SS_TSD 0x00080000
|
|
||||||
#define SS_ZLIB 0x00100000
|
|
||||||
#define SS_USER1 0x01000000
|
|
||||||
#define SS_USER2 0x02000000
|
|
||||||
#define SS_USER3 0x04000000
|
|
||||||
#define SS_USER4 0x08000000
|
|
||||||
#define SS_USER5 0x10000000
|
|
||||||
#define SS_USER6 0x20000000
|
|
||||||
#define SS_USER7 0x40000000
|
|
||||||
#define SS_USER8 0x80000000
|
|
||||||
#define SS_DEBUG_SUBSYS SS_UNDEFINED
|
|
||||||
|
|
||||||
#define SD_TRACE 0x00000001
|
|
||||||
#define SD_INFO 0x00000002
|
|
||||||
#define SD_WARNING 0x00000004
|
|
||||||
#define SD_ERROR 0x00000008
|
|
||||||
#define SD_EMERG 0x00000010
|
|
||||||
#define SD_CONSOLE 0x00000020
|
|
||||||
#define SD_IOCTL 0x00000040
|
|
||||||
#define SD_DPRINTF 0x00000080
|
|
||||||
#define SD_OTHER 0x00000100
|
|
||||||
#define SD_CANTMASK (SD_ERROR | SD_EMERG | SD_WARNING | SD_CONSOLE)
|
|
||||||
|
|
||||||
/* Debug log support enabled */
|
|
||||||
#ifdef DEBUG_LOG
|
|
||||||
|
|
||||||
#define __SDEBUG(cdls, subsys, mask, format, a...) \
|
|
||||||
do { \
|
|
||||||
if (((mask) & SD_CANTMASK) != 0 || \
|
|
||||||
((spl_debug_mask & (mask)) != 0 && \
|
|
||||||
(spl_debug_subsys & (subsys)) != 0)) \
|
|
||||||
spl_debug_msg(cdls, subsys, mask, __FILE__, \
|
|
||||||
__FUNCTION__, __LINE__, format, ## a); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define SDEBUG(mask, format, a...) \
|
|
||||||
__SDEBUG(NULL, SS_DEBUG_SUBSYS, mask, format, ## a)
|
|
||||||
|
|
||||||
#define __SDEBUG_LIMIT(subsys, mask, format, a...) \
|
|
||||||
do { \
|
|
||||||
static spl_debug_limit_state_t cdls; \
|
|
||||||
\
|
|
||||||
__SDEBUG(&cdls, subsys, mask, format, ## a); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define SDEBUG_LIMIT(mask, format, a...) \
|
|
||||||
__SDEBUG_LIMIT(SS_DEBUG_SUBSYS, mask, format, ## a)
|
|
||||||
|
|
||||||
#define SWARN(fmt, a...) SDEBUG_LIMIT(SD_WARNING, fmt, ## a)
|
|
||||||
#define SERROR(fmt, a...) SDEBUG_LIMIT(SD_ERROR, fmt, ## a)
|
|
||||||
#define SEMERG(fmt, a...) SDEBUG_LIMIT(SD_EMERG, fmt, ## a)
|
|
||||||
#define SCONSOLE(mask, fmt, a...) SDEBUG(SD_CONSOLE | (mask), fmt, ## a)
|
|
||||||
|
|
||||||
#define SENTRY SDEBUG(SD_TRACE, "Process entered\n")
|
|
||||||
#define SEXIT SDEBUG(SD_TRACE, "Process leaving\n")
|
|
||||||
|
|
||||||
#define SRETURN(rc) \
|
|
||||||
do { \
|
|
||||||
typeof(rc) RETURN__ret = (rc); \
|
|
||||||
SDEBUG(SD_TRACE, "Process leaving (rc=%lu : %ld : %lx)\n", \
|
|
||||||
(long)RETURN__ret, (long)RETURN__ret, (long)RETURN__ret); \
|
|
||||||
return RETURN__ret; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define SGOTO(label, rc) \
|
|
||||||
do { \
|
|
||||||
long GOTO__ret = (long)(rc); \
|
|
||||||
SDEBUG(SD_TRACE,"Process leaving via %s (rc=%lu : %ld : %lx)\n",\
|
|
||||||
#label, (unsigned long)GOTO__ret, (signed long)GOTO__ret, \
|
|
||||||
(signed long)GOTO__ret); \
|
|
||||||
goto label; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
unsigned long cdls_next;
|
|
||||||
int cdls_count;
|
|
||||||
long cdls_delay;
|
|
||||||
} spl_debug_limit_state_t;
|
|
||||||
|
|
||||||
/* Global debug variables */
|
|
||||||
extern unsigned long spl_debug_subsys;
|
|
||||||
extern unsigned long spl_debug_mask;
|
|
||||||
extern unsigned long spl_debug_printk;
|
|
||||||
extern int spl_debug_mb;
|
|
||||||
extern unsigned int spl_debug_binary;
|
|
||||||
extern unsigned int spl_debug_catastrophe;
|
|
||||||
extern unsigned int spl_debug_panic_on_bug;
|
|
||||||
extern char spl_debug_file_path[PATH_MAX];
|
|
||||||
extern unsigned int spl_console_ratelimit;
|
|
||||||
extern long spl_console_max_delay;
|
|
||||||
extern long spl_console_min_delay;
|
|
||||||
extern unsigned int spl_console_backoff;
|
|
||||||
extern unsigned int spl_debug_stack;
|
|
||||||
|
|
||||||
/* Exported debug functions */
|
|
||||||
extern int spl_debug_mask2str(char *str, int size, unsigned long mask, int ss);
|
|
||||||
extern int spl_debug_str2mask(unsigned long *mask, const char *str, int ss);
|
|
||||||
extern unsigned long spl_debug_set_mask(unsigned long mask);
|
|
||||||
extern unsigned long spl_debug_get_mask(void);
|
|
||||||
extern unsigned long spl_debug_set_subsys(unsigned long mask);
|
|
||||||
extern unsigned long spl_debug_get_subsys(void);
|
|
||||||
extern int spl_debug_set_mb(int mb);
|
|
||||||
extern int spl_debug_get_mb(void);
|
|
||||||
extern int spl_debug_dumplog(int flags);
|
|
||||||
extern void spl_debug_dumpstack(struct task_struct *tsk);
|
|
||||||
extern void spl_debug_bug(char *file, const char *fn, const int line, int fl);
|
|
||||||
extern int spl_debug_msg(void *arg, int subsys, int mask, const char *file,
|
|
||||||
const char *fn, const int line, const char *format, ...);
|
|
||||||
extern int spl_debug_clear_buffer(void);
|
|
||||||
extern int spl_debug_mark_buffer(char *text);
|
|
||||||
|
|
||||||
int spl_debug_init(void);
|
|
||||||
void spl_debug_fini(void);
|
|
||||||
|
|
||||||
/* Debug log support disabled */
|
|
||||||
#else /* DEBUG_LOG */
|
|
||||||
|
|
||||||
#define __SDEBUG(x, y, mask, fmt, a...) ((void)0)
|
|
||||||
#define SDEBUG(mask, fmt, a...) ((void)0)
|
|
||||||
#define SDEBUG_LIMIT(x, y, fmt, a...) ((void)0)
|
|
||||||
#define SWARN(fmt, a...) ((void)0)
|
|
||||||
#define SERROR(fmt, a...) ((void)0)
|
|
||||||
#define SEMERG(fmt, a...) ((void)0)
|
|
||||||
#define SCONSOLE(mask, fmt, a...) ((void)0)
|
|
||||||
|
|
||||||
#define SENTRY ((void)0)
|
|
||||||
#define SEXIT ((void)0)
|
|
||||||
#define SRETURN(x) return (x)
|
|
||||||
#define SGOTO(x, y) { ((void)(y)); goto x; }
|
|
||||||
|
|
||||||
static inline unsigned long
|
|
||||||
spl_debug_set_mask(unsigned long mask) {
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long
|
|
||||||
spl_debug_get_mask(void) {
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long
|
|
||||||
spl_debug_set_subsys(unsigned long mask) {
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long
|
|
||||||
spl_debug_get_subsys(void) {
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
spl_debug_set_mb(int mb) {
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
spl_debug_get_mb(void) {
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
spl_debug_dumplog(int flags)
|
|
||||||
{
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
spl_debug_dumpstack(struct task_struct *tsk)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
spl_debug_bug(char *file, const char *fn, const int line, int fl)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
spl_debug_msg(void *arg, int subsys, int mask, const char *file,
|
|
||||||
const char *fn, const int line, const char *format, ...)
|
|
||||||
{
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
spl_debug_clear_buffer(void)
|
|
||||||
{
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
spl_debug_mark_buffer(char *text)
|
|
||||||
{
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
spl_debug_init(void) {
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
spl_debug_fini(void) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* DEBUG_LOG */
|
|
||||||
|
|
||||||
#endif /* SPL_DEBUG_INTERNAL_H */
|
|
|
@ -1,132 +0,0 @@
|
||||||
/*****************************************************************************\
|
|
||||||
* 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_TRACE_H
|
|
||||||
#define _SPL_TRACE_H
|
|
||||||
|
|
||||||
#define TCD_MAX_PAGES (5 << (20 - PAGE_SHIFT))
|
|
||||||
#define TCD_STOCK_PAGES (TCD_MAX_PAGES)
|
|
||||||
#define TRACE_CONSOLE_BUFFER_SIZE 1024
|
|
||||||
|
|
||||||
#define SPL_DEFAULT_MAX_DELAY (600 * HZ)
|
|
||||||
#define SPL_DEFAULT_MIN_DELAY ((HZ + 1) / 2)
|
|
||||||
#define SPL_DEFAULT_BACKOFF 2
|
|
||||||
|
|
||||||
#define DL_NOTHREAD 0x0001 /* Do not create a new thread */
|
|
||||||
#define DL_SINGLE_CPU 0x0002 /* Collect pages from this CPU*/
|
|
||||||
|
|
||||||
typedef struct dumplog_priv {
|
|
||||||
wait_queue_head_t dp_waitq;
|
|
||||||
pid_t dp_pid;
|
|
||||||
int dp_flags;
|
|
||||||
atomic_t dp_done;
|
|
||||||
} dumplog_priv_t;
|
|
||||||
|
|
||||||
/* Three trace data types */
|
|
||||||
typedef enum {
|
|
||||||
TCD_TYPE_PROC,
|
|
||||||
TCD_TYPE_SOFTIRQ,
|
|
||||||
TCD_TYPE_IRQ,
|
|
||||||
TCD_TYPE_MAX
|
|
||||||
} tcd_type_t;
|
|
||||||
|
|
||||||
union trace_data_union {
|
|
||||||
struct trace_cpu_data {
|
|
||||||
/* pages with trace records not yet processed by tracefiled */
|
|
||||||
struct list_head tcd_pages;
|
|
||||||
/* number of pages on ->tcd_pages */
|
|
||||||
unsigned long tcd_cur_pages;
|
|
||||||
/* Max number of pages allowed on ->tcd_pages */
|
|
||||||
unsigned long tcd_max_pages;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* preallocated pages to write trace records into. Pages from
|
|
||||||
* ->tcd_stock_pages are moved to ->tcd_pages by spl_debug_msg().
|
|
||||||
*
|
|
||||||
* This list is necessary, because on some platforms it's
|
|
||||||
* impossible to perform efficient atomic page allocation in a
|
|
||||||
* non-blockable context.
|
|
||||||
*
|
|
||||||
* Such platforms fill ->tcd_stock_pages "on occasion", when
|
|
||||||
* tracing code is entered in blockable context.
|
|
||||||
*
|
|
||||||
* trace_get_tage_try() tries to get a page from
|
|
||||||
* ->tcd_stock_pages first and resorts to atomic page
|
|
||||||
* allocation only if this queue is empty. ->tcd_stock_pages
|
|
||||||
* is replenished when tracing code is entered in blocking
|
|
||||||
* context (darwin-tracefile.c:trace_get_tcd()). We try to
|
|
||||||
* maintain TCD_STOCK_PAGES (40 by default) pages in this
|
|
||||||
* queue. Atomic allocation is only required if more than
|
|
||||||
* TCD_STOCK_PAGES pagesful are consumed by trace records all
|
|
||||||
* emitted in non-blocking contexts. Which is quite unlikely.
|
|
||||||
*/
|
|
||||||
struct list_head tcd_stock_pages;
|
|
||||||
/* number of pages on ->tcd_stock_pages */
|
|
||||||
unsigned long tcd_cur_stock_pages;
|
|
||||||
|
|
||||||
unsigned short tcd_shutting_down;
|
|
||||||
unsigned short tcd_cpu;
|
|
||||||
unsigned short tcd_type;
|
|
||||||
/* The factors to share debug memory. */
|
|
||||||
unsigned short tcd_pages_factor;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This spinlock is needed to workaround the problem of
|
|
||||||
* set_cpus_allowed() being GPL-only. Since we cannot
|
|
||||||
* schedule a thread on a specific CPU when dumping the
|
|
||||||
* pages, we must use the spinlock for mutual exclusion.
|
|
||||||
*/
|
|
||||||
spinlock_t tcd_lock;
|
|
||||||
unsigned long tcd_lock_flags;
|
|
||||||
} tcd;
|
|
||||||
char __pad[L1_CACHE_ALIGN(sizeof(struct trace_cpu_data))];
|
|
||||||
};
|
|
||||||
|
|
||||||
extern union trace_data_union (*trace_data[TCD_TYPE_MAX])[NR_CPUS];
|
|
||||||
|
|
||||||
#define tcd_for_each(tcd, i, j) \
|
|
||||||
for (i = 0; i < TCD_TYPE_MAX && trace_data[i]; i++) \
|
|
||||||
for (j = 0, ((tcd) = &(*trace_data[i])[j].tcd); \
|
|
||||||
j < num_possible_cpus(); j++, (tcd) = &(*trace_data[i])[j].tcd)
|
|
||||||
|
|
||||||
#define tcd_for_each_type_lock(tcd, i, cpu) \
|
|
||||||
for (i = 0; i < TCD_TYPE_MAX && trace_data[i] && \
|
|
||||||
(tcd = &(*trace_data[i])[cpu].tcd) && \
|
|
||||||
trace_lock_tcd(tcd); trace_unlock_tcd(tcd), i++)
|
|
||||||
|
|
||||||
struct trace_page {
|
|
||||||
struct page *page; /* page itself */
|
|
||||||
struct list_head linkage; /* Used by trace_data_union */
|
|
||||||
unsigned int used; /* number of bytes used within this page */
|
|
||||||
unsigned short cpu; /* cpu that owns this page */
|
|
||||||
unsigned short type; /* type(context) of this page */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct page_collection {
|
|
||||||
struct list_head pc_pages;
|
|
||||||
spinlock_t pc_lock;
|
|
||||||
int pc_want_daemon_pages;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* SPL_TRACE_H */
|
|
|
@ -30,7 +30,6 @@
|
||||||
*
|
*
|
||||||
* 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.
|
||||||
* ASSERTF() - Assert X is true, if not panic and print message.
|
|
||||||
* ASSERTV() - Wraps a variable declaration which is only used by ASSERT().
|
* ASSERTV() - Wraps a variable declaration which is only used by ASSERT().
|
||||||
* 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.
|
||||||
|
@ -44,110 +43,69 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SPL_DEBUG_H
|
#ifndef _SPL_DEBUG_H
|
||||||
#define _SPL_DEBUG_H
|
#define _SPL_DEBUG_H
|
||||||
|
|
||||||
#include <spl-debug.h>
|
|
||||||
|
|
||||||
#ifdef NDEBUG /* Debugging Disabled */
|
|
||||||
|
|
||||||
/* Define SPL_DEBUG_STR to make clear which ASSERT definitions are used */
|
|
||||||
#define SPL_DEBUG_STR ""
|
|
||||||
|
|
||||||
#define PANIC(fmt, a...) \
|
|
||||||
spl_PANIC(__FILE__, __FUNCTION__, __LINE__, fmt, ## a)
|
|
||||||
|
|
||||||
#define __ASSERT(x) ((void)0)
|
|
||||||
#define ASSERT(x) ((void)0)
|
|
||||||
#define ASSERTF(x, y, z...) ((void)0)
|
|
||||||
#define ASSERTV(x)
|
|
||||||
#define VERIFY(cond) \
|
|
||||||
(void)(unlikely(!(cond)) && \
|
|
||||||
spl_PANIC(__FILE__, __FUNCTION__, __LINE__, \
|
|
||||||
"%s", "VERIFY(" #cond ") failed\n"))
|
|
||||||
|
|
||||||
#define VERIFY3_IMPL(LEFT, OP, RIGHT, TYPE, FMT, CAST) \
|
|
||||||
(void)((!((TYPE)(LEFT) OP (TYPE)(RIGHT))) && \
|
|
||||||
spl_PANIC(__FILE__, __FUNCTION__, __LINE__, \
|
|
||||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
|
||||||
"failed (" FMT " " #OP " " FMT ")\n", \
|
|
||||||
CAST (LEFT), CAST (RIGHT)))
|
|
||||||
|
|
||||||
#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", \
|
|
||||||
(unsigned long long))
|
|
||||||
#define VERIFY3P(x,y,z) VERIFY3_IMPL(x, y, z, uintptr_t, "%p", (void *))
|
|
||||||
#define VERIFY0(x) VERIFY3_IMPL(0, ==, x, int64_t, "%lld", (long long))
|
|
||||||
|
|
||||||
#define ASSERT3S(x,y,z) ((void)0)
|
|
||||||
#define ASSERT3U(x,y,z) ((void)0)
|
|
||||||
#define ASSERT3P(x,y,z) ((void)0)
|
|
||||||
#define ASSERT0(x) ((void)0)
|
|
||||||
|
|
||||||
#else /* Debugging Enabled */
|
|
||||||
|
|
||||||
/* Define SPL_DEBUG_STR to make clear which ASSERT definitions are used */
|
|
||||||
#define SPL_DEBUG_STR " (DEBUG mode)"
|
|
||||||
|
|
||||||
#define PANIC(fmt, a...) \
|
|
||||||
spl_PANIC(__FILE__, __FUNCTION__, __LINE__, fmt, ## a)
|
|
||||||
|
|
||||||
/* ASSERTION that is safe to use within the debug system */
|
|
||||||
#define __ASSERT(cond) \
|
|
||||||
do { \
|
|
||||||
if (unlikely(!(cond))) { \
|
|
||||||
printk(KERN_EMERG "ASSERTION(" #cond ") failed\n"); \
|
|
||||||
BUG(); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/* ASSERTION that will debug log used outside the debug sysytem */
|
|
||||||
#define ASSERT(cond) \
|
|
||||||
(void)(unlikely(!(cond)) && \
|
|
||||||
spl_PANIC(__FILE__, __FUNCTION__, __LINE__, \
|
|
||||||
"%s", "ASSERTION(" #cond ") failed\n"))
|
|
||||||
|
|
||||||
#define ASSERTF(cond, fmt, a...) \
|
|
||||||
(void)(unlikely(!(cond)) && \
|
|
||||||
spl_PANIC(__FILE__, __FUNCTION__, __LINE__, \
|
|
||||||
"ASSERTION(" #cond ") failed: " fmt, ## a))
|
|
||||||
|
|
||||||
#define VERIFY3_IMPL(LEFT, OP, RIGHT, TYPE, FMT, CAST) \
|
|
||||||
(void)((!((TYPE)(LEFT) OP (TYPE)(RIGHT))) && \
|
|
||||||
spl_PANIC(__FILE__, __FUNCTION__, __LINE__, \
|
|
||||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
|
||||||
"failed (" FMT " " #OP " " FMT ")\n", \
|
|
||||||
CAST (LEFT), CAST (RIGHT)))
|
|
||||||
|
|
||||||
#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", \
|
|
||||||
(unsigned long long))
|
|
||||||
#define VERIFY3P(x,y,z) VERIFY3_IMPL(x, y, z, uintptr_t, "%p", (void *))
|
|
||||||
#define VERIFY0(x) VERIFY3_IMPL(0, ==, x, int64_t, "%lld", (long long))
|
|
||||||
|
|
||||||
#define ASSERT3S(x,y,z) VERIFY3S(x, y, z)
|
|
||||||
#define ASSERT3U(x,y,z) VERIFY3U(x, y, z)
|
|
||||||
#define ASSERT3P(x,y,z) VERIFY3P(x, y, z)
|
|
||||||
#define ASSERT0(x) VERIFY0(x)
|
|
||||||
|
|
||||||
#define ASSERTV(x) x
|
|
||||||
#define VERIFY(x) ASSERT(x)
|
|
||||||
|
|
||||||
#endif /* NDEBUG */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helpers for the Solaris debug macros above
|
* Common DEBUG functionality.
|
||||||
*/
|
*/
|
||||||
extern int spl_PANIC(char *filename, const char *functionname,
|
int spl_panic(const char *file, const char *func, int line,
|
||||||
int lineno, const char *fmt, ...);
|
const char *fmt, ...);
|
||||||
|
void spl_dumpstack(void);
|
||||||
|
|
||||||
|
#define PANIC(fmt, a...) \
|
||||||
|
spl_panic(__FILE__, __FUNCTION__, __LINE__, fmt, ## a)
|
||||||
|
|
||||||
|
#define VERIFY(cond) \
|
||||||
|
(void)(unlikely(!(cond)) && \
|
||||||
|
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||||
|
"%s", "VERIFY(" #cond ") failed\n"))
|
||||||
|
|
||||||
|
#define VERIFY3_IMPL(LEFT, OP, RIGHT, TYPE, FMT, CAST) \
|
||||||
|
(void)((!((TYPE)(LEFT) OP (TYPE)(RIGHT))) && \
|
||||||
|
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||||
|
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||||
|
"failed (" FMT " " #OP " " FMT ")\n", \
|
||||||
|
CAST (LEFT), CAST (RIGHT)))
|
||||||
|
|
||||||
|
#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", \
|
||||||
|
(unsigned long long))
|
||||||
|
#define VERIFY3P(x,y,z) VERIFY3_IMPL(x, y, z, uintptr_t, "%p", (void *))
|
||||||
|
#define VERIFY0(x) VERIFY3_IMPL(0, ==, x, int64_t, "%lld", (long long))
|
||||||
|
|
||||||
/*
|
|
||||||
* Compile-time assertion. The condition 'x' must be constant.
|
|
||||||
*/
|
|
||||||
#define CTASSERT_GLOBAL(x) _CTASSERT(x, __LINE__)
|
#define CTASSERT_GLOBAL(x) _CTASSERT(x, __LINE__)
|
||||||
#define CTASSERT(x) { _CTASSERT(x, __LINE__); }
|
#define CTASSERT(x) { _CTASSERT(x, __LINE__); }
|
||||||
#define _CTASSERT(x, y) __CTASSERT(x, y)
|
#define _CTASSERT(x, y) __CTASSERT(x, y)
|
||||||
#define __CTASSERT(x, y) \
|
#define __CTASSERT(x, y) \
|
||||||
typedef char __attribute__ ((unused)) \
|
typedef char __attribute__ ((unused)) \
|
||||||
__compile_time_assertion__ ## y[(x) ? 1 : -1]
|
__compile_time_assertion__ ## y[(x) ? 1 : -1]
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Debugging disabled (--disable-debug)
|
||||||
|
*/
|
||||||
|
#ifdef NDEBUG
|
||||||
|
|
||||||
|
#define SPL_DEBUG_STR ""
|
||||||
|
#define ASSERT(x) ((void)0)
|
||||||
|
#define ASSERTV(x)
|
||||||
|
#define ASSERT3S(x,y,z) ((void)0)
|
||||||
|
#define ASSERT3U(x,y,z) ((void)0)
|
||||||
|
#define ASSERT3P(x,y,z) ((void)0)
|
||||||
|
#define ASSERT0(x) ((void)0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Debugging enabled (--enable-debug)
|
||||||
|
*/
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define SPL_DEBUG_STR " (DEBUG mode)"
|
||||||
|
#define ASSERT(cond) VERIFY(cond)
|
||||||
|
#define ASSERTV(x) x
|
||||||
|
#define ASSERT3S(x,y,z) VERIFY3S(x, y, z)
|
||||||
|
#define ASSERT3U(x,y,z) VERIFY3U(x, y, z)
|
||||||
|
#define ASSERT3P(x,y,z) VERIFY3P(x, y, z)
|
||||||
|
#define ASSERT0(x) VERIFY0(x)
|
||||||
|
|
||||||
|
#endif /* NDEBUG */
|
||||||
|
|
||||||
#endif /* SPL_DEBUG_H */
|
#endif /* SPL_DEBUG_H */
|
||||||
|
|
|
@ -74,27 +74,27 @@
|
||||||
* ship a kernel with CONFIG_RT_MUTEX_TESTER disabled.
|
* ship a kernel with CONFIG_RT_MUTEX_TESTER disabled.
|
||||||
*/
|
*/
|
||||||
#if !defined(CONFIG_RT_MUTEX_TESTER) && defined(PF_MUTEX_TESTER)
|
#if !defined(CONFIG_RT_MUTEX_TESTER) && defined(PF_MUTEX_TESTER)
|
||||||
# define PF_NOFS PF_MUTEX_TESTER
|
#define PF_NOFS PF_MUTEX_TESTER
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
sanitize_flags(struct task_struct *p, gfp_t *flags)
|
sanitize_flags(struct task_struct *p, gfp_t *flags)
|
||||||
{
|
{
|
||||||
if (unlikely((p->flags & PF_NOFS) && (*flags & (__GFP_IO|__GFP_FS)))) {
|
if (unlikely((p->flags & PF_NOFS) && (*flags & (__GFP_IO|__GFP_FS)))) {
|
||||||
# ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
SDEBUG_LIMIT(SD_CONSOLE | SD_WARNING, "Fixing allocation for "
|
printk(KERN_WARNING "Fixing allocation for task %s (%d) "
|
||||||
"task %s (%d) which used GFP flags 0x%x with PF_NOFS set\n",
|
"which used GFP flags 0x%x with PF_NOFS set\n",
|
||||||
p->comm, p->pid, flags);
|
p->comm, p->pid, *flags);
|
||||||
spl_debug_dumpstack(p);
|
spl_dumpstack();
|
||||||
*flags &= ~(__GFP_IO|__GFP_FS);
|
*flags &= ~(__GFP_IO|__GFP_FS);
|
||||||
# else
|
#else
|
||||||
PANIC("FATAL allocation for task %s (%d) which used GFP "
|
PANIC("FATAL allocation for task %s (%d) which used GFP "
|
||||||
"flags 0x%x with PF_NOFS set\n", p->comm, p->pid, flags);
|
"flags 0x%x with PF_NOFS set\n", p->comm, p->pid, *flags);
|
||||||
# endif /* NDEBUG */
|
#endif /* NDEBUG */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
# define PF_NOFS 0x00000000
|
#define PF_NOFS 0x00000000
|
||||||
# define sanitize_flags(p, fl) ((void)0)
|
#define sanitize_flags(p, fl) ((void)0)
|
||||||
#endif /* !defined(CONFIG_RT_MUTEX_TESTER) && defined(PF_MUTEX_TESTER) */
|
#endif /* !defined(CONFIG_RT_MUTEX_TESTER) && defined(PF_MUTEX_TESTER) */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -6,7 +6,6 @@ EXTRA_CFLAGS = $(SPL_MODULE_CFLAGS) @KERNELCPPFLAGS@
|
||||||
# Solaris porting layer module
|
# Solaris porting layer module
|
||||||
obj-$(CONFIG_SPL) := $(MODULE).o
|
obj-$(CONFIG_SPL) := $(MODULE).o
|
||||||
|
|
||||||
$(MODULE)-objs += @top_srcdir@/module/spl/spl-debug.o
|
|
||||||
$(MODULE)-objs += @top_srcdir@/module/spl/spl-proc.o
|
$(MODULE)-objs += @top_srcdir@/module/spl/spl-proc.o
|
||||||
$(MODULE)-objs += @top_srcdir@/module/spl/spl-kmem.o
|
$(MODULE)-objs += @top_srcdir@/module/spl/spl-kmem.o
|
||||||
$(MODULE)-objs += @top_srcdir@/module/spl/spl-thread.o
|
$(MODULE)-objs += @top_srcdir@/module/spl/spl-thread.o
|
||||||
|
|
|
@ -25,18 +25,10 @@
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
#include <sys/condvar.h>
|
#include <sys/condvar.h>
|
||||||
#include <spl-debug.h>
|
|
||||||
|
|
||||||
#ifdef SS_DEBUG_SUBSYS
|
|
||||||
#undef SS_DEBUG_SUBSYS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SS_DEBUG_SUBSYS SS_CONDVAR
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
ASSERT(cvp);
|
ASSERT(cvp);
|
||||||
ASSERT(name == NULL);
|
ASSERT(name == NULL);
|
||||||
ASSERT(type == CV_DEFAULT);
|
ASSERT(type == CV_DEFAULT);
|
||||||
|
@ -48,8 +40,6 @@ __cv_init(kcondvar_t *cvp, char *name, kcv_type_t type, void *arg)
|
||||||
atomic_set(&cvp->cv_waiters, 0);
|
atomic_set(&cvp->cv_waiters, 0);
|
||||||
atomic_set(&cvp->cv_refs, 1);
|
atomic_set(&cvp->cv_refs, 1);
|
||||||
cvp->cv_mutex = NULL;
|
cvp->cv_mutex = NULL;
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(__cv_init);
|
EXPORT_SYMBOL(__cv_init);
|
||||||
|
|
||||||
|
@ -68,7 +58,6 @@ cv_destroy_wakeup(kcondvar_t *cvp)
|
||||||
void
|
void
|
||||||
__cv_destroy(kcondvar_t *cvp)
|
__cv_destroy(kcondvar_t *cvp)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
ASSERT(cvp);
|
ASSERT(cvp);
|
||||||
ASSERT(cvp->cv_magic == CV_MAGIC);
|
ASSERT(cvp->cv_magic == CV_MAGIC);
|
||||||
|
|
||||||
|
@ -83,8 +72,6 @@ __cv_destroy(kcondvar_t *cvp)
|
||||||
ASSERT3S(atomic_read(&cvp->cv_refs), ==, 0);
|
ASSERT3S(atomic_read(&cvp->cv_refs), ==, 0);
|
||||||
ASSERT3S(atomic_read(&cvp->cv_waiters), ==, 0);
|
ASSERT3S(atomic_read(&cvp->cv_waiters), ==, 0);
|
||||||
ASSERT3S(waitqueue_active(&cvp->cv_event), ==, 0);
|
ASSERT3S(waitqueue_active(&cvp->cv_event), ==, 0);
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(__cv_destroy);
|
EXPORT_SYMBOL(__cv_destroy);
|
||||||
|
|
||||||
|
@ -92,7 +79,6 @@ static void
|
||||||
cv_wait_common(kcondvar_t *cvp, kmutex_t *mp, int state, int io)
|
cv_wait_common(kcondvar_t *cvp, kmutex_t *mp, int state, int io)
|
||||||
{
|
{
|
||||||
DEFINE_WAIT(wait);
|
DEFINE_WAIT(wait);
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(cvp);
|
ASSERT(cvp);
|
||||||
ASSERT(mp);
|
ASSERT(mp);
|
||||||
|
@ -127,8 +113,6 @@ cv_wait_common(kcondvar_t *cvp, kmutex_t *mp, int state, int io)
|
||||||
|
|
||||||
finish_wait(&cvp->cv_event, &wait);
|
finish_wait(&cvp->cv_event, &wait);
|
||||||
atomic_dec(&cvp->cv_refs);
|
atomic_dec(&cvp->cv_refs);
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -161,7 +145,6 @@ __cv_timedwait_common(kcondvar_t *cvp, kmutex_t *mp,
|
||||||
{
|
{
|
||||||
DEFINE_WAIT(wait);
|
DEFINE_WAIT(wait);
|
||||||
clock_t time_left;
|
clock_t time_left;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(cvp);
|
ASSERT(cvp);
|
||||||
ASSERT(mp);
|
ASSERT(mp);
|
||||||
|
@ -179,7 +162,7 @@ __cv_timedwait_common(kcondvar_t *cvp, kmutex_t *mp,
|
||||||
time_left = expire_time - jiffies;
|
time_left = expire_time - jiffies;
|
||||||
if (time_left <= 0) {
|
if (time_left <= 0) {
|
||||||
atomic_dec(&cvp->cv_refs);
|
atomic_dec(&cvp->cv_refs);
|
||||||
SRETURN(-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
prepare_to_wait_exclusive(&cvp->cv_event, &wait, state);
|
prepare_to_wait_exclusive(&cvp->cv_event, &wait, state);
|
||||||
|
@ -201,7 +184,7 @@ __cv_timedwait_common(kcondvar_t *cvp, kmutex_t *mp,
|
||||||
finish_wait(&cvp->cv_event, &wait);
|
finish_wait(&cvp->cv_event, &wait);
|
||||||
atomic_dec(&cvp->cv_refs);
|
atomic_dec(&cvp->cv_refs);
|
||||||
|
|
||||||
SRETURN(time_left > 0 ? time_left : -1);
|
return (time_left > 0 ? time_left : -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
clock_t
|
clock_t
|
||||||
|
@ -229,7 +212,6 @@ __cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp,
|
||||||
DEFINE_WAIT(wait);
|
DEFINE_WAIT(wait);
|
||||||
hrtime_t time_left, now;
|
hrtime_t time_left, now;
|
||||||
unsigned long time_left_us;
|
unsigned long time_left_us;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(cvp);
|
ASSERT(cvp);
|
||||||
ASSERT(mp);
|
ASSERT(mp);
|
||||||
|
@ -247,7 +229,7 @@ __cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp,
|
||||||
time_left = expire_time - now;
|
time_left = expire_time - now;
|
||||||
if (time_left <= 0) {
|
if (time_left <= 0) {
|
||||||
atomic_dec(&cvp->cv_refs);
|
atomic_dec(&cvp->cv_refs);
|
||||||
SRETURN(-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
time_left_us = time_left / NSEC_PER_USEC;
|
time_left_us = time_left / NSEC_PER_USEC;
|
||||||
|
|
||||||
|
@ -273,7 +255,7 @@ __cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp,
|
||||||
atomic_dec(&cvp->cv_refs);
|
atomic_dec(&cvp->cv_refs);
|
||||||
|
|
||||||
time_left = expire_time - gethrtime();
|
time_left = expire_time - gethrtime();
|
||||||
SRETURN(time_left > 0 ? time_left : -1);
|
return (time_left > 0 ? time_left : -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -302,7 +284,6 @@ EXPORT_SYMBOL(cv_timedwait_hires);
|
||||||
void
|
void
|
||||||
__cv_signal(kcondvar_t *cvp)
|
__cv_signal(kcondvar_t *cvp)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
ASSERT(cvp);
|
ASSERT(cvp);
|
||||||
ASSERT(cvp->cv_magic == CV_MAGIC);
|
ASSERT(cvp->cv_magic == CV_MAGIC);
|
||||||
atomic_inc(&cvp->cv_refs);
|
atomic_inc(&cvp->cv_refs);
|
||||||
|
@ -315,14 +296,12 @@ __cv_signal(kcondvar_t *cvp)
|
||||||
wake_up(&cvp->cv_event);
|
wake_up(&cvp->cv_event);
|
||||||
|
|
||||||
atomic_dec(&cvp->cv_refs);
|
atomic_dec(&cvp->cv_refs);
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(__cv_signal);
|
EXPORT_SYMBOL(__cv_signal);
|
||||||
|
|
||||||
void
|
void
|
||||||
__cv_broadcast(kcondvar_t *cvp)
|
__cv_broadcast(kcondvar_t *cvp)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
ASSERT(cvp);
|
ASSERT(cvp);
|
||||||
ASSERT(cvp->cv_magic == CV_MAGIC);
|
ASSERT(cvp->cv_magic == CV_MAGIC);
|
||||||
atomic_inc(&cvp->cv_refs);
|
atomic_inc(&cvp->cv_refs);
|
||||||
|
@ -333,6 +312,5 @@ __cv_broadcast(kcondvar_t *cvp)
|
||||||
wake_up_all(&cvp->cv_event);
|
wake_up_all(&cvp->cv_event);
|
||||||
|
|
||||||
atomic_dec(&cvp->cv_refs);
|
atomic_dec(&cvp->cv_refs);
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(__cv_broadcast);
|
EXPORT_SYMBOL(__cv_broadcast);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,66 +26,81 @@
|
||||||
|
|
||||||
#include <sys/sysmacros.h>
|
#include <sys/sysmacros.h>
|
||||||
#include <sys/cmn_err.h>
|
#include <sys/cmn_err.h>
|
||||||
#include <spl-debug.h>
|
#include <linux/ratelimit.h>
|
||||||
|
|
||||||
#ifdef SS_DEBUG_SUBSYS
|
/*
|
||||||
#undef SS_DEBUG_SUBSYS
|
* Limit the number of stack traces dumped to not more than 5 every
|
||||||
#endif
|
* 60 seconds to prevent denial-of-service attacks from debug code.
|
||||||
|
*/
|
||||||
|
DEFINE_RATELIMIT_STATE(dumpstack_ratelimit_state, 60 * HZ, 5);
|
||||||
|
|
||||||
#define SS_DEBUG_SUBSYS SS_GENERIC
|
void
|
||||||
|
spl_dumpstack(void)
|
||||||
#ifdef DEBUG_LOG
|
{
|
||||||
static char ce_prefix[CE_IGNORE][10] = { "", "NOTICE: ", "WARNING: ", "" };
|
if (__ratelimit(&dumpstack_ratelimit_state)) {
|
||||||
static char ce_suffix[CE_IGNORE][2] = { "", "\n", "\n", "" };
|
printk("Showing stack for process %d\n", current->pid);
|
||||||
#endif
|
dump_stack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(spl_dumpstack);
|
||||||
|
|
||||||
int
|
int
|
||||||
spl_PANIC(char *filename, const char *functionname,
|
spl_panic(const char *file, const char *func, int line, const char *fmt, ...) {
|
||||||
int lineno, const char *fmt, ...) {
|
const char *newfile;
|
||||||
char msg[MAXMSGLEN];
|
char msg[MAXMSGLEN];
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
newfile = strrchr(file, '/');
|
||||||
|
if (newfile != NULL)
|
||||||
|
newfile = newfile + 1;
|
||||||
|
else
|
||||||
|
newfile = file;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
if (vsnprintf(msg, sizeof (msg), fmt, ap) == sizeof (msg))
|
(void) vsnprintf(msg, sizeof (msg), fmt, ap);
|
||||||
msg[sizeof (msg) - 1] = '\0';
|
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
#ifdef NDEBUG
|
|
||||||
printk(KERN_EMERG "%s", msg);
|
printk(KERN_EMERG "%s", msg);
|
||||||
#else
|
printk(KERN_EMERG "PANIC at %s:%d:%s()\n", newfile, line, func);
|
||||||
spl_debug_msg(NULL, 0, 0,
|
spl_dumpstack();
|
||||||
filename, functionname, lineno, "%s", msg);
|
|
||||||
#endif
|
/* Halt the thread to facilitate further debugging */
|
||||||
spl_debug_bug(filename, functionname, lineno, 0);
|
set_task_state(current, TASK_UNINTERRUPTIBLE);
|
||||||
return 1;
|
while (1)
|
||||||
|
schedule();
|
||||||
|
|
||||||
|
/* Unreachable */
|
||||||
|
return (1);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(spl_PANIC);
|
EXPORT_SYMBOL(spl_panic);
|
||||||
|
|
||||||
void
|
|
||||||
vpanic(const char *fmt, va_list ap)
|
|
||||||
{
|
|
||||||
char msg[MAXMSGLEN];
|
|
||||||
|
|
||||||
vsnprintf(msg, MAXMSGLEN - 1, fmt, ap);
|
|
||||||
PANIC("%s", msg);
|
|
||||||
} /* vpanic() */
|
|
||||||
EXPORT_SYMBOL(vpanic);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
vcmn_err(int ce, const char *fmt, va_list ap)
|
vcmn_err(int ce, const char *fmt, va_list ap)
|
||||||
{
|
{
|
||||||
char msg[MAXMSGLEN];
|
char msg[MAXMSGLEN];
|
||||||
|
|
||||||
if (ce == CE_PANIC)
|
vsnprintf(msg, MAXMSGLEN - 1, fmt, ap);
|
||||||
vpanic(fmt, ap);
|
|
||||||
|
|
||||||
if (ce != CE_NOTE) {
|
switch (ce) {
|
||||||
vsnprintf(msg, MAXMSGLEN - 1, fmt, ap);
|
case CE_IGNORE:
|
||||||
|
break;
|
||||||
|
case CE_CONT:
|
||||||
|
printk("%s", msg);
|
||||||
|
break;
|
||||||
|
case CE_NOTE:
|
||||||
|
printk(KERN_NOTICE "NOTICE: %s\n", msg);
|
||||||
|
break;
|
||||||
|
case CE_WARN:
|
||||||
|
printk(KERN_WARNING "WARNING: %s\n", msg);
|
||||||
|
break;
|
||||||
|
case CE_PANIC:
|
||||||
|
printk(KERN_EMERG "PANIC: %s\n", msg);
|
||||||
|
spl_dumpstack();
|
||||||
|
|
||||||
if (fmt[0] == '!')
|
/* Halt the thread to facilitate further debugging */
|
||||||
SDEBUG(SD_INFO, "%s%s%s",
|
set_task_state(current, TASK_UNINTERRUPTIBLE);
|
||||||
ce_prefix[ce], msg, ce_suffix[ce]);
|
while (1)
|
||||||
else
|
schedule();
|
||||||
SERROR("%s%s%s", ce_prefix[ce], msg, ce_suffix[ce]);
|
|
||||||
}
|
}
|
||||||
} /* vcmn_err() */
|
} /* vcmn_err() */
|
||||||
EXPORT_SYMBOL(vcmn_err);
|
EXPORT_SYMBOL(vcmn_err);
|
||||||
|
@ -100,4 +115,3 @@ cmn_err(int ce, const char *fmt, ...)
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
} /* cmn_err() */
|
} /* cmn_err() */
|
||||||
EXPORT_SYMBOL(cmn_err);
|
EXPORT_SYMBOL(cmn_err);
|
||||||
|
|
||||||
|
|
|
@ -40,13 +40,6 @@
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#include <linux/kmod.h>
|
#include <linux/kmod.h>
|
||||||
#include <linux/proc_compat.h>
|
#include <linux/proc_compat.h>
|
||||||
#include <spl-debug.h>
|
|
||||||
|
|
||||||
#ifdef SS_DEBUG_SUBSYS
|
|
||||||
#undef SS_DEBUG_SUBSYS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SS_DEBUG_SUBSYS SS_GENERIC
|
|
||||||
|
|
||||||
char spl_version[32] = "SPL v" SPL_META_VERSION "-" SPL_META_RELEASE;
|
char spl_version[32] = "SPL v" SPL_META_VERSION "-" SPL_META_RELEASE;
|
||||||
EXPORT_SYMBOL(spl_version);
|
EXPORT_SYMBOL(spl_version);
|
||||||
|
@ -490,39 +483,36 @@ __init spl_init(void)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if ((rc = spl_debug_init()))
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
if ((rc = spl_kmem_init()))
|
if ((rc = spl_kmem_init()))
|
||||||
SGOTO(out1, rc);
|
goto out1;
|
||||||
|
|
||||||
if ((rc = spl_mutex_init()))
|
if ((rc = spl_mutex_init()))
|
||||||
SGOTO(out2, rc);
|
goto out2;
|
||||||
|
|
||||||
if ((rc = spl_rw_init()))
|
if ((rc = spl_rw_init()))
|
||||||
SGOTO(out3, rc);
|
goto out3;
|
||||||
|
|
||||||
if ((rc = spl_taskq_init()))
|
if ((rc = spl_taskq_init()))
|
||||||
SGOTO(out4, rc);
|
goto out4;
|
||||||
|
|
||||||
if ((rc = spl_vn_init()))
|
if ((rc = spl_vn_init()))
|
||||||
SGOTO(out5, rc);
|
goto out5;
|
||||||
|
|
||||||
if ((rc = spl_proc_init()))
|
if ((rc = spl_proc_init()))
|
||||||
SGOTO(out6, rc);
|
goto out6;
|
||||||
|
|
||||||
if ((rc = spl_kstat_init()))
|
if ((rc = spl_kstat_init()))
|
||||||
SGOTO(out7, rc);
|
goto out7;
|
||||||
|
|
||||||
if ((rc = spl_tsd_init()))
|
if ((rc = spl_tsd_init()))
|
||||||
SGOTO(out8, rc);
|
goto out8;
|
||||||
|
|
||||||
if ((rc = spl_zlib_init()))
|
if ((rc = spl_zlib_init()))
|
||||||
SGOTO(out9, rc);
|
goto out9;
|
||||||
|
|
||||||
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);
|
||||||
SRETURN(rc);
|
return (rc);
|
||||||
|
|
||||||
out9:
|
out9:
|
||||||
spl_tsd_fini();
|
spl_tsd_fini();
|
||||||
|
@ -541,19 +531,16 @@ out3:
|
||||||
out2:
|
out2:
|
||||||
spl_kmem_fini();
|
spl_kmem_fini();
|
||||||
out1:
|
out1:
|
||||||
spl_debug_fini();
|
|
||||||
|
|
||||||
printk(KERN_NOTICE "SPL: Failed to Load Solaris Porting Layer "
|
printk(KERN_NOTICE "SPL: Failed to Load Solaris Porting Layer "
|
||||||
"v%s-%s%s, rc = %d\n", SPL_META_VERSION, SPL_META_RELEASE,
|
"v%s-%s%s, rc = %d\n", SPL_META_VERSION, SPL_META_RELEASE,
|
||||||
SPL_DEBUG_STR, rc);
|
SPL_DEBUG_STR, rc);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
spl_fini(void)
|
spl_fini(void)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
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();
|
||||||
|
@ -565,7 +552,6 @@ spl_fini(void)
|
||||||
spl_rw_fini();
|
spl_rw_fini();
|
||||||
spl_mutex_fini();
|
spl_mutex_fini();
|
||||||
spl_kmem_fini();
|
spl_kmem_fini();
|
||||||
spl_debug_fini();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called when a dependent module is loaded */
|
/* Called when a dependent module is loaded */
|
||||||
|
|
|
@ -25,13 +25,6 @@
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
#include <sys/kmem.h>
|
#include <sys/kmem.h>
|
||||||
#include <spl-debug.h>
|
|
||||||
|
|
||||||
#ifdef SS_DEBUG_SUBSYS
|
|
||||||
#undef SS_DEBUG_SUBSYS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SS_DEBUG_SUBSYS SS_KMEM
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Within the scope of spl-kmem.c file the kmem_cache_* definitions
|
* Within the scope of spl-kmem.c file the kmem_cache_* definitions
|
||||||
|
@ -265,7 +258,6 @@ kmem_del_init(spinlock_t *lock, struct hlist_head *table, int bits, const void *
|
||||||
struct hlist_node *node;
|
struct hlist_node *node;
|
||||||
struct kmem_debug *p;
|
struct kmem_debug *p;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
spin_lock_irqsave(lock, flags);
|
spin_lock_irqsave(lock, flags);
|
||||||
|
|
||||||
|
@ -282,7 +274,7 @@ kmem_del_init(spinlock_t *lock, struct hlist_head *table, int bits, const void *
|
||||||
|
|
||||||
spin_unlock_irqrestore(lock, flags);
|
spin_unlock_irqrestore(lock, flags);
|
||||||
|
|
||||||
SRETURN(NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
@ -292,28 +284,26 @@ kmem_alloc_track(size_t size, int flags, const char *func, int line,
|
||||||
void *ptr = NULL;
|
void *ptr = NULL;
|
||||||
kmem_debug_t *dptr;
|
kmem_debug_t *dptr;
|
||||||
unsigned long irq_flags;
|
unsigned long irq_flags;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
/* Function may be called with KM_NOSLEEP so failure is possible */
|
/* Function may be called with KM_NOSLEEP so failure is possible */
|
||||||
dptr = (kmem_debug_t *) kmalloc_nofail(sizeof(kmem_debug_t),
|
dptr = (kmem_debug_t *) kmalloc_nofail(sizeof(kmem_debug_t),
|
||||||
flags & ~__GFP_ZERO);
|
flags & ~__GFP_ZERO);
|
||||||
|
|
||||||
if (unlikely(dptr == NULL)) {
|
if (unlikely(dptr == NULL)) {
|
||||||
SDEBUG_LIMIT(SD_CONSOLE | SD_WARNING, "debug "
|
printk(KERN_WARNING "debug kmem_alloc(%ld, 0x%x) at %s:%d "
|
||||||
"kmem_alloc(%ld, 0x%x) at %s:%d failed (%lld/%llu)\n",
|
"failed (%lld/%llu)\n", sizeof(kmem_debug_t), flags,
|
||||||
sizeof(kmem_debug_t), flags, func, line,
|
func, line, kmem_alloc_used_read(), kmem_alloc_max);
|
||||||
kmem_alloc_used_read(), kmem_alloc_max);
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Marked unlikely because we should never be doing this,
|
* Marked unlikely because we should never be doing this,
|
||||||
* we tolerate to up 2 pages but a single page is best.
|
* we tolerate to up 2 pages but a single page is best.
|
||||||
*/
|
*/
|
||||||
if (unlikely((size > PAGE_SIZE*2) && !(flags & KM_NODEBUG))) {
|
if (unlikely((size > PAGE_SIZE*2) && !(flags & KM_NODEBUG))) {
|
||||||
SDEBUG_LIMIT(SD_CONSOLE | SD_WARNING, "large "
|
printk(KERN_WARNING "large kmem_alloc(%llu, 0x%x) "
|
||||||
"kmem_alloc(%llu, 0x%x) at %s:%d (%lld/%llu)\n",
|
"at %s:%d failed (%lld/%llu)\n",
|
||||||
(unsigned long long) size, flags, func, line,
|
(unsigned long long)size, flags, func, line,
|
||||||
kmem_alloc_used_read(), kmem_alloc_max);
|
kmem_alloc_used_read(), kmem_alloc_max);
|
||||||
spl_debug_dumpstack(NULL);
|
spl_dumpstack();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -325,9 +315,9 @@ kmem_alloc_track(size_t size, int flags, const char *func, int line,
|
||||||
dptr->kd_func = __strdup(func, flags & ~__GFP_ZERO);
|
dptr->kd_func = __strdup(func, flags & ~__GFP_ZERO);
|
||||||
if (unlikely(dptr->kd_func == NULL)) {
|
if (unlikely(dptr->kd_func == NULL)) {
|
||||||
kfree(dptr);
|
kfree(dptr);
|
||||||
SDEBUG_LIMIT(SD_CONSOLE | SD_WARNING,
|
printk(KERN_WARNING "debug __strdup() at %s:%d "
|
||||||
"debug __strdup() at %s:%d failed (%lld/%llu)\n",
|
"failed (%lld/%llu)\n", func, line,
|
||||||
func, line, kmem_alloc_used_read(), kmem_alloc_max);
|
kmem_alloc_used_read(), kmem_alloc_max);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,8 +334,8 @@ kmem_alloc_track(size_t size, int flags, const char *func, int line,
|
||||||
if (unlikely(ptr == NULL)) {
|
if (unlikely(ptr == NULL)) {
|
||||||
kfree(dptr->kd_func);
|
kfree(dptr->kd_func);
|
||||||
kfree(dptr);
|
kfree(dptr);
|
||||||
SDEBUG_LIMIT(SD_CONSOLE | SD_WARNING, "kmem_alloc"
|
printk(KERN_WARNING "kmem_alloc(%llu, 0x%x) "
|
||||||
"(%llu, 0x%x) at %s:%d failed (%lld/%llu)\n",
|
"at %s:%d failed (%lld/%llu)\n",
|
||||||
(unsigned long long) size, flags, func, line,
|
(unsigned long long) size, flags, func, line,
|
||||||
kmem_alloc_used_read(), kmem_alloc_max);
|
kmem_alloc_used_read(), kmem_alloc_max);
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -367,14 +357,9 @@ kmem_alloc_track(size_t size, int flags, const char *func, int line,
|
||||||
&kmem_table[hash_ptr(ptr, KMEM_HASH_BITS)]);
|
&kmem_table[hash_ptr(ptr, KMEM_HASH_BITS)]);
|
||||||
list_add_tail(&dptr->kd_list, &kmem_list);
|
list_add_tail(&dptr->kd_list, &kmem_list);
|
||||||
spin_unlock_irqrestore(&kmem_lock, irq_flags);
|
spin_unlock_irqrestore(&kmem_lock, irq_flags);
|
||||||
|
|
||||||
SDEBUG_LIMIT(SD_INFO,
|
|
||||||
"kmem_alloc(%llu, 0x%x) at %s:%d = %p (%lld/%llu)\n",
|
|
||||||
(unsigned long long) size, flags, func, line, ptr,
|
|
||||||
kmem_alloc_used_read(), kmem_alloc_max);
|
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
SRETURN(ptr);
|
return (ptr);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(kmem_alloc_track);
|
EXPORT_SYMBOL(kmem_alloc_track);
|
||||||
|
|
||||||
|
@ -382,14 +367,12 @@ void
|
||||||
kmem_free_track(const void *ptr, size_t size)
|
kmem_free_track(const void *ptr, size_t size)
|
||||||
{
|
{
|
||||||
kmem_debug_t *dptr;
|
kmem_debug_t *dptr;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERTF(ptr || size > 0, "ptr: %p, size: %llu", ptr,
|
ASSERTF(ptr || size > 0, "ptr: %p, size: %llu", ptr,
|
||||||
(unsigned long long) size);
|
(unsigned long long) size);
|
||||||
|
|
||||||
dptr = kmem_del_init(&kmem_lock, kmem_table, KMEM_HASH_BITS, ptr);
|
|
||||||
|
|
||||||
/* Must exist in hash due to kmem_alloc() */
|
/* Must exist in hash due to kmem_alloc() */
|
||||||
|
dptr = kmem_del_init(&kmem_lock, kmem_table, KMEM_HASH_BITS, ptr);
|
||||||
ASSERT(dptr);
|
ASSERT(dptr);
|
||||||
|
|
||||||
/* Size must match */
|
/* Size must match */
|
||||||
|
@ -398,10 +381,6 @@ kmem_free_track(const void *ptr, size_t size)
|
||||||
(unsigned long long) size, dptr->kd_func, dptr->kd_line);
|
(unsigned long long) size, dptr->kd_func, dptr->kd_line);
|
||||||
|
|
||||||
kmem_alloc_used_sub(size);
|
kmem_alloc_used_sub(size);
|
||||||
SDEBUG_LIMIT(SD_INFO, "kmem_free(%p, %llu) (%lld/%llu)\n", ptr,
|
|
||||||
(unsigned long long) size, kmem_alloc_used_read(),
|
|
||||||
kmem_alloc_max);
|
|
||||||
|
|
||||||
kfree(dptr->kd_func);
|
kfree(dptr->kd_func);
|
||||||
|
|
||||||
memset((void *)dptr, 0x5a, sizeof(kmem_debug_t));
|
memset((void *)dptr, 0x5a, sizeof(kmem_debug_t));
|
||||||
|
@ -409,8 +388,6 @@ kmem_free_track(const void *ptr, size_t size)
|
||||||
|
|
||||||
memset((void *)ptr, 0x5a, size);
|
memset((void *)ptr, 0x5a, size);
|
||||||
kfree(ptr);
|
kfree(ptr);
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(kmem_free_track);
|
EXPORT_SYMBOL(kmem_free_track);
|
||||||
|
|
||||||
|
@ -420,7 +397,6 @@ vmem_alloc_track(size_t size, int flags, const char *func, int line)
|
||||||
void *ptr = NULL;
|
void *ptr = NULL;
|
||||||
kmem_debug_t *dptr;
|
kmem_debug_t *dptr;
|
||||||
unsigned long irq_flags;
|
unsigned long irq_flags;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(flags & KM_SLEEP);
|
ASSERT(flags & KM_SLEEP);
|
||||||
|
|
||||||
|
@ -428,8 +404,8 @@ vmem_alloc_track(size_t size, int flags, const char *func, int line)
|
||||||
dptr = (kmem_debug_t *) kmalloc_nofail(sizeof(kmem_debug_t),
|
dptr = (kmem_debug_t *) kmalloc_nofail(sizeof(kmem_debug_t),
|
||||||
flags & ~__GFP_ZERO);
|
flags & ~__GFP_ZERO);
|
||||||
if (unlikely(dptr == NULL)) {
|
if (unlikely(dptr == NULL)) {
|
||||||
SDEBUG_LIMIT(SD_CONSOLE | SD_WARNING, "debug "
|
printk(KERN_WARNING "debug vmem_alloc(%ld, 0x%x) "
|
||||||
"vmem_alloc(%ld, 0x%x) at %s:%d failed (%lld/%llu)\n",
|
"at %s:%d failed (%lld/%llu)\n",
|
||||||
sizeof(kmem_debug_t), flags, func, line,
|
sizeof(kmem_debug_t), flags, func, line,
|
||||||
vmem_alloc_used_read(), vmem_alloc_max);
|
vmem_alloc_used_read(), vmem_alloc_max);
|
||||||
} else {
|
} else {
|
||||||
|
@ -443,9 +419,9 @@ vmem_alloc_track(size_t size, int flags, const char *func, int line)
|
||||||
dptr->kd_func = __strdup(func, flags & ~__GFP_ZERO);
|
dptr->kd_func = __strdup(func, flags & ~__GFP_ZERO);
|
||||||
if (unlikely(dptr->kd_func == NULL)) {
|
if (unlikely(dptr->kd_func == NULL)) {
|
||||||
kfree(dptr);
|
kfree(dptr);
|
||||||
SDEBUG_LIMIT(SD_CONSOLE | SD_WARNING,
|
printk(KERN_WARNING "debug __strdup() at %s:%d "
|
||||||
"debug __strdup() at %s:%d failed (%lld/%llu)\n",
|
"failed (%lld/%llu)\n", func, line,
|
||||||
func, line, vmem_alloc_used_read(), vmem_alloc_max);
|
vmem_alloc_used_read(), vmem_alloc_max);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,8 +435,8 @@ vmem_alloc_track(size_t size, int flags, const char *func, int line)
|
||||||
if (unlikely(ptr == NULL)) {
|
if (unlikely(ptr == NULL)) {
|
||||||
kfree(dptr->kd_func);
|
kfree(dptr->kd_func);
|
||||||
kfree(dptr);
|
kfree(dptr);
|
||||||
SDEBUG_LIMIT(SD_CONSOLE | SD_WARNING, "vmem_alloc"
|
printk(KERN_WARNING "vmem_alloc (%llu, 0x%x) "
|
||||||
"(%llu, 0x%x) at %s:%d failed (%lld/%llu)\n",
|
"at %s:%d failed (%lld/%llu)\n",
|
||||||
(unsigned long long) size, flags, func, line,
|
(unsigned long long) size, flags, func, line,
|
||||||
vmem_alloc_used_read(), vmem_alloc_max);
|
vmem_alloc_used_read(), vmem_alloc_max);
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -482,14 +458,9 @@ vmem_alloc_track(size_t size, int flags, const char *func, int line)
|
||||||
&vmem_table[hash_ptr(ptr, VMEM_HASH_BITS)]);
|
&vmem_table[hash_ptr(ptr, VMEM_HASH_BITS)]);
|
||||||
list_add_tail(&dptr->kd_list, &vmem_list);
|
list_add_tail(&dptr->kd_list, &vmem_list);
|
||||||
spin_unlock_irqrestore(&vmem_lock, irq_flags);
|
spin_unlock_irqrestore(&vmem_lock, irq_flags);
|
||||||
|
|
||||||
SDEBUG_LIMIT(SD_INFO,
|
|
||||||
"vmem_alloc(%llu, 0x%x) at %s:%d = %p (%lld/%llu)\n",
|
|
||||||
(unsigned long long) size, flags, func, line,
|
|
||||||
ptr, vmem_alloc_used_read(), vmem_alloc_max);
|
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
SRETURN(ptr);
|
return (ptr);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(vmem_alloc_track);
|
EXPORT_SYMBOL(vmem_alloc_track);
|
||||||
|
|
||||||
|
@ -497,14 +468,12 @@ void
|
||||||
vmem_free_track(const void *ptr, size_t size)
|
vmem_free_track(const void *ptr, size_t size)
|
||||||
{
|
{
|
||||||
kmem_debug_t *dptr;
|
kmem_debug_t *dptr;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERTF(ptr || size > 0, "ptr: %p, size: %llu", ptr,
|
ASSERTF(ptr || size > 0, "ptr: %p, size: %llu", ptr,
|
||||||
(unsigned long long) size);
|
(unsigned long long) size);
|
||||||
|
|
||||||
dptr = kmem_del_init(&vmem_lock, vmem_table, VMEM_HASH_BITS, ptr);
|
|
||||||
|
|
||||||
/* Must exist in hash due to vmem_alloc() */
|
/* Must exist in hash due to vmem_alloc() */
|
||||||
|
dptr = kmem_del_init(&vmem_lock, vmem_table, VMEM_HASH_BITS, ptr);
|
||||||
ASSERT(dptr);
|
ASSERT(dptr);
|
||||||
|
|
||||||
/* Size must match */
|
/* Size must match */
|
||||||
|
@ -513,10 +482,6 @@ vmem_free_track(const void *ptr, size_t size)
|
||||||
(unsigned long long) size, dptr->kd_func, dptr->kd_line);
|
(unsigned long long) size, dptr->kd_func, dptr->kd_line);
|
||||||
|
|
||||||
vmem_alloc_used_sub(size);
|
vmem_alloc_used_sub(size);
|
||||||
SDEBUG_LIMIT(SD_INFO, "vmem_free(%p, %llu) (%lld/%llu)\n", ptr,
|
|
||||||
(unsigned long long) size, vmem_alloc_used_read(),
|
|
||||||
vmem_alloc_max);
|
|
||||||
|
|
||||||
kfree(dptr->kd_func);
|
kfree(dptr->kd_func);
|
||||||
|
|
||||||
memset((void *)dptr, 0x5a, sizeof(kmem_debug_t));
|
memset((void *)dptr, 0x5a, sizeof(kmem_debug_t));
|
||||||
|
@ -524,8 +489,6 @@ vmem_free_track(const void *ptr, size_t size)
|
||||||
|
|
||||||
memset((void *)ptr, 0x5a, size);
|
memset((void *)ptr, 0x5a, size);
|
||||||
vfree(ptr);
|
vfree(ptr);
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(vmem_free_track);
|
EXPORT_SYMBOL(vmem_free_track);
|
||||||
|
|
||||||
|
@ -536,18 +499,17 @@ kmem_alloc_debug(size_t size, int flags, const char *func, int line,
|
||||||
int node_alloc, int node)
|
int node_alloc, int node)
|
||||||
{
|
{
|
||||||
void *ptr;
|
void *ptr;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Marked unlikely because we should never be doing this,
|
* Marked unlikely because we should never be doing this,
|
||||||
* we tolerate to up 2 pages but a single page is best.
|
* we tolerate to up 2 pages but a single page is best.
|
||||||
*/
|
*/
|
||||||
if (unlikely((size > PAGE_SIZE * 2) && !(flags & KM_NODEBUG))) {
|
if (unlikely((size > PAGE_SIZE * 2) && !(flags & KM_NODEBUG))) {
|
||||||
SDEBUG(SD_CONSOLE | SD_WARNING,
|
printk(KERN_WARNING
|
||||||
"large kmem_alloc(%llu, 0x%x) at %s:%d (%lld/%llu)\n",
|
"large kmem_alloc(%llu, 0x%x) at %s:%d (%lld/%llu)\n",
|
||||||
(unsigned long long) size, flags, func, line,
|
(unsigned long long)size, flags, func, line,
|
||||||
kmem_alloc_used_read(), kmem_alloc_max);
|
(unsigned long long)kmem_alloc_used_read(), kmem_alloc_max);
|
||||||
spl_debug_dumpstack(NULL);
|
spl_dumpstack();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use the correct allocator */
|
/* Use the correct allocator */
|
||||||
|
@ -561,40 +523,26 @@ kmem_alloc_debug(size_t size, int flags, const char *func, int line,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(ptr == NULL)) {
|
if (unlikely(ptr == NULL)) {
|
||||||
SDEBUG_LIMIT(SD_CONSOLE | SD_WARNING,
|
printk(KERN_WARNING
|
||||||
"kmem_alloc(%llu, 0x%x) at %s:%d failed (%lld/%llu)\n",
|
"kmem_alloc(%llu, 0x%x) at %s:%d failed (%lld/%llu)\n",
|
||||||
(unsigned long long) size, flags, func, line,
|
(unsigned long long)size, flags, func, line,
|
||||||
kmem_alloc_used_read(), kmem_alloc_max);
|
(unsigned long long)kmem_alloc_used_read(), kmem_alloc_max);
|
||||||
} else {
|
} else {
|
||||||
kmem_alloc_used_add(size);
|
kmem_alloc_used_add(size);
|
||||||
if (unlikely(kmem_alloc_used_read() > kmem_alloc_max))
|
if (unlikely(kmem_alloc_used_read() > kmem_alloc_max))
|
||||||
kmem_alloc_max = kmem_alloc_used_read();
|
kmem_alloc_max = kmem_alloc_used_read();
|
||||||
|
|
||||||
SDEBUG_LIMIT(SD_INFO,
|
|
||||||
"kmem_alloc(%llu, 0x%x) at %s:%d = %p (%lld/%llu)\n",
|
|
||||||
(unsigned long long) size, flags, func, line, ptr,
|
|
||||||
kmem_alloc_used_read(), kmem_alloc_max);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SRETURN(ptr);
|
return (ptr);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(kmem_alloc_debug);
|
EXPORT_SYMBOL(kmem_alloc_debug);
|
||||||
|
|
||||||
void
|
void
|
||||||
kmem_free_debug(const void *ptr, size_t size)
|
kmem_free_debug(const void *ptr, size_t size)
|
||||||
{
|
{
|
||||||
SENTRY;
|
ASSERT(ptr || size > 0);
|
||||||
|
|
||||||
ASSERTF(ptr || size > 0, "ptr: %p, size: %llu", ptr,
|
|
||||||
(unsigned long long) size);
|
|
||||||
|
|
||||||
kmem_alloc_used_sub(size);
|
kmem_alloc_used_sub(size);
|
||||||
SDEBUG_LIMIT(SD_INFO, "kmem_free(%p, %llu) (%lld/%llu)\n", ptr,
|
|
||||||
(unsigned long long) size, kmem_alloc_used_read(),
|
|
||||||
kmem_alloc_max);
|
|
||||||
kfree(ptr);
|
kfree(ptr);
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(kmem_free_debug);
|
EXPORT_SYMBOL(kmem_free_debug);
|
||||||
|
|
||||||
|
@ -602,7 +550,6 @@ void *
|
||||||
vmem_alloc_debug(size_t size, int flags, const char *func, int line)
|
vmem_alloc_debug(size_t size, int flags, const char *func, int line)
|
||||||
{
|
{
|
||||||
void *ptr;
|
void *ptr;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(flags & KM_SLEEP);
|
ASSERT(flags & KM_SLEEP);
|
||||||
|
|
||||||
|
@ -614,39 +561,26 @@ vmem_alloc_debug(size_t size, int flags, const char *func, int line)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(ptr == NULL)) {
|
if (unlikely(ptr == NULL)) {
|
||||||
SDEBUG_LIMIT(SD_CONSOLE | SD_WARNING,
|
printk(KERN_WARNING
|
||||||
"vmem_alloc(%llu, 0x%x) at %s:%d failed (%lld/%llu)\n",
|
"vmem_alloc(%llu, 0x%x) at %s:%d failed (%lld/%llu)\n",
|
||||||
(unsigned long long) size, flags, func, line,
|
(unsigned long long)size, flags, func, line,
|
||||||
vmem_alloc_used_read(), vmem_alloc_max);
|
(unsigned long long)vmem_alloc_used_read(), vmem_alloc_max);
|
||||||
} else {
|
} else {
|
||||||
vmem_alloc_used_add(size);
|
vmem_alloc_used_add(size);
|
||||||
if (unlikely(vmem_alloc_used_read() > vmem_alloc_max))
|
if (unlikely(vmem_alloc_used_read() > vmem_alloc_max))
|
||||||
vmem_alloc_max = vmem_alloc_used_read();
|
vmem_alloc_max = vmem_alloc_used_read();
|
||||||
|
|
||||||
SDEBUG_LIMIT(SD_INFO, "vmem_alloc(%llu, 0x%x) = %p "
|
|
||||||
"(%lld/%llu)\n", (unsigned long long) size, flags, ptr,
|
|
||||||
vmem_alloc_used_read(), vmem_alloc_max);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SRETURN(ptr);
|
return (ptr);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(vmem_alloc_debug);
|
EXPORT_SYMBOL(vmem_alloc_debug);
|
||||||
|
|
||||||
void
|
void
|
||||||
vmem_free_debug(const void *ptr, size_t size)
|
vmem_free_debug(const void *ptr, size_t size)
|
||||||
{
|
{
|
||||||
SENTRY;
|
ASSERT(ptr || size > 0);
|
||||||
|
|
||||||
ASSERTF(ptr || size > 0, "ptr: %p, size: %llu", ptr,
|
|
||||||
(unsigned long long) size);
|
|
||||||
|
|
||||||
vmem_alloc_used_sub(size);
|
vmem_alloc_used_sub(size);
|
||||||
SDEBUG_LIMIT(SD_INFO, "vmem_free(%p, %llu) (%lld/%llu)\n", ptr,
|
|
||||||
(unsigned long long) size, vmem_alloc_used_read(),
|
|
||||||
vmem_alloc_max);
|
|
||||||
vfree(ptr);
|
vfree(ptr);
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(vmem_free_debug);
|
EXPORT_SYMBOL(vmem_free_debug);
|
||||||
|
|
||||||
|
@ -833,7 +767,7 @@ spl_slab_alloc(spl_kmem_cache_t *skc, int flags)
|
||||||
|
|
||||||
base = kv_alloc(skc, skc->skc_slab_size, flags);
|
base = kv_alloc(skc, skc->skc_slab_size, flags);
|
||||||
if (base == NULL)
|
if (base == NULL)
|
||||||
SRETURN(NULL);
|
return (NULL);
|
||||||
|
|
||||||
sks = (spl_kmem_slab_t *)base;
|
sks = (spl_kmem_slab_t *)base;
|
||||||
sks->sks_magic = SKS_MAGIC;
|
sks->sks_magic = SKS_MAGIC;
|
||||||
|
@ -851,8 +785,10 @@ spl_slab_alloc(spl_kmem_cache_t *skc, int flags)
|
||||||
for (i = 0; i < sks->sks_objs; i++) {
|
for (i = 0; i < sks->sks_objs; i++) {
|
||||||
if (skc->skc_flags & KMC_OFFSLAB) {
|
if (skc->skc_flags & KMC_OFFSLAB) {
|
||||||
obj = kv_alloc(skc, offslab_size, flags);
|
obj = kv_alloc(skc, offslab_size, flags);
|
||||||
if (!obj)
|
if (!obj) {
|
||||||
SGOTO(out, rc = -ENOMEM);
|
rc = -ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
obj = base + spl_sks_size(skc) + (i * obj_size);
|
obj = base + spl_sks_size(skc) + (i * obj_size);
|
||||||
}
|
}
|
||||||
|
@ -877,7 +813,7 @@ out:
|
||||||
sks = NULL;
|
sks = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRETURN(sks);
|
return (sks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -890,7 +826,6 @@ spl_slab_free(spl_kmem_slab_t *sks,
|
||||||
struct list_head *sks_list, struct list_head *sko_list)
|
struct list_head *sks_list, struct list_head *sko_list)
|
||||||
{
|
{
|
||||||
spl_kmem_cache_t *skc;
|
spl_kmem_cache_t *skc;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(sks->sks_magic == SKS_MAGIC);
|
ASSERT(sks->sks_magic == SKS_MAGIC);
|
||||||
ASSERT(sks->sks_ref == 0);
|
ASSERT(sks->sks_ref == 0);
|
||||||
|
@ -910,8 +845,6 @@ spl_slab_free(spl_kmem_slab_t *sks,
|
||||||
list_del(&sks->sks_list);
|
list_del(&sks->sks_list);
|
||||||
list_add(&sks->sks_list, sks_list);
|
list_add(&sks->sks_list, sks_list);
|
||||||
list_splice_init(&sks->sks_free_list, sko_list);
|
list_splice_init(&sks->sks_free_list, sko_list);
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -931,7 +864,6 @@ spl_slab_reclaim(spl_kmem_cache_t *skc, int count, int flag)
|
||||||
LIST_HEAD(sko_list);
|
LIST_HEAD(sko_list);
|
||||||
uint32_t size = 0;
|
uint32_t size = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Move empty slabs and objects which have not been touched in
|
* Move empty slabs and objects which have not been touched in
|
||||||
|
@ -979,8 +911,6 @@ spl_slab_reclaim(spl_kmem_cache_t *skc, int count, int flag)
|
||||||
ASSERT(sks->sks_magic == SKS_MAGIC);
|
ASSERT(sks->sks_magic == SKS_MAGIC);
|
||||||
kv_free(skc, sks, skc->skc_slab_size);
|
kv_free(skc, sks, skc->skc_slab_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static spl_kmem_emergency_t *
|
static spl_kmem_emergency_t *
|
||||||
|
@ -1037,23 +967,22 @@ spl_emergency_alloc(spl_kmem_cache_t *skc, int flags, void **obj)
|
||||||
{
|
{
|
||||||
spl_kmem_emergency_t *ske;
|
spl_kmem_emergency_t *ske;
|
||||||
int empty;
|
int empty;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
/* Last chance use a partial slab if one now exists */
|
/* Last chance use a partial slab if one now exists */
|
||||||
spin_lock(&skc->skc_lock);
|
spin_lock(&skc->skc_lock);
|
||||||
empty = list_empty(&skc->skc_partial_list);
|
empty = list_empty(&skc->skc_partial_list);
|
||||||
spin_unlock(&skc->skc_lock);
|
spin_unlock(&skc->skc_lock);
|
||||||
if (!empty)
|
if (!empty)
|
||||||
SRETURN(-EEXIST);
|
return (-EEXIST);
|
||||||
|
|
||||||
ske = kmalloc(sizeof(*ske), flags);
|
ske = kmalloc(sizeof(*ske), flags);
|
||||||
if (ske == NULL)
|
if (ske == NULL)
|
||||||
SRETURN(-ENOMEM);
|
return (-ENOMEM);
|
||||||
|
|
||||||
ske->ske_obj = kmalloc(skc->skc_obj_size, flags);
|
ske->ske_obj = kmalloc(skc->skc_obj_size, flags);
|
||||||
if (ske->ske_obj == NULL) {
|
if (ske->ske_obj == NULL) {
|
||||||
kfree(ske);
|
kfree(ske);
|
||||||
SRETURN(-ENOMEM);
|
return (-ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock(&skc->skc_lock);
|
spin_lock(&skc->skc_lock);
|
||||||
|
@ -1069,12 +998,12 @@ spl_emergency_alloc(spl_kmem_cache_t *skc, int flags, void **obj)
|
||||||
if (unlikely(!empty)) {
|
if (unlikely(!empty)) {
|
||||||
kfree(ske->ske_obj);
|
kfree(ske->ske_obj);
|
||||||
kfree(ske);
|
kfree(ske);
|
||||||
SRETURN(-EINVAL);
|
return (-EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
*obj = ske->ske_obj;
|
*obj = ske->ske_obj;
|
||||||
|
|
||||||
SRETURN(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1084,7 +1013,6 @@ static int
|
||||||
spl_emergency_free(spl_kmem_cache_t *skc, void *obj)
|
spl_emergency_free(spl_kmem_cache_t *skc, void *obj)
|
||||||
{
|
{
|
||||||
spl_kmem_emergency_t *ske;
|
spl_kmem_emergency_t *ske;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
spin_lock(&skc->skc_lock);
|
spin_lock(&skc->skc_lock);
|
||||||
ske = spl_emergency_search(&skc->skc_emergency_tree, obj);
|
ske = spl_emergency_search(&skc->skc_emergency_tree, obj);
|
||||||
|
@ -1096,12 +1024,12 @@ spl_emergency_free(spl_kmem_cache_t *skc, void *obj)
|
||||||
spin_unlock(&skc->skc_lock);
|
spin_unlock(&skc->skc_lock);
|
||||||
|
|
||||||
if (unlikely(ske == NULL))
|
if (unlikely(ske == NULL))
|
||||||
SRETURN(-ENOENT);
|
return (-ENOENT);
|
||||||
|
|
||||||
kfree(ske->ske_obj);
|
kfree(ske->ske_obj);
|
||||||
kfree(ske);
|
kfree(ske);
|
||||||
|
|
||||||
SRETURN(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1112,7 +1040,6 @@ static void
|
||||||
__spl_cache_flush(spl_kmem_cache_t *skc, spl_kmem_magazine_t *skm, int flush)
|
__spl_cache_flush(spl_kmem_cache_t *skc, spl_kmem_magazine_t *skm, int flush)
|
||||||
{
|
{
|
||||||
int i, count = MIN(flush, skm->skm_avail);
|
int i, count = MIN(flush, skm->skm_avail);
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(skc->skc_magic == SKC_MAGIC);
|
ASSERT(skc->skc_magic == SKC_MAGIC);
|
||||||
ASSERT(skm->skm_magic == SKM_MAGIC);
|
ASSERT(skm->skm_magic == SKM_MAGIC);
|
||||||
|
@ -1124,8 +1051,6 @@ __spl_cache_flush(spl_kmem_cache_t *skc, spl_kmem_magazine_t *skm, int flush)
|
||||||
skm->skm_avail -= count;
|
skm->skm_avail -= count;
|
||||||
memmove(skm->skm_objs, &(skm->skm_objs[count]),
|
memmove(skm->skm_objs, &(skm->skm_objs[count]),
|
||||||
sizeof(void *) * skm->skm_avail);
|
sizeof(void *) * skm->skm_avail);
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1227,7 +1152,7 @@ spl_slab_size(spl_kmem_cache_t *skc, uint32_t *objs, uint32_t *size)
|
||||||
if (skc->skc_flags & KMC_OFFSLAB) {
|
if (skc->skc_flags & KMC_OFFSLAB) {
|
||||||
*objs = spl_kmem_cache_obj_per_slab;
|
*objs = spl_kmem_cache_obj_per_slab;
|
||||||
*size = P2ROUNDUP(sizeof(spl_kmem_slab_t), PAGE_SIZE);
|
*size = P2ROUNDUP(sizeof(spl_kmem_slab_t), PAGE_SIZE);
|
||||||
SRETURN(0);
|
return (0);
|
||||||
} else {
|
} else {
|
||||||
sks_size = spl_sks_size(skc);
|
sks_size = spl_sks_size(skc);
|
||||||
obj_size = spl_obj_size(skc);
|
obj_size = spl_obj_size(skc);
|
||||||
|
@ -1241,7 +1166,7 @@ spl_slab_size(spl_kmem_cache_t *skc, uint32_t *objs, uint32_t *size)
|
||||||
for (*size = PAGE_SIZE; *size <= max_size; *size *= 2) {
|
for (*size = PAGE_SIZE; *size <= max_size; *size *= 2) {
|
||||||
*objs = (*size - sks_size) / obj_size;
|
*objs = (*size - sks_size) / obj_size;
|
||||||
if (*objs >= spl_kmem_cache_obj_per_slab)
|
if (*objs >= spl_kmem_cache_obj_per_slab)
|
||||||
SRETURN(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1252,10 +1177,10 @@ spl_slab_size(spl_kmem_cache_t *skc, uint32_t *objs, uint32_t *size)
|
||||||
*size = max_size;
|
*size = max_size;
|
||||||
*objs = (*size - sks_size) / obj_size;
|
*objs = (*size - sks_size) / obj_size;
|
||||||
if (*objs >= (spl_kmem_cache_obj_per_slab_min))
|
if (*objs >= (spl_kmem_cache_obj_per_slab_min))
|
||||||
SRETURN(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
SRETURN(-ENOSPC);
|
return (-ENOSPC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1268,7 +1193,6 @@ spl_magazine_size(spl_kmem_cache_t *skc)
|
||||||
{
|
{
|
||||||
uint32_t obj_size = spl_obj_size(skc);
|
uint32_t obj_size = spl_obj_size(skc);
|
||||||
int size;
|
int size;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
/* Per-magazine sizes below assume a 4Kib page size */
|
/* Per-magazine sizes below assume a 4Kib page size */
|
||||||
if (obj_size > (PAGE_SIZE * 256))
|
if (obj_size > (PAGE_SIZE * 256))
|
||||||
|
@ -1282,7 +1206,7 @@ spl_magazine_size(spl_kmem_cache_t *skc)
|
||||||
else
|
else
|
||||||
size = 256;
|
size = 256;
|
||||||
|
|
||||||
SRETURN(size);
|
return (size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1294,7 +1218,6 @@ spl_magazine_alloc(spl_kmem_cache_t *skc, int cpu)
|
||||||
spl_kmem_magazine_t *skm;
|
spl_kmem_magazine_t *skm;
|
||||||
int size = sizeof(spl_kmem_magazine_t) +
|
int size = sizeof(spl_kmem_magazine_t) +
|
||||||
sizeof(void *) * skc->skc_mag_size;
|
sizeof(void *) * skc->skc_mag_size;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
skm = kmem_alloc_node(size, KM_SLEEP, cpu_to_node(cpu));
|
skm = kmem_alloc_node(size, KM_SLEEP, cpu_to_node(cpu));
|
||||||
if (skm) {
|
if (skm) {
|
||||||
|
@ -1307,7 +1230,7 @@ spl_magazine_alloc(spl_kmem_cache_t *skc, int cpu)
|
||||||
skm->skm_cpu = cpu;
|
skm->skm_cpu = cpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRETURN(skm);
|
return (skm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1319,12 +1242,10 @@ spl_magazine_free(spl_kmem_magazine_t *skm)
|
||||||
int size = sizeof(spl_kmem_magazine_t) +
|
int size = sizeof(spl_kmem_magazine_t) +
|
||||||
sizeof(void *) * skm->skm_size;
|
sizeof(void *) * skm->skm_size;
|
||||||
|
|
||||||
SENTRY;
|
|
||||||
ASSERT(skm->skm_magic == SKM_MAGIC);
|
ASSERT(skm->skm_magic == SKM_MAGIC);
|
||||||
ASSERT(skm->skm_avail == 0);
|
ASSERT(skm->skm_avail == 0);
|
||||||
|
|
||||||
kmem_free(skm, size);
|
kmem_free(skm, size);
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1334,10 +1255,9 @@ static int
|
||||||
spl_magazine_create(spl_kmem_cache_t *skc)
|
spl_magazine_create(spl_kmem_cache_t *skc)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
if (skc->skc_flags & KMC_NOMAGAZINE)
|
if (skc->skc_flags & KMC_NOMAGAZINE)
|
||||||
SRETURN(0);
|
return (0);
|
||||||
|
|
||||||
skc->skc_mag_size = spl_magazine_size(skc);
|
skc->skc_mag_size = spl_magazine_size(skc);
|
||||||
skc->skc_mag_refill = (skc->skc_mag_size + 1) / 2;
|
skc->skc_mag_refill = (skc->skc_mag_size + 1) / 2;
|
||||||
|
@ -1348,11 +1268,11 @@ spl_magazine_create(spl_kmem_cache_t *skc)
|
||||||
for (i--; i >= 0; i--)
|
for (i--; i >= 0; i--)
|
||||||
spl_magazine_free(skc->skc_mag[i]);
|
spl_magazine_free(skc->skc_mag[i]);
|
||||||
|
|
||||||
SRETURN(-ENOMEM);
|
return (-ENOMEM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SRETURN(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1363,20 +1283,15 @@ spl_magazine_destroy(spl_kmem_cache_t *skc)
|
||||||
{
|
{
|
||||||
spl_kmem_magazine_t *skm;
|
spl_kmem_magazine_t *skm;
|
||||||
int i;
|
int i;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
if (skc->skc_flags & KMC_NOMAGAZINE) {
|
if (skc->skc_flags & KMC_NOMAGAZINE)
|
||||||
SEXIT;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
for_each_online_cpu(i) {
|
for_each_online_cpu(i) {
|
||||||
skm = skc->skc_mag[i];
|
skm = skc->skc_mag[i];
|
||||||
spl_cache_flush(skc, skm, skm->skm_avail);
|
spl_cache_flush(skc, skm, skm->skm_avail);
|
||||||
spl_magazine_free(skm);
|
spl_magazine_free(skm);
|
||||||
}
|
}
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1409,11 +1324,13 @@ spl_kmem_cache_create(char *name, size_t size, size_t align,
|
||||||
{
|
{
|
||||||
spl_kmem_cache_t *skc;
|
spl_kmem_cache_t *skc;
|
||||||
int rc;
|
int rc;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERTF(!(flags & KMC_NOMAGAZINE), "Bad KMC_NOMAGAZINE (%x)\n", flags);
|
/*
|
||||||
ASSERTF(!(flags & KMC_NOHASH), "Bad KMC_NOHASH (%x)\n", flags);
|
* Unsupported flags
|
||||||
ASSERTF(!(flags & KMC_QCACHE), "Bad KMC_QCACHE (%x)\n", flags);
|
*/
|
||||||
|
ASSERT0(flags & KMC_NOMAGAZINE);
|
||||||
|
ASSERT0(flags & KMC_NOHASH);
|
||||||
|
ASSERT0(flags & KMC_QCACHE);
|
||||||
ASSERT(vmp == NULL);
|
ASSERT(vmp == NULL);
|
||||||
|
|
||||||
might_sleep();
|
might_sleep();
|
||||||
|
@ -1427,14 +1344,14 @@ spl_kmem_cache_create(char *name, size_t size, size_t align,
|
||||||
*/
|
*/
|
||||||
skc = kmem_zalloc(sizeof(*skc), KM_SLEEP| KM_NODEBUG);
|
skc = kmem_zalloc(sizeof(*skc), KM_SLEEP| KM_NODEBUG);
|
||||||
if (skc == NULL)
|
if (skc == NULL)
|
||||||
SRETURN(NULL);
|
return (NULL);
|
||||||
|
|
||||||
skc->skc_magic = SKC_MAGIC;
|
skc->skc_magic = SKC_MAGIC;
|
||||||
skc->skc_name_size = strlen(name) + 1;
|
skc->skc_name_size = strlen(name) + 1;
|
||||||
skc->skc_name = (char *)kmem_alloc(skc->skc_name_size, KM_SLEEP);
|
skc->skc_name = (char *)kmem_alloc(skc->skc_name_size, KM_SLEEP);
|
||||||
if (skc->skc_name == NULL) {
|
if (skc->skc_name == NULL) {
|
||||||
kmem_free(skc, sizeof(*skc));
|
kmem_free(skc, sizeof(*skc));
|
||||||
SRETURN(NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
strncpy(skc->skc_name, name, skc->skc_name_size);
|
strncpy(skc->skc_name, name, skc->skc_name_size);
|
||||||
|
|
||||||
|
@ -1519,16 +1436,18 @@ spl_kmem_cache_create(char *name, size_t size, size_t align,
|
||||||
rc = spl_slab_size(skc,
|
rc = spl_slab_size(skc,
|
||||||
&skc->skc_slab_objs, &skc->skc_slab_size);
|
&skc->skc_slab_objs, &skc->skc_slab_size);
|
||||||
if (rc)
|
if (rc)
|
||||||
SGOTO(out, rc);
|
goto out;
|
||||||
|
|
||||||
rc = spl_magazine_create(skc);
|
rc = spl_magazine_create(skc);
|
||||||
if (rc)
|
if (rc)
|
||||||
SGOTO(out, rc);
|
goto out;
|
||||||
} else {
|
} else {
|
||||||
skc->skc_linux_cache = kmem_cache_create(
|
skc->skc_linux_cache = kmem_cache_create(
|
||||||
skc->skc_name, size, align, 0, NULL);
|
skc->skc_name, size, align, 0, NULL);
|
||||||
if (skc->skc_linux_cache == NULL)
|
if (skc->skc_linux_cache == NULL) {
|
||||||
SGOTO(out, rc = ENOMEM);
|
rc = ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
kmem_cache_set_allocflags(skc, __GFP_COMP);
|
kmem_cache_set_allocflags(skc, __GFP_COMP);
|
||||||
skc->skc_flags |= KMC_NOMAGAZINE;
|
skc->skc_flags |= KMC_NOMAGAZINE;
|
||||||
|
@ -1543,11 +1462,11 @@ spl_kmem_cache_create(char *name, size_t size, size_t align,
|
||||||
list_add_tail(&skc->skc_list, &spl_kmem_cache_list);
|
list_add_tail(&skc->skc_list, &spl_kmem_cache_list);
|
||||||
up_write(&spl_kmem_cache_sem);
|
up_write(&spl_kmem_cache_sem);
|
||||||
|
|
||||||
SRETURN(skc);
|
return (skc);
|
||||||
out:
|
out:
|
||||||
kmem_free(skc->skc_name, skc->skc_name_size);
|
kmem_free(skc->skc_name, skc->skc_name_size);
|
||||||
kmem_free(skc, sizeof(*skc));
|
kmem_free(skc, sizeof(*skc));
|
||||||
SRETURN(NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(spl_kmem_cache_create);
|
EXPORT_SYMBOL(spl_kmem_cache_create);
|
||||||
|
|
||||||
|
@ -1571,7 +1490,6 @@ spl_kmem_cache_destroy(spl_kmem_cache_t *skc)
|
||||||
{
|
{
|
||||||
DECLARE_WAIT_QUEUE_HEAD(wq);
|
DECLARE_WAIT_QUEUE_HEAD(wq);
|
||||||
taskqid_t id;
|
taskqid_t id;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(skc->skc_magic == SKC_MAGIC);
|
ASSERT(skc->skc_magic == SKC_MAGIC);
|
||||||
ASSERT(skc->skc_flags & (KMC_KMEM | KMC_VMEM | KMC_SLAB));
|
ASSERT(skc->skc_flags & (KMC_KMEM | KMC_VMEM | KMC_SLAB));
|
||||||
|
@ -1617,8 +1535,6 @@ spl_kmem_cache_destroy(spl_kmem_cache_t *skc)
|
||||||
spin_unlock(&skc->skc_lock);
|
spin_unlock(&skc->skc_lock);
|
||||||
|
|
||||||
kmem_free(skc, sizeof(*skc));
|
kmem_free(skc, sizeof(*skc));
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(spl_kmem_cache_destroy);
|
EXPORT_SYMBOL(spl_kmem_cache_destroy);
|
||||||
|
|
||||||
|
@ -1708,7 +1624,6 @@ static int
|
||||||
spl_cache_grow(spl_kmem_cache_t *skc, int flags, void **obj)
|
spl_cache_grow(spl_kmem_cache_t *skc, int flags, void **obj)
|
||||||
{
|
{
|
||||||
int remaining, rc;
|
int remaining, rc;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(skc->skc_magic == SKC_MAGIC);
|
ASSERT(skc->skc_magic == SKC_MAGIC);
|
||||||
ASSERT((skc->skc_flags & KMC_SLAB) == 0);
|
ASSERT((skc->skc_flags & KMC_SLAB) == 0);
|
||||||
|
@ -1722,7 +1637,7 @@ spl_cache_grow(spl_kmem_cache_t *skc, int flags, void **obj)
|
||||||
if (test_bit(KMC_BIT_REAPING, &skc->skc_flags)) {
|
if (test_bit(KMC_BIT_REAPING, &skc->skc_flags)) {
|
||||||
rc = spl_wait_on_bit(&skc->skc_flags, KMC_BIT_REAPING,
|
rc = spl_wait_on_bit(&skc->skc_flags, KMC_BIT_REAPING,
|
||||||
TASK_UNINTERRUPTIBLE);
|
TASK_UNINTERRUPTIBLE);
|
||||||
SRETURN(rc ? rc : -EAGAIN);
|
return (rc ? rc : -EAGAIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1738,7 +1653,7 @@ spl_cache_grow(spl_kmem_cache_t *skc, int flags, void **obj)
|
||||||
if (ska == NULL) {
|
if (ska == NULL) {
|
||||||
clear_bit(KMC_BIT_GROWING, &skc->skc_flags);
|
clear_bit(KMC_BIT_GROWING, &skc->skc_flags);
|
||||||
wake_up_all(&skc->skc_waitq);
|
wake_up_all(&skc->skc_waitq);
|
||||||
SRETURN(-ENOMEM);
|
return (-ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic_inc(&skc->skc_ref);
|
atomic_inc(&skc->skc_ref);
|
||||||
|
@ -1776,7 +1691,7 @@ spl_cache_grow(spl_kmem_cache_t *skc, int flags, void **obj)
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRETURN(rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1792,7 +1707,6 @@ spl_cache_refill(spl_kmem_cache_t *skc, spl_kmem_magazine_t *skm, int flags)
|
||||||
spl_kmem_slab_t *sks;
|
spl_kmem_slab_t *sks;
|
||||||
int count = 0, rc, refill;
|
int count = 0, rc, refill;
|
||||||
void *obj = NULL;
|
void *obj = NULL;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(skc->skc_magic == SKC_MAGIC);
|
ASSERT(skc->skc_magic == SKC_MAGIC);
|
||||||
ASSERT(skm->skm_magic == SKM_MAGIC);
|
ASSERT(skm->skm_magic == SKM_MAGIC);
|
||||||
|
@ -1811,14 +1725,14 @@ spl_cache_refill(spl_kmem_cache_t *skc, spl_kmem_magazine_t *skm, int flags)
|
||||||
|
|
||||||
/* Emergency object for immediate use by caller */
|
/* Emergency object for immediate use by caller */
|
||||||
if (rc == 0 && obj != NULL)
|
if (rc == 0 && obj != NULL)
|
||||||
SRETURN(obj);
|
return (obj);
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
SGOTO(out, rc);
|
goto out;
|
||||||
|
|
||||||
/* Rescheduled to different CPU skm is not local */
|
/* Rescheduled to different CPU skm is not local */
|
||||||
if (skm != skc->skc_mag[smp_processor_id()])
|
if (skm != skc->skc_mag[smp_processor_id()])
|
||||||
SGOTO(out, rc);
|
goto out;
|
||||||
|
|
||||||
/* Potentially rescheduled to the same CPU but
|
/* Potentially rescheduled to the same CPU but
|
||||||
* allocations may have occurred from this CPU while
|
* allocations may have occurred from this CPU while
|
||||||
|
@ -1853,7 +1767,7 @@ spl_cache_refill(spl_kmem_cache_t *skc, spl_kmem_magazine_t *skm, int flags)
|
||||||
|
|
||||||
spin_unlock(&skc->skc_lock);
|
spin_unlock(&skc->skc_lock);
|
||||||
out:
|
out:
|
||||||
SRETURN(NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1864,7 +1778,6 @@ spl_cache_shrink(spl_kmem_cache_t *skc, void *obj)
|
||||||
{
|
{
|
||||||
spl_kmem_slab_t *sks = NULL;
|
spl_kmem_slab_t *sks = NULL;
|
||||||
spl_kmem_obj_t *sko = NULL;
|
spl_kmem_obj_t *sko = NULL;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(skc->skc_magic == SKC_MAGIC);
|
ASSERT(skc->skc_magic == SKC_MAGIC);
|
||||||
ASSERT(spin_is_locked(&skc->skc_lock));
|
ASSERT(spin_is_locked(&skc->skc_lock));
|
||||||
|
@ -1895,8 +1808,6 @@ spl_cache_shrink(spl_kmem_cache_t *skc, void *obj)
|
||||||
list_add_tail(&sks->sks_list, &skc->skc_partial_list);
|
list_add_tail(&sks->sks_list, &skc->skc_partial_list);
|
||||||
skc->skc_slab_alloc--;
|
skc->skc_slab_alloc--;
|
||||||
}
|
}
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1908,7 +1819,6 @@ spl_kmem_cache_alloc(spl_kmem_cache_t *skc, int flags)
|
||||||
{
|
{
|
||||||
spl_kmem_magazine_t *skm;
|
spl_kmem_magazine_t *skm;
|
||||||
void *obj = NULL;
|
void *obj = NULL;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(skc->skc_magic == SKC_MAGIC);
|
ASSERT(skc->skc_magic == SKC_MAGIC);
|
||||||
ASSERT(!test_bit(KMC_BIT_DESTROY, &skc->skc_flags));
|
ASSERT(!test_bit(KMC_BIT_DESTROY, &skc->skc_flags));
|
||||||
|
@ -1939,9 +1849,7 @@ restart:
|
||||||
* the local magazine since this may have changed
|
* the local magazine since this may have changed
|
||||||
* when we need to grow the cache. */
|
* when we need to grow the cache. */
|
||||||
skm = skc->skc_mag[smp_processor_id()];
|
skm = skc->skc_mag[smp_processor_id()];
|
||||||
ASSERTF(skm->skm_magic == SKM_MAGIC, "%x != %x: %s/%p/%p %x/%x/%x\n",
|
ASSERT(skm->skm_magic == SKM_MAGIC);
|
||||||
skm->skm_magic, SKM_MAGIC, skc->skc_name, skc, skm,
|
|
||||||
skm->skm_size, skm->skm_refill, skm->skm_avail);
|
|
||||||
|
|
||||||
if (likely(skm->skm_avail)) {
|
if (likely(skm->skm_avail)) {
|
||||||
/* Object available in CPU cache, use it */
|
/* Object available in CPU cache, use it */
|
||||||
|
@ -1950,7 +1858,7 @@ restart:
|
||||||
} else {
|
} else {
|
||||||
obj = spl_cache_refill(skc, skm, flags);
|
obj = spl_cache_refill(skc, skm, flags);
|
||||||
if (obj == NULL)
|
if (obj == NULL)
|
||||||
SGOTO(restart, obj = NULL);
|
goto restart;
|
||||||
}
|
}
|
||||||
|
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
|
@ -1968,7 +1876,7 @@ ret:
|
||||||
|
|
||||||
atomic_dec(&skc->skc_ref);
|
atomic_dec(&skc->skc_ref);
|
||||||
|
|
||||||
SRETURN(obj);
|
return (obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(spl_kmem_cache_alloc);
|
EXPORT_SYMBOL(spl_kmem_cache_alloc);
|
||||||
|
@ -1984,7 +1892,6 @@ spl_kmem_cache_free(spl_kmem_cache_t *skc, void *obj)
|
||||||
{
|
{
|
||||||
spl_kmem_magazine_t *skm;
|
spl_kmem_magazine_t *skm;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(skc->skc_magic == SKC_MAGIC);
|
ASSERT(skc->skc_magic == SKC_MAGIC);
|
||||||
ASSERT(!test_bit(KMC_BIT_DESTROY, &skc->skc_flags));
|
ASSERT(!test_bit(KMC_BIT_DESTROY, &skc->skc_flags));
|
||||||
|
@ -2009,8 +1916,10 @@ spl_kmem_cache_free(spl_kmem_cache_t *skc, void *obj)
|
||||||
* are guaranteed to have physical addresses. They must be removed
|
* are guaranteed to have physical addresses. They must be removed
|
||||||
* from the tree of emergency objects and the freed.
|
* from the tree of emergency objects and the freed.
|
||||||
*/
|
*/
|
||||||
if ((skc->skc_flags & KMC_VMEM) && !kmem_virt(obj))
|
if ((skc->skc_flags & KMC_VMEM) && !kmem_virt(obj)) {
|
||||||
SGOTO(out, spl_emergency_free(skc, obj));
|
spl_emergency_free(skc, obj);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
|
|
||||||
|
@ -2031,8 +1940,6 @@ spl_kmem_cache_free(spl_kmem_cache_t *skc, void *obj)
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
out:
|
out:
|
||||||
atomic_dec(&skc->skc_ref);
|
atomic_dec(&skc->skc_ref);
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(spl_kmem_cache_free);
|
EXPORT_SYMBOL(spl_kmem_cache_free);
|
||||||
|
|
||||||
|
@ -2113,8 +2020,6 @@ SPL_SHRINKER_CALLBACK_WRAPPER(spl_kmem_cache_generic_shrinker);
|
||||||
void
|
void
|
||||||
spl_kmem_cache_reap_now(spl_kmem_cache_t *skc, int count)
|
spl_kmem_cache_reap_now(spl_kmem_cache_t *skc, int count)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(skc->skc_magic == SKC_MAGIC);
|
ASSERT(skc->skc_magic == SKC_MAGIC);
|
||||||
ASSERT(!test_bit(KMC_BIT_DESTROY, &skc->skc_flags));
|
ASSERT(!test_bit(KMC_BIT_DESTROY, &skc->skc_flags));
|
||||||
|
|
||||||
|
@ -2131,14 +2036,14 @@ spl_kmem_cache_reap_now(spl_kmem_cache_t *skc, int count)
|
||||||
if (spl_kmem_cache_expire & KMC_EXPIRE_MEM)
|
if (spl_kmem_cache_expire & KMC_EXPIRE_MEM)
|
||||||
kmem_cache_shrink(skc->skc_linux_cache);
|
kmem_cache_shrink(skc->skc_linux_cache);
|
||||||
|
|
||||||
SGOTO(out, 0);
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prevent concurrent cache reaping when contended.
|
* Prevent concurrent cache reaping when contended.
|
||||||
*/
|
*/
|
||||||
if (test_and_set_bit(KMC_BIT_REAPING, &skc->skc_flags))
|
if (test_and_set_bit(KMC_BIT_REAPING, &skc->skc_flags))
|
||||||
SGOTO(out, 0);
|
goto out;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When a reclaim function is available it may be invoked repeatedly
|
* When a reclaim function is available it may be invoked repeatedly
|
||||||
|
@ -2190,8 +2095,6 @@ spl_kmem_cache_reap_now(spl_kmem_cache_t *skc, int count)
|
||||||
wake_up_bit(&skc->skc_flags, KMC_BIT_REAPING);
|
wake_up_bit(&skc->skc_flags, KMC_BIT_REAPING);
|
||||||
out:
|
out:
|
||||||
atomic_dec(&skc->skc_ref);
|
atomic_dec(&skc->skc_ref);
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(spl_kmem_cache_reap_now);
|
EXPORT_SYMBOL(spl_kmem_cache_reap_now);
|
||||||
|
|
||||||
|
@ -2256,7 +2159,6 @@ static int
|
||||||
spl_kmem_init_tracking(struct list_head *list, spinlock_t *lock, int size)
|
spl_kmem_init_tracking(struct list_head *list, spinlock_t *lock, int size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
spin_lock_init(lock);
|
spin_lock_init(lock);
|
||||||
INIT_LIST_HEAD(list);
|
INIT_LIST_HEAD(list);
|
||||||
|
@ -2264,7 +2166,7 @@ spl_kmem_init_tracking(struct list_head *list, spinlock_t *lock, int size)
|
||||||
for (i = 0; i < size; i++)
|
for (i = 0; i < size; i++)
|
||||||
INIT_HLIST_HEAD(&kmem_table[i]);
|
INIT_HLIST_HEAD(&kmem_table[i]);
|
||||||
|
|
||||||
SRETURN(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2273,7 +2175,6 @@ spl_kmem_fini_tracking(struct list_head *list, spinlock_t *lock)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
kmem_debug_t *kd;
|
kmem_debug_t *kd;
|
||||||
char str[17];
|
char str[17];
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
spin_lock_irqsave(lock, flags);
|
spin_lock_irqsave(lock, flags);
|
||||||
if (!list_empty(list))
|
if (!list_empty(list))
|
||||||
|
@ -2286,7 +2187,6 @@ spl_kmem_fini_tracking(struct list_head *list, spinlock_t *lock)
|
||||||
kd->kd_func, kd->kd_line);
|
kd->kd_func, kd->kd_line);
|
||||||
|
|
||||||
spin_unlock_irqrestore(lock, flags);
|
spin_unlock_irqrestore(lock, flags);
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
#else /* DEBUG_KMEM && DEBUG_KMEM_TRACKING */
|
#else /* DEBUG_KMEM && DEBUG_KMEM_TRACKING */
|
||||||
#define spl_kmem_init_tracking(list, lock, size)
|
#define spl_kmem_init_tracking(list, lock, size)
|
||||||
|
@ -2297,7 +2197,6 @@ int
|
||||||
spl_kmem_init(void)
|
spl_kmem_init(void)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
#ifdef DEBUG_KMEM
|
#ifdef DEBUG_KMEM
|
||||||
kmem_alloc_used_set(0);
|
kmem_alloc_used_set(0);
|
||||||
|
@ -2314,14 +2213,12 @@ spl_kmem_init(void)
|
||||||
|
|
||||||
spl_register_shrinker(&spl_kmem_cache_shrinker);
|
spl_register_shrinker(&spl_kmem_cache_shrinker);
|
||||||
|
|
||||||
SRETURN(rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
spl_kmem_fini(void)
|
spl_kmem_fini(void)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
spl_unregister_shrinker(&spl_kmem_cache_shrinker);
|
spl_unregister_shrinker(&spl_kmem_cache_shrinker);
|
||||||
taskq_destroy(spl_kmem_cache_taskq);
|
taskq_destroy(spl_kmem_cache_taskq);
|
||||||
|
|
||||||
|
@ -2331,19 +2228,14 @@ spl_kmem_fini(void)
|
||||||
* at that address to aid in debugging. Performance is not
|
* at that address to aid in debugging. Performance is not
|
||||||
* a serious concern here since it is module unload time. */
|
* a serious concern here since it is module unload time. */
|
||||||
if (kmem_alloc_used_read() != 0)
|
if (kmem_alloc_used_read() != 0)
|
||||||
SDEBUG_LIMIT(SD_CONSOLE | SD_WARNING,
|
printk(KERN_WARNING "kmem leaked %ld/%llu bytes\n",
|
||||||
"kmem leaked %ld/%ld bytes\n",
|
|
||||||
kmem_alloc_used_read(), kmem_alloc_max);
|
kmem_alloc_used_read(), kmem_alloc_max);
|
||||||
|
|
||||||
|
|
||||||
if (vmem_alloc_used_read() != 0)
|
if (vmem_alloc_used_read() != 0)
|
||||||
SDEBUG_LIMIT(SD_CONSOLE | SD_WARNING,
|
printk(KERN_WARNING "vmem leaked %ld/%llu bytes\n",
|
||||||
"vmem leaked %ld/%ld bytes\n",
|
|
||||||
vmem_alloc_used_read(), vmem_alloc_max);
|
vmem_alloc_used_read(), vmem_alloc_max);
|
||||||
|
|
||||||
spl_kmem_fini_tracking(&kmem_list, &kmem_lock);
|
spl_kmem_fini_tracking(&kmem_list, &kmem_lock);
|
||||||
spl_kmem_fini_tracking(&vmem_list, &vmem_lock);
|
spl_kmem_fini_tracking(&vmem_list, &vmem_lock);
|
||||||
#endif /* DEBUG_KMEM */
|
#endif /* DEBUG_KMEM */
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,13 +25,6 @@
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
#include <sys/kobj.h>
|
#include <sys/kobj.h>
|
||||||
#include <spl-debug.h>
|
|
||||||
|
|
||||||
#ifdef SS_DEBUG_SUBSYS
|
|
||||||
#undef SS_DEBUG_SUBSYS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SS_DEBUG_SUBSYS SS_KOBJ
|
|
||||||
|
|
||||||
struct _buf *
|
struct _buf *
|
||||||
kobj_open_file(const char *name)
|
kobj_open_file(const char *name)
|
||||||
|
@ -39,38 +32,34 @@ kobj_open_file(const char *name)
|
||||||
struct _buf *file;
|
struct _buf *file;
|
||||||
vnode_t *vp;
|
vnode_t *vp;
|
||||||
int rc;
|
int rc;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
file = kmalloc(sizeof(_buf_t), GFP_KERNEL);
|
file = kmalloc(sizeof(_buf_t), GFP_KERNEL);
|
||||||
if (file == NULL)
|
if (file == NULL)
|
||||||
SRETURN((_buf_t *)-1UL);
|
return ((_buf_t *)-1UL);
|
||||||
|
|
||||||
if ((rc = vn_open(name, UIO_SYSSPACE, FREAD, 0644, &vp, 0, 0))) {
|
if ((rc = vn_open(name, UIO_SYSSPACE, FREAD, 0644, &vp, 0, 0))) {
|
||||||
kfree(file);
|
kfree(file);
|
||||||
SRETURN((_buf_t *)-1UL);
|
return ((_buf_t *)-1UL);
|
||||||
}
|
}
|
||||||
|
|
||||||
file->vp = vp;
|
file->vp = vp;
|
||||||
|
|
||||||
SRETURN(file);
|
return (file);
|
||||||
} /* kobj_open_file() */
|
} /* kobj_open_file() */
|
||||||
EXPORT_SYMBOL(kobj_open_file);
|
EXPORT_SYMBOL(kobj_open_file);
|
||||||
|
|
||||||
void
|
void
|
||||||
kobj_close_file(struct _buf *file)
|
kobj_close_file(struct _buf *file)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
VOP_CLOSE(file->vp, 0, 0, 0, 0, 0);
|
VOP_CLOSE(file->vp, 0, 0, 0, 0, 0);
|
||||||
kfree(file);
|
kfree(file);
|
||||||
SEXIT;
|
|
||||||
} /* kobj_close_file() */
|
} /* kobj_close_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, ssize_t size, offset_t off)
|
||||||
{
|
{
|
||||||
SENTRY;
|
return (vn_rdwr(UIO_READ, file->vp, buf, size, off,
|
||||||
SRETURN(vn_rdwr(UIO_READ, file->vp, buf, size, off,
|
|
||||||
UIO_SYSSPACE, 0, RLIM64_INFINITY, 0, NULL));
|
UIO_SYSSPACE, 0, RLIM64_INFINITY, 0, NULL));
|
||||||
} /* kobj_read_file() */
|
} /* kobj_read_file() */
|
||||||
EXPORT_SYMBOL(kobj_read_file);
|
EXPORT_SYMBOL(kobj_read_file);
|
||||||
|
@ -80,14 +69,13 @@ kobj_get_filesize(struct _buf *file, uint64_t *size)
|
||||||
{
|
{
|
||||||
vattr_t vap;
|
vattr_t vap;
|
||||||
int rc;
|
int rc;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
rc = VOP_GETATTR(file->vp, &vap, 0, 0, NULL);
|
rc = VOP_GETATTR(file->vp, &vap, 0, 0, NULL);
|
||||||
if (rc)
|
if (rc)
|
||||||
SRETURN(rc);
|
return (rc);
|
||||||
|
|
||||||
*size = vap.va_size;
|
*size = vap.va_size;
|
||||||
|
|
||||||
SRETURN(rc);
|
return (rc);
|
||||||
} /* kobj_get_filesize() */
|
} /* kobj_get_filesize() */
|
||||||
EXPORT_SYMBOL(kobj_get_filesize);
|
EXPORT_SYMBOL(kobj_get_filesize);
|
||||||
|
|
|
@ -26,13 +26,7 @@
|
||||||
|
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <sys/kstat.h>
|
#include <sys/kstat.h>
|
||||||
#include <spl-debug.h>
|
|
||||||
|
|
||||||
#ifdef SS_DEBUG_SUBSYS
|
|
||||||
#undef SS_DEBUG_SUBSYS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SS_DEBUG_SUBSYS SS_KSTAT
|
|
||||||
#ifndef HAVE_PDE_DATA
|
#ifndef HAVE_PDE_DATA
|
||||||
#define PDE_DATA(x) (PDE(x)->data)
|
#define PDE_DATA(x) (PDE(x)->data)
|
||||||
#endif
|
#endif
|
||||||
|
@ -344,7 +338,6 @@ static void *
|
||||||
kstat_seq_data_addr(kstat_t *ksp, loff_t n)
|
kstat_seq_data_addr(kstat_t *ksp, loff_t n)
|
||||||
{
|
{
|
||||||
void *rc = NULL;
|
void *rc = NULL;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
switch (ksp->ks_type) {
|
switch (ksp->ks_type) {
|
||||||
case KSTAT_TYPE_RAW:
|
case KSTAT_TYPE_RAW:
|
||||||
|
@ -369,7 +362,7 @@ kstat_seq_data_addr(kstat_t *ksp, loff_t n)
|
||||||
PANIC("Undefined kstat type %d\n", ksp->ks_type);
|
PANIC("Undefined kstat type %d\n", ksp->ks_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
SRETURN(rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
|
@ -378,7 +371,6 @@ kstat_seq_start(struct seq_file *f, loff_t *pos)
|
||||||
loff_t n = *pos;
|
loff_t n = *pos;
|
||||||
kstat_t *ksp = (kstat_t *)f->private;
|
kstat_t *ksp = (kstat_t *)f->private;
|
||||||
ASSERT(ksp->ks_magic == KS_MAGIC);
|
ASSERT(ksp->ks_magic == KS_MAGIC);
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
mutex_enter(ksp->ks_lock);
|
mutex_enter(ksp->ks_lock);
|
||||||
|
|
||||||
|
@ -393,12 +385,12 @@ kstat_seq_start(struct seq_file *f, loff_t *pos)
|
||||||
ksp->ks_snaptime = gethrtime();
|
ksp->ks_snaptime = gethrtime();
|
||||||
|
|
||||||
if (!n && kstat_seq_show_headers(f))
|
if (!n && kstat_seq_show_headers(f))
|
||||||
SRETURN(NULL);
|
return (NULL);
|
||||||
|
|
||||||
if (n >= ksp->ks_ndata)
|
if (n >= ksp->ks_ndata)
|
||||||
SRETURN(NULL);
|
return (NULL);
|
||||||
|
|
||||||
SRETURN(kstat_seq_data_addr(ksp, n));
|
return (kstat_seq_data_addr(ksp, n));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
|
@ -406,13 +398,12 @@ kstat_seq_next(struct seq_file *f, void *p, loff_t *pos)
|
||||||
{
|
{
|
||||||
kstat_t *ksp = (kstat_t *)f->private;
|
kstat_t *ksp = (kstat_t *)f->private;
|
||||||
ASSERT(ksp->ks_magic == KS_MAGIC);
|
ASSERT(ksp->ks_magic == KS_MAGIC);
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
++*pos;
|
++*pos;
|
||||||
if (*pos >= ksp->ks_ndata)
|
if (*pos >= ksp->ks_ndata)
|
||||||
SRETURN(NULL);
|
return (NULL);
|
||||||
|
|
||||||
SRETURN(kstat_seq_data_addr(ksp, *pos));
|
return (kstat_seq_data_addr(ksp, *pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -689,19 +680,16 @@ EXPORT_SYMBOL(__kstat_delete);
|
||||||
int
|
int
|
||||||
spl_kstat_init(void)
|
spl_kstat_init(void)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
mutex_init(&kstat_module_lock, NULL, MUTEX_DEFAULT, NULL);
|
mutex_init(&kstat_module_lock, NULL, MUTEX_DEFAULT, NULL);
|
||||||
INIT_LIST_HEAD(&kstat_module_list);
|
INIT_LIST_HEAD(&kstat_module_list);
|
||||||
kstat_id = 0;
|
kstat_id = 0;
|
||||||
SRETURN(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
spl_kstat_fini(void)
|
spl_kstat_fini(void)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
ASSERT(list_empty(&kstat_module_list));
|
ASSERT(list_empty(&kstat_module_list));
|
||||||
mutex_destroy(&kstat_module_lock);
|
mutex_destroy(&kstat_module_lock);
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,13 +30,6 @@
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/proc_compat.h>
|
#include <linux/proc_compat.h>
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
#include <spl-debug.h>
|
|
||||||
|
|
||||||
#ifdef SS_DEBUG_SUBSYS
|
|
||||||
#undef SS_DEBUG_SUBSYS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SS_DEBUG_SUBSYS SS_PROC
|
|
||||||
|
|
||||||
#if defined(CONSTIFY_PLUGIN) && LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
|
#if defined(CONSTIFY_PLUGIN) && LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
|
||||||
typedef struct ctl_table __no_const spl_ctl_table;
|
typedef struct ctl_table __no_const spl_ctl_table;
|
||||||
|
@ -110,209 +103,6 @@ proc_copyout_string(char *ubuffer, int ubuffer_size,
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_LOG
|
|
||||||
static int
|
|
||||||
proc_dobitmasks(struct ctl_table *table, int write,
|
|
||||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
|
||||||
{
|
|
||||||
unsigned long *mask = table->data;
|
|
||||||
int is_subsys = (mask == &spl_debug_subsys) ? 1 : 0;
|
|
||||||
int is_printk = (mask == &spl_debug_printk) ? 1 : 0;
|
|
||||||
int size = 512, rc;
|
|
||||||
char *str;
|
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
str = kmem_alloc(size, KM_SLEEP);
|
|
||||||
if (str == NULL)
|
|
||||||
SRETURN(-ENOMEM);
|
|
||||||
|
|
||||||
if (write) {
|
|
||||||
rc = proc_copyin_string(str, size, buffer, *lenp);
|
|
||||||
if (rc < 0)
|
|
||||||
SRETURN(rc);
|
|
||||||
|
|
||||||
rc = spl_debug_str2mask(mask, str, is_subsys);
|
|
||||||
/* Always print BUG/ASSERT to console, so keep this mask */
|
|
||||||
if (is_printk)
|
|
||||||
*mask |= SD_EMERG;
|
|
||||||
|
|
||||||
*ppos += *lenp;
|
|
||||||
} else {
|
|
||||||
rc = spl_debug_mask2str(str, size, *mask, is_subsys);
|
|
||||||
if (*ppos >= rc)
|
|
||||||
rc = 0;
|
|
||||||
else
|
|
||||||
rc = proc_copyout_string(buffer, *lenp,
|
|
||||||
str + *ppos, "\n");
|
|
||||||
if (rc >= 0) {
|
|
||||||
*lenp = rc;
|
|
||||||
*ppos += rc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
kmem_free(str, size);
|
|
||||||
SRETURN(rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
proc_debug_mb(struct ctl_table *table, int write,
|
|
||||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
|
||||||
{
|
|
||||||
char str[32];
|
|
||||||
int rc, len;
|
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
if (write) {
|
|
||||||
rc = proc_copyin_string(str, sizeof(str), buffer, *lenp);
|
|
||||||
if (rc < 0)
|
|
||||||
SRETURN(rc);
|
|
||||||
|
|
||||||
rc = spl_debug_set_mb(simple_strtoul(str, NULL, 0));
|
|
||||||
*ppos += *lenp;
|
|
||||||
} else {
|
|
||||||
len = snprintf(str, sizeof(str), "%d", spl_debug_get_mb());
|
|
||||||
if (*ppos >= len)
|
|
||||||
rc = 0;
|
|
||||||
else
|
|
||||||
rc = proc_copyout_string(buffer,*lenp,str+*ppos,"\n");
|
|
||||||
|
|
||||||
if (rc >= 0) {
|
|
||||||
*lenp = rc;
|
|
||||||
*ppos += rc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SRETURN(rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
proc_dump_kernel(struct ctl_table *table, int write,
|
|
||||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
|
||||||
{
|
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
if (write) {
|
|
||||||
spl_debug_dumplog(0);
|
|
||||||
*ppos += *lenp;
|
|
||||||
} else {
|
|
||||||
*lenp = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SRETURN(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
proc_force_bug(struct ctl_table *table, int write,
|
|
||||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
|
||||||
{
|
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
if (write)
|
|
||||||
PANIC("Crashing due to forced panic\n");
|
|
||||||
else
|
|
||||||
*lenp = 0;
|
|
||||||
|
|
||||||
SRETURN(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
proc_console_max_delay_cs(struct ctl_table *table, int write,
|
|
||||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
|
||||||
{
|
|
||||||
int rc, max_delay_cs;
|
|
||||||
spl_ctl_table dummy = *table;
|
|
||||||
long d;
|
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
dummy.data = &max_delay_cs;
|
|
||||||
dummy.proc_handler = &proc_dointvec;
|
|
||||||
|
|
||||||
if (write) {
|
|
||||||
max_delay_cs = 0;
|
|
||||||
rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
|
|
||||||
if (rc < 0)
|
|
||||||
SRETURN(rc);
|
|
||||||
|
|
||||||
if (max_delay_cs <= 0)
|
|
||||||
SRETURN(-EINVAL);
|
|
||||||
|
|
||||||
d = (max_delay_cs * HZ) / 100;
|
|
||||||
if (d == 0 || d < spl_console_min_delay)
|
|
||||||
SRETURN(-EINVAL);
|
|
||||||
|
|
||||||
spl_console_max_delay = d;
|
|
||||||
} else {
|
|
||||||
max_delay_cs = (spl_console_max_delay * 100) / HZ;
|
|
||||||
rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
|
|
||||||
}
|
|
||||||
|
|
||||||
SRETURN(rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
proc_console_min_delay_cs(struct ctl_table *table, int write,
|
|
||||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
|
||||||
{
|
|
||||||
int rc, min_delay_cs;
|
|
||||||
spl_ctl_table dummy = *table;
|
|
||||||
long d;
|
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
dummy.data = &min_delay_cs;
|
|
||||||
dummy.proc_handler = &proc_dointvec;
|
|
||||||
|
|
||||||
if (write) {
|
|
||||||
min_delay_cs = 0;
|
|
||||||
rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
|
|
||||||
if (rc < 0)
|
|
||||||
SRETURN(rc);
|
|
||||||
|
|
||||||
if (min_delay_cs <= 0)
|
|
||||||
SRETURN(-EINVAL);
|
|
||||||
|
|
||||||
d = (min_delay_cs * HZ) / 100;
|
|
||||||
if (d == 0 || d > spl_console_max_delay)
|
|
||||||
SRETURN(-EINVAL);
|
|
||||||
|
|
||||||
spl_console_min_delay = d;
|
|
||||||
} else {
|
|
||||||
min_delay_cs = (spl_console_min_delay * 100) / HZ;
|
|
||||||
rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
|
|
||||||
}
|
|
||||||
|
|
||||||
SRETURN(rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
proc_console_backoff(struct ctl_table *table, int write,
|
|
||||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
|
||||||
{
|
|
||||||
int rc, backoff;
|
|
||||||
spl_ctl_table dummy = *table;
|
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
dummy.data = &backoff;
|
|
||||||
dummy.proc_handler = &proc_dointvec;
|
|
||||||
|
|
||||||
if (write) {
|
|
||||||
backoff = 0;
|
|
||||||
rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
|
|
||||||
if (rc < 0)
|
|
||||||
SRETURN(rc);
|
|
||||||
|
|
||||||
if (backoff <= 0)
|
|
||||||
SRETURN(-EINVAL);
|
|
||||||
|
|
||||||
spl_console_backoff = backoff;
|
|
||||||
} else {
|
|
||||||
backoff = spl_console_backoff;
|
|
||||||
rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
|
|
||||||
}
|
|
||||||
|
|
||||||
SRETURN(rc);
|
|
||||||
}
|
|
||||||
#endif /* DEBUG_LOG */
|
|
||||||
|
|
||||||
#ifdef DEBUG_KMEM
|
#ifdef DEBUG_KMEM
|
||||||
static int
|
static int
|
||||||
proc_domemused(struct ctl_table *table, int write,
|
proc_domemused(struct ctl_table *table, int write,
|
||||||
|
@ -321,7 +111,6 @@ proc_domemused(struct ctl_table *table, int write,
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
unsigned long min = 0, max = ~0, val;
|
unsigned long min = 0, max = ~0, val;
|
||||||
spl_ctl_table dummy = *table;
|
spl_ctl_table dummy = *table;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
dummy.data = &val;
|
dummy.data = &val;
|
||||||
dummy.proc_handler = &proc_dointvec;
|
dummy.proc_handler = &proc_dointvec;
|
||||||
|
@ -339,7 +128,7 @@ proc_domemused(struct ctl_table *table, int write,
|
||||||
rc = proc_doulongvec_minmax(&dummy, write, buffer, lenp, ppos);
|
rc = proc_doulongvec_minmax(&dummy, write, buffer, lenp, ppos);
|
||||||
}
|
}
|
||||||
|
|
||||||
SRETURN(rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -350,7 +139,6 @@ proc_doslab(struct ctl_table *table, int write,
|
||||||
unsigned long min = 0, max = ~0, val = 0, mask;
|
unsigned long min = 0, max = ~0, val = 0, mask;
|
||||||
spl_ctl_table dummy = *table;
|
spl_ctl_table dummy = *table;
|
||||||
spl_kmem_cache_t *skc;
|
spl_kmem_cache_t *skc;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
dummy.data = &val;
|
dummy.data = &val;
|
||||||
dummy.proc_handler = &proc_dointvec;
|
dummy.proc_handler = &proc_dointvec;
|
||||||
|
@ -387,7 +175,7 @@ proc_doslab(struct ctl_table *table, int write,
|
||||||
rc = proc_doulongvec_minmax(&dummy, write, buffer, lenp, ppos);
|
rc = proc_doulongvec_minmax(&dummy, write, buffer, lenp, ppos);
|
||||||
}
|
}
|
||||||
|
|
||||||
SRETURN(rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
#endif /* DEBUG_KMEM */
|
#endif /* DEBUG_KMEM */
|
||||||
|
|
||||||
|
@ -397,7 +185,6 @@ proc_dohostid(struct ctl_table *table, int write,
|
||||||
{
|
{
|
||||||
int len, rc = 0;
|
int len, rc = 0;
|
||||||
char *end, str[32];
|
char *end, str[32];
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
if (write) {
|
if (write) {
|
||||||
/* We can't use proc_doulongvec_minmax() in the write
|
/* We can't use proc_doulongvec_minmax() in the write
|
||||||
|
@ -405,11 +192,11 @@ proc_dohostid(struct ctl_table *table, int write,
|
||||||
* leading 0x which confuses the helper function. */
|
* leading 0x which confuses the helper function. */
|
||||||
rc = proc_copyin_string(str, sizeof(str), buffer, *lenp);
|
rc = proc_copyin_string(str, sizeof(str), buffer, *lenp);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
SRETURN(rc);
|
return (rc);
|
||||||
|
|
||||||
spl_hostid = simple_strtoul(str, &end, 16);
|
spl_hostid = simple_strtoul(str, &end, 16);
|
||||||
if (str == end)
|
if (str == end)
|
||||||
SRETURN(-EINVAL);
|
return (-EINVAL);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
len = snprintf(str, sizeof(str), "%lx", spl_hostid);
|
len = snprintf(str, sizeof(str), "%lx", spl_hostid);
|
||||||
|
@ -424,7 +211,7 @@ proc_dohostid(struct ctl_table *table, int write,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SRETURN(rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_KMEM
|
#ifdef DEBUG_KMEM
|
||||||
|
@ -487,7 +274,6 @@ slab_seq_start(struct seq_file *f, loff_t *pos)
|
||||||
{
|
{
|
||||||
struct list_head *p;
|
struct list_head *p;
|
||||||
loff_t n = *pos;
|
loff_t n = *pos;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
down_read(&spl_kmem_cache_sem);
|
down_read(&spl_kmem_cache_sem);
|
||||||
if (!n)
|
if (!n)
|
||||||
|
@ -497,20 +283,19 @@ slab_seq_start(struct seq_file *f, loff_t *pos)
|
||||||
while (n--) {
|
while (n--) {
|
||||||
p = p->next;
|
p = p->next;
|
||||||
if (p == &spl_kmem_cache_list)
|
if (p == &spl_kmem_cache_list)
|
||||||
SRETURN(NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
SRETURN(list_entry(p, spl_kmem_cache_t, skc_list));
|
return (list_entry(p, spl_kmem_cache_t, skc_list));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
slab_seq_next(struct seq_file *f, void *p, loff_t *pos)
|
slab_seq_next(struct seq_file *f, void *p, loff_t *pos)
|
||||||
{
|
{
|
||||||
spl_kmem_cache_t *skc = p;
|
spl_kmem_cache_t *skc = p;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
++*pos;
|
++*pos;
|
||||||
SRETURN((skc->skc_list.next == &spl_kmem_cache_list) ?
|
return ((skc->skc_list.next == &spl_kmem_cache_list) ?
|
||||||
NULL : list_entry(skc->skc_list.next,spl_kmem_cache_t,skc_list));
|
NULL : list_entry(skc->skc_list.next,spl_kmem_cache_t,skc_list));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -541,108 +326,6 @@ static struct file_operations proc_slab_operations = {
|
||||||
};
|
};
|
||||||
#endif /* DEBUG_KMEM */
|
#endif /* DEBUG_KMEM */
|
||||||
|
|
||||||
#ifdef DEBUG_LOG
|
|
||||||
static struct ctl_table spl_debug_table[] = {
|
|
||||||
{
|
|
||||||
.procname = "subsystem",
|
|
||||||
.data = &spl_debug_subsys,
|
|
||||||
.maxlen = sizeof(unsigned long),
|
|
||||||
.mode = 0644,
|
|
||||||
.proc_handler = &proc_dobitmasks
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.procname = "mask",
|
|
||||||
.data = &spl_debug_mask,
|
|
||||||
.maxlen = sizeof(unsigned long),
|
|
||||||
.mode = 0644,
|
|
||||||
.proc_handler = &proc_dobitmasks
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.procname = "printk",
|
|
||||||
.data = &spl_debug_printk,
|
|
||||||
.maxlen = sizeof(unsigned long),
|
|
||||||
.mode = 0644,
|
|
||||||
.proc_handler = &proc_dobitmasks
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.procname = "mb",
|
|
||||||
.mode = 0644,
|
|
||||||
.proc_handler = &proc_debug_mb,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.procname = "binary",
|
|
||||||
.data = &spl_debug_binary,
|
|
||||||
.maxlen = sizeof(int),
|
|
||||||
.mode = 0644,
|
|
||||||
.proc_handler = &proc_dointvec,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.procname = "catastrophe",
|
|
||||||
.data = &spl_debug_catastrophe,
|
|
||||||
.maxlen = sizeof(int),
|
|
||||||
.mode = 0444,
|
|
||||||
.proc_handler = &proc_dointvec,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.procname = "panic_on_bug",
|
|
||||||
.data = &spl_debug_panic_on_bug,
|
|
||||||
.maxlen = sizeof(int),
|
|
||||||
.mode = 0644,
|
|
||||||
.proc_handler = &proc_dointvec
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.procname = "path",
|
|
||||||
.data = spl_debug_file_path,
|
|
||||||
.maxlen = sizeof(spl_debug_file_path),
|
|
||||||
.mode = 0644,
|
|
||||||
.proc_handler = &proc_dostring,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.procname = "dump",
|
|
||||||
.mode = 0200,
|
|
||||||
.proc_handler = &proc_dump_kernel,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.procname = "force_bug",
|
|
||||||
.mode = 0200,
|
|
||||||
.proc_handler = &proc_force_bug,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.procname = "console_ratelimit",
|
|
||||||
.data = &spl_console_ratelimit,
|
|
||||||
.maxlen = sizeof(int),
|
|
||||||
.mode = 0644,
|
|
||||||
.proc_handler = &proc_dointvec,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.procname = "console_max_delay_centisecs",
|
|
||||||
.maxlen = sizeof(int),
|
|
||||||
.mode = 0644,
|
|
||||||
.proc_handler = &proc_console_max_delay_cs,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.procname = "console_min_delay_centisecs",
|
|
||||||
.maxlen = sizeof(int),
|
|
||||||
.mode = 0644,
|
|
||||||
.proc_handler = &proc_console_min_delay_cs,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.procname = "console_backoff",
|
|
||||||
.maxlen = sizeof(int),
|
|
||||||
.mode = 0644,
|
|
||||||
.proc_handler = &proc_console_backoff,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.procname = "stack_max",
|
|
||||||
.data = &spl_debug_stack,
|
|
||||||
.maxlen = sizeof(int),
|
|
||||||
.mode = 0444,
|
|
||||||
.proc_handler = &proc_dointvec,
|
|
||||||
},
|
|
||||||
{0},
|
|
||||||
};
|
|
||||||
#endif /* DEBUG_LOG */
|
|
||||||
|
|
||||||
#ifdef DEBUG_KMEM
|
#ifdef DEBUG_KMEM
|
||||||
static struct ctl_table spl_kmem_table[] = {
|
static struct ctl_table spl_kmem_table[] = {
|
||||||
{
|
{
|
||||||
|
@ -765,13 +448,6 @@ static struct ctl_table spl_table[] = {
|
||||||
.mode = 0644,
|
.mode = 0644,
|
||||||
.proc_handler = &proc_dohostid,
|
.proc_handler = &proc_dohostid,
|
||||||
},
|
},
|
||||||
#ifdef DEBUG_LOG
|
|
||||||
{
|
|
||||||
.procname = "debug",
|
|
||||||
.mode = 0555,
|
|
||||||
.child = spl_debug_table,
|
|
||||||
},
|
|
||||||
#endif
|
|
||||||
#ifdef DEBUG_KMEM
|
#ifdef DEBUG_KMEM
|
||||||
{
|
{
|
||||||
.procname = "kmem",
|
.procname = "kmem",
|
||||||
|
@ -812,31 +488,38 @@ int
|
||||||
spl_proc_init(void)
|
spl_proc_init(void)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
spl_header = register_sysctl_table(spl_root);
|
spl_header = register_sysctl_table(spl_root);
|
||||||
if (spl_header == NULL)
|
if (spl_header == NULL)
|
||||||
SRETURN(-EUNATCH);
|
return (-EUNATCH);
|
||||||
|
|
||||||
proc_spl = proc_mkdir("spl", NULL);
|
proc_spl = proc_mkdir("spl", NULL);
|
||||||
if (proc_spl == NULL)
|
if (proc_spl == NULL) {
|
||||||
SGOTO(out, rc = -EUNATCH);
|
rc = -EUNATCH;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_KMEM
|
#ifdef DEBUG_KMEM
|
||||||
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) {
|
||||||
SGOTO(out, rc = -EUNATCH);
|
rc = -EUNATCH;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
proc_spl_kmem_slab = proc_create_data("slab", 0444,
|
proc_spl_kmem_slab = proc_create_data("slab", 0444,
|
||||||
proc_spl_kmem, &proc_slab_operations, NULL);
|
proc_spl_kmem, &proc_slab_operations, NULL);
|
||||||
if (proc_spl_kmem_slab == NULL)
|
if (proc_spl_kmem_slab == NULL) {
|
||||||
SGOTO(out, rc = -EUNATCH);
|
rc = -EUNATCH;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* DEBUG_KMEM */
|
#endif /* DEBUG_KMEM */
|
||||||
|
|
||||||
proc_spl_kstat = proc_mkdir("kstat", proc_spl);
|
proc_spl_kstat = proc_mkdir("kstat", proc_spl);
|
||||||
if (proc_spl_kstat == NULL)
|
if (proc_spl_kstat == NULL) {
|
||||||
SGOTO(out, rc = -EUNATCH);
|
rc = -EUNATCH;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
out:
|
out:
|
||||||
if (rc) {
|
if (rc) {
|
||||||
remove_proc_entry("kstat", proc_spl);
|
remove_proc_entry("kstat", proc_spl);
|
||||||
|
@ -848,14 +531,12 @@ out:
|
||||||
unregister_sysctl_table(spl_header);
|
unregister_sysctl_table(spl_header);
|
||||||
}
|
}
|
||||||
|
|
||||||
SRETURN(rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
spl_proc_fini(void)
|
spl_proc_fini(void)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
remove_proc_entry("kstat", proc_spl);
|
remove_proc_entry("kstat", proc_spl);
|
||||||
#ifdef DEBUG_KMEM
|
#ifdef DEBUG_KMEM
|
||||||
remove_proc_entry("slab", proc_spl_kmem);
|
remove_proc_entry("slab", proc_spl_kmem);
|
||||||
|
@ -865,6 +546,4 @@ spl_proc_fini(void)
|
||||||
|
|
||||||
ASSERT(spl_header != NULL);
|
ASSERT(spl_header != NULL);
|
||||||
unregister_sysctl_table(spl_header);
|
unregister_sysctl_table(spl_header);
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,13 +26,6 @@
|
||||||
|
|
||||||
#include <sys/taskq.h>
|
#include <sys/taskq.h>
|
||||||
#include <sys/kmem.h>
|
#include <sys/kmem.h>
|
||||||
#include <spl-debug.h>
|
|
||||||
|
|
||||||
#ifdef SS_DEBUG_SUBSYS
|
|
||||||
#undef SS_DEBUG_SUBSYS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SS_DEBUG_SUBSYS SS_TASKQ
|
|
||||||
|
|
||||||
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);
|
||||||
|
@ -63,7 +56,6 @@ task_alloc(taskq_t *tq, uint_t flags)
|
||||||
{
|
{
|
||||||
taskq_ent_t *t;
|
taskq_ent_t *t;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(tq);
|
ASSERT(tq);
|
||||||
ASSERT(spin_is_locked(&tq->tq_lock));
|
ASSERT(spin_is_locked(&tq->tq_lock));
|
||||||
|
@ -77,17 +69,17 @@ retry:
|
||||||
ASSERT(!timer_pending(&t->tqent_timer));
|
ASSERT(!timer_pending(&t->tqent_timer));
|
||||||
|
|
||||||
list_del_init(&t->tqent_list);
|
list_del_init(&t->tqent_list);
|
||||||
SRETURN(t);
|
return (t);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free list is empty and memory allocations are prohibited */
|
/* Free list is empty and memory allocations are prohibited */
|
||||||
if (flags & TQ_NOALLOC)
|
if (flags & TQ_NOALLOC)
|
||||||
SRETURN(NULL);
|
return (NULL);
|
||||||
|
|
||||||
/* Hit maximum taskq_ent_t pool size */
|
/* Hit maximum taskq_ent_t pool size */
|
||||||
if (tq->tq_nalloc >= tq->tq_maxalloc) {
|
if (tq->tq_nalloc >= tq->tq_maxalloc) {
|
||||||
if (flags & TQ_NOSLEEP)
|
if (flags & TQ_NOSLEEP)
|
||||||
SRETURN(NULL);
|
return (NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sleep periodically polling the free list for an available
|
* Sleep periodically polling the free list for an available
|
||||||
|
@ -103,8 +95,10 @@ retry:
|
||||||
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
|
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
|
||||||
schedule_timeout(HZ / 100);
|
schedule_timeout(HZ / 100);
|
||||||
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
|
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
|
||||||
if (count < 100)
|
if (count < 100) {
|
||||||
SGOTO(retry, count++);
|
count++;
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
|
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
|
||||||
|
@ -116,7 +110,7 @@ retry:
|
||||||
tq->tq_nalloc++;
|
tq->tq_nalloc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRETURN(t);
|
return (t);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -126,8 +120,6 @@ retry:
|
||||||
static void
|
static void
|
||||||
task_free(taskq_t *tq, taskq_ent_t *t)
|
task_free(taskq_t *tq, taskq_ent_t *t)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(tq);
|
ASSERT(tq);
|
||||||
ASSERT(t);
|
ASSERT(t);
|
||||||
ASSERT(spin_is_locked(&tq->tq_lock));
|
ASSERT(spin_is_locked(&tq->tq_lock));
|
||||||
|
@ -136,8 +128,6 @@ task_free(taskq_t *tq, taskq_ent_t *t)
|
||||||
|
|
||||||
kmem_free(t, sizeof(taskq_ent_t));
|
kmem_free(t, sizeof(taskq_ent_t));
|
||||||
tq->tq_nalloc--;
|
tq->tq_nalloc--;
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -147,7 +137,6 @@ task_free(taskq_t *tq, taskq_ent_t *t)
|
||||||
static void
|
static void
|
||||||
task_done(taskq_t *tq, taskq_ent_t *t)
|
task_done(taskq_t *tq, taskq_ent_t *t)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
ASSERT(tq);
|
ASSERT(tq);
|
||||||
ASSERT(t);
|
ASSERT(t);
|
||||||
ASSERT(spin_is_locked(&tq->tq_lock));
|
ASSERT(spin_is_locked(&tq->tq_lock));
|
||||||
|
@ -167,8 +156,6 @@ task_done(taskq_t *tq, taskq_ent_t *t)
|
||||||
} else {
|
} else {
|
||||||
task_free(tq, t);
|
task_free(tq, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -222,7 +209,6 @@ taskq_lowest_id(taskq_t *tq)
|
||||||
taskqid_t lowest_id = tq->tq_next_id;
|
taskqid_t lowest_id = tq->tq_next_id;
|
||||||
taskq_ent_t *t;
|
taskq_ent_t *t;
|
||||||
taskq_thread_t *tqt;
|
taskq_thread_t *tqt;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(tq);
|
ASSERT(tq);
|
||||||
ASSERT(spin_is_locked(&tq->tq_lock));
|
ASSERT(spin_is_locked(&tq->tq_lock));
|
||||||
|
@ -249,7 +235,7 @@ taskq_lowest_id(taskq_t *tq)
|
||||||
lowest_id = MIN(lowest_id, tqt->tqt_id);
|
lowest_id = MIN(lowest_id, tqt->tqt_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
SRETURN(lowest_id);
|
return (lowest_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -261,7 +247,6 @@ taskq_insert_in_order(taskq_t *tq, taskq_thread_t *tqt)
|
||||||
taskq_thread_t *w;
|
taskq_thread_t *w;
|
||||||
struct list_head *l;
|
struct list_head *l;
|
||||||
|
|
||||||
SENTRY;
|
|
||||||
ASSERT(tq);
|
ASSERT(tq);
|
||||||
ASSERT(tqt);
|
ASSERT(tqt);
|
||||||
ASSERT(spin_is_locked(&tq->tq_lock));
|
ASSERT(spin_is_locked(&tq->tq_lock));
|
||||||
|
@ -275,8 +260,6 @@ taskq_insert_in_order(taskq_t *tq, taskq_thread_t *tqt)
|
||||||
}
|
}
|
||||||
if (l == &tq->tq_active_list)
|
if (l == &tq->tq_active_list)
|
||||||
list_add(&tqt->tqt_active_list, &tq->tq_active_list);
|
list_add(&tqt->tqt_active_list, &tq->tq_active_list);
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -288,7 +271,6 @@ taskq_find_list(taskq_t *tq, struct list_head *lh, taskqid_t id)
|
||||||
{
|
{
|
||||||
struct list_head *l;
|
struct list_head *l;
|
||||||
taskq_ent_t *t;
|
taskq_ent_t *t;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(spin_is_locked(&tq->tq_lock));
|
ASSERT(spin_is_locked(&tq->tq_lock));
|
||||||
|
|
||||||
|
@ -296,13 +278,13 @@ taskq_find_list(taskq_t *tq, struct list_head *lh, taskqid_t id)
|
||||||
t = list_entry(l, taskq_ent_t, tqent_list);
|
t = list_entry(l, taskq_ent_t, tqent_list);
|
||||||
|
|
||||||
if (t->tqent_id == id)
|
if (t->tqent_id == id)
|
||||||
SRETURN(t);
|
return (t);
|
||||||
|
|
||||||
if (t->tqent_id > id)
|
if (t->tqent_id > id)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRETURN(NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -317,33 +299,32 @@ taskq_find(taskq_t *tq, taskqid_t id, int *active)
|
||||||
taskq_thread_t *tqt;
|
taskq_thread_t *tqt;
|
||||||
struct list_head *l;
|
struct list_head *l;
|
||||||
taskq_ent_t *t;
|
taskq_ent_t *t;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(spin_is_locked(&tq->tq_lock));
|
ASSERT(spin_is_locked(&tq->tq_lock));
|
||||||
*active = 0;
|
*active = 0;
|
||||||
|
|
||||||
t = taskq_find_list(tq, &tq->tq_delay_list, id);
|
t = taskq_find_list(tq, &tq->tq_delay_list, id);
|
||||||
if (t)
|
if (t)
|
||||||
SRETURN(t);
|
return (t);
|
||||||
|
|
||||||
t = taskq_find_list(tq, &tq->tq_prio_list, id);
|
t = taskq_find_list(tq, &tq->tq_prio_list, id);
|
||||||
if (t)
|
if (t)
|
||||||
SRETURN(t);
|
return (t);
|
||||||
|
|
||||||
t = taskq_find_list(tq, &tq->tq_pend_list, id);
|
t = taskq_find_list(tq, &tq->tq_pend_list, id);
|
||||||
if (t)
|
if (t)
|
||||||
SRETURN(t);
|
return (t);
|
||||||
|
|
||||||
list_for_each(l, &tq->tq_active_list) {
|
list_for_each(l, &tq->tq_active_list) {
|
||||||
tqt = list_entry(l, taskq_thread_t, tqt_active_list);
|
tqt = list_entry(l, taskq_thread_t, tqt_active_list);
|
||||||
if (tqt->tqt_id == id) {
|
if (tqt->tqt_id == id) {
|
||||||
t = tqt->tqt_task;
|
t = tqt->tqt_task;
|
||||||
*active = 1;
|
*active = 1;
|
||||||
SRETURN(t);
|
return (t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SRETURN(NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -405,7 +386,7 @@ taskq_wait_check(taskq_t *tq, taskqid_t id)
|
||||||
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, tq->tq_lock_flags);
|
||||||
|
|
||||||
SRETURN(rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -419,7 +400,7 @@ void
|
||||||
taskq_wait(taskq_t *tq)
|
taskq_wait(taskq_t *tq)
|
||||||
{
|
{
|
||||||
taskqid_t id;
|
taskqid_t id;
|
||||||
SENTRY;
|
|
||||||
ASSERT(tq);
|
ASSERT(tq);
|
||||||
|
|
||||||
/* Wait for the largest outstanding taskqid */
|
/* Wait for the largest outstanding taskqid */
|
||||||
|
@ -428,9 +409,6 @@ taskq_wait(taskq_t *tq)
|
||||||
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
|
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
|
||||||
|
|
||||||
taskq_wait_all(tq, id);
|
taskq_wait_all(tq, id);
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(taskq_wait);
|
EXPORT_SYMBOL(taskq_wait);
|
||||||
|
|
||||||
|
@ -439,7 +417,6 @@ taskq_member(taskq_t *tq, void *t)
|
||||||
{
|
{
|
||||||
struct list_head *l;
|
struct list_head *l;
|
||||||
taskq_thread_t *tqt;
|
taskq_thread_t *tqt;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(tq);
|
ASSERT(tq);
|
||||||
ASSERT(t);
|
ASSERT(t);
|
||||||
|
@ -447,10 +424,10 @@ taskq_member(taskq_t *tq, void *t)
|
||||||
list_for_each(l, &tq->tq_thread_list) {
|
list_for_each(l, &tq->tq_thread_list) {
|
||||||
tqt = list_entry(l, taskq_thread_t, tqt_thread_list);
|
tqt = list_entry(l, taskq_thread_t, tqt_thread_list);
|
||||||
if (tqt->tqt_thread == (struct task_struct *)t)
|
if (tqt->tqt_thread == (struct task_struct *)t)
|
||||||
SRETURN(1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
SRETURN(0);
|
return (0);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(taskq_member);
|
EXPORT_SYMBOL(taskq_member);
|
||||||
|
|
||||||
|
@ -466,7 +443,6 @@ 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;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(tq);
|
ASSERT(tq);
|
||||||
|
|
||||||
|
@ -507,7 +483,7 @@ taskq_cancel_id(taskq_t *tq, taskqid_t id)
|
||||||
rc = EBUSY;
|
rc = EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRETURN(rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(taskq_cancel_id);
|
EXPORT_SYMBOL(taskq_cancel_id);
|
||||||
|
|
||||||
|
@ -516,7 +492,6 @@ 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 = 0;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(tq);
|
ASSERT(tq);
|
||||||
ASSERT(func);
|
ASSERT(func);
|
||||||
|
@ -525,15 +500,15 @@ taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t flags)
|
||||||
|
|
||||||
/* Taskq being destroyed and all tasks drained */
|
/* Taskq being destroyed and all tasks drained */
|
||||||
if (!(tq->tq_flags & TQ_ACTIVE))
|
if (!(tq->tq_flags & TQ_ACTIVE))
|
||||||
SGOTO(out, rc = 0);
|
goto out;
|
||||||
|
|
||||||
/* 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))
|
||||||
SGOTO(out, rc = 0);
|
goto out;
|
||||||
|
|
||||||
if ((t = task_alloc(tq, flags)) == NULL)
|
if ((t = task_alloc(tq, flags)) == NULL)
|
||||||
SGOTO(out, rc = 0);
|
goto out;
|
||||||
|
|
||||||
spin_lock(&t->tqent_lock);
|
spin_lock(&t->tqent_lock);
|
||||||
|
|
||||||
|
@ -559,7 +534,7 @@ 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:
|
||||||
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
|
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
|
||||||
SRETURN(rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(taskq_dispatch);
|
EXPORT_SYMBOL(taskq_dispatch);
|
||||||
|
|
||||||
|
@ -567,9 +542,8 @@ 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)
|
||||||
{
|
{
|
||||||
taskq_ent_t *t;
|
|
||||||
taskqid_t rc = 0;
|
taskqid_t rc = 0;
|
||||||
SENTRY;
|
taskq_ent_t *t;
|
||||||
|
|
||||||
ASSERT(tq);
|
ASSERT(tq);
|
||||||
ASSERT(func);
|
ASSERT(func);
|
||||||
|
@ -578,10 +552,10 @@ taskq_dispatch_delay(taskq_t *tq, task_func_t func, void *arg,
|
||||||
|
|
||||||
/* Taskq being destroyed and all tasks drained */
|
/* Taskq being destroyed and all tasks drained */
|
||||||
if (!(tq->tq_flags & TQ_ACTIVE))
|
if (!(tq->tq_flags & TQ_ACTIVE))
|
||||||
SGOTO(out, rc = 0);
|
goto out;
|
||||||
|
|
||||||
if ((t = task_alloc(tq, flags)) == NULL)
|
if ((t = task_alloc(tq, flags)) == NULL)
|
||||||
SGOTO(out, rc = 0);
|
goto out;
|
||||||
|
|
||||||
spin_lock(&t->tqent_lock);
|
spin_lock(&t->tqent_lock);
|
||||||
|
|
||||||
|
@ -603,7 +577,7 @@ taskq_dispatch_delay(taskq_t *tq, task_func_t func, void *arg,
|
||||||
spin_unlock(&t->tqent_lock);
|
spin_unlock(&t->tqent_lock);
|
||||||
out:
|
out:
|
||||||
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
|
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
|
||||||
SRETURN(rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(taskq_dispatch_delay);
|
EXPORT_SYMBOL(taskq_dispatch_delay);
|
||||||
|
|
||||||
|
@ -611,8 +585,6 @@ 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)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(tq);
|
ASSERT(tq);
|
||||||
ASSERT(func);
|
ASSERT(func);
|
||||||
ASSERT(!(tq->tq_flags & TASKQ_DYNAMIC));
|
ASSERT(!(tq->tq_flags & TASKQ_DYNAMIC));
|
||||||
|
@ -650,7 +622,6 @@ taskq_dispatch_ent(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:
|
||||||
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
|
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(taskq_dispatch_ent);
|
EXPORT_SYMBOL(taskq_dispatch_ent);
|
||||||
|
|
||||||
|
@ -685,7 +656,6 @@ taskq_thread(void *args)
|
||||||
taskq_t *tq;
|
taskq_t *tq;
|
||||||
taskq_ent_t *t;
|
taskq_ent_t *t;
|
||||||
struct list_head *pend_list;
|
struct list_head *pend_list;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(tqt);
|
ASSERT(tqt);
|
||||||
tq = tqt->tqt_tq;
|
tq = tqt->tqt_tq;
|
||||||
|
@ -778,7 +748,7 @@ taskq_thread(void *args)
|
||||||
|
|
||||||
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
|
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
|
||||||
|
|
||||||
SRETURN(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
taskq_t *
|
taskq_t *
|
||||||
|
@ -789,7 +759,6 @@ 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 rc = 0, i, j = 0;
|
int rc = 0, i, j = 0;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(name != NULL);
|
ASSERT(name != NULL);
|
||||||
ASSERT(pri <= maxclsyspri);
|
ASSERT(pri <= maxclsyspri);
|
||||||
|
@ -808,7 +777,7 @@ taskq_create(const char *name, int nthreads, pri_t pri,
|
||||||
|
|
||||||
tq = kmem_alloc(sizeof(*tq), KM_PUSHPAGE);
|
tq = kmem_alloc(sizeof(*tq), KM_PUSHPAGE);
|
||||||
if (tq == NULL)
|
if (tq == NULL)
|
||||||
SRETURN(NULL);
|
return (NULL);
|
||||||
|
|
||||||
spin_lock_init(&tq->tq_lock);
|
spin_lock_init(&tq->tq_lock);
|
||||||
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
|
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
|
||||||
|
@ -869,7 +838,7 @@ taskq_create(const char *name, int nthreads, pri_t pri,
|
||||||
tq = NULL;
|
tq = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRETURN(tq);
|
return (tq);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(taskq_create);
|
EXPORT_SYMBOL(taskq_create);
|
||||||
|
|
||||||
|
@ -879,7 +848,6 @@ 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;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(tq);
|
ASSERT(tq);
|
||||||
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
|
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
|
||||||
|
@ -929,30 +897,24 @@ taskq_destroy(taskq_t *tq)
|
||||||
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
|
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
|
||||||
|
|
||||||
kmem_free(tq, sizeof(taskq_t));
|
kmem_free(tq, sizeof(taskq_t));
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(taskq_destroy);
|
EXPORT_SYMBOL(taskq_destroy);
|
||||||
|
|
||||||
int
|
int
|
||||||
spl_taskq_init(void)
|
spl_taskq_init(void)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
/* Solaris creates a dynamic taskq of up to 64 threads, however in
|
/* Solaris creates a dynamic taskq of up to 64 threads, however in
|
||||||
* a Linux environment 1 thread per-core is usually about right */
|
* a Linux environment 1 thread per-core is usually about right */
|
||||||
system_taskq = taskq_create("spl_system_taskq", num_online_cpus(),
|
system_taskq = taskq_create("spl_system_taskq", num_online_cpus(),
|
||||||
minclsyspri, 4, 512, TASKQ_PREPOPULATE);
|
minclsyspri, 4, 512, TASKQ_PREPOPULATE);
|
||||||
if (system_taskq == NULL)
|
if (system_taskq == NULL)
|
||||||
SRETURN(1);
|
return (1);
|
||||||
|
|
||||||
SRETURN(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
spl_taskq_fini(void)
|
spl_taskq_fini(void)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
taskq_destroy(system_taskq);
|
taskq_destroy(system_taskq);
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,13 +27,6 @@
|
||||||
#include <sys/thread.h>
|
#include <sys/thread.h>
|
||||||
#include <sys/kmem.h>
|
#include <sys/kmem.h>
|
||||||
#include <sys/tsd.h>
|
#include <sys/tsd.h>
|
||||||
#include <spl-debug.h>
|
|
||||||
|
|
||||||
#ifdef SS_DEBUG_SUBSYS
|
|
||||||
#undef SS_DEBUG_SUBSYS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SS_DEBUG_SUBSYS SS_THREAD
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Thread interfaces
|
* Thread interfaces
|
||||||
|
@ -73,8 +66,6 @@ thread_generic_wrapper(void *arg)
|
||||||
void
|
void
|
||||||
__thread_exit(void)
|
__thread_exit(void)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
SEXIT;
|
|
||||||
tsd_exit();
|
tsd_exit();
|
||||||
complete_and_exit(NULL, 0);
|
complete_and_exit(NULL, 0);
|
||||||
/* Unreachable */
|
/* Unreachable */
|
||||||
|
@ -92,7 +83,6 @@ __thread_create(caddr_t stk, size_t stksize, thread_func_t func,
|
||||||
thread_priv_t *tp;
|
thread_priv_t *tp;
|
||||||
struct task_struct *tsk;
|
struct task_struct *tsk;
|
||||||
char *p;
|
char *p;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
/* Option pp is simply ignored */
|
/* Option pp is simply ignored */
|
||||||
/* Variable stack size unsupported */
|
/* Variable stack size unsupported */
|
||||||
|
@ -100,7 +90,7 @@ __thread_create(caddr_t stk, size_t stksize, thread_func_t func,
|
||||||
|
|
||||||
tp = kmem_alloc(sizeof(thread_priv_t), KM_PUSHPAGE);
|
tp = kmem_alloc(sizeof(thread_priv_t), KM_PUSHPAGE);
|
||||||
if (tp == NULL)
|
if (tp == NULL)
|
||||||
SRETURN(NULL);
|
return (NULL);
|
||||||
|
|
||||||
tp->tp_magic = TP_MAGIC;
|
tp->tp_magic = TP_MAGIC;
|
||||||
tp->tp_name_size = strlen(name) + 1;
|
tp->tp_name_size = strlen(name) + 1;
|
||||||
|
@ -108,7 +98,7 @@ __thread_create(caddr_t stk, size_t stksize, thread_func_t func,
|
||||||
tp->tp_name = kmem_alloc(tp->tp_name_size, KM_PUSHPAGE);
|
tp->tp_name = kmem_alloc(tp->tp_name_size, KM_PUSHPAGE);
|
||||||
if (tp->tp_name == NULL) {
|
if (tp->tp_name == NULL) {
|
||||||
kmem_free(tp, sizeof(thread_priv_t));
|
kmem_free(tp, sizeof(thread_priv_t));
|
||||||
SRETURN(NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(tp->tp_name, name, tp->tp_name_size);
|
strncpy(tp->tp_name, name, tp->tp_name_size);
|
||||||
|
@ -128,13 +118,11 @@ __thread_create(caddr_t stk, size_t stksize, thread_func_t func,
|
||||||
|
|
||||||
tsk = spl_kthread_create(thread_generic_wrapper, (void *)tp,
|
tsk = spl_kthread_create(thread_generic_wrapper, (void *)tp,
|
||||||
"%s", tp->tp_name);
|
"%s", tp->tp_name);
|
||||||
if (IS_ERR(tsk)) {
|
if (IS_ERR(tsk))
|
||||||
SERROR("Failed to create thread: %ld\n", PTR_ERR(tsk));
|
return (NULL);
|
||||||
SRETURN(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
wake_up_process(tsk);
|
wake_up_process(tsk);
|
||||||
SRETURN((kthread_t *)tsk);
|
return ((kthread_t *)tsk);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(__thread_create);
|
EXPORT_SYMBOL(__thread_create);
|
||||||
|
|
||||||
|
|
|
@ -61,14 +61,6 @@
|
||||||
#include <sys/kmem.h>
|
#include <sys/kmem.h>
|
||||||
#include <sys/thread.h>
|
#include <sys/thread.h>
|
||||||
#include <sys/tsd.h>
|
#include <sys/tsd.h>
|
||||||
#include <spl-debug.h>
|
|
||||||
|
|
||||||
#ifdef DEBUG_SUBSYSTEM
|
|
||||||
#undef DEBUG_SUBSYSTEM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define DEBUG_SUBSYSTEM SS_TSD
|
|
||||||
#define DEBUG_SUBSYSTEM SS_TSD
|
|
||||||
|
|
||||||
typedef struct tsd_hash_bin {
|
typedef struct tsd_hash_bin {
|
||||||
spinlock_t hb_lock;
|
spinlock_t hb_lock;
|
||||||
|
@ -108,7 +100,6 @@ tsd_hash_search(tsd_hash_table_t *table, uint_t key, pid_t pid)
|
||||||
tsd_hash_entry_t *entry;
|
tsd_hash_entry_t *entry;
|
||||||
tsd_hash_bin_t *bin;
|
tsd_hash_bin_t *bin;
|
||||||
ulong_t hash;
|
ulong_t hash;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
hash = hash_long((ulong_t)key * (ulong_t)pid, table->ht_bits);
|
hash = hash_long((ulong_t)key * (ulong_t)pid, table->ht_bits);
|
||||||
bin = &table->ht_bins[hash];
|
bin = &table->ht_bins[hash];
|
||||||
|
@ -117,12 +108,12 @@ tsd_hash_search(tsd_hash_table_t *table, uint_t key, pid_t pid)
|
||||||
entry = list_entry(node, tsd_hash_entry_t, he_list);
|
entry = list_entry(node, tsd_hash_entry_t, he_list);
|
||||||
if ((entry->he_key == key) && (entry->he_pid == pid)) {
|
if ((entry->he_key == key) && (entry->he_pid == pid)) {
|
||||||
spin_unlock(&bin->hb_lock);
|
spin_unlock(&bin->hb_lock);
|
||||||
SRETURN(entry);
|
return (entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock(&bin->hb_lock);
|
spin_unlock(&bin->hb_lock);
|
||||||
SRETURN(NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -136,7 +127,6 @@ static void
|
||||||
tsd_hash_dtor(struct hlist_head *work)
|
tsd_hash_dtor(struct hlist_head *work)
|
||||||
{
|
{
|
||||||
tsd_hash_entry_t *entry;
|
tsd_hash_entry_t *entry;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
while (!hlist_empty(work)) {
|
while (!hlist_empty(work)) {
|
||||||
entry = hlist_entry(work->first, tsd_hash_entry_t, he_list);
|
entry = hlist_entry(work->first, tsd_hash_entry_t, he_list);
|
||||||
|
@ -147,8 +137,6 @@ tsd_hash_dtor(struct hlist_head *work)
|
||||||
|
|
||||||
kmem_free(entry, sizeof(tsd_hash_entry_t));
|
kmem_free(entry, sizeof(tsd_hash_entry_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -170,14 +158,13 @@ tsd_hash_add(tsd_hash_table_t *table, uint_t key, pid_t pid, void *value)
|
||||||
tsd_hash_bin_t *bin;
|
tsd_hash_bin_t *bin;
|
||||||
ulong_t hash;
|
ulong_t hash;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT3P(tsd_hash_search(table, key, pid), ==, NULL);
|
ASSERT3P(tsd_hash_search(table, key, pid), ==, NULL);
|
||||||
|
|
||||||
/* New entry allocate structure, set value, and add to hash */
|
/* New entry allocate structure, set value, and add to hash */
|
||||||
entry = kmem_alloc(sizeof(tsd_hash_entry_t), KM_PUSHPAGE);
|
entry = kmem_alloc(sizeof(tsd_hash_entry_t), KM_PUSHPAGE);
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
SRETURN(ENOMEM);
|
return (ENOMEM);
|
||||||
|
|
||||||
entry->he_key = key;
|
entry->he_key = key;
|
||||||
entry->he_pid = pid;
|
entry->he_pid = pid;
|
||||||
|
@ -209,7 +196,7 @@ tsd_hash_add(tsd_hash_table_t *table, uint_t key, pid_t pid, void *value)
|
||||||
spin_unlock(&bin->hb_lock);
|
spin_unlock(&bin->hb_lock);
|
||||||
spin_unlock(&table->ht_lock);
|
spin_unlock(&table->ht_lock);
|
||||||
|
|
||||||
SRETURN(rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -230,14 +217,13 @@ tsd_hash_add_key(tsd_hash_table_t *table, uint_t *keyp, dtor_func_t dtor)
|
||||||
tsd_hash_bin_t *bin;
|
tsd_hash_bin_t *bin;
|
||||||
ulong_t hash;
|
ulong_t hash;
|
||||||
int keys_checked = 0;
|
int keys_checked = 0;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT3P(table, !=, NULL);
|
ASSERT3P(table, !=, NULL);
|
||||||
|
|
||||||
/* Allocate entry to be used as a destructor for this key */
|
/* Allocate entry to be used as a destructor for this key */
|
||||||
entry = kmem_alloc(sizeof(tsd_hash_entry_t), KM_PUSHPAGE);
|
entry = kmem_alloc(sizeof(tsd_hash_entry_t), KM_PUSHPAGE);
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
SRETURN(ENOMEM);
|
return (ENOMEM);
|
||||||
|
|
||||||
/* Determine next available key value */
|
/* Determine next available key value */
|
||||||
spin_lock(&table->ht_lock);
|
spin_lock(&table->ht_lock);
|
||||||
|
@ -249,7 +235,7 @@ tsd_hash_add_key(tsd_hash_table_t *table, uint_t *keyp, dtor_func_t dtor)
|
||||||
/* Ensure failure when all TSD_KEYS_MAX keys are in use */
|
/* Ensure failure when all TSD_KEYS_MAX keys are in use */
|
||||||
if (keys_checked++ >= TSD_KEYS_MAX) {
|
if (keys_checked++ >= TSD_KEYS_MAX) {
|
||||||
spin_unlock(&table->ht_lock);
|
spin_unlock(&table->ht_lock);
|
||||||
SRETURN(ENOENT);
|
return (ENOENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp_entry = tsd_hash_search(table, table->ht_key, DTOR_PID);
|
tmp_entry = tsd_hash_search(table, table->ht_key, DTOR_PID);
|
||||||
|
@ -273,7 +259,7 @@ tsd_hash_add_key(tsd_hash_table_t *table, uint_t *keyp, dtor_func_t dtor)
|
||||||
spin_unlock(&bin->hb_lock);
|
spin_unlock(&bin->hb_lock);
|
||||||
spin_unlock(&table->ht_lock);
|
spin_unlock(&table->ht_lock);
|
||||||
|
|
||||||
SRETURN(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -291,12 +277,11 @@ tsd_hash_add_pid(tsd_hash_table_t *table, pid_t pid)
|
||||||
tsd_hash_entry_t *entry;
|
tsd_hash_entry_t *entry;
|
||||||
tsd_hash_bin_t *bin;
|
tsd_hash_bin_t *bin;
|
||||||
ulong_t hash;
|
ulong_t hash;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
/* Allocate entry to be used as the process reference */
|
/* Allocate entry to be used as the process reference */
|
||||||
entry = kmem_alloc(sizeof(tsd_hash_entry_t), KM_PUSHPAGE);
|
entry = kmem_alloc(sizeof(tsd_hash_entry_t), KM_PUSHPAGE);
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
SRETURN(ENOMEM);
|
return (ENOMEM);
|
||||||
|
|
||||||
spin_lock(&table->ht_lock);
|
spin_lock(&table->ht_lock);
|
||||||
entry->he_key = PID_KEY;
|
entry->he_key = PID_KEY;
|
||||||
|
@ -316,7 +301,7 @@ tsd_hash_add_pid(tsd_hash_table_t *table, pid_t pid)
|
||||||
spin_unlock(&bin->hb_lock);
|
spin_unlock(&bin->hb_lock);
|
||||||
spin_unlock(&table->ht_lock);
|
spin_unlock(&table->ht_lock);
|
||||||
|
|
||||||
SRETURN(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -328,14 +313,10 @@ tsd_hash_add_pid(tsd_hash_table_t *table, pid_t pid)
|
||||||
static void
|
static void
|
||||||
tsd_hash_del(tsd_hash_table_t *table, tsd_hash_entry_t *entry)
|
tsd_hash_del(tsd_hash_table_t *table, tsd_hash_entry_t *entry)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(spin_is_locked(&table->ht_lock));
|
ASSERT(spin_is_locked(&table->ht_lock));
|
||||||
hlist_del(&entry->he_list);
|
hlist_del(&entry->he_list);
|
||||||
list_del_init(&entry->he_key_list);
|
list_del_init(&entry->he_key_list);
|
||||||
list_del_init(&entry->he_pid_list);
|
list_del_init(&entry->he_pid_list);
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -350,17 +331,16 @@ tsd_hash_table_init(uint_t bits)
|
||||||
{
|
{
|
||||||
tsd_hash_table_t *table;
|
tsd_hash_table_t *table;
|
||||||
int hash, size = (1 << bits);
|
int hash, size = (1 << bits);
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
table = kmem_zalloc(sizeof(tsd_hash_table_t), KM_SLEEP);
|
table = kmem_zalloc(sizeof(tsd_hash_table_t), KM_SLEEP);
|
||||||
if (table == NULL)
|
if (table == NULL)
|
||||||
SRETURN(NULL);
|
return (NULL);
|
||||||
|
|
||||||
table->ht_bins = kmem_zalloc(sizeof(tsd_hash_bin_t) * size,
|
table->ht_bins = kmem_zalloc(sizeof(tsd_hash_bin_t) * size,
|
||||||
KM_SLEEP | KM_NODEBUG);
|
KM_SLEEP | KM_NODEBUG);
|
||||||
if (table->ht_bins == NULL) {
|
if (table->ht_bins == NULL) {
|
||||||
kmem_free(table, sizeof(tsd_hash_table_t));
|
kmem_free(table, sizeof(tsd_hash_table_t));
|
||||||
SRETURN(NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (hash = 0; hash < size; hash++) {
|
for (hash = 0; hash < size; hash++) {
|
||||||
|
@ -372,7 +352,7 @@ tsd_hash_table_init(uint_t bits)
|
||||||
table->ht_bits = bits;
|
table->ht_bits = bits;
|
||||||
table->ht_key = 1;
|
table->ht_key = 1;
|
||||||
|
|
||||||
SRETURN(table);
|
return (table);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -390,7 +370,6 @@ tsd_hash_table_fini(tsd_hash_table_t *table)
|
||||||
tsd_hash_bin_t *bin;
|
tsd_hash_bin_t *bin;
|
||||||
tsd_hash_entry_t *entry;
|
tsd_hash_entry_t *entry;
|
||||||
int size, i;
|
int size, i;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT3P(table, !=, NULL);
|
ASSERT3P(table, !=, NULL);
|
||||||
spin_lock(&table->ht_lock);
|
spin_lock(&table->ht_lock);
|
||||||
|
@ -410,8 +389,6 @@ tsd_hash_table_fini(tsd_hash_table_t *table)
|
||||||
tsd_hash_dtor(&work);
|
tsd_hash_dtor(&work);
|
||||||
kmem_free(table->ht_bins, sizeof(tsd_hash_bin_t)*(1<<table->ht_bits));
|
kmem_free(table->ht_bins, sizeof(tsd_hash_bin_t)*(1<<table->ht_bits));
|
||||||
kmem_free(table, sizeof(tsd_hash_table_t));
|
kmem_free(table, sizeof(tsd_hash_table_t));
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -432,20 +409,19 @@ tsd_set(uint_t key, void *value)
|
||||||
tsd_hash_entry_t *entry;
|
tsd_hash_entry_t *entry;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int rc;
|
int rc;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
table = tsd_hash_table;
|
table = tsd_hash_table;
|
||||||
pid = curthread->pid;
|
pid = curthread->pid;
|
||||||
ASSERT3P(table, !=, NULL);
|
ASSERT3P(table, !=, NULL);
|
||||||
|
|
||||||
if ((key == 0) || (key > TSD_KEYS_MAX))
|
if ((key == 0) || (key > TSD_KEYS_MAX))
|
||||||
SRETURN(EINVAL);
|
return (EINVAL);
|
||||||
|
|
||||||
/* Entry already exists in hash table update value */
|
/* Entry already exists in hash table update value */
|
||||||
entry = tsd_hash_search(table, key, pid);
|
entry = tsd_hash_search(table, key, pid);
|
||||||
if (entry) {
|
if (entry) {
|
||||||
entry->he_value = value;
|
entry->he_value = value;
|
||||||
SRETURN(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add a process entry to the hash if not yet exists */
|
/* Add a process entry to the hash if not yet exists */
|
||||||
|
@ -453,11 +429,11 @@ tsd_set(uint_t key, void *value)
|
||||||
if (entry == NULL) {
|
if (entry == NULL) {
|
||||||
rc = tsd_hash_add_pid(table, pid);
|
rc = tsd_hash_add_pid(table, pid);
|
||||||
if (rc)
|
if (rc)
|
||||||
SRETURN(rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = tsd_hash_add(table, key, pid, value);
|
rc = tsd_hash_add(table, key, pid, value);
|
||||||
SRETURN(rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(tsd_set);
|
EXPORT_SYMBOL(tsd_set);
|
||||||
|
|
||||||
|
@ -473,18 +449,17 @@ void *
|
||||||
tsd_get(uint_t key)
|
tsd_get(uint_t key)
|
||||||
{
|
{
|
||||||
tsd_hash_entry_t *entry;
|
tsd_hash_entry_t *entry;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT3P(tsd_hash_table, !=, NULL);
|
ASSERT3P(tsd_hash_table, !=, NULL);
|
||||||
|
|
||||||
if ((key == 0) || (key > TSD_KEYS_MAX))
|
if ((key == 0) || (key > TSD_KEYS_MAX))
|
||||||
SRETURN(NULL);
|
return (NULL);
|
||||||
|
|
||||||
entry = tsd_hash_search(tsd_hash_table, key, curthread->pid);
|
entry = tsd_hash_search(tsd_hash_table, key, curthread->pid);
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
SRETURN(NULL);
|
return (NULL);
|
||||||
|
|
||||||
SRETURN(entry->he_value);
|
return (entry->he_value);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(tsd_get);
|
EXPORT_SYMBOL(tsd_get);
|
||||||
|
|
||||||
|
@ -503,17 +478,11 @@ EXPORT_SYMBOL(tsd_get);
|
||||||
void
|
void
|
||||||
tsd_create(uint_t *keyp, dtor_func_t dtor)
|
tsd_create(uint_t *keyp, dtor_func_t dtor)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT3P(keyp, !=, NULL);
|
ASSERT3P(keyp, !=, NULL);
|
||||||
if (*keyp) {
|
if (*keyp)
|
||||||
SEXIT;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
(void)tsd_hash_add_key(tsd_hash_table, keyp, dtor);
|
(void)tsd_hash_add_key(tsd_hash_table, keyp, dtor);
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(tsd_create);
|
EXPORT_SYMBOL(tsd_create);
|
||||||
|
|
||||||
|
@ -534,7 +503,6 @@ tsd_destroy(uint_t *keyp)
|
||||||
tsd_hash_entry_t *dtor_entry, *entry;
|
tsd_hash_entry_t *dtor_entry, *entry;
|
||||||
tsd_hash_bin_t *dtor_entry_bin, *entry_bin;
|
tsd_hash_bin_t *dtor_entry_bin, *entry_bin;
|
||||||
ulong_t hash;
|
ulong_t hash;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
table = tsd_hash_table;
|
table = tsd_hash_table;
|
||||||
ASSERT3P(table, !=, NULL);
|
ASSERT3P(table, !=, NULL);
|
||||||
|
@ -543,7 +511,6 @@ tsd_destroy(uint_t *keyp)
|
||||||
dtor_entry = tsd_hash_search(table, *keyp, DTOR_PID);
|
dtor_entry = tsd_hash_search(table, *keyp, DTOR_PID);
|
||||||
if (dtor_entry == NULL) {
|
if (dtor_entry == NULL) {
|
||||||
spin_unlock(&table->ht_lock);
|
spin_unlock(&table->ht_lock);
|
||||||
SEXIT;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -580,8 +547,6 @@ tsd_destroy(uint_t *keyp)
|
||||||
|
|
||||||
tsd_hash_dtor(&work);
|
tsd_hash_dtor(&work);
|
||||||
*keyp = 0;
|
*keyp = 0;
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(tsd_destroy);
|
EXPORT_SYMBOL(tsd_destroy);
|
||||||
|
|
||||||
|
@ -601,7 +566,6 @@ tsd_exit(void)
|
||||||
tsd_hash_entry_t *pid_entry, *entry;
|
tsd_hash_entry_t *pid_entry, *entry;
|
||||||
tsd_hash_bin_t *pid_entry_bin, *entry_bin;
|
tsd_hash_bin_t *pid_entry_bin, *entry_bin;
|
||||||
ulong_t hash;
|
ulong_t hash;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
table = tsd_hash_table;
|
table = tsd_hash_table;
|
||||||
ASSERT3P(table, !=, NULL);
|
ASSERT3P(table, !=, NULL);
|
||||||
|
@ -610,7 +574,6 @@ tsd_exit(void)
|
||||||
pid_entry = tsd_hash_search(table, PID_KEY, curthread->pid);
|
pid_entry = tsd_hash_search(table, PID_KEY, curthread->pid);
|
||||||
if (pid_entry == NULL) {
|
if (pid_entry == NULL) {
|
||||||
spin_unlock(&table->ht_lock);
|
spin_unlock(&table->ht_lock);
|
||||||
SEXIT;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,28 +609,22 @@ tsd_exit(void)
|
||||||
spin_unlock(&table->ht_lock);
|
spin_unlock(&table->ht_lock);
|
||||||
|
|
||||||
tsd_hash_dtor(&work);
|
tsd_hash_dtor(&work);
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(tsd_exit);
|
EXPORT_SYMBOL(tsd_exit);
|
||||||
|
|
||||||
int
|
int
|
||||||
spl_tsd_init(void)
|
spl_tsd_init(void)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
tsd_hash_table = tsd_hash_table_init(TSD_HASH_TABLE_BITS_DEFAULT);
|
tsd_hash_table = tsd_hash_table_init(TSD_HASH_TABLE_BITS_DEFAULT);
|
||||||
if (tsd_hash_table == NULL)
|
if (tsd_hash_table == NULL)
|
||||||
SRETURN(1);
|
return (1);
|
||||||
|
|
||||||
SRETURN(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
spl_tsd_fini(void)
|
spl_tsd_fini(void)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
tsd_hash_table_fini(tsd_hash_table);
|
tsd_hash_table_fini(tsd_hash_table);
|
||||||
tsd_hash_table = NULL;
|
tsd_hash_table = NULL;
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,13 +27,6 @@
|
||||||
#include <sys/cred.h>
|
#include <sys/cred.h>
|
||||||
#include <sys/vnode.h>
|
#include <sys/vnode.h>
|
||||||
#include <linux/falloc.h>
|
#include <linux/falloc.h>
|
||||||
#include <spl-debug.h>
|
|
||||||
|
|
||||||
#ifdef SS_DEBUG_SUBSYS
|
|
||||||
#undef SS_DEBUG_SUBSYS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SS_DEBUG_SUBSYS SS_VNODE
|
|
||||||
|
|
||||||
vnode_t *rootdir = (vnode_t *)0xabcd1234;
|
vnode_t *rootdir = (vnode_t *)0xabcd1234;
|
||||||
EXPORT_SYMBOL(rootdir);
|
EXPORT_SYMBOL(rootdir);
|
||||||
|
@ -107,7 +100,6 @@ vnode_t *
|
||||||
vn_alloc(int flag)
|
vn_alloc(int flag)
|
||||||
{
|
{
|
||||||
vnode_t *vp;
|
vnode_t *vp;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
vp = kmem_cache_alloc(vn_cache, flag);
|
vp = kmem_cache_alloc(vn_cache, flag);
|
||||||
if (vp != NULL) {
|
if (vp != NULL) {
|
||||||
|
@ -115,16 +107,14 @@ vn_alloc(int flag)
|
||||||
vp->v_type = 0;
|
vp->v_type = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRETURN(vp);
|
return (vp);
|
||||||
} /* vn_alloc() */
|
} /* vn_alloc() */
|
||||||
EXPORT_SYMBOL(vn_alloc);
|
EXPORT_SYMBOL(vn_alloc);
|
||||||
|
|
||||||
void
|
void
|
||||||
vn_free(vnode_t *vp)
|
vn_free(vnode_t *vp)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
kmem_cache_free(vn_cache, vp);
|
kmem_cache_free(vn_cache, vp);
|
||||||
SEXIT;
|
|
||||||
} /* vn_free() */
|
} /* vn_free() */
|
||||||
EXPORT_SYMBOL(vn_free);
|
EXPORT_SYMBOL(vn_free);
|
||||||
|
|
||||||
|
@ -137,7 +127,6 @@ vn_open(const char *path, uio_seg_t seg, int flags, int mode,
|
||||||
int rc, saved_umask = 0;
|
int rc, saved_umask = 0;
|
||||||
gfp_t saved_gfp;
|
gfp_t saved_gfp;
|
||||||
vnode_t *vp;
|
vnode_t *vp;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(flags & (FWRITE | FREAD));
|
ASSERT(flags & (FWRITE | FREAD));
|
||||||
ASSERT(seg == UIO_SYSSPACE);
|
ASSERT(seg == UIO_SYSSPACE);
|
||||||
|
@ -163,7 +152,7 @@ vn_open(const char *path, uio_seg_t seg, int flags, int mode,
|
||||||
(void)xchg(¤t->fs->umask, saved_umask);
|
(void)xchg(¤t->fs->umask, saved_umask);
|
||||||
|
|
||||||
if (IS_ERR(fp))
|
if (IS_ERR(fp))
|
||||||
SRETURN(-PTR_ERR(fp));
|
return (-PTR_ERR(fp));
|
||||||
|
|
||||||
#ifdef HAVE_2ARGS_VFS_GETATTR
|
#ifdef HAVE_2ARGS_VFS_GETATTR
|
||||||
rc = vfs_getattr(&fp->f_path, &stat);
|
rc = vfs_getattr(&fp->f_path, &stat);
|
||||||
|
@ -172,13 +161,13 @@ vn_open(const char *path, uio_seg_t seg, int flags, int mode,
|
||||||
#endif
|
#endif
|
||||||
if (rc) {
|
if (rc) {
|
||||||
filp_close(fp, 0);
|
filp_close(fp, 0);
|
||||||
SRETURN(-rc);
|
return (-rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
vp = vn_alloc(KM_SLEEP);
|
vp = vn_alloc(KM_SLEEP);
|
||||||
if (!vp) {
|
if (!vp) {
|
||||||
filp_close(fp, 0);
|
filp_close(fp, 0);
|
||||||
SRETURN(ENOMEM);
|
return (ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
saved_gfp = mapping_gfp_mask(fp->f_mapping);
|
saved_gfp = mapping_gfp_mask(fp->f_mapping);
|
||||||
|
@ -191,7 +180,7 @@ vn_open(const char *path, uio_seg_t seg, int flags, int mode,
|
||||||
*vpp = vp;
|
*vpp = vp;
|
||||||
mutex_exit(&vp->v_lock);
|
mutex_exit(&vp->v_lock);
|
||||||
|
|
||||||
SRETURN(0);
|
return (0);
|
||||||
} /* vn_open() */
|
} /* vn_open() */
|
||||||
EXPORT_SYMBOL(vn_open);
|
EXPORT_SYMBOL(vn_open);
|
||||||
|
|
||||||
|
@ -201,20 +190,19 @@ vn_openat(const char *path, uio_seg_t seg, int flags, int mode,
|
||||||
{
|
{
|
||||||
char *realpath;
|
char *realpath;
|
||||||
int len, rc;
|
int len, rc;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(vp == rootdir);
|
ASSERT(vp == rootdir);
|
||||||
|
|
||||||
len = strlen(path) + 2;
|
len = strlen(path) + 2;
|
||||||
realpath = kmalloc(len, GFP_KERNEL);
|
realpath = kmalloc(len, GFP_KERNEL);
|
||||||
if (!realpath)
|
if (!realpath)
|
||||||
SRETURN(ENOMEM);
|
return (ENOMEM);
|
||||||
|
|
||||||
(void)snprintf(realpath, len, "/%s", path);
|
(void)snprintf(realpath, len, "/%s", path);
|
||||||
rc = vn_open(realpath, seg, flags, mode, vpp, x1, x2);
|
rc = vn_open(realpath, seg, flags, mode, vpp, x1, x2);
|
||||||
kfree(realpath);
|
kfree(realpath);
|
||||||
|
|
||||||
SRETURN(rc);
|
return (rc);
|
||||||
} /* vn_openat() */
|
} /* vn_openat() */
|
||||||
EXPORT_SYMBOL(vn_openat);
|
EXPORT_SYMBOL(vn_openat);
|
||||||
|
|
||||||
|
@ -226,7 +214,6 @@ vn_rdwr(uio_rw_t uio, vnode_t *vp, void *addr, ssize_t len, offset_t off,
|
||||||
mm_segment_t saved_fs;
|
mm_segment_t saved_fs;
|
||||||
struct file *fp;
|
struct file *fp;
|
||||||
int rc;
|
int rc;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(uio == UIO_WRITE || uio == UIO_READ);
|
ASSERT(uio == UIO_WRITE || uio == UIO_READ);
|
||||||
ASSERT(vp);
|
ASSERT(vp);
|
||||||
|
@ -256,16 +243,16 @@ vn_rdwr(uio_rw_t uio, vnode_t *vp, void *addr, ssize_t len, offset_t off,
|
||||||
fp->f_pos = offset;
|
fp->f_pos = offset;
|
||||||
|
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
SRETURN(-rc);
|
return (-rc);
|
||||||
|
|
||||||
if (residp) {
|
if (residp) {
|
||||||
*residp = len - rc;
|
*residp = len - rc;
|
||||||
} else {
|
} else {
|
||||||
if (rc != len)
|
if (rc != len)
|
||||||
SRETURN(EIO);
|
return (EIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
SRETURN(0);
|
return (0);
|
||||||
} /* vn_rdwr() */
|
} /* vn_rdwr() */
|
||||||
EXPORT_SYMBOL(vn_rdwr);
|
EXPORT_SYMBOL(vn_rdwr);
|
||||||
|
|
||||||
|
@ -273,7 +260,6 @@ int
|
||||||
vn_close(vnode_t *vp, int flags, int x1, int x2, void *x3, void *x4)
|
vn_close(vnode_t *vp, int flags, int x1, int x2, void *x3, void *x4)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(vp);
|
ASSERT(vp);
|
||||||
ASSERT(vp->v_file);
|
ASSERT(vp->v_file);
|
||||||
|
@ -282,7 +268,7 @@ vn_close(vnode_t *vp, int flags, int x1, int x2, void *x3, void *x4)
|
||||||
rc = filp_close(vp->v_file, 0);
|
rc = filp_close(vp->v_file, 0);
|
||||||
vn_free(vp);
|
vn_free(vp);
|
||||||
|
|
||||||
SRETURN(-rc);
|
return (-rc);
|
||||||
} /* vn_close() */
|
} /* vn_close() */
|
||||||
EXPORT_SYMBOL(vn_close);
|
EXPORT_SYMBOL(vn_close);
|
||||||
|
|
||||||
|
@ -386,7 +372,6 @@ vn_remove(const char *path, uio_seg_t seg, int flags)
|
||||||
struct path parent;
|
struct path parent;
|
||||||
struct inode *inode = NULL;
|
struct inode *inode = NULL;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(seg == UIO_SYSSPACE);
|
ASSERT(seg == UIO_SYSSPACE);
|
||||||
ASSERT(flags == RMFILE);
|
ASSERT(flags == RMFILE);
|
||||||
|
@ -394,14 +379,18 @@ vn_remove(const char *path, uio_seg_t seg, int flags)
|
||||||
dentry = spl_kern_path_locked(path, &parent);
|
dentry = spl_kern_path_locked(path, &parent);
|
||||||
rc = PTR_ERR(dentry);
|
rc = PTR_ERR(dentry);
|
||||||
if (!IS_ERR(dentry)) {
|
if (!IS_ERR(dentry)) {
|
||||||
if (parent.dentry->d_name.name[parent.dentry->d_name.len])
|
if (parent.dentry->d_name.name[parent.dentry->d_name.len]) {
|
||||||
SGOTO(slashes, rc = 0);
|
rc = 0;
|
||||||
|
goto slashes;
|
||||||
|
}
|
||||||
|
|
||||||
inode = dentry->d_inode;
|
inode = dentry->d_inode;
|
||||||
if (inode)
|
if (inode) {
|
||||||
atomic_inc(&inode->i_count);
|
atomic_inc(&inode->i_count);
|
||||||
else
|
} else {
|
||||||
SGOTO(slashes, rc = 0);
|
rc = 0;
|
||||||
|
goto slashes;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_2ARGS_VFS_UNLINK
|
#ifdef HAVE_2ARGS_VFS_UNLINK
|
||||||
rc = vfs_unlink(parent.dentry->d_inode, dentry);
|
rc = vfs_unlink(parent.dentry->d_inode, dentry);
|
||||||
|
@ -419,12 +408,12 @@ exit1:
|
||||||
iput(inode); /* truncate the inode here */
|
iput(inode); /* truncate the inode here */
|
||||||
|
|
||||||
path_put(&parent);
|
path_put(&parent);
|
||||||
SRETURN(-rc);
|
return (-rc);
|
||||||
|
|
||||||
slashes:
|
slashes:
|
||||||
rc = !dentry->d_inode ? -ENOENT :
|
rc = !dentry->d_inode ? -ENOENT :
|
||||||
S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR;
|
S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR;
|
||||||
SGOTO(exit1, rc);
|
goto exit1;
|
||||||
} /* vn_remove() */
|
} /* vn_remove() */
|
||||||
EXPORT_SYMBOL(vn_remove);
|
EXPORT_SYMBOL(vn_remove);
|
||||||
|
|
||||||
|
@ -437,23 +426,26 @@ vn_rename(const char *oldname, const char *newname, int x1)
|
||||||
struct dentry *trap;
|
struct dentry *trap;
|
||||||
struct path old_parent, new_parent;
|
struct path old_parent, new_parent;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
old_dentry = spl_kern_path_locked(oldname, &old_parent);
|
old_dentry = spl_kern_path_locked(oldname, &old_parent);
|
||||||
if (IS_ERR(old_dentry))
|
if (IS_ERR(old_dentry)) {
|
||||||
SGOTO(exit, rc = PTR_ERR(old_dentry));
|
rc = PTR_ERR(old_dentry);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
spl_inode_unlock(old_parent.dentry->d_inode);
|
spl_inode_unlock(old_parent.dentry->d_inode);
|
||||||
|
|
||||||
new_dentry = spl_kern_path_locked(newname, &new_parent);
|
new_dentry = spl_kern_path_locked(newname, &new_parent);
|
||||||
if (IS_ERR(new_dentry))
|
if (IS_ERR(new_dentry)) {
|
||||||
SGOTO(exit2, rc = PTR_ERR(new_dentry));
|
rc = PTR_ERR(new_dentry);
|
||||||
|
goto exit2;
|
||||||
|
}
|
||||||
|
|
||||||
spl_inode_unlock(new_parent.dentry->d_inode);
|
spl_inode_unlock(new_parent.dentry->d_inode);
|
||||||
|
|
||||||
rc = -EXDEV;
|
rc = -EXDEV;
|
||||||
if (old_parent.mnt != new_parent.mnt)
|
if (old_parent.mnt != new_parent.mnt)
|
||||||
SGOTO(exit3, rc);
|
goto exit3;
|
||||||
|
|
||||||
old_dir = old_parent.dentry;
|
old_dir = old_parent.dentry;
|
||||||
new_dir = new_parent.dentry;
|
new_dir = new_parent.dentry;
|
||||||
|
@ -462,25 +454,25 @@ vn_rename(const char *oldname, const char *newname, int x1)
|
||||||
/* source should not be ancestor of target */
|
/* source should not be ancestor of target */
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
if (old_dentry == trap)
|
if (old_dentry == trap)
|
||||||
SGOTO(exit4, rc);
|
goto exit4;
|
||||||
|
|
||||||
/* target should not be an ancestor of source */
|
/* target should not be an ancestor of source */
|
||||||
rc = -ENOTEMPTY;
|
rc = -ENOTEMPTY;
|
||||||
if (new_dentry == trap)
|
if (new_dentry == trap)
|
||||||
SGOTO(exit4, rc);
|
goto exit4;
|
||||||
|
|
||||||
/* source must exist */
|
/* source must exist */
|
||||||
rc = -ENOENT;
|
rc = -ENOENT;
|
||||||
if (!old_dentry->d_inode)
|
if (!old_dentry->d_inode)
|
||||||
SGOTO(exit4, rc);
|
goto exit4;
|
||||||
|
|
||||||
/* unless the source is a directory trailing slashes give -ENOTDIR */
|
/* unless the source is a directory trailing slashes give -ENOTDIR */
|
||||||
if (!S_ISDIR(old_dentry->d_inode->i_mode)) {
|
if (!S_ISDIR(old_dentry->d_inode->i_mode)) {
|
||||||
rc = -ENOTDIR;
|
rc = -ENOTDIR;
|
||||||
if (old_dentry->d_name.name[old_dentry->d_name.len])
|
if (old_dentry->d_name.name[old_dentry->d_name.len])
|
||||||
SGOTO(exit4, rc);
|
goto exit4;
|
||||||
if (new_dentry->d_name.name[new_dentry->d_name.len])
|
if (new_dentry->d_name.name[new_dentry->d_name.len])
|
||||||
SGOTO(exit4, rc);
|
goto exit4;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_4ARGS_VFS_RENAME)
|
#if defined(HAVE_4ARGS_VFS_RENAME)
|
||||||
|
@ -502,7 +494,7 @@ exit2:
|
||||||
dput(old_dentry);
|
dput(old_dentry);
|
||||||
path_put(&old_parent);
|
path_put(&old_parent);
|
||||||
exit:
|
exit:
|
||||||
SRETURN(-rc);
|
return (-rc);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(vn_rename);
|
EXPORT_SYMBOL(vn_rename);
|
||||||
|
|
||||||
|
@ -512,7 +504,6 @@ vn_getattr(vnode_t *vp, vattr_t *vap, int flags, void *x3, void *x4)
|
||||||
struct file *fp;
|
struct file *fp;
|
||||||
struct kstat stat;
|
struct kstat stat;
|
||||||
int rc;
|
int rc;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(vp);
|
ASSERT(vp);
|
||||||
ASSERT(vp->v_file);
|
ASSERT(vp->v_file);
|
||||||
|
@ -526,7 +517,7 @@ vn_getattr(vnode_t *vp, vattr_t *vap, int flags, void *x3, void *x4)
|
||||||
rc = vfs_getattr(fp->f_path.mnt, fp->f_dentry, &stat);
|
rc = vfs_getattr(fp->f_path.mnt, fp->f_dentry, &stat);
|
||||||
#endif
|
#endif
|
||||||
if (rc)
|
if (rc)
|
||||||
SRETURN(-rc);
|
return (-rc);
|
||||||
|
|
||||||
vap->va_type = vn_mode_to_vtype(stat.mode);
|
vap->va_type = vn_mode_to_vtype(stat.mode);
|
||||||
vap->va_mode = stat.mode;
|
vap->va_mode = stat.mode;
|
||||||
|
@ -543,14 +534,13 @@ vn_getattr(vnode_t *vp, vattr_t *vap, int flags, void *x3, void *x4)
|
||||||
vap->va_rdev = stat.rdev;
|
vap->va_rdev = stat.rdev;
|
||||||
vap->va_nblocks = stat.blocks;
|
vap->va_nblocks = stat.blocks;
|
||||||
|
|
||||||
SRETURN(0);
|
return (0);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(vn_getattr);
|
EXPORT_SYMBOL(vn_getattr);
|
||||||
|
|
||||||
int vn_fsync(vnode_t *vp, int flags, void *x3, void *x4)
|
int vn_fsync(vnode_t *vp, int flags, void *x3, void *x4)
|
||||||
{
|
{
|
||||||
int datasync = 0;
|
int datasync = 0;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
ASSERT(vp);
|
ASSERT(vp);
|
||||||
ASSERT(vp->v_file);
|
ASSERT(vp->v_file);
|
||||||
|
@ -558,7 +548,7 @@ int vn_fsync(vnode_t *vp, int flags, void *x3, void *x4)
|
||||||
if (flags & FDSYNC)
|
if (flags & FDSYNC)
|
||||||
datasync = 1;
|
datasync = 1;
|
||||||
|
|
||||||
SRETURN(-spl_filp_fsync(vp->v_file, datasync));
|
return (-spl_filp_fsync(vp->v_file, datasync));
|
||||||
} /* vn_fsync() */
|
} /* vn_fsync() */
|
||||||
EXPORT_SYMBOL(vn_fsync);
|
EXPORT_SYMBOL(vn_fsync);
|
||||||
|
|
||||||
|
@ -566,10 +556,9 @@ int vn_space(vnode_t *vp, int cmd, struct flock *bfp, int flag,
|
||||||
offset_t offset, void *x6, void *x7)
|
offset_t offset, void *x6, void *x7)
|
||||||
{
|
{
|
||||||
int error = EOPNOTSUPP;
|
int error = EOPNOTSUPP;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
if (cmd != F_FREESP || bfp->l_whence != 0)
|
if (cmd != F_FREESP || bfp->l_whence != 0)
|
||||||
SRETURN(EOPNOTSUPP);
|
return (EOPNOTSUPP);
|
||||||
|
|
||||||
ASSERT(vp);
|
ASSERT(vp);
|
||||||
ASSERT(vp->v_file);
|
ASSERT(vp->v_file);
|
||||||
|
@ -584,7 +573,7 @@ int vn_space(vnode_t *vp, int cmd, struct flock *bfp, int flag,
|
||||||
FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
|
FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
|
||||||
bfp->l_start, bfp->l_len);
|
bfp->l_start, bfp->l_len);
|
||||||
if (error == 0)
|
if (error == 0)
|
||||||
SRETURN(0);
|
return (0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_INODE_TRUNCATE_RANGE
|
#ifdef HAVE_INODE_TRUNCATE_RANGE
|
||||||
|
@ -600,7 +589,7 @@ int vn_space(vnode_t *vp, int cmd, struct flock *bfp, int flag,
|
||||||
if (end % PAGE_SIZE != 0) {
|
if (end % PAGE_SIZE != 0) {
|
||||||
end &= ~(off_t)(PAGE_SIZE - 1);
|
end &= ~(off_t)(PAGE_SIZE - 1);
|
||||||
if (end <= bfp->l_start)
|
if (end <= bfp->l_start)
|
||||||
SRETURN(0);
|
return (0);
|
||||||
}
|
}
|
||||||
--end;
|
--end;
|
||||||
|
|
||||||
|
@ -608,11 +597,11 @@ int vn_space(vnode_t *vp, int cmd, struct flock *bfp, int flag,
|
||||||
vp->v_file->f_dentry->d_inode,
|
vp->v_file->f_dentry->d_inode,
|
||||||
bfp->l_start, end
|
bfp->l_start, end
|
||||||
);
|
);
|
||||||
SRETURN(0);
|
return (0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SRETURN(error);
|
return (error);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(vn_space);
|
EXPORT_SYMBOL(vn_space);
|
||||||
|
|
||||||
|
@ -642,7 +631,6 @@ vn_getf(int fd)
|
||||||
file_t *fp;
|
file_t *fp;
|
||||||
vnode_t *vp;
|
vnode_t *vp;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
/* Already open just take an extra reference */
|
/* Already open just take an extra reference */
|
||||||
spin_lock(&vn_file_lock);
|
spin_lock(&vn_file_lock);
|
||||||
|
@ -651,7 +639,7 @@ vn_getf(int fd)
|
||||||
if (fp) {
|
if (fp) {
|
||||||
atomic_inc(&fp->f_ref);
|
atomic_inc(&fp->f_ref);
|
||||||
spin_unlock(&vn_file_lock);
|
spin_unlock(&vn_file_lock);
|
||||||
SRETURN(fp);
|
return (fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock(&vn_file_lock);
|
spin_unlock(&vn_file_lock);
|
||||||
|
@ -659,7 +647,7 @@ vn_getf(int fd)
|
||||||
/* File was not yet opened create the object and setup */
|
/* File was not yet opened create the object and setup */
|
||||||
fp = kmem_cache_alloc(vn_file_cache, KM_SLEEP);
|
fp = kmem_cache_alloc(vn_file_cache, KM_SLEEP);
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
SGOTO(out, rc);
|
goto out;
|
||||||
|
|
||||||
mutex_enter(&fp->f_lock);
|
mutex_enter(&fp->f_lock);
|
||||||
|
|
||||||
|
@ -670,11 +658,11 @@ vn_getf(int fd)
|
||||||
|
|
||||||
lfp = fget(fd);
|
lfp = fget(fd);
|
||||||
if (lfp == NULL)
|
if (lfp == NULL)
|
||||||
SGOTO(out_mutex, rc);
|
goto out_mutex;
|
||||||
|
|
||||||
vp = vn_alloc(KM_SLEEP);
|
vp = vn_alloc(KM_SLEEP);
|
||||||
if (vp == NULL)
|
if (vp == NULL)
|
||||||
SGOTO(out_fget, rc);
|
goto out_fget;
|
||||||
|
|
||||||
#ifdef HAVE_2ARGS_VFS_GETATTR
|
#ifdef HAVE_2ARGS_VFS_GETATTR
|
||||||
rc = vfs_getattr(&lfp->f_path, &stat);
|
rc = vfs_getattr(&lfp->f_path, &stat);
|
||||||
|
@ -682,7 +670,7 @@ vn_getf(int fd)
|
||||||
rc = vfs_getattr(lfp->f_path.mnt, lfp->f_dentry, &stat);
|
rc = vfs_getattr(lfp->f_path.mnt, lfp->f_dentry, &stat);
|
||||||
#endif
|
#endif
|
||||||
if (rc)
|
if (rc)
|
||||||
SGOTO(out_vnode, rc);
|
goto out_vnode;
|
||||||
|
|
||||||
mutex_enter(&vp->v_lock);
|
mutex_enter(&vp->v_lock);
|
||||||
vp->v_type = vn_mode_to_vtype(stat.mode);
|
vp->v_type = vn_mode_to_vtype(stat.mode);
|
||||||
|
@ -698,7 +686,7 @@ vn_getf(int fd)
|
||||||
spin_unlock(&vn_file_lock);
|
spin_unlock(&vn_file_lock);
|
||||||
|
|
||||||
mutex_exit(&fp->f_lock);
|
mutex_exit(&fp->f_lock);
|
||||||
SRETURN(fp);
|
return (fp);
|
||||||
|
|
||||||
out_vnode:
|
out_vnode:
|
||||||
vn_free(vp);
|
vn_free(vp);
|
||||||
|
@ -708,7 +696,7 @@ out_mutex:
|
||||||
mutex_exit(&fp->f_lock);
|
mutex_exit(&fp->f_lock);
|
||||||
kmem_cache_free(vn_file_cache, fp);
|
kmem_cache_free(vn_file_cache, fp);
|
||||||
out:
|
out:
|
||||||
SRETURN(NULL);
|
return (NULL);
|
||||||
} /* getf() */
|
} /* getf() */
|
||||||
EXPORT_SYMBOL(getf);
|
EXPORT_SYMBOL(getf);
|
||||||
|
|
||||||
|
@ -728,7 +716,6 @@ void
|
||||||
vn_releasef(int fd)
|
vn_releasef(int fd)
|
||||||
{
|
{
|
||||||
file_t *fp;
|
file_t *fp;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
spin_lock(&vn_file_lock);
|
spin_lock(&vn_file_lock);
|
||||||
fp = file_find(fd);
|
fp = file_find(fd);
|
||||||
|
@ -736,7 +723,6 @@ vn_releasef(int fd)
|
||||||
atomic_dec(&fp->f_ref);
|
atomic_dec(&fp->f_ref);
|
||||||
if (atomic_read(&fp->f_ref) > 0) {
|
if (atomic_read(&fp->f_ref) > 0) {
|
||||||
spin_unlock(&vn_file_lock);
|
spin_unlock(&vn_file_lock);
|
||||||
SEXIT;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -745,7 +731,6 @@ vn_releasef(int fd)
|
||||||
}
|
}
|
||||||
spin_unlock(&vn_file_lock);
|
spin_unlock(&vn_file_lock);
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
return;
|
return;
|
||||||
} /* releasef() */
|
} /* releasef() */
|
||||||
EXPORT_SYMBOL(releasef);
|
EXPORT_SYMBOL(releasef);
|
||||||
|
@ -783,7 +768,6 @@ vn_set_pwd(const char *filename)
|
||||||
struct path path;
|
struct path path;
|
||||||
mm_segment_t saved_fs;
|
mm_segment_t saved_fs;
|
||||||
int rc;
|
int rc;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* user_path_dir() and __user_walk() both expect 'filename' to be
|
* user_path_dir() and __user_walk() both expect 'filename' to be
|
||||||
|
@ -795,11 +779,11 @@ vn_set_pwd(const char *filename)
|
||||||
|
|
||||||
rc = user_path_dir(filename, &path);
|
rc = user_path_dir(filename, &path);
|
||||||
if (rc)
|
if (rc)
|
||||||
SGOTO(out, rc);
|
goto out;
|
||||||
|
|
||||||
rc = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS);
|
rc = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS);
|
||||||
if (rc)
|
if (rc)
|
||||||
SGOTO(dput_and_out, rc);
|
goto dput_and_out;
|
||||||
|
|
||||||
vn_set_fs_pwd(current->fs, &path);
|
vn_set_fs_pwd(current->fs, &path);
|
||||||
|
|
||||||
|
@ -808,7 +792,7 @@ dput_and_out:
|
||||||
out:
|
out:
|
||||||
set_fs(saved_fs);
|
set_fs(saved_fs);
|
||||||
|
|
||||||
SRETURN(-rc);
|
return (-rc);
|
||||||
} /* vn_set_pwd() */
|
} /* vn_set_pwd() */
|
||||||
EXPORT_SYMBOL(vn_set_pwd);
|
EXPORT_SYMBOL(vn_set_pwd);
|
||||||
|
|
||||||
|
@ -853,7 +837,6 @@ vn_file_cache_destructor(void *buf, void *cdrarg)
|
||||||
int
|
int
|
||||||
spl_vn_init(void)
|
spl_vn_init(void)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
vn_cache = kmem_cache_create("spl_vn_cache",
|
vn_cache = kmem_cache_create("spl_vn_cache",
|
||||||
sizeof(struct vnode), 64,
|
sizeof(struct vnode), 64,
|
||||||
vn_cache_constructor,
|
vn_cache_constructor,
|
||||||
|
@ -865,7 +848,7 @@ spl_vn_init(void)
|
||||||
vn_file_cache_constructor,
|
vn_file_cache_constructor,
|
||||||
vn_file_cache_destructor,
|
vn_file_cache_destructor,
|
||||||
NULL, NULL, NULL, KMC_KMEM);
|
NULL, NULL, NULL, KMC_KMEM);
|
||||||
SRETURN(0);
|
return (0);
|
||||||
} /* vn_init() */
|
} /* vn_init() */
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -873,7 +856,6 @@ spl_vn_fini(void)
|
||||||
{
|
{
|
||||||
file_t *fp, *next_fp;
|
file_t *fp, *next_fp;
|
||||||
int leaked = 0;
|
int leaked = 0;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
spin_lock(&vn_file_lock);
|
spin_lock(&vn_file_lock);
|
||||||
|
|
||||||
|
@ -886,11 +868,10 @@ spl_vn_fini(void)
|
||||||
spin_unlock(&vn_file_lock);
|
spin_unlock(&vn_file_lock);
|
||||||
|
|
||||||
if (leaked > 0)
|
if (leaked > 0)
|
||||||
SWARN("Warning %d files leaked\n", leaked);
|
printk(KERN_WARNING "WARNING: %d vnode files leaked\n", leaked);
|
||||||
|
|
||||||
kmem_cache_destroy(vn_file_cache);
|
kmem_cache_destroy(vn_file_cache);
|
||||||
kmem_cache_destroy(vn_cache);
|
kmem_cache_destroy(vn_cache);
|
||||||
|
|
||||||
SEXIT;
|
|
||||||
return;
|
return;
|
||||||
} /* vn_fini() */
|
} /* vn_fini() */
|
||||||
|
|
|
@ -27,13 +27,6 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <rpc/types.h>
|
#include <rpc/types.h>
|
||||||
#include <rpc/xdr.h>
|
#include <rpc/xdr.h>
|
||||||
#include <spl-debug.h>
|
|
||||||
|
|
||||||
#ifdef SS_DEBUG_SUBSYS
|
|
||||||
#undef SS_DEBUG_SUBSYS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SS_DEBUG_SUBSYS SS_XDR
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SPL's XDR mem implementation.
|
* SPL's XDR mem implementation.
|
||||||
|
@ -150,7 +143,6 @@ xdrmem_create(XDR *xdrs, const caddr_t addr, const uint_t size,
|
||||||
xdrs->x_ops = &xdrmem_decode_ops;
|
xdrs->x_ops = &xdrmem_decode_ops;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
SWARN("Invalid op value: %d\n", op);
|
|
||||||
xdrs->x_ops = NULL; /* Let the caller know we failed */
|
xdrs->x_ops = NULL; /* Let the caller know we failed */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -160,7 +152,6 @@ xdrmem_create(XDR *xdrs, const caddr_t addr, const uint_t size,
|
||||||
xdrs->x_addr_end = addr + size;
|
xdrs->x_addr_end = addr + size;
|
||||||
|
|
||||||
if (xdrs->x_addr_end < xdrs->x_addr) {
|
if (xdrs->x_addr_end < xdrs->x_addr) {
|
||||||
SWARN("Overflow while creating xdrmem: %p, %u\n", addr, size);
|
|
||||||
xdrs->x_ops = NULL;
|
xdrs->x_ops = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,10 +162,8 @@ xdrmem_control(XDR *xdrs, int req, void *info)
|
||||||
{
|
{
|
||||||
struct xdr_bytesrec *rec = (struct xdr_bytesrec *) info;
|
struct xdr_bytesrec *rec = (struct xdr_bytesrec *) info;
|
||||||
|
|
||||||
if (req != XDR_GET_BYTES_AVAIL) {
|
if (req != XDR_GET_BYTES_AVAIL)
|
||||||
SWARN("Called with unknown request: %d\n", req);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
rec->xc_is_last_record = TRUE; /* always TRUE in xdrmem streams */
|
rec->xc_is_last_record = TRUE; /* always TRUE in xdrmem streams */
|
||||||
rec->xc_num_avail = xdrs->x_addr_end - xdrs->x_addr;
|
rec->xc_num_avail = xdrs->x_addr_end - xdrs->x_addr;
|
||||||
|
|
|
@ -55,13 +55,6 @@
|
||||||
|
|
||||||
#include <sys/kmem.h>
|
#include <sys/kmem.h>
|
||||||
#include <sys/zmod.h>
|
#include <sys/zmod.h>
|
||||||
#include <spl-debug.h>
|
|
||||||
|
|
||||||
#ifdef DEBUG_SUBSYSTEM
|
|
||||||
#undef DEBUG_SUBSYSTEM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define DEBUG_SUBSYSTEM SS_ZLIB
|
|
||||||
|
|
||||||
static spl_kmem_cache_t *zlib_workspace_cache;
|
static spl_kmem_cache_t *zlib_workspace_cache;
|
||||||
|
|
||||||
|
@ -200,7 +193,6 @@ int
|
||||||
spl_zlib_init(void)
|
spl_zlib_init(void)
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
SENTRY;
|
|
||||||
|
|
||||||
size = MAX(spl_zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL),
|
size = MAX(spl_zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL),
|
||||||
zlib_inflate_workspacesize());
|
zlib_inflate_workspacesize());
|
||||||
|
@ -210,16 +202,14 @@ spl_zlib_init(void)
|
||||||
size, 0, NULL, NULL, NULL, NULL, NULL,
|
size, 0, NULL, NULL, NULL, NULL, NULL,
|
||||||
KMC_VMEM | KMC_NOEMERGENCY);
|
KMC_VMEM | KMC_NOEMERGENCY);
|
||||||
if (!zlib_workspace_cache)
|
if (!zlib_workspace_cache)
|
||||||
SRETURN(1);
|
return (1);
|
||||||
|
|
||||||
SRETURN(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
spl_zlib_fini(void)
|
spl_zlib_fini(void)
|
||||||
{
|
{
|
||||||
SENTRY;
|
|
||||||
kmem_cache_destroy(zlib_workspace_cache);
|
kmem_cache_destroy(zlib_workspace_cache);
|
||||||
zlib_workspace_cache = NULL;
|
zlib_workspace_cache = NULL;
|
||||||
SEXIT;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#ifndef _SPLAT_INTERNAL_H
|
#ifndef _SPLAT_INTERNAL_H
|
||||||
#define _SPLAT_INTERNAL_H
|
#define _SPLAT_INTERNAL_H
|
||||||
|
|
||||||
#include "spl-debug.h"
|
|
||||||
#include "splat-ctl.h"
|
#include "splat-ctl.h"
|
||||||
#include <sys/mutex.h>
|
#include <sys/mutex.h>
|
||||||
|
|
||||||
|
|
|
@ -313,7 +313,7 @@ splat_kmem_cache_test_kct_alloc(kmem_cache_priv_t *kcp, int id)
|
||||||
{
|
{
|
||||||
kmem_cache_thread_t *kct;
|
kmem_cache_thread_t *kct;
|
||||||
|
|
||||||
ASSERTF(id < SPLAT_KMEM_THREADS, "id=%d\n", id);
|
ASSERT3S(id, <, SPLAT_KMEM_THREADS);
|
||||||
ASSERT(kcp->kcp_kct[id] == NULL);
|
ASSERT(kcp->kcp_kct[id] == NULL);
|
||||||
|
|
||||||
kct = kmem_zalloc(sizeof(kmem_cache_thread_t), KM_SLEEP);
|
kct = kmem_zalloc(sizeof(kmem_cache_thread_t), KM_SLEEP);
|
||||||
|
|
|
@ -37,10 +37,6 @@ PRE_BUILD="configure
|
||||||
then
|
then
|
||||||
echo --enable-debug
|
echo --enable-debug
|
||||||
fi
|
fi
|
||||||
if [[ \${SPL_DKMS_ENABLE_DEBUG_LOG,,} == @(y|yes) ]]
|
|
||||||
then
|
|
||||||
echo --enable-debug-log
|
|
||||||
fi
|
|
||||||
if [[ \${SPL_DKMS_ENABLE_DEBUG_KMEM,,} == @(y|yes) ]]
|
if [[ \${SPL_DKMS_ENABLE_DEBUG_KMEM,,} == @(y|yes) ]]
|
||||||
then
|
then
|
||||||
echo --enable-debug-kmem
|
echo --enable-debug-kmem
|
||||||
|
|
Loading…
Reference in New Issue