@@ -55,6 +55,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += sw_evdev.c
SRCS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += sw_evdev_worker.c
SRCS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += sw_evdev_scheduler.c
SRCS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += sw_evdev_xstats.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += sw_evdev_timer_adapter.c
# export include files
SYMLINK-y-include +=
@@ -49,6 +49,8 @@
#define SCHED_QUANTA_ARG "sched_quanta"
#define CREDIT_QUANTA_ARG "credit_quanta"
+extern const struct rte_event_timer_adapter_ops sw_event_adapter_timer_ops;
+
static void
sw_info_get(struct rte_eventdev *dev, struct rte_event_dev_info *info);
@@ -733,6 +735,13 @@ static int32_t sw_sched_service_func(void *args)
}
static int
+sw_event_timer_adapter_ctrl(void *arg)
+{
+ *(const void **)arg = &sw_event_adapter_timer_ops;
+ return 0;
+}
+
+static int
sw_probe(struct rte_vdev_device *vdev)
{
static const struct rte_eventdev_ops evdev_sw_ops = {
@@ -756,6 +765,8 @@ sw_probe(struct rte_vdev_device *vdev)
.xstats_get_names = sw_xstats_get_names,
.xstats_get_by_name = sw_xstats_get_by_name,
.xstats_reset = sw_xstats_reset,
+
+ .event_timer_adapter_ctrl = sw_event_timer_adapter_ctrl,
};
static const char *const args[] = {
new file mode 100644
@@ -0,0 +1,124 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016-2017 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 <string.h>
+#include <stdbool.h>
+
+#include <rte_event_timer_adapter.h>
+#include <rte_event_timer_adapter_driver.h>
+#include <rte_service_component.h>
+#include <rte_service.h>
+#include <rte_log.h>
+
+static int
+event_timer_adapter_service_func(void *args)
+{
+ RTE_SET_USED(args);
+
+ return 0;
+}
+
+static int
+start_event_timer_adapter_service(struct rte_event_timer_adapter *adapter,
+ uint8_t id)
+{
+ RTE_SET_USED(adapter);
+ RTE_SET_USED(id);
+
+ RTE_SET_USED(event_timer_adapter_service_func);
+
+ return 0;
+}
+
+static int
+sw_event_timer_adapter_start(struct rte_event_timer_adapter *adapter)
+{
+ RTE_SET_USED(adapter);
+
+ RTE_SET_USED(start_event_timer_adapter_service);
+
+ return 0;
+}
+
+static int
+sw_event_timer_adapter_stop(struct rte_event_timer_adapter *adapter)
+{
+ RTE_SET_USED(adapter);
+
+ return 0;
+}
+
+static int
+sw_event_timer_arm_burst(struct rte_event_timer_adapter *adapter,
+ struct rte_event_timer **tims,
+ const uint16_t nb_tims)
+{
+ RTE_SET_USED(adapter);
+ RTE_SET_USED(tims);
+ RTE_SET_USED(nb_tims);
+
+ return 0;
+}
+
+static int
+sw_event_timer_arm_tmo_tick_burst(struct rte_event_timer_adapter *adapter,
+ struct rte_event_timer **tims,
+ const uint64_t timeout_tick,
+ const uint16_t nb_tims)
+{
+ RTE_SET_USED(adapter);
+ RTE_SET_USED(tims);
+ RTE_SET_USED(timeout_tick);
+ RTE_SET_USED(nb_tims);
+
+ return 0;
+}
+
+static int
+sw_event_timer_cancel_burst(struct rte_event_timer_adapter *adapter,
+ struct rte_event_timer **tims,
+ const uint16_t nb_tims)
+{
+ RTE_SET_USED(adapter);
+ RTE_SET_USED(tims);
+ RTE_SET_USED(nb_tims);
+
+ return 0;
+}
+
+const struct rte_event_timer_adapter_ops sw_event_adapter_timer_ops = {
+ .adapter_start = sw_event_timer_adapter_start,
+ .adapter_stop = sw_event_timer_adapter_stop,
+ .event_timer_arm_burst = sw_event_timer_arm_burst,
+ .event_timer_arm_tmo_tick_burst = sw_event_timer_arm_tmo_tick_burst,
+ .event_timer_cancel_burst = sw_event_timer_cancel_burst,
+};
@@ -43,6 +43,7 @@ CFLAGS += $(WERROR_FLAGS)
# library source files
SRCS-y += rte_eventdev.c
SRCS-y += rte_event_ring.c
+SRCS-y += rte_event_timer_adapter.c
# export include files
SYMLINK-y-include += rte_eventdev.h
@@ -50,6 +51,8 @@ SYMLINK-y-include += rte_eventdev_pmd.h
SYMLINK-y-include += rte_eventdev_pmd_pci.h
SYMLINK-y-include += rte_eventdev_pmd_vdev.h
SYMLINK-y-include += rte_event_ring.h
+SYMLINK-y-include += rte_event_timer_adapter.h
+SYMLINK-y-include += rte_event_timer_adapter_driver.h
# versioning export map
EXPORT_MAP := rte_eventdev_version.map
new file mode 100644
@@ -0,0 +1,227 @@
+/*
+ * Copyright(c) 2017 Intel Corporation. All rights reserved.
+ * 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 <string.h>
+
+#include <rte_malloc.h>
+#include <rte_memzone.h>
+#include <rte_lcore.h>
+#include <rte_log.h>
+#include <rte_service_component.h>
+#include <rte_branch_prediction.h>
+
+#include "rte_eventdev_pmd.h"
+#include "rte_event_timer_adapter.h"
+#include "rte_event_timer_adapter_driver.h"
+
+#define RTE_EVENT_TIMER_ADAPTER_NUM_MAX 64
+
+static struct rte_event_timer_adapter *rte_event_timer_adapters;
+
+static inline int
+adapter_valid(uint16_t id)
+{
+ RTE_SET_USED(id);
+
+ return -1;
+}
+
+/* validate ID and retrieve adapter pointer, or return error value */
+#define ADAPTER_VALID_GET_OR_ERR_RET(id, adapter, retval) do { \
+ if (id >= RTE_EVENT_TIMER_ADAPTER_NUM_MAX || !adapter_valid(id)) \
+ return retval; \
+ adapter = &rte_event_timer_adapters[id]; \
+} while (0)
+
+
+static int
+default_port_conf_cb(uint16_t id, uint8_t event_dev_id, uint8_t event_port_id,
+ void *conf_arg)
+{
+ RTE_SET_USED(id);
+ RTE_SET_USED(event_dev_id);
+ RTE_SET_USED(event_port_id);
+ RTE_SET_USED(conf_arg);
+
+ return 0;
+}
+
+int
+rte_event_timer_adapter_create(struct rte_event_timer_adapter_conf *conf)
+{
+ /* TODO: check default values */
+ struct rte_event_port_conf port_conf = {
+ .new_event_threshold = 128,
+ .dequeue_depth = 32,
+ .enqueue_depth = 32
+ };
+
+ return rte_event_timer_adapter_create_ext(conf, default_port_conf_cb,
+ &port_conf);
+}
+
+int
+rte_event_timer_adapter_create_ext(struct rte_event_timer_adapter_conf *conf,
+ rte_event_timer_adapter_port_conf_cb_t conf_cb,
+ void *conf_arg)
+{
+ RTE_SET_USED(conf);
+ RTE_SET_USED(conf_cb);
+ RTE_SET_USED(conf_arg);
+
+ return 0;
+}
+
+int
+rte_event_timer_adapter_get_info(uint16_t id,
+ struct rte_event_timer_adapter_info *adapter_info)
+{
+
+ RTE_SET_USED(id);
+ RTE_SET_USED(adapter_info);
+
+ return 0;
+}
+
+int
+rte_event_timer_adapter_start(uint16_t id)
+{
+ const struct rte_event_timer_adapter_ops *ops = NULL;
+ struct rte_event_timer_adapter *adapter;
+
+ ADAPTER_VALID_GET_OR_ERR_RET(id, adapter, -EINVAL);
+
+ ops = rte_event_timer_adapter_ops_get(adapter);
+ if (unlikely(!ops))
+ return -1;
+ if (likely(!!ops->adapter_start))
+ return ops->adapter_start(adapter);
+
+ return -1;
+}
+
+int
+rte_event_timer_adapter_stop(uint16_t id)
+{
+ const struct rte_event_timer_adapter_ops *ops = NULL;
+ struct rte_event_timer_adapter *adapter;
+
+ ADAPTER_VALID_GET_OR_ERR_RET(id, adapter, -EINVAL);
+
+ ops = rte_event_timer_adapter_ops_get(adapter);
+ if (unlikely(!ops))
+ return -1;
+ if (likely(!!ops->adapter_stop))
+ return ops->adapter_stop(adapter);
+
+ return -1;
+}
+
+int
+rte_event_timer_adapter_free(uint16_t id)
+{
+ RTE_SET_USED(id);
+ return 0;
+}
+
+const struct rte_event_timer_adapter_ops *
+rte_event_timer_adapter_ops_get(struct rte_event_timer_adapter *adapter)
+{
+ struct rte_eventdev *evdev = &rte_eventdevs[adapter->event_dev_id];
+ struct rte_event_timer_adapter_ops *ops;
+ RTE_SET_USED(evdev);
+
+ if (unlikely(!evdev->dev_ops->event_timer_adapter_ctrl ||
+ evdev->dev_ops->event_timer_adapter_ctrl(&ops) || !ops))
+ return NULL;
+
+ return ops;
+}
+
+int
+rte_event_timer_arm_burst(uint16_t id,
+ struct rte_event_timer **tim,
+ uint16_t nb_tims)
+{
+ const struct rte_event_timer_adapter_ops *ops = NULL;
+ struct rte_event_timer_adapter *adapter;
+
+ ADAPTER_VALID_GET_OR_ERR_RET(id, adapter, -EINVAL);
+
+ ops = rte_event_timer_adapter_ops_get(adapter);
+ if (unlikely(!ops))
+ return -1;
+ if (likely(!!ops->event_timer_arm_burst))
+ return ops->event_timer_arm_burst(adapter, tim, nb_tims);
+
+ return -1;
+}
+
+int
+rte_event_timer_arm_tmo_tick_burst(uint16_t id,
+ struct rte_event_timer **tim,
+ const uint64_t timeout_tick,
+ uint16_t nb_tims)
+{
+ const struct rte_event_timer_adapter_ops *ops = NULL;
+ struct rte_event_timer_adapter *adapter;
+
+ ADAPTER_VALID_GET_OR_ERR_RET(id, adapter, -EINVAL);
+
+ ops = rte_event_timer_adapter_ops_get(adapter);
+ if (unlikely(!ops))
+ return -1;
+ if (likely(!!ops->event_timer_arm_tmo_tick_burst))
+ return ops->event_timer_arm_tmo_tick_burst(adapter,
+ tim,
+ timeout_tick,
+ nb_tims);
+
+ return -1;
+}
+
+int rte_event_timer_cancel_burst(uint16_t id,
+ struct rte_event_timer **tim,
+ uint16_t nb_tims)
+{
+ const struct rte_event_timer_adapter_ops *ops = NULL;
+ struct rte_event_timer_adapter *adapter;
+
+ ADAPTER_VALID_GET_OR_ERR_RET(id, adapter, -EINVAL);
+
+ ops = rte_event_timer_adapter_ops_get(adapter);
+ if (unlikely(!ops))
+ return -1;
+ if (likely(!!ops->event_timer_cancel_burst))
+ return ops->event_timer_cancel_burst(adapter, tim, nb_tims);
+
+ return -1;
+}
new file mode 100644
@@ -0,0 +1,388 @@
+/*
+ * Copyright(c) 2017 Intel Corporation. All rights reserved.
+ * 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.
+ */
+
+#ifndef _RTE_EVENT_TIMER_ADAPTER_H_
+#define _RTE_EVENT_TIMER_ADAPTER_H_
+
+/**
+ * @file
+ *
+ * RTE Event Timer Adapter
+ *
+ * TODO: Update description
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "rte_eventdev.h"
+
+/*
+ * Timer adapter clock source
+ */
+enum rte_event_timer_adapter_clk_src {
+ RTE_EVENT_TIMER_ADAPTER_CPU_CLK,
+ /**< Use CPU clock as the clock source. */
+ RTE_EVENT_TIMER_ADAPTER_EXT_CLK0,
+ /**< Platform dependent external clock source 0. */
+ RTE_EVENT_TIMER_ADAPTER_EXT_CLK1,
+ /**< Platform dependent external clock source 1. */
+ RTE_EVENT_TIMER_ADAPTER_EXT_CLK2,
+ /**< Platform dependent external clock source 2. */
+ RTE_EVENT_TIMER_ADAPTER_EXT_CLK3,
+ /**< Platform dependent external clock source 3. */
+};
+
+#define RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES (1ULL << 0)
+/**< The event timer adapter implementation may have constraints on the
+ * resolution (timer_tick_ns) and maximum timer expiry timeout(max_tmo_ns)
+ * based on the given timer adapter or system. If this flag is set, the
+ * implementation adjusts the resolution and maximum timeout to the best
+ * possible configuration. On successful timer adapter creation, the
+ * application can get the configured resolution and max timeout with
+ * ``rte_event_timer_adapter_get_info()``.
+ */
+#define RTE_EVENT_TIMER_ADAPTER_F_SP_PUT (1ULL << 1)
+/**< ``rte_event_timer_arm_burst()`` API to be used in single producer mode.
+ *
+ * @see struct rte_event_timer_adapter_conf::timer_wheel_flags
+ */
+
+
+/*
+ * Timer adapter configuration structure
+ */
+struct rte_event_timer_adapter_conf {
+ uint8_t event_dev_id;
+ /**< Event device identifier */
+ uint16_t timer_adapter_id;
+ /**< Event timer adapter identifier */
+ enum rte_event_timer_adapter_clk_src clk_src;
+ /**< Clock source for timer adapter */
+ uint64_t timer_tick_ns;
+ /**< Timer wheel resolution in ns */
+ uint64_t max_tmo_ns;
+ /**< Maximum timer timeout(expiry) in ns */
+ uint64_t nb_timers;
+ /**< Total number of timers per adapter */
+ uint32_t timer_adapter_flags;
+ /**< Timer adapter config flags (RTE_EVENT_TIMER_ADAPTER_F_*) */
+};
+
+struct rte_event_timer_adapter; /* opaque pointer */
+
+/*
+ * Callback function type for producer port creation.
+ */
+typedef int (*rte_event_timer_adapter_port_conf_cb_t)(uint16_t id,
+ uint8_t event_dev_id,
+ uint8_t event_port_id,
+ void *conf_arg);
+
+/*
+ * Create an event timer adapter.
+ *
+ * This function must be invoked first before any other function in the API.
+ *
+ * @param conf
+ * The event timer adapter configuration structure.
+ *
+ * @return
+ * Possible rte_errno values include:
+ * - ERANGE: timer_tick_ns is not in supported range.
+ */
+int rte_event_timer_adapter_create(struct rte_event_timer_adapter_conf *conf);
+
+/*
+ * Create a timer adapter with the supplied callback.
+ *
+ * This function can be used to have a more granular control over the timer
+ * adapter creation. If a built-in port is absent, then the function uses the
+ * callback provided to create and get the port id to be used as a producer
+ * port.
+ *
+ * @param conf
+ * The timer adapter configuration structure
+ * @param conf_cb
+ * The port config callback function.
+ * @param conf_arg
+ * Opaque pointer to the argument for the callback function
+ *
+ * @return
+ * Pointer to the new allocated event timer adapter on success.
+ * NULL on error with rte_errno set appropriately.
+ * Possible rte_errno values include:
+ * - ERANGE: timer_tick_ns is not in supported range.
+ */
+int rte_event_timer_adapter_create_ext(
+ struct rte_event_timer_adapter_conf *conf,
+ rte_event_timer_adapter_port_conf_cb_t conf_cb,
+ void *conf_arg);
+
+/*
+ * Timer adapter info structure.
+ */
+struct rte_event_timer_adapter_info {
+ uint64_t min_resolution_ns;
+ /**< Minimum timer adapter resolution in ns */
+ uint64_t max_tmo_ns;
+ /**< Maximum timer timeout(expire) in ns */
+ struct rte_event_timer_adapter_conf conf;
+ /**< Configured timer adapter attributes */
+ uint8_t event_dev_port_id;
+ /* TODO: document this */
+};
+
+/**
+ * Retrieve the contextual information of an event timer adapter.
+ *
+ * @param id
+ * The identifier of an event timer adapter.
+ *
+ * @param[out] adapter_info
+ * A pointer to a structure of type *rte_event_timer_adapter_info* to be
+ * filled with the contextual information of the adapter.
+ *
+ * @return
+ * - 0: Success, driver updates the contextual information of the
+ * timer adapter
+ * - <0: Error code returned by the driver info get function.
+ * - -EINVAL if adapter identifier invalid
+ *
+ * @see RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES,
+ * struct rte_event_timer_adapter_info
+ *
+ */
+int rte_event_timer_adapter_get_info(uint16_t id,
+ struct rte_event_timer_adapter_info *adapter_info);
+
+/**
+ * Start a timer adapter.
+ *
+ * The adapter start step is the last one and consists of setting the timer
+ * adapter to start accepting the timers and schedules to event queues.
+ *
+ * On success, all basic functions exported by the API (timer arm,
+ * timer cancel and so on) can be invoked.
+ *
+ * @param id
+ * The identifier of an event timer adapter.
+ *
+ * @return
+ * - 0: Success, adapter started.
+ * - <0: Error code returned by the driver start function.
+ * - -EINVAL if adapter identifier invalid
+ */
+int rte_event_timer_adapter_start(uint16_t id);
+
+/**
+ * Stop an event timer adapter.
+ *
+ * The adapter can be restarted with a call to
+ * ``rte_event_timer_adapter_start()``.
+ *
+ * @param id
+ * The identifier of an event timer adapter.
+ *
+ * @return
+ * - 0: Success, adapter stop.
+ * - <0: Error code returned by the driver stop function.
+ * - -EINVAL if adapter identifier invalid
+ */
+int rte_event_timer_adapter_stop(uint16_t id);
+
+/**
+ * Free an event timer adapter.
+ *
+ * Destroy an event timer adapter, freeing all resources.
+ *
+ * Before invoking this function, the application must wait for all the armed
+ * timers to expire or cancel the outstanding armed timers.
+ *
+ * @param id
+ * The identifier of an event timer adapter.
+ *
+ * @return
+ * - 0 on successfully freed the event timer adapter resources.
+ * - <0 on failure to free an event timer adapter.
+ * - -EAGAIN if adapter is busy
+ * - -EINVAL if adapter identifier invalid
+ */
+int rte_event_timer_adapter_free(uint16_t id);
+
+/**
+ * Event timer state.
+ */
+enum rte_event_timer_state {
+ RTE_EVENT_TIMER_NOT_ARMED = 0,
+ /**< Event timer is in not armed state.*/
+ RTE_EVENT_TIMER_ARMED = 1,
+ /**< Event timer successfully armed.*/
+ RTE_EVENT_TIMER_ERROR = -1,
+ /**< Generic event timer error.*/
+ RTE_EVENT_TIMER_ERROR_TOOEARLY = -2,
+ /**< Event timer timeout tick is too little to add to the adapter. */
+ RTE_EVENT_TIMER_ERROR_TOOLATE = -3,
+ /**< Event timer timeout tick is greater than the maximum timeout.*/
+};
+
+/**
+ * The generic *rte_event_timer* structure to hold the event timer attributes
+ * for arm and cancel operations.
+ */
+RTE_STD_C11
+struct rte_event_timer {
+ struct rte_event ev;
+ /**<
+ * Expiry event attributes. On successful event timer timeout,
+ * the following attributes will be used to inject the expiry event to
+ * the eventdev:
+ * - event_queue_id: Targeted event queue id for expiry events.
+ * - event_priority: Event priority of the event expiry event in the
+ * event queue relative to other events.
+ * - sched_type: Scheduling type of the expiry event.
+ * - flow_id: Flow id of the expiry event.
+ * - op: RTE_EVENT_OP_NEW
+ * - event_type: RTE_EVENT_TYPE_TIMER
+ */
+ enum rte_event_timer_state state;
+ /**< State of the event timer. */
+ uint64_t timeout_ticks;
+ /**< Expiry timer ticks expressed in number of *timer_ticks_ns* from
+ * now.
+ * @see struct rte_event_timer_adapter_info::adapter_conf::timer_tick_ns
+ */
+ uint64_t impl_opaque[2];
+ /**< Implementation-specific opaque data.
+ * An event timer adapter implementation use this field to hold
+ * implementation specific values to share between the arm and cancel
+ * operations. The application should not modify this field.
+ */
+ uint8_t user_meta[];
+ /**< Memory to store user specific metadata.
+ * The event timer adapter implementation should not modify this area.
+ */
+} __rte_cache_aligned;
+
+/**
+ * Arm a burst of event timers with separate expiration timeout tick for each
+ * event timer.
+ *
+ * Before calling this function, the application allocates
+ * ``struct rte_event_timer`` objects from mempool or huge page backed
+ * application buffers of desired size. On successful allocation,
+ * application updates the `struct rte_event_timer`` attributes such as
+ * expiry event attributes, timeout ticks from now.
+ * This function submits the event timer arm requests to the event timer adapter
+ * and on expiry, the events will be injected to designated event queue.
+ *
+ * @param id
+ * The identifier of an event timer adapter.
+ * @param tim
+ * Points to an array of objects of type *rte_event_timer* structure.
+ * @param nb_timers
+ * Number of event timers in the supplied array.
+ *
+ * @return
+ * The number of successfully armed event timers. The return value can be less
+ * than the value of the *nb_timers* parameter. If the return value is less
+ * than *nb_events*, the remaining event timers at the end of *tim*
+ * are not consumed, and the caller has to take care of them, and rte_errno
+ * is set accordingly. Possible errno values include:
+ * - -EINVAL Invalid timer adapter identifier, expiry event queue ID is
+ * invalid, or an expiry event's sched type doesn't match the capabilities of
+ * the destination event queue.
+ */
+int rte_event_timer_arm_burst(uint16_t id,
+ struct rte_event_timer **tim,
+ uint16_t nb_timers);
+
+/**
+ * Arm a burst of event timers with same expiration timeout tick.
+ *
+ * Provides the same functionality as ``rte_event_timer_arm_burst()``, except
+ * that application can use this API when all the event timers have the
+ * same timeout expiration tick. This specialized function can provide the
+ * additional hint to the adapter implementation and optimize if possible.
+ *
+ * @param id
+ * The identifier of an event timer adapter.
+ * @param tim
+ * Points to an array of objects of type *rte_event_timer* structure.
+ * @param nb_timers
+ * Number of event timers in the supplied array.
+ *
+ * @return
+ * The number of successfully armed event timers. The return value can be less
+ * than the value of the *nb_timers* parameter. If the return value is less
+ * than *nb_events*, the remaining event timers at the end of *tim*
+ * are not consumed, and the caller has to take care of them, and rte_errno
+ * is set accordingly. Possible errno values include:
+ * - -EINVAL Invalid timer adapter identifier, expiry event queue ID is
+ * invalid, or an expiry event's sched type doesn't match the capabilities of
+ * the destination event queue.
+ */
+int
+rte_event_timer_arm_tmo_tick_burst(
+ uint16_t id,
+ struct rte_event_timer **tim,
+ const uint64_t timeout_tick,
+ const uint16_t nb_timers);
+
+/**
+ * Cancel a burst of event timer from being scheduled to the event device.
+ *
+ * @param id
+ * The identifier of an event timer adapter.
+ * @param tim
+ * Points to an array of objects of type *rte_event_timer* structure
+ * @param nb_timers
+ * Number of event timer instances in the supplied array.
+ *
+ * @return
+ * The number of successfully canceled event timers. The return value can be
+ * less than the value of the *nb_timers* parameter. If the return value is
+ * less than *nb_events*, the remaining event timers at the end of *tim*
+ * are not consumed, and the caller has to take care of them, and rte_errno
+ * is set accordingly. Possible errno values include:
+ * - -EINVAL Invalid timer adapter identifier
+ */
+int rte_event_timer_cancel_burst(uint16_t id,
+ struct rte_event_timer **tim,
+ uint16_t nb_timers);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_EVENT_TIMER_ADAPTER_H_ */
new file mode 100644
@@ -0,0 +1,128 @@
+/*
+ * Copyright(c) 2017 Intel Corporation. All rights reserved.
+ * 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.
+ */
+
+#ifndef RTE_EVENT_TIMER_ADAPTER_DRIVER_H_
+#define RTE_EVENT_TIMER_ADAPTER_DRIVER_H_
+
+/**
+ * @file
+ * RTE event timer adapter driver side API
+ *
+ * This file provides implementation helpers for internal use by plugins, they
+ * are not intended to be exposed to applications and are not subject to ABI
+ * versioning.
+ */
+#include <rte_timer.h>
+#include <rte_ring.h>
+
+#include "rte_event_timer_adapter.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Event timer adapter structure.
+ */
+struct rte_event_timer_adapter {
+ uint8_t event_dev_id;
+ /**< Event device identifier */
+ uint8_t event_port_id;
+ /**< Event device port identifier */
+ uint16_t id;
+ /**< Event timer adapter identifier */
+ rte_event_timer_adapter_port_conf_cb_t conf_cb;
+ /**< Port configuration callback function for event timer adapter. */
+ void *conf_arg;
+ /**< Argument for port configuration callback function. */
+
+ /**
+ * Fields for software implementation
+ */
+ uint32_t service_id;
+ /**< Identifier of service executing timer management logic. */
+ int socket_id;
+ /**< Socket identifier of service. */
+ struct rte_ring event_timer_ring;
+ /**< Ring of messages submitted by application to arm/cancel event
+ * timers.
+ */
+ /* event buffer */
+ /**< Buffered timer events to be enqueued to an event device. */
+
+ /* stats */
+};
+
+/**
+ * These callback functions are not supposed to be used by applications
+ * directly, which must rely on the API defined in rte_event_timer_adapter.h.
+ *
+ * See also rte_event_timer_adapter_ops_get().
+ */
+struct rte_event_timer_adapter_ops {
+ int (*adapter_start)
+ (struct rte_event_timer_adapter *adapter);
+ int (*adapter_stop)
+ (struct rte_event_timer_adapter *adapter);
+ int (*event_timer_arm_burst)
+ (struct rte_event_timer_adapter *adapter,
+ struct rte_event_timer **tims,
+ const uint16_t nb_tims);
+ int (*event_timer_arm_tmo_tick_burst)
+ (struct rte_event_timer_adapter *adapter,
+ struct rte_event_timer **tims,
+ const uint64_t timeout_tick,
+ const uint16_t nb_tims);
+ int (*event_timer_cancel_burst)
+ (struct rte_event_timer_adapter *adapter,
+ struct rte_event_timer **tims,
+ const uint16_t nb_tims);
+};
+
+/**
+ * Get event timer adapter operations structure from an event device.
+ *
+ * @param adapter
+ * Pointer to adapter for which to obtain an operations struct.
+ *
+ * @return
+ * The adapter operation structure associated with the event device, NULL in
+ * case of error, in which case rte_errno is set and the error structure
+ * contains additional details.
+ */
+const struct rte_event_timer_adapter_ops *
+rte_event_timer_adapter_ops_get(struct rte_event_timer_adapter *adapter);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RTE_EVENT_TIMER_ADAPTER_DRIVER_H_ */
@@ -865,7 +865,7 @@ rte_event_dev_close(uint8_t dev_id);
/**< The event generated from ethdev subsystem */
#define RTE_EVENT_TYPE_CRYPTODEV 0x1
/**< The event generated from crypodev subsystem */
-#define RTE_EVENT_TYPE_TIMERDEV 0x2
+#define RTE_EVENT_TYPE_TIMER 0x2
/**< The event generated from timerdev subsystem */
#define RTE_EVENT_TYPE_CPU 0x3
/**< The event generated from cpu for pipelining.
@@ -412,6 +412,18 @@ typedef int (*eventdev_xstats_get_names_t)(const struct rte_eventdev *dev,
unsigned int *ids, unsigned int size);
/**
+ * Timer adapter control function for an event device. Currently used to
+ * fill an ops structure with function pointers for an adapter plugin.
+ *
+ * @param arg
+ * Pointer to an ops structure to fill
+ * @return
+ * 0: Success
+ * <0: Failure
+ */
+typedef int (*event_timer_adapter_ctrl_t)(void *arg);
+
+/**
* Get value of one stats and optionally return its id
*
* @param dev
@@ -468,6 +480,9 @@ struct rte_eventdev_ops {
/**< Get one value by name. */
eventdev_xstats_reset_t xstats_reset;
/**< Reset the statistics values in xstats. */
+
+ event_timer_adapter_ctrl_t event_timer_adapter_ctrl;
+ /**< Perform actions related to an event timer adapter.*/
};
/**
@@ -51,3 +51,17 @@ DPDK_17.08 {
rte_event_ring_init;
rte_event_ring_lookup;
} DPDK_17.05;
+
+DPDK_17.11 {
+ global:
+
+ rte_event_timer_adapter_create;
+ rte_event_timer_adapter_create_ext;
+ rte_event_timer_adapter_get_info;
+ rte_event_timer_adapter_start;
+ rte_event_timer_adapter_stop;
+ rte_event_timer_adapter_free;
+ rte_event_timer_arm_burst;
+ rte_event_timer_arm_tmo_tick_burst;
+ rte_event_timer_cancel_burst;
+} DPDK_17.08;
@@ -204,6 +204,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev.c
ifeq ($(CONFIG_RTE_LIBRTE_EVENTDEV),y)
SRCS-y += test_eventdev.c
SRCS-y += test_event_ring.c
+SRCS-y += test_event_timer_adapter.c
SRCS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += test_eventdev_sw.c
SRCS-$(CONFIG_RTE_LIBRTE_PMD_OCTEONTX_SSOVF) += test_eventdev_octeontx.c
endif
new file mode 100644
@@ -0,0 +1,183 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2017 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 <string.h>
+
+#include <rte_eventdev.h>
+#include <rte_dev.h>
+#include <rte_event_timer_adapter.h>
+#include <rte_mempool.h>
+#include <rte_errno.h>
+
+#include "test.h"
+
+static int evdev;
+struct rte_event_timer_adapter *g_adapter;
+struct rte_event_timer *g_evtimer;
+struct rte_mempool *g_event_timer_pool;
+
+static inline void
+devconf_set_default_sane_values(struct rte_event_dev_config *dev_conf,
+ struct rte_event_dev_info *info)
+{
+ memset(dev_conf, 0, sizeof(struct rte_event_dev_config));
+ dev_conf->dequeue_timeout_ns = info->min_dequeue_timeout_ns;
+ dev_conf->nb_event_ports = info->max_event_ports;
+ dev_conf->nb_event_queues = info->max_event_queues;
+ dev_conf->nb_event_queue_flows = info->max_event_queue_flows;
+ dev_conf->nb_event_port_dequeue_depth =
+ info->max_event_port_dequeue_depth;
+ dev_conf->nb_event_port_enqueue_depth =
+ info->max_event_port_enqueue_depth;
+ dev_conf->nb_event_port_enqueue_depth =
+ info->max_event_port_enqueue_depth;
+ dev_conf->nb_events_limit =
+ info->max_num_events;
+}
+
+static int
+configure_event_dev(void)
+{
+ struct rte_event_dev_config devconf;
+ int ret;
+ const char *eventdev_name = "event_sw0";
+ struct rte_event_dev_info info;
+
+ evdev = rte_event_dev_get_dev_id(eventdev_name);
+ if (evdev < 0) {
+ if (rte_vdev_init(eventdev_name, NULL) < 0) {
+ printf("Error creating eventdev\n");
+ return TEST_FAILED;
+ }
+ evdev = rte_event_dev_get_dev_id(eventdev_name);
+ if (evdev < 0) {
+ printf("Error finding newly created eventdev\n");
+ return TEST_FAILED;
+ }
+ }
+
+ ret = rte_event_dev_info_get(evdev, &info);
+ TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info");
+
+ devconf_set_default_sane_values(&devconf, &info);
+
+ ret = rte_event_dev_configure(evdev, &devconf);
+ TEST_ASSERT_SUCCESS(ret, "Failed to configure eventdev");
+
+ /* Start the event device */
+ ret = rte_event_dev_start(evdev);
+ TEST_ASSERT_SUCCESS(ret, "Failed to start device");
+
+ return TEST_SUCCESS;
+}
+
+static int
+testsuite_setup(void)
+{
+ int ret;
+
+ /* Setup and start event device. */
+ ret = configure_event_dev();
+ if (ret) {
+ printf("Failed to configure event dev\n");
+ return TEST_FAILED;
+ }
+
+ /* Create a mempool of event timers. */
+ g_event_timer_pool = rte_mempool_create("event_timer_mempool",
+ 32,
+ sizeof(struct rte_event_timer),
+ 0,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ rte_socket_id(),
+ 0);
+ if (g_event_timer_pool == NULL) {
+ /* Failed to create event timer mempool. */
+ printf("Failed to configure event timer mempool: %s\n",
+ rte_strerror(rte_errno));
+ return TEST_FAILED;
+ }
+
+ return TEST_SUCCESS;
+}
+
+static void
+testsuite_teardown(void)
+{
+ /* TODO: tear down adapter and evdev */
+
+ rte_mempool_free(g_event_timer_pool);
+}
+
+static int
+adapter_create_free(void)
+{
+ int ret;
+
+ struct rte_event_timer_adapter_conf conf = {
+ .event_dev_id = evdev,
+ .timer_adapter_id = 0,
+ };
+
+ ret = rte_event_timer_adapter_create(&conf);
+ if (ret)
+ return TEST_FAILED;
+
+ ret = rte_event_timer_adapter_free(conf.timer_adapter_id);
+ if (ret)
+ return TEST_FAILED;
+
+ return TEST_SUCCESS;
+}
+
+static struct unit_test_suite adapter_tests = {
+ .suite_name = "event timer adapter test suite",
+ .setup = testsuite_setup,
+ .teardown = testsuite_teardown,
+ .unit_test_cases = {
+ TEST_CASE(adapter_create_free),
+ TEST_CASES_END() /**< NULL terminate unit test array */
+ }
+};
+
+static int
+test_event_timer_adapter_common(void)
+{
+ return unit_test_suite_runner(&adapter_tests);
+}
+
+REGISTER_TEST_COMMAND(event_timer_adapter_autotest,
+ test_event_timer_adapter_common);