-
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] Various pktio fixes #397
Conversation
@@ -643,6 +643,10 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED, | |||
uint16_t pkt_len = msgvec[i].msg_len; | |||
int ret; | |||
|
|||
if (odp_unlikely(msgvec[i].msg_hdr.msg_flags & MSG_TRUNC)) { | |||
odp_packet_free(pkt); |
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 to just set error bit and deliver this packet to application?
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.
The odp_pktin_maxlen() API states:
Maximum frame length in bytes that the packet IO interface can receive.
I interpret this so that the application shouln't see packets which exceed pktin max length.
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.
The error bit simply says the packet was truncated to max length. Perhaps the application is only interested in the first few bytes of a packet?
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.
The most specific error type an application can see is odp_packet_has_l2_error(), so it cannot trust packet contents anyway.
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.
inconsistent with counters. You do not increase drop counter for pktio and silently drop packet. I would add at least ODP_DBG() so people on debug can see what is happening.
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.
Problem is that you cannot increase drop counters manually with socket pktio. The counters are read directly from ethtool or sysfs. ODP_DBG() may be the best option here.
@@ -202,6 +202,12 @@ static inline unsigned pkt_mmap_v2_rx(pktio_entry_t *pktio_entry, | |||
pkt_buf = (uint8_t *)ppd.raw + ppd.v2->tp_h.tp_mac; | |||
pkt_len = ppd.v2->tp_h.tp_snaplen; | |||
|
|||
if (odp_unlikely(pkt_len > pkt_sock->mtu)) { |
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.
same here.
Codecov Report
@@ Coverage Diff @@
## master #397 +/- ##
=============================================
- Coverage 78.565% 78.552% -0.014%
=============================================
Files 194 194
Lines 34818 34852 +34
=============================================
+ Hits 27355 27377 +22
- Misses 7463 7475 +12
|
platform/linux-generic/pktio/loop.c
Outdated
@@ -177,13 +177,15 @@ static int loopback_send(pktio_entry_t *pktio_entry, int index ODP_UNUSED, | |||
int i; | |||
int ret; | |||
uint32_t bytes = 0; | |||
uint32_t out_octets_tbl[len]; |
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're doing miscellaneous cleanups anyway, perhaps changing len
to num
here should be considered? len
is confusing since it doesn't represent packet length.
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.
Will fix.
platform/linux-generic/pktio/loop.c
Outdated
|
||
if (odp_unlikely(len > QUEUE_MULTI_MAX)) | ||
len = QUEUE_MULTI_MAX; | ||
|
||
for (i = 0; i < len; ++i) { | ||
hdr_tbl[i] = packet_to_buf_hdr(pkt_tbl[i]); | ||
bytes += odp_packet_len(pkt_tbl[i]); | ||
out_octets_tbl[i] = bytes; |
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.
Not sure I understand what out_octets_tbl
is accumulating here. If I'm sending three 100 byte packets this will set out_octets_tbl[0]
to 100, out_octets_tbl[1]
to 200, and out_octets_tbl[2]
to 300.
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.
This array is used to update stats.out_octets
correctly if enq_multi()
fails to enqueue all packets. Without it a second for loop would be required inside if (ret > 0)
clause below.
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.
Ok, clever. A comment might be useful here.
@@ -361,11 +365,13 @@ static void mmap_fill_ring(struct ring *ring, odp_pool_t pool_hdl, int fanout) | |||
pool->tailroom + TPACKET_HDRLEN + | |||
TPACKET_ALIGNMENT + + (pz - 1)) & (-pz); | |||
|
|||
/* Calculate how many pages do we need to hold all pool packets |
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.
If we're cleaning up, might as well delete that extraneous +
in the above line: TPACKET_ALIGNMENT + + (pz - 1)) & (-pz);
I'm surprised the compiler doesn't flag that since it's normally so picky about issuing warnings.
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.
Will fix.
@@ -148,6 +155,11 @@ static uint8_t *pkt_mmap_vlan_insert(uint8_t *l2_hdr_ptr, | |||
return l2_hdr_ptr; | |||
} | |||
|
|||
static inline unsigned next_frame(unsigned cur_frame, unsigned frame_count) | |||
{ | |||
return odp_unlikely(cur_frame + 1 >= frame_count) ? 0 : cur_frame + 1; |
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 ring->rd_num
is a power of two, is the concern here that the %
operator might result in a division if the compiler doesn't know that it's a power of two? In that case:
return ++cur_frame & (frame_count - 1);
solves that problem and avoids conditional branching.
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.
ring->rd_num is not guaranteed to be a power of two. At least on my test system (28 lcores) it is not.
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.
OK. From the original code's use of %
I assumed that was the case. Perhaps that's why this is a fix. :)
frame_num = next_frame(frame_num, frame_count); | ||
} | ||
|
||
ring->frame_num = (first_frame_num + nb_tx) % frame_count; |
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.
ring->frame_num = next_frame(first_frame_num + nb_tx - 1, frame_count);
is an alternative here.
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.
Will fix.
@@ -643,6 +643,10 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED, | |||
uint16_t pkt_len = msgvec[i].msg_len; | |||
int ret; | |||
|
|||
if (odp_unlikely(msgvec[i].msg_hdr.msg_flags & MSG_TRUNC)) { | |||
odp_packet_free(pkt); |
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.
The error bit simply says the packet was truncated to max length. Perhaps the application is only interested in the first few bytes of a packet?
The maximum frame length should include Ethernet header. Signed-off-by: Matias Elo <matias.elo@nokia.com>
odp_pktio_stats_t.out_octets was updated incorrectly if all packets were not successfully enqueued. Signed-off-by: Matias Elo <matias.elo@nokia.com>
Use more realistic MTU value. The value is also checked in TX. Signed-off-by: Matias Elo <matias.elo@nokia.com>
Allocating enough memory for storing each packet in the packet pool in each RX/TX block wastes a lot of memory. Also, the following mmap() call in mmap_sock() can start failing when the number of memory blocks increases (large number of CPU cores). Reduce the amount of required memory by limiting the size of memory blocks. Signed-off-by: Matias Elo <matias.elo@nokia.com>
During sock_mmap_send() when all packets are not transmitted by sendto() call the used ring slots have to be marked as TP_STATUS_AVAILABLE or they will be transmitted during the next sock_mmap_send() call, thus breaking the function logic. To reduce the number of failed TX operations (visible to applications) the pktio implementation can call sendto() up to TX_RETRIES times during a single sock_mmap_recv() call. Signed-off-by: Matias Elo <matias.elo@nokia.com>
Drop truncated packets received from kernel during sock_mmsg_recv() call. Signed-off-by: Matias Elo <matias.elo@nokia.com>
Some NICs do not automatically drop packets which exceed MTU. Signed-off-by: Matias Elo <matias.elo@nokia.com>
Some NICs do not automatically drop packets which exceed MTU. Signed-off-by: Matias Elo <matias.elo@nokia.com>
Use argument named 'num' on all pktio devices to pass the number of packets to receive/transmit. Signed-off-by: Matias Elo <matias.elo@nokia.com>
@@ -202,6 +202,12 @@ static inline unsigned pkt_mmap_v2_rx(pktio_entry_t *pktio_entry, | |||
pkt_buf = (uint8_t *)ppd.raw + ppd.v2->tp_h.tp_mac; | |||
pkt_len = ppd.v2->tp_h.tp_snaplen; | |||
|
|||
if (odp_unlikely(pkt_len > pkt_sock->mtu)) { |
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.
Why do these extra long packets need to be dropped?
Maybe odp_pktin_maxlen() is not defined clearly enough regarding unexpectedly long packets. Does it merely promise that packets up to the maxlen can always be received (as I thought) or does it also promise that no bigger packets than that ever come out of the pktin? Would the latter be even useful?
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.
At this point the API is quite clear:
Maximum frame length in bytes that the packet IO interface can receive.
Merged. |
V2: