Skip to content
This repository was archived by the owner on Feb 26, 2020. It is now read-only.

Commit

Permalink
Multi-buffer sha256 support in SPL to ZFS
Browse files Browse the repository at this point in the history
This patch implements multi-buffer hash facilities to export a general
SHA256 api to ZFS. When multibuffer hash is configured in SPL, its
SHA256 api for ZFS will automaticlly transfer SHA256 compute task to
multi-buffer hash facilities which will increase SHA256 performance
2~7 times.

ISA-L multi-buffer hash provides software acceleration for SHA256:
https://github.com/01org/isa-l_crypto
* To enable multi-buffer hash acceleration, you need to download ISA-L
crypto lib source code from above link and checkout master branch.
* Configure multi-buffer hash in SPL, e.g.:
 ./configure --with-hash-mb=<isa-l-crypto-code-path>
 make
  Following make notice, run:
 make -C <isa-l-crypto-code-path> -f Makefile.kern kernobj
 Then, continue run:
 make
* After that, a C predefine marco HAVE_HASH_MB and C api mulbuf_sha256
will be exported out to ZFS module

Signed-off-by: Xiaodong Liu <[email protected]>
  • Loading branch information
dong-liuliu committed Aug 23, 2017
1 parent 9df9692 commit ac18a8f
Show file tree
Hide file tree
Showing 14 changed files with 2,378 additions and 0 deletions.
73 changes: 73 additions & 0 deletions config/spl-build.m4
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
KERNELCPPFLAGS="$KERNELCPPFLAGS -Wstrict-prototypes"
AC_SUBST(KERNELCPPFLAGS)
SPL_AC_HASH_MB
SPL_AC_DEBUG
SPL_AC_DEBUG_KMEM
SPL_AC_DEBUG_KMEM_TRACKING
Expand Down Expand Up @@ -187,6 +188,55 @@ AC_DEFUN([SPL_AC_KERNEL], [
SPL_AC_MODULE_SYMVERS
])

dnl #
dnl # Detect ISA-L multi-buffer hash
dnl # ISA-L multi-buffer hash provides software acceleration for SHA256:
dnl # https://github.com/01org/isa-l_crypto
dnl # * Download ISA-L crypto lib source code from above link and checkout
dnl # master branch.
dnl # * Enable multi-buffer hash in SPL, e.g.:
dnl # ./configure --with-hash-mb=<isa-l-crypto-code-path>
dnl # make
dnl # Following make notice, run:
dnl # make -C <isa-l-crypto-code-path> -f Makefile.kern kernobj
dnl # Then, continue run:
dnl # make
dnl #
dnl # Then multi-buffer hash facility is built into SPL and exported sha256
dnl # API out to ZFS.
dnl # * To disable multi-buffer hash facility:
dnl # modprobe spl spl_hash_mb_disable=1
dnl #
AC_DEFUN([SPL_AC_HASH_MB], [
AC_ARG_WITH([hash_mb],
AS_HELP_STRING([--with-hash-mb=PATH],
[Path to isa-l crypto source]),
[hash_mb_src="$withval"])
AS_IF([test ! -z "${hash_mb_src}"], [
AC_MSG_CHECKING([hash-mb source directory])
AC_MSG_RESULT([$hash_mb_src])
HASH_MB_SRC="${hash_mb_src}"
AS_IF([ test ! -e "$HASH_MB_SRC/include/multi_buffer.h"], [
AC_MSG_ERROR([
*** Please make sure the isa-l crypto source is downloaded
*** and specify the location of its source with the
*** '--with-hash-mb=PATH' option then try again. Failed to
*** find multi_buffer.h in:
${HASH_MB_SRC}/include])
])
])
AS_IF([test ! -z "${hash_mb_src}"], [
AC_SUBST(HASH_MB_SRC)
AC_DEFINE(HAVE_HASH_MB, 1,
[multi-buffer hash is enabled])
SPL_AC_FPU_HEADER
])
])


dnl #
dnl # Default SPL user configuration
dnl #
Expand Down Expand Up @@ -429,6 +479,10 @@ AC_DEFUN([SPL_AC_CONFIG], [
AM_CONDITIONAL([CONFIG_KERNEL],
[test "$SPL_CONFIG" = kernel -o "$SPL_CONFIG" = all] &&
[test "x$enable_linux_builtin" != xyes ])
AM_CONDITIONAL([CONFIG_HASH_MB],
[test "$SPL_CONFIG" = kernel -o "$SPL_CONFIG" = all] &&
[test "x$hash_mb_src" != x])
])

dnl #
Expand Down Expand Up @@ -1395,6 +1449,25 @@ AC_DEFUN([SPL_AC_SCHED_RT_HEADER],
])
])

dnl #
dnl # 4.1 API change,
dnl # Moved things from asm/i387.h to asm/fpu/api.h
dnl #
AC_DEFUN([SPL_AC_FPU_HEADER],
[AC_MSG_CHECKING([whether header asm/fpu/api.h exists])
SPL_LINUX_TRY_COMPILE([
#include <linux/types.h>
#include <asm/fpu/api.h>
],[
return 0;
],[
AC_DEFINE(HAVE_FPU_HEADER, 1, [asm/fpu/api.h exists])
AC_MSG_RESULT(yes)
],[
AC_MSG_RESULT(no)
])
])

dnl #
dnl # 4.11 API change,
dnl # Moved things from linux/sched.h to linux/sched/signal.h
Expand Down
5 changes: 5 additions & 0 deletions include/sys/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ KERNEL_H = \
$(top_srcdir)/include/sys/modctl.h \
$(top_srcdir)/include/sys/mode.h \
$(top_srcdir)/include/sys/mount.h \
$(top_srcdir)/include/sys/multi_buffer.h \
$(top_srcdir)/include/sys/mulbuf_queue_sha256.h \
$(top_srcdir)/include/sys/mulbuf_queue.h \
$(top_srcdir)/include/sys/mulbuf_thdpool.h \
$(top_srcdir)/include/sys/mutex.h \
$(top_srcdir)/include/sys/note.h \
$(top_srcdir)/include/sys/open.h \
Expand All @@ -70,6 +74,7 @@ KERNEL_H = \
$(top_srcdir)/include/sys/resource.h \
$(top_srcdir)/include/sys/rwlock.h \
$(top_srcdir)/include/sys/sdt.h \
$(top_srcdir)/include/sys/sha256_mb.h \
$(top_srcdir)/include/sys/sid.h \
$(top_srcdir)/include/sys/signal.h \
$(top_srcdir)/include/sys/stat.h \
Expand Down
95 changes: 95 additions & 0 deletions include/sys/mulbuf_queue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*****************************************************************************\
* 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 <[email protected]>.
* 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_MULBUF_QUEUE_H
#define _SPL_MULBUF_QUEUE_H

#if defined(__x86_64) && defined(__KERNEL__) && defined(HAVE_HASH_MB)

#include <linux/module.h>
#include <linux/gfp.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/kthread.h>
#include <sys/types.h>
#include <sys/thread.h>
#include <sys/rwlock.h>

#include "mulbuf_thdpool.h"

/* taskjob's callback function */
typedef struct mbtp_task mbtp_task_t;
typedef void (*mbtp_task_cb)(mbtp_task_t *mb_task, void *arg);


struct mbtp_task {
void *buffer;
size_t size;
unsigned char *digest;

mbtp_task_cb cb_fn; /* callback after task is completed or cancelled */
void *cb_arg;
int processsed; /* 1 if processed by hash fn, 2 if cancelled by queue's close */

struct list_head queue_entry;
};

struct mbtp_queue{
char *queue_name; /* queue name */
struct list_head plthread_list;
int curr_threadcnt; /* current thread count attached to this queue */
int idle_threadcnt; /* thread in queue, but not running hash-mb-proc-fn */
int max_threadcnt; /* max thread count doing jobs */
int min_threadcnt; /* min thread count waiting to do job */

struct list_head task_list;
int curr_taskcnt; /* task count attached to this queue, waiting to be processed */
int proc_taskcnt; /* task count in processing */
int total_taskcnt; /* task count processed */

mulbuf_thdpool_t *pool;
int leave; /* 1 means this queue is going to leave */

threadp_func_t thread_fn; /* which function queue's thread should run */

spinlock_t queue_lock;
wait_queue_head_t queue_waitq;
};

int mbtp_queue_create(mbtp_queue_t **queue_r, const char *name, mulbuf_thdpool_t *pool,
int min_threadcnt, int max_threadcnt, threadp_func_t hash_mb_fn);
void mbtp_queue_destroy(mbtp_queue_t *queue);

int mbtp_queue_assign_taskjobcnt(mbtp_queue_t *queue, int process_num, int concurrent_num);

int mbtp_queue_add_thread(mbtp_queue_t *queue);
void mbtp_queue_shrink_thread(mbtp_queue_t *queue, mbtp_thread_t *tpt);
int mbtp_queue_check_add_thread(mbtp_queue_t *queue, int concurrent_num);
int mbtp_queue_check_shrink_thread(mbtp_queue_t *queue, int concurrent_num);

void mbtp_queue_submit_job(mbtp_task_t *mb_task, mbtp_queue_t *queue);

#endif /* __KERNEL__ && __x86_64 && HAVE_HASH_MB */

#endif /* _SPL_MULBUF_QUEUE_H */
57 changes: 57 additions & 0 deletions include/sys/mulbuf_queue_sha256.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*****************************************************************************\
* 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 <[email protected]>.
* 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 MULBUF_QUEUE_SHA256_H_
#define MULBUF_QUEUE_SHA256_H_

#if defined(__x86_64) && defined(__KERNEL__) && defined(HAVE_HASH_MB)

#include <linux/interrupt.h>
#include <linux/kthread.h>
#include <sys/kmem.h>
#include <sys/mulbuf_queue.h>

void mulbuf_sha256_fn(void *args);

int mulbuf_suite_sha256_init(void);
void mulbuf_suite_sha256_fini(void);

int mulbuf_sha256_queue_choose(void *buffer, size_t size,
unsigned char *digest, mbtp_queue_t *queue);
int mulbuf_sha256(void *buffer, size_t size, unsigned char *digest);

#else

static inline int mulbuf_suite_sha256_init(void)
{
return 0;
}
static inline void mulbuf_suite_sha256_fini(void)
{
return;
}

#endif /* __KERNEL__ && __x86_64 && HAVE_HASH_MB */

#endif /* MULBUF_QUEUE_SHA256_H_ */
105 changes: 105 additions & 0 deletions include/sys/mulbuf_thdpool.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*****************************************************************************\
* 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 <[email protected]>.
* 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_MULBUF_THDPOOL_H
#define _SPL_MULBUF_THDPOOL_H

#if defined(__x86_64) && defined(__KERNEL__) && defined(HAVE_HASH_MB)

#include <linux/module.h>
#include <linux/gfp.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/kthread.h>
#include <linux/mutex.h>
#include <sys/types.h>
#include <sys/thread.h>
#include <sys/rwlock.h>


typedef void (*threadp_func_t)(void *);
typedef struct mulbuf_thdpool mulbuf_thdpool_t; /* thread pool for multi-buffer crypto */
typedef struct mbtp_thread mbtp_thread_t; /* thread for multi-buffer thread pool */
typedef struct mbtp_queue mbtp_queue_t; /* task queue for mb thread pool */

typedef enum mbtp_thd_state {
THREAD_SETUP,
THREAD_READY,
THREAD_RUNNING,
THREAD_EXIT
} mbtp_thd_state_t;


struct mbtp_thread {
struct list_head pool_entry;
mulbuf_thdpool_t *pool;
struct list_head queue_entry;
mbtp_queue_t *queue;

spinlock_t thd_lock;
wait_queue_head_t thread_waitq;

struct task_struct *tp_thread;
mbtp_thd_state_t curr_state;
mbtp_thd_state_t next_state;

threadp_func_t fn;
void *arg;
};

struct mulbuf_thdpool {
char *pool_name; /* thread pool name */
int curr_threadcnt; /* current thread count */
int max_threadcnt; /* max thread count, if 0, then unlimited */
int idle_threadcnt; /* idle thread count */

spinlock_t pool_lock;
unsigned long pool_lock_flags; /* interrupt state */
wait_queue_head_t pool_waitq;

struct list_head plthread_idle_list; /* idle thread not attached to any queue */
struct list_head plthread_busy_list; /* busy thread attached to one queue */
};

/* Initialize thread pool */
int mulbuf_thdpool_create(mulbuf_thdpool_t **pool_r, const char *name, int threadcnt, int max_threadcnt);

/* Destroy thread pool */
void mulbuf_thdpool_destroy(mulbuf_thdpool_t *pool);

/*
* Get a valid thread from pool
* return 0 if success
*/
int mulbuf_thdpool_get_thread(mulbuf_thdpool_t *pool, mbtp_thread_t **tpt_r);

/* Get a valid thread from pool */
void mbtp_thread_run_fn(mbtp_thread_t *tpt, threadp_func_t fn, void *arg);

/* Return a valid thread to its pool */
void mulbuf_thdpool_put_thread(mbtp_thread_t *tpt);

#endif /* __KERNEL__ && __x86_64 && HAVE_HASH_MB */

#endif /* _SPL_MULBUF_THDPOOL_H */
Loading

0 comments on commit ac18a8f

Please sign in to comment.