Implemented pktout event queues.
Signed-off-by: Petri Savolainen <[email protected]>
---
.../linux-generic/include/odp_packet_io_internal.h | 2 +
.../linux-generic/include/odp_queue_internal.h | 2 +-
platform/linux-generic/odp_packet_io.c | 123 +++++++++++++++++++--
3 files changed, 117 insertions(+), 10 deletions(-)
diff --git a/platform/linux-generic/include/odp_packet_io_internal.h
b/platform/linux-generic/include/odp_packet_io_internal.h
index 0a4a55b..9297fc7 100644
--- a/platform/linux-generic/include/odp_packet_io_internal.h
+++ b/platform/linux-generic/include/odp_packet_io_internal.h
@@ -153,6 +153,7 @@ struct pktio_entry {
} in_queue[PKTIO_MAX_QUEUES];
struct {
+ odp_queue_t queue;
odp_pktout_queue_t pktout;
} out_queue[PKTIO_MAX_QUEUES];
};
@@ -254,6 +255,7 @@ int single_output_queues_config(pktio_entry_t *entry,
int single_in_queues(pktio_entry_t *entry, odp_queue_t queues[], int num);
int single_pktin_queues(pktio_entry_t *entry, odp_pktin_queue_t queues[],
int num);
+int single_out_queues(pktio_entry_t *entry, odp_queue_t queues[], int num);
int single_pktout_queues(pktio_entry_t *entry, odp_pktout_queue_t queues[],
int num);
int single_recv_queue(pktio_entry_t *entry, int index, odp_packet_t packets[],
diff --git a/platform/linux-generic/include/odp_queue_internal.h
b/platform/linux-generic/include/odp_queue_internal.h
index 912427f..2e352ae 100644
--- a/platform/linux-generic/include/odp_queue_internal.h
+++ b/platform/linux-generic/include/odp_queue_internal.h
@@ -77,7 +77,7 @@ struct queue_entry_s {
odp_queue_type_t type;
odp_queue_param_t param;
odp_pktin_queue_t pktin;
- odp_pktio_t pktout;
+ odp_pktout_queue_t pktout;
char name[ODP_QUEUE_NAME_LEN];
uint64_t order_in;
uint64_t order_out;
diff --git a/platform/linux-generic/odp_packet_io.c
b/platform/linux-generic/odp_packet_io.c
index e3827ae..83a03d8 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -116,18 +116,33 @@ static void unlock_entry(pktio_entry_t *entry)
odp_ticketlock_unlock(&entry->s.rxl);
}
-static void init_pktio_entry(pktio_entry_t *entry)
+static void init_in_queues(pktio_entry_t *entry)
{
int i;
- set_taken(entry);
- pktio_cls_enabled_set(entry, 0);
+ for (i = 0; i < PKTIO_MAX_QUEUES; i++) {
+ entry->s.in_queue[i].queue = ODP_QUEUE_INVALID;
+ entry->s.in_queue[i].pktin = PKTIN_INVALID;
+ }
+}
+
+static void init_out_queues(pktio_entry_t *entry)
+{
+ int i;
for (i = 0; i < PKTIO_MAX_QUEUES; i++) {
- entry->s.in_queue[i].queue = ODP_QUEUE_INVALID;
- entry->s.in_queue[i].pktin = PKTIN_INVALID;
+ entry->s.out_queue[i].queue = ODP_QUEUE_INVALID;
entry->s.out_queue[i].pktout = PKTOUT_INVALID;
}
+}
+
+static void init_pktio_entry(pktio_entry_t *entry)
+{
+ set_taken(entry);
+ pktio_cls_enabled_set(entry, 0);
+
+ init_in_queues(entry);
+ init_out_queues(entry);
pktio_classifier_init(entry);
}
@@ -280,6 +295,18 @@ static void destroy_in_queues(pktio_entry_t *entry, int
num)
}
}
+static void destroy_out_queues(pktio_entry_t *entry, int num)
+{
+ int i;
+
+ for (i = 0; i < num; i++) {
+ if (entry->s.out_queue[i].queue != ODP_QUEUE_INVALID) {
+ odp_queue_destroy(entry->s.out_queue[i].queue);
+ entry->s.out_queue[i].queue = ODP_QUEUE_INVALID;
+ }
+ }
+}
+
static void flush_in_queues(pktio_entry_t *entry)
{
odp_pktin_mode_t mode;
@@ -322,6 +349,7 @@ int odp_pktio_close(odp_pktio_t id)
lock_entry(entry);
destroy_in_queues(entry, entry->s.num_in_queue);
+ destroy_out_queues(entry, entry->s.num_out_queue);
entry->s.num_in_queue = 0;
entry->s.num_out_queue = 0;
@@ -493,7 +521,7 @@ int pktout_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t
*buf_hdr)
int len = 1;
int nbr;
- nbr = _odp_pktio_send(qentry->s.pktout, &pkt, len);
+ nbr = odp_pktout_send(qentry->s.pktout, &pkt, len);
return (nbr == len ? 0 : -1);
}
@@ -513,7 +541,7 @@ int pktout_enq_multi(queue_entry_t *qentry,
odp_buffer_hdr_t *buf_hdr[],
for (i = 0; i < num; ++i)
pkt_tbl[i] = _odp_packet_from_buffer(buf_hdr[i]->handle.handle);
- nbr = _odp_pktio_send(qentry->s.pktout, pkt_tbl, num);
+ nbr = odp_pktout_send(qentry->s.pktout, pkt_tbl, num);
return nbr;
}
@@ -1133,7 +1161,7 @@ int odp_pktout_queue_config(odp_pktio_t pktio,
if (mode == ODP_PKTOUT_MODE_DISABLED || mode == ODP_PKTOUT_MODE_TM)
return 0;
- if (mode != ODP_PKTOUT_MODE_DIRECT) {
+ if (mode != ODP_PKTOUT_MODE_DIRECT && mode != ODP_PKTOUT_MODE_QUEUE) {
ODP_DBG("pktio %s: bad packet output mode\n", entry->s.name);
return -1;
}
@@ -1152,13 +1180,59 @@ int odp_pktout_queue_config(odp_pktio_t pktio,
return -1;
}
+ /* If re-configuring, destroy old queues */
+ if (entry->s.num_out_queue) {
+ destroy_out_queues(entry, entry->s.num_out_queue);
+ entry->s.num_out_queue = 0;
+ }
+
+ init_out_queues(entry);
+
for (i = 0; i < num_queues; i++) {
entry->s.out_queue[i].pktout.index = i;
- entry->s.out_queue[i].pktout.pktio = entry->s.handle;
+ entry->s.out_queue[i].pktout.pktio = pktio;
}
entry->s.num_out_queue = num_queues;
+ if (mode == ODP_PKTOUT_MODE_QUEUE) {
+ for (i = 0; i < num_queues; i++) {
+ odp_queue_t queue;
+ odp_queue_param_t queue_param;
+ queue_entry_t *qentry;
+ char name[ODP_QUEUE_NAME_LEN];
+ int pktio_id = pktio_to_id(pktio);
+
+ snprintf(name, sizeof(name), "odp-pktout-%i-%i",
+ pktio_id, i);
+
+ odp_queue_param_init(&queue_param);
+ /* Application cannot dequeue from the queue */
+ queue_param.deq_mode = ODP_QUEUE_OP_DISABLED;
+
+ queue = odp_queue_create(name, &queue_param);
+
+ if (queue == ODP_QUEUE_INVALID) {
+ ODP_DBG("pktout %s: event queue create
failed\n",
+ entry->s.name);
+ destroy_out_queues(entry, i + 1);
+ return -1;
+ }
+
+ qentry = queue_to_qentry(queue);
+ qentry->s.pktout.index = i;
+ qentry->s.pktout.pktio = pktio;
+
+ /* Override default enqueue / dequeue functions */
+ qentry->s.enqueue = queue_pktout_enq;
+ qentry->s.dequeue = pktout_dequeue;
+ qentry->s.enqueue_multi = queue_pktout_enq_multi;
+ qentry->s.dequeue_multi = pktout_deq_multi;
+
+ entry->s.out_queue[i].queue = queue;
+ }
+ }
+
if (entry->s.ops->output_queues_config)
return entry->s.ops->output_queues_config(entry, param);
@@ -1216,6 +1290,37 @@ int odp_pktin_queue(odp_pktio_t pktio, odp_pktin_queue_t
queues[], int num)
return single_pktin_queues(entry, queues, num);
}
+int odp_pktout_event_queue(odp_pktio_t pktio, odp_queue_t queues[], int num)
+{
+ pktio_entry_t *entry;
+ odp_pktout_mode_t mode;
+ int i;
+ int num_queues;
+
+ entry = get_pktio_entry(pktio);
+ if (entry == NULL) {
+ ODP_DBG("pktio entry %d does not exist\n", pktio);
+ return -1;
+ }
+
+ mode = entry->s.param.out_mode;
+
+ if (mode == ODP_PKTOUT_MODE_DISABLED)
+ return 0;
+
+ if (mode != ODP_PKTOUT_MODE_QUEUE)
+ return -1;
+
+ num_queues = entry->s.num_out_queue;
+
+ if (queues && num > 0) {
+ for (i = 0; i < num && i < num_queues; i++)
+ queues[i] = entry->s.out_queue[i].queue;
+ }
+
+ return num_queues;
+}
+
int odp_pktout_queue(odp_pktio_t pktio, odp_pktout_queue_t queues[], int num)
{
pktio_entry_t *entry;
--
2.7.1
_______________________________________________
lng-odp mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/lng-odp