aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h1
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c19
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c6
3 files changed, 26 insertions, 0 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 0dcbab3203c9..8754b364f229 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -95,6 +95,7 @@ enum {
95 IPOIB_MCAST_FLAG_ATTACHED = 3, 95 IPOIB_MCAST_FLAG_ATTACHED = 3,
96 96
97 MAX_SEND_CQE = 16, 97 MAX_SEND_CQE = 16,
98 IPOIB_CM_COPYBREAK = 256,
98}; 99};
99 100
100#define IPOIB_OP_RECV (1ul << 31) 101#define IPOIB_OP_RECV (1ul << 31)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 91c959299910..6223fc39af70 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -523,6 +523,7 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
523 u64 mapping[IPOIB_CM_RX_SG]; 523 u64 mapping[IPOIB_CM_RX_SG];
524 int frags; 524 int frags;
525 int has_srq; 525 int has_srq;
526 struct sk_buff *small_skb;
526 527
527 ipoib_dbg_data(priv, "cm recv completion: id %d, status: %d\n", 528 ipoib_dbg_data(priv, "cm recv completion: id %d, status: %d\n",
528 wr_id, wc->status); 529 wr_id, wc->status);
@@ -577,6 +578,23 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
577 } 578 }
578 } 579 }
579 580
581 if (wc->byte_len < IPOIB_CM_COPYBREAK) {
582 int dlen = wc->byte_len;
583
584 small_skb = dev_alloc_skb(dlen + 12);
585 if (small_skb) {
586 skb_reserve(small_skb, 12);
587 ib_dma_sync_single_for_cpu(priv->ca, rx_ring[wr_id].mapping[0],
588 dlen, DMA_FROM_DEVICE);
589 skb_copy_from_linear_data(skb, small_skb->data, dlen);
590 ib_dma_sync_single_for_device(priv->ca, rx_ring[wr_id].mapping[0],
591 dlen, DMA_FROM_DEVICE);
592 skb_put(small_skb, dlen);
593 skb = small_skb;
594 goto copied;
595 }
596 }
597
580 frags = PAGE_ALIGN(wc->byte_len - min(wc->byte_len, 598 frags = PAGE_ALIGN(wc->byte_len - min(wc->byte_len,
581 (unsigned)IPOIB_CM_HEAD_SIZE)) / PAGE_SIZE; 599 (unsigned)IPOIB_CM_HEAD_SIZE)) / PAGE_SIZE;
582 600
@@ -599,6 +617,7 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
599 617
600 skb_put_frags(skb, IPOIB_CM_HEAD_SIZE, wc->byte_len, newskb); 618 skb_put_frags(skb, IPOIB_CM_HEAD_SIZE, wc->byte_len, newskb);
601 619
620copied:
602 skb->protocol = ((struct ipoib_header *) skb->data)->proto; 621 skb->protocol = ((struct ipoib_header *) skb->data)->proto;
603 skb_reset_mac_header(skb); 622 skb_reset_mac_header(skb);
604 skb_pull(skb, IPOIB_ENCAP_LEN); 623 skb_pull(skb, IPOIB_ENCAP_LEN);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index f217b1edd0ac..bfe1dbf99207 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -1302,6 +1302,12 @@ static int __init ipoib_init_module(void)
1302 ipoib_max_conn_qp = min(ipoib_max_conn_qp, IPOIB_CM_MAX_CONN_QP); 1302 ipoib_max_conn_qp = min(ipoib_max_conn_qp, IPOIB_CM_MAX_CONN_QP);
1303#endif 1303#endif
1304 1304
1305 /*
1306 * When copying small received packets, we only copy from the
1307 * linear data part of the SKB, so we rely on this condition.
1308 */
1309 BUILD_BUG_ON(IPOIB_CM_COPYBREAK > IPOIB_CM_HEAD_SIZE);
1310
1305 ret = ipoib_register_debugfs(); 1311 ret = ipoib_register_debugfs();
1306 if (ret) 1312 if (ret)
1307 return ret; 1313 return ret;