Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 Jan 2020 12:13:58 +0200
From:      Andriy Gapon <avg@FreeBSD.org>
To:        freebsd-net <freebsd-net@FreeBSD.org>
Subject:   iflib: how to signal that a packet has an error?
Message-ID:  <724363cd-99e3-5f73-e40a-38adc5125a13@FreeBSD.org>

next in thread | raw e-mail | index | archive | help

I am comparing vmxnet3 driver code before and after its conversion to iflib.
The old code used to do this:
        if (rxcd->error) {
                rxq->vxrxq_stats.vmrxs_ierrors++;
                m_freem(m);
                return;
        }

A vmx rx completion descriptor has a field that signals an error.
In practice I can see that something like this can happen:

(kgdb) p $4.vxrxq_comp_ring.vxcr_u.rxcd[444]
$8 = {rxd_idx = 80, pad1 = 0, eop = 0, sop = 1, qid = 0, rss_type = 0, no_csum =
0, pad2 = 0, rss_hash = 0, len = 2048, error = 0, vlan = 0, vtag = 0, csum = 0,
csum_ok = 0, udp = 0, tcp = 0, ipcsum_ok = 0, ipv6 = 0, ipv4 = 0,
  fragment = 0, fcs = 0, type = 3, gen = 1}
(kgdb) p $4.vxrxq_comp_ring.vxcr_u.rxcd[445]
$9 = {rxd_idx = 108, pad1 = 0, eop = 0, sop = 0, qid = 4, rss_type = 0, no_csum
= 0, pad2 = 0, rss_hash = 0, len = 2048, error = 0, vlan = 0, vtag = 0, csum =
0, csum_ok = 0, udp = 0, tcp = 0, ipcsum_ok = 0, ipv6 = 0, ipv4 = 0,
  fragment = 0, fcs = 0, type = 3, gen = 1}
(kgdb) p $4.vxrxq_comp_ring.vxcr_u.rxcd[446]
$10 = {rxd_idx = 109, pad1 = 0, eop = 0, sop = 0, qid = 4, rss_type = 0, no_csum
= 0, pad2 = 0, rss_hash = 0, len = 2048, error = 0, vlan = 0, vtag = 0, csum =
0, csum_ok = 0, udp = 0, tcp = 0, ipcsum_ok = 0, ipv6 = 0, ipv4 = 0,
  fragment = 0, fcs = 0, type = 3, gen = 1}
(kgdb) p $4.vxrxq_comp_ring.vxcr_u.rxcd[447]
$11 = {rxd_idx = 110, pad1 = 0, eop = 0, sop = 0, qid = 4, rss_type = 0, no_csum
= 0, pad2 = 0, rss_hash = 0, len = 2048, error = 0, vlan = 0, vtag = 0, csum =
0, csum_ok = 0, udp = 0, tcp = 0, ipcsum_ok = 0, ipv6 = 0, ipv4 = 0,
  fragment = 0, fcs = 0, type = 3, gen = 1}
⋮
(kgdb) p $4.vxrxq_comp_ring.vxcr_u.rxcd[455]
$12 = {rxd_idx = 118, pad1 = 0, eop = 0, sop = 0, qid = 4, rss_type = 0, no_csum
= 0, pad2 = 0, rss_hash = 0, len = 2048, error = 0, vlan = 0, vtag = 0, csum =
0, csum_ok = 0, udp = 0, tcp = 0, ipcsum_ok = 0, ipv6 = 0, ipv4 = 0,
  fragment = 0, fcs = 0, type = 3, gen = 1}
(kgdb) p $4.vxrxq_comp_ring.vxcr_u.rxcd[456]
$13 = {rxd_idx = 119, pad1 = 0, eop = 0, sop = 0, qid = 4, rss_type = 0, no_csum
= 0, pad2 = 0, rss_hash = 0, len = 2048, error = 0, vlan = 0, vtag = 0, csum =
0, csum_ok = 0, udp = 0, tcp = 0, ipcsum_ok = 0, ipv6 = 0, ipv4 = 0,
  fragment = 0, fcs = 0, type = 3, gen = 1}
(kgdb) p $4.vxrxq_comp_ring.vxcr_u.rxcd[457]
$14 = {rxd_idx = 120, pad1 = 0, eop = 1, sop = 0, qid = 4, rss_type = 0, no_csum
= 0, pad2 = 0, rss_hash = 0, len = 2048, error = 1, vlan = 0, vtag = 0, csum =
0, csum_ok = 0, udp = 0, tcp = 0, ipcsum_ok = 0, ipv6 = 0, ipv4 = 0,
  fragment = 0, fcs = 1, type = 3, gen = 1}

So, we have a start-of-packet descriptor (sop=1) followed by a bunch of
"continuation" descriptors (sop=0, eop=0) followed by the final end-of-packet
descriptor (eop=1).  And the final descriptor has error=1.

I am not sure what kind of an error is signaled in that fashion.
The old code would discard such a packet upon seeing eop=1 and error=1.
But the new code never examines the error field at all and, so, it passes up to
iflib all the fragments described by the descriptors and iflib assembles them
into a packet.

I am not sure if that's a problem or not.
But if we assume that that's a problem, then how should the driver let iflib
know that the packet should be ignored?
Should we extend the iflib interface or is there a way to achieve that using the
current interface?

Thank you!
-- 
Andriy Gapon



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?724363cd-99e3-5f73-e40a-38adc5125a13>