From 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 20:24:20 +0200 Subject: Adding upstream version 14.2.21. Signed-off-by: Daniel Baumann --- src/spdk/dpdk/drivers/bus/vdev/Makefile | 30 ++ src/spdk/dpdk/drivers/bus/vdev/meson.build | 7 + src/spdk/dpdk/drivers/bus/vdev/rte_bus_vdev.h | 162 ++++++ .../dpdk/drivers/bus/vdev/rte_bus_vdev_version.map | 18 + src/spdk/dpdk/drivers/bus/vdev/vdev.c | 549 +++++++++++++++++++++ src/spdk/dpdk/drivers/bus/vdev/vdev_logs.h | 16 + 6 files changed, 782 insertions(+) create mode 100644 src/spdk/dpdk/drivers/bus/vdev/Makefile create mode 100644 src/spdk/dpdk/drivers/bus/vdev/meson.build create mode 100644 src/spdk/dpdk/drivers/bus/vdev/rte_bus_vdev.h create mode 100644 src/spdk/dpdk/drivers/bus/vdev/rte_bus_vdev_version.map create mode 100644 src/spdk/dpdk/drivers/bus/vdev/vdev.c create mode 100644 src/spdk/dpdk/drivers/bus/vdev/vdev_logs.h (limited to 'src/spdk/dpdk/drivers/bus/vdev') diff --git a/src/spdk/dpdk/drivers/bus/vdev/Makefile b/src/spdk/dpdk/drivers/bus/vdev/Makefile new file mode 100644 index 00000000..bd0bb895 --- /dev/null +++ b/src/spdk/dpdk/drivers/bus/vdev/Makefile @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2017 Intel Corporation + +include $(RTE_SDK)/mk/rte.vars.mk + +# +# library name +# +LIB = librte_bus_vdev.a + +CFLAGS += -O3 +CFLAGS += $(WERROR_FLAGS) +CFLAGS += -DALLOW_EXPERIMENTAL_API + +# versioning export map +EXPORT_MAP := rte_bus_vdev_version.map + +# library version +LIBABIVER := 1 + +SRCS-y += vdev.c + +LDLIBS += -lrte_eal + +# +# Export include files +# +SYMLINK-y-include += rte_bus_vdev.h + +include $(RTE_SDK)/mk/rte.lib.mk diff --git a/src/spdk/dpdk/drivers/bus/vdev/meson.build b/src/spdk/dpdk/drivers/bus/vdev/meson.build new file mode 100644 index 00000000..2ee648b4 --- /dev/null +++ b/src/spdk/dpdk/drivers/bus/vdev/meson.build @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2017 Intel Corporation + +sources = files('vdev.c') +install_headers('rte_bus_vdev.h') + +allow_experimental_apis = true diff --git a/src/spdk/dpdk/drivers/bus/vdev/rte_bus_vdev.h b/src/spdk/dpdk/drivers/bus/vdev/rte_bus_vdev.h new file mode 100644 index 00000000..9ae3eaae --- /dev/null +++ b/src/spdk/dpdk/drivers/bus/vdev/rte_bus_vdev.h @@ -0,0 +1,162 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2016 RehiveTech. All rights reserved. + */ + +#ifndef RTE_VDEV_H +#define RTE_VDEV_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +struct rte_vdev_device { + TAILQ_ENTRY(rte_vdev_device) next; /**< Next attached vdev */ + struct rte_device device; /**< Inherit core device */ +}; + +/** + * @internal + * Helper macro for drivers that need to convert to struct rte_vdev_device. + */ +#define RTE_DEV_TO_VDEV(ptr) \ + container_of(ptr, struct rte_vdev_device, device) + +#define RTE_DEV_TO_VDEV_CONST(ptr) \ + container_of(ptr, const struct rte_vdev_device, device) + +static inline const char * +rte_vdev_device_name(const struct rte_vdev_device *dev) +{ + if (dev && dev->device.name) + return dev->device.name; + return NULL; +} + +static inline const char * +rte_vdev_device_args(const struct rte_vdev_device *dev) +{ + if (dev && dev->device.devargs) + return dev->device.devargs->args; + return ""; +} + +/** Double linked list of virtual device drivers. */ +TAILQ_HEAD(vdev_driver_list, rte_vdev_driver); + +/** + * Probe function called for each virtual device driver once. + */ +typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev); + +/** + * Remove function called for each virtual device driver once. + */ +typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev); + +/** + * A virtual device driver abstraction. + */ +struct rte_vdev_driver { + TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */ + struct rte_driver driver; /**< Inherited general driver. */ + rte_vdev_probe_t *probe; /**< Virtual device probe function. */ + rte_vdev_remove_t *remove; /**< Virtual device remove function. */ +}; + +/** + * Register a virtual device driver. + * + * @param driver + * A pointer to a rte_vdev_driver structure describing the driver + * to be registered. + */ +void rte_vdev_register(struct rte_vdev_driver *driver); + +/** + * Unregister a virtual device driver. + * + * @param driver + * A pointer to a rte_vdev_driver structure describing the driver + * to be unregistered. + */ +void rte_vdev_unregister(struct rte_vdev_driver *driver); + +#define RTE_PMD_REGISTER_VDEV(nm, vdrv)\ +static const char *vdrvinit_ ## nm ## _alias;\ +RTE_INIT(vdrvinitfn_ ##vdrv)\ +{\ + (vdrv).driver.name = RTE_STR(nm);\ + (vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\ + rte_vdev_register(&vdrv);\ +} \ +RTE_PMD_EXPORT_NAME(nm, __COUNTER__) + +#define RTE_PMD_REGISTER_ALIAS(nm, alias)\ +static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias) + +typedef void (*rte_vdev_scan_callback)(void *user_arg); + +/** + * Add a callback to be called on vdev scan + * before reading the devargs list. + * + * This function cannot be called in a scan callback + * because of deadlock. + * + * @param callback + * The function to be called which can update the devargs list. + * @param user_arg + * An opaque pointer passed to callback. + * @return + * 0 on success, negative on error + */ +int +rte_vdev_add_custom_scan(rte_vdev_scan_callback callback, void *user_arg); + +/** + * Remove a registered scan callback. + * + * This function cannot be called in a scan callback + * because of deadlock. + * + * @param callback + * The registered function to be removed. + * @param user_arg + * The associated opaque pointer or (void*)-1 for any. + * @return + * 0 on success + */ +int +rte_vdev_remove_custom_scan(rte_vdev_scan_callback callback, void *user_arg); + +/** + * Initialize a driver specified by name. + * + * @param name + * The pointer to a driver name to be initialized. + * @param args + * The pointer to arguments used by driver initialization. + * @return + * 0 on success, negative on error + */ +int rte_vdev_init(const char *name, const char *args); + +/** + * Uninitalize a driver specified by name. + * + * @param name + * The pointer to a driver name to be initialized. + * @return + * 0 on success, negative on error + */ +int rte_vdev_uninit(const char *name); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/spdk/dpdk/drivers/bus/vdev/rte_bus_vdev_version.map b/src/spdk/dpdk/drivers/bus/vdev/rte_bus_vdev_version.map new file mode 100644 index 00000000..590cf9b4 --- /dev/null +++ b/src/spdk/dpdk/drivers/bus/vdev/rte_bus_vdev_version.map @@ -0,0 +1,18 @@ +DPDK_17.11 { + global: + + rte_vdev_init; + rte_vdev_register; + rte_vdev_uninit; + rte_vdev_unregister; + + local: *; +}; + +DPDK_18.02 { + global: + + rte_vdev_add_custom_scan; + rte_vdev_remove_custom_scan; + +} DPDK_17.11; diff --git a/src/spdk/dpdk/drivers/bus/vdev/vdev.c b/src/spdk/dpdk/drivers/bus/vdev/vdev.c new file mode 100644 index 00000000..1cdffd43 --- /dev/null +++ b/src/spdk/dpdk/drivers/bus/vdev/vdev.c @@ -0,0 +1,549 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2016 RehiveTech. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rte_bus_vdev.h" +#include "vdev_logs.h" + +#define VDEV_MP_KEY "bus_vdev_mp" + +int vdev_logtype_bus; + +/* Forward declare to access virtual bus name */ +static struct rte_bus rte_vdev_bus; + +/** Double linked list of virtual device drivers. */ +TAILQ_HEAD(vdev_device_list, rte_vdev_device); + +static struct vdev_device_list vdev_device_list = + TAILQ_HEAD_INITIALIZER(vdev_device_list); +/* The lock needs to be recursive because a vdev can manage another vdev. */ +static rte_spinlock_recursive_t vdev_device_list_lock = + RTE_SPINLOCK_RECURSIVE_INITIALIZER; + +struct vdev_driver_list vdev_driver_list = + TAILQ_HEAD_INITIALIZER(vdev_driver_list); + +struct vdev_custom_scan { + TAILQ_ENTRY(vdev_custom_scan) next; + rte_vdev_scan_callback callback; + void *user_arg; +}; +TAILQ_HEAD(vdev_custom_scans, vdev_custom_scan); +static struct vdev_custom_scans vdev_custom_scans = + TAILQ_HEAD_INITIALIZER(vdev_custom_scans); +static rte_spinlock_t vdev_custom_scan_lock = RTE_SPINLOCK_INITIALIZER; + +/* register a driver */ +void +rte_vdev_register(struct rte_vdev_driver *driver) +{ + TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next); +} + +/* unregister a driver */ +void +rte_vdev_unregister(struct rte_vdev_driver *driver) +{ + TAILQ_REMOVE(&vdev_driver_list, driver, next); +} + +int +rte_vdev_add_custom_scan(rte_vdev_scan_callback callback, void *user_arg) +{ + struct vdev_custom_scan *custom_scan; + + rte_spinlock_lock(&vdev_custom_scan_lock); + + /* check if already registered */ + TAILQ_FOREACH(custom_scan, &vdev_custom_scans, next) { + if (custom_scan->callback == callback && + custom_scan->user_arg == user_arg) + break; + } + + if (custom_scan == NULL) { + custom_scan = malloc(sizeof(struct vdev_custom_scan)); + if (custom_scan != NULL) { + custom_scan->callback = callback; + custom_scan->user_arg = user_arg; + TAILQ_INSERT_TAIL(&vdev_custom_scans, custom_scan, next); + } + } + + rte_spinlock_unlock(&vdev_custom_scan_lock); + + return (custom_scan == NULL) ? -1 : 0; +} + +int +rte_vdev_remove_custom_scan(rte_vdev_scan_callback callback, void *user_arg) +{ + struct vdev_custom_scan *custom_scan, *tmp_scan; + + rte_spinlock_lock(&vdev_custom_scan_lock); + TAILQ_FOREACH_SAFE(custom_scan, &vdev_custom_scans, next, tmp_scan) { + if (custom_scan->callback != callback || + (custom_scan->user_arg != (void *)-1 && + custom_scan->user_arg != user_arg)) + continue; + TAILQ_REMOVE(&vdev_custom_scans, custom_scan, next); + free(custom_scan); + } + rte_spinlock_unlock(&vdev_custom_scan_lock); + + return 0; +} + +static int +vdev_parse(const char *name, void *addr) +{ + struct rte_vdev_driver **out = addr; + struct rte_vdev_driver *driver = NULL; + + TAILQ_FOREACH(driver, &vdev_driver_list, next) { + if (strncmp(driver->driver.name, name, + strlen(driver->driver.name)) == 0) + break; + if (driver->driver.alias && + strncmp(driver->driver.alias, name, + strlen(driver->driver.alias)) == 0) + break; + } + if (driver != NULL && + addr != NULL) + *out = driver; + return driver == NULL; +} + +static int +vdev_probe_all_drivers(struct rte_vdev_device *dev) +{ + const char *name; + struct rte_vdev_driver *driver; + int ret; + + name = rte_vdev_device_name(dev); + + VDEV_LOG(DEBUG, "Search driver %s to probe device %s", name, + rte_vdev_device_name(dev)); + + if (vdev_parse(name, &driver)) + return -1; + dev->device.driver = &driver->driver; + ret = driver->probe(dev); + if (ret) + dev->device.driver = NULL; + return ret; +} + +/* The caller shall be responsible for thread-safe */ +static struct rte_vdev_device * +find_vdev(const char *name) +{ + struct rte_vdev_device *dev; + + if (!name) + return NULL; + + TAILQ_FOREACH(dev, &vdev_device_list, next) { + const char *devname = rte_vdev_device_name(dev); + + if (!strcmp(devname, name)) + return dev; + } + + return NULL; +} + +static struct rte_devargs * +alloc_devargs(const char *name, const char *args) +{ + struct rte_devargs *devargs; + int ret; + + devargs = calloc(1, sizeof(*devargs)); + if (!devargs) + return NULL; + + devargs->bus = &rte_vdev_bus; + if (args) + devargs->args = strdup(args); + else + devargs->args = strdup(""); + + ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name); + if (ret < 0 || ret >= (int)sizeof(devargs->name)) { + free(devargs->args); + free(devargs); + return NULL; + } + + return devargs; +} + +static int +insert_vdev(const char *name, const char *args, struct rte_vdev_device **p_dev) +{ + struct rte_vdev_device *dev; + struct rte_devargs *devargs; + int ret; + + if (name == NULL) + return -EINVAL; + + devargs = alloc_devargs(name, args); + if (!devargs) + return -ENOMEM; + + dev = calloc(1, sizeof(*dev)); + if (!dev) { + ret = -ENOMEM; + goto fail; + } + + dev->device.devargs = devargs; + dev->device.numa_node = SOCKET_ID_ANY; + dev->device.name = devargs->name; + + if (find_vdev(name)) { + ret = -EEXIST; + goto fail; + } + + TAILQ_INSERT_TAIL(&vdev_device_list, dev, next); + rte_devargs_insert(devargs); + + if (p_dev) + *p_dev = dev; + + return 0; +fail: + free(devargs->args); + free(devargs); + free(dev); + return ret; +} + +int +rte_vdev_init(const char *name, const char *args) +{ + struct rte_vdev_device *dev; + struct rte_devargs *devargs; + int ret; + + rte_spinlock_recursive_lock(&vdev_device_list_lock); + ret = insert_vdev(name, args, &dev); + if (ret == 0) { + ret = vdev_probe_all_drivers(dev); + if (ret) { + if (ret > 0) + VDEV_LOG(ERR, "no driver found for %s", name); + /* If fails, remove it from vdev list */ + devargs = dev->device.devargs; + TAILQ_REMOVE(&vdev_device_list, dev, next); + rte_devargs_remove(devargs->bus->name, devargs->name); + free(dev); + } + } + rte_spinlock_recursive_unlock(&vdev_device_list_lock); + return ret; +} + +static int +vdev_remove_driver(struct rte_vdev_device *dev) +{ + const char *name = rte_vdev_device_name(dev); + const struct rte_vdev_driver *driver; + + if (!dev->device.driver) { + VDEV_LOG(DEBUG, "no driver attach to device %s", name); + return 1; + } + + driver = container_of(dev->device.driver, const struct rte_vdev_driver, + driver); + return driver->remove(dev); +} + +int +rte_vdev_uninit(const char *name) +{ + struct rte_vdev_device *dev; + struct rte_devargs *devargs; + int ret; + + if (name == NULL) + return -EINVAL; + + rte_spinlock_recursive_lock(&vdev_device_list_lock); + + dev = find_vdev(name); + if (!dev) { + ret = -ENOENT; + goto unlock; + } + + ret = vdev_remove_driver(dev); + if (ret) + goto unlock; + + TAILQ_REMOVE(&vdev_device_list, dev, next); + devargs = dev->device.devargs; + rte_devargs_remove(devargs->bus->name, devargs->name); + free(dev); + +unlock: + rte_spinlock_recursive_unlock(&vdev_device_list_lock); + return ret; +} + +struct vdev_param { +#define VDEV_SCAN_REQ 1 +#define VDEV_SCAN_ONE 2 +#define VDEV_SCAN_REP 3 + int type; + int num; + char name[RTE_DEV_NAME_MAX_LEN]; +}; + +static int vdev_plug(struct rte_device *dev); + +/** + * This function works as the action for both primary and secondary process + * for static vdev discovery when a secondary process is booting. + * + * step 1, secondary process sends a sync request to ask for vdev in primary; + * step 2, primary process receives the request, and send vdevs one by one; + * step 3, primary process sends back reply, which indicates how many vdevs + * are sent. + */ +static int +vdev_action(const struct rte_mp_msg *mp_msg, const void *peer) +{ + struct rte_vdev_device *dev; + struct rte_mp_msg mp_resp; + struct vdev_param *ou = (struct vdev_param *)&mp_resp.param; + const struct vdev_param *in = (const struct vdev_param *)mp_msg->param; + const char *devname; + int num; + + strlcpy(mp_resp.name, VDEV_MP_KEY, sizeof(mp_resp.name)); + mp_resp.len_param = sizeof(*ou); + mp_resp.num_fds = 0; + + switch (in->type) { + case VDEV_SCAN_REQ: + ou->type = VDEV_SCAN_ONE; + ou->num = 1; + num = 0; + + rte_spinlock_recursive_lock(&vdev_device_list_lock); + TAILQ_FOREACH(dev, &vdev_device_list, next) { + devname = rte_vdev_device_name(dev); + if (strlen(devname) == 0) { + VDEV_LOG(INFO, "vdev with no name is not sent"); + continue; + } + VDEV_LOG(INFO, "send vdev, %s", devname); + strlcpy(ou->name, devname, RTE_DEV_NAME_MAX_LEN); + if (rte_mp_sendmsg(&mp_resp) < 0) + VDEV_LOG(ERR, "send vdev, %s, failed, %s", + devname, strerror(rte_errno)); + num++; + } + rte_spinlock_recursive_unlock(&vdev_device_list_lock); + + ou->type = VDEV_SCAN_REP; + ou->num = num; + if (rte_mp_reply(&mp_resp, peer) < 0) + VDEV_LOG(ERR, "Failed to reply a scan request"); + break; + case VDEV_SCAN_ONE: + VDEV_LOG(INFO, "receive vdev, %s", in->name); + if (insert_vdev(in->name, NULL, NULL) < 0) + VDEV_LOG(ERR, "failed to add vdev, %s", in->name); + break; + default: + VDEV_LOG(ERR, "vdev cannot recognize this message"); + } + + return 0; +} + +static int +vdev_scan(void) +{ + struct rte_vdev_device *dev; + struct rte_devargs *devargs; + struct vdev_custom_scan *custom_scan; + + if (rte_mp_action_register(VDEV_MP_KEY, vdev_action) < 0 && + rte_errno != EEXIST) { + VDEV_LOG(ERR, "Failed to add vdev mp action"); + return -1; + } + + if (rte_eal_process_type() == RTE_PROC_SECONDARY) { + struct rte_mp_msg mp_req, *mp_rep; + struct rte_mp_reply mp_reply; + struct timespec ts = {.tv_sec = 5, .tv_nsec = 0}; + struct vdev_param *req = (struct vdev_param *)mp_req.param; + struct vdev_param *resp; + + strlcpy(mp_req.name, VDEV_MP_KEY, sizeof(mp_req.name)); + mp_req.len_param = sizeof(*req); + mp_req.num_fds = 0; + req->type = VDEV_SCAN_REQ; + if (rte_mp_request_sync(&mp_req, &mp_reply, &ts) == 0 && + mp_reply.nb_received == 1) { + mp_rep = &mp_reply.msgs[0]; + resp = (struct vdev_param *)mp_rep->param; + VDEV_LOG(INFO, "Received %d vdevs", resp->num); + free(mp_reply.msgs); + } else + VDEV_LOG(ERR, "Failed to request vdev from primary"); + + /* Fall through to allow private vdevs in secondary process */ + } + + /* call custom scan callbacks if any */ + rte_spinlock_lock(&vdev_custom_scan_lock); + TAILQ_FOREACH(custom_scan, &vdev_custom_scans, next) { + if (custom_scan->callback != NULL) + /* + * the callback should update devargs list + * by calling rte_devargs_insert() with + * devargs.bus = rte_bus_find_by_name("vdev"); + * devargs.type = RTE_DEVTYPE_VIRTUAL; + * devargs.policy = RTE_DEV_WHITELISTED; + */ + custom_scan->callback(custom_scan->user_arg); + } + rte_spinlock_unlock(&vdev_custom_scan_lock); + + /* for virtual devices we scan the devargs_list populated via cmdline */ + RTE_EAL_DEVARGS_FOREACH("vdev", devargs) { + + dev = calloc(1, sizeof(*dev)); + if (!dev) + return -1; + + rte_spinlock_recursive_lock(&vdev_device_list_lock); + + if (find_vdev(devargs->name)) { + rte_spinlock_recursive_unlock(&vdev_device_list_lock); + free(dev); + continue; + } + + dev->device.devargs = devargs; + dev->device.numa_node = SOCKET_ID_ANY; + dev->device.name = devargs->name; + + TAILQ_INSERT_TAIL(&vdev_device_list, dev, next); + + rte_spinlock_recursive_unlock(&vdev_device_list_lock); + } + + return 0; +} + +static int +vdev_probe(void) +{ + struct rte_vdev_device *dev; + int ret = 0; + + /* call the init function for each virtual device */ + TAILQ_FOREACH(dev, &vdev_device_list, next) { + /* we don't use the vdev lock here, as it's only used in DPDK + * initialization; and we don't want to hold such a lock when + * we call each driver probe. + */ + + if (dev->device.driver) + continue; + + if (vdev_probe_all_drivers(dev)) { + VDEV_LOG(ERR, "failed to initialize %s device", + rte_vdev_device_name(dev)); + ret = -1; + } + } + + return ret; +} + +static struct rte_device * +vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp, + const void *data) +{ + const struct rte_vdev_device *vstart; + struct rte_vdev_device *dev; + + rte_spinlock_recursive_lock(&vdev_device_list_lock); + if (start != NULL) { + vstart = RTE_DEV_TO_VDEV_CONST(start); + dev = TAILQ_NEXT(vstart, next); + } else { + dev = TAILQ_FIRST(&vdev_device_list); + } + while (dev != NULL) { + if (cmp(&dev->device, data) == 0) + break; + dev = TAILQ_NEXT(dev, next); + } + rte_spinlock_recursive_unlock(&vdev_device_list_lock); + + return dev ? &dev->device : NULL; +} + +static int +vdev_plug(struct rte_device *dev) +{ + return vdev_probe_all_drivers(RTE_DEV_TO_VDEV(dev)); +} + +static int +vdev_unplug(struct rte_device *dev) +{ + return rte_vdev_uninit(dev->name); +} + +static struct rte_bus rte_vdev_bus = { + .scan = vdev_scan, + .probe = vdev_probe, + .find_device = vdev_find_device, + .plug = vdev_plug, + .unplug = vdev_unplug, + .parse = vdev_parse, +}; + +RTE_REGISTER_BUS(vdev, rte_vdev_bus); + +RTE_INIT(vdev_init_log) +{ + vdev_logtype_bus = rte_log_register("bus.vdev"); + if (vdev_logtype_bus >= 0) + rte_log_set_level(vdev_logtype_bus, RTE_LOG_NOTICE); +} diff --git a/src/spdk/dpdk/drivers/bus/vdev/vdev_logs.h b/src/spdk/dpdk/drivers/bus/vdev/vdev_logs.h new file mode 100644 index 00000000..87593741 --- /dev/null +++ b/src/spdk/dpdk/drivers/bus/vdev/vdev_logs.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2017 Intel Corporation + */ + +#ifndef _VDEV_LOGS_H_ +#define _VDEV_LOGS_H_ + +#include + +extern int vdev_logtype_bus; + +#define VDEV_LOG(level, fmt, args...) \ + rte_log(RTE_LOG_ ## level, vdev_logtype_bus, "%s(): " fmt "\n", \ + __func__, ##args) + +#endif /* _VDEV_LOGS_H_ */ -- cgit v1.2.3