]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
xsigo: Optimizing Transmit completions
authorPradeep Gopanapalli <pradeep.gopanapalli@oracle.com>
Tue, 1 Nov 2016 19:34:29 +0000 (19:34 +0000)
committerChuck Anderson <chuck.anderson@oracle.com>
Thu, 3 Nov 2016 17:37:24 +0000 (10:37 -0700)
Orabug: 24928865

Added a timer for polling Transmit completion and
removed polling completion from a thread context.

Seeing Good Performance improvments with the changes.
In some cases uVNIC is seeing 10% increase in throughput

Reported-by: Pradeep Gopanapalli <pradeep.gopanapalli@oracle.com>
Signed-off-by: Pradeep Gopanapalli <pradeep.gopanapalli@oracle.com>
Reviewed-by: sajid zia <szia@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_ib.c
drivers/infiniband/ulp/xsigo/xve/xve_main.c
drivers/infiniband/ulp/xsigo/xve/xve_multicast.c
drivers/infiniband/ulp/xsigo/xve/xve_stats.c

index 59f4757d18edca5c648274b0a7dfa2c42cd26660..06e05f91bd64855af643df2bdd74a0ce3ce2ecd2 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.r8029\"
+ccflags-y += -DXSIGO_LOCAL_VERSION=\"6.0.r8031\"
 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 7900b401d044f56f7323710da9c9880aeca5e91b..08e128851670173766296d90732ee5979c4b547f 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.r8029\"
+ccflags-y += -DXSIGO_LOCAL_VERSION=\"6.0.r8031\"
 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 f9e33c532184591d1ea32bd8f68c7595549ae738..3f4edcdcc46cc78acb90c3a433f999c074f1c448 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.r8029\"
+ccflags-y += -DXSIGO_LOCAL_VERSION=\"6.0.r8031\"
 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 50b46acbcb5c7f7f58f36078f7d49ae75db113f2..1f038eabdbc4f01f465316f8fb0efdd13dfd008b 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.r8029\"
+ccflags-y += -DXSIGO_LOCAL_VERSION=\"6.0.r8031\"
 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 a31f5219003bacd26d7d4334b516fabb86412d89..1be1cd7006412407564ed3d5eeea7394b1f4aa60 100644 (file)
@@ -236,6 +236,7 @@ enum {
        XVE_TX_DROP_OPER_DOWN_COUNT,
        XVE_TX_SKB_ALLOC_ERROR_COUNTER,
        XVE_TX_RING_FULL_COUNTER,
+       XVE_TX_WMARK_REACH_COUNTER,
        XVE_TX_WAKE_UP_COUNTER,
        XVE_TX_QUEUE_STOP_COUNTER,
        XVE_RX_SKB_COUNTER,
@@ -292,6 +293,7 @@ enum {
        XVE_TX_UD_COUNTER,
        XVE_TX_RC_COUNTER,
        XVE_TX_MCAST_PKT,
+       XVE_TX_BCAST_PKT,
        XVE_TX_MCAST_ARP_QUERY,
        XVE_TX_MCAST_NDP_QUERY,
        XVE_TX_MCAST_ARP_VLAN_QUERY,
@@ -707,6 +709,7 @@ struct xve_dev_priv {
        struct net_device_stats stats;
        struct napi_struct napi;
        struct xve_ethtool_st ethtool;
+       struct timer_list poll_timer;
        u8 lro_mode;
        struct xve_lro lro;
        unsigned long flags;
@@ -1179,7 +1182,8 @@ void xve_remove_fwt_entry(struct xve_dev_priv *priv,
 void xve_fwt_entry_free(struct xve_dev_priv *priv,
                        struct xve_fwt_entry *fwt_entry);
 
-int xve_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb);
+int xve_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb,
+               u8 bcast);
 void xve_advert_mcast_join(struct xve_dev_priv *priv);
 int xve_mcast_start_thread(struct net_device *dev);
 int xve_mcast_stop_thread(struct net_device *dev, int flush);
index 73c71114ab5c082bfb8fc10911b7b5badf5db380..08c3850a20ff20b4b6e5f1240aada7eed912df14 100644 (file)
@@ -694,17 +694,31 @@ void xve_data_recv_handler(struct xve_dev_priv *priv)
        }
 }
 
-void xve_send_comp_handler(struct ib_cq *cq, void *dev_ptr)
+static void xve_ib_tx_timer_func(unsigned long ctx)
 {
-       struct xve_dev_priv *priv = netdev_priv((struct net_device *)dev_ptr);
+       struct net_device *dev = (struct net_device *)ctx;
+       struct xve_dev_priv *priv = netdev_priv(dev);
        unsigned long flags = 0;
 
+       netif_tx_lock(dev);
        spin_lock_irqsave(&priv->lock, flags);
        if (test_bit(XVE_OPER_UP, &priv->state) &&
-           !test_bit(XVE_DELETING, &priv->state)) {
+                       !test_bit(XVE_DELETING, &priv->state)) {
                poll_tx(priv);
        }
        spin_unlock_irqrestore(&priv->lock, flags);
+       if (netif_queue_stopped(dev))
+               mod_timer(&priv->poll_timer, jiffies + 1);
+
+       netif_tx_unlock(dev);
+}
+
+
+void xve_send_comp_handler(struct ib_cq *cq, void *dev_ptr)
+{
+       struct xve_dev_priv *priv = netdev_priv((struct net_device *)dev_ptr);
+
+       mod_timer(&priv->poll_timer, jiffies);
 }
 
 static inline int post_send(struct xve_dev_priv *priv,
@@ -761,8 +775,10 @@ static inline int post_send(struct xve_dev_priv *priv,
 /* Always called with priv->lock held
  * type argument is used to differentiate between the GATEWAY
  * and UVNIC packet.
- * 1 -> GATEWAY PACKET
  * 0 -> normal UVNIC PACKET
+ * 1 -> GATEWAY Broadcast PACKET
+ * 2 -> Sending Queued PACKET
+ * 3 -> Path Not found PACKET
  */
 int xve_send(struct net_device *dev, struct sk_buff *skb,
              struct xve_ah *address, u32 qpn, int type)
@@ -772,6 +788,7 @@ int xve_send(struct net_device *dev, struct sk_buff *skb,
        int hlen;
        void *phead;
        int ret = NETDEV_TX_OK;
+       u8 packet_sent = 0;
 
        if (skb_is_gso(skb)) {
                hlen = skb_transport_offset(skb) + tcp_hdrlen(skb);
@@ -843,16 +860,6 @@ int xve_send(struct net_device *dev, struct sk_buff *skb,
                netif_stop_queue(dev);
        }
 
-       if (netif_queue_stopped(dev)) {
-               int rc;
-
-               rc = ib_req_notify_cq(priv->send_cq,
-                               IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS);
-               if (rc < 0)
-                       xve_warn(priv, "request notify on send CQ failed\n");
-               else if (rc)
-                       poll_tx(priv);
-        }
        skb_orphan(skb);
        skb_dst_drop(skb);
 
@@ -874,17 +881,24 @@ int xve_send(struct net_device *dev, struct sk_buff *skb,
                --priv->tx_outstanding;
                priv->counters[XVE_TX_RING_FULL_COUNTER]++;
                xve_put_ah_refcnt(address);
+               xve_free_txbuf_memory(priv, tx_req);
                if (netif_queue_stopped(dev)) {
                        priv->counters[XVE_TX_WAKE_UP_COUNTER]++;
                        netif_wake_queue(dev);
                }
-               xve_free_txbuf_memory(priv, tx_req);
-       } else
+       } else {
+               packet_sent = 1;
                ++priv->tx_head;
+       }
 
        priv->send_hbeat_flag = 0;
-       if (unlikely(priv->tx_outstanding > SENDQ_LOW_WMARK))
+       if (unlikely(priv->tx_outstanding > SENDQ_LOW_WMARK)) {
+               priv->counters[XVE_TX_WMARK_REACH_COUNTER]++;
                poll_tx(priv);
+       }
+
+       if (packet_sent)
+               priv->counters[XVE_TX_COUNTER]++;
        return ret;
 }
 
@@ -1157,6 +1171,8 @@ int xve_ib_dev_stop(struct net_device *dev, int flush)
        xve_debug(DEBUG_IBDEV_INFO, priv, "%s All sends and receives done\n",
                  __func__);
 timeout:
+       xve_warn(priv, "Deleting TX timer");
+       del_timer_sync(&priv->poll_timer);
        qp_attr.qp_state = IB_QPS_RESET;
        if (ib_modify_qp(priv->qp, &qp_attr, IB_QP_STATE))
                xve_warn(priv, "Failed to modify QP to RESET state\n");
@@ -1184,6 +1200,9 @@ int xve_ib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
                return -ENODEV;
        }
 
+       setup_timer(&priv->poll_timer, xve_ib_tx_timer_func,
+                       (unsigned long)dev);
+
        if (dev->flags & IFF_UP) {
                if (xve_ib_dev_open(dev) != 0) {
                        xve_transport_dev_cleanup(dev);
index 45b1e2d9b3fad980c9c767aa2b878cec04f672e8..53f93f8718ea34354ae6e89a2abd05b43a35c5eb 100644 (file)
@@ -622,7 +622,7 @@ static void path_rec_completion(int status,
                skb->dev = dev;
                xve_get_ah_refcnt(path->ah);
                /* Sending the queued GATEWAY Packet */
-               ret = xve_send(dev, skb, path->ah, priv->gw.t_data_qp, 1);
+               ret = xve_send(dev, skb, path->ah, priv->gw.t_data_qp, 2);
                if (ret == NETDEV_TX_BUSY) {
                        xve_warn(priv, "send queue full full, dropping packet for %s\n",
                                        priv->xve_name);
@@ -892,9 +892,15 @@ static int xve_start_xmit(struct sk_buff *skb, struct net_device *dev)
        fwt_entry = xve_fwt_lookup(&priv->xve_fwt, eth_hdr(skb)->h_dest,
                        vlan_tag, 0);
        if (!fwt_entry) {
-               if (is_multicast_ether_addr(eth_hdr(skb)->h_dest)) {
+               if (is_broadcast_ether_addr(eth_hdr(skb)->h_dest)) {
+                       ret = xve_mcast_send(dev,
+                                       (void *)priv->bcast_mgid.raw, skb, 1);
+                       priv->counters[XVE_TX_BCAST_PKT]++;
+                       goto stats;
+               } else if (is_multicast_ether_addr(eth_hdr(skb)->h_dest)) {
+                       /* For Now Send Multicast Packet to G/W also */
                        ret = xve_mcast_send(dev,
-                                       (void *)priv->bcast_mgid.raw, skb);
+                                       (void *)priv->bcast_mgid.raw, skb, 1);
                        priv->counters[XVE_TX_MCAST_PKT]++;
                        goto stats;
                } else {
@@ -920,7 +926,7 @@ static int xve_start_xmit(struct sk_buff *skb, struct net_device *dev)
                                if (bcast_skb != NULL)
                                        ret = xve_mcast_send(dev,
                                                       (void *)priv->bcast_mgid.
-                                                      raw, bcast_skb);
+                                                      raw, bcast_skb, 1);
                        /*
                         * Now send the original packet also to over broadcast
                         * Later add counters for flood mode
@@ -928,7 +934,7 @@ static int xve_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        if (xve_is_edr(priv) ||
                                        len < XVE_UD_MTU(priv->max_ib_mtu)) {
                                ret = xve_mcast_send(dev,
-                                      (void *)priv->bcast_mgid.raw, skb);
+                                      (void *)priv->bcast_mgid.raw, skb, 1);
                                priv->counters[XVE_TX_MCAST_FLOOD_UD]++;
                        } else {
                                if (xve_flood_rc) {
@@ -982,7 +988,7 @@ static int xve_start_xmit(struct sk_buff *skb, struct net_device *dev)
                xve_debug(DEBUG_SEND_INFO, priv, "%s path ah is %p\n",
                          __func__, path->ah);
                xve_get_ah_refcnt(path->ah);
-               ret = xve_send(dev, skb, path->ah, fwt_entry->dqpn, 0);
+               ret = xve_send(dev, skb, path->ah, fwt_entry->dqpn, 3);
                priv->counters[XVE_TX_UD_COUNTER]++;
                goto stats;
        }
@@ -1001,7 +1007,6 @@ static int xve_start_xmit(struct sk_buff *skb, struct net_device *dev)
 stats:
        INC_TX_PKT_STATS(priv, dev);
        INC_TX_BYTE_STATS(priv, dev, len);
-       priv->counters[XVE_TX_COUNTER]++;
 free_fwt_ctx:
        if (path)
                xve_put_path(path, 0);
@@ -1601,15 +1606,6 @@ static int xve_state_machine(struct xve_dev_priv *priv)
                handle_action_flags(priv);
 
                if (priv->send_hbeat_flag) {
-                       unsigned long flags = 0;
-
-                       if (unlikely(priv->tx_outstanding > SENDQ_LOW_WMARK)) {
-                               netif_tx_lock(priv->netdev);
-                               spin_lock_irqsave(&priv->lock, flags);
-                               poll_tx(priv);
-                               spin_unlock_irqrestore(&priv->lock, flags);
-                               netif_tx_unlock(priv->netdev);
-                        }
                        if (xve_is_ovn(priv))
                                xve_send_hbeat(priv);
                }
index a753a6e5f47e64b2f6cef9dbdfd231ff318be0f3..917ceafe74db304e9cec7326b39a48f99e09a742 100644 (file)
@@ -667,7 +667,8 @@ static int xve_mcast_leave(struct net_device *dev, struct xve_mcast *mcast)
        return 0;
 }
 
-int xve_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb)
+int xve_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb,
+               u8 broadcast)
 {
        struct xve_dev_priv *priv = netdev_priv(dev);
        struct xve_mcast *mcast;
@@ -681,11 +682,14 @@ int xve_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb)
                return ret;
        }
 
-       if (xve_is_uplink(priv) && xve_gw_linkup(priv)) {
+       if (broadcast && (xve_is_uplink(priv) && xve_gw_linkup(priv))) {
                struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
 
-               if (nskb)
+               if (nskb) {
                        ret = xve_gw_send(dev, nskb);
+                       if (ret != NETDEV_TX_OK)
+                               return ret;
+               }
        }
 
        mcast = __xve_mcast_find(dev, mgid);
index 4a426b6a23af5793e12cf8e8d9677d93fe27247b..77f833576747f83b7f4952f1620cfbc2da4b63f2 100755 (executable)
@@ -73,6 +73,7 @@ static char *counter_name[XVE_MAX_COUNTERS] = {
        "tx drop oper down count:\t",
        "tx drop skb error count:\t",
        "tx drop ring full count:\t",
+       "tx ring wmark reached count:\t",
        "tx wake up count\t\t",
        "tx queue stop count:\t\t",
        "rx_skb_count:\t\t\t",
@@ -126,6 +127,7 @@ static char *counter_name[XVE_MAX_COUNTERS] = {
        "tx ud count:\t\t\t",
        "tx rc count:\t\t\t",
        "tx mcast count:\t\t\t",
+       "tx broadcast count:\t\t\t",
        "tx arp count:\t\t\t",
        "tx ndp count:\t\t\t",
        "tx arp vlan count:\t\t",
@@ -146,7 +148,7 @@ static char *counter_name[XVE_MAX_COUNTERS] = {
        "ib lid_active count:\t\t",
        "ib pkey_change count:\t\t",
        "ib invalid count:\t\t",
-       "uplink unicast:\t\t\t",
+       "tx uplink broadcast:\t\t\t",
        "Heartbeat Count(0x8919):\t\t",
        "Link State message count:\t",
        "RX frames without GRH\t\t",
@@ -468,6 +470,7 @@ static int xve_proc_read_device(struct seq_file *m, void *data)
 
        seq_printf(m, "Receive Queue size: \t\t%d\n", vp->xve_recvq_size);
        seq_printf(m, "Transmit Queue size: \t\t%d\n", vp->xve_sendq_size);
+       seq_printf(m, "Completion Queue size: \t\t%d\n", vp->xve_max_send_cqe);
 
        if (vp->cm_supported) {
                seq_printf(m, "Num of cm frags: \t\t%d\n", vp->cm.num_frags);