All of lore.kernel.org
 help / color / mirror / Atom feed
From: Doug Ledford <dledford@redhat.com>
To: Hans Westgaard Ry <hans.westgaard.ry@oracle.com>
Cc: Sean Hefty <sean.hefty@intel.com>,
	Hal Rosenstock <hal.rosenstock@gmail.com>,
	Christoph Lameter <cl@linux.com>,
	Erez Shitrit <erezsh@mellanox.com>,
	Or Gerlitz <ogerlitz@mellanox.com>,
	Bart Van Assche <bart.vanassche@sandisk.com>,
	Yuval Shaia <yuval.shaia@oracle.com>,
	Haakon Bugge <haakon.bugge@oracle.com>,
	Wei Lin Guay <wei.lin.guay@oracle.com>,
	Chuck Lever <chuck.lever@oracle.com>,
	Jason Gunthorpe <jgunthorpe@obsidianresearch.com>,
	Haggai Eran <haggaie@mellanox.com>,
	Matan Barak <matanb@mellanox.com>,
	"open list:INFINIBAND SUBSYSTEM" <linux-rdma@vger.kernel.org>,
	open list <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v2] IB/ipoib: Add handling for sending of skb with many frags
Date: Thu, 3 Mar 2016 10:11:08 -0500	[thread overview]
Message-ID: <56D8540C.8010805@redhat.com> (raw)
In-Reply-To: <1456922668-24956-1-git-send-email-hans.westgaard.ry@oracle.com>

[-- Attachment #1: Type: text/plain, Size: 6453 bytes --]

On 03/02/2016 07:44 AM, Hans Westgaard Ry wrote:
> IPoIB converts skb-fragments to sge adding 1 extra sge when SG is enabled.
> Current codepath assumes that the max number of sge a device support
> is at least MAX_SKB_FRAGS+1, there is no interaction with upper layers
> to limit number of fragments in an skb if a device suports fewer
> sges. The assumptions also lead to requesting a fixed number of sge
> when IPoIB creates queue-pairs with SG enabled.
> 
> A fallback/slowpath is implemented using skb_linearize to
> handle cases where the conversion would result in more sges than supported.
> 
> Signed-off-by: Hans Westgaard Ry <hans.westgaard.ry@oracle.com>
> Reviewed-by: Håkon Bugge <haakon.bugge@oracle.com>
> Reviewed-by: Wei Lin Guay <wei.lin.guay@oracle.com>

Thanks for the version 2 that handles both connected and disconnected
mode.  Applied.

> ---
>  drivers/infiniband/ulp/ipoib/ipoib.h       |  2 ++
>  drivers/infiniband/ulp/ipoib/ipoib_cm.c    | 23 +++++++++++++++++++++--
>  drivers/infiniband/ulp/ipoib/ipoib_ib.c    | 18 ++++++++++++++++++
>  drivers/infiniband/ulp/ipoib/ipoib_verbs.c |  5 ++++-
>  4 files changed, 45 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
> index a6f3eab..85be0de 100644
> --- a/drivers/infiniband/ulp/ipoib/ipoib.h
> +++ b/drivers/infiniband/ulp/ipoib/ipoib.h
> @@ -244,6 +244,7 @@ struct ipoib_cm_tx {
>  	unsigned	     tx_tail;
>  	unsigned long	     flags;
>  	u32		     mtu;
> +	unsigned             max_send_sge;
>  };
>  
>  struct ipoib_cm_rx_buf {
> @@ -390,6 +391,7 @@ struct ipoib_dev_priv {
>  	int	hca_caps;
>  	struct ipoib_ethtool_st ethtool;
>  	struct timer_list poll_timer;
> +	unsigned max_send_sge;
>  };
>  
>  struct ipoib_ah {
> diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
> index 917e46e..c8ed535 100644
> --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
> +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
> @@ -710,6 +710,7 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_
>  	struct ipoib_dev_priv *priv = netdev_priv(dev);
>  	struct ipoib_tx_buf *tx_req;
>  	int rc;
> +	unsigned usable_sge = tx->max_send_sge - !!skb_headlen(skb);
>  
>  	if (unlikely(skb->len > tx->mtu)) {
>  		ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n",
> @@ -719,7 +720,23 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_
>  		ipoib_cm_skb_too_long(dev, skb, tx->mtu - IPOIB_ENCAP_LEN);
>  		return;
>  	}
> -
> +	if (skb_shinfo(skb)->nr_frags > usable_sge) {
> +		if (skb_linearize(skb) < 0) {
> +			ipoib_warn(priv, "skb could not be linearized\n");
> +			++dev->stats.tx_dropped;
> +			++dev->stats.tx_errors;
> +			dev_kfree_skb_any(skb);
> +			return;
> +		}
> +		/* Does skb_linearize return ok without reducing nr_frags? */
> +		if (skb_shinfo(skb)->nr_frags > usable_sge) {
> +			ipoib_warn(priv, "too many frags after skb linearize\n");
> +			++dev->stats.tx_dropped;
> +			++dev->stats.tx_errors;
> +			dev_kfree_skb_any(skb);
> +			return;
> +		}
> +	}
>  	ipoib_dbg_data(priv, "sending packet: head 0x%x length %d connection 0x%x\n",
>  		       tx->tx_head, skb->len, tx->qp->qp_num);
>  
> @@ -1031,7 +1048,8 @@ static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ipoib_
>  	struct ib_qp *tx_qp;
>  
>  	if (dev->features & NETIF_F_SG)
> -		attr.cap.max_send_sge = MAX_SKB_FRAGS + 1;
> +		attr.cap.max_send_sge =
> +			min_t(u32, priv->ca->attrs.max_sge, MAX_SKB_FRAGS + 1);
>  
>  	tx_qp = ib_create_qp(priv->pd, &attr);
>  	if (PTR_ERR(tx_qp) == -EINVAL) {
> @@ -1040,6 +1058,7 @@ static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ipoib_
>  		attr.create_flags &= ~IB_QP_CREATE_USE_GFP_NOIO;
>  		tx_qp = ib_create_qp(priv->pd, &attr);
>  	}
> +	tx->max_send_sge = attr.cap.max_send_sge;
>  	return tx_qp;
>  }
>  
> diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
> index 5ea0c14..ee7a555 100644
> --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
> +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
> @@ -540,6 +540,7 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb,
>  	struct ipoib_tx_buf *tx_req;
>  	int hlen, rc;
>  	void *phead;
> +	unsigned usable_sge = priv->max_send_sge - !!skb_headlen(skb);
>  
>  	if (skb_is_gso(skb)) {
>  		hlen = skb_transport_offset(skb) + tcp_hdrlen(skb);
> @@ -563,6 +564,23 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb,
>  		phead = NULL;
>  		hlen  = 0;
>  	}
> +	if (skb_shinfo(skb)->nr_frags > usable_sge) {
> +		if (skb_linearize(skb) < 0) {
> +			ipoib_warn(priv, "skb could not be linearized\n");
> +			++dev->stats.tx_dropped;
> +			++dev->stats.tx_errors;
> +			dev_kfree_skb_any(skb);
> +			return;
> +		}
> +		/* Does skb_linearize return ok without reducing nr_frags? */
> +		if (skb_shinfo(skb)->nr_frags > usable_sge) {
> +			ipoib_warn(priv, "too many frags after skb linearize\n");
> +			++dev->stats.tx_dropped;
> +			++dev->stats.tx_errors;
> +			dev_kfree_skb_any(skb);
> +			return;
> +		}
> +	}
>  
>  	ipoib_dbg_data(priv, "sending packet, length=%d address=%p qpn=0x%06x\n",
>  		       skb->len, address, qpn);
> diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
> index d48c5ba..b809c37 100644
> --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
> +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
> @@ -206,7 +206,8 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca)
>  		init_attr.create_flags |= IB_QP_CREATE_NETIF_QP;
>  
>  	if (dev->features & NETIF_F_SG)
> -		init_attr.cap.max_send_sge = MAX_SKB_FRAGS + 1;
> +		init_attr.cap.max_send_sge =
> +			min_t(u32, priv->ca->attrs.max_sge, MAX_SKB_FRAGS + 1);
>  
>  	priv->qp = ib_create_qp(priv->pd, &init_attr);
>  	if (IS_ERR(priv->qp)) {
> @@ -233,6 +234,8 @@ int ipoib_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;
>  
>  out_free_send_cq:
> 


-- 
Doug Ledford <dledford@redhat.com>
              GPG KeyID: 0E572FDD



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 884 bytes --]

      parent reply	other threads:[~2016-03-03 15:11 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-18  8:37 [PATCH] IB/ipoib: Add handling of skb with many frags Hans Westgaard Ry
2016-02-18  8:37 ` Hans Westgaard Ry
     [not found] ` <1455784674-8412-1-git-send-email-hans.westgaard.ry-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>
2016-03-02 12:44   ` [PATCH v2] IB/ipoib: Add handling for sending " Hans Westgaard Ry
2016-03-02 12:44     ` Hans Westgaard Ry
     [not found]     ` <1456922668-24956-1-git-send-email-hans.westgaard.ry-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>
2016-03-02 17:03       ` Yuval Shaia
2016-03-03 15:11     ` Doug Ledford [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=56D8540C.8010805@redhat.com \
    --to=dledford@redhat.com \
    --cc=bart.vanassche@sandisk.com \
    --cc=chuck.lever@oracle.com \
    --cc=cl@linux.com \
    --cc=erezsh@mellanox.com \
    --cc=haakon.bugge@oracle.com \
    --cc=haggaie@mellanox.com \
    --cc=hal.rosenstock@gmail.com \
    --cc=hans.westgaard.ry@oracle.com \
    --cc=jgunthorpe@obsidianresearch.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rdma@vger.kernel.org \
    --cc=matanb@mellanox.com \
    --cc=ogerlitz@mellanox.com \
    --cc=sean.hefty@intel.com \
    --cc=wei.lin.guay@oracle.com \
    --cc=yuval.shaia@oracle.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.