On Thu, Feb 25, 2016 at 5:31 AM, Petri Savolainen < [email protected]> wrote:
> 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); > What happens if the out_queue is not empty? odp_queue_destroy() will fail then and the result will be a resource leakage. The corresponding destroy_in_queues() is guarded by the flush_in_queues() routine to ensure that they are empty. It seems we need a corresponding flush_out_queues() routine to ensure that the output queues are similarly empty. > + 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 >
_______________________________________________ lng-odp mailing list [email protected] https://lists.linaro.org/mailman/listinfo/lng-odp
