This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "".
The branch, next has been updated via 53d71e1a9e543e8da738fbf4b9d028e750939147 (commit) via 348ba720aa596ad2179de50f8be1486c0b2f2103 (commit) via f4d24e9b3c8fd6fa5f2724e652b45d13ddae1378 (commit) via 4b6d85a80fb0a190cde95944e2cf62886447df93 (commit) via f1502d11a771cf53a9e9ba189c949305cc3ba94e (commit) via 5cd91a6e3bf76edc0045bc379dd18fa75f65ccd2 (commit) from 63a39fabe4924d142d2df041d817f732eb4fdafb (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- commit 53d71e1a9e543e8da738fbf4b9d028e750939147 Author: Yi He yi.he@linaro.org Date: Fri Dec 23 02:32:09 2016 +0000
linux-gen: sched: fix SP scheduler hang in process mode
SP scheduler hangs in process mode performance test due to global data structure were not created in shared memory region.
Signed-off-by: Yi He yi.he@linaro.org Reviewed-and-tested-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/odp_schedule_sp.c b/platform/linux-generic/odp_schedule_sp.c index ad01bfe..bdfb6af 100644 --- a/platform/linux-generic/odp_schedule_sp.c +++ b/platform/linux-generic/odp_schedule_sp.c @@ -9,6 +9,7 @@ #include <odp/api/thread.h> #include <odp/api/time.h> #include <odp/api/schedule.h> +#include <odp/api/shared_memory.h> #include <odp_schedule_if.h> #include <odp_debug_internal.h> #include <odp_align_internal.h> @@ -107,6 +108,7 @@ typedef struct { sched_cmd_t pktio_cmd[NUM_PKTIO]; prio_queue_t prio_queue[NUM_GROUP][NUM_PRIO]; sched_group_t sched_group; + odp_shm_t shm; } sched_global_t;
typedef struct { @@ -118,7 +120,7 @@ typedef struct { int group[NUM_GROUP]; } sched_local_t;
-static sched_global_t sched_global; +static sched_global_t *sched_global; static __thread sched_local_t sched_local;
static inline uint32_t index_to_ring_idx(int pktio, uint32_t index) @@ -144,30 +146,44 @@ static inline uint32_t index_from_ring_idx(uint32_t *index, uint32_t ring_idx) static int init_global(void) { int i, j; - sched_group_t *sched_group = &sched_global.sched_group; + odp_shm_t shm; + sched_group_t *sched_group = NULL;
ODP_DBG("Using SP scheduler\n");
- memset(&sched_global, 0, sizeof(sched_global_t)); + shm = odp_shm_reserve("sp_scheduler", + 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"); + return -1; + } + + memset(sched_global, 0, sizeof(sched_global_t)); + 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].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); }
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].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; }
for (i = 0; i < NUM_GROUP; i++) for (j = 0; j < NUM_PRIO; j++) - ring_init(&sched_global.prio_queue[i][j].ring); + ring_init(&sched_global->prio_queue[i][j].ring);
+ sched_group = &sched_global->sched_group; odp_ticketlock_init(&sched_group->s.lock);
for (i = 0; i < NUM_THREAD; i++) @@ -201,16 +217,22 @@ static int init_local(void)
static int term_global(void) { - int qi; + int qi, ret = 0;
for (qi = 0; qi < NUM_QUEUE; qi++) { - if (sched_global.queue_cmd[qi].s.init) { + if (sched_global->queue_cmd[qi].s.init) { /* todo: dequeue until empty ? */ sched_cb_queue_destroy_finalize(qi); } }
- return 0; + ret = odp_shm_free(sched_global->shm); + if (ret < 0) { + ODP_ERR("Shm free failed for sp_scheduler"); + ret = -1; + } + + return ret; }
static int term_local(void) @@ -266,7 +288,7 @@ static void remove_group(sched_group_t *sched_group, int thr, int group)
static int thr_add(odp_schedule_group_t group, int thr) { - sched_group_t *sched_group = &sched_global.sched_group; + sched_group_t *sched_group = &sched_global->sched_group;
if (group < 0 || group >= NUM_GROUP) return -1; @@ -291,7 +313,7 @@ static int thr_add(odp_schedule_group_t group, int thr)
static int thr_rem(odp_schedule_group_t group, int thr) { - sched_group_t *sched_group = &sched_global.sched_group; + sched_group_t *sched_group = &sched_global->sched_group;
if (group < 0 || group >= NUM_GROUP) return -1; @@ -319,7 +341,7 @@ static int num_grps(void)
static int init_queue(uint32_t qi, const odp_schedule_param_t *sched_param) { - sched_group_t *sched_group = &sched_global.sched_group; + sched_group_t *sched_group = &sched_global->sched_group; odp_schedule_group_t group = sched_param->group; int prio = 0;
@@ -332,18 +354,18 @@ static int init_queue(uint32_t qi, const odp_schedule_param_t *sched_param) if (sched_param->prio > 0) prio = LOWEST_QUEUE_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].s.prio = prio; + sched_global->queue_cmd[qi].s.group = group; + sched_global->queue_cmd[qi].s.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].s.prio = 0; + sched_global->queue_cmd[qi].s.group = 0; + sched_global->queue_cmd[qi].s.init = 0; }
static inline void add_tail(sched_cmd_t *cmd) @@ -353,8 +375,7 @@ static inline void add_tail(sched_cmd_t *cmd) int prio = cmd->s.prio; uint32_t idx = cmd->s.ring_idx;
- prio_queue = &sched_global.prio_queue[group][prio]; - + prio_queue = &sched_global->prio_queue[group][prio]; ring_enq(&prio_queue->ring, RING_MASK, idx); }
@@ -364,8 +385,7 @@ static inline sched_cmd_t *rem_head(int group, int prio) uint32_t ring_idx, index; int pktio;
- prio_queue = &sched_global.prio_queue[group][prio]; - + prio_queue = &sched_global->prio_queue[group][prio]; ring_idx = ring_deq(&prio_queue->ring, RING_MASK);
if (ring_idx == RING_EMPTY) @@ -374,16 +394,16 @@ static inline sched_cmd_t *rem_head(int group, int prio) pktio = index_from_ring_idx(&index, ring_idx);
if (pktio) - return &sched_global.pktio_cmd[index]; + return &sched_global->pktio_cmd[index];
- return &sched_global.queue_cmd[index]; + return &sched_global->queue_cmd[index]; }
static int sched_queue(uint32_t qi) { sched_cmd_t *cmd;
- cmd = &sched_global.queue_cmd[qi]; + cmd = &sched_global->queue_cmd[qi]; add_tail(cmd);
return 0; @@ -409,7 +429,7 @@ static void pktio_start(int pktio_index, int num, int pktin_idx[]) ODP_DBG("pktio index: %i, %i pktin queues %i\n", pktio_index, num, pktin_idx[0]);
- cmd = &sched_global.pktio_cmd[pktio_index]; + cmd = &sched_global->pktio_cmd[pktio_index];
if (num > NUM_PKTIN) ODP_ABORT("Supports only %i pktin queues per interface\n", @@ -427,7 +447,7 @@ static inline sched_cmd_t *sched_cmd(void) { int prio, i; int thr = sched_local.thr_id; - sched_group_t *sched_group = &sched_global.sched_group; + sched_group_t *sched_group = &sched_global->sched_group; thr_group_t *thr_group = &sched_group->s.thr[thr]; uint32_t gen_cnt;
@@ -601,7 +621,7 @@ static odp_schedule_group_t schedule_group_create(const char *name, const odp_thrmask_t *thrmask) { odp_schedule_group_t group = ODP_SCHED_GROUP_INVALID; - sched_group_t *sched_group = &sched_global.sched_group; + sched_group_t *sched_group = &sched_global->sched_group; int i;
odp_ticketlock_lock(&sched_group->s.lock); @@ -632,7 +652,7 @@ 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; + sched_group_t *sched_group = &sched_global->sched_group;
if (group < NUM_STATIC_GROUP || group >= NUM_GROUP) return -1; @@ -655,7 +675,7 @@ static int schedule_group_destroy(odp_schedule_group_t group) static odp_schedule_group_t schedule_group_lookup(const char *name) { odp_schedule_group_t group = ODP_SCHED_GROUP_INVALID; - sched_group_t *sched_group = &sched_global.sched_group; + sched_group_t *sched_group = &sched_global->sched_group; int i;
odp_ticketlock_lock(&sched_group->s.lock); @@ -676,7 +696,7 @@ static int schedule_group_join(odp_schedule_group_t group, const odp_thrmask_t *thrmask) { int thr; - sched_group_t *sched_group = &sched_global.sched_group; + sched_group_t *sched_group = &sched_global->sched_group;
if (group < 0 || group >= NUM_GROUP) return -1; @@ -708,7 +728,7 @@ static int schedule_group_leave(odp_schedule_group_t group, const odp_thrmask_t *thrmask) { int thr; - sched_group_t *sched_group = &sched_global.sched_group; + sched_group_t *sched_group = &sched_global->sched_group; odp_thrmask_t *all = &sched_group->s.group[GROUP_ALL].mask; odp_thrmask_t not;
@@ -742,7 +762,7 @@ static int schedule_group_leave(odp_schedule_group_t group, static int schedule_group_thrmask(odp_schedule_group_t group, odp_thrmask_t *thrmask) { - sched_group_t *sched_group = &sched_global.sched_group; + sched_group_t *sched_group = &sched_global->sched_group;
if (group < 0 || group >= NUM_GROUP) return -1; @@ -764,7 +784,7 @@ static int schedule_group_thrmask(odp_schedule_group_t group, static int schedule_group_info(odp_schedule_group_t group, odp_schedule_group_info_t *info) { - sched_group_t *sched_group = &sched_global.sched_group; + sched_group_t *sched_group = &sched_global->sched_group;
if (group < 0 || group >= NUM_GROUP) return -1;
commit 348ba720aa596ad2179de50f8be1486c0b2f2103 Author: Petri Savolainen petri.savolainen@linaro.org Date: Mon Feb 13 14:53:30 2017 +0200
linux-gen: packet: implement references as copy
Implement packet references API as packet copy. This is the simplest way to support the API, as other packet functions are not affected at all.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-and-tested-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index 024f694..1d2b506 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -2221,3 +2221,81 @@ uint64_t odp_packet_seg_to_u64(odp_packet_seg_t hdl) { return _odp_pri(hdl); } + +odp_packet_t odp_packet_ref_static(odp_packet_t pkt) +{ + odp_packet_t new; + + new = odp_packet_copy(pkt, odp_packet_pool(pkt)); + + return new; +} + +odp_packet_t odp_packet_ref(odp_packet_t pkt, uint32_t offset) +{ + odp_packet_t new; + int ret; + + new = odp_packet_copy(pkt, odp_packet_pool(pkt)); + + if (new == ODP_PACKET_INVALID) { + ODP_ERR("copy failed\n"); + return ODP_PACKET_INVALID; + } + + ret = odp_packet_trunc_head(&new, offset, NULL, NULL); + + if (ret < 0) { + ODP_ERR("trunk_head failed\n"); + odp_packet_free(new); + return ODP_PACKET_INVALID; + } + + return new; +} + +odp_packet_t odp_packet_ref_pkt(odp_packet_t pkt, uint32_t offset, + odp_packet_t hdr) +{ + odp_packet_t new; + int ret; + + new = odp_packet_copy(pkt, odp_packet_pool(pkt)); + + if (new == ODP_PACKET_INVALID) { + ODP_ERR("copy failed\n"); + return ODP_PACKET_INVALID; + } + + if (offset) { + ret = odp_packet_trunc_head(&new, offset, NULL, NULL); + + if (ret < 0) { + ODP_ERR("trunk_head failed\n"); + odp_packet_free(new); + return ODP_PACKET_INVALID; + } + } + + ret = odp_packet_concat(&hdr, new); + + if (ret < 0) { + ODP_ERR("concat failed\n"); + odp_packet_free(new); + return ODP_PACKET_INVALID; + } + + return hdr; +} + +int odp_packet_has_ref(odp_packet_t pkt) +{ + (void)pkt; + + return 0; +} + +uint32_t odp_packet_unshared_len(odp_packet_t pkt) +{ + return odp_packet_len(pkt); +}
commit f4d24e9b3c8fd6fa5f2724e652b45d13ddae1378 Author: Petri Savolainen petri.savolainen@linaro.org Date: Mon Feb 13 14:53:28 2017 +0200
validation: packet: remove non compatible tests
Tests for bad inputs are not compatible to the spec. Out-of-range values cause undefined results and must not be tested in validation suite.
Remove reference checks that do not comply anymore to the new odp_packet_has_ref() specification.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-and-tested-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/test/common_plat/validation/api/packet/packet.c b/test/common_plat/validation/api/packet/packet.c index f64c599..900c426 100644 --- a/test/common_plat/validation/api/packet/packet.c +++ b/test/common_plat/validation/api/packet/packet.c @@ -1877,46 +1877,70 @@ void packet_test_extend_ref(void) /* Verify ref lengths */ CU_ASSERT(ref != ODP_PACKET_INVALID); CU_ASSERT(odp_packet_len(ref) == max_len - 200); - CU_ASSERT(odp_packet_unshared_len(ref) == 0); + if (odp_packet_has_ref(ref) == 1) { + CU_ASSERT(odp_packet_unshared_len(ref) == 0);
- /* And ref's affect on max_pkt */ - CU_ASSERT(odp_packet_has_ref(max_pkt) == 1); - CU_ASSERT(odp_packet_unshared_len(max_pkt) == 100); + /* And ref's affect on max_pkt */ + CU_ASSERT(odp_packet_has_ref(max_pkt) == 1); + CU_ASSERT(odp_packet_unshared_len(max_pkt) == 100); + } else { + CU_ASSERT(odp_packet_unshared_len(ref) == odp_packet_len(ref)); + CU_ASSERT(odp_packet_unshared_len(max_pkt) == + odp_packet_len(max_pkt)); + }
/* Now extend max_pkt and verify effect */ CU_ASSERT(odp_packet_extend_head(&max_pkt, 10, NULL, NULL) >= 0); CU_ASSERT(odp_packet_len(max_pkt) == max_len - 90); - CU_ASSERT(odp_packet_unshared_len(max_pkt) == 110); - CU_ASSERT(odp_packet_has_ref(max_pkt) == 1); + + if (odp_packet_has_ref(max_pkt) == 1) { + /* CU_ASSERT needs braces */ + CU_ASSERT(odp_packet_unshared_len(max_pkt) == 110); + }
/* Extend on max_pkt should not affect ref */ - CU_ASSERT(odp_packet_has_ref(ref) == 1); CU_ASSERT(odp_packet_len(ref) == max_len - 200); - CU_ASSERT(odp_packet_unshared_len(ref) == 0); + + if (odp_packet_has_ref(ref) == 1) { + /* CU_ASSERT needs braces */ + CU_ASSERT(odp_packet_unshared_len(ref) == 0); + }
/* Now extend ref and verify effect*/ CU_ASSERT(odp_packet_extend_head(&ref, 20, NULL, NULL) >= 0); CU_ASSERT(odp_packet_len(ref) == max_len - 180); - CU_ASSERT(odp_packet_unshared_len(ref) == 20); + + if (odp_packet_has_ref(ref) == 1) { + /* CU_ASSERT needs braces */ + CU_ASSERT(odp_packet_unshared_len(ref) == 20); + }
/* Extend on ref should not affect max_pkt */ CU_ASSERT(odp_packet_len(max_pkt) == max_len - 90); - CU_ASSERT(odp_packet_unshared_len(max_pkt) == 110); - CU_ASSERT(odp_packet_has_ref(max_pkt) == 1); + + if (odp_packet_has_ref(max_pkt) == 1) { + /* CU_ASSERT needs braces */ + CU_ASSERT(odp_packet_unshared_len(max_pkt) == 110); + }
/* Trunc max_pkt of all unshared len */ - CU_ASSERT(odp_packet_trunc_head(&max_pkt, - odp_packet_unshared_len(max_pkt), - NULL, NULL) >= 0); + CU_ASSERT(odp_packet_trunc_head(&max_pkt, 110, NULL, NULL) >= 0);
/* Verify effect on max_pkt */ CU_ASSERT(odp_packet_len(max_pkt) == max_len - 200); - CU_ASSERT(odp_packet_unshared_len(max_pkt) == 0); - CU_ASSERT(odp_packet_has_ref(max_pkt) == 1); + + if (odp_packet_has_ref(max_pkt) == 1) { + /* CU_ASSERT needs braces */ + CU_ASSERT(odp_packet_unshared_len(max_pkt) == 0); + }
/* Verify that ref is unchanged */ CU_ASSERT(odp_packet_len(ref) == max_len - 180); - CU_ASSERT(odp_packet_unshared_len(ref) == 20); + + if (odp_packet_has_ref(ref) == 1) { + /* CU_ASSERT needs braces */ + CU_ASSERT(odp_packet_unshared_len(ref) == 20); + }
/* Free ref and verify that max_pkt is back to being unreferenced */ odp_packet_free(ref); @@ -2089,37 +2113,42 @@ void packet_test_ref(void) odp_packet_unshared_len(hdr_pkt[i])); }
- /* Attempt an invalid ref */ - refhdr_pkt[0] = odp_packet_ref_pkt(base_pkt, pkt_len, hdr_pkt[0]); - CU_ASSERT(refhdr_pkt[0] == ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_ref(hdr_pkt[0]) == 0); - CU_ASSERT(odp_packet_has_ref(base_pkt) == 0); - - /* We can't ref to ourselves */ - refhdr_pkt[0] = odp_packet_ref_pkt(hdr_pkt[0], 0, hdr_pkt[0]); - CU_ASSERT(refhdr_pkt[0] == ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_ref(hdr_pkt[0]) == 0); - - /* Now create a couple of valid refs */ + /* Create a couple of refs */ refhdr_pkt[0] = odp_packet_ref_pkt(base_pkt, offset[0], hdr_pkt[0]); refhdr_pkt[1] = odp_packet_ref_pkt(base_pkt, offset[1], hdr_pkt[1]);
CU_ASSERT(refhdr_pkt[0] != ODP_PACKET_INVALID); CU_ASSERT(refhdr_pkt[1] != ODP_PACKET_INVALID);
- CU_ASSERT(odp_packet_has_ref(refhdr_pkt[0]) == 1); - CU_ASSERT(odp_packet_has_ref(refhdr_pkt[1]) == 1); - CU_ASSERT(odp_packet_has_ref(base_pkt) == 1); + /* If base packet has now references, ref packet should be also + * references. */ + if (odp_packet_has_ref(base_pkt) == 1) { + CU_ASSERT(odp_packet_has_ref(refhdr_pkt[0]) == 1); + CU_ASSERT(odp_packet_has_ref(refhdr_pkt[1]) == 1);
- /* Verify ref lengths and contents */ - CU_ASSERT(odp_packet_unshared_len(base_pkt) == 0); + CU_ASSERT(odp_packet_unshared_len(base_pkt) == 0); + } else { + CU_ASSERT(odp_packet_unshared_len(base_pkt) == pkt_len); + }
CU_ASSERT(odp_packet_len(refhdr_pkt[0]) == hdr_len[0] + pkt_len - offset[0]); - CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[0]) == hdr_len[0]); CU_ASSERT(odp_packet_len(refhdr_pkt[1]) == hdr_len[1] + pkt_len - offset[1]); - CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[1]) == hdr_len[1]); + + if (odp_packet_has_ref(refhdr_pkt[0]) == 1) { + CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[0]) == hdr_len[0]); + } else { + CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[0]) == + odp_packet_len(refhdr_pkt[0])); + } + + if (odp_packet_has_ref(refhdr_pkt[1]) == 1) { + CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[1]) == hdr_len[1]); + } else { + CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[1]) == + odp_packet_len(refhdr_pkt[1])); + }
packet_compare_offset(refhdr_pkt[0], hdr_len[0], base_pkt, offset[0], @@ -2137,23 +2166,16 @@ void packet_test_ref(void) refhdr_pkt[2] = odp_packet_ref_pkt(refhdr_pkt[0], 2, hdr_cpy); CU_ASSERT(refhdr_pkt[2] != ODP_PACKET_INVALID);
- if (refhdr_pkt[2] != ODP_PACKET_INVALID) { - CU_ASSERT(odp_packet_has_ref(base_pkt) == 1); - CU_ASSERT(odp_packet_has_ref(refhdr_pkt[2]) == 1); + if (odp_packet_has_ref(refhdr_pkt[2]) == 1) { CU_ASSERT(odp_packet_has_ref(refhdr_pkt[0]) == 1); CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[2]) == hdr_len[2]); CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[0]) == 2); - - /* Free the compound ref and verify we're back to simple ref */ - odp_packet_free(refhdr_pkt[2]); - CU_ASSERT(odp_packet_has_ref(base_pkt) == 1); - CU_ASSERT(odp_packet_has_ref(refhdr_pkt[0]) == 1); - CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[0]) == hdr_len[0]); }
/* Delete the refs */ odp_packet_free(refhdr_pkt[0]); odp_packet_free(refhdr_pkt[1]); + odp_packet_free(refhdr_pkt[2]);
/* Verify that base_pkt no longer has a ref */ CU_ASSERT(odp_packet_has_ref(base_pkt) == 0); @@ -2164,9 +2186,11 @@ void packet_test_ref(void)
CU_ASSERT(hdr_pkt[2] != ODP_PACKET_INVALID); CU_ASSERT(hdr_pkt[3] != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_ref(refhdr_pkt[2]) == 1); - CU_ASSERT(odp_packet_has_ref(refhdr_pkt[3]) == 1); - CU_ASSERT(odp_packet_has_ref(base_pkt) == 1); + + if (odp_packet_has_ref(base_pkt) == 1) { + CU_ASSERT(odp_packet_has_ref(refhdr_pkt[2]) == 1); + CU_ASSERT(odp_packet_has_ref(refhdr_pkt[3]) == 1); + }
CU_ASSERT(odp_packet_len(refhdr_pkt[2]) == odp_packet_len(refhdr_pkt[3])); @@ -2185,7 +2209,12 @@ void packet_test_ref(void) /* Create a static reference */ ref_pkt[0] = odp_packet_ref_static(base_pkt); CU_ASSERT(ref_pkt[0] != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_ref(base_pkt) == 1); + + if (odp_packet_has_ref(base_pkt) == 1) { + /* CU_ASSERT needs braces */ + CU_ASSERT(odp_packet_has_ref(ref_pkt[0]) == 1); + } + CU_ASSERT(odp_packet_len(ref_pkt[0]) == odp_packet_len(base_pkt)); packet_compare_offset(ref_pkt[0], 0, base_pkt, 0, odp_packet_len(base_pkt)); @@ -2194,33 +2223,38 @@ void packet_test_ref(void) odp_packet_free(ref_pkt[0]); CU_ASSERT(odp_packet_has_ref(base_pkt) == 0);
- /* Create an invalid basic reference */ - ref_pkt[0] = odp_packet_ref(segmented_base_pkt, segmented_pkt_len); - CU_ASSERT(ref_pkt[0] == ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_ref(segmented_base_pkt) == 0); - - /* Now create valid references */ + /* Create references */ ref_pkt[0] = odp_packet_ref(segmented_base_pkt, offset[0]); - CU_ASSERT(odp_packet_has_ref(ref_pkt[0]) == 1); - CU_ASSERT(odp_packet_has_ref(segmented_base_pkt) == 1); + if (odp_packet_has_ref(ref_pkt[0]) == 1) { + /* CU_ASSERT needs braces */ + CU_ASSERT(odp_packet_has_ref(segmented_base_pkt) == 1); + }
ref_pkt[1] = odp_packet_ref(segmented_base_pkt, offset[1]); - CU_ASSERT(odp_packet_has_ref(ref_pkt[1]) == 1); - CU_ASSERT(odp_packet_has_ref(segmented_base_pkt) == 1); + + if (odp_packet_has_ref(ref_pkt[1]) == 1) { + /* CU_ASSERT needs braces */ + CU_ASSERT(odp_packet_has_ref(segmented_base_pkt) == 1); + }
/* Verify reference lengths */ CU_ASSERT(odp_packet_len(ref_pkt[0]) == segmented_pkt_len - offset[0]); CU_ASSERT(odp_packet_len(ref_pkt[1]) == segmented_pkt_len - offset[1]); - CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == 0); - CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == 0); + + if (odp_packet_has_ref(ref_pkt[0]) == 1) { + /* CU_ASSERT needs braces */ + CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == 0); + } + + if (odp_packet_has_ref(ref_pkt[1]) == 1) { + /* CU_ASSERT needs braces */ + CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 0); + }
/* Free the base pkts -- references should still be valid */ odp_packet_free(base_pkt); odp_packet_free(segmented_base_pkt);
- CU_ASSERT(odp_packet_has_ref(ref_pkt[0]) == 1); - CU_ASSERT(odp_packet_has_ref(ref_pkt[1]) == 1); - packet_compare_offset(ref_pkt[0], 0, segmented_test_packet, offset[0], segmented_pkt_len - offset[0]); @@ -2233,20 +2267,35 @@ void packet_test_ref(void) hr[1] = odp_packet_headroom(ref_pkt[1]);
CU_ASSERT(odp_packet_push_head(ref_pkt[0], hr[0]) != NULL); - CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == hr[0]); + + if (odp_packet_has_ref(ref_pkt[0]) == 1) { + /* CU_ASSERT needs braces */ + CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == hr[0]); + } + CU_ASSERT(odp_packet_len(ref_pkt[0]) == hr[0] + segmented_pkt_len - offset[0]);
CU_ASSERT(odp_packet_pull_head(ref_pkt[0], hr[0] / 2) != NULL); - CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == hr[0] - (hr[0] / 2)); + + if (odp_packet_has_ref(ref_pkt[0]) == 1) { + CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == + hr[0] - (hr[0] / 2)); + }
if (hr[1] > 0) { CU_ASSERT(odp_packet_push_head(ref_pkt[1], 1) != NULL); - CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 1); + if (odp_packet_has_ref(ref_pkt[1]) == 1) { + /* CU_ASSERT needs braces */ + CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 1); + } CU_ASSERT(odp_packet_len(ref_pkt[1]) == 1 + segmented_pkt_len - offset[1]); CU_ASSERT(odp_packet_pull_head(ref_pkt[1], 1) != NULL); - CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 0); + if (odp_packet_has_ref(ref_pkt[1]) == 1) { + /* CU_ASSERT needs braces */ + CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 0); + } CU_ASSERT(odp_packet_len(ref_pkt[1]) == segmented_pkt_len - offset[1]); } @@ -2261,36 +2310,68 @@ void packet_test_ref(void) CU_ASSERT_FATAL(ref_pkt[1] != ODP_PACKET_INVALID); ref_len[1] = odp_packet_len(ref_pkt[1]); CU_ASSERT(ref_len[1] == odp_packet_len(base_pkt) - offset[1]); - CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 0); + + if (odp_packet_has_ref(ref_pkt[1]) == 1) { + /* CU_ASSERT needs braces */ + CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 0); + }
CU_ASSERT(odp_packet_push_head(base_pkt, base_hr / 2) != NULL); - CU_ASSERT(odp_packet_unshared_len(base_pkt) == base_hr / 2 + offset[1]); + + if (odp_packet_has_ref(base_pkt) == 1) { + CU_ASSERT(odp_packet_unshared_len(base_pkt) == + base_hr / 2 + offset[1]); + } CU_ASSERT(odp_packet_len(ref_pkt[1]) == ref_len[1]); - CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 0); + if (odp_packet_has_ref(ref_pkt[1]) == 1) { + /* CU_ASSERT needs braces */ + CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 0); + }
ref_pkt[0] = odp_packet_ref(base_pkt, offset[0]); CU_ASSERT_FATAL(ref_pkt[0] != ODP_PACKET_INVALID); ref_len[0] = odp_packet_len(ref_pkt[0]); CU_ASSERT(ref_len[0] = odp_packet_len(base_pkt) - offset[0]); - CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == 0); + if (odp_packet_has_ref(ref_pkt[0]) == 1) { + /* CU_ASSERT needs braces */ + CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == 0); + }
CU_ASSERT(odp_packet_push_head(base_pkt, base_hr - base_hr / 2) != NULL); - CU_ASSERT(odp_packet_unshared_len(base_pkt) == - base_hr - base_hr / 2 + offset[0]); + if (odp_packet_has_ref(base_pkt) == 1) { + CU_ASSERT(odp_packet_unshared_len(base_pkt) == + base_hr - base_hr / 2 + offset[0]); + } CU_ASSERT(odp_packet_len(ref_pkt[1]) == ref_len[1]); CU_ASSERT(odp_packet_len(ref_pkt[0]) == ref_len[0]); - CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 0); - CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == 0); + + if (odp_packet_has_ref(ref_pkt[1]) == 1) { + /* CU_ASSERT needs braces */ + CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 0); + } + if (odp_packet_has_ref(ref_pkt[0]) == 1) { + /* CU_ASSERT needs braces */ + CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == 0); + }
hr[0] = odp_packet_headroom(ref_pkt[0]); hr[1] = odp_packet_headroom(ref_pkt[1]); CU_ASSERT(odp_packet_push_head(ref_pkt[0], hr[0]) != NULL); CU_ASSERT(odp_packet_push_head(ref_pkt[1], hr[1]) != NULL); - CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == hr[0]); - CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == hr[1]); - CU_ASSERT(odp_packet_unshared_len(base_pkt) == - base_hr - base_hr / 2 + offset[0]); + if (odp_packet_has_ref(ref_pkt[0]) == 1) { + /* CU_ASSERT needs braces */ + CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == hr[0]); + } + if (odp_packet_has_ref(ref_pkt[1]) == 1) { + /* CU_ASSERT needs braces */ + CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == hr[1]); + } + if (odp_packet_has_ref(base_pkt) == 1) { + /* CU_ASSERT needs braces */ + CU_ASSERT(odp_packet_unshared_len(base_pkt) == + base_hr - base_hr / 2 + offset[0]); + }
odp_packet_free(base_pkt); odp_packet_free(ref_pkt[0]);
commit 4b6d85a80fb0a190cde95944e2cf62886447df93 Author: Bill Fischofer bill.fischofer@linaro.org Date: Tue Jan 10 20:33:57 2017 -0600
validation: packet: add packet reference tests
Add validation tests for the new packet reference APIs: - odp_packet_ref_static() - odp_packet_ref() - odp_packet_ref_pkt() - odp_packet_has_ref() - odp_packet_unshared_len()
Signed-off-by: Bill Fischofer bill.fischofer@linaro.org Reviewed-by: Balasubramanian Manoharan bala.manoharan@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/test/common_plat/validation/api/packet/packet.c b/test/common_plat/validation/api/packet/packet.c index e3d28f6..f64c599 100644 --- a/test/common_plat/validation/api/packet/packet.c +++ b/test/common_plat/validation/api/packet/packet.c @@ -245,6 +245,7 @@ void packet_test_alloc_free(void) params.pkt.num = 1;
pool = odp_pool_create("packet_pool_alloc", ¶ms); + CU_ASSERT_FATAL(pool != ODP_POOL_INVALID);
/* Allocate the only buffer from the pool */ packet = odp_packet_alloc(pool, packet_len); @@ -1447,7 +1448,7 @@ void packet_test_concat_extend_trunc(void) param.pkt.num = 100;
pool = odp_pool_create("packet_pool_concat", ¶m); - CU_ASSERT(packet_pool != ODP_POOL_INVALID); + CU_ASSERT_FATAL(packet_pool != ODP_POOL_INVALID);
pkt = odp_packet_alloc(pool, alloc_len); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); @@ -1466,6 +1467,7 @@ void packet_test_concat_extend_trunc(void)
CU_ASSERT(odp_packet_len(pkt) == (cur_len + alloc_len)); cur_len = odp_packet_len(pkt); + CU_ASSERT(cur_len == odp_packet_unshared_len(pkt)); }
ret = odp_packet_extend_tail(&pkt, ext_len, NULL, NULL); @@ -1473,12 +1475,14 @@ void packet_test_concat_extend_trunc(void)
CU_ASSERT(odp_packet_len(pkt) == (cur_len + ext_len)); cur_len = odp_packet_len(pkt); + CU_ASSERT(cur_len == odp_packet_unshared_len(pkt));
ret = odp_packet_extend_head(&pkt, ext_len, NULL, NULL); CU_ASSERT(ret >= 0);
CU_ASSERT(odp_packet_len(pkt) == (cur_len + ext_len)); cur_len = odp_packet_len(pkt); + CU_ASSERT(cur_len == odp_packet_unshared_len(pkt));
pkt2 = odp_packet_alloc(pool, alloc_len); CU_ASSERT_FATAL(pkt2 != ODP_PACKET_INVALID); @@ -1491,18 +1495,21 @@ void packet_test_concat_extend_trunc(void)
CU_ASSERT(odp_packet_len(pkt) == (cur_len + alloc_len)); cur_len = odp_packet_len(pkt); + CU_ASSERT(cur_len == odp_packet_unshared_len(pkt));
ret = odp_packet_trunc_head(&pkt, trunc_len, NULL, NULL); CU_ASSERT(ret >= 0);
CU_ASSERT(odp_packet_len(pkt) == (cur_len - trunc_len)); cur_len = odp_packet_len(pkt); + CU_ASSERT(cur_len == odp_packet_unshared_len(pkt));
ret = odp_packet_trunc_tail(&pkt, trunc_len, NULL, NULL); CU_ASSERT(ret >= 0);
CU_ASSERT(odp_packet_len(pkt) == (cur_len - trunc_len)); cur_len = odp_packet_len(pkt); + CU_ASSERT(cur_len == odp_packet_unshared_len(pkt));
odp_packet_free(pkt);
@@ -1534,7 +1541,7 @@ void packet_test_extend_small(void) param.pkt.num = 100;
pool = odp_pool_create("packet_pool_extend", ¶m); - CU_ASSERT(packet_pool != ODP_POOL_INVALID); + CU_ASSERT_FATAL(packet_pool != ODP_POOL_INVALID);
for (round = 0; round < 2; round++) { pkt = odp_packet_alloc(pool, 1); @@ -1570,6 +1577,7 @@ void packet_test_extend_small(void) }
CU_ASSERT(odp_packet_len(pkt) == len); + CU_ASSERT(odp_packet_unshared_len(pkt) == len);
len = odp_packet_len(pkt);
@@ -1628,7 +1636,7 @@ void packet_test_extend_large(void) param.pkt.num = 100;
pool = odp_pool_create("packet_pool_extend", ¶m); - CU_ASSERT(packet_pool != ODP_POOL_INVALID); + CU_ASSERT_FATAL(packet_pool != ODP_POOL_INVALID);
for (round = 0; round < 2 * num_div; round++) { ext_len = len / div; @@ -1747,7 +1755,7 @@ void packet_test_extend_mix(void) param.pkt.num = 100;
pool = odp_pool_create("packet_pool_extend", ¶m); - CU_ASSERT(packet_pool != ODP_POOL_INVALID); + CU_ASSERT_FATAL(packet_pool != ODP_POOL_INVALID);
for (round = 0; round < 2; round++) { small_count = 30; @@ -1835,6 +1843,90 @@ void packet_test_extend_mix(void) CU_ASSERT(odp_pool_destroy(pool) == 0); }
+void packet_test_extend_ref(void) +{ + odp_packet_t max_pkt, ref; + uint32_t hr, tr, max_len; + + max_pkt = odp_packet_copy(segmented_test_packet, + odp_packet_pool(segmented_test_packet)); + CU_ASSERT_FATAL(max_pkt != ODP_PACKET_INVALID); + max_len = odp_packet_len(max_pkt); + + /* Maximize the max pkt */ + hr = odp_packet_headroom(max_pkt); + tr = odp_packet_tailroom(max_pkt); + odp_packet_push_head(max_pkt, hr); + odp_packet_push_tail(max_pkt, tr); + + /* Max packet should not be extendable at either end */ + CU_ASSERT(odp_packet_extend_tail(&max_pkt, 1, NULL, NULL) < 0); + CU_ASSERT(odp_packet_extend_head(&max_pkt, 1, NULL, NULL) < 0); + + /* See if we can trunc and extend anyway */ + CU_ASSERT(odp_packet_trunc_tail(&max_pkt, hr + tr + 1, + NULL, NULL) >= 0); + CU_ASSERT(odp_packet_extend_head(&max_pkt, 1, NULL, NULL) >= 0); + CU_ASSERT(odp_packet_len(max_pkt) == max_len); + CU_ASSERT(odp_packet_unshared_len(max_pkt) == max_len); + + /* Now try with a reference in place */ + CU_ASSERT(odp_packet_trunc_tail(&max_pkt, 100, NULL, NULL) >= 0); + ref = odp_packet_ref(max_pkt, 100); + + /* Verify ref lengths */ + CU_ASSERT(ref != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_len(ref) == max_len - 200); + CU_ASSERT(odp_packet_unshared_len(ref) == 0); + + /* And ref's affect on max_pkt */ + CU_ASSERT(odp_packet_has_ref(max_pkt) == 1); + CU_ASSERT(odp_packet_unshared_len(max_pkt) == 100); + + /* Now extend max_pkt and verify effect */ + CU_ASSERT(odp_packet_extend_head(&max_pkt, 10, NULL, NULL) >= 0); + CU_ASSERT(odp_packet_len(max_pkt) == max_len - 90); + CU_ASSERT(odp_packet_unshared_len(max_pkt) == 110); + CU_ASSERT(odp_packet_has_ref(max_pkt) == 1); + + /* Extend on max_pkt should not affect ref */ + CU_ASSERT(odp_packet_has_ref(ref) == 1); + CU_ASSERT(odp_packet_len(ref) == max_len - 200); + CU_ASSERT(odp_packet_unshared_len(ref) == 0); + + /* Now extend ref and verify effect*/ + CU_ASSERT(odp_packet_extend_head(&ref, 20, NULL, NULL) >= 0); + CU_ASSERT(odp_packet_len(ref) == max_len - 180); + CU_ASSERT(odp_packet_unshared_len(ref) == 20); + + /* Extend on ref should not affect max_pkt */ + CU_ASSERT(odp_packet_len(max_pkt) == max_len - 90); + CU_ASSERT(odp_packet_unshared_len(max_pkt) == 110); + CU_ASSERT(odp_packet_has_ref(max_pkt) == 1); + + /* Trunc max_pkt of all unshared len */ + CU_ASSERT(odp_packet_trunc_head(&max_pkt, + odp_packet_unshared_len(max_pkt), + NULL, NULL) >= 0); + + /* Verify effect on max_pkt */ + CU_ASSERT(odp_packet_len(max_pkt) == max_len - 200); + CU_ASSERT(odp_packet_unshared_len(max_pkt) == 0); + CU_ASSERT(odp_packet_has_ref(max_pkt) == 1); + + /* Verify that ref is unchanged */ + CU_ASSERT(odp_packet_len(ref) == max_len - 180); + CU_ASSERT(odp_packet_unshared_len(ref) == 20); + + /* Free ref and verify that max_pkt is back to being unreferenced */ + odp_packet_free(ref); + CU_ASSERT(odp_packet_has_ref(max_pkt) == 0); + CU_ASSERT(odp_packet_len(max_pkt) == max_len - 200); + CU_ASSERT(odp_packet_unshared_len(max_pkt) == max_len - 200); + + odp_packet_free(max_pkt); +} + void packet_test_align(void) { odp_packet_t pkt; @@ -1939,6 +2031,272 @@ void packet_test_offset(void) CU_ASSERT_PTR_NOT_NULL(ptr); }
+void packet_test_ref(void) +{ + odp_packet_t base_pkt, segmented_base_pkt, hdr_pkt[4], + ref_pkt[4], refhdr_pkt[4], hdr_cpy; + uint32_t pkt_len, segmented_pkt_len, hdr_len[4], offset[4], hr[4], + base_hr, ref_len[4]; + int i; + + base_pkt = odp_packet_copy(test_packet, odp_packet_pool(test_packet)); + base_hr = odp_packet_headroom(base_pkt); + pkt_len = odp_packet_len(test_packet); + CU_ASSERT_FATAL(base_pkt != ODP_PACKET_INVALID); + + segmented_base_pkt = + odp_packet_copy(segmented_test_packet, + odp_packet_pool(segmented_test_packet)); + segmented_pkt_len = odp_packet_len(segmented_test_packet); + CU_ASSERT_FATAL(segmented_base_pkt != ODP_PACKET_INVALID); + + CU_ASSERT(odp_packet_has_ref(base_pkt) == 0); + + hdr_pkt[0] = + odp_packet_copy_part(segmented_test_packet, 0, + odp_packet_len(segmented_test_packet) / 4, + odp_packet_pool(segmented_test_packet)); + CU_ASSERT_FATAL(hdr_pkt[0] != ODP_PACKET_INVALID); + hdr_len[0] = odp_packet_len(hdr_pkt[0]); + offset[0] = 0; + + hdr_pkt[1] = + odp_packet_copy_part(segmented_test_packet, 10, + odp_packet_len(segmented_test_packet) / 8, + odp_packet_pool(segmented_test_packet)); + CU_ASSERT_FATAL(hdr_pkt[1] != ODP_PACKET_INVALID); + hdr_len[1] = odp_packet_len(hdr_pkt[1]); + offset[1] = 5; + + hdr_pkt[2] = odp_packet_copy_part(test_packet, 0, + odp_packet_len(test_packet) / 4, + odp_packet_pool(test_packet)); + CU_ASSERT_FATAL(hdr_pkt[2] != ODP_PACKET_INVALID); + hdr_len[2] = odp_packet_len(hdr_pkt[2]); + offset[2] = 64; + + hdr_pkt[3] = odp_packet_copy_part(test_packet, 0, + odp_packet_len(test_packet) / 4, + odp_packet_pool(test_packet)); + CU_ASSERT_FATAL(hdr_pkt[3] != ODP_PACKET_INVALID); + hdr_len[3] = odp_packet_len(hdr_pkt[3]); + offset[3] = 64; + + /* Nothing is a ref or has a ref before we start */ + for (i = 0; i < 4; i++) { + CU_ASSERT(odp_packet_has_ref(hdr_pkt[i]) == 0); + CU_ASSERT(odp_packet_len(hdr_pkt[i]) == + odp_packet_unshared_len(hdr_pkt[i])); + } + + /* Attempt an invalid ref */ + refhdr_pkt[0] = odp_packet_ref_pkt(base_pkt, pkt_len, hdr_pkt[0]); + CU_ASSERT(refhdr_pkt[0] == ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_ref(hdr_pkt[0]) == 0); + CU_ASSERT(odp_packet_has_ref(base_pkt) == 0); + + /* We can't ref to ourselves */ + refhdr_pkt[0] = odp_packet_ref_pkt(hdr_pkt[0], 0, hdr_pkt[0]); + CU_ASSERT(refhdr_pkt[0] == ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_ref(hdr_pkt[0]) == 0); + + /* Now create a couple of valid refs */ + refhdr_pkt[0] = odp_packet_ref_pkt(base_pkt, offset[0], hdr_pkt[0]); + refhdr_pkt[1] = odp_packet_ref_pkt(base_pkt, offset[1], hdr_pkt[1]); + + CU_ASSERT(refhdr_pkt[0] != ODP_PACKET_INVALID); + CU_ASSERT(refhdr_pkt[1] != ODP_PACKET_INVALID); + + CU_ASSERT(odp_packet_has_ref(refhdr_pkt[0]) == 1); + CU_ASSERT(odp_packet_has_ref(refhdr_pkt[1]) == 1); + CU_ASSERT(odp_packet_has_ref(base_pkt) == 1); + + /* Verify ref lengths and contents */ + CU_ASSERT(odp_packet_unshared_len(base_pkt) == 0); + + CU_ASSERT(odp_packet_len(refhdr_pkt[0]) == + hdr_len[0] + pkt_len - offset[0]); + CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[0]) == hdr_len[0]); + CU_ASSERT(odp_packet_len(refhdr_pkt[1]) == + hdr_len[1] + pkt_len - offset[1]); + CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[1]) == hdr_len[1]); + + packet_compare_offset(refhdr_pkt[0], hdr_len[0], + base_pkt, offset[0], + pkt_len - offset[0]); + + packet_compare_offset(refhdr_pkt[1], hdr_len[1], + base_pkt, offset[1], + pkt_len - offset[1]); + + /* See if compound references are supported and if so that they + * operate properly */ + hdr_cpy = odp_packet_copy(hdr_pkt[2], odp_packet_pool(hdr_pkt[2])); + CU_ASSERT_FATAL(hdr_cpy != ODP_PACKET_INVALID); + + refhdr_pkt[2] = odp_packet_ref_pkt(refhdr_pkt[0], 2, hdr_cpy); + CU_ASSERT(refhdr_pkt[2] != ODP_PACKET_INVALID); + + if (refhdr_pkt[2] != ODP_PACKET_INVALID) { + CU_ASSERT(odp_packet_has_ref(base_pkt) == 1); + CU_ASSERT(odp_packet_has_ref(refhdr_pkt[2]) == 1); + CU_ASSERT(odp_packet_has_ref(refhdr_pkt[0]) == 1); + CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[2]) == hdr_len[2]); + CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[0]) == 2); + + /* Free the compound ref and verify we're back to simple ref */ + odp_packet_free(refhdr_pkt[2]); + CU_ASSERT(odp_packet_has_ref(base_pkt) == 1); + CU_ASSERT(odp_packet_has_ref(refhdr_pkt[0]) == 1); + CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[0]) == hdr_len[0]); + } + + /* Delete the refs */ + odp_packet_free(refhdr_pkt[0]); + odp_packet_free(refhdr_pkt[1]); + + /* Verify that base_pkt no longer has a ref */ + CU_ASSERT(odp_packet_has_ref(base_pkt) == 0); + + /* Now create a two more shared refs */ + refhdr_pkt[2] = odp_packet_ref_pkt(base_pkt, offset[2], hdr_pkt[2]); + refhdr_pkt[3] = odp_packet_ref_pkt(base_pkt, offset[3], hdr_pkt[3]); + + CU_ASSERT(hdr_pkt[2] != ODP_PACKET_INVALID); + CU_ASSERT(hdr_pkt[3] != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_ref(refhdr_pkt[2]) == 1); + CU_ASSERT(odp_packet_has_ref(refhdr_pkt[3]) == 1); + CU_ASSERT(odp_packet_has_ref(base_pkt) == 1); + + CU_ASSERT(odp_packet_len(refhdr_pkt[2]) == + odp_packet_len(refhdr_pkt[3])); + + packet_compare_offset(refhdr_pkt[2], 0, + refhdr_pkt[3], 0, + odp_packet_len(hdr_pkt[2])); + + /* Delete the headers */ + odp_packet_free(refhdr_pkt[2]); + odp_packet_free(refhdr_pkt[3]); + + /* Verify that base_pkt is no longer ref'd */ + CU_ASSERT(odp_packet_has_ref(base_pkt) == 0); + + /* Create a static reference */ + ref_pkt[0] = odp_packet_ref_static(base_pkt); + CU_ASSERT(ref_pkt[0] != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_ref(base_pkt) == 1); + CU_ASSERT(odp_packet_len(ref_pkt[0]) == odp_packet_len(base_pkt)); + packet_compare_offset(ref_pkt[0], 0, base_pkt, 0, + odp_packet_len(base_pkt)); + + /* Now delete it */ + odp_packet_free(ref_pkt[0]); + CU_ASSERT(odp_packet_has_ref(base_pkt) == 0); + + /* Create an invalid basic reference */ + ref_pkt[0] = odp_packet_ref(segmented_base_pkt, segmented_pkt_len); + CU_ASSERT(ref_pkt[0] == ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_ref(segmented_base_pkt) == 0); + + /* Now create valid references */ + ref_pkt[0] = odp_packet_ref(segmented_base_pkt, offset[0]); + CU_ASSERT(odp_packet_has_ref(ref_pkt[0]) == 1); + CU_ASSERT(odp_packet_has_ref(segmented_base_pkt) == 1); + + ref_pkt[1] = odp_packet_ref(segmented_base_pkt, offset[1]); + CU_ASSERT(odp_packet_has_ref(ref_pkt[1]) == 1); + CU_ASSERT(odp_packet_has_ref(segmented_base_pkt) == 1); + + /* Verify reference lengths */ + CU_ASSERT(odp_packet_len(ref_pkt[0]) == segmented_pkt_len - offset[0]); + CU_ASSERT(odp_packet_len(ref_pkt[1]) == segmented_pkt_len - offset[1]); + CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == 0); + CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == 0); + + /* Free the base pkts -- references should still be valid */ + odp_packet_free(base_pkt); + odp_packet_free(segmented_base_pkt); + + CU_ASSERT(odp_packet_has_ref(ref_pkt[0]) == 1); + CU_ASSERT(odp_packet_has_ref(ref_pkt[1]) == 1); + + packet_compare_offset(ref_pkt[0], 0, + segmented_test_packet, offset[0], + segmented_pkt_len - offset[0]); + packet_compare_offset(ref_pkt[1], 0, + segmented_test_packet, offset[1], + segmented_pkt_len - offset[1]); + + /* Verify we can modify the refs */ + hr[0] = odp_packet_headroom(ref_pkt[0]); + hr[1] = odp_packet_headroom(ref_pkt[1]); + + CU_ASSERT(odp_packet_push_head(ref_pkt[0], hr[0]) != NULL); + CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == hr[0]); + CU_ASSERT(odp_packet_len(ref_pkt[0]) == + hr[0] + segmented_pkt_len - offset[0]); + + CU_ASSERT(odp_packet_pull_head(ref_pkt[0], hr[0] / 2) != NULL); + CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == hr[0] - (hr[0] / 2)); + + if (hr[1] > 0) { + CU_ASSERT(odp_packet_push_head(ref_pkt[1], 1) != NULL); + CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 1); + CU_ASSERT(odp_packet_len(ref_pkt[1]) == + 1 + segmented_pkt_len - offset[1]); + CU_ASSERT(odp_packet_pull_head(ref_pkt[1], 1) != NULL); + CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 0); + CU_ASSERT(odp_packet_len(ref_pkt[1]) == + segmented_pkt_len - offset[1]); + } + + odp_packet_free(ref_pkt[0]); + odp_packet_free(ref_pkt[1]); + + /* Verify we can modify base packet after reference is created */ + base_pkt = odp_packet_copy(test_packet, odp_packet_pool(test_packet)); + + ref_pkt[1] = odp_packet_ref(base_pkt, offset[1]); + CU_ASSERT_FATAL(ref_pkt[1] != ODP_PACKET_INVALID); + ref_len[1] = odp_packet_len(ref_pkt[1]); + CU_ASSERT(ref_len[1] == odp_packet_len(base_pkt) - offset[1]); + CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 0); + + CU_ASSERT(odp_packet_push_head(base_pkt, base_hr / 2) != NULL); + CU_ASSERT(odp_packet_unshared_len(base_pkt) == base_hr / 2 + offset[1]); + CU_ASSERT(odp_packet_len(ref_pkt[1]) == ref_len[1]); + CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 0); + + ref_pkt[0] = odp_packet_ref(base_pkt, offset[0]); + CU_ASSERT_FATAL(ref_pkt[0] != ODP_PACKET_INVALID); + ref_len[0] = odp_packet_len(ref_pkt[0]); + CU_ASSERT(ref_len[0] = odp_packet_len(base_pkt) - offset[0]); + CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == 0); + + CU_ASSERT(odp_packet_push_head(base_pkt, + base_hr - base_hr / 2) != NULL); + CU_ASSERT(odp_packet_unshared_len(base_pkt) == + base_hr - base_hr / 2 + offset[0]); + CU_ASSERT(odp_packet_len(ref_pkt[1]) == ref_len[1]); + CU_ASSERT(odp_packet_len(ref_pkt[0]) == ref_len[0]); + CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 0); + CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == 0); + + hr[0] = odp_packet_headroom(ref_pkt[0]); + hr[1] = odp_packet_headroom(ref_pkt[1]); + CU_ASSERT(odp_packet_push_head(ref_pkt[0], hr[0]) != NULL); + CU_ASSERT(odp_packet_push_head(ref_pkt[1], hr[1]) != NULL); + CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == hr[0]); + CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == hr[1]); + CU_ASSERT(odp_packet_unshared_len(base_pkt) == + base_hr - base_hr / 2 + offset[0]); + + odp_packet_free(base_pkt); + odp_packet_free(ref_pkt[0]); + odp_packet_free(ref_pkt[1]); +} + odp_testinfo_t packet_suite[] = { ODP_TEST_INFO(packet_test_alloc_free), ODP_TEST_INFO(packet_test_alloc_free_multi), @@ -1965,8 +2323,10 @@ odp_testinfo_t packet_suite[] = { ODP_TEST_INFO(packet_test_extend_small), ODP_TEST_INFO(packet_test_extend_large), ODP_TEST_INFO(packet_test_extend_mix), + ODP_TEST_INFO(packet_test_extend_ref), ODP_TEST_INFO(packet_test_align), ODP_TEST_INFO(packet_test_offset), + ODP_TEST_INFO(packet_test_ref), ODP_TEST_INFO_NULL, };
diff --git a/test/common_plat/validation/api/packet/packet.h b/test/common_plat/validation/api/packet/packet.h index 9bc3d63..783b7a1 100644 --- a/test/common_plat/validation/api/packet/packet.h +++ b/test/common_plat/validation/api/packet/packet.h @@ -35,8 +35,10 @@ void packet_test_concat_extend_trunc(void); void packet_test_extend_small(void); void packet_test_extend_large(void); void packet_test_extend_mix(void); +void packet_test_extend_ref(void); void packet_test_align(void); void packet_test_offset(void); +void packet_test_ref(void);
/* test arrays: */ extern odp_testinfo_t packet_suite[];
commit f1502d11a771cf53a9e9ba189c949305cc3ba94e Author: Petri Savolainen petri.savolainen@linaro.org Date: Mon Feb 13 14:53:27 2017 +0200
api: packet: references may be implemented as copy
Some implementations may implement new references as packet copy. odp_packet_has_ref() will return 0 for copies, since those are unique packets.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-and-tested-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/packet.h b/include/odp/api/spec/packet.h index b6450c1..05ffd68 100644 --- a/include/odp/api/spec/packet.h +++ b/include/odp/api/spec/packet.h @@ -892,9 +892,6 @@ odp_packet_t odp_packet_ref_static(odp_packet_t pkt); * dynamic references must not be mixed. Results are undefined if these * restrictions are not observed. * - * odp_packet_unshared_len() may be used to determine the number of bytes - * starting at offset zero that are unique to a packet handle. - * * The packet handle 'pkt' may itself by a (dynamic) reference to a packet. * * If the caller does not intend to modify either the packet or the new @@ -952,8 +949,9 @@ odp_packet_t odp_packet_ref_pkt(odp_packet_t pkt, uint32_t offset, * When a packet has multiple references, packet data is divided into two * parts: unshared and shared. The unshared part always precedes the shared * part. This call returns number of bytes in the unshared part. When a - * packet has only a single reference, all packet data is unshared and - * unshared length equals the packet length (odp_packet_len()). + * packet has only a single reference (see odp_packet_has_ref()), all packet + * data is unshared and unshared length equals the packet length + * (odp_packet_len()). * * Application may modify only the unshared part, the rest of the packet data * must be treated as read only. @@ -967,8 +965,16 @@ uint32_t odp_packet_unshared_len(odp_packet_t pkt); /** * Test if packet has multiple references * - * A packet that has multiple references shares data and possibly metadata - * with other packets. Shared part must be treated as read only. + * A packet that has multiple references share data with other packets. In case + * of a static reference it also shares metadata. Shared parts must be treated + * as read only. + * + * New references are created with odp_packet_ref_static(), odp_packet_ref() and + * odp_packet_ref_pkt() calls. However, some of those calls may implement the + * new reference as a packet copy. If a copy is done, the new reference is + * actually a new, unique packet and this function returns '0' for it. + * When a real reference is created (instead of a copy), this function + * returns '1' for both packets (the original packet and the new reference). * * @param pkt Packet handle *
commit 5cd91a6e3bf76edc0045bc379dd18fa75f65ccd2 Author: Petri Savolainen petri.savolainen@nokia.com Date: Tue Jan 10 20:33:55 2017 -0600
api: packet: add support for packet references
Introduce new APIs that support efficient sharing of portions of packets: * odp_packet_ref_static() creates a new static reference for a packet * odp_packet_ref() creates a new dynamic reference to a packet * odp_packet_ref_pkt() creates a reference to a packet with a supplied header packet * odp_packet_has_ref() checks if a packet has multiple references to it * odp_packet_unshared_len() returns the unshared data length of a reference
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Signed-off-by: Bill Fischofer bill.fischofer@linaro.org Reviewed-by: Balasubramanian Manoharan bala.manoharan@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/packet.h b/include/odp/api/spec/packet.h index 4a86eba..b6450c1 100644 --- a/include/odp/api/spec/packet.h +++ b/include/odp/api/spec/packet.h @@ -795,7 +795,7 @@ uint32_t odp_packet_seg_data_len(odp_packet_t pkt, odp_packet_seg_t seg); * data pointers. Otherwise, all old pointers remain valid. * * The resulting packet is always allocated from the same pool as - * the destination packet. The source packet may have been allocate from + * the destination packet. The source packet may have been allocated from * any pool. * * On failure, both handles remain valid and packets are not modified. @@ -848,6 +848,137 @@ int odp_packet_split(odp_packet_t *pkt, uint32_t len, odp_packet_t *tail);
/* * + * References + * ******************************************************** + * + */ + +/** + * Create a static reference to a packet + * + * A static reference is used to obtain an additional handle for referring to + * the entire packet as it is. As long as a packet has multiple (static) + * references, any of the references (including 'pkt') must not be used to + * modify the packet in any way - both data and metadata must remain static. + * The packet may be modified again when there is a single reference left. + * Static and dynamic references must not be mixed. Results are undefined if + * these restrictions are not observed. + * + * While static references are inflexible they offer efficient way to do, + * e.g., packet retransmissions. Use odp_packet_ref() or odp_packet_ref_pkt() + * for more flexible, dynamic references. + * + * Packet is not modified on failure. + * + * @param pkt Handle of the packet for which a static reference is + * to be created. + * + * @return Static reference to the packet + * @retval ODP_PACKET_INVALID On failure + */ +odp_packet_t odp_packet_ref_static(odp_packet_t pkt); + +/** + * Create a reference to a packet + * + * Returns a new (dynamic) reference to a packet starting the shared part of + * the data at a specified byte offset. Metadata and data before the offset + * are not shared with other references of the packet. The rest of the data is + * shared and must be treated as read only. Initially the returned reference + * has metadata initialized to default values and does not contain unshared + * data. Packet (head) manipulation functions may be used normally to, e.g., + * add a unique header onto the shared payload. The shared part of the packet + * may be modified again when there is a single reference left. Static and + * dynamic references must not be mixed. Results are undefined if these + * restrictions are not observed. + * + * odp_packet_unshared_len() may be used to determine the number of bytes + * starting at offset zero that are unique to a packet handle. + * + * The packet handle 'pkt' may itself by a (dynamic) reference to a packet. + * + * If the caller does not intend to modify either the packet or the new + * reference to it, odp_packet_ref_static() may be used to create + * a static reference that is more optimized for that use case. + * + * Packet is not modified on failure. + * + * @param pkt Handle of the packet for which a reference is to be + * created. + * + * @param offset Byte offset in the packet at which the shared part is to + * begin. This must be in the range 0 ... odp_packet_len(pkt)-1. + * + * @return New reference to the packet + * @retval ODP_PACKET_INVALID On failure + */ +odp_packet_t odp_packet_ref(odp_packet_t pkt, uint32_t offset); + +/** + * Create a reference to a packet with a header packet + * + * This operation is otherwise identical to odp_packet_ref(), but it prepends + * a supplied 'hdr' packet as the head of the new reference. The resulting + * packet consists metadata and data of the 'hdr' packet, followed by the + * shared part of packet 'pkt'. + * + * The packet handle ('pkt') may itself by a (dynamic) reference to a packet, + * but the header packet handle ('hdr') must be unique. Both packets must be + * have been allocated from the same pool and the handles must not refer to + * the same packet. Results are undefined if these restrictions are not + * observed. + * + * Packets are not modified on failure. The header packet 'hdr' is consumed + * on success. + * + * @param pkt Handle of the packet for which a reference is to be + * created. + * + * @param offset Byte offset in 'pkt' at which the shared part is to + * begin. Must be in the range 0 ... odp_packet_len(pkt)-1. + * + * @param hdr Handle of the header packet to be prefixed onto the new + * reference. Must be a unique reference. + * + * @return New reference the reference packet + * @retval ODP_PACKET_INVALID On failure + */ +odp_packet_t odp_packet_ref_pkt(odp_packet_t pkt, uint32_t offset, + odp_packet_t hdr); + +/** + * Packet unshared data length + * + * When a packet has multiple references, packet data is divided into two + * parts: unshared and shared. The unshared part always precedes the shared + * part. This call returns number of bytes in the unshared part. When a + * packet has only a single reference, all packet data is unshared and + * unshared length equals the packet length (odp_packet_len()). + * + * Application may modify only the unshared part, the rest of the packet data + * must be treated as read only. + * + * @param pkt Packet handle + * + * @return Packet unshared data length + */ +uint32_t odp_packet_unshared_len(odp_packet_t pkt); + +/** + * Test if packet has multiple references + * + * A packet that has multiple references shares data and possibly metadata + * with other packets. Shared part must be treated as read only. + * + * @param pkt Packet handle + * + * @retval 0 This is the single reference to the packet + * @retval 1 Packet has multiple references + */ +int odp_packet_has_ref(odp_packet_t pkt); + +/* + * * Copy * ******************************************************** *
-----------------------------------------------------------------------
Summary of changes: include/odp/api/spec/packet.h | 139 +++++++- platform/linux-generic/odp_packet.c | 78 ++++ platform/linux-generic/odp_schedule_sp.c | 100 +++--- test/common_plat/validation/api/packet/packet.c | 449 +++++++++++++++++++++++- test/common_plat/validation/api/packet/packet.h | 2 + 5 files changed, 723 insertions(+), 45 deletions(-)
hooks/post-receive