diff options
Diffstat (limited to 'platform/linux-generic/odp_schedule_sp.c')
-rw-r--r-- | platform/linux-generic/odp_schedule_sp.c | 522 |
1 files changed, 390 insertions, 132 deletions
diff --git a/platform/linux-generic/odp_schedule_sp.c b/platform/linux-generic/odp_schedule_sp.c index d2ba539ce..1ada5581b 100644 --- a/platform/linux-generic/odp_schedule_sp.c +++ b/platform/linux-generic/odp_schedule_sp.c @@ -1,30 +1,50 @@ -/* Copyright (c) 2016, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2016-2018 Linaro Limited + * Copyright (c) 2019-2021 Nokia */ -#include <string.h> +/* + * Suppress bounds warnings about interior zero length arrays. Such an array + * is used intentionally in prio_queue_t. + */ +#if __GNUC__ >= 10 +#pragma GCC diagnostic ignored "-Wzero-length-bounds" +#endif + +#include <odp/api/packet.h> #include <odp/api/ticketlock.h> #include <odp/api/thread.h> +#include <odp/api/plat/thread_inlines.h> #include <odp/api/time.h> +#include <odp/api/plat/time_inlines.h> #include <odp/api/schedule.h> #include <odp/api/shared_memory.h> + +#include <odp/api/plat/schedule_inline_types.h> + #include <odp_schedule_if.h> #include <odp_debug_internal.h> -#include <odp_align_internal.h> #include <odp_config_internal.h> -#include <odp_ring_internal.h> +#include <odp_event_internal.h> +#include <odp_macros_internal.h> +#include <odp_ring_u32_internal.h> +#include <odp_timer_internal.h> +#include <odp_queue_basic_internal.h> +#include <odp_string_internal.h> +#include <odp_global_data.h> + +#include <string.h> #define NUM_THREAD ODP_THREAD_COUNT_MAX -#define NUM_QUEUE ODP_CONFIG_QUEUES -#define NUM_PKTIO ODP_CONFIG_PKTIO_ENTRIES +#define NUM_QUEUE CONFIG_MAX_SCHED_QUEUES +#define NUM_PKTIO CONFIG_PKTIO_ENTRIES #define NUM_ORDERED_LOCKS 1 -#define NUM_PRIO 3 #define NUM_STATIC_GROUP 3 #define NUM_GROUP (NUM_STATIC_GROUP + 9) #define NUM_PKTIN 32 -#define LOWEST_QUEUE_PRIO (NUM_PRIO - 2) +#define NUM_PRIO 3 +#define MAX_API_PRIO (NUM_PRIO - 2) +/* Lowest internal priority */ #define PKTIN_PRIO (NUM_PRIO - 1) #define CMD_QUEUE 0 #define CMD_PKTIO 1 @@ -34,20 +54,17 @@ #define GROUP_PKTIN GROUP_ALL /* Maximum number of commands: one priority/group for all queues and pktios */ -#define RING_SIZE (ROUNDUP_POWER2_U32(NUM_QUEUE + NUM_PKTIO)) +#define RING_SIZE (_ODP_ROUNDUP_POWER2_U32(NUM_QUEUE + NUM_PKTIO)) #define RING_MASK (RING_SIZE - 1) /* Ring size must be power of two */ -ODP_STATIC_ASSERT(CHECK_IS_POWER2(RING_SIZE), +ODP_STATIC_ASSERT(_ODP_CHECK_IS_POWER2(RING_SIZE), "Ring_size_is_not_power_of_two"); ODP_STATIC_ASSERT(NUM_ORDERED_LOCKS <= CONFIG_QUEUE_MAX_ORD_LOCKS, "Too_many_ordered_locks"); -struct sched_cmd_t; - -struct sched_cmd_s { - struct sched_cmd_t *next; +typedef struct ODP_ALIGNED_CACHE { uint32_t index; uint32_t ring_idx; int type; @@ -56,22 +73,20 @@ struct sched_cmd_s { int init; int num_pktin; int pktin_idx[NUM_PKTIN]; -}; - -typedef struct sched_cmd_t { - struct sched_cmd_s s; - uint8_t pad[ROUNDUP_CACHE_LINE(sizeof(struct sched_cmd_s)) - - sizeof(struct sched_cmd_s)]; -} sched_cmd_t ODP_ALIGNED_CACHE; + odp_queue_t queue[NUM_PKTIN]; +} sched_cmd_t; -typedef struct { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" +typedef struct ODP_ALIGNED_CACHE { /* Ring header */ - ring_t ring; + ring_u32_t ring; /* Ring data: queue indexes */ - uint32_t ring_idx[RING_SIZE]; + uint32_t ring_idx[RING_SIZE]; /* overlaps with ring.data[] */ -} prio_queue_t ODP_ALIGNED_CACHE; +} prio_queue_t; +#pragma GCC diagnostic pop typedef struct thr_group_t { /* A generation counter for fast comparison if groups have changed */ @@ -85,13 +100,13 @@ typedef struct thr_group_t { } thr_group_t; -typedef struct sched_group_t { +typedef struct ODP_ALIGNED_CACHE sched_group_t { struct { odp_ticketlock_t lock; /* All groups */ struct { - char name[ODP_SCHED_GROUP_NAME_LEN + 1]; + char name[ODP_SCHED_GROUP_NAME_LEN]; odp_thrmask_t mask; int allocated; } group[NUM_GROUP]; @@ -101,14 +116,20 @@ typedef struct sched_group_t { } s; -} sched_group_t ODP_ALIGNED_CACHE; +} sched_group_t; typedef struct { sched_cmd_t queue_cmd[NUM_QUEUE]; sched_cmd_t pktio_cmd[NUM_PKTIO]; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" prio_queue_t prio_queue[NUM_GROUP][NUM_PRIO]; +#pragma GCC diagnostic pop sched_group_t sched_group; odp_shm_t shm; + /* Scheduler interface config options (not used in fast path) */ + schedule_config_t config_if; } sched_global_t; typedef struct { @@ -123,6 +144,8 @@ typedef struct { static sched_global_t *sched_global; static __thread sched_local_t sched_local; +static void remove_group(sched_group_t *sched_group, int thr, int group); + static inline uint32_t index_to_ring_idx(int pktio, uint32_t index) { if (pktio) @@ -149,16 +172,16 @@ static int init_global(void) odp_shm_t shm; sched_group_t *sched_group = NULL; - ODP_DBG("Using SP scheduler\n"); + _ODP_DBG("Using SP scheduler\n"); - shm = odp_shm_reserve("sp_scheduler", + shm = odp_shm_reserve("_odp_sched_sp_global", sizeof(sched_global_t), ODP_CACHE_LINE_SIZE, 0); sched_global = odp_shm_addr(shm); if (sched_global == NULL) { - ODP_ERR("Schedule init: Shm reserve failed.\n"); + _ODP_ERR("Schedule init: Shm reserve failed.\n"); return -1; } @@ -166,22 +189,22 @@ static int init_global(void) sched_global->shm = shm; for (i = 0; i < NUM_QUEUE; i++) { - sched_global->queue_cmd[i].s.type = CMD_QUEUE; - sched_global->queue_cmd[i].s.index = i; - sched_global->queue_cmd[i].s.ring_idx = index_to_ring_idx(0, i); + sched_global->queue_cmd[i].type = CMD_QUEUE; + sched_global->queue_cmd[i].index = i; + sched_global->queue_cmd[i].ring_idx = index_to_ring_idx(0, i); } for (i = 0; i < NUM_PKTIO; i++) { - sched_global->pktio_cmd[i].s.type = CMD_PKTIO; - sched_global->pktio_cmd[i].s.index = i; - sched_global->pktio_cmd[i].s.ring_idx = index_to_ring_idx(1, i); - sched_global->pktio_cmd[i].s.prio = PKTIN_PRIO; - sched_global->pktio_cmd[i].s.group = GROUP_PKTIN; + sched_global->pktio_cmd[i].type = CMD_PKTIO; + sched_global->pktio_cmd[i].index = i; + sched_global->pktio_cmd[i].ring_idx = index_to_ring_idx(1, i); + sched_global->pktio_cmd[i].prio = PKTIN_PRIO; + sched_global->pktio_cmd[i].group = GROUP_PKTIN; } for (i = 0; i < NUM_GROUP; i++) for (j = 0; j < NUM_PRIO; j++) - ring_init(&sched_global->prio_queue[i][j].ring); + ring_u32_init(&sched_global->prio_queue[i][j].ring); sched_group = &sched_global->sched_group; odp_ticketlock_init(&sched_group->s.lock); @@ -189,21 +212,25 @@ static int init_global(void) for (i = 0; i < NUM_THREAD; i++) odp_atomic_init_u32(&sched_group->s.thr[i].gen_cnt, 0); - strncpy(sched_group->s.group[GROUP_ALL].name, "__group_all", - ODP_SCHED_GROUP_NAME_LEN); + _odp_strcpy(sched_group->s.group[GROUP_ALL].name, "__group_all", + ODP_SCHED_GROUP_NAME_LEN); odp_thrmask_zero(&sched_group->s.group[GROUP_ALL].mask); sched_group->s.group[GROUP_ALL].allocated = 1; - strncpy(sched_group->s.group[GROUP_WORKER].name, "__group_worker", - ODP_SCHED_GROUP_NAME_LEN); + _odp_strcpy(sched_group->s.group[GROUP_WORKER].name, "__group_worker", + ODP_SCHED_GROUP_NAME_LEN); odp_thrmask_zero(&sched_group->s.group[GROUP_WORKER].mask); sched_group->s.group[GROUP_WORKER].allocated = 1; - strncpy(sched_group->s.group[GROUP_CONTROL].name, "__group_control", - ODP_SCHED_GROUP_NAME_LEN); + _odp_strcpy(sched_group->s.group[GROUP_CONTROL].name, "__group_control", + ODP_SCHED_GROUP_NAME_LEN); odp_thrmask_zero(&sched_group->s.group[GROUP_CONTROL].mask); sched_group->s.group[GROUP_CONTROL].allocated = 1; + sched_global->config_if.group_enable.all = 1; + sched_global->config_if.group_enable.control = 1; + sched_global->config_if.group_enable.worker = 1; + return 0; } @@ -217,18 +244,26 @@ static int init_local(void) static int term_global(void) { + odp_event_t event; int qi, ret = 0; for (qi = 0; qi < NUM_QUEUE; qi++) { - if (sched_global->queue_cmd[qi].s.init) { - /* todo: dequeue until empty ? */ - sched_cb_queue_destroy_finalize(qi); + int report = 1; + + if (sched_global->queue_cmd[qi].init) { + while (_odp_sched_queue_deq(qi, &event, 1, 1) > 0) { + if (report) { + _ODP_ERR("Queue not empty\n"); + report = 0; + } + odp_event_free(event); + } } } ret = odp_shm_free(sched_global->shm); if (ret < 0) { - ODP_ERR("Shm free failed for sp_scheduler"); + _ODP_ERR("Shm free failed for sp_scheduler"); ret = -1; } @@ -240,7 +275,61 @@ static int term_local(void) return 0; } -static unsigned max_ordered_locks(void) +static void schedule_config_init(odp_schedule_config_t *config) +{ + config->num_queues = CONFIG_MAX_SCHED_QUEUES; + config->queue_size = _odp_queue_glb->config.max_queue_size; + config->sched_group.all = true; + config->sched_group.control = true; + config->sched_group.worker = true; +} + +static void schedule_group_clear(odp_schedule_group_t group) +{ + sched_group_t *sched_group = &sched_global->sched_group; + int thr; + const odp_thrmask_t *thrmask; + + if (group < 0 || group >= NUM_STATIC_GROUP) + _ODP_ABORT("Invalid scheduling group\n"); + + thrmask = &sched_group->s.group[group].mask; + + thr = odp_thrmask_first(thrmask); + while (thr >= 0) { + remove_group(sched_group, thr, group); + thr = odp_thrmask_next(thrmask, thr); + } + + memset(&sched_group->s.group[group], 0, sizeof(sched_group->s.group[0])); +} + +static int schedule_config(const odp_schedule_config_t *config) +{ + sched_group_t *sched_group = &sched_global->sched_group; + + odp_ticketlock_lock(&sched_group->s.lock); + + sched_global->config_if.group_enable.all = config->sched_group.all; + sched_global->config_if.group_enable.control = config->sched_group.control; + sched_global->config_if.group_enable.worker = config->sched_group.worker; + + /* Remove existing threads from predefined scheduling groups. */ + if (!config->sched_group.all) + schedule_group_clear(ODP_SCHED_GROUP_ALL); + + if (!config->sched_group.worker) + schedule_group_clear(ODP_SCHED_GROUP_WORKER); + + if (!config->sched_group.control) + schedule_group_clear(ODP_SCHED_GROUP_CONTROL); + + odp_ticketlock_unlock(&sched_group->s.lock); + + return 0; +} + +static uint32_t max_ordered_locks(void) { return NUM_ORDERED_LOCKS; } @@ -255,7 +344,7 @@ static void add_group(sched_group_t *sched_group, int thr, int group) thr_group->group[num] = group; thr_group->num_group = num + 1; gen_cnt = odp_atomic_load_u32(&thr_group->gen_cnt); - odp_atomic_store_u32(&thr_group->gen_cnt, gen_cnt + 1); + odp_atomic_store_rel_u32(&thr_group->gen_cnt, gen_cnt + 1); } static void remove_group(sched_group_t *sched_group, int thr, int group) @@ -266,6 +355,12 @@ static void remove_group(sched_group_t *sched_group, int thr, int group) num = thr_group->num_group; + /* Extra array bounds check to suppress warning on GCC 7.4 with -O3 */ + if (num >= NUM_GROUP) { + _ODP_ERR("Too many groups"); + return; + } + for (i = 0; i < num; i++) { if (thr_group->group[i] == group) { found = 1; @@ -282,7 +377,7 @@ static void remove_group(sched_group_t *sched_group, int thr, int group) thr_group->num_group = num - 1; gen_cnt = odp_atomic_load_u32(&thr_group->gen_cnt); - odp_atomic_store_u32(&thr_group->gen_cnt, gen_cnt + 1); + odp_atomic_store_rel_u32(&thr_group->gen_cnt, gen_cnt + 1); } } @@ -290,7 +385,7 @@ static int thr_add(odp_schedule_group_t group, int thr) { sched_group_t *sched_group = &sched_global->sched_group; - if (group < 0 || group >= NUM_GROUP) + if (group < 0 || group >= NUM_STATIC_GROUP) return -1; if (thr < 0 || thr >= NUM_THREAD) @@ -300,7 +395,7 @@ static int thr_add(odp_schedule_group_t group, int thr) if (!sched_group->s.group[group].allocated) { odp_ticketlock_unlock(&sched_group->s.lock); - return -1; + return 0; } odp_thrmask_set(&sched_group->s.group[group].mask, thr); @@ -315,14 +410,14 @@ static int thr_rem(odp_schedule_group_t group, int thr) { sched_group_t *sched_group = &sched_global->sched_group; - if (group < 0 || group >= NUM_GROUP) + if (group < 0 || group >= NUM_STATIC_GROUP) return -1; odp_ticketlock_lock(&sched_group->s.lock); if (!sched_group->s.group[group].allocated) { odp_ticketlock_unlock(&sched_group->s.lock); - return -1; + return 0; } odp_thrmask_clr(&sched_group->s.group[group].mask, thr); @@ -339,44 +434,49 @@ static int num_grps(void) return NUM_GROUP - NUM_STATIC_GROUP; } -static int init_queue(uint32_t qi, const odp_schedule_param_t *sched_param) +static int create_queue(uint32_t qi, const odp_schedule_param_t *sched_param) { sched_group_t *sched_group = &sched_global->sched_group; odp_schedule_group_t group = sched_param->group; int prio = 0; + if (odp_global_rw->schedule_configured == 0) { + _ODP_ERR("Scheduler has not been configured\n"); + return -1; + } + if (group < 0 || group >= NUM_GROUP) return -1; if (!sched_group->s.group[group].allocated) return -1; - if (sched_param->prio > 0) - prio = LOWEST_QUEUE_PRIO; + /* Inverted prio value (max = 0) vs API */ + prio = MAX_API_PRIO - sched_param->prio; - sched_global->queue_cmd[qi].s.prio = prio; - sched_global->queue_cmd[qi].s.group = group; - sched_global->queue_cmd[qi].s.init = 1; + sched_global->queue_cmd[qi].prio = prio; + sched_global->queue_cmd[qi].group = group; + sched_global->queue_cmd[qi].init = 1; return 0; } static void destroy_queue(uint32_t qi) { - sched_global->queue_cmd[qi].s.prio = 0; - sched_global->queue_cmd[qi].s.group = 0; - sched_global->queue_cmd[qi].s.init = 0; + sched_global->queue_cmd[qi].prio = 0; + sched_global->queue_cmd[qi].group = 0; + sched_global->queue_cmd[qi].init = 0; } static inline void add_tail(sched_cmd_t *cmd) { prio_queue_t *prio_queue; - int group = cmd->s.group; - int prio = cmd->s.prio; - uint32_t idx = cmd->s.ring_idx; + int group = cmd->group; + int prio = cmd->prio; + uint32_t idx = cmd->ring_idx; prio_queue = &sched_global->prio_queue[group][prio]; - ring_enq(&prio_queue->ring, RING_MASK, idx); + ring_u32_enq(&prio_queue->ring, RING_MASK, idx); } static inline sched_cmd_t *rem_head(int group, int prio) @@ -386,9 +486,8 @@ static inline sched_cmd_t *rem_head(int group, int prio) int pktio; prio_queue = &sched_global->prio_queue[group][prio]; - ring_idx = ring_deq(&prio_queue->ring, RING_MASK); - if (ring_idx == RING_EMPTY) + if (ring_u32_deq(&prio_queue->ring, RING_MASK, &ring_idx) == 0) return NULL; pktio = index_from_ring_idx(&index, ring_idx); @@ -409,10 +508,10 @@ static int sched_queue(uint32_t qi) return 0; } -static int ord_enq_multi(queue_t q_int, void *buf_hdr[], int num, +static int ord_enq_multi(odp_queue_t queue, void *buf_hdr[], int num, int *ret) { - (void)q_int; + (void)queue; (void)buf_hdr; (void)num; (void)ret; @@ -421,24 +520,27 @@ static int ord_enq_multi(queue_t q_int, void *buf_hdr[], int num, return 0; } -static void pktio_start(int pktio_index, int num, int pktin_idx[]) +static void pktio_start(int pktio_index, + int num, + int pktin_idx[], + odp_queue_t queue[]) { int i; sched_cmd_t *cmd; - ODP_DBG("pktio index: %i, %i pktin queues %i\n", - pktio_index, num, pktin_idx[0]); + _ODP_DBG("pktio index: %i, %i pktin queues %i\n", pktio_index, num, pktin_idx[0]); cmd = &sched_global->pktio_cmd[pktio_index]; if (num > NUM_PKTIN) - ODP_ABORT("Supports only %i pktin queues per interface\n", - NUM_PKTIN); + _ODP_ABORT("Supports only %i pktin queues per interface\n", NUM_PKTIN); - for (i = 0; i < num; i++) - cmd->s.pktin_idx[i] = pktin_idx[i]; + for (i = 0; i < num; i++) { + cmd->pktin_idx[i] = pktin_idx[i]; + cmd->queue[i] = queue[i]; + } - cmd->s.num_pktin = num; + cmd->num_pktin = num; add_tail(cmd); } @@ -490,6 +592,26 @@ static uint64_t schedule_wait_time(uint64_t ns) return ns; } +static inline void enqueue_packets(odp_queue_t queue, + _odp_event_hdr_t *hdr_tbl[], int num_pkt) +{ + int num_enq, num_drop; + + num_enq = odp_queue_enq_multi(queue, (odp_event_t *)hdr_tbl, + num_pkt); + + if (num_enq < 0) + num_enq = 0; + + if (num_enq < num_pkt) { + num_drop = num_pkt - num_enq; + + _ODP_DBG("Dropped %i packets\n", num_drop); + odp_packet_free_multi((odp_packet_t *)&hdr_tbl[num_enq], + num_drop); + } +} + static int schedule_multi(odp_queue_t *from, uint64_t wait, odp_event_t events[], int max_events ODP_UNUSED) { @@ -498,7 +620,7 @@ static int schedule_multi(odp_queue_t *from, uint64_t wait, if (sched_local.cmd) { /* Continue scheduling if queue is not empty */ - if (sched_cb_queue_empty(sched_local.cmd->s.index) == 0) + if (_odp_sched_queue_empty(sched_local.cmd->index) == 0) add_tail(sched_local.cmd); sched_local.cmd = NULL; @@ -514,12 +636,34 @@ static int schedule_multi(odp_queue_t *from, uint64_t wait, cmd = sched_cmd(); - if (cmd && cmd->s.type == CMD_PKTIO) { - if (sched_cb_pktin_poll(cmd->s.index, cmd->s.num_pktin, - cmd->s.pktin_idx)) { - /* Pktio stopped or closed. */ - sched_cb_pktio_stop_finalize(cmd->s.index); - } else { + if (cmd && cmd->type == CMD_PKTIO) { + _odp_event_hdr_t *hdr_tbl[CONFIG_BURST_SIZE]; + int i; + int num_pkt = 0; + int max_num = CONFIG_BURST_SIZE; + int pktio_idx = cmd->index; + int num_pktin = cmd->num_pktin; + int *pktin_idx = cmd->pktin_idx; + odp_queue_t *queue = cmd->queue; + + for (i = 0; i < num_pktin; i++) { + num_pkt = _odp_sched_cb_pktin_poll(pktio_idx, + pktin_idx[i], + hdr_tbl, max_num); + + if (num_pkt < 0) { + /* Pktio stopped or closed. */ + _odp_sched_cb_pktio_stop_finalize(pktio_idx); + break; + } + + if (num_pkt == 0) + continue; + + enqueue_packets(queue[i], hdr_tbl, num_pkt); + } + + if (num_pkt >= 0) { /* Continue polling pktio. */ add_tail(cmd); } @@ -529,6 +673,7 @@ static int schedule_multi(odp_queue_t *from, uint64_t wait, } if (cmd == NULL) { + timer_run(1); /* All priority queues are empty */ if (wait == ODP_SCHED_NO_WAIT) return 0; @@ -537,8 +682,7 @@ static int schedule_multi(odp_queue_t *from, uint64_t wait, continue; if (update_t1) { - t1 = odp_time_sum(odp_time_local(), - odp_time_local_from_ns(wait)); + t1 = odp_time_add_ns(odp_time_local(), wait); update_t1 = 0; continue; } @@ -549,31 +693,26 @@ static int schedule_multi(odp_queue_t *from, uint64_t wait, return 0; } - qi = cmd->s.index; - num = sched_cb_queue_deq_multi(qi, events, 1); + qi = cmd->index; + num = _odp_sched_queue_deq(qi, events, 1, 1); - if (num > 0) { - sched_local.cmd = cmd; + if (num <= 0) { + timer_run(1); + /* Destroyed or empty queue. Remove empty queue from + * scheduling. A dequeue operation to on an already + * empty queue moves it to NOTSCHED state and + * sched_queue() will be called on next enqueue. */ + continue; + } - if (from) - *from = sched_cb_queue_handle(qi); + timer_run(2); - return num; - } + sched_local.cmd = cmd; - if (num < 0) { - /* Destroyed queue */ - sched_cb_queue_destroy_finalize(qi); - continue; - } + if (from) + *from = queue_from_index(qi); - if (num == 0) { - /* Remove empty queue from scheduling. A dequeue - * operation to on an already empty queue moves - * it to NOTSCHED state and sched_queue() will - * be called on next enqueue. */ - continue; - } + return num; } } @@ -587,6 +726,18 @@ static odp_event_t schedule(odp_queue_t *from, uint64_t wait) return ODP_EVENT_INVALID; } +static int schedule_multi_wait(odp_queue_t *from, odp_event_t events[], + int max_num) +{ + return schedule_multi(from, ODP_SCHED_WAIT, events, max_num); +} + +static int schedule_multi_no_wait(odp_queue_t *from, odp_event_t events[], + int max_num) +{ + return schedule_multi(from, ODP_SCHED_NO_WAIT, events, max_num); +} + static void schedule_pause(void) { sched_local.pause = 1; @@ -599,10 +750,12 @@ static void schedule_resume(void) static void schedule_release_atomic(void) { + /* Nothing to do */ } static void schedule_release_ordered(void) { + /* Nothing to do */ } static void schedule_prefetch(int num) @@ -610,6 +763,21 @@ static void schedule_prefetch(int num) (void)num; } +static int schedule_min_prio(void) +{ + return 0; +} + +static int schedule_max_prio(void) +{ + return MAX_API_PRIO; +} + +static int schedule_default_prio(void) +{ + return schedule_max_prio() / 2; +} + static int schedule_num_prio(void) { /* Lowest priority is used for pktin polling and is internal @@ -622,7 +790,7 @@ static odp_schedule_group_t schedule_group_create(const char *name, { odp_schedule_group_t group = ODP_SCHED_GROUP_INVALID; sched_group_t *sched_group = &sched_global->sched_group; - int i; + int i, thr; odp_ticketlock_lock(&sched_group->s.lock); @@ -630,17 +798,27 @@ static odp_schedule_group_t schedule_group_create(const char *name, if (!sched_group->s.group[i].allocated) { char *grp_name = sched_group->s.group[i].name; - if (name == NULL) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" +#if __GNUC__ >= 13 +#pragma GCC diagnostic ignored "-Wstringop-overflow" +#endif + if (name == NULL) grp_name[0] = 0; - } else { - strncpy(grp_name, name, - ODP_SCHED_GROUP_NAME_LEN - 1); - grp_name[ODP_SCHED_GROUP_NAME_LEN - 1] = 0; - } - odp_thrmask_copy(&sched_group->s.group[i].mask, - thrmask); + else + _odp_strcpy(grp_name, name, + ODP_SCHED_GROUP_NAME_LEN); +#pragma GCC diagnostic pop + + odp_thrmask_copy(&sched_group->s.group[i].mask, thrmask); sched_group->s.group[i].allocated = 1; group = i; + + thr = odp_thrmask_first(thrmask); + while (thr >= 0) { + add_group(sched_group, thr, group); + thr = odp_thrmask_next(thrmask, thr); + } break; } } @@ -653,6 +831,8 @@ static odp_schedule_group_t schedule_group_create(const char *name, static int schedule_group_destroy(odp_schedule_group_t group) { sched_group_t *sched_group = &sched_global->sched_group; + int thr; + const odp_thrmask_t *thrmask; if (group < NUM_STATIC_GROUP || group >= NUM_GROUP) return -1; @@ -664,6 +844,14 @@ static int schedule_group_destroy(odp_schedule_group_t group) return -1; } + thrmask = &sched_group->s.group[group].mask; + + thr = odp_thrmask_first(thrmask); + while (thr >= 0) { + remove_group(sched_group, thr, group); + thr = odp_thrmask_next(thrmask, thr); + } + memset(&sched_group->s.group[group], 0, sizeof(sched_group->s.group[0])); @@ -804,32 +992,89 @@ static int schedule_group_info(odp_schedule_group_t group, return 0; } -static void schedule_order_lock(unsigned lock_index) +static void schedule_order_lock(uint32_t lock_index) { (void)lock_index; } -static void schedule_order_unlock(unsigned lock_index) +static void schedule_order_unlock(uint32_t lock_index) +{ + (void)lock_index; +} + +static void schedule_order_unlock_lock(uint32_t unlock_index, + uint32_t lock_index) +{ + (void)unlock_index; + (void)lock_index; +} + +static void schedule_order_lock_start(uint32_t lock_index) +{ + (void)lock_index; +} + +static void schedule_order_lock_wait(uint32_t lock_index) { (void)lock_index; } static void order_lock(void) { + /* Nothing to do */ } static void order_unlock(void) { + /* Nothing to do */ +} + +static int schedule_capability(odp_schedule_capability_t *capa) +{ + memset(capa, 0, sizeof(odp_schedule_capability_t)); + + capa->max_ordered_locks = max_ordered_locks(); + capa->max_groups = num_grps(); + capa->max_prios = schedule_num_prio(); + capa->max_queues = CONFIG_MAX_SCHED_QUEUES; + capa->max_queue_size = _odp_queue_glb->config.max_queue_size; + + return 0; +} + +static void schedule_print(void) +{ + odp_schedule_capability_t capa; + + (void)schedule_capability(&capa); + + _ODP_PRINT("\nScheduler debug info\n"); + _ODP_PRINT("--------------------\n"); + _ODP_PRINT(" scheduler: sp\n"); + _ODP_PRINT(" max groups: %u\n", capa.max_groups); + _ODP_PRINT(" max priorities: %u\n", capa.max_prios); + _ODP_PRINT("\n"); +} + +static void get_config(schedule_config_t *config) +{ + *config = sched_global->config_if; +} + +const _odp_schedule_api_fn_t _odp_schedule_sp_api; + +static const _odp_schedule_api_fn_t *sched_api(void) +{ + return &_odp_schedule_sp_api; } /* Fill in scheduler interface */ -const schedule_fn_t schedule_sp_fn = { - .status_sync = 0, +const schedule_fn_t _odp_schedule_sp_fn = { .pktio_start = pktio_start, .thr_add = thr_add, .thr_rem = thr_rem, .num_grps = num_grps, - .init_queue = init_queue, + .create_queue = create_queue, .destroy_queue = destroy_queue, .sched_queue = sched_queue, .ord_enq_multi = ord_enq_multi, @@ -840,20 +1085,28 @@ const schedule_fn_t schedule_sp_fn = { .order_lock = order_lock, .order_unlock = order_unlock, .max_ordered_locks = max_ordered_locks, - .unsched_queue = NULL, - .save_context = NULL + .get_config = get_config, + .sched_api = sched_api, }; /* Fill in scheduler API calls */ -const schedule_api_t schedule_sp_api = { +const _odp_schedule_api_fn_t _odp_schedule_sp_api = { .schedule_wait_time = schedule_wait_time, + .schedule_capability = schedule_capability, + .schedule_config_init = schedule_config_init, + .schedule_config = schedule_config, .schedule = schedule, .schedule_multi = schedule_multi, + .schedule_multi_wait = schedule_multi_wait, + .schedule_multi_no_wait = schedule_multi_no_wait, .schedule_pause = schedule_pause, .schedule_resume = schedule_resume, .schedule_release_atomic = schedule_release_atomic, .schedule_release_ordered = schedule_release_ordered, .schedule_prefetch = schedule_prefetch, + .schedule_min_prio = schedule_min_prio, + .schedule_max_prio = schedule_max_prio, + .schedule_default_prio = schedule_default_prio, .schedule_num_prio = schedule_num_prio, .schedule_group_create = schedule_group_create, .schedule_group_destroy = schedule_group_destroy, @@ -863,5 +1116,10 @@ const schedule_api_t schedule_sp_api = { .schedule_group_thrmask = schedule_group_thrmask, .schedule_group_info = schedule_group_info, .schedule_order_lock = schedule_order_lock, - .schedule_order_unlock = schedule_order_unlock + .schedule_order_unlock = schedule_order_unlock, + .schedule_order_unlock_lock = schedule_order_unlock_lock, + .schedule_order_lock_start = schedule_order_lock_start, + .schedule_order_lock_wait = schedule_order_lock_wait, + .schedule_order_wait = order_lock, + .schedule_print = schedule_print }; |