diff options
author | Petri Savolainen <petri.savolainen@linaro.org> | 2018-10-30 15:46:52 +0200 |
---|---|---|
committer | Maxim Uvarov <maxim.uvarov@linaro.org> | 2018-11-28 17:16:39 +0300 |
commit | ec16951089de3ed475570d253f1f0b0746304cc9 (patch) | |
tree | 4c348c6aa8e3333e0fd6f0d9aceebf61646a09c0 | |
parent | 7b23d26816a334804277a87e5ea93f2958e5a6ec (diff) |
linux-gen: sched: implement min/max/default prio functions
Implemented the new functions for all schedulers. API defines now
that priority level increases with the integer value.
Implementations use internally inversed priority levels (max == 0).
Classifier test had wrong assumption about previous API priority
level specification, and needed fixing. Previously, integer values
were implementation specific, i.e. it was possible that value of
PRIO_LOWEST < PRIO_HIGHEST, or PRIO_LOWEST > PRIO_HIGHEST.
Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>
Reviewed-by: Bill Fischofer <bill.fischofer@linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
-rw-r--r-- | include/odp/api/abi-default/schedule_types.h | 8 | ||||
-rw-r--r-- | platform/linux-generic/include/odp_schedule_if.h | 3 | ||||
-rw-r--r-- | platform/linux-generic/odp_queue_basic.c | 20 | ||||
-rw-r--r-- | platform/linux-generic/odp_queue_scalable.c | 21 | ||||
-rw-r--r-- | platform/linux-generic/odp_schedule_basic.c | 43 | ||||
-rw-r--r-- | platform/linux-generic/odp_schedule_if.c | 15 | ||||
-rw-r--r-- | platform/linux-generic/odp_schedule_scalable.c | 25 | ||||
-rw-r--r-- | platform/linux-generic/odp_schedule_sp.c | 27 | ||||
-rw-r--r-- | test/validation/api/classification/odp_classification_tests.c | 10 |
9 files changed, 132 insertions, 40 deletions
diff --git a/include/odp/api/abi-default/schedule_types.h b/include/odp/api/abi-default/schedule_types.h index e7258f0c7..6c7730cd9 100644 --- a/include/odp/api/abi-default/schedule_types.h +++ b/include/odp/api/abi-default/schedule_types.h @@ -21,13 +21,13 @@ extern "C" { * @{ */ -#define ODP_SCHED_PRIO_HIGHEST 0 +#define ODP_SCHED_PRIO_HIGHEST (odp_schedule_max_prio()) -#define ODP_SCHED_PRIO_NORMAL 4 +#define ODP_SCHED_PRIO_NORMAL (odp_schedule_default_prio()) -#define ODP_SCHED_PRIO_LOWEST 7 +#define ODP_SCHED_PRIO_LOWEST (odp_schedule_min_prio()) -#define ODP_SCHED_PRIO_DEFAULT ODP_SCHED_PRIO_NORMAL +#define ODP_SCHED_PRIO_DEFAULT (odp_schedule_default_prio()) typedef int odp_schedule_sync_t; diff --git a/platform/linux-generic/include/odp_schedule_if.h b/platform/linux-generic/include/odp_schedule_if.h index a131b6eb5..8c00f9227 100644 --- a/platform/linux-generic/include/odp_schedule_if.h +++ b/platform/linux-generic/include/odp_schedule_if.h @@ -97,6 +97,9 @@ typedef struct { void (*schedule_release_atomic)(void); void (*schedule_release_ordered)(void); void (*schedule_prefetch)(int); + int (*schedule_min_prio)(void); + int (*schedule_max_prio)(void); + int (*schedule_default_prio)(void); int (*schedule_num_prio)(void); odp_schedule_group_t (*schedule_group_create)(const char *, const odp_thrmask_t *); diff --git a/platform/linux-generic/odp_queue_basic.c b/platform/linux-generic/odp_queue_basic.c index 5790e1c3d..f02a9a329 100644 --- a/platform/linux-generic/odp_queue_basic.c +++ b/platform/linux-generic/odp_queue_basic.c @@ -270,21 +270,31 @@ static odp_queue_t queue_create(const char *name, uint32_t i; queue_entry_t *queue; void *queue_lf; - odp_queue_t handle = ODP_QUEUE_INVALID; - odp_queue_type_t type = ODP_QUEUE_TYPE_PLAIN; + odp_queue_type_t type; odp_queue_param_t default_param; + odp_queue_t handle = ODP_QUEUE_INVALID; if (param == NULL) { odp_queue_param_init(&default_param); param = &default_param; } + type = param->type; + + if (type == ODP_QUEUE_TYPE_SCHED) { + if (param->sched.prio < odp_schedule_min_prio() || + param->sched.prio > odp_schedule_max_prio()) { + ODP_ERR("Bad queue priority: %i\n", param->sched.prio); + return ODP_QUEUE_INVALID; + } + } + if (param->nonblocking == ODP_BLOCKING) { if (param->size > queue_glb->config.max_queue_size) return ODP_QUEUE_INVALID; } else if (param->nonblocking == ODP_NONBLOCKING_LF) { /* Only plain type lock-free queues supported */ - if (param->type != ODP_QUEUE_TYPE_PLAIN) + if (type != ODP_QUEUE_TYPE_PLAIN) return ODP_QUEUE_INVALID; if (param->size > queue_glb->queue_lf_size) return ODP_QUEUE_INVALID; @@ -327,8 +337,6 @@ static odp_queue_t queue_create(const char *name, queue->s.orig_dequeue_multi = lf_fn->deq_multi; } - type = queue->s.type; - if (type == ODP_QUEUE_TYPE_SCHED) queue->s.status = QUEUE_STATUS_NOTSCHED; else @@ -607,7 +615,7 @@ static void queue_param_init(odp_queue_param_t *params) params->enq_mode = ODP_QUEUE_OP_MT; params->deq_mode = ODP_QUEUE_OP_MT; params->nonblocking = ODP_BLOCKING; - params->sched.prio = ODP_SCHED_PRIO_DEFAULT; + params->sched.prio = odp_schedule_default_prio(); params->sched.sync = ODP_SCHED_SYNC_PARALLEL; params->sched.group = ODP_SCHED_GROUP_ALL; } diff --git a/platform/linux-generic/odp_queue_scalable.c b/platform/linux-generic/odp_queue_scalable.c index 4f2c1b6ce..5bff13543 100644 --- a/platform/linux-generic/odp_queue_scalable.c +++ b/platform/linux-generic/odp_queue_scalable.c @@ -167,6 +167,8 @@ static int queue_init(queue_entry_t *queue, const char *name, /* Queue initialized successfully, add it to the sched group */ if (queue->s.type == ODP_QUEUE_TYPE_SCHED) { + int prio = odp_schedule_max_prio() - param->sched.prio; + if (queue->s.param.sched.sync == ODP_SCHED_SYNC_ORDERED) { sched_elem->rwin = rwin_alloc(queue_shm_pool, @@ -177,9 +179,9 @@ static int queue_init(queue_entry_t *queue, const char *name, } } sched_elem->sched_grp = param->sched.group; - sched_elem->sched_prio = param->sched.prio; + sched_elem->sched_prio = prio; sched_elem->schedq = - sched_queue_add(param->sched.group, param->sched.prio); + sched_queue_add(param->sched.group, prio); ODP_ASSERT(sched_elem->schedq != NULL); } @@ -356,15 +358,26 @@ static odp_queue_t queue_create(const char *name, const odp_queue_param_t *param) { int queue_idx; - odp_queue_t handle = ODP_QUEUE_INVALID; queue_entry_t *queue; + odp_queue_type_t type; odp_queue_param_t default_param; + odp_queue_t handle = ODP_QUEUE_INVALID; if (param == NULL) { odp_queue_param_init(&default_param); param = &default_param; } + type = param->type; + + if (type == ODP_QUEUE_TYPE_SCHED) { + if (param->sched.prio < odp_schedule_min_prio() || + param->sched.prio > odp_schedule_max_prio()) { + ODP_ERR("Bad queue priority: %i\n", param->sched.prio); + return ODP_QUEUE_INVALID; + } + } + for (queue_idx = 0; queue_idx < ODP_CONFIG_QUEUES; queue_idx++) { queue = &queue_tbl->queue[queue_idx]; @@ -872,7 +885,7 @@ static void queue_param_init(odp_queue_param_t *params) params->enq_mode = ODP_QUEUE_OP_MT; params->deq_mode = ODP_QUEUE_OP_MT; params->nonblocking = ODP_BLOCKING; - params->sched.prio = ODP_SCHED_PRIO_DEFAULT; + params->sched.prio = odp_schedule_default_prio(); params->sched.sync = ODP_SCHED_SYNC_PARALLEL; params->sched.group = ODP_SCHED_GROUP_ALL; } diff --git a/platform/linux-generic/odp_schedule_basic.c b/platform/linux-generic/odp_schedule_basic.c index 22eb6ff13..3ce251477 100644 --- a/platform/linux-generic/odp_schedule_basic.c +++ b/platform/linux-generic/odp_schedule_basic.c @@ -36,13 +36,6 @@ /* Number of priority levels */ #define NUM_PRIO 8 -ODP_STATIC_ASSERT(ODP_SCHED_PRIO_LOWEST == (NUM_PRIO - 1), - "lowest_prio_does_not_match_with_num_prios"); - -ODP_STATIC_ASSERT((ODP_SCHED_PRIO_NORMAL > 0) && - (ODP_SCHED_PRIO_NORMAL < (NUM_PRIO - 1)), - "normal_prio_is_not_between_highest_and_lowest"); - /* Number of scheduling groups */ #define NUM_SCHED_GRPS 32 @@ -195,6 +188,7 @@ typedef struct { struct { uint8_t grp; + /* Inverted prio value (max = 0) vs API (min = 0)*/ uint8_t prio; uint8_t spread; uint8_t sync; @@ -537,6 +531,31 @@ static uint32_t schedule_max_ordered_locks(void) return CONFIG_QUEUE_MAX_ORD_LOCKS; } +static int schedule_min_prio(void) +{ + return 0; +} + +static int schedule_max_prio(void) +{ + return NUM_PRIO - 1; +} + +static int schedule_default_prio(void) +{ + return schedule_max_prio() / 2; +} + +static int schedule_num_prio(void) +{ + return NUM_PRIO; +} + +static inline int prio_level_from_api(int api_prio) +{ + return schedule_max_prio() - api_prio; +} + static void pri_set(int id, int prio) { odp_spinlock_lock(&sched->mask_lock); @@ -576,7 +595,7 @@ static int schedule_init_queue(uint32_t queue_index, { uint32_t ring_size; int i; - int prio = sched_param->prio; + int prio = prio_level_from_api(sched_param->prio); pri_set_queue(queue_index, prio); sched->queue[queue_index].grp = sched_param->group; @@ -1289,11 +1308,6 @@ static uint64_t schedule_wait_time(uint64_t ns) return ns; } -static int schedule_num_prio(void) -{ - return NUM_PRIO; -} - static odp_schedule_group_t schedule_group_create(const char *name, const odp_thrmask_t *mask) { @@ -1542,6 +1556,9 @@ const schedule_api_t schedule_basic_api = { .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, diff --git a/platform/linux-generic/odp_schedule_if.c b/platform/linux-generic/odp_schedule_if.c index c88b35fd5..084dced69 100644 --- a/platform/linux-generic/odp_schedule_if.c +++ b/platform/linux-generic/odp_schedule_if.c @@ -66,6 +66,21 @@ void odp_schedule_prefetch(int num) return sched_api->schedule_prefetch(num); } +int odp_schedule_min_prio(void) +{ + return sched_api->schedule_min_prio(); +} + +int odp_schedule_max_prio(void) +{ + return sched_api->schedule_max_prio(); +} + +int odp_schedule_default_prio(void) +{ + return sched_api->schedule_default_prio(); +} + int odp_schedule_num_prio(void) { return sched_api->schedule_num_prio(); diff --git a/platform/linux-generic/odp_schedule_scalable.c b/platform/linux-generic/odp_schedule_scalable.c index ccafcb770..05e285323 100644 --- a/platform/linux-generic/odp_schedule_scalable.c +++ b/platform/linux-generic/odp_schedule_scalable.c @@ -46,13 +46,6 @@ #define FLAG_PKTIN 0x80 -ODP_STATIC_ASSERT(ODP_SCHED_PRIO_LOWEST == (ODP_SCHED_PRIO_NUM - 2), - "lowest_prio_does_not_match_with_num_prios"); - -ODP_STATIC_ASSERT((ODP_SCHED_PRIO_NORMAL > 0) && - (ODP_SCHED_PRIO_NORMAL < (ODP_SCHED_PRIO_NUM - 2)), - "normal_prio_is_not_between_highest_and_lowest"); - ODP_STATIC_ASSERT(CHECK_IS_POWER2(ODP_CONFIG_QUEUES), "Number_of_queues_is_not_power_of_two"); @@ -1368,6 +1361,21 @@ static int schedule_num_prio(void) return ODP_SCHED_PRIO_NUM - 1; /* Discount the pktin priority level */ } +static int schedule_min_prio(void) +{ + return 0; +} + +static int schedule_max_prio(void) +{ + return schedule_num_prio() - 1; +} + +static int schedule_default_prio(void) +{ + return schedule_max_prio() / 2; +} + static int schedule_group_update(sched_group_t *sg, uint32_t sgi, const odp_thrmask_t *mask, @@ -2114,6 +2122,9 @@ const schedule_api_t schedule_scalable_api = { .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, diff --git a/platform/linux-generic/odp_schedule_sp.c b/platform/linux-generic/odp_schedule_sp.c index 52c8873cc..055ee35f0 100644 --- a/platform/linux-generic/odp_schedule_sp.c +++ b/platform/linux-generic/odp_schedule_sp.c @@ -26,11 +26,12 @@ #define NUM_QUEUE ODP_CONFIG_QUEUES #define NUM_PKTIO ODP_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 @@ -367,8 +368,8 @@ static int init_queue(uint32_t qi, const odp_schedule_param_t *sched_param) 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; @@ -668,6 +669,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 @@ -926,6 +942,9 @@ const schedule_api_t schedule_sp_api = { .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, diff --git a/test/validation/api/classification/odp_classification_tests.c b/test/validation/api/classification/odp_classification_tests.c index 3b9e02761..a5de458cd 100644 --- a/test/validation/api/classification/odp_classification_tests.c +++ b/test/validation/api/classification/odp_classification_tests.c @@ -18,6 +18,7 @@ static odp_pool_t pool_list[CLS_ENTRIES]; static odp_pool_t pool_default; static odp_pktio_t pktio_loop; static odp_cls_testcase_u tc; +static int global_num_l2_qos; #define NUM_COS_PMR_CHAIN 2 #define NUM_COS_DEFAULT 1 @@ -457,12 +458,17 @@ void configure_cos_with_l2_priority(void) for (i = 0; i < CLS_L2_QOS_MAX; i++) qos_tbl[i] = 0; + if (odp_schedule_num_prio() < num_qos) + num_qos = odp_schedule_num_prio(); + + global_num_l2_qos = num_qos; + odp_queue_param_init(&qparam); qparam.type = ODP_QUEUE_TYPE_SCHED; qparam.sched.sync = ODP_SCHED_SYNC_PARALLEL; qparam.sched.group = ODP_SCHED_GROUP_ALL; for (i = 0; i < num_qos; i++) { - qparam.sched.prio = ODP_SCHED_PRIO_LOWEST - i; + qparam.sched.prio = ODP_SCHED_PRIO_LOWEST + i; sprintf(queuename, "%s_%d", "L2_Queue", i); queue_tbl[i] = odp_queue_create(queuename, &qparam); CU_ASSERT_FATAL(queue_tbl[i] != ODP_QUEUE_INVALID); @@ -506,7 +512,7 @@ void test_cos_with_l2_priority(void) pkt_info.udp = true; pkt_info.vlan = true; - for (i = 0; i < CLS_L2_QOS_MAX; i++) { + for (i = 0; i < global_num_l2_qos; i++) { pkt = create_packet(pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); |