On Wed, Jan 26, 2022 at 01:29:42AM +0100, Alexander Bluhm wrote:
> Hi,
> 
> There were some problems with ix(4) and ixl(4) hardware checksumming
> for the output path on strict alignment architectures.
> 
> I have merged jan@'s diffs and added some sanity checks and
> workarounds.
> 
> - If the first mbuf is not aligned or not contigous, use m_copydata()
>   to extract the IP, IPv6, TCP header.
> - If the header is in the first mbuf, use m_data for the fast path.
> - Add netstat counter for invalid header chains.  This makes
>   us aware when hardware checksumming fails.
> - Add netstat counter for header copies.  This indicates that
>   better storage allocation in the network stack is possible.
>   It also allows to recognize alignment problems on non-strict
>   architectures.
> - There is not risk of crashes on sparc64.
> 
> Does this aproach make sense?
> 
> ix(4) works quite well, but finds some UDP packets that need copy.
> ixl(4) has not been tested yet.  I would like to have some feedback
> for the idea first.
> 
> bluhm
> 
> Index: sys/dev/pci/if_ixl.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/dev/pci/if_ixl.c,v
> retrieving revision 1.78
> diff -u -p -r1.78 if_ixl.c
> --- sys/dev/pci/if_ixl.c      9 Jan 2022 05:42:54 -0000       1.78
> +++ sys/dev/pci/if_ixl.c      25 Jan 2022 23:50:01 -0000
> @@ -1388,6 +1398,7 @@ static int      ixl_rxeof(struct ixl_softc *,
>  static void  ixl_rxfill(struct ixl_softc *, struct ixl_rx_ring *);
>  static void  ixl_rxrefill(void *);
>  static int   ixl_rxrinfo(struct ixl_softc *, struct if_rxrinfo *);
> +static void  ixl_rx_checksum(struct mbuf *, uint64_t);
>  
>  #if NKSTAT > 0
>  static void  ixl_kstat_attach(struct ixl_softc *);
> @@ -3190,6 +3318,7 @@ ixl_rxeof(struct ixl_softc *sc, struct i
>                                       m->m_pkthdr.csum_flags |= M_FLOWID;
>                               }
>  
> +                             ixl_rx_checksum(m, word);
>                               ml_enqueue(&ml, m);
>                       } else {
>                               ifp->if_ierrors++; /* XXX */
> @@ -3320,6 +3449,23 @@ ixl_rxrinfo(struct ixl_softc *sc, struct
>       free(ifr, M_TEMP, ixl_nqueues(sc) * sizeof(*ifr));
>  
>       return (rv);
> +}
> +
> +static void
> +ixl_rx_checksum(struct mbuf *m, uint64_t word)
> +{
> +     if (!ISSET(word, IXL_RX_DESC_L3L4P))
> +             return;
> +
> +     if (ISSET(word, IXL_RX_DESC_IPE))
> +             return;
> +
> +     m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK;
> +
> +     if (ISSET(word, IXL_RX_DESC_L4E))
> +             return;
> +
> +     m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK | M_UDP_CSUM_IN_OK;
>  }
>  
>  static int

this is ok by me. tested on both amd64 and sparc64.

dlg

Reply via email to