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