diff mbox

[API-NEXT,2/5] linux-gen: schedule: fix creating event group with no name

Message ID 1476434952-8282-3-git-send-email-matias.elo@nokia.com
State Accepted
Commit 279ecc54b69ad1621fbba837bee31adcc9fd704a
Headers show

Commit Message

Elo, Matias (Nokia - FI/Espoo) Oct. 14, 2016, 8:49 a.m. UTC
Previously trying to create an event group with no name (=NULL) caused a
segfault. Fix this and test it in the validation suite.

Signed-off-by: Matias Elo <matias.elo@nokia.com>

---
 platform/linux-generic/odp_schedule.c              | 26 +++++++++++++++-------
 platform/linux-generic/odp_schedule_sp.c           | 11 +++++++--
 .../validation/api/scheduler/scheduler.c           |  9 +++++++-
 3 files changed, 35 insertions(+), 11 deletions(-)

-- 
2.7.4
diff mbox

Patch

diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c
index 78982d9..e24eec3 100644
--- a/platform/linux-generic/odp_schedule.c
+++ b/platform/linux-generic/odp_schedule.c
@@ -181,6 +181,7 @@  typedef struct {
 	struct {
 		char           name[ODP_SCHED_GROUP_NAME_LEN];
 		odp_thrmask_t  mask;
+		int	       allocated;
 	} sched_grp[NUM_SCHED_GRPS];
 
 	struct {
@@ -869,11 +870,19 @@  static odp_schedule_group_t schedule_group_create(const char *name,
 	odp_spinlock_lock(&sched->grp_lock);
 
 	for (i = SCHED_GROUP_NAMED; i < NUM_SCHED_GRPS; i++) {
-		if (sched->sched_grp[i].name[0] == 0) {
-			strncpy(sched->sched_grp[i].name, name,
-				ODP_SCHED_GROUP_NAME_LEN - 1);
+		if (!sched->sched_grp[i].allocated) {
+			char *grp_name = sched->sched_grp[i].name;
+
+			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->sched_grp[i].mask, mask);
 			group = (odp_schedule_group_t)i;
+			sched->sched_grp[i].allocated = 1;
 			break;
 		}
 	}
@@ -889,10 +898,11 @@  static int schedule_group_destroy(odp_schedule_group_t group)
 	odp_spinlock_lock(&sched->grp_lock);
 
 	if (group < NUM_SCHED_GRPS && group >= SCHED_GROUP_NAMED &&
-	    sched->sched_grp[group].name[0] != 0) {
+	    sched->sched_grp[group].allocated) {
 		odp_thrmask_zero(&sched->sched_grp[group].mask);
 		memset(sched->sched_grp[group].name, 0,
 		       ODP_SCHED_GROUP_NAME_LEN);
+		sched->sched_grp[group].allocated = 0;
 		ret = 0;
 	} else {
 		ret = -1;
@@ -928,7 +938,7 @@  static int schedule_group_join(odp_schedule_group_t group,
 	odp_spinlock_lock(&sched->grp_lock);
 
 	if (group < NUM_SCHED_GRPS && group >= SCHED_GROUP_NAMED &&
-	    sched->sched_grp[group].name[0] != 0) {
+	    sched->sched_grp[group].allocated) {
 		odp_thrmask_or(&sched->sched_grp[group].mask,
 			       &sched->sched_grp[group].mask,
 			       mask);
@@ -949,7 +959,7 @@  static int schedule_group_leave(odp_schedule_group_t group,
 	odp_spinlock_lock(&sched->grp_lock);
 
 	if (group < NUM_SCHED_GRPS && group >= SCHED_GROUP_NAMED &&
-	    sched->sched_grp[group].name[0] != 0) {
+	    sched->sched_grp[group].allocated) {
 		odp_thrmask_t leavemask;
 
 		odp_thrmask_xor(&leavemask, mask, &sched->mask_all);
@@ -973,7 +983,7 @@  static int schedule_group_thrmask(odp_schedule_group_t group,
 	odp_spinlock_lock(&sched->grp_lock);
 
 	if (group < NUM_SCHED_GRPS && group >= SCHED_GROUP_NAMED &&
-	    sched->sched_grp[group].name[0] != 0) {
+	    sched->sched_grp[group].allocated) {
 		*thrmask = sched->sched_grp[group].mask;
 		ret = 0;
 	} else {
@@ -992,7 +1002,7 @@  static int schedule_group_info(odp_schedule_group_t group,
 	odp_spinlock_lock(&sched->grp_lock);
 
 	if (group < NUM_SCHED_GRPS && group >= SCHED_GROUP_NAMED &&
-	    sched->sched_grp[group].name[0] != 0) {
+	    sched->sched_grp[group].allocated) {
 		info->name    = sched->sched_grp[group].name;
 		info->thrmask = sched->sched_grp[group].mask;
 		ret = 0;
diff --git a/platform/linux-generic/odp_schedule_sp.c b/platform/linux-generic/odp_schedule_sp.c
index 2e28aa4..b7b1de4 100644
--- a/platform/linux-generic/odp_schedule_sp.c
+++ b/platform/linux-generic/odp_schedule_sp.c
@@ -501,8 +501,15 @@  static odp_schedule_group_t schedule_group_create(const char *name,
 
 	for (i = NUM_STATIC_GROUP; i < NUM_GROUP; i++) {
 		if (!sched_group->s.group[i].allocated) {
-			strncpy(sched_group->s.group[i].name, name,
-				ODP_SCHED_GROUP_NAME_LEN);
+			char *grp_name = sched_group->s.group[i].name;
+
+			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);
 			sched_group->s.group[i].allocated = 1;
diff --git a/test/common_plat/validation/api/scheduler/scheduler.c b/test/common_plat/validation/api/scheduler/scheduler.c
index 919cfb6..dd3f6cd 100644
--- a/test/common_plat/validation/api/scheduler/scheduler.c
+++ b/test/common_plat/validation/api/scheduler/scheduler.c
@@ -273,7 +273,7 @@  void scheduler_test_groups(void)
 				      ODP_SCHED_SYNC_ORDERED};
 	int thr_id = odp_thread_id();
 	odp_thrmask_t zeromask, mymask, testmask;
-	odp_schedule_group_t mygrp1, mygrp2, lookup;
+	odp_schedule_group_t mygrp1, mygrp2, null_grp, lookup;
 	odp_schedule_group_info_t info;
 
 	odp_thrmask_zero(&zeromask);
@@ -327,6 +327,10 @@  void scheduler_test_groups(void)
 	CU_ASSERT(rc == 0);
 	CU_ASSERT(!odp_thrmask_isset(&testmask, thr_id));
 
+	/* Create group with no name */
+	null_grp = odp_schedule_group_create(NULL, &zeromask);
+	CU_ASSERT(null_grp != ODP_SCHED_GROUP_INVALID);
+
 	/* We shouldn't be able to find our second group before creating it */
 	lookup = odp_schedule_group_lookup("Test Group 2");
 	CU_ASSERT(lookup == ODP_SCHED_GROUP_INVALID);
@@ -338,6 +342,9 @@  void scheduler_test_groups(void)
 	lookup = odp_schedule_group_lookup("Test Group 2");
 	CU_ASSERT(lookup == mygrp2);
 
+	/* Destroy group with no name */
+	CU_ASSERT_FATAL(odp_schedule_group_destroy(null_grp) == 0);
+
 	/* Verify we're not part of it */
 	rc = odp_schedule_group_thrmask(mygrp2, &testmask);
 	CU_ASSERT(rc == 0);