Skip to content

Commit

Permalink
Add libtpool (thread pools)
Browse files Browse the repository at this point in the history
OpenZFS provides a library called tpool which implements thread
pools for user space applications.  Porting this library means
the zpool utility no longer needs to borrow the kernel mutex and
taskq interfaces from libzpool.  This code was updated to use
the tpool library which behaves in a very similar fashion.

Porting libtpool was relatively straight forward and minimal
modifications were needed.  The core changes were:

* Fully convert the library to use pthreads.
* Updated signal handling.
* lmalloc/lfree converted to calloc/free
* Implemented portable pthread_attr_clone() function.

Finally, update the build system such that libzpool.so is no
longer linked in to zfs(8), zpool(8), etc.  All that is required
is libzfs to which the zcommon soures were added (which is the way
it always should have been).  Removing the libzpool dependency
resulted in several build issues which needed to be resolved.

* Moved zfeature support to module/zcommon/zfeature_common.c
* Moved ratelimiting to to module/zfs/zfs_ratelimit.c
* Moved get_system_hostid() to lib/libspl/gethostid.c
* Removed use of cmn_err() in zcommon source
* Removed dprintf_setup() call from zpool_main.c and zfs_main.c
* Removed highbit() and lowbit()
* Removed unnecessary library dependencies from Makefiles
* Removed fletcher-4 kstat in user space
* Added sha2 support explicitly to libzfs
* Added highbit64() and lowbit64() to zpool_util.c

Reviewed-by: Tony Hutter <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #6442
  • Loading branch information
behlendorf authored Aug 9, 2017
1 parent 5146d80 commit 46364cb
Show file tree
Hide file tree
Showing 46 changed files with 1,191 additions and 410 deletions.
5 changes: 1 addition & 4 deletions cmd/mount_zfs/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,4 @@ mount_zfs_SOURCES = \

mount_zfs_LDADD = \
$(top_builddir)/lib/libnvpair/libnvpair.la \
$(top_builddir)/lib/libuutil/libuutil.la \
$(top_builddir)/lib/libzpool/libzpool.la \
$(top_builddir)/lib/libzfs/libzfs.la \
$(top_builddir)/lib/libzfs_core/libzfs_core.la
$(top_builddir)/lib/libzfs/libzfs.la
2 changes: 0 additions & 2 deletions cmd/raidz_test/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ raidz_test_SOURCES = \
raidz_bench.c

raidz_test_LDADD = \
$(top_builddir)/lib/libnvpair/libnvpair.la \
$(top_builddir)/lib/libuutil/libuutil.la \
$(top_builddir)/lib/libzpool/libzpool.la

raidz_test_LDADD += -lm -ldl
4 changes: 1 addition & 3 deletions cmd/zdb/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,5 @@ zdb_SOURCES = \

zdb_LDADD = \
$(top_builddir)/lib/libnvpair/libnvpair.la \
$(top_builddir)/lib/libuutil/libuutil.la \
$(top_builddir)/lib/libzpool/libzpool.la \
$(top_builddir)/lib/libzfs/libzfs.la \
$(top_builddir)/lib/libzfs_core/libzfs_core.la
$(top_builddir)/lib/libzpool/libzpool.la
9 changes: 3 additions & 6 deletions cmd/zed/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,12 @@ FMA_SRC = \
zed_SOURCES = $(ZED_SRC) $(FMA_SRC)

zed_LDADD = \
$(top_builddir)/lib/libavl/libavl.la \
$(top_builddir)/lib/libnvpair/libnvpair.la \
$(top_builddir)/lib/libspl/libspl.la \
$(top_builddir)/lib/libuutil/libuutil.la \
$(top_builddir)/lib/libzpool/libzpool.la \
$(top_builddir)/lib/libzfs/libzfs.la \
$(top_builddir)/lib/libzfs_core/libzfs_core.la
$(top_builddir)/lib/libzfs/libzfs.la

zed_LDFLAGS = -lrt -pthread
zed_LDADD += -lrt
zed_LDFLAGS = -pthread

zedconfdir = $(sysconfdir)/zfs/zed.d

Expand Down
3 changes: 0 additions & 3 deletions cmd/zfs/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,5 @@ zfs_SOURCES = \
zfs_LDADD = \
$(top_builddir)/lib/libnvpair/libnvpair.la \
$(top_builddir)/lib/libuutil/libuutil.la \
$(top_builddir)/lib/libzpool/libzpool.la \
$(top_builddir)/lib/libzfs/libzfs.la \
$(top_builddir)/lib/libzfs_core/libzfs_core.la

zfs_LDFLAGS = -pthread
3 changes: 1 addition & 2 deletions cmd/zfs/zfs_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/fs/zfs.h>
#include <sys/systeminfo.h>
#include <sys/types.h>
#include <time.h>

Expand Down Expand Up @@ -7045,8 +7046,6 @@ main(int argc, char **argv)
(void) setlocale(LC_ALL, "");
(void) textdomain(TEXT_DOMAIN);

dprintf_setup(&argc, argv);

opterr = 0;

/*
Expand Down
4 changes: 1 addition & 3 deletions cmd/zhack/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,5 @@ zhack_SOURCES = \

zhack_LDADD = \
$(top_builddir)/lib/libnvpair/libnvpair.la \
$(top_builddir)/lib/libuutil/libuutil.la \
$(top_builddir)/lib/libzpool/libzpool.la \
$(top_builddir)/lib/libzfs/libzfs.la \
$(top_builddir)/lib/libzfs_core/libzfs_core.la
$(top_builddir)/lib/libzpool/libzpool.la
4 changes: 1 addition & 3 deletions cmd/zinject/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,5 @@ zinject_SOURCES = \

zinject_LDADD = \
$(top_builddir)/lib/libnvpair/libnvpair.la \
$(top_builddir)/lib/libuutil/libuutil.la \
$(top_builddir)/lib/libzpool/libzpool.la \
$(top_builddir)/lib/libzfs/libzfs.la \
$(top_builddir)/lib/libzfs_core/libzfs_core.la
$(top_builddir)/lib/libzpool/libzpool.la
7 changes: 3 additions & 4 deletions cmd/zpool/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@ zpool_SOURCES = \
zpool_LDADD = \
$(top_builddir)/lib/libnvpair/libnvpair.la \
$(top_builddir)/lib/libuutil/libuutil.la \
$(top_builddir)/lib/libzpool/libzpool.la \
$(top_builddir)/lib/libzfs/libzfs.la \
$(top_builddir)/lib/libzfs_core/libzfs_core.la \
-lm $(LIBBLKID)
$(top_builddir)/lib/libzfs/libzfs.la

zpool_LDADD += -lm $(LIBBLKID)

zpoolconfdir = $(sysconfdir)/zfs/zpool.d
zpoolexecdir = $(libexecdir)/zfs/zpool.d
Expand Down
28 changes: 8 additions & 20 deletions cmd/zpool/zpool_iter.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <thread_pool.h>

#include <libzfs.h>
#include <sys/zfs_context.h>
Expand Down Expand Up @@ -668,34 +669,21 @@ all_pools_for_each_vdev_gather_cb(zpool_handle_t *zhp, void *cb_vcdl)
static void
all_pools_for_each_vdev_run_vcdl(vdev_cmd_data_list_t *vcdl)
{
taskq_t *t;
int i;
/* 5 * boot_ncpus selfishly chosen since it works best on LLNL's HW */
int max_threads = 5 * boot_ncpus;

/*
* Under Linux we use a taskq to parallelize running a command
* on each vdev. It is therefore necessary to initialize this
* functionality for the duration of the threads.
*/
thread_init();
tpool_t *t;

t = taskq_create("z_pool_cmd", max_threads, defclsyspri, max_threads,
INT_MAX, 0);
t = tpool_create(1, 5 * sysconf(_SC_NPROCESSORS_ONLN), 0, NULL);
if (t == NULL)
return;

/* Spawn off the command for each vdev */
for (i = 0; i < vcdl->count; i++) {
(void) taskq_dispatch(t, vdev_run_cmd_thread,
(void *) &vcdl->data[i], TQ_SLEEP);
for (int i = 0; i < vcdl->count; i++) {
(void) tpool_dispatch(t, vdev_run_cmd_thread,
(void *) &vcdl->data[i]);
}

/* Wait for threads to finish */
taskq_wait(t);
taskq_destroy(t);
thread_fini();

tpool_wait(t);
tpool_destroy(t);
}

/*
Expand Down
11 changes: 1 addition & 10 deletions cmd/zpool/zpool_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include <zfs_prop.h>
#include <sys/fs/zfs.h>
#include <sys/stat.h>
#include <sys/systeminfo.h>
#include <sys/fm/fs/zfs.h>
#include <sys/fm/util.h>
#include <sys/fm/protocol.h>
Expand Down Expand Up @@ -2645,15 +2646,7 @@ zpool_do_import(int argc, char **argv)
idata.cachefile = cachefile;
idata.scan = do_scan;

/*
* Under Linux the zpool_find_import_impl() function leverages the
* taskq implementation to parallelize device scanning. It is
* therefore necessary to initialize this functionality for the
* duration of the zpool_search_import() function.
*/
thread_init();
pools = zpool_search_import(g_zfs, &idata);
thread_fini();

if (pools != NULL && idata.exists &&
(argc == 1 || strcmp(argv[0], argv[1]) == 0)) {
Expand Down Expand Up @@ -7968,8 +7961,6 @@ main(int argc, char **argv)
(void) textdomain(TEXT_DOMAIN);
srand(time(NULL));

dprintf_setup(&argc, argv);

opterr = 0;

/*
Expand Down
26 changes: 26 additions & 0 deletions cmd/zpool/zpool_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,29 @@ isnumber(char *str)

return (1);
}

/*
* Find highest one bit set.
* Returns bit number + 1 of highest bit that is set, otherwise returns 0.
*/
int
highbit64(uint64_t i)
{
if (i == 0)
return (0);

return (NBBY * sizeof (uint64_t) - __builtin_clzll(i));
}

/*
* Find lowest one bit set.
* Returns bit number + 1 of lowest bit that is set, otherwise returns 0.
*/
int
lowbit64(uint64_t i)
{
if (i == 0)
return (0);

return (__builtin_ffsll(i));
}
2 changes: 2 additions & 0 deletions cmd/zpool/zpool_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ void zpool_no_memory(void);
uint_t num_logs(nvlist_t *nv);
uint64_t array64_max(uint64_t array[], unsigned int len);
int isnumber(char *str);
int highbit64(uint64_t i);
int lowbit64(uint64_t i);

/*
* Misc utility functions
Expand Down
5 changes: 1 addition & 4 deletions cmd/zstreamdump/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,4 @@ zstreamdump_SOURCES = \

zstreamdump_LDADD = \
$(top_builddir)/lib/libnvpair/libnvpair.la \
$(top_builddir)/lib/libuutil/libuutil.la \
$(top_builddir)/lib/libzpool/libzpool.la \
$(top_builddir)/lib/libzfs/libzfs.la \
$(top_builddir)/lib/libzfs_core/libzfs_core.la
$(top_builddir)/lib/libzfs/libzfs.la
5 changes: 2 additions & 3 deletions cmd/ztest/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ ztest_SOURCES = \

ztest_LDADD = \
$(top_builddir)/lib/libnvpair/libnvpair.la \
$(top_builddir)/lib/libuutil/libuutil.la \
$(top_builddir)/lib/libzpool/libzpool.la \
$(top_builddir)/lib/libzfs/libzfs.la \
$(top_builddir)/lib/libzfs_core/libzfs_core.la
$(top_builddir)/lib/libzpool/libzpool.la

ztest_LDADD += -lm
ztest_LDFLAGS = -pthread
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ AC_CONFIG_FILES([
lib/libefi/Makefile
lib/libicp/Makefile
lib/libnvpair/Makefile
lib/libtpool/Makefile
lib/libunicode/Makefile
lib/libuutil/Makefile
lib/libzpool/Makefile
Expand Down
3 changes: 2 additions & 1 deletion include/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ USER_H = \
$(top_srcdir)/include/libuutil_impl.h \
$(top_srcdir)/include/libzfs.h \
$(top_srcdir)/include/libzfs_core.h \
$(top_srcdir)/include/libzfs_impl.h
$(top_srcdir)/include/libzfs_impl.h \
$(top_srcdir)/include/thread_pool.h

EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)

Expand Down
1 change: 0 additions & 1 deletion include/libzfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,6 @@ typedef enum {
ZPOOL_STATUS_OK
} zpool_status_t;

extern unsigned long get_system_hostid(void);
extern zpool_status_t zpool_get_status(zpool_handle_t *, char **,
zpool_errata_t *);
extern zpool_status_t zpool_import_status(nvlist_t *, char **,
Expand Down
4 changes: 0 additions & 4 deletions include/sys/zfs_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -668,15 +668,11 @@ extern uint64_t physmem;

extern int highbit64(uint64_t i);
extern int lowbit64(uint64_t i);
extern int highbit(ulong_t i);
extern int lowbit(ulong_t i);
extern int random_get_bytes(uint8_t *ptr, size_t len);
extern int random_get_pseudo_bytes(uint8_t *ptr, size_t len);

extern void kernel_init(int);
extern void kernel_fini(void);
extern void thread_init(void);
extern void thread_fini(void);
extern void random_init(void);
extern void random_fini(void);

Expand Down
72 changes: 72 additions & 0 deletions include/thread_pool.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/

/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/

#ifndef _THREAD_POOL_H_
#define _THREAD_POOL_H_

#include <sys/types.h>
#include <thread.h>
#include <pthread.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct tpool tpool_t; /* opaque thread pool descriptor */

#if defined(__STDC__)

extern tpool_t *tpool_create(uint_t min_threads, uint_t max_threads,
uint_t linger, pthread_attr_t *attr);
extern int tpool_dispatch(tpool_t *tpool,
void (*func)(void *), void *arg);
extern void tpool_destroy(tpool_t *tpool);
extern void tpool_abandon(tpool_t *tpool);
extern void tpool_wait(tpool_t *tpool);
extern void tpool_suspend(tpool_t *tpool);
extern int tpool_suspended(tpool_t *tpool);
extern void tpool_resume(tpool_t *tpool);
extern int tpool_member(tpool_t *tpool);

#else /* Non ANSI */

extern tpool_t *tpool_create();
extern int tpool_dispatch();
extern void tpool_destroy();
extern void tpool_abandon();
extern void tpool_wait();
extern void tpool_suspend();
extern int tpool_suspended();
extern void tpool_resume();
extern int tpool_member();

#endif /* __STDC__ */

#ifdef __cplusplus
}
#endif

#endif /* _THREAD_POOL_H_ */
2 changes: 1 addition & 1 deletion lib/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# NB: GNU Automake Manual, Chapter 8.3.5: Libtool Convenience Libraries
# These six libraries are intermediary build components.
SUBDIRS = libspl libavl libefi libshare libunicode libicp
SUBDIRS = libavl libefi libicp libshare libspl libtpool libunicode

# These four libraries, which are installed as the final build product,
# incorporate the six convenience libraries given above.
Expand Down
4 changes: 1 addition & 3 deletions lib/libnvpair/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ nodist_libnvpair_la_SOURCES = \
$(USER_C) \
$(KERNEL_C)

libnvpair_la_LIBADD = \
$(top_builddir)/lib/libuutil/libuutil.la \
$(LIBTIRPC)
libnvpair_la_LIBADD = $(LIBTIRPC)
libnvpair_la_LDFLAGS = -version-info 1:1:0

EXTRA_DIST = $(USER_C)
1 change: 1 addition & 0 deletions lib/libspl/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ noinst_LTLIBRARIES = libspl.la

USER_C = \
getexecname.c \
gethostid.c \
gethrtime.c \
gethrestime.c \
getmntany.c \
Expand Down
Loading

0 comments on commit 46364cb

Please sign in to comment.