Skip to content
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

Closed
wants to merge 9 commits into from
Closed

[PATCH v2] Various pktio fixes #397

wants to merge 9 commits into from

Conversation

MatiasElo
Copy link
Collaborator

@MatiasElo MatiasElo commented Jan 17, 2018

V2:

  • Added ODP_DBG messages where packets are dropped (Maxim)
  • Renamed recv/send function argument len -> num (Bill)

@MatiasElo MatiasElo changed the title Various pktio fixes [PATCH v1] Various pktio fixes Jan 17, 2018
@@ -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);
Copy link
Contributor

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?

Copy link
Collaborator Author

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.

Copy link
Contributor

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?

Copy link
Collaborator Author

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.

Copy link
Contributor

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.

Copy link
Collaborator Author

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)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here.

@muvarov muvarov changed the title [PATCH v1] Various pktio fixes [PATCH v2] Various pktio fixes Jan 17, 2018
@codecov
Copy link

codecov bot commented Jan 17, 2018

Codecov Report

Merging #397 into master will decrease coverage by 0.013%.
The diff coverage is 60.784%.

@@              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
Impacted Files Coverage Δ
platform/linux-generic/include/odp_packet_socket.h 100% <ø> (ø) ⬆️
platform/linux-generic/pktio/ipc.c 78.612% <100%> (+0.578%) ⬆️
platform/linux-generic/pktio/pcap.c 81.675% <100%> (ø) ⬆️
platform/linux-generic/pktio/tap.c 65.596% <100%> (ø) ⬆️
platform/linux-generic/pktio/netmap.c 82.092% <100%> (+0.329%) ⬆️
platform/linux-generic/pktio/socket_mmap.c 69.491% <34.693%> (-2.632%) ⬇️
platform/linux-generic/pktio/loop.c 85.606% <76.19%> (-2.099%) ⬇️
platform/linux-generic/pktio/socket.c 62.529% <76.923%> (-0.355%) ⬇️
platform/linux-generic/test/pktio_ipc/pktio_ipc2.c 68.217% <0%> (+0.775%) ⬆️
... and 1 more

@@ -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];
Copy link
Contributor

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.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will fix.


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;
Copy link
Contributor

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.

Copy link
Collaborator Author

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.

Copy link
Contributor

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
Copy link
Contributor

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.

Copy link
Collaborator Author

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;
Copy link
Contributor

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.

Copy link
Collaborator Author

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.

Copy link
Contributor

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;
Copy link
Contributor

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.

Copy link
Collaborator Author

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);
Copy link
Contributor

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)) {
Copy link
Collaborator

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?

Copy link
Collaborator Author

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.

@muvarov muvarov changed the title [PATCH v2] Various pktio fixes [PATCH v3] Various pktio fixes Jan 19, 2018
@MatiasElo MatiasElo changed the title [PATCH v3] Various pktio fixes [PATCH v2] Various pktio fixes Jan 19, 2018
@muvarov
Copy link
Contributor

muvarov commented Jan 22, 2018

Merged.

@muvarov muvarov closed this Jan 22, 2018
@MatiasElo MatiasElo deleted the dev/pktio_fixes branch February 20, 2018 07:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants