]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
xsigo: supported SGE's for LSO QP
authorPradeep Gopanapalli <pradeep.gopanapalli@oracle.com>
Thu, 10 Nov 2016 23:45:37 +0000 (23:45 +0000)
committerChuck Anderson <chuck.anderson@oracle.com>
Sat, 26 Nov 2016 14:01:34 +0000 (06:01 -0800)
Orabug: 25029868

PSIF supports 15 SGE's in case LSO QP linearize skb
if number of frags is greater than allowed sge's

Reported-by: Pradeep Gopanapalli <pradeep.gopanapalli@oracle.com>
Signed-off-by: Pradeep Gopanapalli <pradeep.gopanapalli@oracle.com>
Reviewed-by: viswa krishnamurthy <viswa.krishnamurthy@oracle.com>
Reviewed-by: UmaShankar Tumari Mahabalagiri <umashankar.mahabalagiri@oracle.com>
drivers/infiniband/ulp/xsigo/xscore/Makefile
drivers/infiniband/ulp/xsigo/xsvhba/Makefile
drivers/infiniband/ulp/xsigo/xsvnic/Makefile
drivers/infiniband/ulp/xsigo/xve/Makefile
drivers/infiniband/ulp/xsigo/xve/xve.h
drivers/infiniband/ulp/xsigo/xve/xve_cm.c
drivers/infiniband/ulp/xsigo/xve/xve_ib.c
drivers/infiniband/ulp/xsigo/xve/xve_stats.c
drivers/infiniband/ulp/xsigo/xve/xve_verbs.c

index d800cc89ecfeb32d230a3505c210bf52296e2d22..fe29e002e3a54e8f2a8218590375111e3f9271e4 100644 (file)
@@ -2,7 +2,7 @@ obj-$(CONFIG_INFINIBAND_XSCORE) := xscore.o
 xscore-y := xscore_impl.o xs_ud.o xscore_api.o xsmp.o \
            xscore_stats.o xscore_uadm.o
 
-ccflags-y += -DXSIGO_LOCAL_VERSION=\"6.0.r8037\"
+ccflags-y += -DXSIGO_LOCAL_VERSION=\"6.0.r8038\"
 ccflags-y += -DRDMA_PORT_LINK_LAYER_CHANGES -DHAS_SKB_ACCESS_FUNCTIONS
 ccflags-y += -DSCSI_STRUCT_CHANGES -DSCSI_TIMEOUT_CHANGES -DLLE
 ccflags-y += -DXG_FRAG_SIZE_PRESENT -DXG_FRAG_PAGE_PRESENT
index 9baf33ffa148f437178cc704e17e814774de7333..85b14c8dc5e536301aefaf699395dc7506ef4471 100644 (file)
@@ -3,7 +3,7 @@ xsvhba-y := vhba_main.o vhba_xsmp.o vhba_create.o vhba_init.o vhba_delete.o \
            vhba_attr.o vhba_wq.o vhba_proc.o vhba_stats.o vhba_ib.o        \
            vhba_scsi_intf.o vhba_align.o
 
-ccflags-y += -DXSIGO_LOCAL_VERSION=\"6.0.r8037\"
+ccflags-y += -DXSIGO_LOCAL_VERSION=\"6.0.r8038\"
 ccflags-y += -DRDMA_PORT_LINK_LAYER_CHANGES -DHAS_SKB_ACCESS_FUNCTIONS
 ccflags-y += -DSCSI_STRUCT_CHANGES -DSCSI_TIMEOUT_CHANGES -DLLE
 ccflags-y += -DXG_FRAG_SIZE_PRESENT -DXG_FRAG_PAGE_PRESENT
index abd8202f8f8dbd3fd648ce8dcb3a6089c3ac7b35..b5daeb1bdc388b2e362062acea98d7024c4146ef 100644 (file)
@@ -1,7 +1,7 @@
 obj-$(CONFIG_INFINIBAND_XSVNIC) := xsvnic.o
 xsvnic-y := xsvnic_main.o xsvnic_stats.o
 
-ccflags-y += -DXSIGO_LOCAL_VERSION=\"6.0.r8037\"
+ccflags-y += -DXSIGO_LOCAL_VERSION=\"6.0.r8038\"
 ccflags-y += -DRDMA_PORT_LINK_LAYER_CHANGES -DHAS_SKB_ACCESS_FUNCTIONS
 ccflags-y += -DSCSI_STRUCT_CHANGES -DSCSI_TIMEOUT_CHANGES -DLLE
 ccflags-y += -DXG_FRAG_SIZE_PRESENT -DXG_FRAG_PAGE_PRESENT
index 58f03f2aad8de4925665721f9dddcba568663493..892ce1385347b949429e13aab120731dbb56d7a9 100644 (file)
@@ -2,7 +2,7 @@ obj-$(CONFIG_INFINIBAND_XVE) := xve.o
 xve-y := xve_main.o xve_verbs.o xve_multicast.o xve_ib.o xve_tables.o \
         xve_ethtool.o xve_cm.o xve_stats.o
 
-ccflags-y += -DXSIGO_LOCAL_VERSION=\"6.0.r8037\"
+ccflags-y += -DXSIGO_LOCAL_VERSION=\"6.0.r8038\"
 ccflags-y += -DRDMA_PORT_LINK_LAYER_CHANGES -DHAS_SKB_ACCESS_FUNCTIONS
 ccflags-y += -DSCSI_STRUCT_CHANGES -DSCSI_TIMEOUT_CHANGES -DLLE
 ccflags-y += -DXG_FRAG_SIZE_PRESENT -DXG_FRAG_PAGE_PRESENT
index f0edb3b2b14c38c86d6afb315953675b5faac772..03d8ea1c0796a260a08f5f8b57c239aaf621fd48 100644 (file)
@@ -241,6 +241,7 @@ enum {
        XVE_TX_WMARK_REACH_COUNTER,
        XVE_TX_WAKE_UP_COUNTER,
        XVE_TX_QUEUE_STOP_COUNTER,
+       XVE_TX_LIN_SKB_COUNTER,
        XVE_RX_SKB_COUNTER,
        XVE_RX_SKB_ALLOC_COUNTER,
        XVE_RX_SMALLSKB_ALLOC_COUNTER,
@@ -774,6 +775,7 @@ struct xve_dev_priv {
        struct ib_send_wr tx_wr;
        struct ib_wc send_wc[MAX_SEND_CQE];
        struct ib_recv_wr rx_wr;
+       uint32_t max_send_sge;
        /* Allocate EDR SG for now */
        struct ib_sge rx_sge[XVE_UD_RX_EDR_SG];
        struct ib_wc ibwc[XVE_NUM_WC];
@@ -1309,8 +1311,43 @@ static inline u16 xg_vlan_get_rxtag(struct sk_buff *skb)
 
 }
 
+
+static inline int xve_linearize_skb(struct net_device *dev,
+               struct sk_buff *skb,
+               struct xve_dev_priv *priv,
+               unsigned max_send_sge)
+{
+       unsigned usable_sge = max_send_sge - !!skb_headlen(skb);
+
+       if (skb_shinfo(skb)->nr_frags > usable_sge) {
+               if (skb_linearize(skb) < 0) {
+                       pr_warn_ratelimited("XVE: %s failure to linearize\n",
+                                       priv->xve_name);
+                       INC_TX_DROP_STATS(priv, dev);
+                       INC_TX_ERROR_STATS(priv, dev);
+                       dev_kfree_skb_any(skb);
+                       return -1;
+               }
+
+               /* skb_linearize returned ok but still not reducing nr_frags */
+               if (skb_shinfo(skb)->nr_frags > usable_sge) {
+                       pr_warn_ratelimited
+                               ("XVE: %s too many frags after skb linearize\n",
+                                priv->xve_name);
+                       INC_TX_DROP_STATS(priv, dev);
+                       INC_TX_ERROR_STATS(priv, dev);
+                       dev_kfree_skb_any(skb);
+                       return -1;
+               }
+               priv->counters[XVE_TX_LIN_SKB_COUNTER]++;
+       }
+       return 0;
+
+}
+
+
 /*
- * ipoib_calc_speed - calculate port speed
+ * xve_calc_speed - calculate port speed
  *
  * @priv - device private data
  *
index f21b5ca02cf4d61397512ebc2a9cef2f4d1759e8..16837dd02aebde5ba6170d0dd2b023de645947ed 100644 (file)
@@ -1438,6 +1438,9 @@ int xve_cm_dev_init(struct net_device *dev)
                return ret;
        }
 
+       /* PSIF determines SGE value based on stack unwind */
+       priv->dev_attr = attr;
+
        /* Based on the admin mtu from the chassis */
        attr.max_srq_sge =
            min_t(int,
index 4cae01e27910fdea0f5083405f10003672af04ce..f08c509df08fcfbbf07b5a142ca7cc9a3e82aed8 100644 (file)
@@ -835,6 +835,10 @@ int xve_send(struct net_device *dev, struct sk_buff *skb,
                hlen = 0;
        }
 
+       /* Linearize if there are more than allowed SGE's */
+       if (xve_linearize_skb(dev, skb, priv, priv->max_send_sge) < 0)
+               return ret;
+
        xve_dbg_data(priv,
                     "%s sending packet, length=%d address=%p qpn=0x%06x\n",
                     __func__, skb->len, address, qpn);
index b7497474e2108b498d0401c7c027c16521fb9bc2..537d253c9ae4586cfea645e769b095be7af744b2 100755 (executable)
@@ -77,6 +77,7 @@ static char *counter_name[XVE_MAX_COUNTERS] = {
        "tx ring wmark reached count:\t",
        "tx wake up count\t\t",
        "tx queue stop count:\t\t",
+       "tx linearize skb count:\t",
        "rx_skb_count:\t\t\t",
        "rx_skb_alloc_count:\t\t",
        "rx_smallskb_alloc_count:\t",
@@ -471,6 +472,7 @@ static int xve_proc_read_device(struct seq_file *m, void *data)
        seq_printf(m, "IB MAX MTU: \t\t\t%d\n", vp->max_ib_mtu);
        seq_printf(m, "SG UD Mode:\t\t\t%d\n", xve_ud_need_sg(vp->admin_mtu));
        seq_printf(m, "Max SG supported(HCA):\t\t%d\n", vp->dev_attr.max_sge);
+       seq_printf(m, "SG Capability:\t\t\t%d\n", vp->max_send_sge);
        seq_printf(m, "Eoib:\t\t\t\t%s\n", (vp->is_eoib) ? "yes" : "no");
        seq_printf(m, "Jumbo:\t\t\t\t%s\n", (vp->is_jumbo) ? "yes" : "no");
        seq_printf(m, "Titan:\t\t\t\t%s\n", (vp->is_titan) ? "yes" : "no");
@@ -495,7 +497,7 @@ static int xve_proc_read_device(struct seq_file *m, void *data)
                seq_puts(m, "Multicast Report:\n");
                seq_printf(m, "Flag:                \t\t%lx\n",
                                vp->broadcast->flags);
-               seq_printf(m, "join state:              \t\t%s\n",
+               seq_printf(m, "join state:      \t\t%s\n",
                           test_bit(XVE_MCAST_FLAG_ATTACHED,
                                    &vp->broadcast->
                                    flags) ? "Joined" : "Not joined");
@@ -606,7 +608,7 @@ static int xve_proc_read_device(struct seq_file *m, void *data)
        if (vp->work_queue_failed != 0)
                seq_printf(m, "WQ Failed:\t\t\t%ld\n", vp->work_queue_failed);
 
-       seq_printf(m, "TX Net queue \t\t%s %d:%d\n",
+       seq_printf(m, "TX Net queue \t\t\t%s %d:%d\n",
                        netif_queue_stopped(vp->netdev) ? "stopped" : "active",
                        vp->counters[XVE_TX_WAKE_UP_COUNTER],
                        vp->counters[XVE_TX_QUEUE_STOP_COUNTER]);
index aa311508970b3d9fd4d3aa82162f961defdf804a..2afcf736299063c447ff11aa08838080ee06520a 100644 (file)
@@ -228,21 +228,22 @@ int xve_transport_dev_init(struct net_device *dev, struct ib_device *ca)
        if (priv->hca_caps & IB_DEVICE_BLOCK_MULTICAST_LOOPBACK)
                init_attr.create_flags |= IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK;
 
-       if (dev->features & NETIF_F_SG) {
-               /* As Titan Card supports less than MAX SKB we need to check */
-               max_sge = priv->dev_attr.max_sge;
-               if (max_sge >= (MAX_SKB_FRAGS + 1))
-                       max_sge = MAX_SKB_FRAGS + 1;
-               init_attr.cap.max_send_sge = max_sge;
-       }
-
        if (priv->is_eoib && priv->is_titan) {
                init_attr.create_flags |= IB_QP_CREATE_EOIB;
                init_attr.cap.max_inline_data = xve_max_inline_data;
-               xve_debug(DEBUG_QP_INFO, priv, "Setting eoIB mode%x data%x\n",
-                               init_attr.create_flags, xve_max_inline_data);
        }
 
+       if (dev->features & NETIF_F_SG) {
+               /*PSIF supports 16 SGE's*/
+               max_sge =  min_t(uint32_t, priv->dev_attr.max_sge,
+                               MAX_SKB_FRAGS + 1);
+
+               init_attr.cap.max_send_sge = max_sge;
+       }
+
+       xve_debug(DEBUG_QP_INFO, priv, "Create QP flags%x sge%d\n",
+                               init_attr.create_flags, max_sge);
+
        priv->qp = ib_create_qp(priv->pd, &init_attr);
        if (IS_ERR(priv->qp)) {
                pr_warn("%s: failed to create QP\n", ca->name);
@@ -270,6 +271,7 @@ int xve_transport_dev_init(struct net_device *dev, struct ib_device *ca)
        }
        priv->rx_wr.next = NULL;
        priv->rx_wr.sg_list = priv->rx_sge;
+       priv->max_send_sge = init_attr.cap.max_send_sge;
 
        return 0;