Many open source projects have moved to using SPDX identifiers to specify license information, reducing the amount of boilerplate code in every source file. This patch replaces the bulk of SPDK .c, .cpp and Makefiles with the BSD-3-Clause identifier. Almost all of these files share the exact same license text, and this patch only modifies the files that contain the most common license text. There can be slight variations because the third clause contains company names - most say "Intel Corporation", but there are instances for Nvidia, Samsung, Eideticom and even "the copyright holder". Used a bash script to automate replacement of the license text with SPDX identifier which is checked into scripts/spdx.sh. Signed-off-by: Jim Harris <james.r.harris@intel.com> Change-Id: Iaa88ab5e92ea471691dc298cfe41ebfb5d169780 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12904 Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com> Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-by: Dong Yi <dongx.yi@intel.com> Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com> Reviewed-by: Paul Luse <paul.e.luse@intel.com> Reviewed-by: <qun.wan@intel.com>
189 lines
4.5 KiB
C
189 lines
4.5 KiB
C
/* SPDX-License-Identifier: BSD-3-Clause
|
|
* Copyright (c) Intel Corporation.
|
|
* All rights reserved.
|
|
*
|
|
*/
|
|
|
|
#include "spdk/stdinc.h"
|
|
|
|
#include <accel-config/libaccel_config.h>
|
|
|
|
#include "spdk/env.h"
|
|
#include "spdk/util.h"
|
|
#include "spdk/memory.h"
|
|
#include "spdk/likely.h"
|
|
|
|
#include "spdk/log.h"
|
|
#include "spdk_internal/idxd.h"
|
|
|
|
#include "idxd.h"
|
|
|
|
struct spdk_kernel_idxd_device {
|
|
struct spdk_idxd_device idxd;
|
|
struct accfg_ctx *ctx;
|
|
|
|
unsigned int max_batch_size;
|
|
unsigned int max_xfer_size;
|
|
unsigned int max_xfer_bits;
|
|
|
|
/* We only use a single WQ */
|
|
struct accfg_wq *wq;
|
|
int fd;
|
|
void *portal;
|
|
};
|
|
|
|
#define __kernel_idxd(idxd) SPDK_CONTAINEROF(idxd, struct spdk_kernel_idxd_device, idxd)
|
|
|
|
static void
|
|
kernel_idxd_device_destruct(struct spdk_idxd_device *idxd)
|
|
{
|
|
struct spdk_kernel_idxd_device *kernel_idxd = __kernel_idxd(idxd);
|
|
|
|
if (kernel_idxd->portal != NULL) {
|
|
munmap(kernel_idxd->portal, 0x1000);
|
|
}
|
|
|
|
if (kernel_idxd->fd >= 0) {
|
|
close(kernel_idxd->fd);
|
|
}
|
|
|
|
accfg_unref(kernel_idxd->ctx);
|
|
free(kernel_idxd);
|
|
}
|
|
|
|
static struct spdk_idxd_impl g_kernel_idxd_impl;
|
|
|
|
static int
|
|
kernel_idxd_probe(void *cb_ctx, spdk_idxd_attach_cb attach_cb, spdk_idxd_probe_cb probe_cb)
|
|
{
|
|
int rc;
|
|
struct accfg_ctx *ctx;
|
|
struct accfg_device *device;
|
|
|
|
rc = accfg_new(&ctx);
|
|
if (rc < 0) {
|
|
SPDK_ERRLOG("Unable to allocate accel-config context\n");
|
|
return rc;
|
|
}
|
|
|
|
/* Loop over each IDXD device */
|
|
accfg_device_foreach(ctx, device) {
|
|
enum accfg_device_state dstate;
|
|
struct spdk_kernel_idxd_device *kernel_idxd;
|
|
struct accfg_wq *wq;
|
|
|
|
/* Make sure that the device is enabled */
|
|
dstate = accfg_device_get_state(device);
|
|
if (dstate != ACCFG_DEVICE_ENABLED) {
|
|
continue;
|
|
}
|
|
|
|
kernel_idxd = calloc(1, sizeof(struct spdk_kernel_idxd_device));
|
|
if (kernel_idxd == NULL) {
|
|
SPDK_ERRLOG("Failed to allocate memory for kernel_idxd device.\n");
|
|
/* TODO: Goto error cleanup */
|
|
return -ENOMEM;
|
|
}
|
|
|
|
kernel_idxd->max_batch_size = accfg_device_get_max_batch_size(device);
|
|
kernel_idxd->max_xfer_size = accfg_device_get_max_transfer_size(device);
|
|
kernel_idxd->idxd.socket_id = accfg_device_get_numa_node(device);
|
|
kernel_idxd->idxd.impl = &g_kernel_idxd_impl;
|
|
kernel_idxd->fd = -1;
|
|
|
|
accfg_wq_foreach(device, wq) {
|
|
enum accfg_wq_state wstate;
|
|
enum accfg_wq_mode mode;
|
|
enum accfg_wq_type type;
|
|
int major, minor;
|
|
char path[1024];
|
|
|
|
wstate = accfg_wq_get_state(wq);
|
|
if (wstate != ACCFG_WQ_ENABLED) {
|
|
continue;
|
|
}
|
|
|
|
type = accfg_wq_get_type(wq);
|
|
if (type != ACCFG_WQT_USER) {
|
|
continue;
|
|
}
|
|
|
|
/* TODO: For now, only support dedicated WQ */
|
|
mode = accfg_wq_get_mode(wq);
|
|
if (mode != ACCFG_WQ_DEDICATED) {
|
|
continue;
|
|
}
|
|
|
|
major = accfg_device_get_cdev_major(device);
|
|
if (major < 0) {
|
|
continue;
|
|
}
|
|
|
|
minor = accfg_wq_get_cdev_minor(wq);
|
|
if (minor < 0) {
|
|
continue;
|
|
}
|
|
|
|
/* Map the portal */
|
|
snprintf(path, sizeof(path), "/dev/char/%u:%u", major, minor);
|
|
kernel_idxd->fd = open(path, O_RDWR);
|
|
if (kernel_idxd->fd < 0) {
|
|
SPDK_ERRLOG("Can not open the WQ file descriptor on path=%s\n",
|
|
path);
|
|
continue;
|
|
}
|
|
|
|
kernel_idxd->portal = mmap(NULL, 0x1000, PROT_WRITE,
|
|
MAP_SHARED | MAP_POPULATE, kernel_idxd->fd, 0);
|
|
if (kernel_idxd->portal == MAP_FAILED) {
|
|
perror("mmap");
|
|
continue;
|
|
}
|
|
|
|
kernel_idxd->wq = wq;
|
|
|
|
/* Since we only use a single WQ, the total size is the size of this WQ */
|
|
kernel_idxd->idxd.total_wq_size = accfg_wq_get_size(wq);
|
|
kernel_idxd->idxd.chan_per_device = (kernel_idxd->idxd.total_wq_size >= 128) ? 8 : 4;
|
|
/* TODO: Handle BOF when we add support for shared WQ */
|
|
/* wq_ctx->bof = accfg_wq_get_block_on_fault(wq); */
|
|
|
|
/* We only use a single WQ, so once we've found one we can stop looking. */
|
|
break;
|
|
}
|
|
|
|
if (kernel_idxd->idxd.total_wq_size > 0) {
|
|
/* This device has at least 1 WQ available, so ask the user if they want to use it. */
|
|
attach_cb(cb_ctx, &kernel_idxd->idxd);
|
|
} else {
|
|
kernel_idxd_device_destruct(&kernel_idxd->idxd);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
kernel_idxd_dump_sw_error(struct spdk_idxd_device *idxd, void *portal)
|
|
{
|
|
/* Need to be enhanced later */
|
|
}
|
|
|
|
static char *
|
|
kernel_idxd_portal_get_addr(struct spdk_idxd_device *idxd)
|
|
{
|
|
struct spdk_kernel_idxd_device *kernel_idxd = __kernel_idxd(idxd);
|
|
|
|
return kernel_idxd->portal;
|
|
}
|
|
|
|
static struct spdk_idxd_impl g_kernel_idxd_impl = {
|
|
.name = "kernel",
|
|
.probe = kernel_idxd_probe,
|
|
.destruct = kernel_idxd_device_destruct,
|
|
.dump_sw_error = kernel_idxd_dump_sw_error,
|
|
.portal_get_addr = kernel_idxd_portal_get_addr,
|
|
};
|
|
|
|
SPDK_IDXD_IMPL_REGISTER(kernel, &g_kernel_idxd_impl);
|