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 ec84962de6f2b392bbde9e8ebc802781979b95dc (commit) via 6b07d871100f5eb92a14e8b5eec56a4bf014c60a (commit) via 5ea562d5d0c4f292ede6d366e205641b0db6c454 (commit) via 9fc7566c08ea131ea24c8f95e5ac92b1b45c1aa4 (commit) via 88339aef26f169fe01f06e158835b1d2f3617db7 (commit) via fffeaa22246f15a4b7c6c41d4bcfd7943c2b33cc (commit) via 02ab1ec8f2c3e9fd6934c296d68f22ba33620706 (commit) via 3f5429ed2383056b0a085b99db6d180c39afa85e (commit) from b3ef83fd050912b82dd2dcaa2063ef1e8c12ee4d (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 ec84962de6f2b392bbde9e8ebc802781979b95dc Author: Petri Savolainen petri.savolainen@nokia.com Date: Thu Dec 22 16:33:08 2016 +0200
linux-gen: config: increase max num of segments
Higher segment count enables optimizations (no data copy) on operations that modifying packet length.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com 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/include/odp_config_internal.h b/platform/linux-generic/include/odp_config_internal.h index e89a6a3..e7d84c9 100644 --- a/platform/linux-generic/include/odp_config_internal.h +++ b/platform/linux-generic/include/odp_config_internal.h @@ -75,7 +75,7 @@ extern "C" { /* * Maximum number of segments per packet */ -#define CONFIG_PACKET_MAX_SEGS 2 +#define CONFIG_PACKET_MAX_SEGS 6
/* * Maximum packet segment size including head- and tailrooms
commit 6b07d871100f5eb92a14e8b5eec56a4bf014c60a Author: Petri Savolainen petri.savolainen@nokia.com Date: Thu Dec 22 16:33:07 2016 +0200
validation: packet: add new concat and extend tests
Added new tests for better packet concat and extend test coverage. Both small and large data length are needed to create various segmentation scenarios.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com 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 25252a6..cf11c01 100644 --- a/test/common_plat/validation/api/packet/packet.c +++ b/test/common_plat/validation/api/packet/packet.c @@ -54,6 +54,38 @@ static void _packet_compare_data(odp_packet_t pkt1, odp_packet_t pkt2) } }
+static int fill_data_forward(odp_packet_t pkt, uint32_t offset, uint32_t len, + uint32_t *cur_data) +{ + uint8_t buf[len]; + uint32_t i, data; + + data = *cur_data; + + for (i = 0; i < len; i++) + buf[i] = data++; + + *cur_data = data; + + return odp_packet_copy_from_mem(pkt, offset, len, buf); +} + +static int fill_data_backward(odp_packet_t pkt, uint32_t offset, uint32_t len, + uint32_t *cur_data) +{ + uint8_t buf[len]; + uint32_t i, data; + + data = *cur_data; + + for (i = 0; i < len; i++) + buf[len - i - 1] = data++; + + *cur_data = data; + + return odp_packet_copy_from_mem(pkt, offset, len, buf); +} + int packet_suite_init(void) { odp_pool_param_t params; @@ -1289,6 +1321,459 @@ void packet_test_concatsplit(void) odp_packet_free(pkt); }
+void packet_test_concat_small(void) +{ + odp_pool_capability_t capa; + odp_pool_t pool; + odp_pool_param_t param; + odp_packet_t pkt, pkt2; + int ret; + uint8_t *data; + uint32_t i; + uint32_t len = 32000; + uint8_t buf[len]; + + CU_ASSERT_FATAL(odp_pool_capability(&capa) == 0); + + if (capa.pkt.max_len && capa.pkt.max_len < len) + len = capa.pkt.max_len; + + odp_pool_param_init(¶m); + + param.type = ODP_POOL_PACKET; + param.pkt.len = len; + param.pkt.num = 100; + + pool = odp_pool_create("packet_pool_concat", ¶m); + CU_ASSERT(packet_pool != ODP_POOL_INVALID); + + pkt = odp_packet_alloc(pool, 1); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + + data = odp_packet_data(pkt); + *data = 0; + + for (i = 0; i < len - 1; i++) { + pkt2 = odp_packet_alloc(pool, 1); + CU_ASSERT_FATAL(pkt2 != ODP_PACKET_INVALID); + + data = odp_packet_data(pkt2); + *data = i + 1; + + ret = odp_packet_concat(&pkt, pkt2); + CU_ASSERT(ret >= 0); + + if (ret < 0) { + odp_packet_free(pkt2); + break; + } + } + + CU_ASSERT(odp_packet_len(pkt) == len); + + len = odp_packet_len(pkt); + + memset(buf, 0, len); + CU_ASSERT(odp_packet_copy_to_mem(pkt, 0, len, buf) == 0); + + for (i = 0; i < len; i++) + CU_ASSERT(buf[i] == (i % 256)); + + odp_packet_free(pkt); + + CU_ASSERT(odp_pool_destroy(pool) == 0); +} + +void packet_test_concat_extend_trunc(void) +{ + odp_pool_capability_t capa; + odp_pool_t pool; + odp_pool_param_t param; + odp_packet_t pkt, pkt2; + int i, ret; + uint32_t alloc_len, ext_len, trunc_len, cur_len; + uint32_t len = 1900; + + CU_ASSERT_FATAL(odp_pool_capability(&capa) == 0); + + if (capa.pkt.max_len && capa.pkt.max_len < len) + len = capa.pkt.max_len; + + alloc_len = len / 8; + ext_len = len / 4; + trunc_len = len / 3; + + odp_pool_param_init(¶m); + + param.type = ODP_POOL_PACKET; + param.pkt.len = len; + param.pkt.num = 100; + + pool = odp_pool_create("packet_pool_concat", ¶m); + CU_ASSERT(packet_pool != ODP_POOL_INVALID); + + pkt = odp_packet_alloc(pool, alloc_len); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + + cur_len = odp_packet_len(pkt); + + for (i = 0; i < 2; i++) { + pkt2 = odp_packet_alloc(pool, alloc_len); + CU_ASSERT_FATAL(pkt2 != ODP_PACKET_INVALID); + + ret = odp_packet_concat(&pkt, pkt2); + CU_ASSERT(ret >= 0); + + if (ret < 0) + odp_packet_free(pkt2); + + CU_ASSERT(odp_packet_len(pkt) == (cur_len + alloc_len)); + cur_len = odp_packet_len(pkt); + } + + ret = odp_packet_extend_tail(&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); + + 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); + + pkt2 = odp_packet_alloc(pool, alloc_len); + CU_ASSERT_FATAL(pkt2 != ODP_PACKET_INVALID); + + ret = odp_packet_concat(&pkt, pkt2); + CU_ASSERT(ret >= 0); + + if (ret < 0) + odp_packet_free(pkt2); + + CU_ASSERT(odp_packet_len(pkt) == (cur_len + alloc_len)); + cur_len = odp_packet_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); + + 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); + + odp_packet_free(pkt); + + CU_ASSERT(odp_pool_destroy(pool) == 0); +} + +void packet_test_extend_small(void) +{ + odp_pool_capability_t capa; + odp_pool_t pool; + odp_pool_param_t param; + odp_packet_t pkt; + int ret, round; + uint8_t *data; + uint32_t i, seg_len; + int tail = 1; + uint32_t len = 32000; + uint8_t buf[len]; + + CU_ASSERT_FATAL(odp_pool_capability(&capa) == 0); + + if (capa.pkt.max_len && capa.pkt.max_len < len) + len = capa.pkt.max_len; + + odp_pool_param_init(¶m); + + param.type = ODP_POOL_PACKET; + param.pkt.len = len; + param.pkt.num = 100; + + pool = odp_pool_create("packet_pool_extend", ¶m); + CU_ASSERT(packet_pool != ODP_POOL_INVALID); + + for (round = 0; round < 2; round++) { + pkt = odp_packet_alloc(pool, 1); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + + data = odp_packet_data(pkt); + *data = 0; + + for (i = 0; i < len - 1; i++) { + if (tail) { + ret = odp_packet_extend_tail(&pkt, 1, + (void **)&data, + &seg_len); + CU_ASSERT(ret >= 0); + } else { + ret = odp_packet_extend_head(&pkt, 1, + (void **)&data, + &seg_len); + CU_ASSERT(ret >= 0); + } + + if (ret < 0) + break; + + if (tail) { + /* assert needs brackets */ + CU_ASSERT(seg_len == 1); + } else { + CU_ASSERT(seg_len > 0); + } + + *data = i + 1; + } + + CU_ASSERT(odp_packet_len(pkt) == len); + + len = odp_packet_len(pkt); + + memset(buf, 0, len); + CU_ASSERT(odp_packet_copy_to_mem(pkt, 0, len, buf) == 0); + + for (i = 0; i < len; i++) { + if (tail) { + /* assert needs brackets */ + CU_ASSERT(buf[i] == (i % 256)); + } else { + CU_ASSERT(buf[len - 1 - i] == (i % 256)); + } + } + + odp_packet_free(pkt); + + tail = 0; + } + + CU_ASSERT(odp_pool_destroy(pool) == 0); +} + +void packet_test_extend_large(void) +{ + odp_pool_capability_t capa; + odp_pool_t pool; + odp_pool_param_t param; + odp_packet_t pkt; + int ret, round; + uint8_t *data; + uint32_t i, seg_len, ext_len, cur_len, cur_data; + int tail = 1; + int num_div = 16; + int div = 1; + uint32_t len = 32000; + uint8_t buf[len]; + + CU_ASSERT_FATAL(odp_pool_capability(&capa) == 0); + + if (capa.pkt.max_len && capa.pkt.max_len < len) + len = capa.pkt.max_len; + + odp_pool_param_init(¶m); + + param.type = ODP_POOL_PACKET; + param.pkt.len = len; + param.pkt.num = 100; + + pool = odp_pool_create("packet_pool_extend", ¶m); + CU_ASSERT(packet_pool != ODP_POOL_INVALID); + + for (round = 0; round < 2 * num_div; round++) { + ext_len = len / div; + cur_len = ext_len; + + div++; + if (div > num_div) { + /* test extend head */ + div = 1; + tail = 0; + } + + pkt = odp_packet_alloc(pool, ext_len); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + + cur_data = 0; + + if (tail) { + ret = fill_data_forward(pkt, 0, ext_len, &cur_data); + CU_ASSERT(ret == 0); + } else { + ret = fill_data_backward(pkt, 0, ext_len, &cur_data); + CU_ASSERT(ret == 0); + } + + while (cur_len < len) { + if ((len - cur_len) < ext_len) + ext_len = len - cur_len; + + if (tail) { + ret = odp_packet_extend_tail(&pkt, ext_len, + (void **)&data, + &seg_len); + CU_ASSERT(ret >= 0); + } else { + ret = odp_packet_extend_head(&pkt, ext_len, + (void **)&data, + &seg_len); + CU_ASSERT(ret >= 0); + } + + if (ret < 0) + break; + + if (tail) { + /* assert needs brackets */ + CU_ASSERT((seg_len > 0) && + (seg_len <= ext_len)); + ret = fill_data_forward(pkt, cur_len, ext_len, + &cur_data); + CU_ASSERT(ret == 0); + } else { + CU_ASSERT(seg_len > 0); + CU_ASSERT(data == odp_packet_data(pkt)); + ret = fill_data_backward(pkt, 0, ext_len, + &cur_data); + CU_ASSERT(ret == 0); + } + + cur_len += ext_len; + } + + CU_ASSERT(odp_packet_len(pkt) == len); + + len = odp_packet_len(pkt); + + memset(buf, 0, len); + CU_ASSERT(odp_packet_copy_to_mem(pkt, 0, len, buf) == 0); + + for (i = 0; i < len; i++) { + if (tail) { + /* assert needs brackets */ + CU_ASSERT(buf[i] == (i % 256)); + } else { + CU_ASSERT(buf[len - 1 - i] == (i % 256)); + } + } + + odp_packet_free(pkt); + } + + CU_ASSERT(odp_pool_destroy(pool) == 0); +} + +void packet_test_extend_mix(void) +{ + odp_pool_capability_t capa; + odp_pool_t pool; + odp_pool_param_t param; + odp_packet_t pkt; + int ret, round; + uint8_t *data; + uint32_t i, seg_len, ext_len, cur_len, cur_data; + int small_count; + int tail = 1; + uint32_t len = 32000; + uint8_t buf[len]; + + CU_ASSERT_FATAL(odp_pool_capability(&capa) == 0); + + if (capa.pkt.max_len && capa.pkt.max_len < len) + len = capa.pkt.max_len; + + odp_pool_param_init(¶m); + + param.type = ODP_POOL_PACKET; + param.pkt.len = len; + param.pkt.num = 100; + + pool = odp_pool_create("packet_pool_extend", ¶m); + CU_ASSERT(packet_pool != ODP_POOL_INVALID); + + for (round = 0; round < 2; round++) { + small_count = 30; + ext_len = len / 10; + cur_len = ext_len; + + pkt = odp_packet_alloc(pool, ext_len); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + + cur_data = 0; + + if (tail) { + ret = fill_data_forward(pkt, 0, ext_len, &cur_data); + CU_ASSERT(ret == 0); + } else { + ret = fill_data_backward(pkt, 0, ext_len, &cur_data); + CU_ASSERT(ret == 0); + } + + while (cur_len < len) { + if (small_count) { + small_count--; + ext_len = len / 100; + } else { + ext_len = len / 4; + } + + if ((len - cur_len) < ext_len) + ext_len = len - cur_len; + + if (tail) { + ret = odp_packet_extend_tail(&pkt, ext_len, + (void **)&data, + &seg_len); + CU_ASSERT(ret >= 0); + CU_ASSERT((seg_len > 0) && + (seg_len <= ext_len)); + ret = fill_data_forward(pkt, cur_len, ext_len, + &cur_data); + CU_ASSERT(ret == 0); + } else { + ret = odp_packet_extend_head(&pkt, ext_len, + (void **)&data, + &seg_len); + CU_ASSERT(ret >= 0); + CU_ASSERT(seg_len > 0); + CU_ASSERT(data == odp_packet_data(pkt)); + ret = fill_data_backward(pkt, 0, ext_len, + &cur_data); + CU_ASSERT(ret == 0); + } + + cur_len += ext_len; + } + + CU_ASSERT(odp_packet_len(pkt) == len); + + len = odp_packet_len(pkt); + + memset(buf, 0, len); + CU_ASSERT(odp_packet_copy_to_mem(pkt, 0, len, buf) == 0); + + for (i = 0; i < len; i++) { + if (tail) { + /* assert needs brackets */ + CU_ASSERT(buf[i] == (i % 256)); + } else { + CU_ASSERT(buf[len - 1 - i] == (i % 256)); + } + } + + odp_packet_free(pkt); + + tail = 0; + } + + CU_ASSERT(odp_pool_destroy(pool) == 0); +} + void packet_test_align(void) { odp_packet_t pkt; @@ -1414,6 +1899,11 @@ odp_testinfo_t packet_suite[] = { ODP_TEST_INFO(packet_test_copy), ODP_TEST_INFO(packet_test_copydata), ODP_TEST_INFO(packet_test_concatsplit), + ODP_TEST_INFO(packet_test_concat_small), + ODP_TEST_INFO(packet_test_concat_extend_trunc), + 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_align), ODP_TEST_INFO(packet_test_offset), 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 10a377c..9bc3d63 100644 --- a/test/common_plat/validation/api/packet/packet.h +++ b/test/common_plat/validation/api/packet/packet.h @@ -30,6 +30,11 @@ void packet_test_add_rem_data(void); void packet_test_copy(void); void packet_test_copydata(void); void packet_test_concatsplit(void); +void packet_test_concat_small(void); +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_align(void); void packet_test_offset(void);
commit 5ea562d5d0c4f292ede6d366e205641b0db6c454 Author: Petri Savolainen petri.savolainen@nokia.com Date: Thu Dec 22 16:33:06 2016 +0200
linux-gen: packet: optimize concat
Optimized concat operation to avoid packet copy when destination packet has room to link source packet segments. Since concat uses extend tail it was also modified to handle variable segment sizes.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com 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/include/odp_buffer_internal.h b/platform/linux-generic/include/odp_buffer_internal.h index 4cc51d3..6149290 100644 --- a/platform/linux-generic/include/odp_buffer_internal.h +++ b/platform/linux-generic/include/odp_buffer_internal.h @@ -75,7 +75,7 @@ struct odp_buffer_hdr_t { uint32_t size;
/* Initial buffer data pointer and length */ - void *base_data; + uint8_t *base_data; uint32_t base_len; uint8_t *buf_end;
diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index 2d9e3e6..58b6f32 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -74,6 +74,15 @@ static inline void *packet_tail(odp_packet_hdr_t *pkt_hdr) return pkt_hdr->buf_hdr.seg[last].data + seg_len; }
+static inline uint32_t seg_headroom(odp_packet_hdr_t *pkt_hdr, int seg) +{ + odp_buffer_hdr_t *hdr = pkt_hdr->buf_hdr.seg[seg].hdr; + uint8_t *base = hdr->base_data; + uint8_t *head = pkt_hdr->buf_hdr.seg[seg].data; + + return CONFIG_PACKET_HEADROOM + (head - base); +} + static inline uint32_t seg_tailroom(odp_packet_hdr_t *pkt_hdr, int seg) { uint32_t seg_len = pkt_hdr->buf_hdr.seg[seg].len; @@ -297,7 +306,7 @@ static inline int num_segments(uint32_t len) return num; }
-static inline void copy_all_segs(odp_packet_hdr_t *to, odp_packet_hdr_t *from) +static inline void add_all_segs(odp_packet_hdr_t *to, odp_packet_hdr_t *from) { int i; int n = to->buf_hdr.segcount; @@ -313,52 +322,53 @@ static inline void copy_all_segs(odp_packet_hdr_t *to, odp_packet_hdr_t *from) }
static inline void copy_num_segs(odp_packet_hdr_t *to, odp_packet_hdr_t *from, - int num) + int first, int num) { int i;
for (i = 0; i < num; i++) { - to->buf_hdr.seg[i].hdr = from->buf_hdr.seg[num + i].hdr; - to->buf_hdr.seg[i].data = from->buf_hdr.seg[num + i].data; - to->buf_hdr.seg[i].len = from->buf_hdr.seg[num + i].len; + to->buf_hdr.seg[i].hdr = from->buf_hdr.seg[first + i].hdr; + to->buf_hdr.seg[i].data = from->buf_hdr.seg[first + i].data; + to->buf_hdr.seg[i].len = from->buf_hdr.seg[first + i].len; }
to->buf_hdr.segcount = num; }
-static inline odp_packet_hdr_t *add_segments(odp_packet_hdr_t *pkt_hdr, - uint32_t len, int head) +static inline odp_packet_hdr_t *alloc_segments(pool_t *pool, int num) { - pool_t *pool = pool_entry_from_hdl(pkt_hdr->buf_hdr.pool_hdl); - odp_packet_hdr_t *new_hdr; - int num, ret; - uint32_t seg_len, offset; + odp_buffer_t buf[num]; + int ret;
- num = num_segments(len); + ret = buffer_alloc_multi(pool, buf, NULL, num); + if (odp_unlikely(ret != num)) { + if (ret > 0) + buffer_free_multi(buf, ret);
- if ((pkt_hdr->buf_hdr.segcount + num) > CONFIG_PACKET_MAX_SEGS) return NULL; + }
- { - odp_buffer_t buf[num]; + return init_segments(buf, num); +}
- ret = buffer_alloc_multi(pool, buf, NULL, num); - if (odp_unlikely(ret != num)) { - if (ret > 0) - buffer_free_multi(buf, ret); +static inline odp_packet_hdr_t *add_segments(odp_packet_hdr_t *pkt_hdr, + pool_t *pool, uint32_t len, + int num, int head) +{ + odp_packet_hdr_t *new_hdr; + uint32_t seg_len, offset;
- return NULL; - } + new_hdr = alloc_segments(pool, num);
- new_hdr = init_segments(buf, num); - } + if (new_hdr == NULL) + return NULL;
seg_len = len - ((num - 1) * pool->max_seg_len); offset = pool->max_seg_len - seg_len;
if (head) { /* add into the head*/ - copy_all_segs(new_hdr, pkt_hdr); + add_all_segs(new_hdr, pkt_hdr);
/* adjust first segment length */ new_hdr->buf_hdr.seg[0].data += offset; @@ -374,7 +384,7 @@ static inline odp_packet_hdr_t *add_segments(odp_packet_hdr_t *pkt_hdr, int last;
/* add into the tail */ - copy_all_segs(pkt_hdr, new_hdr); + add_all_segs(pkt_hdr, new_hdr);
/* adjust last segment length */ last = packet_last_seg(pkt_hdr); @@ -387,49 +397,60 @@ static inline odp_packet_hdr_t *add_segments(odp_packet_hdr_t *pkt_hdr, return pkt_hdr; }
+static inline void free_bufs(odp_packet_hdr_t *pkt_hdr, int first, int num) +{ + int i; + odp_buffer_t buf[num]; + + for (i = 0; i < num; i++) + buf[i] = buffer_handle(pkt_hdr->buf_hdr.seg[first + i].hdr); + + buffer_free_multi(buf, num); +} + static inline odp_packet_hdr_t *free_segments(odp_packet_hdr_t *pkt_hdr, int num, uint32_t free_len, uint32_t pull_len, int head) { - int i; - odp_buffer_t buf[num]; - int n = pkt_hdr->buf_hdr.segcount - num; + int num_remain = pkt_hdr->buf_hdr.segcount - num;
if (head) { odp_packet_hdr_t *new_hdr; + int i; + odp_buffer_t buf[num];
for (i = 0; i < num; i++) buf[i] = buffer_handle(pkt_hdr->buf_hdr.seg[i].hdr);
/* First remaining segment is the new packet descriptor */ new_hdr = pkt_hdr->buf_hdr.seg[num].hdr; - copy_num_segs(new_hdr, pkt_hdr, n); + + copy_num_segs(new_hdr, pkt_hdr, num, num_remain); packet_seg_copy_md(new_hdr, pkt_hdr);
/* Tailroom not changed */ new_hdr->tailroom = pkt_hdr->tailroom; - /* No headroom in non-first segments */ - new_hdr->headroom = 0; + new_hdr->headroom = seg_headroom(new_hdr, 0); new_hdr->frame_len = pkt_hdr->frame_len - free_len;
pull_head(new_hdr, pull_len);
pkt_hdr = new_hdr; + + buffer_free_multi(buf, num); } else { - for (i = 0; i < num; i++) - buf[i] = buffer_handle(pkt_hdr->buf_hdr.seg[n + i].hdr); + /* Free last 'num' bufs */ + free_bufs(pkt_hdr, num_remain, num);
/* Head segment remains, no need to copy or update majority * of the metadata. */ - pkt_hdr->buf_hdr.segcount = n; + pkt_hdr->buf_hdr.segcount = num_remain; pkt_hdr->frame_len -= free_len; - pkt_hdr->tailroom = seg_tailroom(pkt_hdr, n - 1); + pkt_hdr->tailroom = seg_tailroom(pkt_hdr, num_remain - 1);
pull_tail(pkt_hdr, pull_len); }
- buffer_free_multi(buf, num); - return pkt_hdr; }
@@ -530,19 +551,10 @@ void odp_packet_free(odp_packet_t pkt) odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); int num_seg = pkt_hdr->buf_hdr.segcount;
- if (odp_likely(CONFIG_PACKET_MAX_SEGS == 1 || num_seg == 1)) { + if (odp_likely(CONFIG_PACKET_MAX_SEGS == 1 || num_seg == 1)) buffer_free_multi((odp_buffer_t *)&pkt, 1); - } else { - odp_buffer_t buf[num_seg]; - int i; - - buf[0] = (odp_buffer_t)pkt; - - for (i = 1; i < num_seg; i++) - buf[i] = buffer_handle(pkt_hdr->buf_hdr.seg[i].hdr); - - buffer_free_multi(buf, num_seg); - } + else + free_bufs(pkt_hdr, 0, num_seg); }
void odp_packet_free_multi(const odp_packet_t pkt[], int num) @@ -676,25 +688,277 @@ void *odp_packet_push_head(odp_packet_t pkt, uint32_t len) return packet_data(pkt_hdr); }
+static inline uint32_t pack_seg_head(odp_packet_hdr_t *pkt_hdr, int seg) +{ + odp_buffer_hdr_t *hdr = pkt_hdr->buf_hdr.seg[seg].hdr; + uint32_t len = pkt_hdr->buf_hdr.seg[seg].len; + uint8_t *src = pkt_hdr->buf_hdr.seg[seg].data; + uint8_t *dst = hdr->base_data; + + if (dst != src) { + memmove(dst, src, len); + pkt_hdr->buf_hdr.seg[seg].data = dst; + } + + return len; +} + +static inline uint32_t pack_seg_tail(odp_packet_hdr_t *pkt_hdr, int seg) +{ + odp_buffer_hdr_t *hdr = pkt_hdr->buf_hdr.seg[seg].hdr; + uint32_t len = pkt_hdr->buf_hdr.seg[seg].len; + uint8_t *src = pkt_hdr->buf_hdr.seg[seg].data; + uint8_t *dst = hdr->base_data + hdr->base_len - len; + + if (dst != src) { + memmove(dst, src, len); + pkt_hdr->buf_hdr.seg[seg].data = dst; + } + + return len; +} + +static inline uint32_t fill_seg_head(odp_packet_hdr_t *pkt_hdr, int dst_seg, + int src_seg, uint32_t max_len) +{ + uint32_t len = pkt_hdr->buf_hdr.seg[src_seg].len; + uint8_t *src = pkt_hdr->buf_hdr.seg[src_seg].data; + uint32_t offset = pkt_hdr->buf_hdr.seg[dst_seg].len; + uint8_t *dst = pkt_hdr->buf_hdr.seg[dst_seg].data + offset; + + if (len > max_len) + len = max_len; + + memmove(dst, src, len); + + pkt_hdr->buf_hdr.seg[dst_seg].len += len; + pkt_hdr->buf_hdr.seg[src_seg].len -= len; + pkt_hdr->buf_hdr.seg[src_seg].data += len; + + if (pkt_hdr->buf_hdr.seg[src_seg].len == 0) { + odp_buffer_hdr_t *hdr = pkt_hdr->buf_hdr.seg[src_seg].hdr; + + pkt_hdr->buf_hdr.seg[src_seg].data = hdr->base_data; + } + + return len; +} + +static inline uint32_t fill_seg_tail(odp_packet_hdr_t *pkt_hdr, int dst_seg, + int src_seg, uint32_t max_len) +{ + uint32_t src_len = pkt_hdr->buf_hdr.seg[src_seg].len; + uint8_t *src = pkt_hdr->buf_hdr.seg[src_seg].data; + uint8_t *dst = pkt_hdr->buf_hdr.seg[dst_seg].data; + uint32_t len = src_len; + + if (len > max_len) + len = max_len; + + src += src_len - len; + dst -= len; + + memmove(dst, src, len); + + pkt_hdr->buf_hdr.seg[dst_seg].data -= len; + pkt_hdr->buf_hdr.seg[dst_seg].len += len; + pkt_hdr->buf_hdr.seg[src_seg].len -= len; + + if (pkt_hdr->buf_hdr.seg[src_seg].len == 0) { + odp_buffer_hdr_t *hdr = pkt_hdr->buf_hdr.seg[src_seg].hdr; + + pkt_hdr->buf_hdr.seg[src_seg].data = hdr->base_data; + } + + return len; +} + +static inline int move_data_to_head(odp_packet_hdr_t *pkt_hdr, int segs) +{ + int dst_seg, src_seg; + uint32_t base_len, len, free_len; + uint32_t moved = 0; + + base_len = pkt_hdr->buf_hdr.base_len; + + for (dst_seg = 0; dst_seg < segs; dst_seg++) { + len = pack_seg_head(pkt_hdr, dst_seg); + moved += len; + + if (len == base_len) + continue; + + free_len = base_len - len; + + for (src_seg = dst_seg + 1; src_seg < segs; src_seg++) { + len = fill_seg_head(pkt_hdr, dst_seg, src_seg, + free_len); + moved += len; + + if (len == free_len) { + /* dst seg is full */ + break; + } + + /* src seg is empty */ + free_len -= len; + } + + if (moved == pkt_hdr->frame_len) + break; + } + + /* last segment which have data */ + return dst_seg; +} + +static inline int move_data_to_tail(odp_packet_hdr_t *pkt_hdr, int segs) +{ + int dst_seg, src_seg; + uint32_t base_len, len, free_len; + uint32_t moved = 0; + + base_len = pkt_hdr->buf_hdr.base_len; + + for (dst_seg = segs - 1; dst_seg >= 0; dst_seg--) { + len = pack_seg_tail(pkt_hdr, dst_seg); + moved += len; + + if (len == base_len) + continue; + + free_len = base_len - len; + + for (src_seg = dst_seg - 1; src_seg >= 0; src_seg--) { + len = fill_seg_tail(pkt_hdr, dst_seg, src_seg, + free_len); + moved += len; + + if (len == free_len) { + /* dst seg is full */ + break; + } + + /* src seg is empty */ + free_len -= len; + } + + if (moved == pkt_hdr->frame_len) + break; + } + + /* first segment which have data */ + return dst_seg; +} + +static inline void reset_seg(odp_packet_hdr_t *pkt_hdr, int first, int num) +{ + odp_buffer_hdr_t *hdr; + void *base; + int i; + uint32_t base_len = pkt_hdr->buf_hdr.base_len; + + for (i = first; i < first + num; i++) { + hdr = pkt_hdr->buf_hdr.seg[i].hdr; + base = hdr->base_data; + pkt_hdr->buf_hdr.seg[i].len = base_len; + pkt_hdr->buf_hdr.seg[i].data = base; + } +} + int odp_packet_extend_head(odp_packet_t *pkt, uint32_t len, void **data_ptr, uint32_t *seg_len) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(*pkt); - odp_packet_hdr_t *new_hdr; - uint32_t headroom = pkt_hdr->headroom; + uint32_t frame_len = pkt_hdr->frame_len; + uint32_t headroom = pkt_hdr->headroom; + int ret = 0;
if (len > headroom) { - push_head(pkt_hdr, headroom); - new_hdr = add_segments(pkt_hdr, len - headroom, 1); + pool_t *pool = pool_entry_from_hdl(pkt_hdr->buf_hdr.pool_hdl); + int num; + int segs;
- if (new_hdr == NULL) { - /* segment alloc failed, rollback changes */ - pull_head(pkt_hdr, headroom); + if (odp_unlikely((frame_len + len) > pool->max_len)) return -1; - }
- *pkt = packet_handle(new_hdr); - pkt_hdr = new_hdr; + num = num_segments(len - headroom); + segs = pkt_hdr->buf_hdr.segcount; + + if (odp_unlikely((segs + num) > CONFIG_PACKET_MAX_SEGS)) { + /* Cannot directly add new segments */ + odp_packet_hdr_t *new_hdr; + int new_segs = 0; + int free_segs = 0; + uint32_t base_len = pkt_hdr->buf_hdr.base_len; + uint32_t offset; + + num = num_segments(frame_len + len); + + if (num > segs) { + /* Allocate additional segments */ + new_segs = num - segs; + new_hdr = alloc_segments(pool, new_segs); + + if (new_hdr == NULL) + return -1; + + } else if (num < segs) { + free_segs = segs - num; + } + + /* Pack all data to packet tail */ + move_data_to_tail(pkt_hdr, segs); + reset_seg(pkt_hdr, 0, segs); + + if (new_segs) { + add_all_segs(new_hdr, pkt_hdr); + packet_seg_copy_md(new_hdr, pkt_hdr); + segs += new_segs; + + pkt_hdr = new_hdr; + *pkt = packet_handle(pkt_hdr); + } else if (free_segs) { + new_hdr = pkt_hdr->buf_hdr.seg[free_segs].hdr; + packet_seg_copy_md(new_hdr, pkt_hdr); + + /* Free extra segs */ + free_bufs(pkt_hdr, 0, free_segs); + + segs -= free_segs; + pkt_hdr = new_hdr; + *pkt = packet_handle(pkt_hdr); + } + + frame_len += len; + offset = (segs * base_len) - frame_len; + + pkt_hdr->buf_hdr.seg[0].data += offset; + pkt_hdr->buf_hdr.seg[0].len -= offset; + + pkt_hdr->buf_hdr.segcount = segs; + pkt_hdr->frame_len = frame_len; + pkt_hdr->headroom = offset + pool->headroom; + pkt_hdr->tailroom = pool->tailroom; + + /* Data was moved */ + ret = 1; + } else { + void *ptr; + + push_head(pkt_hdr, headroom); + ptr = add_segments(pkt_hdr, pool, len - headroom, + num, 1); + + if (ptr == NULL) { + /* segment alloc failed, rollback changes */ + pull_head(pkt_hdr, headroom); + return -1; + } + + *pkt = packet_handle(ptr); + pkt_hdr = ptr; + } } else { push_head(pkt_hdr, len); } @@ -705,7 +969,7 @@ int odp_packet_extend_head(odp_packet_t *pkt, uint32_t len, if (seg_len) *seg_len = packet_first_seg_len(pkt_hdr);
- return 0; + return ret; }
void *odp_packet_pull_head(odp_packet_t pkt, uint32_t len) @@ -769,30 +1033,96 @@ void *odp_packet_push_tail(odp_packet_t pkt, uint32_t len) }
int odp_packet_extend_tail(odp_packet_t *pkt, uint32_t len, - void **data_ptr, uint32_t *seg_len) + void **data_ptr, uint32_t *seg_len_out) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(*pkt); - void *ret; - uint32_t tailroom = pkt_hdr->tailroom; - uint32_t tail_off = pkt_hdr->frame_len; + uint32_t frame_len = pkt_hdr->frame_len; + uint32_t tailroom = pkt_hdr->tailroom; + uint32_t tail_off = frame_len; + int ret = 0;
if (len > tailroom) { - push_tail(pkt_hdr, tailroom); - ret = add_segments(pkt_hdr, len - tailroom, 0); + pool_t *pool = pool_entry_from_hdl(pkt_hdr->buf_hdr.pool_hdl); + int num; + int segs;
- if (ret == NULL) { - /* segment alloc failed, rollback changes */ - pull_tail(pkt_hdr, tailroom); + if (odp_unlikely((frame_len + len) > pool->max_len)) return -1; + + num = num_segments(len - tailroom); + segs = pkt_hdr->buf_hdr.segcount; + + if (odp_unlikely((segs + num) > CONFIG_PACKET_MAX_SEGS)) { + /* Cannot directly add new segments */ + odp_packet_hdr_t *new_hdr; + int new_segs = 0; + int free_segs = 0; + uint32_t base_len = pkt_hdr->buf_hdr.base_len; + uint32_t offset; + + num = num_segments(frame_len + len); + + if (num > segs) { + /* Allocate additional segments */ + new_segs = num - segs; + new_hdr = alloc_segments(pool, new_segs); + + if (new_hdr == NULL) + return -1; + + } else if (num < segs) { + free_segs = segs - num; + } + + /* Pack all data to packet head */ + move_data_to_head(pkt_hdr, segs); + reset_seg(pkt_hdr, 0, segs); + + if (new_segs) { + /* Add new segs */ + add_all_segs(pkt_hdr, new_hdr); + segs += new_segs; + } else if (free_segs) { + /* Free extra segs */ + free_bufs(pkt_hdr, segs - free_segs, free_segs); + + segs -= free_segs; + } + + frame_len += len; + offset = (segs * base_len) - frame_len; + + pkt_hdr->buf_hdr.seg[segs - 1].len -= offset; + + pkt_hdr->buf_hdr.segcount = segs; + pkt_hdr->frame_len = frame_len; + pkt_hdr->headroom = pool->headroom; + pkt_hdr->tailroom = offset + pool->tailroom; + + /* Data was moved */ + ret = 1; + } else { + void *ptr; + + push_tail(pkt_hdr, tailroom); + + ptr = add_segments(pkt_hdr, pool, len - tailroom, + num, 0); + + if (ptr == NULL) { + /* segment alloc failed, rollback changes */ + pull_tail(pkt_hdr, tailroom); + return -1; + } } } else { push_tail(pkt_hdr, len); }
if (data_ptr) - *data_ptr = packet_map(pkt_hdr, tail_off, seg_len, NULL); + *data_ptr = packet_map(pkt_hdr, tail_off, seg_len_out, NULL);
- return 0; + return ret; }
void *odp_packet_pull_tail(odp_packet_t pkt, uint32_t len) @@ -1199,19 +1529,38 @@ int odp_packet_align(odp_packet_t *pkt, uint32_t offset, uint32_t len,
int odp_packet_concat(odp_packet_t *dst, odp_packet_t src) { - uint32_t dst_len = odp_packet_len(*dst); - uint32_t src_len = odp_packet_len(src); - - if (odp_packet_extend_tail(dst, src_len, NULL, NULL) >= 0) { - (void)odp_packet_copy_from_pkt(*dst, dst_len, - src, 0, src_len); - if (src != *dst) + odp_packet_hdr_t *dst_hdr = odp_packet_hdr(*dst); + odp_packet_hdr_t *src_hdr = odp_packet_hdr(src); + int dst_segs = dst_hdr->buf_hdr.segcount; + int src_segs = src_hdr->buf_hdr.segcount; + odp_pool_t dst_pool = dst_hdr->buf_hdr.pool_hdl; + odp_pool_t src_pool = src_hdr->buf_hdr.pool_hdl; + uint32_t dst_len = dst_hdr->frame_len; + uint32_t src_len = src_hdr->frame_len; + + /* Do a copy if resulting packet would be out of segments or packets + * are from different pools. */ + if (odp_unlikely((dst_segs + src_segs) > CONFIG_PACKET_MAX_SEGS) || + odp_unlikely(dst_pool != src_pool)) { + if (odp_packet_extend_tail(dst, src_len, NULL, NULL) >= 0) { + (void)odp_packet_copy_from_pkt(*dst, dst_len, + src, 0, src_len); odp_packet_free(src);
- return 0; + /* Data was moved in memory */ + return 1; + } + + return -1; }
- return -1; + add_all_segs(dst_hdr, src_hdr); + + dst_hdr->frame_len = dst_len + src_len; + dst_hdr->tailroom = src_hdr->tailroom; + + /* Data was not moved in memory */ + return 0; }
int odp_packet_split(odp_packet_t *pkt, uint32_t len, odp_packet_t *tail)
commit 9fc7566c08ea131ea24c8f95e5ac92b1b45c1aa4 Author: Petri Savolainen petri.savolainen@nokia.com Date: Thu Dec 22 16:33:05 2016 +0200
validation: packet: concat-split test bug fix
Successful concat return values are 0 and >0.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com 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 3ad00ed..25252a6 100644 --- a/test/common_plat/validation/api/packet/packet.c +++ b/test/common_plat/validation/api/packet/packet.c @@ -1232,7 +1232,7 @@ void packet_test_concatsplit(void) CU_ASSERT(pkt_len == odp_packet_len(pkt)); CU_ASSERT(pkt_len == odp_packet_len(pkt2));
- CU_ASSERT(odp_packet_concat(&pkt, pkt2) == 0); + CU_ASSERT(odp_packet_concat(&pkt, pkt2) >= 0); CU_ASSERT(odp_packet_len(pkt) == pkt_len * 2); _packet_compare_offset(pkt, 0, pkt, pkt_len, pkt_len);
@@ -1262,7 +1262,7 @@ void packet_test_concatsplit(void) _packet_compare_offset(splits[0], 0, segmented_test_packet, pkt_len / 2, odp_packet_len(splits[0]));
- CU_ASSERT(odp_packet_concat(&pkt, splits[0]) == 0); + CU_ASSERT(odp_packet_concat(&pkt, splits[0]) >= 0); _packet_compare_offset(pkt, 0, segmented_test_packet, 0, pkt_len / 2); _packet_compare_offset(pkt, pkt_len / 2, segmented_test_packet, pkt_len / 2, pkt_len / 2); @@ -1279,9 +1279,9 @@ void packet_test_concatsplit(void) CU_ASSERT(odp_packet_len(splits[0]) + odp_packet_len(splits[1]) + odp_packet_len(splits[2]) + odp_packet_len(pkt) == pkt_len);
- CU_ASSERT(odp_packet_concat(&pkt, splits[2]) == 0); - CU_ASSERT(odp_packet_concat(&pkt, splits[1]) == 0); - CU_ASSERT(odp_packet_concat(&pkt, splits[0]) == 0); + CU_ASSERT(odp_packet_concat(&pkt, splits[2]) >= 0); + CU_ASSERT(odp_packet_concat(&pkt, splits[1]) >= 0); + CU_ASSERT(odp_packet_concat(&pkt, splits[0]) >= 0);
CU_ASSERT(odp_packet_len(pkt) == odp_packet_len(segmented_test_packet)); _packet_compare_data(pkt, segmented_test_packet);
commit 88339aef26f169fe01f06e158835b1d2f3617db7 Author: Petri Savolainen petri.savolainen@nokia.com Date: Thu Dec 22 16:33:04 2016 +0200
linux-gen: packet: improve packet print
Added segmentation and head-/tailroom information to packet print out.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com 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 10fbded..2d9e3e6 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -1395,6 +1395,7 @@ int odp_packet_move_data(odp_packet_t pkt, uint32_t dst_offset,
void odp_packet_print(odp_packet_t pkt) { + odp_packet_seg_t seg; int max_len = 512; char str[max_len]; int len = 0; @@ -1421,6 +1422,25 @@ void odp_packet_print(odp_packet_t pkt) len += snprintf(&str[len], n - len, " input %" PRIu64 "\n", odp_pktio_to_u64(hdr->input)); + len += snprintf(&str[len], n - len, + " headroom %" PRIu32 "\n", + odp_packet_headroom(pkt)); + len += snprintf(&str[len], n - len, + " tailroom %" PRIu32 "\n", + odp_packet_tailroom(pkt)); + len += snprintf(&str[len], n - len, + " num_segs %i\n", odp_packet_num_segs(pkt)); + + seg = odp_packet_first_seg(pkt); + + while (seg != ODP_PACKET_SEG_INVALID) { + len += snprintf(&str[len], n - len, + " seg_len %" PRIu32 "\n", + odp_packet_seg_data_len(pkt, seg)); + + seg = odp_packet_next_seg(pkt, seg); + } + str[len] = '\0';
ODP_PRINT("\n%s\n", str);
commit fffeaa22246f15a4b7c6c41d4bcfd7943c2b33cc Author: Petri Savolainen petri.savolainen@nokia.com Date: Thu Dec 22 16:33:03 2016 +0200
linux-gen: packet: fix bug in tailroom calculation
Tailroom is calculated from the end of the last segment, not from the first.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com 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 0d3fd05..10fbded 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -74,6 +74,15 @@ static inline void *packet_tail(odp_packet_hdr_t *pkt_hdr) return pkt_hdr->buf_hdr.seg[last].data + seg_len; }
+static inline uint32_t seg_tailroom(odp_packet_hdr_t *pkt_hdr, int seg) +{ + uint32_t seg_len = pkt_hdr->buf_hdr.seg[seg].len; + odp_buffer_hdr_t *hdr = pkt_hdr->buf_hdr.seg[seg].hdr; + uint8_t *tail = pkt_hdr->buf_hdr.seg[seg].data + seg_len; + + return hdr->buf_end - tail; +} + static inline void push_head(odp_packet_hdr_t *pkt_hdr, uint32_t len) { pkt_hdr->headroom -= len; @@ -383,11 +392,12 @@ static inline odp_packet_hdr_t *free_segments(odp_packet_hdr_t *pkt_hdr, uint32_t pull_len, int head) { int i; - odp_packet_hdr_t *new_hdr; odp_buffer_t buf[num]; int n = pkt_hdr->buf_hdr.segcount - num;
if (head) { + odp_packet_hdr_t *new_hdr; + for (i = 0; i < num; i++) buf[i] = buffer_handle(pkt_hdr->buf_hdr.seg[i].hdr);
@@ -413,8 +423,7 @@ static inline odp_packet_hdr_t *free_segments(odp_packet_hdr_t *pkt_hdr, * of the metadata. */ pkt_hdr->buf_hdr.segcount = n; pkt_hdr->frame_len -= free_len; - pkt_hdr->tailroom = pkt_hdr->buf_hdr.buf_end - - (uint8_t *)packet_tail(pkt_hdr); + pkt_hdr->tailroom = seg_tailroom(pkt_hdr, n - 1);
pull_tail(pkt_hdr, pull_len); }
commit 02ab1ec8f2c3e9fd6934c296d68f22ba33620706 Author: Petri Savolainen petri.savolainen@nokia.com Date: Thu Dec 22 16:33:02 2016 +0200
api: packet: src and dst packet must not be the same
Concat and copy_from_pkt operations must be called with src and dst packet handles which refer to the same packet.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Balasubramanian Manoharan bala.manoharan@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 faf62e2..4a86eba 100644 --- a/include/odp/api/spec/packet.h +++ b/include/odp/api/spec/packet.h @@ -781,7 +781,8 @@ uint32_t odp_packet_seg_data_len(odp_packet_t pkt, odp_packet_seg_t seg); * Concatenate all packet data from 'src' packet into tail of 'dst' packet. * Operation preserves 'dst' packet metadata in the resulting packet, * while 'src' packet handle, metadata and old segment handles for both packets - * become invalid. + * become invalid. Source and destination packet handles must not refer to + * the same packet. * * A successful operation overwrites 'dst' packet handle with a new handle, * which application must use as the reference to the resulting packet @@ -928,6 +929,9 @@ int odp_packet_copy_from_mem(odp_packet_t pkt, uint32_t offset, * Copy 'len' bytes of data from 'src' packet to 'dst' packet. Copy starts from * the specified source and destination packet offsets. Copied areas * (offset ... offset + len) must not exceed their packet data lengths. + * Source and destination packet handles must not refer to the same packet (use + * odp_packet_copy_data() or odp_packet_move_data() for a single packet). + * * Packet is not modified on an error. * * @param dst Destination packet handle
commit 3f5429ed2383056b0a085b99db6d180c39afa85e Author: Balasubramanian Manoharan bala.manoharan@linaro.org Date: Fri Nov 4 23:04:30 2016 +0530
api: pktio: adds further definition for classification configuration
Updates classification configuration documentation.
Signed-off-by: Balasubramanian Manoharan bala.manoharan@linaro.org Reviewed-by: Petri Savolainen petri.savolainen@nokia.com Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/packet_io.h b/include/odp/api/spec/packet_io.h index d46e405..2dabfcc 100644 --- a/include/odp/api/spec/packet_io.h +++ b/include/odp/api/spec/packet_io.h @@ -189,12 +189,11 @@ typedef struct odp_pktin_queue_param_t {
/** Number of input queues to be created * - * When classifier is enabled the number of queues may be zero - * (in odp_pktin_queue_config() step), otherwise at least one - * queue is required. More than one input queues require either flow - * hashing or classifier enabled. The maximum value is defined by - * pktio capability 'max_input_queues'. Queue type is defined by the - * input mode. The default value is 1. */ + * When classifier is enabled in odp_ipktin_queue_config() this + * value is ignored, otherwise at least one queue is required. + * More than one input queues require flow hashing configured. + * The maximum value is defined by pktio capability 'max_input_queues'. + * Queue type is defined by the input mode. The default value is 1. */ unsigned num_queues;
/** Queue parameters @@ -202,7 +201,9 @@ typedef struct odp_pktin_queue_param_t { * These are used for input queue creation in ODP_PKTIN_MODE_QUEUE * or ODP_PKTIN_MODE_SCHED modes. Scheduler parameters are considered * only in ODP_PKTIN_MODE_SCHED mode. Default values are defined in - * odp_queue_param_t documentation. */ + * odp_queue_param_t documentation. + * When classifier is enabled in odp_pktin_queue_config() this + * value is ignored. */ odp_queue_param_t queue_param;
} odp_pktin_queue_param_t; @@ -887,6 +888,8 @@ int odp_pktio_mac_addr(odp_pktio_t pktio, void *mac_addr, int size); * * @retval 0 on success * @retval <0 on failure + * + * @note The default_cos has to be unique per odp_pktio_t instance. */ int odp_pktio_default_cos_set(odp_pktio_t pktio, odp_cos_t default_cos);
-----------------------------------------------------------------------
Summary of changes: include/odp/api/spec/packet.h | 6 +- include/odp/api/spec/packet_io.h | 17 +- .../linux-generic/include/odp_buffer_internal.h | 2 +- .../linux-generic/include/odp_config_internal.h | 2 +- platform/linux-generic/odp_packet.c | 542 +++++++++++++++++---- test/common_plat/validation/api/packet/packet.c | 500 ++++++++++++++++++- test/common_plat/validation/api/packet/packet.h | 5 + 7 files changed, 977 insertions(+), 97 deletions(-)
hooks/post-receive