Author: sbruno
Date: Thu Jan  7 16:48:47 2016
New Revision: 293332
URL: https://svnweb.freebsd.org/changeset/base/293332

Log:
  Disable the reuse of checksum offload context descriptors in the case
  of multiple queues in em(4).  Document errata in the code.
  
  MFC after:    2 weeks
  Sponsored by: Limelight Networks
  Differential Revision:        https://reviews.freebsd.org/D3995

Modified:
  head/sys/dev/e1000/if_em.c

Modified: head/sys/dev/e1000/if_em.c
==============================================================================
--- head/sys/dev/e1000/if_em.c  Thu Jan  7 16:42:48 2016        (r293331)
+++ head/sys/dev/e1000/if_em.c  Thu Jan  7 16:48:47 2016        (r293332)
@@ -3735,29 +3735,38 @@ em_transmit_checksum_setup(struct tx_rin
                offload |= CSUM_TCP;
                tucss = hdr_len;
                tucso = hdr_len + offsetof(struct tcphdr, th_sum);
-               /*
-                * Setting up new checksum offload context for every frames
-                * takes a lot of processing time for hardware. This also
-                * reduces performance a lot for small sized frames so avoid
-                * it if driver can use previously configured checksum
-                * offload context.
-                */
-               if (txr->last_hw_offload == offload) {
-                       if (offload & CSUM_IP) {
-                               if (txr->last_hw_ipcss == ipcss &&
-                                   txr->last_hw_ipcso == ipcso &&
-                                   txr->last_hw_tucss == tucss &&
-                                   txr->last_hw_tucso == tucso)
-                                       return;
-                       } else {
-                               if (txr->last_hw_tucss == tucss &&
-                                   txr->last_hw_tucso == tucso)
-                                       return;
-                       }
-               }
-               txr->last_hw_offload = offload;
-               txr->last_hw_tucss = tucss;
-               txr->last_hw_tucso = tucso;
+               /*
+                * The 82574L can only remember the *last* context used
+                * regardless of queue that it was use for.  We cannot reuse
+                * contexts on this hardware platform and must generate a new
+                * context every time.  82574L hardware spec, section 7.2.6,
+                * second note.
+                */
+               if (adapter->num_queues < 2) {
+                       /*
+                       * Setting up new checksum offload context for every
+                       * frames takes a lot of processing time for hardware.
+                       * This also reduces performance a lot for small sized
+                       * frames so avoid it if driver can use previously
+                       * configured checksum offload context.
+                       */
+                       if (txr->last_hw_offload == offload) {
+                               if (offload & CSUM_IP) {
+                                       if (txr->last_hw_ipcss == ipcss &&
+                                       txr->last_hw_ipcso == ipcso &&
+                                       txr->last_hw_tucss == tucss &&
+                                       txr->last_hw_tucso == tucso)
+                                               return;
+                               } else {
+                                       if (txr->last_hw_tucss == tucss &&
+                                       txr->last_hw_tucso == tucso)
+                                               return;
+                               }
+                       }
+                       txr->last_hw_offload = offload;
+                       txr->last_hw_tucss = tucss;
+                       txr->last_hw_tucso = tucso;
+               }
                /*
                 * Start offset for payload checksum calculation.
                 * End offset for payload checksum calculation.
@@ -3773,29 +3782,38 @@ em_transmit_checksum_setup(struct tx_rin
                *txd_upper |= E1000_TXD_POPTS_TXSM << 8;
                tucss = hdr_len;
                tucso = hdr_len + offsetof(struct udphdr, uh_sum);
-               /*
-                * Setting up new checksum offload context for every frames
-                * takes a lot of processing time for hardware. This also
-                * reduces performance a lot for small sized frames so avoid
-                * it if driver can use previously configured checksum
-                * offload context.
-                */
-               if (txr->last_hw_offload == offload) {
-                       if (offload & CSUM_IP) {
-                               if (txr->last_hw_ipcss == ipcss &&
-                                   txr->last_hw_ipcso == ipcso &&
-                                   txr->last_hw_tucss == tucss &&
-                                   txr->last_hw_tucso == tucso)
-                                       return;
-                       } else {
-                               if (txr->last_hw_tucss == tucss &&
-                                   txr->last_hw_tucso == tucso)
-                                       return;
+               /*
+                * The 82574L can only remember the *last* context used
+                * regardless of queue that it was use for.  We cannot reuse
+                * contexts on this hardware platform and must generate a new
+                * context every time.  82574L hardware spec, section 7.2.6,
+                * second note.
+                */
+               if (adapter->num_queues < 2) {
+                       /*
+                       * Setting up new checksum offload context for every
+                       * frames takes a lot of processing time for hardware.
+                       * This also reduces performance a lot for small sized
+                       * frames so avoid it if driver can use previously
+                       * configured checksum offload context.
+                       */
+                       if (txr->last_hw_offload == offload) {
+                               if (offload & CSUM_IP) {
+                                       if (txr->last_hw_ipcss == ipcss &&
+                                       txr->last_hw_ipcso == ipcso &&
+                                       txr->last_hw_tucss == tucss &&
+                                       txr->last_hw_tucso == tucso)
+                                               return;
+                               } else {
+                                       if (txr->last_hw_tucss == tucss &&
+                                       txr->last_hw_tucso == tucso)
+                                               return;
+                               }
                        }
-               }
-               txr->last_hw_offload = offload;
-               txr->last_hw_tucss = tucss;
-               txr->last_hw_tucso = tucso;
+                       txr->last_hw_offload = offload;
+                       txr->last_hw_tucss = tucss;
+                       txr->last_hw_tucso = tucso;
+               }
                /*
                 * Start offset for header checksum calculation.
                 * End offset for header checksum calculation.
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to