The following API is implemented:
 - odp_pktio_inqs_setdef()
 - odp_pktio_inqs_remdef()
 - odp_pktio_inqs_getdef()
 - odp_pktio_outqs_getdef()
Scheduler is reimplemented to multiqueue mode.
Single queue API is preserved and implemented using multiqueue API.

Signed-off-by: Nikita Kalyazin <n.kalya...@samsung.com>
Reviewed-by: Ilya Maximets <i.maxim...@samsung.com>
---
 .../linux-generic/include/odp_packet_io_internal.h |   7 +-
 .../linux-generic/include/odp_queue_internal.h     |   2 +
 .../linux-generic/include/odp_schedule_internal.h  |   1 +
 platform/linux-generic/odp_packet_io.c             | 239 +++++++++++++++------
 platform/linux-generic/odp_schedule.c              |  26 ++-
 5 files changed, 201 insertions(+), 74 deletions(-)

diff --git a/platform/linux-generic/include/odp_packet_io_internal.h 
b/platform/linux-generic/include/odp_packet_io_internal.h
index 74c6338..641f06c 100644
--- a/platform/linux-generic/include/odp_packet_io_internal.h
+++ b/platform/linux-generic/include/odp_packet_io_internal.h
@@ -45,8 +45,9 @@ struct pktio_entry {
        int taken;                      /**< is entry taken(1) or free(0) */
        int cls_enabled;                /**< is classifier enabled */
        odp_pktio_t handle;             /**< pktio handle */
-       odp_queue_t inq_default;        /**< default input queue, if set */
-       odp_queue_t outq_default;       /**< default out queue */
+       odp_queue_t inqs_default[ODP_CONFIG_PKTIO_QUEUES]; /**< default input 
queues, if set */
+       odp_queue_t outqs_default[ODP_CONFIG_PKTIO_QUEUES]; /**< default out 
queues */
+       int inqs_set;                   /**< is input queues set */
        uint32_t num_rx_queues;         /**< current number of rx hw queues */
        uint32_t num_tx_queues;         /**< current number of tx hw queues */
        union {
@@ -134,7 +135,7 @@ static inline void pktio_cls_enabled_set(pktio_entry_t 
*entry, int ena)
        entry->s.cls_enabled = ena;
 }
 
-int pktin_poll(pktio_entry_t *entry);
+int pktin_poll(pktio_entry_t *entry, uint32_t qid);
 
 extern const pktio_if_ops_t netmap_pktio_ops;
 extern const pktio_if_ops_t sock_mmsg_pktio_ops;
diff --git a/platform/linux-generic/include/odp_queue_internal.h 
b/platform/linux-generic/include/odp_queue_internal.h
index 5747277..5e9535c 100644
--- a/platform/linux-generic/include/odp_queue_internal.h
+++ b/platform/linux-generic/include/odp_queue_internal.h
@@ -77,7 +77,9 @@ struct queue_entry_s {
        odp_queue_type_t  type;
        odp_queue_param_t param;
        odp_pktio_t       pktin;
+       uint32_t          pktin_qid;
        odp_pktio_t       pktout;
+       uint32_t          pktout_qid;
        char              name[ODP_QUEUE_NAME_LEN];
        uint64_t          order_in;
        uint64_t          order_out;
diff --git a/platform/linux-generic/include/odp_schedule_internal.h 
b/platform/linux-generic/include/odp_schedule_internal.h
index 6f9cbdc..a9d5793 100644
--- a/platform/linux-generic/include/odp_schedule_internal.h
+++ b/platform/linux-generic/include/odp_schedule_internal.h
@@ -30,6 +30,7 @@ static inline int schedule_queue(const queue_entry_t *qe)
 }
 
 int schedule_pktio_start(odp_pktio_t pktio, int prio);
+int schedule_pktio_start_queue(odp_pktio_t pktio, int prio, uint32_t qid);
 void odp_schedule_release_context(void);
 
 #ifdef __cplusplus
diff --git a/platform/linux-generic/odp_packet_io.c 
b/platform/linux-generic/odp_packet_io.c
index 202e850..69faa17 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -39,7 +39,7 @@ int odp_pktio_init_global(void)
        int id;
        odp_shm_t shm;
        int pktio_if;
-       int i;
+       int i, qid_err;
 
        shm = odp_shm_reserve("odp_pktio_entries",
                              sizeof(pktio_table_t),
@@ -64,20 +64,30 @@ int odp_pktio_init_global(void)
                odp_spinlock_init(&pktio_entry->s.cls.l3_cos_table.lock);
 
                pktio_entry_ptr[id - 1] = pktio_entry;
-               /* Create a default output queue for each pktio resource */
-               snprintf(name, sizeof(name), "%i-pktio_outq_default", (int)id);
-               name[ODP_QUEUE_NAME_LEN-1] = '\0';
-
-               qid = odp_queue_create(name, ODP_QUEUE_TYPE_PKTOUT, NULL);
-               if (qid == ODP_QUEUE_INVALID)
-                       return -1;
-               pktio_entry->s.outq_default = qid;
-
-               queue_entry = queue_to_qentry(qid);
-               queue_entry->s.pktout = _odp_cast_scalar(odp_pktio_t, id);
+               /* Create a default output queues for each pktio resource */
+               for (i = 0; i < ODP_CONFIG_PKTIO_QUEUES; i++) {
+                       snprintf(name, sizeof(name), "%i-%i-pktio_outq_default",
+                                (int)id, i);
+                       name[ODP_QUEUE_NAME_LEN - 1] = '\0';
+
+                       qid = odp_queue_create(name, ODP_QUEUE_TYPE_PKTOUT,
+                                              NULL);
+                       if (qid == ODP_QUEUE_INVALID) {
+                               ODP_ERR("failed to create outq def %d\n", i);
+                               qid_err = i;
+                               goto err;
+                       }
+                       pktio_entry->s.outqs_default[i] = qid;
 
+                       queue_entry = queue_to_qentry(qid);
+                       queue_entry->s.pktout = _odp_cast_scalar(odp_pktio_t,
+                                                                id);
+                       queue_entry->s.pktout_qid = i;
+               }
+               pktio_entry->s.inqs_set = 0;
                pktio_entry->s.num_rx_queues = 1;
                pktio_entry->s.num_tx_queues = 1;
+
        }
 
        for (pktio_if = 0; pktio_if_ops[pktio_if]; ++pktio_if) {
@@ -88,6 +98,12 @@ int odp_pktio_init_global(void)
        }
 
        return 0;
+
+err:
+       for (i = 0; i < qid_err; i++)
+               odp_queue_destroy(pktio_entry->s.outqs_default[i]);
+
+       return -1;
 }
 
 int odp_pktio_term_global(void)
@@ -105,8 +121,10 @@ int odp_pktio_term_global(void)
        }
 
        for (id = 1; id <= ODP_CONFIG_PKTIO_ENTRIES; ++id) {
+               int i;
                pktio_entry = &pktio_tbl->entries[id - 1];
-               odp_queue_destroy(pktio_entry->s.outq_default);
+               for (i = 0; i < ODP_CONFIG_PKTIO_QUEUES; i++)
+                       odp_queue_destroy(pktio_entry->s.outqs_default[i]);
        }
 
        ret = odp_shm_free(odp_shm_lookup("odp_pktio_entries"));
@@ -182,9 +200,12 @@ static void unlock_entry_classifier(pktio_entry_t *entry)
 
 static void init_pktio_entry(pktio_entry_t *entry)
 {
+       int i;
+
        set_taken(entry);
        pktio_cls_enabled_set(entry, 0);
-       entry->s.inq_default = ODP_QUEUE_INVALID;
+       for (i = 0; i < ODP_CONFIG_PKTIO_QUEUES; i++)
+               entry->s.inqs_default[i] = ODP_QUEUE_INVALID;
 
        pktio_classifier_init(entry);
 }
@@ -550,66 +571,126 @@ int odp_pktio_send(odp_pktio_t id, odp_packet_t 
pkt_table[], int len)
        return odp_pktio_send_queue(id, 0, pkt_table, len);
 }
 
+/* Must be called with pktio entry lock */
+static void __odp_pktio_inqs_remdef_one(pktio_entry_t *pktio_entry,
+                                       uint32_t qid)
+{
+       odp_queue_t queue;
+       queue_entry_t *qentry;
+
+       queue = pktio_entry->s.inqs_default[qid];
+       qentry = queue_to_qentry(queue);
+
+       queue_lock(qentry);
+       qentry->s.pktin = ODP_PKTIO_INVALID;
+       qentry->s.pktin_qid = 0;
+       queue_unlock(qentry);
+
+       pktio_entry->s.inqs_default[qid] = ODP_QUEUE_INVALID;
+}
+
+/* Must be called with pktio entry lock */
+static void __odp_pktio_inqs_remdef(odp_pktio_t id)
+{
+       pktio_entry_t *pktio_entry = get_pktio_entry(id);
+       unsigned int i;
+
+       for (i = 0; i < pktio_entry->s.num_rx_queues; i++)
+               __odp_pktio_inqs_remdef_one(pktio_entry, i);
+       pktio_entry->s.inqs_set = 0;
+}
+
 int odp_pktio_inq_setdef(odp_pktio_t id, odp_queue_t queue)
 {
+       return odp_pktio_inqs_setdef(id, &queue);
+}
+
+int odp_pktio_inqs_setdef(odp_pktio_t id, odp_queue_t queues[])
+{
        pktio_entry_t *pktio_entry = get_pktio_entry(id);
        queue_entry_t *qentry;
+       unsigned int i, qid_err;
 
-       if (pktio_entry == NULL || queue == ODP_QUEUE_INVALID)
+       if (pktio_entry == NULL)
                return -1;
 
-       qentry = queue_to_qentry(queue);
+       lock_entry(pktio_entry);
+       if (pktio_entry->s.inqs_set)
+               __odp_pktio_inqs_remdef(id);
 
-       if (qentry->s.type != ODP_QUEUE_TYPE_PKTIN)
-               return -1;
+       for (i = 0; i < pktio_entry->s.num_rx_queues; i++) {
+               if (queues[i] == ODP_QUEUE_INVALID) {
+                       qid_err = i;
+                       goto err;
+               }
 
-       lock_entry(pktio_entry);
-       pktio_entry->s.inq_default = queue;
-       unlock_entry(pktio_entry);
+               qentry = queue_to_qentry(queues[i]);
 
-       switch (qentry->s.type) {
-       /* Change to ODP_QUEUE_TYPE_POLL when ODP_QUEUE_TYPE_PKTIN is removed */
-       case ODP_QUEUE_TYPE_PKTIN:
-               /* User polls the input queue */
-               queue_lock(qentry);
-               qentry->s.pktin = id;
-               queue_unlock(qentry);
-
-       /* Uncomment when ODP_QUEUE_TYPE_PKTIN is removed
-               break;
-       case ODP_QUEUE_TYPE_SCHED:
-       */
-               /* Packet input through the scheduler */
-               if (schedule_pktio_start(id, ODP_SCHED_PRIO_LOWEST)) {
-                       ODP_ERR("Schedule pktio start failed\n");
-                       return -1;
+               if (qentry->s.type != ODP_QUEUE_TYPE_PKTIN) {
+                       qid_err = i;
+                       goto err;
+               }
+
+               pktio_entry->s.inqs_default[i] = queues[i];
+               switch (qentry->s.type) {
+               /* Change to ODP_QUEUE_TYPE_POLL
+                  when ODP_QUEUE_TYPE_PKTIN is removed */
+               case ODP_QUEUE_TYPE_PKTIN:
+                       /* User polls the input queue */
+                       queue_lock(qentry);
+                       qentry->s.pktin = id;
+                       qentry->s.pktin_qid = i;
+                       queue_unlock(qentry);
+
+               /* Uncomment when ODP_QUEUE_TYPE_PKTIN is removed
+                       break;
+               case ODP_QUEUE_TYPE_SCHED:
+               */
+                       /* Packet input through the scheduler */
+                       if (schedule_pktio_start_queue(id,
+                                                      ODP_SCHED_PRIO_LOWEST,
+                                                      i)) {
+                               ODP_ERR("Schedule pktio start failed\n");
+                               qid_err = i + 1;
+                               goto err;
+                       }
+                       break;
+               default:
+                       ODP_ABORT("Bad queue type\n");
                }
-               break;
-       default:
-               ODP_ABORT("Bad queue type\n");
        }
+       pktio_entry->s.inqs_set = 1;
+       unlock_entry(pktio_entry);
 
        return 0;
+
+err:
+       for (i = 0; i < qid_err; i++)
+               __odp_pktio_inqs_remdef_one(pktio_entry, i);
+       unlock_entry(pktio_entry);
+
+       return -1;
 }
 
 int odp_pktio_inq_remdef(odp_pktio_t id)
 {
+       return odp_pktio_inqs_remdef(id);
+}
+
+int odp_pktio_inqs_remdef(odp_pktio_t id)
+{
        pktio_entry_t *pktio_entry = get_pktio_entry(id);
-       odp_queue_t queue;
-       queue_entry_t *qentry;
 
        if (pktio_entry == NULL)
                return -1;
 
        lock_entry(pktio_entry);
-       queue = pktio_entry->s.inq_default;
-       qentry = queue_to_qentry(queue);
-
-       queue_lock(qentry);
-       qentry->s.pktin = ODP_PKTIO_INVALID;
-       queue_unlock(qentry);
+       if (!pktio_entry->s.inqs_set) {
+               unlock_entry(pktio_entry);
+               return -1;
+       }
 
-       pktio_entry->s.inq_default = ODP_QUEUE_INVALID;
+       __odp_pktio_inqs_remdef(id);
        unlock_entry(pktio_entry);
 
        return 0;
@@ -617,22 +698,53 @@ int odp_pktio_inq_remdef(odp_pktio_t id)
 
 odp_queue_t odp_pktio_inq_getdef(odp_pktio_t id)
 {
+       odp_queue_t queue;
+
+       return odp_pktio_inqs_getdef(id, &queue) ? ODP_QUEUE_INVALID : queue;
+}
+
+int odp_pktio_inqs_getdef(odp_pktio_t id, odp_queue_t queues[])
+{
        pktio_entry_t *pktio_entry = get_pktio_entry(id);
+       unsigned int i;
 
        if (pktio_entry == NULL)
-               return ODP_QUEUE_INVALID;
+               return -1;
 
-       return pktio_entry->s.inq_default;
+       lock_entry(pktio_entry);
+       if (!pktio_entry->s.inqs_set) {
+               unlock_entry(pktio_entry);
+               return -1;
+       }
+
+       for (i = 0; i < pktio_entry->s.num_rx_queues; i++)
+               queues[i] = pktio_entry->s.inqs_default[i];
+       unlock_entry(pktio_entry);
+
+       return 0;
 }
 
 odp_queue_t odp_pktio_outq_getdef(odp_pktio_t id)
 {
+       odp_queue_t queue;
+
+       return odp_pktio_outqs_getdef(id, &queue) ? ODP_QUEUE_INVALID : queue;
+}
+
+int odp_pktio_outqs_getdef(odp_pktio_t id, odp_queue_t queues[])
+{
        pktio_entry_t *pktio_entry = get_pktio_entry(id);
+       unsigned int i;
 
        if (pktio_entry == NULL)
-               return ODP_QUEUE_INVALID;
+               return -1;
 
-       return pktio_entry->s.outq_default;
+       lock_entry(pktio_entry);
+       for (i = 0; i < pktio_entry->s.num_tx_queues; i++)
+               queues[i] = pktio_entry->s.outqs_default[i];
+       unlock_entry(pktio_entry);
+
+       return 0;
 }
 
 int pktout_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr)
@@ -641,7 +753,8 @@ 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_pktio_send_queue(qentry->s.pktout, qentry->s.pktout_qid, &pkt,
+                                  len);
        return (nbr == len ? 0 : -1);
 }
 
@@ -661,7 +774,8 @@ 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_pktio_send_queue(qentry->s.pktout, qentry->s.pktout_qid,
+                                  pkt_tbl, num);
        return nbr;
 }
 
@@ -695,7 +809,8 @@ odp_buffer_hdr_t *pktin_dequeue(queue_entry_t *qentry)
 
        pktio = qentry->s.pktin;
 
-       pkts = odp_pktio_recv(pktio, pkt_tbl, QUEUE_MULTI_MAX);
+       pkts = odp_pktio_recv_queue(pktio, qentry->s.pktin_qid, pkt_tbl,
+                                   QUEUE_MULTI_MAX);
        if (pkts <= 0)
                return NULL;
 
@@ -754,7 +869,8 @@ int pktin_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t 
*buf_hdr[], int num)
 
        pktio = qentry->s.pktin;
 
-       pkts = odp_pktio_recv(pktio, pkt_tbl, QUEUE_MULTI_MAX);
+       pkts = odp_pktio_recv_queue(pktio, qentry->s.pktin_qid, pkt_tbl,
+                                   QUEUE_MULTI_MAX);
        if (pkts <= 0)
                return nbr;
 
@@ -786,7 +902,7 @@ int pktin_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t 
*buf_hdr[], int num)
        return nbr;
 }
 
-int pktin_poll(pktio_entry_t *entry)
+int pktin_poll(pktio_entry_t *entry, uint32_t qid)
 {
        odp_packet_t pkt_tbl[QUEUE_MULTI_MAX];
        odp_buffer_hdr_t *hdr_tbl[QUEUE_MULTI_MAX];
@@ -799,14 +915,13 @@ int pktin_poll(pktio_entry_t *entry)
        if (odp_unlikely(is_free(entry)))
                return -1;
 
-       if (odp_unlikely(entry->s.inq_default == ODP_QUEUE_INVALID))
+       if (odp_unlikely(entry->s.inqs_default[qid] == ODP_QUEUE_INVALID))
                return -1;
 
        if (entry->s.state == STATE_STOP)
                return 0;
 
-       num = odp_pktio_recv(pktio, pkt_tbl, QUEUE_MULTI_MAX);
-
+       num = odp_pktio_recv_queue(pktio, qid, pkt_tbl, QUEUE_MULTI_MAX);
        if (num == 0)
                return 0;
 
@@ -833,7 +948,7 @@ int pktin_poll(pktio_entry_t *entry)
 
        if (num_enq) {
                queue_entry_t *qentry;
-               qentry = queue_to_qentry(entry->s.inq_default);
+               qentry = queue_to_qentry(entry->s.inqs_default[qid]);
                queue_enq_multi(qentry, hdr_tbl, num_enq, 0);
        }
 
diff --git a/platform/linux-generic/odp_schedule.c 
b/platform/linux-generic/odp_schedule.c
index 827fcf0..5b2ffd7 100644
--- a/platform/linux-generic/odp_schedule.c
+++ b/platform/linux-generic/odp_schedule.c
@@ -68,6 +68,7 @@ typedef struct {
 
                struct {
                        odp_pktio_t   pktio;
+                       uint32_t      qid;
                        pktio_entry_t *pe;
                        int           prio;
                };
@@ -272,9 +273,9 @@ static int pri_id_queue(odp_queue_t queue)
        return (QUEUES_PER_PRIO-1) & (queue_to_id(queue));
 }
 
-static int pri_id_pktio(odp_pktio_t pktio)
+static int pri_id_pktio(odp_pktio_t pktio, uint32_t qid)
 {
-       return (QUEUES_PER_PRIO-1) & (pktio_to_id(pktio));
+       return (QUEUES_PER_PRIO - 1) & (pktio_to_id(pktio) + qid);
 }
 
 static odp_queue_t pri_set(int id, int prio)
@@ -307,9 +308,9 @@ static odp_queue_t pri_set_queue(odp_queue_t queue, int 
prio)
        return pri_set(id, prio);
 }
 
-static odp_queue_t pri_set_pktio(odp_pktio_t pktio, int prio)
+static odp_queue_t pri_set_pktio(odp_pktio_t pktio, int prio, uint32_t qid)
 {
-       int id = pri_id_pktio(pktio);
+       int id = pri_id_pktio(pktio, qid);
 
        return pri_set(id, prio);
 }
@@ -320,9 +321,9 @@ static void pri_clr_queue(odp_queue_t queue, int prio)
        pri_clr(id, prio);
 }
 
-static void pri_clr_pktio(odp_pktio_t pktio, int prio)
+static void pri_clr_pktio(odp_pktio_t pktio, int prio, uint32_t qid)
 {
-       int id = pri_id_pktio(pktio);
+       int id = pri_id_pktio(pktio, qid);
        pri_clr(id, prio);
 }
 
@@ -358,6 +359,11 @@ void schedule_queue_destroy(queue_entry_t *qe)
 
 int schedule_pktio_start(odp_pktio_t pktio, int prio)
 {
+       return schedule_pktio_start_queue(pktio, prio, 0);
+}
+
+int schedule_pktio_start_queue(odp_pktio_t pktio, int prio, uint32_t qid)
+{
        odp_buffer_t buf;
        sched_cmd_t *sched_cmd;
        odp_queue_t pri_queue;
@@ -370,10 +376,11 @@ int schedule_pktio_start(odp_pktio_t pktio, int prio)
        sched_cmd        = odp_buffer_addr(buf);
        sched_cmd->cmd   = SCHED_CMD_POLL_PKTIN;
        sched_cmd->pktio = pktio;
+       sched_cmd->qid   = qid;
        sched_cmd->pe    = get_pktio_entry(pktio);
        sched_cmd->prio  = prio;
 
-       pri_queue  = pri_set_pktio(pktio, prio);
+       pri_queue  = pri_set_pktio(pktio, prio, qid);
 
        if (odp_queue_enq(pri_queue, odp_buffer_to_event(buf)))
                ODP_ABORT("schedule_pktio_start failed\n");
@@ -491,10 +498,11 @@ static int schedule(odp_queue_t *out_queue, odp_event_t 
out_ev[],
 
                        if (sched_cmd->cmd == SCHED_CMD_POLL_PKTIN) {
                                /* Poll packet input */
-                               if (pktin_poll(sched_cmd->pe)) {
+                               if (pktin_poll(sched_cmd->pe, sched_cmd->qid)) {
                                        /* Stop scheduling the pktio */
                                        pri_clr_pktio(sched_cmd->pktio,
-                                                     sched_cmd->prio);
+                                                     sched_cmd->prio,
+                                                     sched_cmd->qid);
                                        odp_buffer_free(buf);
                                } else {
                                        /* Continue scheduling the pktio */
-- 
2.5.3

_______________________________________________
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to