Skip to content

Instantly share code, notes, and snippets.

@christian-marie
Created November 19, 2014 21:06
Show Gist options
  • Save christian-marie/e8048b9c118bd3925957 to your computer and use it in GitHub Desktop.
Save christian-marie/e8048b9c118bd3925957 to your computer and use it in GitHub Desktop.
diff -ru mlnx-ofa_kernel-2.3/drivers/infiniband/ulp/ipoib/ipoib.h mlnx-ofa_kernel-2.3p/drivers/infiniband/ulp/ipoib/ipoib.h
--- mlnx-ofa_kernel-2.3/drivers/infiniband/ulp/ipoib/ipoib.h 2014-11-06 22:18:12.000000000 +1100
+++ mlnx-ofa_kernel-2.3p/drivers/infiniband/ulp/ipoib/ipoib.h 2014-11-18 14:59:35.509774088 +1100
@@ -658,6 +658,8 @@
void ipoib_mcast_dev_down(struct net_device *dev);
void ipoib_mcast_dev_flush(struct net_device *dev);
+int ipoib_dma_map_tx(struct ib_device *ca, struct ipoib_tx_buf *tx_req);
+
#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev);
int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter);
diff -ru mlnx-ofa_kernel-2.3/drivers/infiniband/ulp/ipoib/ipoib_cm.c mlnx-ofa_kernel-2.3p/drivers/infiniband/ulp/ipoib/ipoib_cm.c
--- mlnx-ofa_kernel-2.3/drivers/infiniband/ulp/ipoib/ipoib_cm.c 2014-11-06 22:18:08.000000000 +1100
+++ mlnx-ofa_kernel-2.3p/drivers/infiniband/ulp/ipoib/ipoib_cm.c 2014-11-18 14:51:21.513768260 +1100
@@ -732,11 +732,40 @@
return ib_post_send(tx->qp, &send_ring->tx_wr, &bad_wr);
}
+static inline int post_send_sg(struct ipoib_dev_priv *priv,
+ struct ipoib_cm_tx *tx,
+ unsigned int wr_id,
+ struct sk_buff *skb,
+ u64 mapping[MAX_SKB_FRAGS + 1],
+ struct ipoib_send_ring *send_ring)
+{
+ struct ib_send_wr *bad_wr;
+ int i, off;
+ skb_frag_t *frags = skb_shinfo(skb)->frags;
+ int nr_frags = skb_shinfo(skb)->nr_frags;
+ if (skb_headlen(skb)) {
+ send_ring->tx_sge[0].addr = mapping[0];
+ send_ring->tx_sge[0].length = skb_headlen(skb);
+ off = 1;
+ } else
+ off = 0;
+
+ for (i = 0; i < nr_frags; ++i) {
+ send_ring->tx_sge[i + off].addr = mapping[i + off];
+ send_ring->tx_sge[i + off].length = frags[i].size;
+ }
+ send_ring->tx_wr.num_sge = nr_frags + off;
+ send_ring->tx_wr.wr_id = wr_id | IPOIB_OP_CM;
+
+ return ib_post_send(tx->qp, &send_ring->tx_wr, &bad_wr);
+}
+
void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_tx *tx)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
struct ipoib_cm_tx_buf *tx_req;
- u64 addr;
+ struct ipoib_tx_buf sg_tx_req;
+ u64 addr = 0;
int rc;
struct ipoib_send_ring *send_ring;
u16 queue_index;
@@ -768,26 +797,42 @@
tx_req = &tx->tx_ring[tx->tx_head & (priv->sendq_size - 1)];
tx_req->skb = skb;
- if (skb->len < ipoib_inline_thold && !skb_shinfo(skb)->nr_frags) {
- addr = (u64) skb->data;
- send_ring->tx_wr.send_flags |= IB_SEND_INLINE;
- tx_req->is_inline = 1;
- } else {
- addr = ib_dma_map_single(priv->ca, skb->data,
- skb->len, DMA_TO_DEVICE);
- if (unlikely(ib_dma_mapping_error(priv->ca, addr))) {
+ if (skb_shinfo(skb)->nr_frags) {
+ sg_tx_req.skb = skb;
+ if (unlikely(ipoib_dma_map_tx(priv->ca, &sg_tx_req))) {
++send_ring->stats.tx_errors;
dev_kfree_skb_any(skb);
return;
}
- tx_req->mapping = addr;
tx_req->is_inline = 0;
- send_ring->tx_wr.send_flags &= ~IB_SEND_INLINE;
+ rc = post_send_sg(priv, tx, tx->tx_head &
+ (ipoib_sendq_size - 1),
+ skb, sg_tx_req.mapping, send_ring);
+ } else {
+ if (skb->len < ipoib_inline_thold &&
+ !skb_shinfo(skb)->nr_frags) {
+ addr = (u64) skb->data;
+ send_ring->tx_wr.send_flags |= IB_SEND_INLINE;
+ tx_req->is_inline = 1;
+ } else {
+ addr = ib_dma_map_single(priv->ca, skb->data,
+ skb->len, DMA_TO_DEVICE);
+ if (unlikely(ib_dma_mapping_error(priv->ca, addr))) {
+ ++send_ring->stats.tx_errors;
+ dev_kfree_skb_any(skb);
+ return;
+ }
+
+ tx_req->mapping = addr;
+ tx_req->is_inline = 0;
+ send_ring->tx_wr.send_flags &= ~IB_SEND_INLINE;
+ }
+
+ rc = post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1),
+ addr, skb->len, send_ring);
}
- rc = post_send(priv, tx, tx->tx_head & (priv->sendq_size - 1),
- addr, skb->len, send_ring);
if (unlikely(rc)) {
ipoib_warn(priv, "%s: post_send failed, error %d queue_index: %d skb->len: %d\n",
__func__, rc, queue_index, skb->len);
@@ -1103,6 +1148,9 @@
/* CM uses ipoib_ib_completion for TX completion and work using NAPI */
attr.send_cq = attr.recv_cq = priv->recv_ring[tx->neigh->index].recv_cq;
+ if (dev->features & NETIF_F_SG)
+ attr.cap.max_send_sge = MAX_SKB_FRAGS + 1;
+
spin_unlock_irqrestore(&priv->lock, flags);
return ib_create_qp(priv->pd, &attr);
diff -ru mlnx-ofa_kernel-2.3/drivers/infiniband/ulp/ipoib/ipoib_ib.c mlnx-ofa_kernel-2.3p/drivers/infiniband/ulp/ipoib/ipoib_ib.c
--- mlnx-ofa_kernel-2.3/drivers/infiniband/ulp/ipoib/ipoib_ib.c 2014-11-06 22:18:08.000000000 +1100
+++ mlnx-ofa_kernel-2.3p/drivers/infiniband/ulp/ipoib/ipoib_ib.c 2014-11-18 14:57:29.930788235 +1100
@@ -414,7 +414,7 @@
"for buf %d\n", wr_id);
}
-static int ipoib_dma_map_tx(struct ib_device *ca,
+int ipoib_dma_map_tx(struct ib_device *ca,
struct ipoib_tx_buf *tx_req)
{
struct sk_buff *skb = tx_req->skb;
diff -ru mlnx-ofa_kernel-2.3/drivers/infiniband/ulp/ipoib/ipoib_main.c mlnx-ofa_kernel-2.3p/drivers/infiniband/ulp/ipoib/ipoib_main.c
--- mlnx-ofa_kernel-2.3/drivers/infiniband/ulp/ipoib/ipoib_main.c 2014-11-06 22:18:08.000000000 +1100
+++ mlnx-ofa_kernel-2.3p/drivers/infiniband/ulp/ipoib/ipoib_main.c 2014-11-18 12:47:59.780427723 +1100
@@ -201,8 +201,7 @@
struct ipoib_dev_priv *priv = netdev_priv(dev);
if (test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags))
- features &= ~(NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
- NETIF_F_RXCSUM);
+ features &= ~(NETIF_F_IP_CSUM | NETIF_F_TSO | NETIF_F_RXCSUM);
return features;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment