aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetri Savolainen <petri.savolainen@linaro.org>2018-10-30 15:46:52 +0200
committerMaxim Uvarov <maxim.uvarov@linaro.org>2018-11-28 17:16:39 +0300
commitec16951089de3ed475570d253f1f0b0746304cc9 (patch)
tree4c348c6aa8e3333e0fd6f0d9aceebf61646a09c0
parent7b23d26816a334804277a87e5ea93f2958e5a6ec (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.h8
-rw-r--r--platform/linux-generic/include/odp_schedule_if.h3
-rw-r--r--platform/linux-generic/odp_queue_basic.c20
-rw-r--r--platform/linux-generic/odp_queue_scalable.c21
-rw-r--r--platform/linux-generic/odp_schedule_basic.c43
-rw-r--r--platform/linux-generic/odp_schedule_if.c15
-rw-r--r--platform/linux-generic/odp_schedule_scalable.c25
-rw-r--r--platform/linux-generic/odp_schedule_sp.c27
-rw-r--r--test/validation/api/classification/odp_classification_tests.c10
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);