-
Notifications
You must be signed in to change notification settings - Fork 127
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[PATCH v2] Packet function inlines #437
Conversation
} | ||
|
||
void odp_packet_ts_set(odp_packet_t pkt, odp_time_t timestamp) | ||
{ | ||
odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt); | ||
|
||
pkt_hdr->timestamp = timestamp; | ||
pkt_hdr->p.input_flags.timestamp = 1; | ||
packet_set_ts(pkt_hdr, ×tamp); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be in its own commit? Different function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could rename the patch to:
"linux-gen: packet: use inlined flow hash and ts set"
... if necessary. The comment says already that also ts set is modified the same way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm OK with just a modified commit name. I agree we needn't be too granular about these things.
#ifndef __clang__ | ||
ODP_STATIC_ASSERT(ODP_PACKET_INVALID == 0, "Packet invalid not 0"); | ||
ODP_STATIC_ASSERT(ODP_BUFFER_INVALID == 0, "Buffer invalid not 0"); | ||
ODP_STATIC_ASSERT(ODP_EVENT_INVALID == 0, "Event invalid not 0"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you want to breech the strong type you need to use the internal odp_typeval()
macro here.
ODP_STATIC_ASSERT(_odp_typeval(ODP_EVENT_INVALID) == 0, "Event invalid not 0");
etc. I've verified that this works fine for clang, so no need for the conditional compilation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did try several combinations of type casts of invalid values, also cast to uintptr_t. The problem is that gcc and clang (clang version 3.8.0-2ubuntu4) of my machine accepted all of those casts, but the clang version in Travis (clang version 3.8.0-2ubuntu3~trusty5) does not accept anything.
Maybe it's a bug in the particular version of clang. Anyway, addition of this check even only on gcc side is improvement against what we currently have (no check). Packet invalid is currently 0xfffffff in ABI spec, but event/buffer invalid are 0.
odp_packet.c:55:19: error: static_assert expression is not an integral constant
expression
ODP_STATIC_ASSERT(((uintptr_t)ODP_PACKET_INVALID) == 0, "Packet invalid not 0");
../../include/odp/api/abi-default/debug.h:26:53: note: expanded from macro
'ODP_STATIC_ASSERT'
#define ODP_STATIC_ASSERT(cond, msg) _Static_assert(cond, msg)
^~~~
odp_packet.c:55:20: note: cast that performs the conversions of a
reinterpret_cast is not allowed in a constant expression
ODP_STATIC_ASSERT(((uintptr_t)ODP_PACKET_INVALID) == 0, "Packet invalid not 0");
^
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_odp_typeval()
is defined as:
#define _odp_typeval(handle) ((uint32_t)(uintptr_t)(handle))
It's used elsewhere in the ODP code and clang doesn't have any problem with it. I've verified this works for clang 4.2.1. Since it works elsewhere on Travis I'm not sure why it wouldn't in this instance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static_assert() seems special. The clang version in Travis does not accept type casts with static_assert(). The cast confuses it to think that (uintptr_t)0 == 0 is not an integral constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
odp_packet.c:52:19: error: static_assert expression is not an integral constant
expression
ODP_STATIC_ASSERT(_odp_typeval(ODP_BUFFER_INVALID) == 0, "Buffer inval not 0");
../../platform/linux-generic/include/odp/api/plat/strong_types.h:32:30: note:
expanded from macro '_odp_typeval'
#define _odp_typeval(handle) ((uint32_t)(uintptr_t)(handle))
^
../../include/odp/api/abi-default/debug.h:26:53: note: expanded from macro
'ODP_STATIC_ASSERT'
#define ODP_STATIC_ASSERT(cond, msg) _Static_assert(cond, msg)
^~~~
odp_packet.c:52:19: note: cast that performs the conversions of a
reinterpret_cast is not allowed in a constant expression
../../platform/linux-generic/include/odp/api/plat/strong_types.h:32:41: note:
expanded from macro '_odp_typeval'
#define _odp_typeval(handle) ((uint32_t)(uintptr_t)(handle))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very strange. I'm Ok with this workaround, but a comment about clang version might be appropriate. Don't know if it's worth doing a clang version check. We do things like that in the ODP_STATIC_ASSERT()
macro itself for similar reasons.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe (uintptr_t)(handle) == (uintptr_t)0
would do the trick?
Travis failure is a false positive checkpatch issue: |
Use inlined version of flow hash set function. Also changed API to use inlined timestamp function, so that the same function is not implemented twice. Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>
Use @cond tag to hide internal functions from Doxygen. Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>
Inline commonly used packet to/from memory copy functions. Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>
Use always inlined versions of packet to/from memory copy functions. Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>
Use only one function (packet_hdr) in handle to header pointer conversion. odp_packet_hdr is bad name for an implementation internal function as API function prefix is odp_packet_. Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>
For minimal code complexity and negative impact, prefetch only when the requested address is in the first segment and prefetch only one cache line. Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>
Inline implementation of packet_from_event and packet_to_event functions. Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>
Use multi versions of packet / event conversion functions. Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>
Fast path functions cannot be expected to always check against invalid handles. Also a handle that has been closed (or destroyed) must not be passed to any API function. Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>
Inline packet IO interface handle to index conversion function which may be used frequently. Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>
Inline packet input interface index function which may be used frequently. Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>
e0d7d50
to
559591f
Compare
Codecov Report
@@ Coverage Diff @@
## master #437 +/- ##
=============================================
+ Coverage 77.774% 77.847% +0.072%
=============================================
Files 199 201 +2
Lines 35766 35987 +221
=============================================
+ Hits 27817 28015 +198
- Misses 7949 7972 +23
|
} | ||
|
||
return 0; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason to move function bodies?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those need to be inside #include <odp/visibility_begin.h> #include <odp/visibility_end.h>. It's cleaner to have one vs multiple such regions in one c file.
|
||
CU_ASSERT(odp_pktio_close(pktio) == 0); | ||
CU_ASSERT(odp_pktio_index(pktio) < 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally I would agree. However we explicitly have the invalid usecase in API:
@retval <0 On failure (e.g., handle not valid)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can have _odp_pktio_index()
which does not perform such checks and odp_pktio_index()
which does ODP_PKTIO_INVALID
check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
API does not (and should not) guarantee that invalid or stale handles are checked on fast path functions, such as this conversion to index. Especially, any API function is not specified to check against stale handles. Function may return -1, if it finds an error but we don't guarantee which errors are checked. For example, there may be check against invalid handle, but there may not be either. Invalid values are mostly needed for API function to be able return that e.g. create/open/alloc failed. E.g. here, application should check that pktio open succeeded, if it did not succeed it should not continue and pass that invalid handle to other pktio calls. That way every API call does not need to check the handle, only application needs to check it once after open/create/alloc.
This close + index test above it basically the same thing as doing:
odp_packet_free(pkt);
data = odp_packet_data(pkt);
// now we can assume that data is NULL, since pkt packet was freed and this function always searches through valid handles and notices that this handle value is not valid anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To me "(e.g. handle not valid)" does not yet guarantee the check. This would:
"<0 When pktio handle is invalid, or some other error happened".
In general, we should remove all such "e.g. handle not valid" comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@psavol Totally agree about close + index.
With minor comments: |
Ping. This has been 4 days ready to merge. |
Merged. |
Continue inlining of commonly used small packet and pktio API functions. These improve few percents packet rate of L2fwd (both direct/scheduled mode) and OFP burst test. Especially, in non-ABI compat mode and with copying pktios (test with DPDK).