Commit 1dbf53ee authored by Piotr Pelplinski's avatar Piotr Pelplinski Committed by Jim Harris
Browse files

vhost: add a library and app for userspace vhost-scsi processing



This patch adds a library, application and test scripts for extending
SPDK to present virtio-scsi controllers to QEMU-based VMs and
process I/O submitted to devices attached to those controllers.
This functionality is dependent on QEMU patches to enable
vhost-scsi in userspace - those patches are currently working their
way through the QEMU mailing list, but temporary patches to enable
this functionality in QEMU will be made available shortly through the
SPDK github repository.

Signed-off-by: default avatarJim Harris <james.r.harris@intel.com>
Signed-off-by: default avatarKrzysztof Jakimiak <krzysztof.jakimiak@intel.com>
Signed-off-by: default avatarMichal Kosciowski <michal.kosciowski@intel.com>
Signed-off-by: default avatarKarol Latecki <karolx.latecki@intel.com>
Signed-off-by: default avatarPiotr Pelplinski <piotr.pelplinski@intel.com>
Signed-off-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Signed-off-by: default avatarPawel Wodkowski <pawelx.wodkowski@intel.com>
Signed-off-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>

Signed-off-by: default avatarKrzysztof Jakimiak <krzysztof.jakimiak@intel.com>
Change-Id: I138e4021f0ac4b1cd9a6e4041783cdf06e6f0efb
parent 16bbcb3f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ DIRS-y += trace
DIRS-y += nvmf_tgt
DIRS-y += iscsi_top
ifeq ($(OS),Linux)
DIRS-y += iscsi_tgt
DIRS-y += iscsi_tgt vhost
endif

.PHONY: all clean $(DIRS-y)

app/vhost/Makefile

0 → 100644
+62 −0
Original line number Diff line number Diff line
#
#  BSD LICENSE
#
#  Copyright (c) Intel Corporation.
#  All rights reserved.
#
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions
#  are met:
#
#    * Redistributions of source code must retain the above copyright
#      notice, this list of conditions and the following disclaimer.
#    * Redistributions in binary form must reproduce the above copyright
#      notice, this list of conditions and the following disclaimer in
#      the documentation and/or other materials provided with the
#      distribution.
#    * Neither the name of Intel Corporation nor the names of its
#      contributors may be used to endorse or promote products derived
#      from this software without specific prior written permission.
#
#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
#  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
#  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
#  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
#  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
#  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
#  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
#  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
#  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#

SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
include $(SPDK_ROOT_DIR)/mk/spdk.app.mk
include $(SPDK_ROOT_DIR)/mk/spdk.modules.mk

APP = vhost

CFLAGS += $(ENV_CFLAGS)

C_SRCS := vhost.c

SPDK_LIB_LIST = jsonrpc json rpc bdev_rpc bdev scsi net copy trace conf
SPDK_LIB_LIST += util log log_rpc event app_rpc
SPDK_LIB_LIST += vhost rte_vhost

LIBS += $(BLOCKDEV_MODULES_LINKER_ARGS) \
	$(COPY_MODULES_LINKER_ARGS)
LIBS += $(SPDK_LIB_LINKER_ARGS)
LIBS += $(ENV_LINKER_ARGS)

all : $(APP)

$(APP) : $(OBJS) $(SPDK_LIB_FILES) $(ENV_LIBS) $(BLOCKDEV_MODULES_FILES) $(COPY_MODULES_FILES)
	$(LINK_C)

clean :
	$(CLEAN_C) $(APP)

include $(SPDK_ROOT_DIR)/mk/spdk.deps.mk

app/vhost/vhost.c

0 → 100644
+164 −0
Original line number Diff line number Diff line
/*-
 *   BSD LICENSE
 *
 *   Copyright (c) Intel Corporation.
 *   All rights reserved.
 *
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following conditions
 *   are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in
 *       the documentation and/or other materials provided with the
 *       distribution.
 *     * Neither the name of Intel Corporation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <getopt.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>

#include "spdk/log.h"
#include "spdk/conf.h"
#include "spdk/event.h"

#include "spdk/vhost.h"


#define SPDK_VHOST_DEFAULT_CONFIG "/usr/local/etc/spdk/vhost.conf"
#define SPDK_VHOST_DEFAULT_ENABLE_COREDUMP true
#define SPDK_VHOST_DEFAULT_MEM_SIZE 1024

static void
vhost_app_opts_init(struct spdk_app_opts *opts)
{
	spdk_app_opts_init(opts);
	opts->name = "vhost";
	opts->config_file = SPDK_VHOST_DEFAULT_CONFIG;
	opts->dpdk_mem_size = SPDK_VHOST_DEFAULT_MEM_SIZE;
}

static void
usage(char *executable_name)
{
	struct spdk_app_opts defaults;

	vhost_app_opts_init(&defaults);

	printf("%s [options]\n", executable_name);
	printf("options:\n");
	printf(" -c config  config file (default: %s)\n", defaults.config_file);
	printf(" -e mask    tracepoint group mask for spdk trace buffers (default: 0x0)\n");
	printf(" -m mask    reactor core mask (default: 0x1)\n");
	printf(" -l facility use specific syslog facility (default: %s)\n", defaults.log_facility);
	printf(" -n channel number of memory channels used for DPDK\n");
	printf(" -p core    master (primary) core for DPDK\n");
	printf(" -s size    memory size in MB for DPDK (default: %dMB)\n", defaults.dpdk_mem_size);
	printf(" -S dir     directory where to create vhost sockets (default: pwd)\n");
	spdk_tracelog_usage(stdout, "-t");
	printf(" -h         show this usage\n");
	printf(" -d         disable coredump file enabling\n");
	printf(" -q         disable notice level logging to stderr\n");
}

int
main(int argc, char *argv[])
{
	struct spdk_app_opts opts = {};
	char ch;
	int rc;
	const char *socket_path = NULL;

	vhost_app_opts_init(&opts);

	while ((ch = getopt(argc, argv, "c:de:l:m:p:qs:S:t:h")) != -1) {
		switch (ch) {
		case 'c':
			opts.config_file = optarg;
			break;
		case 'd':
			opts.enable_coredump = false;
			break;
		case 'e':
			opts.tpoint_group_mask = optarg;
			break;
		case 'h':
			usage(argv[0]);
			exit(EXIT_SUCCESS);
		case 'l':
			opts.log_facility = optarg;
			break;
		case 'm':
			opts.reactor_mask = optarg;
			break;
		case 'p':
			opts.dpdk_master_core = strtoul(optarg, NULL, 10);
			break;
		case 'q':
			spdk_g_notice_stderr_flag = 0;
			break;
		case 's':
			opts.dpdk_mem_size = strtoul(optarg, NULL, 10);
			break;
		case 'S':
			socket_path = optarg;
			break;
		case 't':
			rc = spdk_log_set_trace_flag(optarg);
			if (rc < 0) {
				fprintf(stderr, "unknown flag\n");
				usage(argv[0]);
				exit(EXIT_FAILURE);
			}
#ifndef DEBUG
			fprintf(stderr, "%s must be rebuilt with CONFIG_DEBUG=y for -t flag.\n",
				argv[0]);
			usage(argv[0]);
			exit(EXIT_FAILURE);
#endif
			break;
		default:
			fprintf(stderr, "%s Unknown option '-%c'.\n", argv[0], ch);
			usage(argv[0]);
			exit(EXIT_FAILURE);
		}
	}

	if (spdk_g_notice_stderr_flag == 1 &&
	    isatty(STDERR_FILENO) &&
	    !strncmp(ttyname(STDERR_FILENO), "/dev/tty", strlen("/dev/tty"))) {
		printf("Warning: printing stderr to console terminal without -q option specified.\n");
		printf("Suggest using -q to disable logging to stderr and monitor syslog, or\n");
		printf("redirect stderr to a file.\n");
		printf("(Delaying for 10 seconds...)\n");
		sleep(10);
	}

	opts.shutdown_cb = spdk_vhost_shutdown_cb;
	spdk_app_init(&opts);

	/* Blocks until the application is exiting */
	rc = spdk_app_start(spdk_vhost_startup, (void *)socket_path, NULL);

	spdk_app_fini();

	return rc;
}
+4 −0
Original line number Diff line number Diff line
@@ -137,6 +137,10 @@ timing_exit host

timing_exit nvmf

timing_enter vhost
run_test ./test/vhost/spdk_vhost.sh --integrity
timing_exit vhost

timing_enter cleanup
rbd_cleanup
./scripts/setup.sh reset

etc/spdk/vhost.conf.in

0 → 100644
+133 −0
Original line number Diff line number Diff line
# SPDK vhost configuration file
#
# Please write all parameters using ASCII.
# The parameter must be quoted if it includes whitespace.

# Configuration syntax:
# Leading whitespace is ignored.
# Lines starting with '#' are comments.
# Lines ending with '\' are concatenated with the next line.
# Bracketed ([]) names define sections

[Global]
  # Instance ID for multi-process support
  # Default: 0
  #InstanceID 0

  # Users can restrict work items to only run on certain cores by
  #  specifying a ReactorMask.  Default is to allow work items to run
  #  on core 0.
  #ReactorMask 0xFFFF

  # Tracepoint group mask for spdk trace buffers
  # Default: 0x0 (all tracepoint groups disabled)
  # Set to 0xFFFFFFFFFFFFFFFF to enable all tracepoint groups.
  #TpointGroupMask 0x0

  # syslog facility
   LogFacility "local7"

[Rpc]
  # Defines whether SPDK vhost will enable configuration via RPC.
  # Default is disabled.  Note that the RPC interface is not
  # authenticated, so users should be careful about enabling
  # RPC in non-trusted environments.
  Enable No
  # Listen address for the RPC service.
  # May be an IP address or an absolute path to a Unix socket.
  Listen 127.0.0.1

# Users may not want to use offload even it is available.
# Users may use the whitelist to initialize specified devices, IDS
#  uses BUS:DEVICE.FUNCTION to identify each Ioat channel.
[Ioat]
  Disable Yes
  #Whitelist 00:04.0
  #Whitelist 00:04.1

# Users must change this section to match the /dev/sdX devices to be
#  exported as vhost scsi drives. The devices are accessed using Linux AIO.
[AIO]
  #AIO /dev/sdb
  #AIO /dev/sdc

# Users may change this section to create a different number or size of
#  malloc LUNs.
# If the system has hardware DMA engine, it will use an IOAT
# (i.e. Crystal Beach DMA) channel to do the copy instead of memcpy.
# Of course, users can disable offload even it is available.
[Malloc]
  # Number of Malloc targets
  NumberOfLuns 3
  # Malloc targets are 128M
  LunSizeInMB 128
  # Block size. Default is 512 bytes.
  BlockSize 4096

# NVMe configuration options
[Nvme]
  # NVMe Device Whitelist
  # Users may specify which NVMe devices to claim by their PCI
  # domain, bus, device, and function. The format is dddd:bb:dd.f, which is
  # the same format displayed by lspci or in /sys/bus/pci/devices. The second
  # argument is a "name" for the device that can be anything. The name
  # is referenced later in the Subsystem section.
  #
  # Alternatively, the user can specify ClaimAllDevices. All
  # NVMe devices will be claimed and named Nvme0, Nvme1, etc.
  #BDF 0000:81:00.0 Nvme0
  #BDF 0000:01:00.0 Nvme1
  ClaimAllDevices

  # The number of attempts per I/O when an I/O fails. Do not include
  # this key to get the default behavior.
  NvmeRetryCount 4
  # The maximum number of NVMe controllers to claim. Do not include this key to
  # claim all of them.
  NumControllers 2
  # Registers the application to receive timeout callback and to reset the controller.
  ResetControllerOnTimeout Yes
  # Timeout value.
  NvmeTimeoutValue 30
  # Set how often the admin queue is polled for asynchronous events.
  # Units in microseconds.
  AdminPollRate 100000

# The Split virtual block device slices block devices into multiple smaller bdevs.
[Split]
  # Syntax:
  #   Split <bdev> <count> [<size_in_megabytes>]
  #
  # Split Nvme1n1 into two equally-sized portions, Nvme1n1p0 and Nvme1n1p1
  #Split Nvme1n1 2

  # Split Malloc2 into eight 1-megabyte portions, Malloc2p0 ... Malloc2p7,
  # leaving the rest of the device inaccessible
  #Split Malloc2 8 1

# Vhost scsi controller configuration
# Users should change the VhostScsi section(s) below to match the desired
# vhost configuration.
# Name is minimum required
[VhostScsi0]
  # Define name for controller
  Name vhost.0
  # Assign devices from backend
  # Use the first malloc device
  Dev0 Malloc0
  # Use the first AIO device
  #Dev1 AIO0
  # Use the frist Nvme device
  #Dev2 Nvme0n1
  # Use the third partition from second Nvme device
  #Dev3 Nvme1n1p2

  # Start the poller for this vhost controller on one of the cores in
  #  this cpumask.  By default, it not specified, will use any core in the
  #  SPDK process.
  #Cpumask 0x1

#[VhostScsi1]
#  Name vhost.1
#  Dev0 AIO1
#  Cpumask 0x1
Loading