]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
sdp: Fix bugs in huge paged HW's
authorAmir Vadai <amirv@mellanox.co.il>
Tue, 16 Feb 2010 15:36:00 +0000 (17:36 +0200)
committerMukesh Kacker <mukesh.kacker@oracle.com>
Tue, 6 Oct 2015 12:04:47 +0000 (05:04 -0700)
* Protect some constants that are based on PAGE_SIZE:
  - FMR size
  - xmit_goal
* renamed SDP_HEAD_SIZE => SDP_SKB_HEAD_SIZE
* removed unneeded special IA64 code due to changes here

Signed-off-by: Amir Vadai <amirv@mellanox.co.il>
drivers/infiniband/ulp/sdp/sdp.h
drivers/infiniband/ulp/sdp/sdp_main.c
drivers/infiniband/ulp/sdp/sdp_rx.c

index dc5332c2d6a3d4889a717d42824733f48884f1bd..893e33f974cba5f439dffd5d1371eb9782ea24cb 100644 (file)
@@ -30,7 +30,7 @@
 #define SDP_TX_SIZE 0x40
 #define SDP_RX_SIZE 0x40
 
-#define SDP_FMR_SIZE (PAGE_SIZE / sizeof(u64))
+#define SDP_FMR_SIZE (MIN(0x1000, PAGE_SIZE) / sizeof(u64))
 #define SDP_FMR_POOL_SIZE      1024
 #define SDP_FMR_DIRTY_SIZE     ( SDP_FMR_POOL_SIZE / 4 )
 
 #define SDP_MAX_RECV_SKB_FRAGS (PAGE_SIZE > 0x8000 ? 1 : 0x8000 / PAGE_SIZE)
 #define SDP_MAX_SEND_SKB_FRAGS (SDP_MAX_RECV_SKB_FRAGS + 1)
 
-/* payload len - rest will be rx'ed into frags */
-#define SDP_HEAD_SIZE (PAGE_SIZE / 2 + sizeof(struct sdp_bsdh))
+/* skb inlined data len - rest will be rx'ed into frags */
+#define SDP_SKB_HEAD_SIZE (0x500 + sizeof(struct sdp_bsdh))
+
+/* limit tx payload len, if the sink supports bigger buffers than the source
+ * can handle.
+ * or rx fragment size (limited by sge->length size) */
+#define SDP_MAX_PAYLOAD ((1 << 16) - SDP_SKB_HEAD_SIZE)
+
 #define SDP_NUM_WC 4
-#define SDP_MAX_PAYLOAD ((1 << 16) - SDP_HEAD_SIZE)
 
 #define SDP_DEF_ZCOPY_THRESH 64*1024
 #define SDP_MIN_ZCOPY_THRESH PAGE_SIZE
index be77cdf94aa06a0a944b64fb6d48284711efd274..a7e050c07ce9c4d865acc42be6b582e6f1051fd2 100644 (file)
@@ -1914,6 +1914,13 @@ new_segment:
 
                                skb_entail(sk, ssk, skb);
                                copy = size_goal;
+
+                               sdp_dbg_data(sk, "created new skb: %p"
+                                       " len = %d, sk_send_head: %p "
+                                       "copy: %d size_goal: %d\n",
+                                       skb, skb->len, sk->sk_send_head, copy, size_goal);
+
+
                        } else {
                                sdp_dbg_data(sk, "adding to existing skb: %p"
                                        " len = %d, sk_send_head: %p "
index f869f96b4b7f288149dc91f88e167bdd49883544..44d9f1a2e5a8429b4d620e1b051679e98f4f7e8b 100644 (file)
@@ -164,11 +164,11 @@ static int sdp_post_recv(struct sdp_sock *ssk)
        /* TODO: allocate from cache */
 
        if (unlikely(ssk->isk.sk.sk_allocation)) {
-               skb = sdp_stream_alloc_skb(&ssk->isk.sk, SDP_HEAD_SIZE,
+               skb = sdp_stream_alloc_skb(&ssk->isk.sk, SDP_SKB_HEAD_SIZE,
                                          ssk->isk.sk.sk_allocation);
                gfp_page = ssk->isk.sk.sk_allocation | __GFP_HIGHMEM;
        } else {
-               skb = sdp_stream_alloc_skb(&ssk->isk.sk, SDP_HEAD_SIZE,
+               skb = sdp_stream_alloc_skb(&ssk->isk.sk, SDP_SKB_HEAD_SIZE,
                                          GFP_KERNEL);
                gfp_page = GFP_HIGHUSER;
        }
@@ -193,14 +193,14 @@ static int sdp_post_recv(struct sdp_sock *ssk)
        rx_req = ssk->rx_ring.buffer + (id & (SDP_RX_SIZE - 1));
        rx_req->skb = skb;
        dev = ssk->ib_device;
-       addr = ib_dma_map_single(dev, h, SDP_HEAD_SIZE, DMA_FROM_DEVICE);
+       addr = ib_dma_map_single(dev, h, SDP_SKB_HEAD_SIZE, DMA_FROM_DEVICE);
        BUG_ON(ib_dma_mapping_error(dev, addr));
 
        rx_req->mapping[0] = addr;
 
        /* TODO: proper error handling */
        sge->addr = (u64)addr;
-       sge->length = SDP_HEAD_SIZE;
+       sge->length = SDP_SKB_HEAD_SIZE;
        sge->lkey = ssk->sdp_dev->mr->lkey;
        frags = skb_shinfo(skb)->nr_frags;
        for (i = 0; i < frags; ++i) {
@@ -242,7 +242,7 @@ static inline int sdp_post_recvs_needed(struct sdp_sock *ssk)
 {
        struct sock *sk = &ssk->isk.sk;
        int scale = ssk->rcvbuf_scale;
-       int buffer_size = SDP_HEAD_SIZE + ssk->recv_frags * PAGE_SIZE;
+       int buffer_size = SDP_SKB_HEAD_SIZE + ssk->recv_frags * PAGE_SIZE;
        unsigned long max_bytes;
 
        if (!ssk->qp_active)
@@ -344,7 +344,7 @@ static inline struct sk_buff *sdp_sock_queue_rcv_skb(struct sock *sk,
 
 int sdp_init_buffers(struct sdp_sock *ssk, u32 new_size)
 {
-       ssk->recv_frags = PAGE_ALIGN(new_size - SDP_HEAD_SIZE) / PAGE_SIZE;
+       ssk->recv_frags = PAGE_ALIGN(new_size - SDP_SKB_HEAD_SIZE) / PAGE_SIZE;
        if (ssk->recv_frags > SDP_MAX_RECV_SKB_FRAGS)
                ssk->recv_frags = SDP_MAX_RECV_SKB_FRAGS;
        ssk->rcvbuf_scale = rcvbuf_scale;
@@ -356,22 +356,13 @@ int sdp_init_buffers(struct sdp_sock *ssk, u32 new_size)
 
 int sdp_resize_buffers(struct sdp_sock *ssk, u32 new_size)
 {
-       u32 curr_size = SDP_HEAD_SIZE + ssk->recv_frags * PAGE_SIZE;
-#if defined(__ia64__)
-       /* for huge PAGE_SIZE systems, aka IA64, limit buffers size
-          [re-]negotiation to a known+working size that will not
-          trigger a HW error/rc to be interpreted as a IB_WC_LOC_LEN_ERR */
-       u32 max_size = (SDP_HEAD_SIZE + SDP_MAX_RECV_SKB_FRAGS * PAGE_SIZE) <=
-               32784 ?
-               (SDP_HEAD_SIZE + SDP_MAX_RECV_SKB_FRAGS * PAGE_SIZE) : 32784;
-#else
-       u32 max_size = SDP_HEAD_SIZE + SDP_MAX_RECV_SKB_FRAGS * PAGE_SIZE;
-#endif
+       u32 curr_size = SDP_SKB_HEAD_SIZE + ssk->recv_frags * PAGE_SIZE;
+       u32 max_size = SDP_SKB_HEAD_SIZE + SDP_MAX_RECV_SKB_FRAGS * PAGE_SIZE;
 
        if (new_size > curr_size && new_size <= max_size &&
            sdp_get_large_socket(ssk)) {
                ssk->rcvbuf_scale = rcvbuf_scale;
-               ssk->recv_frags = PAGE_ALIGN(new_size - SDP_HEAD_SIZE) /
+               ssk->recv_frags = PAGE_ALIGN(new_size - SDP_SKB_HEAD_SIZE) /
                        PAGE_SIZE;
                if (ssk->recv_frags > SDP_MAX_RECV_SKB_FRAGS)
                        ssk->recv_frags = SDP_MAX_RECV_SKB_FRAGS;
@@ -434,7 +425,7 @@ static struct sk_buff *sdp_recv_completion(struct sdp_sock *ssk, int id)
        dev = ssk->ib_device;
        rx_req = &ssk->rx_ring.buffer[id & (SDP_RX_SIZE - 1)];
        skb = rx_req->skb;
-       ib_dma_unmap_single(dev, rx_req->mapping[0], SDP_HEAD_SIZE,
+       ib_dma_unmap_single(dev, rx_req->mapping[0], SDP_SKB_HEAD_SIZE,
                            DMA_FROM_DEVICE);
        frags = skb_shinfo(skb)->nr_frags;
        for (i = 0; i < frags; ++i)
@@ -642,8 +633,8 @@ static struct sk_buff *sdp_process_rx_wc(struct sdp_sock *ssk,
 
        h = (struct sdp_bsdh *)skb->data;
 
-       if (likely(wc->byte_len > SDP_HEAD_SIZE))
-               skb->data_len = wc->byte_len - SDP_HEAD_SIZE;
+       if (likely(wc->byte_len > SDP_SKB_HEAD_SIZE))
+               skb->data_len = wc->byte_len - SDP_SKB_HEAD_SIZE;
        else
                skb->data_len = 0;