Added support for new multi-queue pktio API for scheduled
queues.

Signed-off-by: Petri Savolainen <[email protected]>
---
 .../linux-generic/include/odp_packet_io_internal.h |   8 +-
 .../linux-generic/include/odp_schedule_internal.h  |   3 +-
 platform/linux-generic/odp_packet_io.c             | 136 +++++++++++++--------
 platform/linux-generic/odp_schedule.c              |  26 ++--
 4 files changed, 110 insertions(+), 63 deletions(-)

diff --git a/platform/linux-generic/include/odp_packet_io_internal.h 
b/platform/linux-generic/include/odp_packet_io_internal.h
index fdea65e..61bedc9 100644
--- a/platform/linux-generic/include/odp_packet_io_internal.h
+++ b/platform/linux-generic/include/odp_packet_io_internal.h
@@ -35,6 +35,8 @@ extern "C" {
 
 #define PKTIO_NAME_LEN 256
 
+#define PKTIN_INVALID  ((odp_pktin_queue_t) {ODP_PKTIO_INVALID, 0})
+#define PKTOUT_INVALID ((odp_pktout_queue_t) {ODP_PKTIO_INVALID, 0})
 
 /** Determine if a socket read/write error should be reported. Transient errors
  *  that simply require the caller to retry are ignored, the _send/_recv APIs
@@ -71,7 +73,6 @@ 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 */
        union {
                pkt_loop_t pkt_loop;            /**< Using loopback for IO */
@@ -96,6 +97,9 @@ struct pktio_entry {
 
        /* Storage for queue handles
         * Multi-queue support is pktio driver specific */
+       unsigned num_in_queue;
+       unsigned num_out_queue;
+
        struct {
                odp_queue_t        queue;
                odp_pktin_queue_t  pktin;
@@ -184,7 +188,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, int num_queue, int index[]);
 
 /*
  * Dummy single queue implementations of multi-queue API
diff --git a/platform/linux-generic/include/odp_schedule_internal.h 
b/platform/linux-generic/include/odp_schedule_internal.h
index 6b301cd..78e16c4 100644
--- a/platform/linux-generic/include/odp_schedule_internal.h
+++ b/platform/linux-generic/include/odp_schedule_internal.h
@@ -23,7 +23,8 @@ extern "C" {
 int schedule_queue_init(queue_entry_t *qe);
 void schedule_queue_destroy(queue_entry_t *qe);
 int schedule_queue(const queue_entry_t *qe);
-int schedule_pktio_start(odp_pktio_t pktio, int prio);
+void schedule_pktio_start(odp_pktio_t pktio, int num_in_queue,
+                         int in_queue_idx[], int prio);
 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 c8c262b..d625db2 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -128,9 +128,16 @@ 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 < 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].pktout = PKTOUT_INVALID;
+       }
 
        pktio_classifier_init(entry);
 }
@@ -295,6 +302,7 @@ int odp_pktio_close(odp_pktio_t id)
 int odp_pktio_start(odp_pktio_t id)
 {
        pktio_entry_t *entry;
+       odp_pktio_input_mode_t mode;
        int res = 0;
 
        entry = get_pktio_entry(id);
@@ -310,8 +318,27 @@ int odp_pktio_start(odp_pktio_t id)
                res = entry->s.ops->start(entry);
        if (!res)
                entry->s.state = STATE_START;
+
        unlock_entry(entry);
 
+       mode = entry->s.param.in_mode;
+
+       if (mode == ODP_PKTIN_MODE_SCHED) {
+               unsigned i;
+
+               for (i = 0; i < entry->s.num_in_queue; i++) {
+                       int index = i;
+
+                       if (entry->s.in_queue[i].queue == ODP_QUEUE_INVALID) {
+                               ODP_ERR("No input queue\n");
+                               return -1;
+                       }
+
+                       schedule_pktio_start(id, 1, &index,
+                                            ODP_SCHED_PRIO_LOWEST);
+               }
+       }
+
        return res;
 }
 
@@ -445,30 +472,18 @@ int odp_pktio_inq_setdef(odp_pktio_t id, odp_queue_t 
queue)
                unlock_entry(pktio_entry);
                return -1;
        }
-       pktio_entry->s.inq_default = queue;
+
+       /* Temporary support for default input queue */
+       pktio_entry->s.in_queue[0].queue = queue;
+       pktio_entry->s.in_queue[0].pktin.pktio = id;
+       pktio_entry->s.in_queue[0].pktin.index = 0;
+       pktio_entry->s.num_in_queue = 1;
        unlock_entry(pktio_entry);
 
-       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;
-               }
-               break;
-       default:
-               ODP_ABORT("Bad queue type\n");
-       }
+       /* User polls the input queue */
+       queue_lock(qentry);
+       qentry->s.pktin = id;
+       queue_unlock(qentry);
 
        return 0;
 }
@@ -487,14 +502,19 @@ int odp_pktio_inq_remdef(odp_pktio_t id)
                unlock_entry(pktio_entry);
                return -1;
        }
-       queue = pktio_entry->s.inq_default;
+
+       /* Temporary support for default input queue */
+       queue = pktio_entry->s.in_queue[0].queue;
        qentry = queue_to_qentry(queue);
 
        queue_lock(qentry);
        qentry->s.pktin = ODP_PKTIO_INVALID;
        queue_unlock(qentry);
 
-       pktio_entry->s.inq_default = ODP_QUEUE_INVALID;
+       pktio_entry->s.in_queue[0].queue = ODP_QUEUE_INVALID;
+       pktio_entry->s.in_queue[0].pktin.pktio = ODP_PKTIO_INVALID;
+       pktio_entry->s.in_queue[0].pktin.index = 0;
+       pktio_entry->s.num_in_queue = 0;
        unlock_entry(pktio_entry);
 
        return 0;
@@ -507,7 +527,8 @@ odp_queue_t odp_pktio_inq_getdef(odp_pktio_t id)
        if (pktio_entry == NULL)
                return ODP_QUEUE_INVALID;
 
-       return pktio_entry->s.inq_default;
+       /* Temporary support for default input queue */
+       return pktio_entry->s.in_queue[0].queue;
 }
 
 odp_queue_t odp_pktio_outq_getdef(odp_pktio_t id)
@@ -645,43 +666,47 @@ 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, int num_queue, int index[])
 {
        odp_packet_t pkt_tbl[QUEUE_MULTI_MAX];
        odp_buffer_hdr_t *hdr_tbl[QUEUE_MULTI_MAX];
-       int num, i;
+       int num, i, idx;
        odp_buffer_t buf;
-       odp_pktio_t pktio;
 
-       pktio = entry->s.handle;
-
-       if (odp_unlikely(is_free(entry)))
+       if (odp_unlikely(is_free(entry))) {
+               ODP_ERR("Bad pktio entry\n");
                return -1;
+       }
 
-       if (odp_unlikely(entry->s.inq_default == ODP_QUEUE_INVALID))
+       /* Temporarely needed for odp_pktio_inq_remdef() */
+       if (odp_unlikely(entry->s.num_in_queue == 0))
                return -1;
 
        if (entry->s.state == STATE_STOP)
                return 0;
 
-       num = odp_pktio_recv(pktio, pkt_tbl, QUEUE_MULTI_MAX);
-
-       if (num == 0)
-               return 0;
-
-       if (num < 0) {
-               ODP_ERR("Packet recv error\n");
-               return -1;
-       }
-
-       for (i = 0; i < num; i++) {
-               buf        = _odp_packet_to_buffer(pkt_tbl[i]);
-               hdr_tbl[i] = odp_buf_to_hdr(buf);
-       }
-
-       if (num) {
+       for (idx = 0; idx < num_queue; idx++) {
                queue_entry_t *qentry;
-               qentry = queue_to_qentry(entry->s.inq_default);
+               odp_queue_t queue;
+               odp_pktin_queue_t pktin = entry->s.in_queue[index[idx]].pktin;
+
+               num = odp_pktio_recv_queue(pktin, pkt_tbl, QUEUE_MULTI_MAX);
+
+               if (num == 0)
+                       continue;
+
+               if (num < 0) {
+                       ODP_ERR("Packet recv error\n");
+                       return -1;
+               }
+
+               for (i = 0; i < num; i++) {
+                       buf        = _odp_packet_to_buffer(pkt_tbl[i]);
+                       hdr_tbl[i] = odp_buf_to_hdr(buf);
+               }
+
+               queue = entry->s.in_queue[index[idx]].queue;
+               qentry = queue_to_qentry(queue);
                queue_enq_multi(qentry, hdr_tbl, num, 0);
        }
 
@@ -1111,11 +1136,14 @@ int single_input_queues_config(pktio_entry_t *entry,
 
                entry->s.in_queue[0].queue = queue;
        } else {
-               entry->s.in_queue[0].queue       = ODP_QUEUE_INVALID;
-               entry->s.in_queue[0].pktin.pktio = entry->s.handle;
-               entry->s.in_queue[0].pktin.index = 0;
+               entry->s.in_queue[0].queue = ODP_QUEUE_INVALID;
        }
 
+       entry->s.in_queue[0].pktin.pktio = entry->s.handle;
+       entry->s.in_queue[0].pktin.index = 0;
+
+       entry->s.num_in_queue = 1;
+
        return 0;
 }
 
@@ -1128,6 +1156,8 @@ int single_output_queues_config(pktio_entry_t *entry,
        entry->s.out_queue[0].pktout.pktio = entry->s.handle;
        entry->s.out_queue[0].pktout.index = 0;
 
+       entry->s.num_out_queue = 1;
+
        return 0;
 }
 
diff --git a/platform/linux-generic/odp_schedule.c 
b/platform/linux-generic/odp_schedule.c
index 58f1b1b..22af755 100644
--- a/platform/linux-generic/odp_schedule.c
+++ b/platform/linux-generic/odp_schedule.c
@@ -36,6 +36,8 @@ odp_thrmask_t sched_mask_all;
 /* Maximum number of dequeues */
 #define MAX_DEQ 4
 
+/* Maximum number of packet input queues per command */
+#define MAX_PKTIN 8
 
 /* Mask of queues per priority */
 typedef uint8_t pri_mask_t;
@@ -69,8 +71,10 @@ typedef struct {
 
                struct {
                        odp_pktio_t   pktio;
+                       int           num;
+                       int           index[MAX_PKTIN];
                        pktio_entry_t *pe;
-                       int           prio;
+                       int           prio;
                };
        };
 } sched_cmd_t;
@@ -357,30 +361,36 @@ void schedule_queue_destroy(queue_entry_t *qe)
        qe->s.pri_queue = ODP_QUEUE_INVALID;
 }
 
-int schedule_pktio_start(odp_pktio_t pktio, int prio)
+void schedule_pktio_start(odp_pktio_t pktio, int num_in_queue,
+                         int in_queue_idx[], int prio)
 {
        odp_buffer_t buf;
        sched_cmd_t *sched_cmd;
        odp_queue_t pri_queue;
+       int i;
 
        buf = odp_buffer_alloc(sched->pool);
 
        if (buf == ODP_BUFFER_INVALID)
-               return -1;
+               ODP_ABORT("Sched pool empty\n");
 
        sched_cmd        = odp_buffer_addr(buf);
        sched_cmd->cmd   = SCHED_CMD_POLL_PKTIN;
        sched_cmd->pktio = pktio;
+       sched_cmd->num   = num_in_queue;
        sched_cmd->pe    = get_pktio_entry(pktio);
        sched_cmd->prio  = prio;
 
+       if (num_in_queue > MAX_PKTIN)
+               ODP_ABORT("Too many input queues for scheduler\n");
+
+       for (i = 0; i < num_in_queue; i++)
+               sched_cmd->index[i] = in_queue_idx[i];
+
        pri_queue  = pri_set_pktio(pktio, prio);
 
        if (odp_queue_enq(pri_queue, odp_buffer_to_event(buf)))
                ODP_ABORT("schedule_pktio_start failed\n");
-
-
-       return 0;
 }
 
 void odp_schedule_release_atomic(void)
@@ -493,7 +503,9 @@ 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->num,
+                                              sched_cmd->index)) {
                                        /* Stop scheduling the pktio */
                                        pri_clr_pktio(sched_cmd->pktio,
                                                      sched_cmd->prio);
-- 
2.6.3

_______________________________________________
lng-odp mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to