#include <rte_service_component.h>
#include <rte_bus_vdev.h>
-#include "test.h"
+#include "sw_evdev.h"
#define MAX_PORTS 16
#define MAX_QIDS 16
#define NUM_PACKETS (1<<18)
+#define DEQUEUE_DEPTH 128
static int evdev;
.nb_event_ports = nb_ports,
.nb_event_queue_flows = 1024,
.nb_events_limit = 4096,
- .nb_event_port_dequeue_depth = 128,
+ .nb_event_port_dequeue_depth = DEQUEUE_DEPTH,
.nb_event_port_enqueue_depth = 128,
};
int ret;
.mbuf = arp
};
err = rte_event_enqueue_burst(evdev, t->port[0], &ev, 1);
- if (err < 0) {
+ if (err != 1) {
printf("%d: error failed to enqueue\n", __LINE__);
return -1;
}
/* generate pkt and enqueue */
err = rte_event_enqueue_burst(evdev, rx_enq, &ev, 1);
- if (err < 0) {
+ if (err != 1) {
printf("%d: error failed to enqueue\n", __LINE__);
return -1;
}
for (i = 0; i < 1000; i++) {
err = rte_event_enqueue_burst(evdev, 0, &ev, 1);
- if (err < 0) {
+ if (err != 1) {
printf("%d: error failed to enqueue\n", __LINE__);
return -1;
}
};
/* generate pkt and enqueue */
err = rte_event_enqueue_burst(evdev, t->port[rx_port], &ev, 1);
- if (err < 0) {
+ if (err != 1) {
printf("%d: Failed to enqueue\n", __LINE__);
return -1;
}
/* Enqueue op only */
err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &release_ev, 1);
- if (err < 0) {
+ if (err != 1) {
printf("%d: Failed to enqueue\n", __LINE__);
return -1;
}
return 0;
}
+static int
+unlink_in_progress(struct test *t)
+{
+ /* Test unlinking API, in particular that when an unlink request has
+ * not yet been seen by the scheduler thread, that the
+ * unlink_in_progress() function returns the number of unlinks.
+ */
+ unsigned int i;
+ /* Create instance with 1 ports, and 3 qids */
+ if (init(t, 3, 1) < 0 ||
+ create_ports(t, 1) < 0) {
+ printf("%d: Error initializing device\n", __LINE__);
+ return -1;
+ }
+
+ for (i = 0; i < 3; i++) {
+ /* Create QID */
+ const struct rte_event_queue_conf conf = {
+ .schedule_type = RTE_SCHED_TYPE_ATOMIC,
+ /* increase priority (0 == highest), as we go */
+ .priority = RTE_EVENT_DEV_PRIORITY_NORMAL - i,
+ .nb_atomic_flows = 1024,
+ .nb_atomic_order_sequences = 1024,
+ };
+
+ if (rte_event_queue_setup(evdev, i, &conf) < 0) {
+ printf("%d: error creating qid %d\n", __LINE__, i);
+ return -1;
+ }
+ t->qid[i] = i;
+ }
+ t->nb_qids = i;
+ /* map all QIDs to port */
+ rte_event_port_link(evdev, t->port[0], NULL, NULL, 0);
+
+ if (rte_event_dev_start(evdev) < 0) {
+ printf("%d: Error with start call\n", __LINE__);
+ return -1;
+ }
+
+ /* unlink all ports to have outstanding unlink requests */
+ int ret = rte_event_port_unlink(evdev, t->port[0], NULL, 0);
+ if (ret < 0) {
+ printf("%d: Failed to unlink queues\n", __LINE__);
+ return -1;
+ }
+
+ /* get active unlinks here, expect 3 */
+ int unlinks_in_progress =
+ rte_event_port_unlinks_in_progress(evdev, t->port[0]);
+ if (unlinks_in_progress != 3) {
+ printf("%d: Expected num unlinks in progress == 3, got %d\n",
+ __LINE__, unlinks_in_progress);
+ return -1;
+ }
+
+ /* run scheduler service on this thread to ack the unlinks */
+ rte_service_run_iter_on_app_lcore(t->service_id, 1);
+
+ /* active unlinks expected as 0 as scheduler thread has acked */
+ unlinks_in_progress =
+ rte_event_port_unlinks_in_progress(evdev, t->port[0]);
+ if (unlinks_in_progress != 0) {
+ printf("%d: Expected num unlinks in progress == 0, got %d\n",
+ __LINE__, unlinks_in_progress);
+ }
+
+ cleanup(t);
+ return 0;
+}
+
static int
load_balancing(struct test *t)
{
};
/* generate pkt and enqueue */
err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
- if (err < 0) {
+ if (err != 1) {
printf("%d: Failed to enqueue\n", __LINE__);
return -1;
}
}
arp->hash.rss = flows1[i];
err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
- if (err < 0) {
+ if (err != 1) {
printf("%d: Failed to enqueue\n", __LINE__);
return -1;
}
arp->hash.rss = flows2[i];
err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
- if (err < 0) {
+ if (err != 1) {
printf("%d: Failed to enqueue\n", __LINE__);
return -1;
}
};
/* generate pkt and enqueue */
err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
- if (err < 0) {
+ if (err != 1) {
printf("%d: Failed to enqueue\n", __LINE__);
return -1;
}
arp->seqn = MAGIC_SEQN;
err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
- if (err < 0) {
+ if (err != 1) {
printf("%d: Failed to enqueue\n", __LINE__);
return -1;
}
rte_pktmbuf_free(ev.mbuf);
err = rte_event_enqueue_burst(evdev, t->port[wrk_enq], &release_ev, 1);
- if (err < 0) {
+ if (err != 1) {
printf("%d: Failed to enqueue\n", __LINE__);
return -1;
}
return -1;
}
+static void
+flush(uint8_t dev_id __rte_unused, struct rte_event event, void *arg)
+{
+ *((uint8_t *) arg) += (event.u64 == 0xCA11BACC) ? 1 : 0;
+}
+
+static int
+dev_stop_flush(struct test *t) /* test to check we can properly flush events */
+{
+ const struct rte_event new_ev = {
+ .op = RTE_EVENT_OP_NEW,
+ .u64 = 0xCA11BACC,
+ .queue_id = 0
+ };
+ struct rte_event ev = new_ev;
+ uint8_t count = 0;
+ int i;
+
+ if (init(t, 1, 1) < 0 ||
+ create_ports(t, 1) < 0 ||
+ create_atomic_qids(t, 1) < 0) {
+ printf("%d: Error initializing device\n", __LINE__);
+ return -1;
+ }
+
+ /* Link the queue so *_start() doesn't error out */
+ if (rte_event_port_link(evdev, t->port[0], NULL, NULL, 0) != 1) {
+ printf("%d: Error linking queue to port\n", __LINE__);
+ goto err;
+ }
+
+ if (rte_event_dev_start(evdev) < 0) {
+ printf("%d: Error with start call\n", __LINE__);
+ goto err;
+ }
+
+ for (i = 0; i < DEQUEUE_DEPTH + 1; i++) {
+ if (rte_event_enqueue_burst(evdev, t->port[0], &ev, 1) != 1) {
+ printf("%d: Error enqueuing events\n", __LINE__);
+ goto err;
+ }
+ }
+
+ /* Schedule the events from the port to the IQ. At least one event
+ * should be remaining in the queue.
+ */
+ rte_service_run_iter_on_app_lcore(t->service_id, 1);
+
+ if (rte_event_dev_stop_flush_callback_register(evdev, flush, &count)) {
+ printf("%d: Error installing the flush callback\n", __LINE__);
+ goto err;
+ }
+
+ cleanup(t);
+
+ if (count == 0) {
+ printf("%d: Error executing the flush callback\n", __LINE__);
+ goto err;
+ }
+
+ if (rte_event_dev_stop_flush_callback_register(evdev, NULL, NULL)) {
+ printf("%d: Error uninstalling the flush callback\n", __LINE__);
+ goto err;
+ }
+
+ return 0;
+err:
+ rte_event_dev_dump(evdev, stdout);
+ cleanup(t);
+ return -1;
+}
+
static int
worker_loopback_worker_fn(void *arg)
{
static struct rte_mempool *eventdev_func_mempool;
-static int
+int
test_sw_eventdev(void)
{
- struct test *t = malloc(sizeof(struct test));
+ struct test *t;
int ret;
+ t = malloc(sizeof(struct test));
+ if (t == NULL)
+ return -1;
/* manually initialize the op, older gcc's complain on static
* initialization of struct elements that are a bitfield.
*/
release_ev.op = RTE_EVENT_OP_RELEASE;
- const char *eventdev_name = "event_sw0";
+ const char *eventdev_name = "event_sw";
evdev = rte_event_dev_get_dev_id(eventdev_name);
if (evdev < 0) {
printf("%d: Eventdev %s not found - creating.\n",
__LINE__, eventdev_name);
if (rte_vdev_init(eventdev_name, NULL) < 0) {
printf("Error creating eventdev\n");
- return -1;
+ goto test_fail;
}
evdev = rte_event_dev_get_dev_id(eventdev_name);
if (evdev < 0) {
printf("Error finding newly created eventdev\n");
- return -1;
+ goto test_fail;
}
}
if (rte_event_dev_service_id_get(evdev, &t->service_id) < 0) {
printf("Failed to get service ID for software event dev\n");
- return -1;
+ goto test_fail;
}
rte_service_runstate_set(t->service_id, 1);
rte_socket_id());
if (!eventdev_func_mempool) {
printf("ERROR creating mempool\n");
- return -1;
+ goto test_fail;
}
}
t->mbuf_pool = eventdev_func_mempool;
ret = test_single_directed_packet(t);
if (ret != 0) {
printf("ERROR - Single Directed Packet test FAILED.\n");
- return ret;
+ goto test_fail;
}
printf("*** Running Directed Forward Credit test...\n");
ret = test_directed_forward_credits(t);
if (ret != 0) {
printf("ERROR - Directed Forward Credit test FAILED.\n");
- return ret;
+ goto test_fail;
}
printf("*** Running Single Load Balanced Packet test...\n");
ret = single_packet(t);
if (ret != 0) {
printf("ERROR - Single Packet test FAILED.\n");
- return ret;
+ goto test_fail;
}
printf("*** Running Unordered Basic test...\n");
ret = unordered_basic(t);
if (ret != 0) {
printf("ERROR - Unordered Basic test FAILED.\n");
- return ret;
+ goto test_fail;
}
printf("*** Running Ordered Basic test...\n");
ret = ordered_basic(t);
if (ret != 0) {
printf("ERROR - Ordered Basic test FAILED.\n");
- return ret;
+ goto test_fail;
}
printf("*** Running Burst Packets test...\n");
ret = burst_packets(t);
if (ret != 0) {
printf("ERROR - Burst Packets test FAILED.\n");
- return ret;
+ goto test_fail;
}
printf("*** Running Load Balancing test...\n");
ret = load_balancing(t);
if (ret != 0) {
printf("ERROR - Load Balancing test FAILED.\n");
- return ret;
+ goto test_fail;
}
printf("*** Running Prioritized Directed test...\n");
ret = test_priority_directed(t);
if (ret != 0) {
printf("ERROR - Prioritized Directed test FAILED.\n");
- return ret;
+ goto test_fail;
}
printf("*** Running Prioritized Atomic test...\n");
ret = test_priority_atomic(t);
if (ret != 0) {
printf("ERROR - Prioritized Atomic test FAILED.\n");
- return ret;
+ goto test_fail;
}
printf("*** Running Prioritized Ordered test...\n");
ret = test_priority_ordered(t);
if (ret != 0) {
printf("ERROR - Prioritized Ordered test FAILED.\n");
- return ret;
+ goto test_fail;
}
printf("*** Running Prioritized Unordered test...\n");
ret = test_priority_unordered(t);
if (ret != 0) {
printf("ERROR - Prioritized Unordered test FAILED.\n");
- return ret;
+ goto test_fail;
}
printf("*** Running Invalid QID test...\n");
ret = invalid_qid(t);
if (ret != 0) {
printf("ERROR - Invalid QID test FAILED.\n");
- return ret;
+ goto test_fail;
}
printf("*** Running Load Balancing History test...\n");
ret = load_balancing_history(t);
if (ret != 0) {
printf("ERROR - Load Balancing History test FAILED.\n");
- return ret;
+ goto test_fail;
}
printf("*** Running Inflight Count test...\n");
ret = inflight_counts(t);
if (ret != 0) {
printf("ERROR - Inflight Count test FAILED.\n");
- return ret;
+ goto test_fail;
}
printf("*** Running Abuse Inflights test...\n");
ret = abuse_inflights(t);
if (ret != 0) {
printf("ERROR - Abuse Inflights test FAILED.\n");
- return ret;
+ goto test_fail;
}
printf("*** Running XStats test...\n");
ret = xstats_tests(t);
if (ret != 0) {
printf("ERROR - XStats test FAILED.\n");
- return ret;
+ goto test_fail;
}
printf("*** Running XStats ID Reset test...\n");
ret = xstats_id_reset_tests(t);
if (ret != 0) {
printf("ERROR - XStats ID Reset test FAILED.\n");
- return ret;
+ goto test_fail;
}
printf("*** Running XStats Brute Force test...\n");
ret = xstats_brute_force(t);
if (ret != 0) {
printf("ERROR - XStats Brute Force test FAILED.\n");
- return ret;
+ goto test_fail;
}
printf("*** Running XStats ID Abuse test...\n");
ret = xstats_id_abuse_tests(t);
if (ret != 0) {
printf("ERROR - XStats ID Abuse test FAILED.\n");
- return ret;
+ goto test_fail;
}
printf("*** Running QID Priority test...\n");
ret = qid_priorities(t);
if (ret != 0) {
printf("ERROR - QID Priority test FAILED.\n");
- return ret;
+ goto test_fail;
+ }
+ printf("*** Running Unlink-in-progress test...\n");
+ ret = unlink_in_progress(t);
+ if (ret != 0) {
+ printf("ERROR - Unlink in progress test FAILED.\n");
+ goto test_fail;
}
printf("*** Running Ordered Reconfigure test...\n");
ret = ordered_reconfigure(t);
if (ret != 0) {
printf("ERROR - Ordered Reconfigure test FAILED.\n");
- return ret;
+ goto test_fail;
}
printf("*** Running Port LB Single Reconfig test...\n");
ret = port_single_lb_reconfig(t);
if (ret != 0) {
printf("ERROR - Port LB Single Reconfig test FAILED.\n");
- return ret;
+ goto test_fail;
}
printf("*** Running Port Reconfig Credits test...\n");
ret = port_reconfig_credits(t);
if (ret != 0) {
printf("ERROR - Port Reconfig Credits Reset test FAILED.\n");
- return ret;
+ goto test_fail;
}
printf("*** Running Head-of-line-blocking test...\n");
ret = holb(t);
if (ret != 0) {
printf("ERROR - Head-of-line-blocking test FAILED.\n");
- return ret;
+ goto test_fail;
+ }
+ printf("*** Running Stop Flush test...\n");
+ ret = dev_stop_flush(t);
+ if (ret != 0) {
+ printf("ERROR - Stop Flush test FAILED.\n");
+ goto test_fail;
}
if (rte_lcore_count() >= 3) {
printf("*** Running Worker loopback test...\n");
ret = worker_loopback(t, 1);
if (ret != 0) {
printf("ERROR - Worker loopback test FAILED.\n");
- return ret;
+ goto test_fail;
}
} else {
printf("### Not enough cores for worker loopback tests.\n");
*/
free(t);
+ printf("SW Eventdev Selftest Successful.\n");
return 0;
+test_fail:
+ free(t);
+ printf("SW Eventdev Selftest Failed.\n");
+ return -1;
}
-
-REGISTER_TEST_COMMAND(eventdev_sw_autotest, test_sw_eventdev);