From: Amir Vadai Date: Wed, 27 Oct 2010 12:24:07 +0000 (+0200) Subject: sdp: BUG2158 - do not send SrcAvail too small X-Git-Tag: v4.1.12-92~264^2~5^2~68 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=7e43b7c63b5b404a15a38b373ca2e243068c2a02;p=users%2Fjedix%2Flinux-maple.git sdp: BUG2158 - do not send SrcAvail too small - Shouldn't send SrcAvail with no RDMA payload - could happen when RLIMIT is too small. - Do not crash when getting 2 SrcAvail. Signed-off-by: Amir Vadai --- diff --git a/drivers/infiniband/ulp/sdp/sdp_rx.c b/drivers/infiniband/ulp/sdp/sdp_rx.c index b9c54d1643b5e..f90b88304f247 100644 --- a/drivers/infiniband/ulp/sdp/sdp_rx.c +++ b/drivers/infiniband/ulp/sdp/sdp_rx.c @@ -570,8 +570,15 @@ static int sdp_process_rx_skb(struct sdp_sock *ssk, struct sk_buff *skb) skb_pull(skb, sizeof(struct sdp_bsdh)); - if (unlikely(h->mid == SDP_MID_SRCAVAIL)) - skb_pull(skb, sizeof(struct sdp_srcah)); + if (unlikely(h->mid == SDP_MID_SRCAVAIL)) { + if (ssk->rx_sa) { + sdp_dbg_data(sk, "SrcAvail in the middle of another SrcAvail. Aborting\n"); + h->mid = SDP_MID_DATA; + sdp_post_sendsm(sk); + } else { + skb_pull(skb, sizeof(struct sdp_srcah)); + } + } if (unlikely(h->mid == SDP_MID_DATA && skb->len == 0)) { /* Credit update is valid even after RCV_SHUTDOWN */ diff --git a/drivers/infiniband/ulp/sdp/sdp_zcopy.c b/drivers/infiniband/ulp/sdp/sdp_zcopy.c index 8960ec84f2ab7..dd8c9c0bb2243 100644 --- a/drivers/infiniband/ulp/sdp/sdp_zcopy.c +++ b/drivers/infiniband/ulp/sdp/sdp_zcopy.c @@ -412,7 +412,7 @@ static unsigned long sdp_get_max_memlockable_bytes(unsigned long offset) } static int sdp_alloc_fmr(struct sock *sk, void *uaddr, size_t len, - struct ib_pool_fmr **_fmr, struct ib_umem **_umem, int access) + struct ib_pool_fmr **_fmr, struct ib_umem **_umem, int access, int min_len) { struct ib_pool_fmr *fmr; struct ib_umem *umem; @@ -436,7 +436,7 @@ static int sdp_alloc_fmr(struct sock *sk, void *uaddr, size_t len, len = max_lockable_bytes; } - if (unlikely(len == 0)) + if (unlikely(len <= min_len)) return -EAGAIN; sdp_dbg_data(sk, "user buf: %p, len:0x%zx max_lockable_bytes: 0x%lx\n", @@ -446,9 +446,9 @@ static int sdp_alloc_fmr(struct sock *sk, void *uaddr, size_t len, access, 0); if (IS_ERR(umem)) { - rc = PTR_ERR(umem); - sdp_warn(sk, "Error doing umem_get 0x%zx bytes: %d\n", len, rc); - sdp_warn(sk, "RLIMIT_MEMLOCK: 0x%lx[cur] 0x%lx[max] CAP_IPC_LOCK: %d\n", + rc = -EAGAIN; + sdp_dbg_data(sk, "Error doing umem_get 0x%zx bytes: %d\n", len, rc); + sdp_dbg_data(sk, "RLIMIT_MEMLOCK: 0x%lx[cur] 0x%lx[max] CAP_IPC_LOCK: %d\n", current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur, current->signal->rlim[RLIMIT_MEMLOCK].rlim_max, capable(CAP_IPC_LOCK)); @@ -586,7 +586,7 @@ int sdp_rdma_to_iovec(struct sock *sk, struct iovec *iov, struct sk_buff *skb, } rc = sdp_alloc_fmr(sk, iov->iov_base, len, &rx_sa->fmr, &rx_sa->umem, - IB_ACCESS_LOCAL_WRITE); + IB_ACCESS_LOCAL_WRITE, 0); if (rc) { sdp_dbg_data(sk, "Error allocating fmr: %d\n", rc); goto err_alloc_fmr; @@ -654,7 +654,7 @@ static int do_sdp_sendmsg_zcopy(struct sock *sk, struct tx_srcavail_state *tx_sa unsigned long lock_flags; rc = sdp_alloc_fmr(sk, iov->iov_base, iov->iov_len, - &tx_sa->fmr, &tx_sa->umem, IB_ACCESS_REMOTE_READ); + &tx_sa->fmr, &tx_sa->umem, IB_ACCESS_REMOTE_READ, sdp_zcopy_thresh); if (unlikely(rc)) { sdp_dbg_data(sk, "Error allocating fmr: %d\n", rc); goto err_alloc_fmr;